The Operator's ===OPERATOR-DECISION=== schema gains an optional "escalation" field (<=2 steps of model/reasoning_effort/iteration_limit, validated against a new per-runtime orchestration.MODEL_POOL allowlist): per-parent for direct_builder, per-child for split. On limit_reached, completion_watcher.py now walks this ladder (via the shared fanout.escalation_ladder_for()) instead of a single flat identical-params retry, escalating model/iteration_limit before falling back to today's manual repair/Aufteilen-angefordert checkpoints. A card that never went through the Operator keeps its existing flat single-retry behavior unchanged. orchestration.child_failed(), fanout.child_terminal(), and trigger.py's Aufteilen-angefordert guard all switch from the old hardcoded ">= 1" threshold to the card's actual ladder length. board.html surfaces the current attempt count on affected cards. Also includes the board-session-usage-indicator research writeup (Codex app-server JSON-RPC + Claude /api/oauth/usage as the two non-interactive usage sources) and its Operator-produced child intents, plus the operator_klaerung_noetig phase-visibility fix already staged in this checkout (distinct phase for a needs_human/crashed Operator run that never produced children, instead of reusing "durch_kinder_blockiert"). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SyeDivnWm6hgiNd3YKjK7Z
3.3 KiB
Intent: Board-Usage-Endpunkt mit Claude-Nutzungsquelle
Ziel
Einen neuen, ausschließlich lesenden HTTP-Endpunkt GET /api/board/usage
in hosts/blunix/localServices/board-agent/trigger.py einführen, der die
verbleibenden bzw. verbrauchten Nutzungsanteile der geteilten interaktiven
drone-Identität als Prozentwerte zurückgibt. In diesem Schritt wird nur
die Claude-Seite tatsächlich befüllt; die Codex-Seite wird bereits im
Antwortvertrag vorgesehen, aber vorerst als Leerdarstellung (null)
ausgeliefert.
Umfang
-
Neue Route
GET /api/board/usageindo_GETvontrigger.py, im Stil der vorhandenen/api/board/...-Routen und mit_send_json. -
Antwortvertrag (verbindlich, spätere Karten bauen darauf auf):
{ "claude": { "five_hour_used_percent": 42.0, "seven_day_used_percent": 7.5, "five_hour_resets_at": "2026-09-10T18:00:00Z", "seven_day_resets_at": "2026-09-14T00:00:00Z" }, "codex": { "five_hour_used_percent": null, "seven_day_used_percent": null, "five_hour_resets_at": null, "seven_day_resets_at": null } }Alle Werte sind verbrauchte Prozent (
used_percent); die Umrechnung auf "übrig" macht das Frontend. -
Claude-Seite: OAuth-Access-Token aus
~/.claude/.credentials.jsonlesen undGET https://api.anthropic.com/api/oauth/usagemit den HeadernAuthorization: Bearer <token>undanthropic-beta: oauth-2025-04-20aufrufen. Aus dem JSON-Bodyfive_hour.utilization,seven_day.utilizationund die jeweiligenresets_atübernehmen. -
Kurzes Timeout (wenige Sekunden) und vollständige Fehlerisolierung: jeder Fehler (Datei fehlt, JSON kaputt, Netzfehler, Nicht-200, unerwartete Struktur) führt zu
null-Werten für Claude, nicht zu einem Fehlschlag des gesamten Endpunkts. -
Niemals Tokens, Rohantworten, Dollar- oder Limit-Felder an den Client durchreichen; nur die oben genannten Schlüssel.
-
Tests in
test_board_agent.py(Erfolgsfall, Fehlerfälle, kein Token-Leck) im Stil der bestehenden Endpunkt-Tests. -
Kurze Ergänzung der Endpunkt-Übersicht in
README.md.
Explizit ausgeschlossen
- Keine Codex-Anbindung (eigene Folgekarte) und keine Änderung an
board-agent.nix. - Keine UI-Änderung in
board.html(eigene Folgekarte). - Kein Verlauf/Graph, keine Alarmierung, keine Aufschlüsselung pro Rolle.
- Keine Änderung an Board-Spalten oder Trigger-Logik; rein additiv.
Annahmen
board-agent-trigger.servicehat bereits ausgehenden Netzwerkzugriff undProtectHome = "read-only"reicht für das reine Lesen von~/.claude/.credentials.json; es ist keine Sandbox-Anpassung nötig.- Der Endpunkt braucht keine Authentifizierung, weil das Board selbst
bereits nur lokal erreichbar ist wie die übrigen
/api/board/-Routen.
Offene Risiken
/api/oauth/usageist ein undokumentierter, privater Endpunkt und kann sich ändern; deshalb ist die Fehlerisolierung (Leerdarstellung statt Ausnahme) verpflichtend und nicht optional.- Die Feldnamen der Upstream-Antwort können abweichen; der Code muss fehlende Felder tolerieren.
Erfolgskriterien
GET /api/board/usageantwortet mit 200 und dem oben festgelegten Objekt; die Codex-Felder sindnull.- Tests belegen Erfolgsfall, Fehlerfälle und dass keine Secrets im Antwortkörper landen.
- Der bestehende Testlauf bleibt grün.