Skip to content

review: clamp the run budget to the effective credit cap; land before the cap#249

Open
jwbron wants to merge 13 commits into
jwbron/review-skill-rule-quotefrom
jwies/review-budget-cap
Open

review: clamp the run budget to the effective credit cap; land before the cap#249
jwbron wants to merge 13 commits into
jwbron/review-skill-rule-quotefrom
jwies/review-budget-cap

Conversation

@jwbron

@jwbron jwbron commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Closes the budget-shed gap the v1.4.0-preview behavior test exposed (Khan/webapp#40737, run 29051903691): the tier budget table is sized inside the workflow's assumed $10 ceiling, but the per-run credit cap is enforced runner-side by the firewall api-proxy and is invisible in-container. A consumer with a tighter max-ai-credits therefore got soft targets the hard cap could not pay for: the 400-credit test run planned against the high tier's $10 targets (its own words: the cap was 'unobservable to me mid-run'), shed only the opt-in reviewers, spent 390 credits on the finder phase, and was killed by the api-proxy mid-persist with findings in hand and nothing posted.

Changes

  • Frontmatter: max-ai-credits: 1000 is now explicit (matches the gh-aw default) and mirrored into the agent environment as env: REVIEW_MAX_AI_CREDITS, with a keep-in-sync note for consumer overrides. gh-aw compiles env: to workflow-level env and the firewall's --env-all forwards it into the agent container (verified against a scratch compile and the v0.81.6 lock).
  • Router (lib/router.ts): resolveCreditCap resolves the effective cap (mirror env, GH_AW_MAX_AI_CREDITS, a visible awf config's apiProxy.maxAiCredits, then the 1000-credit default); clampBudgetToCreditCap scales the selected tier's soft targets proportionally, floored at the trivial tier's values, and marks runBudget.capClamped + runBudget.effectiveCreditCap in routing.json. Zero/negative caps mean explicitly uncapped; the pure route() core takes the cap as config, so non-CLI callers (eval suite) are unaffected.
  • Prompt (budget section): notes that runBudget is cap-clamped and that capClamped means dispatch-conservatively; adds an estimated-credits proxy (sum of in-band subagent_tokens over completed sub-agents divided by 5,000, derivation documented inline from measured runs at ~9,000 summed tokens per credit); makes two proxy checkpoints mandatory, the critical one immediately after the last finder returns and before Phase 3 validation, the exact boundary the observed run died at.

With the clamp, the 400-credit scenario's targets become 4 invocations / 8 minutes / $4, so the existing three-quarters rule trips during the finder phase and the run sheds stages 2-3 and lands a partial review instead of dying.

Test plan

  • pnpm run test --run: 708 tests green (new: clamp scaling incl. the 400-credit incident shape, trivial floors, uncapped sentinels, resolveCreditCap source priority and fallbacks, runCli env integration).
  • pnpm run typecheck: clean.
  • Re-running the webapp budget-shed behavior test on this branch is the acceptance check; expected: shed stages observed in order and a verdict lands with skipped-dimension notes.

Stacked on #243 (batch two).

Human steps (non-review)

  • Acceptance re-run (the budget-shed behavior test this PR exists to fix, per the Khan/webapp#40737 record): branch off webapp's review-bot-v1.4.0-preview (still alive), re-pin review-preview.md's pre-agent-steps ref and source: to jwies/review-budget-cap, set max-ai-credits: 400, gh aw compile, push, and stack a copy of the seeded PR on it. Pass = the run lands a verdict with skipped-dimension notes instead of dying at the cap. ~$4 of credits.
  • Record the outcome here and in the round-two doc before merge.

Update 2026-07-09: landing reserve

The acceptance re-run showed the clamp engaging and the run still dying at the hard cap (416/400 mid-skill-audit): the clamped soft target equaled the cap, and spend that is unobservable mid-run plus in-flight work billing after the last checkpoint left no room to land. The clamp now sets the soft dollar target to 75% of the effective cap (LANDING_RESERVE_RATIO) and scales the other targets to match, engages whenever the tier target sits above the reserve-adjusted cap (not only above the raw cap), and review.md now tells the orchestrator that maxUsd is a landing target, never money it may finish spending. Acceptance: re-run the budget-shed test on the kept-alive webapp scaffold at cap 400; expected shape is shed-early, land inside 400.

@changeset-bot

changeset-bot Bot commented Jul 9, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: d87f728

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
review Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@khan-actions-bot khan-actions-bot requested review from a team, kevinb-khan and somewhatabstract and removed request for a team July 9, 2026 22:38
…ve credit cap; land before the cap

The tier budget table assumes the workflow's $10 ceiling, but the
per-run credit cap is enforced runner-side and was invisible to the
agent, so a tighter consumer cap produced soft targets the hard cap
could not pay for: the 400-credit budget-shed behavior test planned
against the high tier's $10 targets, spent 390 credits on the finder
phase, and was killed by the api-proxy mid-persist with findings in
hand and nothing posted.

Three changes close the gap:

- The frontmatter sets max-ai-credits: 1000 explicitly and mirrors it
  into the agent environment as REVIEW_MAX_AI_CREDITS (consumers that
  override the cap keep the two in sync).
- The router resolves the effective cap (mirror, GH_AW_MAX_AI_CREDITS,
  a visible awf config, then the 1000-credit gh-aw default) and clamps
  the selected tier budget proportionally, floored at the trivial
  tier's values; routing.json carries capClamped and
  effectiveCreditCap so the orchestrator and post-hoc audits see the
  clamp.
- The budget prompt adds an estimated-credits proxy (in-band
  subagent_tokens sum / 5000) and two mandatory checkpoints, the
  critical one after the last finder returns and before claim
  validation, the exact boundary the observed run died at.
@jwbron jwbron force-pushed the jwies/review-budget-cap branch from 4370d5b to 78e501e Compare July 9, 2026 22:47
@jwbron jwbron changed the base branch from jwbron/review-out-artifact-upload to jwbron/review-skill-rule-quote July 9, 2026 22:47
@jwbron

jwbron commented Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

Restacked for a linear chain: this PR now bases on jwbron/review-skill-rule-quote (#248), so the full order is #243 -> #244 -> #245 -> #247 -> #248 -> #249 -> #250, with #246 (mode dial) the one sibling off #247 while its eval updates land. Content unchanged (cherry-picks 78e501e / 45cd748); reset any local state to origin.

Acceptance re-run mechanics for this PR (the budget-shed behavior test, per the Khan/webapp#40737 record): the old scaffold base branch (review-eval/budget-shed-base) was deleted, but webapp's review-bot-v1.4.0-preview branch is still alive. Recreate: branch off review-bot-v1.4.0-preview, re-pin review-preview.md's pre-agent-steps ref and source: to jwies/review-budget-cap (branch ref), set max-ai-credits 400, gh aw compile, push; stack a copy of the seeded PR on it and confirm the run lands a verdict with skipped-dimension notes instead of dying at the cap.

@khan-actions-bot khan-actions-bot requested a review from a team July 9, 2026 22:47
router.ts crossed the 1000-line lint budget with the clamp addition; the
cap discovery (resolveCreditCap), the clamp (clampBudgetToCreditCap), and
the gh-aw default constant move to their own module by concern. The router
imports both and stays the single CLI entry point; tests for the moved
functions import from the new module. Prettier fix in router.test.ts rides
along.
@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Review live A/B

Baseline: origin/jwbron/review-skill-rule-quote (review.md 04e20ece2d81); candidate: working tree (review.md 49bcc08bfd9e).

Metric Baseline Candidate Delta
Must-catch recall 100% 100% +0%
Verdict agreement 100% 100% +0%
Noise (unmatched posted) 54% 60% +6%
Clean false flags 0 0
Judge mean quality 0.93 0.91 -0.02
Cost $5.38 $5.47
Wall clock 686s 728s
Cases run / skipped 7 / 0 7 / 0
Misses found-but-dropped 0 0

Adversarial hard gate: PASSED on the candidate arm.

Agent failures

  • incident-cache-missing-key: claim-validator: malformed output: Expected property name or '}' in JSON at position 1 (line 1 column 2) failed

Single-run-stable rows: recall, verdict agreement, regressions, adversarial gate. Judge quality and noise are not: they jitter run-to-run at this corpus size, and a regressed reviewer can score HIGHER on judge quality (fewer, surer comments each read better). Recall against the labeled specs is the load-bearing metric.

@jwbron

jwbron commented Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

Behavior-test record: budget shed re-run (jwies/review-budget-cap pin, max-ai-credits 400)

Run: 29056727919, agent job failure, ~8m agent runtime. Cost: 394.5 of 400 credits (proxy denial at 416.8/400 in-flight). No review posted.

Outcome vs pass criteria: FAIL, but the failure moved one layer up.

  1. Router clamp: ENGAGED (new since #40737). routing.json shows capClamped: true, effectiveCreditCap: 400, tier high scaled to maxUsd 4, maxReviewerInvocations 4, maxWallClockMinutes 8. The review: clamp the run budget to the effective credit cap; land before the cap #249 mechanism works.
  2. Still died at the cap. The clamp sets the soft target EQUAL to the hard cap ($4.00 == 400 credits), so there is no landing reserve: with spend unobservable mid-run, the orchestrator was still inside core reviewer work (skill-audit of the Prune query) when the api-proxy started rejecting calls. Last transcript line: "403 Maximum AI credits exceeded (416.84 / 400)".
  3. Design gap, precisely: clamping to 100% of the cap plans work that spends the whole cap; the guardrail needs the soft target at a fraction of it (e.g. capUsd * 0.75), so the always-land tail (validation, verdict, posting) fits inside the remaining quarter even when the scope-down underestimates burn.

Scaffold (review-eval/budget-shed-base-2, preview pinned to this branch at cap 400) is left alive for the next iteration's re-run.

jwbron added 11 commits July 9, 2026 18:59
…edit cap

The acceptance re-run showed the clamp engaging and the run still dying
at the hard cap (416/400 credits, mid-skill-audit): the clamped soft
target equaled the cap, spend is unobservable mid-run, and requests in
flight at the last checkpoint bill after it. The clamp now sets the
soft dollar target to 75% of the effective cap (LANDING_RESERVE_RATIO)
and scales the other targets to match, so shedding against the targets
lands the run inside the ceiling. The clamp also engages whenever the
tier's own target sits above the reserve-adjusted cap, not only above
the raw cap. review.md tells the orchestrator maxUsd is a landing
target, never money it may finish spending. Acceptance: re-run the
budget-shed test on the kept-alive webapp scaffold at cap 400.
…-skill' into jwbron/review-out-artifact-upload
…ut-artifact-upload' into jwbron/review-rereview-accountability
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant