feat(scan): report token budget stop in JSON summary.budget_exceeded - #791
Open
chethanuk wants to merge 1 commit into
Open
feat(scan): report token budget stop in JSON summary.budget_exceeded#791chethanuk wants to merge 1 commit into
chethanuk wants to merge 1 commit into
Conversation
Contributor
|
✅ OpenCodeReview: Review complete: 0 finding(s) across 1 selected item(s). |
scan already detects the aggregate token-budget stop (it prints the
"[ocr] token budget reached" line and records a token_budget_reached
warning) but BudgetExceeded() was hard-coded false, so
summary.budget_exceeded never appeared in `ocr scan --format json`.
The write goes next to `budgetHit = true` in dispatchBatch's per-file
gate. That is the only site that sets budgetHit, and it covers all three
exits that carry the stop out of dispatchBatch: normal return, ctx-cancel
return, and the caller's `if budgetHit { break }`. Setting it at the
dispatchSubtasks break instead would lose it on the ctx-cancel path.
Plain bool, no mutex: dispatchBatch's loop is the only writer, it runs on
the caller's goroutine, and the value is read by emitRunResult after Run
returns. The spawned subtask goroutines never touch it. Matches the
existing internal/agent.Agent.budgetExceeded field.
Status and exit code are untouched — reaching the budget is a controlled
truncation, so out.Status stays the warning-derived value.
chethanuk
force-pushed
the
feat/issue-771-scan-budget-exceeded
branch
from
August 14, 2026 21:06
3f1bea5 to
611847e
Compare
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
ocr scan --format json --max-tokens-budget Nalready detects the aggregate budget stop — it records atoken_budget_reachedwarning and stops dispatching — butsummary.budget_exceededstayedfalse, becausescan.Agent.BudgetExceeded()was hardcoded toreturn false. Automation consuming the JSON had to parse the warning list to tell a complete scan from one truncated by the budget.The signal already existed inside scan; it just never reached the result provider.
The flag is set where
budgetHitis set, not at thebreak.dispatchBatchhas three exits that carrybudgetHit, and the ctx-cancel exit at:651reachesdispatchSubtasks'err != nilreturn at:538— which fires before theif budgetHitcheck at:557. Writing the flag at the break would silently lose it on cancel-after-budget-hit. One write at:641covers all three exits.No mutex or atomic:
budgetHit = trueruns indispatchBatch's own loop body, beforesem <- struct{}{}and outside the worker closure, anddispatchBatchhas one caller in a sequential batch loop — one writer on one goroutine, read only afterRunreturns.internal/agent/agent.gostores the same flag as a plainboolon the diff-review path.make testruns with-race, so this is enforced rather than argued.budget_exceededis diagnostic only and does not touch scan's status semantics: scan publishes no run manifest, so the status stays whatever the warnings imply —completed_with_warningswhen the gate trips (thetoken_budget_reachedwarning is what produces that, not this flag),successotherwise. Both subtests assert the status explicitly so this cannot start driving it.omitemptykeepsbudget_exceededout of the JSON entirely when the gate does not trip.Limitation
The new CLI-level test drives the real
*scan.Agentand the realemitRunResult, not a spawnedocrbinary — no test in this repo spawns it, and doing so would need live provider credentials. The flag-parsing layer betweenparseScanFlagsandscan.Args.MaxTokensBudgetis covered separately bycmd/opencodereview/scan_cmd_test.go.Type of Change
How Has This Been Tested?
make testpasses locallymake test(with-race) andmake checkboth pass on the currentmain.cmd/opencodereview/scan_budget_json_test.go(new) — drives a real*scan.Agentover eight fixture files through the real budget gate andemitRunResult, assertingsummary.budget_exceeded == trueplus thetoken_budget_reachedwarning atMaxTokensBudget=120_000, and that the raw JSON contains nobudget_exceededkey at all when no budget is set.internal/scan/budget_exceeded_test.go(new) — table-driven, both directions, throughdispatchSubtasks.a.budgetExceeded = trueline fails both.Checklist
go fmt,go vet)budget_exceededis currently undocumented underpages/for the review path too, so documenting it belongs in a separate docs PR rather than this one.Related Issues
closes #771