fix(context-guard): describe the 0.5.0 audience split in the reader contract - #3040
Conversation
…ontract The zone-crossing hooks section still called the advisory injection "a minimal generic continuation tree plus a presence-gated pointer to session-flow:workflow's router" — one undifferentiated block, which is the shape from before 0.5.0 moved the menu off the model channel. Every reader of the seam was therefore told the model receives an exit menu it has not received since 0.5.0. The section now states what each channel actually carries: additionalContext gets the determination plus the counter-steer (and the durable-note addendum in dumb), systemMessage gets the same crossing plus the continuation menu and the router pointer, and neither the menu nor the pointer ever reaches the model channel. The I23 rationale sits where the split is described, including why the model channel says continuation is the operator's call but never that the operator has seen the menu. Verified against hooks/zone-crossing-inject.sh's actual emission rather than its header summary. Swept the rest of the contract for pre-0.5.0 injection prose: the other injection mentions describe hysteresis and the compaction marker, and are accurate. Documentation only; no behavior change. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QbfCrj3X9FfGL7VRZYmrn4
|
Claude finished @kyle-sexton's task in 44s —— View job Security Review —
|
The new entry replaced the 0.7.14 heading instead of being inserted above it, so that release's notes were absorbed into 0.7.15 — caught by changelog-parity-gate's absorbed-heading check, which is exactly the defect it exists to find. The heading is back and both sections own their own notes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QbfCrj3X9FfGL7VRZYmrn4
|
Last security-reviewed head: |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ddf5bc6d8d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Claude finished @kyle-sexton's task in 2m 2s —— View job Code review complete
No blocking findings. This is a documentation-only fix and it holds up against the implementation it describes. What I checked:
Nothing else in the diff (the Branch: |
|
Claude has reviewed this PR 1 time. The lane skips further automatic reviews after 5; deleting this comment resets the count. |
…zone interplay (#3042) Closes #2995 ## Summary The reader contract stated that no auto-compaction threshold is documented and stopped there, which reads as "the trigger is opaque". The *default* is unpublished, but the trigger is operator-tunable — and none of the surfaces that tune it appeared anywhere in the plugin. Consumers tuning zone bands therefore had no guidance on how the bands relate to the auto-compact trigger, and the PostCompact marker's `trigger` field had documented values but no consumer guidance. Documentation only; no behavior change. context-guard 0.7.15 → 0.7.16. ## Fix **`reference/reader-contract.md` — the four auto-compact config surfaces.** Verified 2026-08-17 against two independent pools (the official settings reference and the shipped binary's schema strings, v2.1.233), and re-verified 2026-08-19 against the live settings, env-vars, and model-config pages: | Surface | Kind | What it does | |---|---|---| | `autoCompactWindow` | `settings.json` | Tokens, `100000`–`1000000`; **no numeric default** (model-tuned when unset). Written by `/autocompact`; `--autocompact` sets it for one launch and, unlike the command, isn't preempted by a higher-priority settings scope. | | `CLAUDE_CODE_AUTO_COMPACT_WINDOW` | environment | Same units; **highest precedence**. Plain integer only — `500k` reads as `500` and clamps to the 100K minimum. | | `CLAUDE_AUTOCOMPACT_PCT_OVERRIDE` | environment | Percentage (1–100) of the auto-compact window at which compaction triggers; **lower-only**. Applies to subagents too. | | `autoCompactEnabled` / `DISABLE_AUTO_COMPACT` | `settings.json` (default `true`) / environment | Off switch. (`DISABLE_COMPACT` is recorded as binary-strings-sourced and **unconfirmed by docs** as of 2026-08-19.) | **The bands-below-the-trigger rule, with rationale.** Whatever the trigger resolves to, `dumb` should be reached first: auto-compact offers no steering hook, so a firing means the boundary decision was reached too late. **Comparisons are normalized into the percentage shape, never occupancy.** The contract already forbids equating its two zone shapes; the new guidance honors that explicitly. A configured window is a fill threshold in the percentage shape's input-token accounting, not the token shape's occupancy. Worked example: a 400,000-token window on a 1M-class model puts the trigger at **40% of the full window — inside the shipped `smart` band (≤ 50)**, so auto-compact fires while every zone still reads green. Recorded with the docs' own consequence: `used_percentage` **always** measures against the model's full context window, so a lowered window stops being visible in the percentage at all. **Only the diagnostic half of the house stance is adopted.** The prescription that usually travels with it (disable auto-compact) is explicitly rejected: unattended cloud and autonomous sessions have no human at the boundary, and a degraded continuation beats a hard stall at the window. Auto-compact stays enabled as the last-resort safety net beneath the instrumented ladder. **The Boris §64 rot figure (300–400k; `CLAUDE_CODE_AUTO_COMPACT_WINDOW=400000`) is recorded as a named practitioner anchor, never an adopted number** — carrying its own amendment, that the calibration is Opus 4.7-era and the Opus 5 prompting guide (verified 2026-08-08) removes its degradation premise. Consistent with claim-ladder bucket ii. **The marker's `trigger` field now has consumer guidance.** Consumers deliberately do *not* differentiate on it — evidence degradation is trigger-independent, holding identically for a steered `/compact` and an auto-compact. The field is captured anyway so the stance is falsifiable: it is the observable for the track-on-event condition recorded in `docs/upstream/aihero-course.md` lane 3. **A dated refinement to the adjacent "no documented threshold" paragraph.** Upstream is now more specific than the "when approaching context limits" phrasing that paragraph quotes: an unconfigured session compacts **at** the model's context limit, with five enumerated earlier-firing exceptions — including Sonnet 5 at "about 967K tokens by default". The conclusion is unchanged (no percentage default is published, so the bands stay declared judgment defaults), but the trigger is now documented as model- and environment-dependent, which is why no single band set is correct everywhere. **`README.md`** gains a pointer naming the four surfaces, the below-the-trigger rule, and the full-window percentage caveat, deferring to the contract as SSOT. ## Verification Every claim about shipped behavior was checked against the hooks' **emitted strings**, not their header comments: `hooks/post-compact-mark.sh` regex-captures `manual|auto`, defaults `unknown`, and writes the marker unconditionally (no boundary-timed carve-out), matching what the contract now states. Every upstream claim was checked against a live fetch of the primary page, not from memory. Full local gate, re-run after each of the three commits: - `scripts/validate-plugins.sh` — all manifests + catalog pass - `generate-catalog.mjs --check` / `generate-cheatsheet.mjs --check` — both in sync - `check-changelog-parity.sh` all four modes — `--check`, `--check-order`, `--check-bump origin/main`, `--check-preserved origin/main` (**40 headings compared, all preserved** — the entry was inserted above `## [0.7.15]`, not over it) - `check-changed-skills.sh origin/main` — no skills touched - `markdownlint-cli2` on every touched file — 0 issues - `typos` on `plugins/context-guard/` — clean - Test suites of everything the change could affect: `zones-inline-drift.test.sh` 11/0, `context-zone.test.sh` 73/0, `statusline-tee.test.sh` 47/0, `statusline-shim.test.sh` 36/0 — **167 passed, 0 failed**. The drift suite matters here specifically: the reader contract's operable-floor values are inlined by consumers, and none of them were altered. ### Review rounds Four findings raised across three review passes, all verified against primary sources before acting, all fixed and resolved: 1. *(Codex, P2)* The worked example equated occupancy with the trigger's input-token accounting — breaking the contract's own "never equate them without normalizing" rule. Fixed in `a4168554`. 2. *(Claude, Important)* The surface table omitted `CLAUDE_AUTOCOMPACT_PCT_OVERRIDE`. Confirmed against a live fetch and added in `a4168554`. 3. *(Claude, Important)* The refinement named three of upstream's five default-threshold exceptions, dropping Sonnet 5's. Fixed in `7c88cee5`. 4. *(Claude, Nit)* `auto-compact` split across a soft line break rendered as "auto- compact". Fixed in `7c88cee5`, along with a pre-existing instance of the same defect (`hard` / `-stops`) a few lines above. ## Related - Refs #2901 (lane 3, the verification that produced verdicts C1–C3) - Refs #2973 (adjacent reader-contract drift fix, merged as #3040) - Refs #2994 (the durable AI Hero course roadmap this item sits in) --- 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01QbfCrj3X9FfGL7VRZYmrn4 --------- Co-authored-by: Claude <noreply@anthropic.com>
Closes #2973
Summary
reference/reader-contract.md's zone-crossing hooks section described the advisory injection as it worked before the 0.5.0 audience split — as one undifferentiated block carrying "a minimal generic continuation tree plus a presence-gated pointer tosession-flow:workflow's router". Since 0.5.0 the menu has been operator-channel only, so the reference told every reader of the seam that the model receives an exit menu it has not received for many versions. Surfaced by the fresh-context verifier during AI Hero course lane 2 (#2900).Fix
The section now states what each channel actually carries, and why:
additionalContext) — the determination plus the counter-steer (the reading is a measurement rather than an instruction; real degradation shows up in the model's own output, never in a zone word; keep working the task in hand), plus the durable-note addendum indumb.systemMessage) — the same crossing plus the continuation menu that is the human's call (continue //clear/ handoff-then-/clear, with the hand-written resume note as the standalone-install fallback //compact) and the presence-gated router pointer.claude-config,reference/criteria.md): a menu injected into model context manufactures the model's own initiative to stop, summarize, or hand off, and I23's Remediate clause prescribes exactly this shape — counter-steer plainly stated, reassurance rather than an exit menu.Verification
hooks/zone-crossing-inject.shbuildsguidance(model) andoperator(operator) separately and emits both viahook::emit_channels— the rewritten prose tracks those two strings, including thedumb-only addendum and the option-3 manual fallback.grepover the whole contract for injection/menu/channel prose found the content described in exactly one place (the section rewritten here). The other injection mentions cover hysteresis and the compaction marker and are accurate — no other section describes pre-0.5.0 behavior.bash plugins/context-guard/hooks/zone-crossing-inject.test.sh— PASS=53 FAIL=0 (hook untouched; run because this doc is its contract).bash scripts/validate-plugins.sh— all manifests + catalog validated;generate-catalog.mjs --checkin sync.bash scripts/check-changelog-parity.sh --check/--check-bump origin/main/--check-order— all green.bash scripts/check-changed-skills.sh origin/main— no changed skills underplugins/*/skills/(this is a plugin-levelreference/file).bash scripts/check-cross-plugin-source-drift.sh— exit 0.npx markdownlint-cli2on both changed markdown files — 0 issues;typosclean.context-guard0.7.14 → 0.7.15 (patch — documentation accuracy, no behavior change).Related
docs/upstream/aihero-course.mdlane 2 rows🤖 Generated with Claude Code
https://claude.ai/code/session_01QbfCrj3X9FfGL7VRZYmrn4
Generated by Claude Code