Repository navigation
feat(coordinator): replace turn budget with per-cycle USD cost budget (REHOR-211) - #588
Open
Hyperkid123 wants to merge 1 commit into
Open
Hyperkid123 wants to merge 1 commit into
Hyperkid123 wants to merge 1 commit into
Conversation
Hyperkid123
force-pushed
the
feat/rehor-211-cost-budget
branch
from
October 27, 2026 13:59
65c43c6 to
66bc807
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Replaces the turn/tool-call budget with a per-cycle-run USD cost budget (default $5, configurable), fixing the semantic mismatch where
maxTurns: 200meant 200 model turns on the Claude runtime but 200 tool calls (root + subagents) on OpenCode — ~10x stricter, which killed delegation-heavy runs mid-wrap-up (evidence: RHCLOUD-52555 cycle 52325, terminalfailed/max_turnsat 23 root turns with 568 tool calls, PR already open, state not saved).REHOR-211
What changed:
CostBudgetPolicyreplacesTurnBudgetPolicy(both incoordinator/src/coordinator.ts): a sharedUsageLedger(domain/usage.ts, snapshot rules identical to the compatibility projection) accumulates cost fromusageevents across root and subagent sessions. Thresholds 50% info / 75% warning / 90% critical / 100% exhausted — each fires once with an agent-facing notice telling the agent to save state viatask_update. Grace window: at 100% the agent is told to wrap up; hard abort at 115% with terminal reasonbudget_exceeded(expected-failure handling, same as the oldmax_turns).maxTurnsremoved from the coordinator contract:rehor-run.v1.jsonlimits are nowtimeoutMs + budgetUsd; default $5 flows through the TS python bridge (DEFAULT_BUDGET_USD),bot/config.py(budget_usd, default 5.0), andcoordinator_bridge.py. The Claude SDKmaxTurnspass-through is removed;enforcesTurnLimitis now false on both runtimes.onPolicyNoticepush channel onAgentRuntimeRunContext; the OpenCode runtime delivers via a queued root-session prompt (fire-and-forget, failures logged and non-fatal), the Claude runtime flushes a notice queue through the PostToolUse hooksystemMessage.COST BUDGET INACTIVEpolicy event when cost is affirmativelysource: "unknown"(unsettled in-flight snapshots do not disable the budget); the cycle timeout remains the backstop.devbot_cost_budget_event_total(info/warning/critical/exhausted); docs updated (coordinator README, opencode-migration, openshell-deployment, presets-design, root README example config).Deliberately out of scope (documented in the ticket): the legacy
bot/agent.pyPython turn hook stays until the legacy direct path retires;opencode.maxToolCalls/REHOR_OPENCODE_MAX_TOOL_CALLSare now parsed-but-unused removal candidates.Blast radius
budgetUsdcontract change is atomic; instance configs withoutbudgetUsdget the $5 default.cost-budget-policy.test.ts, 10 tests; 4 new integration tests incl. 115% abort and unknown-pricing fail-open; reworked OpenCode runtime tests for hard-limit abort, grace window, notice delivery), pythonbot/tests(config + coordinator_bridge updated forbudgetUsd).Rollback plan
git revertof the single commit is sufficient — the schema/budget field is only consumed by code shipped in the same image, stored transcripts/events are unaffected (policy payload is a new shape rendered generically), and instance configs withoutbudgetUsdfall back to the default either way. After revert, turn budget is restored with the oldmaxTurnssemantics.Checklist
latestAI disclosure
Assisted by: OpenCode (GLM 5.3) — implementation delegated to and reviewed by the primary session; all tests/typecheck/lint run locally and independently re-verified.