From 1d65d87a8cf2ae38fdac90054326140cd19650c1 Mon Sep 17 00:00:00 2001 From: Kyle Sexton <153232337+kyle-sexton@users.noreply.github.com> Date: Fri, 9 Oct 2026 02:16:30 -0400 Subject: [PATCH 1/3] fix(context-guard): read dumb past 500000 tokens on a 1M window, not 250000 At 26% of a 1M window the shipped token band read "dumb zone (3 of 3)", and sessions stopped work on it. The 1M row's acceptable edge moves to 500000; the smart edge stays at 128000. The reader contract re-anchors the row on Google's GraphWalks BFS figures for Opus 5.5 and Fable 5.1 and on Context Arena's 8-needle MRCR, and corrects the Sonnet 5 MRCR figures. Closes #6644 Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01PCiAaEVSXdj1VnWVXtjyu2 --- .../fix-context-guard-1m-band-2f868982.md | 11 ++++++ .../fix-context-guard-1m-band-a79971d9.md | 7 ++++ lib/context-zone.fixtures.mjs | 5 ++- lib/context-zone.sh | 8 ++-- plugins/context-guard/README.md | 2 +- .../context-guard/hooks/context-guard.test.ts | 7 ++++ plugins/context-guard/hooks/zone.ts | 2 +- .../reference/reader-contract.md | 37 +++++++++++-------- .../scripts/context-zone.fixtures.mjs | 5 ++- plugins/context-guard/scripts/context-zone.sh | 8 ++-- .../scripts/context-zone.test.sh | 3 +- plugins/context-guard/skills/setup/SKILL.md | 2 +- .../scripts/context-zone.fixtures.mjs | 5 ++- .../plugin-quality/scripts/context-zone.sh | 8 ++-- .../scripts/context-zone.test.sh | 3 +- .../scripts/zones-inline-drift.test.sh | 2 +- 16 files changed, 76 insertions(+), 39 deletions(-) create mode 100644 .changes/context-guard/fix-context-guard-1m-band-2f868982.md create mode 100644 .changes/plugin-quality/fix-context-guard-1m-band-a79971d9.md diff --git a/.changes/context-guard/fix-context-guard-1m-band-2f868982.md b/.changes/context-guard/fix-context-guard-1m-band-2f868982.md new file mode 100644 index 0000000000..e39d65d50b --- /dev/null +++ b/.changes/context-guard/fix-context-guard-1m-band-2f868982.md @@ -0,0 +1,11 @@ +--- +bump: minor +--- + +### Changed + +- **The 1M-window token band reads `dumb` past 500000 tokens, not 250000 ([#6644](https://github.com/melodic-software/claude-code-plugins/issues/6644)).** At 26% of a 1M window the shipped bands read `dumb (3 of 3)` and sessions stopped work on it. The `smart` edge stays at 128000. The reader contract records the new basis: Google's GraphWalks BFS figures for Opus 5.5 and Fable 5.1, and Context Arena's 8-needle MRCR, where both Claude rows first score under one half at 512K. The 200k row and the percentage bands are unchanged; `zones.json` still overrides. + +### Fixed + +- **Band provenance figures.** The reader contract gave Claude Sonnet 5's 8-needle MRCR as at least 0.957 through 256K; the live table reads 0.529 at 128K and 0.522 at 256K. It also said no per-length data exists for Opus 5.5, but Google publishes its GraphWalks BFS scores (90.6% up to 128K, 66.8% from 256K to 1M). diff --git a/.changes/plugin-quality/fix-context-guard-1m-band-a79971d9.md b/.changes/plugin-quality/fix-context-guard-1m-band-a79971d9.md new file mode 100644 index 0000000000..165e32fa2e --- /dev/null +++ b/.changes/plugin-quality/fix-context-guard-1m-band-a79971d9.md @@ -0,0 +1,7 @@ +--- +bump: patch +--- + +### Changed + +- **The bundled zone resolver's 1M-window token band reads `dumb` past 500000 tokens, not 250000 ([#6644](https://github.com/melodic-software/claude-code-plugins/issues/6644)),** synced from context-guard's reader contract. diff --git a/lib/context-zone.fixtures.mjs b/lib/context-zone.fixtures.mjs index 508e489c6d..4a6784c283 100644 --- a/lib/context-zone.fixtures.mjs +++ b/lib/context-zone.fixtures.mjs @@ -38,8 +38,9 @@ export default [ {"name":"tokens 200000+1 in 200000","sid":"s1","snapshot":{"captured_at":"@now-30","session_id":"s1","context_window":{"used_percentage":null,"remaining_percentage":80,"current_usage":{"input_tokens":100},"total_input_tokens":200000,"total_output_tokens":1,"context_window_size":200000},"cli_version":"2.1.200"},"zones":null,"word":"unknown","notices":[]}, {"name":"tokens 118000+10000 in 1000000","sid":"s1","snapshot":{"captured_at":"@now-30","session_id":"s1","context_window":{"used_percentage":null,"remaining_percentage":80,"current_usage":{"input_tokens":100},"total_input_tokens":118000,"total_output_tokens":10000,"context_window_size":1000000},"cli_version":"2.1.200"},"zones":null,"word":"smart","notices":[]}, {"name":"tokens 128000+1 in 1000000","sid":"s1","snapshot":{"captured_at":"@now-30","session_id":"s1","context_window":{"used_percentage":null,"remaining_percentage":80,"current_usage":{"input_tokens":100},"total_input_tokens":128000,"total_output_tokens":1,"context_window_size":1000000},"cli_version":"2.1.200"},"zones":null,"word":"acceptable","notices":[]}, - {"name":"tokens 249000+1000 in 1000000","sid":"s1","snapshot":{"captured_at":"@now-30","session_id":"s1","context_window":{"used_percentage":null,"remaining_percentage":80,"current_usage":{"input_tokens":100},"total_input_tokens":249000,"total_output_tokens":1000,"context_window_size":1000000},"cli_version":"2.1.200"},"zones":null,"word":"acceptable","notices":[]}, - {"name":"tokens 250000+1 in 1000000","sid":"s1","snapshot":{"captured_at":"@now-30","session_id":"s1","context_window":{"used_percentage":null,"remaining_percentage":80,"current_usage":{"input_tokens":100},"total_input_tokens":250000,"total_output_tokens":1,"context_window_size":1000000},"cli_version":"2.1.200"},"zones":null,"word":"dumb","notices":[]}, + {"name":"tokens 260000 in 1000000 (26% used, #6644) is not dumb","sid":"s1","snapshot":{"captured_at":"@now-30","session_id":"s1","context_window":{"used_percentage":26,"remaining_percentage":74,"current_usage":{"input_tokens":100},"total_input_tokens":260000,"total_output_tokens":0,"context_window_size":1000000},"cli_version":"2.1.200"},"zones":null,"word":"acceptable","notices":[]}, + {"name":"tokens 499000+1000 in 1000000","sid":"s1","snapshot":{"captured_at":"@now-30","session_id":"s1","context_window":{"used_percentage":null,"remaining_percentage":80,"current_usage":{"input_tokens":100},"total_input_tokens":499000,"total_output_tokens":1000,"context_window_size":1000000},"cli_version":"2.1.200"},"zones":null,"word":"acceptable","notices":[]}, + {"name":"tokens 500000+1 in 1000000","sid":"s1","snapshot":{"captured_at":"@now-30","session_id":"s1","context_window":{"used_percentage":null,"remaining_percentage":80,"current_usage":{"input_tokens":100},"total_input_tokens":500000,"total_output_tokens":1,"context_window_size":1000000},"cli_version":"2.1.200"},"zones":null,"word":"dumb","notices":[]}, {"name":"tokens 999000+1000 in 1000000","sid":"s1","snapshot":{"captured_at":"@now-30","session_id":"s1","context_window":{"used_percentage":null,"remaining_percentage":80,"current_usage":{"input_tokens":100},"total_input_tokens":999000,"total_output_tokens":1000,"context_window_size":1000000},"cli_version":"2.1.200"},"zones":null,"word":"dumb","notices":[]}, {"name":"tokens 1000000+1 in 1000000","sid":"s1","snapshot":{"captured_at":"@now-30","session_id":"s1","context_window":{"used_percentage":null,"remaining_percentage":80,"current_usage":{"input_tokens":100},"total_input_tokens":1000000,"total_output_tokens":1,"context_window_size":1000000},"cli_version":"2.1.200"},"zones":null,"word":"unknown","notices":[]}, {"name":"window 500000 takes the 200000 class","sid":"s1","snapshot":{"captured_at":"@now-30","session_id":"s1","context_window":{"used_percentage":null,"remaining_percentage":80,"current_usage":{"input_tokens":100},"total_input_tokens":110000,"total_output_tokens":0,"context_window_size":500000},"cli_version":"2.1.200"},"zones":null,"word":"acceptable","notices":[]}, diff --git a/lib/context-zone.sh b/lib/context-zone.sh index f31dcdb5a2..61bf9096be 100755 --- a/lib/context-zone.sh +++ b/lib/context-zone.sh @@ -53,7 +53,7 @@ # window-class token bands over occupancy: # # window class 200000: smart ≤ 100000 < acceptable ≤ 150000 < dumb -# window class 1000000: smart ≤ 128000 < acceptable ≤ 250000 < dumb +# window class 1000000: smart ≤ 128000 < acceptable ≤ 500000 < dumb # # All are declared judgment defaults, NOT doc- or benchmark-derived # constants (anchors and provenance are recorded in the reader contract). @@ -64,7 +64,7 @@ # "acceptable_max_used_percentage": 75, # "token_bands": { # "200000": { "smart_max_tokens": 100000, "acceptable_max_tokens": 150000 }, -# "1000000": { "smart_max_tokens": 128000, "acceptable_max_tokens": 250000 } +# "1000000": { "smart_max_tokens": 128000, "acceptable_max_tokens": 500000 } # } # } # @@ -92,7 +92,7 @@ DEFAULT_ACCEPTABLE_MAX=75 # [class, smart_max, acceptable_max] rows, ascending class order. JSON rather # than whitespace rows because the bands are handed to the snapshot pass as # data, so the comparison happens there instead of in a separate awk process. -DEFAULT_TOKEN_BANDS='[[200000,100000,150000],[1000000,128000,250000]]' +DEFAULT_TOKEN_BANDS='[[200000,100000,150000],[1000000,128000,500000]]' unknown() { printf 'unknown\n' @@ -197,7 +197,7 @@ if [[ -e "$zones" ]]; then acceptable_max=${zpct#* } fi if [[ "$ztb" == "invalid" ]]; then - printf 'context-guard: zones.json token_bands malformed — using shipped default token bands (200000:100000/150000, 1000000:128000/250000)\n' >&2 + printf 'context-guard: zones.json token_bands malformed — using shipped default token bands (200000:100000/150000, 1000000:128000/500000)\n' >&2 elif [[ "$ztb" != "absent" ]]; then token_bands=$ztb fi diff --git a/plugins/context-guard/README.md b/plugins/context-guard/README.md index 3020926e0a..cdb390e7e1 100644 --- a/plugins/context-guard/README.md +++ b/plugins/context-guard/README.md @@ -14,7 +14,7 @@ degraded context **before** quality slips, instead of guessing. Four parts: worse computable zone wins): percentage bands over `used_percentage` (shipped defaults smart ≤ 50 < acceptable ≤ 75 < dumb) and window-class token bands over occupancy (`total_input_tokens + total_output_tokens`; shipped defaults 100k/150k on a 200k window, - 128k/250k on a 1M window). Bands come from the machine-scope + 128k/500k on a 1M window). Bands come from the machine-scope `~/.claude/context-guard/zones.json` when present and valid, else from the shipped defaults. Zones say *where you are*; consumers decide *what to do*. - **PostCompact marker hook** (`hooks/post-compact-mark.sh`), a settings hook, so it runs where diff --git a/plugins/context-guard/hooks/context-guard.test.ts b/plugins/context-guard/hooks/context-guard.test.ts index 731a23a1b1..566657436c 100644 --- a/plugins/context-guard/hooks/context-guard.test.ts +++ b/plugins/context-guard/hooks/context-guard.test.ts @@ -421,6 +421,13 @@ test('zones.json: an extra threshold gets its approach line and its line once pe ]) }) +// Issue #6644: on a 1000000-token window with the shipped bands, 26% used (260000 tokens) read +// dumb. The reader contract's 1M row puts the dumb edge past 500000 tokens. +test('shipped bands, 1000000 window: 26% used announces acceptable, never dumb; 51% announces dumb', async ($, on) => { + const { w } = world(on, { window: 1_000_000 }) + expect(await walk($, w, [5, 26, 51])).toEqual([[], [crossing('acceptable')], [crossing('dumb')]]) +}) + // The token edges of a 1000000-token window at 210000 and 410000; the percentage edges there // (50% and 75%) sit at 500000 and 750000 tokens, so the token shape decides both crossings. const TOKEN_EDGES = { token_bands: { '1000000': { smart_max_tokens: 210_000, acceptable_max_tokens: 410_000 } } } diff --git a/plugins/context-guard/hooks/zone.ts b/plugins/context-guard/hooks/zone.ts index 0f04dbd608..f12896ac9d 100644 --- a/plugins/context-guard/hooks/zone.ts +++ b/plugins/context-guard/hooks/zone.ts @@ -13,7 +13,7 @@ export const DEFAULT_BANDS: Bands = { acceptable: 75, tokens: [ [200_000, 100_000, 150_000], - [1_000_000, 128_000, 250_000], + [1_000_000, 128_000, 500_000], ], } export const RANK: Record = { smart: 0, acceptable: 1, dumb: 2 } diff --git a/plugins/context-guard/reference/reader-contract.md b/plugins/context-guard/reference/reader-contract.md index c98ee2bf2a..b4a7c43700 100644 --- a/plugins/context-guard/reference/reader-contract.md +++ b/plugins/context-guard/reference/reader-contract.md @@ -59,7 +59,7 @@ same triggers. These stamps are probe results with a date, not standing facts. - **Default token bands (over occupancy = `total_input_tokens` + `total_output_tokens`, uppers inclusive, selected by window class as described under "Occupancy and combination rule"):** window class **200000**: `smart` ≤ **100000** < `acceptable` ≤ **150000** < `dumb`; - window class **1000000**: `smart` ≤ **128000** < `acceptable` ≤ **250000** < `dumb`. + window class **1000000**: `smart` ≤ **128000** < `acceptable` ≤ **500000** < `dumb`. - **Token-shape version floor (fixed):** the token shape is computable only when the snapshot's `cli_version` is present, purely numeric dotted, and **≥ 2.1.132**, the release from which the token fields mean current occupancy rather than cumulative session totals. @@ -226,13 +226,19 @@ a version field cannot (there is no writer authentication, so `cli_version` is u every other snapshot value). The bundled resolver implements both gates. **Band provenance:** the shipped token bands are **declared judgment**, not benchmark-derived -constants. No per-length long-context data is published for Claude Opus 5.5, Sonnet 5.5 or Fable -5.1; their system cards report only an aggregate ProgramBench score. The 1M row's edges, 128000 -and 250000, are anchored on the nearest published data: on Context Arena's 8-needle MRCR (max -effort, Google tokenizer) Claude Opus 5 scores 0.913 at 128K, 0.656 at 256K and 0.425 at 512K, and -Claude Sonnet 5 a median of at least 0.957 through 256K and 0.041 at 512K; on GraphWalks BFS, run -by Google at max reasoning and published with Gemini 4 Argon on 2026-09-30, Fable 5.1 scores 91.4% -up to 128K and 65.0% from 256K to 1M. The 200k row's `acceptable` edge, 150000, sits at +constants. Anthropic publishes no per-length long-context scores for Claude Opus 5.5, Sonnet 5.5 +or Fable 5.1: their system cards report one aggregate ProgramBench score each, an agentic task +whose episodes run up to the full 1M window. The published per-length data is retrieval and graph +traversal, not agentic work, and no study we found links those scores to agentic task quality. On +GraphWalks BFS, run by Google at max reasoning and published with Gemini 4 Argon, Opus 5.5 scores +90.6% up to 128K and 66.8% from 256K to 1M, and Fable 5.1 91.4% and 65.0%. On Context Arena's +8-needle MRCR (max effort), Claude Opus 5 scores 0.913 at 128K, 0.656 at 256K and 0.425 at 512K, +and Claude Sonnet 5 0.529, 0.522 and 0.320. The 1M row's `smart` edge, 128000, is the last length +at which those current-model scores are still near their best. Its `acceptable` edge, 500000, +sits below 512K, the first MRCR length at which both Claude rows score under one half. Between +the two, scores sag without a measured cliff, so a reading there is `acceptable`, not `dumb`: an +`acceptable` edge of 250000 read `dumb` at 26% of a 1M window on no evidence for current models +or agentic work (#6644). The 200k row's `acceptable` edge, 150000, sits at the top of the practitioner consensus of about 125-150K. `zones.json` is the correction path, and the numeric agreement of the 200k row's percentage translation with the shipped 50/75 percentage defaults is coincidence, not validation. @@ -240,14 +246,15 @@ defaults is coincidence, not validation. - **Pointer**: when re-deriving a 1M band edge, fetch live: [Context Arena, 8 needles](https://contextarena.ai/api/needle-summary?needles=8), the Claude Opus 5 and Claude Sonnet 5 rows; [Gemini models](https://deepmind.google/models/gemini), the - Gemini 4 Argon table's GraphWalks BFS rows; the absence of per-length data, the + Gemini 4 Argon table's Opus 5.5 and Fable 5.1 GraphWalks BFS rows; the absence of per-length data, the [Opus 5.5 system card](https://www-cdn.anthropic.com/fc1b44717c85dc068bc6ba5024219938094694bd/Claude%20Opus%205.5%20System%20Card.pdf) section 8.10 and the [Fable 5.1 system card](https://www-cdn.anthropic.com/0339e6a7c5c7b87f5c07798616dc32c215d14235/Claude%20Fable%205.1%20&%20Claude%20Mythos%205.1%20System%20Card.pdf) section 8.11. For the 200k row, correlate with [AI Hero, "Smart Zone"](https://www.aihero.dev/ai-coding-dictionary/smart-zone) and [Geoffrey Huntley, "Ralph"](https://ghuntley.com/ralph/); no docs page covers where quality degrades on a 200K window as of 2026-10-04. -- **As of**: 2026-10-07 -- **Recheck trigger**: Opus 5.5, Fable 5.1 or Sonnet 5.5 appear on Context Arena; a new or revised +- **As of**: 2026-10-09 +- **Recheck trigger**: Opus 5.5, Fable 5.1 or Sonnet 5.5 appear on Context Arena; Google's table + splits the 256K-1M GraphWalks bin; a new or revised Anthropic system card publishes per-length scores; or a docs page starts covering where quality degrades on a 200K window, at which point the 200k row's pointer moves there. @@ -382,7 +389,7 @@ session itself can know. compaction fires at or near the model's context limit; the cases that fire earlier depend on the model, the window it runs with, and the environment. For the current thresholds, see [Claude Code model config, "Default auto-compact thresholds"](https://code.claude.com/docs/en/model-config#default-auto-compact-thresholds). -**As of:** 2026-09-30, the one number that section publishes, for native 1M windows, sits above +**As of:** 2026-10-09, the one number that section publishes for native 1M windows, about 967K tokens, sits above the shipped `dumb` band, so it does not disturb the margin that the bands-below-the-trigger rule protects, the way a lowered window does. **Recheck trigger:** that section is renamed or removed, or publishes a default at or below the `dumb` band's lower edge. `CLAUDE_AUTOCOMPACT_PCT_OVERRIDE` @@ -451,8 +458,8 @@ hook, so a firing is best read diagnostically: **it means the boundary was misse window was managed. Lowering the window moves the trigger, so the bands in `zones.json` must move with it, normalized into the percentage shape. A 400000-token window on a 1M-class model puts the trigger at **40% of the full window**, which is *inside* the shipped percentage `smart` band -(≤ 50), so the percentage shape still reads smart when auto-compact fires (the token shape decides -the zone there). Keeping the percentage bands below that trigger means pulling them under 40, not +(≤ 50), so the percentage shape still reads smart when auto-compact fires, and the token shape, +which decides the zone there, reads `acceptable`: neither shipped shape reaches `dumb` first. Keeping the percentage bands below that trigger means pulling them under 40, not comparing 400000 against the token bands' occupancy edges, which measure a different quantity. That diagnostic reading is adopted; the prescription that usually travels with it is not. **Leave @@ -500,7 +507,7 @@ what the human sees and what consumers decide on. Zones say *where you are*; con "acceptable_max_used_percentage": 75, "token_bands": { "200000": { "smart_max_tokens": 100000, "acceptable_max_tokens": 150000 }, - "1000000": { "smart_max_tokens": 128000, "acceptable_max_tokens": 250000 } + "1000000": { "smart_max_tokens": 128000, "acceptable_max_tokens": 500000 } } } ``` diff --git a/plugins/context-guard/scripts/context-zone.fixtures.mjs b/plugins/context-guard/scripts/context-zone.fixtures.mjs index 815c045ab1..62525c73ae 100644 --- a/plugins/context-guard/scripts/context-zone.fixtures.mjs +++ b/plugins/context-guard/scripts/context-zone.fixtures.mjs @@ -40,8 +40,9 @@ export default [ {"name":"tokens 200000+1 in 200000","sid":"s1","snapshot":{"captured_at":"@now-30","session_id":"s1","context_window":{"used_percentage":null,"remaining_percentage":80,"current_usage":{"input_tokens":100},"total_input_tokens":200000,"total_output_tokens":1,"context_window_size":200000},"cli_version":"2.1.200"},"zones":null,"word":"unknown","notices":[]}, {"name":"tokens 118000+10000 in 1000000","sid":"s1","snapshot":{"captured_at":"@now-30","session_id":"s1","context_window":{"used_percentage":null,"remaining_percentage":80,"current_usage":{"input_tokens":100},"total_input_tokens":118000,"total_output_tokens":10000,"context_window_size":1000000},"cli_version":"2.1.200"},"zones":null,"word":"smart","notices":[]}, {"name":"tokens 128000+1 in 1000000","sid":"s1","snapshot":{"captured_at":"@now-30","session_id":"s1","context_window":{"used_percentage":null,"remaining_percentage":80,"current_usage":{"input_tokens":100},"total_input_tokens":128000,"total_output_tokens":1,"context_window_size":1000000},"cli_version":"2.1.200"},"zones":null,"word":"acceptable","notices":[]}, - {"name":"tokens 249000+1000 in 1000000","sid":"s1","snapshot":{"captured_at":"@now-30","session_id":"s1","context_window":{"used_percentage":null,"remaining_percentage":80,"current_usage":{"input_tokens":100},"total_input_tokens":249000,"total_output_tokens":1000,"context_window_size":1000000},"cli_version":"2.1.200"},"zones":null,"word":"acceptable","notices":[]}, - {"name":"tokens 250000+1 in 1000000","sid":"s1","snapshot":{"captured_at":"@now-30","session_id":"s1","context_window":{"used_percentage":null,"remaining_percentage":80,"current_usage":{"input_tokens":100},"total_input_tokens":250000,"total_output_tokens":1,"context_window_size":1000000},"cli_version":"2.1.200"},"zones":null,"word":"dumb","notices":[]}, + {"name":"tokens 260000 in 1000000 (26% used, #6644) is not dumb","sid":"s1","snapshot":{"captured_at":"@now-30","session_id":"s1","context_window":{"used_percentage":26,"remaining_percentage":74,"current_usage":{"input_tokens":100},"total_input_tokens":260000,"total_output_tokens":0,"context_window_size":1000000},"cli_version":"2.1.200"},"zones":null,"word":"acceptable","notices":[]}, + {"name":"tokens 499000+1000 in 1000000","sid":"s1","snapshot":{"captured_at":"@now-30","session_id":"s1","context_window":{"used_percentage":null,"remaining_percentage":80,"current_usage":{"input_tokens":100},"total_input_tokens":499000,"total_output_tokens":1000,"context_window_size":1000000},"cli_version":"2.1.200"},"zones":null,"word":"acceptable","notices":[]}, + {"name":"tokens 500000+1 in 1000000","sid":"s1","snapshot":{"captured_at":"@now-30","session_id":"s1","context_window":{"used_percentage":null,"remaining_percentage":80,"current_usage":{"input_tokens":100},"total_input_tokens":500000,"total_output_tokens":1,"context_window_size":1000000},"cli_version":"2.1.200"},"zones":null,"word":"dumb","notices":[]}, {"name":"tokens 999000+1000 in 1000000","sid":"s1","snapshot":{"captured_at":"@now-30","session_id":"s1","context_window":{"used_percentage":null,"remaining_percentage":80,"current_usage":{"input_tokens":100},"total_input_tokens":999000,"total_output_tokens":1000,"context_window_size":1000000},"cli_version":"2.1.200"},"zones":null,"word":"dumb","notices":[]}, {"name":"tokens 1000000+1 in 1000000","sid":"s1","snapshot":{"captured_at":"@now-30","session_id":"s1","context_window":{"used_percentage":null,"remaining_percentage":80,"current_usage":{"input_tokens":100},"total_input_tokens":1000000,"total_output_tokens":1,"context_window_size":1000000},"cli_version":"2.1.200"},"zones":null,"word":"unknown","notices":[]}, {"name":"window 500000 takes the 200000 class","sid":"s1","snapshot":{"captured_at":"@now-30","session_id":"s1","context_window":{"used_percentage":null,"remaining_percentage":80,"current_usage":{"input_tokens":100},"total_input_tokens":110000,"total_output_tokens":0,"context_window_size":500000},"cli_version":"2.1.200"},"zones":null,"word":"acceptable","notices":[]}, diff --git a/plugins/context-guard/scripts/context-zone.sh b/plugins/context-guard/scripts/context-zone.sh index 3ae893e045..4b3138de7c 100755 --- a/plugins/context-guard/scripts/context-zone.sh +++ b/plugins/context-guard/scripts/context-zone.sh @@ -55,7 +55,7 @@ # window-class token bands over occupancy: # # window class 200000: smart ≤ 100000 < acceptable ≤ 150000 < dumb -# window class 1000000: smart ≤ 128000 < acceptable ≤ 250000 < dumb +# window class 1000000: smart ≤ 128000 < acceptable ≤ 500000 < dumb # # All are declared judgment defaults, NOT doc- or benchmark-derived # constants (anchors and provenance are recorded in the reader contract). @@ -66,7 +66,7 @@ # "acceptable_max_used_percentage": 75, # "token_bands": { # "200000": { "smart_max_tokens": 100000, "acceptable_max_tokens": 150000 }, -# "1000000": { "smart_max_tokens": 128000, "acceptable_max_tokens": 250000 } +# "1000000": { "smart_max_tokens": 128000, "acceptable_max_tokens": 500000 } # } # } # @@ -94,7 +94,7 @@ DEFAULT_ACCEPTABLE_MAX=75 # [class, smart_max, acceptable_max] rows, ascending class order. JSON rather # than whitespace rows because the bands are handed to the snapshot pass as # data, so the comparison happens there instead of in a separate awk process. -DEFAULT_TOKEN_BANDS='[[200000,100000,150000],[1000000,128000,250000]]' +DEFAULT_TOKEN_BANDS='[[200000,100000,150000],[1000000,128000,500000]]' unknown() { printf 'unknown\n' @@ -199,7 +199,7 @@ if [[ -e "$zones" ]]; then acceptable_max=${zpct#* } fi if [[ "$ztb" == "invalid" ]]; then - printf 'context-guard: zones.json token_bands malformed — using shipped default token bands (200000:100000/150000, 1000000:128000/250000)\n' >&2 + printf 'context-guard: zones.json token_bands malformed — using shipped default token bands (200000:100000/150000, 1000000:128000/500000)\n' >&2 elif [[ "$ztb" != "absent" ]]; then token_bands=$ztb fi diff --git a/plugins/context-guard/scripts/context-zone.test.sh b/plugins/context-guard/scripts/context-zone.test.sh index 865bb6f8ed..c5532b80cb 100755 --- a/plugins/context-guard/scripts/context-zone.test.sh +++ b/plugins/context-guard/scripts/context-zone.test.sh @@ -179,7 +179,8 @@ HT="$WORK/h-token" # Token shape stands alone when used_percentage is null but tokens are valid. write_snapshot_tok "$HT" t1 null 110000 10000 1000000 && expect "tokens alone: occ=120k on 1M" smart "$HT" t1 write_snapshot_tok "$HT" t2 null 180000 20000 1000000 && expect "tokens alone: occ=200k on 1M" acceptable "$HT" t2 -write_snapshot_tok "$HT" t3 null 240000 10001 1000000 && expect "tokens alone: occ=250001 on 1M" dumb "$HT" t3 +write_snapshot_tok "$HT" t4 null 260000 0 1000000 && expect "tokens alone: occ=260000 (26%, #6644) on 1M" acceptable "$HT" t4 +write_snapshot_tok "$HT" t3 null 490000 10001 1000000 && expect "tokens alone: occ=500001 on 1M" dumb "$HT" t3 # Shipped 200k-class edges, uppers inclusive. write_snapshot_tok "$HT" t4 null 90000 10000 200000 && expect "200k class: occ=100000 (smart edge)" smart "$HT" t4 write_snapshot_tok "$HT" t5 null 140000 10000 200000 && expect "200k class: occ=150000 (acceptable edge)" acceptable "$HT" t5 diff --git a/plugins/context-guard/skills/setup/SKILL.md b/plugins/context-guard/skills/setup/SKILL.md index f81391e906..adcfa3aaa3 100644 --- a/plugins/context-guard/skills/setup/SKILL.md +++ b/plugins/context-guard/skills/setup/SKILL.md @@ -155,7 +155,7 @@ The `defaults` argument changes only how a present file is treated: "acceptable_max_used_percentage": 75, "token_bands": { "200000": { "smart_max_tokens": 100000, "acceptable_max_tokens": 150000 }, - "1000000": { "smart_max_tokens": 128000, "acceptable_max_tokens": 250000 } + "1000000": { "smart_max_tokens": 128000, "acceptable_max_tokens": 500000 } } } ``` diff --git a/plugins/plugin-quality/scripts/context-zone.fixtures.mjs b/plugins/plugin-quality/scripts/context-zone.fixtures.mjs index 815c045ab1..62525c73ae 100644 --- a/plugins/plugin-quality/scripts/context-zone.fixtures.mjs +++ b/plugins/plugin-quality/scripts/context-zone.fixtures.mjs @@ -40,8 +40,9 @@ export default [ {"name":"tokens 200000+1 in 200000","sid":"s1","snapshot":{"captured_at":"@now-30","session_id":"s1","context_window":{"used_percentage":null,"remaining_percentage":80,"current_usage":{"input_tokens":100},"total_input_tokens":200000,"total_output_tokens":1,"context_window_size":200000},"cli_version":"2.1.200"},"zones":null,"word":"unknown","notices":[]}, {"name":"tokens 118000+10000 in 1000000","sid":"s1","snapshot":{"captured_at":"@now-30","session_id":"s1","context_window":{"used_percentage":null,"remaining_percentage":80,"current_usage":{"input_tokens":100},"total_input_tokens":118000,"total_output_tokens":10000,"context_window_size":1000000},"cli_version":"2.1.200"},"zones":null,"word":"smart","notices":[]}, {"name":"tokens 128000+1 in 1000000","sid":"s1","snapshot":{"captured_at":"@now-30","session_id":"s1","context_window":{"used_percentage":null,"remaining_percentage":80,"current_usage":{"input_tokens":100},"total_input_tokens":128000,"total_output_tokens":1,"context_window_size":1000000},"cli_version":"2.1.200"},"zones":null,"word":"acceptable","notices":[]}, - {"name":"tokens 249000+1000 in 1000000","sid":"s1","snapshot":{"captured_at":"@now-30","session_id":"s1","context_window":{"used_percentage":null,"remaining_percentage":80,"current_usage":{"input_tokens":100},"total_input_tokens":249000,"total_output_tokens":1000,"context_window_size":1000000},"cli_version":"2.1.200"},"zones":null,"word":"acceptable","notices":[]}, - {"name":"tokens 250000+1 in 1000000","sid":"s1","snapshot":{"captured_at":"@now-30","session_id":"s1","context_window":{"used_percentage":null,"remaining_percentage":80,"current_usage":{"input_tokens":100},"total_input_tokens":250000,"total_output_tokens":1,"context_window_size":1000000},"cli_version":"2.1.200"},"zones":null,"word":"dumb","notices":[]}, + {"name":"tokens 260000 in 1000000 (26% used, #6644) is not dumb","sid":"s1","snapshot":{"captured_at":"@now-30","session_id":"s1","context_window":{"used_percentage":26,"remaining_percentage":74,"current_usage":{"input_tokens":100},"total_input_tokens":260000,"total_output_tokens":0,"context_window_size":1000000},"cli_version":"2.1.200"},"zones":null,"word":"acceptable","notices":[]}, + {"name":"tokens 499000+1000 in 1000000","sid":"s1","snapshot":{"captured_at":"@now-30","session_id":"s1","context_window":{"used_percentage":null,"remaining_percentage":80,"current_usage":{"input_tokens":100},"total_input_tokens":499000,"total_output_tokens":1000,"context_window_size":1000000},"cli_version":"2.1.200"},"zones":null,"word":"acceptable","notices":[]}, + {"name":"tokens 500000+1 in 1000000","sid":"s1","snapshot":{"captured_at":"@now-30","session_id":"s1","context_window":{"used_percentage":null,"remaining_percentage":80,"current_usage":{"input_tokens":100},"total_input_tokens":500000,"total_output_tokens":1,"context_window_size":1000000},"cli_version":"2.1.200"},"zones":null,"word":"dumb","notices":[]}, {"name":"tokens 999000+1000 in 1000000","sid":"s1","snapshot":{"captured_at":"@now-30","session_id":"s1","context_window":{"used_percentage":null,"remaining_percentage":80,"current_usage":{"input_tokens":100},"total_input_tokens":999000,"total_output_tokens":1000,"context_window_size":1000000},"cli_version":"2.1.200"},"zones":null,"word":"dumb","notices":[]}, {"name":"tokens 1000000+1 in 1000000","sid":"s1","snapshot":{"captured_at":"@now-30","session_id":"s1","context_window":{"used_percentage":null,"remaining_percentage":80,"current_usage":{"input_tokens":100},"total_input_tokens":1000000,"total_output_tokens":1,"context_window_size":1000000},"cli_version":"2.1.200"},"zones":null,"word":"unknown","notices":[]}, {"name":"window 500000 takes the 200000 class","sid":"s1","snapshot":{"captured_at":"@now-30","session_id":"s1","context_window":{"used_percentage":null,"remaining_percentage":80,"current_usage":{"input_tokens":100},"total_input_tokens":110000,"total_output_tokens":0,"context_window_size":500000},"cli_version":"2.1.200"},"zones":null,"word":"acceptable","notices":[]}, diff --git a/plugins/plugin-quality/scripts/context-zone.sh b/plugins/plugin-quality/scripts/context-zone.sh index 3ae893e045..4b3138de7c 100755 --- a/plugins/plugin-quality/scripts/context-zone.sh +++ b/plugins/plugin-quality/scripts/context-zone.sh @@ -55,7 +55,7 @@ # window-class token bands over occupancy: # # window class 200000: smart ≤ 100000 < acceptable ≤ 150000 < dumb -# window class 1000000: smart ≤ 128000 < acceptable ≤ 250000 < dumb +# window class 1000000: smart ≤ 128000 < acceptable ≤ 500000 < dumb # # All are declared judgment defaults, NOT doc- or benchmark-derived # constants (anchors and provenance are recorded in the reader contract). @@ -66,7 +66,7 @@ # "acceptable_max_used_percentage": 75, # "token_bands": { # "200000": { "smart_max_tokens": 100000, "acceptable_max_tokens": 150000 }, -# "1000000": { "smart_max_tokens": 128000, "acceptable_max_tokens": 250000 } +# "1000000": { "smart_max_tokens": 128000, "acceptable_max_tokens": 500000 } # } # } # @@ -94,7 +94,7 @@ DEFAULT_ACCEPTABLE_MAX=75 # [class, smart_max, acceptable_max] rows, ascending class order. JSON rather # than whitespace rows because the bands are handed to the snapshot pass as # data, so the comparison happens there instead of in a separate awk process. -DEFAULT_TOKEN_BANDS='[[200000,100000,150000],[1000000,128000,250000]]' +DEFAULT_TOKEN_BANDS='[[200000,100000,150000],[1000000,128000,500000]]' unknown() { printf 'unknown\n' @@ -199,7 +199,7 @@ if [[ -e "$zones" ]]; then acceptable_max=${zpct#* } fi if [[ "$ztb" == "invalid" ]]; then - printf 'context-guard: zones.json token_bands malformed — using shipped default token bands (200000:100000/150000, 1000000:128000/250000)\n' >&2 + printf 'context-guard: zones.json token_bands malformed — using shipped default token bands (200000:100000/150000, 1000000:128000/500000)\n' >&2 elif [[ "$ztb" != "absent" ]]; then token_bands=$ztb fi diff --git a/plugins/plugin-quality/scripts/context-zone.test.sh b/plugins/plugin-quality/scripts/context-zone.test.sh index 865bb6f8ed..c5532b80cb 100755 --- a/plugins/plugin-quality/scripts/context-zone.test.sh +++ b/plugins/plugin-quality/scripts/context-zone.test.sh @@ -179,7 +179,8 @@ HT="$WORK/h-token" # Token shape stands alone when used_percentage is null but tokens are valid. write_snapshot_tok "$HT" t1 null 110000 10000 1000000 && expect "tokens alone: occ=120k on 1M" smart "$HT" t1 write_snapshot_tok "$HT" t2 null 180000 20000 1000000 && expect "tokens alone: occ=200k on 1M" acceptable "$HT" t2 -write_snapshot_tok "$HT" t3 null 240000 10001 1000000 && expect "tokens alone: occ=250001 on 1M" dumb "$HT" t3 +write_snapshot_tok "$HT" t4 null 260000 0 1000000 && expect "tokens alone: occ=260000 (26%, #6644) on 1M" acceptable "$HT" t4 +write_snapshot_tok "$HT" t3 null 490000 10001 1000000 && expect "tokens alone: occ=500001 on 1M" dumb "$HT" t3 # Shipped 200k-class edges, uppers inclusive. write_snapshot_tok "$HT" t4 null 90000 10000 200000 && expect "200k class: occ=100000 (smart edge)" smart "$HT" t4 write_snapshot_tok "$HT" t5 null 140000 10000 200000 && expect "200k class: occ=150000 (acceptable edge)" acceptable "$HT" t5 diff --git a/plugins/plugin-quality/scripts/zones-inline-drift.test.sh b/plugins/plugin-quality/scripts/zones-inline-drift.test.sh index 96a8a48a78..3ae0875e84 100755 --- a/plugins/plugin-quality/scripts/zones-inline-drift.test.sh +++ b/plugins/plugin-quality/scripts/zones-inline-drift.test.sh @@ -75,7 +75,7 @@ resolver_and_contract "snapshot path pattern" "~/.claude/context-guard/context/< resolver_and_contract "zones file path" "~/.claude/context-guard/zones.json" resolver_and_contract "percentage floor" "smart ≤ 50 < acceptable ≤ 75 < dumb" resolver_and_contract "200k-class token band" "200000: smart ≤ 100000 < acceptable ≤ 150000 < dumb" -resolver_and_contract "1M-class token band" "1000000: smart ≤ 128000 < acceptable ≤ 250000 < dumb" +resolver_and_contract "1M-class token band" "1000000: smart ≤ 128000 < acceptable ≤ 500000 < dumb" resolver_and_contract "occupancy definition" "total_input_tokens + total_output_tokens" resolver_and_contract "token-shape version floor" "cli_version" resolver_and_contract "token-shape version floor value" "2.1.132" From 0f0b98eac3bde5c017820d35c9fd6b656c7c20f2 Mon Sep 17 00:00:00 2001 From: Kyle Sexton <153232337+kyle-sexton@users.noreply.github.com> Date: Fri, 9 Oct 2026 11:15:41 -0400 Subject: [PATCH 2/3] test(context-guard): drop the tracker reference from the 1M-band test comment The comment-hygiene scan in lint-repo flags issue references in code comments. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01PCiAaEVSXdj1VnWVXtjyu2 --- plugins/context-guard/hooks/context-guard.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/context-guard/hooks/context-guard.test.ts b/plugins/context-guard/hooks/context-guard.test.ts index 566657436c..d6512276f7 100644 --- a/plugins/context-guard/hooks/context-guard.test.ts +++ b/plugins/context-guard/hooks/context-guard.test.ts @@ -421,8 +421,8 @@ test('zones.json: an extra threshold gets its approach line and its line once pe ]) }) -// Issue #6644: on a 1000000-token window with the shipped bands, 26% used (260000 tokens) read -// dumb. The reader contract's 1M row puts the dumb edge past 500000 tokens. +// On a 1000000-token window with the shipped bands, 26% used (260000 tokens) reads acceptable: +// the reader contract's 1M row puts the dumb edge past 500000 tokens. test('shipped bands, 1000000 window: 26% used announces acceptable, never dumb; 51% announces dumb', async ($, on) => { const { w } = world(on, { window: 1_000_000 }) expect(await walk($, w, [5, 26, 51])).toEqual([[], [crossing('acceptable')], [crossing('dumb')]]) From e5e69af19cda3493a98fc95efecb85cd6369a366 Mon Sep 17 00:00:00 2001 From: Kyle Sexton <153232337+kyle-sexton@users.noreply.github.com> Date: Fri, 9 Oct 2026 11:16:23 -0400 Subject: [PATCH 3/3] test(context-guard): give the 26%-of-1M resolver case its own snapshot id It reused t4, which the 200k-class case below also uses. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01PCiAaEVSXdj1VnWVXtjyu2 --- plugins/context-guard/scripts/context-zone.test.sh | 2 +- plugins/plugin-quality/scripts/context-zone.test.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/context-guard/scripts/context-zone.test.sh b/plugins/context-guard/scripts/context-zone.test.sh index c5532b80cb..b8f1b2b3ad 100755 --- a/plugins/context-guard/scripts/context-zone.test.sh +++ b/plugins/context-guard/scripts/context-zone.test.sh @@ -179,7 +179,7 @@ HT="$WORK/h-token" # Token shape stands alone when used_percentage is null but tokens are valid. write_snapshot_tok "$HT" t1 null 110000 10000 1000000 && expect "tokens alone: occ=120k on 1M" smart "$HT" t1 write_snapshot_tok "$HT" t2 null 180000 20000 1000000 && expect "tokens alone: occ=200k on 1M" acceptable "$HT" t2 -write_snapshot_tok "$HT" t4 null 260000 0 1000000 && expect "tokens alone: occ=260000 (26%, #6644) on 1M" acceptable "$HT" t4 +write_snapshot_tok "$HT" t26 null 260000 0 1000000 && expect "tokens alone: occ=260000 (26%, #6644) on 1M" acceptable "$HT" t26 write_snapshot_tok "$HT" t3 null 490000 10001 1000000 && expect "tokens alone: occ=500001 on 1M" dumb "$HT" t3 # Shipped 200k-class edges, uppers inclusive. write_snapshot_tok "$HT" t4 null 90000 10000 200000 && expect "200k class: occ=100000 (smart edge)" smart "$HT" t4 diff --git a/plugins/plugin-quality/scripts/context-zone.test.sh b/plugins/plugin-quality/scripts/context-zone.test.sh index c5532b80cb..b8f1b2b3ad 100755 --- a/plugins/plugin-quality/scripts/context-zone.test.sh +++ b/plugins/plugin-quality/scripts/context-zone.test.sh @@ -179,7 +179,7 @@ HT="$WORK/h-token" # Token shape stands alone when used_percentage is null but tokens are valid. write_snapshot_tok "$HT" t1 null 110000 10000 1000000 && expect "tokens alone: occ=120k on 1M" smart "$HT" t1 write_snapshot_tok "$HT" t2 null 180000 20000 1000000 && expect "tokens alone: occ=200k on 1M" acceptable "$HT" t2 -write_snapshot_tok "$HT" t4 null 260000 0 1000000 && expect "tokens alone: occ=260000 (26%, #6644) on 1M" acceptable "$HT" t4 +write_snapshot_tok "$HT" t26 null 260000 0 1000000 && expect "tokens alone: occ=260000 (26%, #6644) on 1M" acceptable "$HT" t26 write_snapshot_tok "$HT" t3 null 490000 10001 1000000 && expect "tokens alone: occ=500001 on 1M" dumb "$HT" t3 # Shipped 200k-class edges, uppers inclusive. write_snapshot_tok "$HT" t4 null 90000 10000 200000 && expect "200k class: occ=100000 (smart edge)" smart "$HT" t4