fix(context-budget): measure against the real window with an explicit token budget - #49
Open
TastyTom13 wants to merge 4 commits into
Open
TastyTom13 wants to merge 4 commits into
TastyTom13 wants to merge 4 commits into
Conversation
TastyTom13
force-pushed
the
fm/firstmate-context-nudge-real-window
branch
from
October 2, 2026 14:43
fcc0ff7 to
8a0037f
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.
Intent
Fix the fork-only context nudge so it measures against the real Claude Code compaction window (FM_CONTEXT_WINDOW, else CLAUDE_CODE_AUTO_COMPACT_WINDOW, else 200000) and nudges early against an explicit FM_CONTEXT_BUDGET token budget (default 500000, clamped to the window) with bands at 40/60 percent of the budget overridable in tokens, printing tokens, percent of window, percent of budget, and band, keeping the throttle and quiet-moment rule unchanged; docs explain the budget sits below the window per the captain's 2026-10-02 decision.
What Changed
bin/fm-context-budget.shnow resolves the real window from--window, thenFM_CONTEXT_WINDOW, then a numericCLAUDE_CODE_AUTO_COMPACT_WINDOW, then 200000. It adds anFM_CONTEXT_BUDGETtoken budget (default 500000, clamped to the window). The 40/60 percent bands are now token thresholds taken from that budget, andFM_CONTEXT_NUDGE_SUGGESTandFM_CONTEXT_NUDGE_NOWoverride them in tokens. The printed line shows tokens, percent of the window (with its source), percent of the budget, and the band. The throttle step is now budget percent divided by 20. The quiet-moment rule and the throttle record format are unchanged.docs/configuration.md,docs/turnend-guard.md, and the comments inbin/fm-turnend-guard.shdescribe the window and budget precedence, the new env vars, and the budget-based steps. The docs say the budget sits below the window per the captain's 2026-10-02 decision, so the nudge fires before Claude Code's hard auto-compaction.tests/fm-context-budget.test.shadds 78 lines of cases for the new behaviour.Risk Assessment
✅ Low: The change is confined to one advisory script, its docs and its tests, it matches every point of the stated intent, and the earlier environment-leak finding is fixed by a single top-of-file unset.
Testing
I ran the budget test file (all pass) and drove the real script by hand on synthetic transcripts. The printed line shows tokens, percent of window, percent of budget, source and band. Window precedence, clamp, 40/60 token bands and overrides all behave. The nudge throttle fires once per 20 percent budget step and rejects repeats. Docs explain the budget sits below the window. The change has no UI, so there are no screenshots. The Stop hook was covered by the test file, not by a live Claude session, so that scenario is marked untested.
Evidence: Live script transcript
Source: Live script transcript
Evidence: Test file run
Source: Test file run
Pipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
🔧 **Review** - 1 issue found → auto-fixed ✅
tests/fm-context-budget.test.sh:158- The new budget tests rely on the caller's environment. test_budget_bands_and_clamp (tests/fm-context-budget.test.sh:158-185) and test_nudge_steps_follow_the_budget (:188-203) pass only --window 600000. They assume the default 500000 budget and the default 40/60 bands, but nothing unsets FM_CONTEXT_BUDGET, FM_CONTEXT_NUDGE_SUGGEST or FM_CONTEXT_NUDGE_NOW. The script now reads all three, so a shell that exports one of them gives different bands and the tests fail. Same class, same file: the hook tests (:368 and :376) pin FM_CONTEXT_WINDOW=200000 but inherit FM_CONTEXT_BUDGET and the NUDGE_* thresholds, so a lower exported budget changes when the guard nudges. The 'nudge()' helper (:207-209) also passes only --window. The fix is to run these calls underenv -u FM_CONTEXT_BUDGET -u FM_CONTEXT_NUDGE_SUGGEST -u FM_CONTEXT_NUDGE_NOW -u CLAUDE_CODE_AUTO_COMPACT_WINDOW, or to unset them once at the top of the test file.🔧 Fix applied.
✅ Re-checked - no issues remain.
✅ **Test** - passed
✅ No issues found.
bash tests/fm-context-budget.test.sh(21 ok, includes the review-round env isolation and the real turn-end guard hook tests)Hand-drivenbin/fm-context-budget.shagainst synthetic Claude transcripts: default window clamp, CLAUDE_CODE_AUTO_COMPACT_WINDOW window, FM_CONTEXT_WINDOW precedence, explicit FM_CONTEXT_BUDGET, token-threshold overrides, invalid values, --percent, --nudge throttleRead the docs diff (docs/configuration.md, docs/turnend-guard.md) for the budget-below-window explanation and 2026-10-02 decision✅ **Document** - passed
✅ No issues found.
✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.