Skip to content

docs(context-guard): document the verified auto-compact surfaces and zone interplay - #3042

Merged
kyle-sexton merged 3 commits into
mainfrom
claude/pocock-steering-course-00zkvd
Aug 19, 2026
Merged

docs(context-guard): document the verified auto-compact surfaces and zone interplay#3042
kyle-sexton merged 3 commits into
mainfrom
claude/pocock-steering-course-00zkvd

Conversation

@kyle-sexton

@kyle-sexton kyle-sexton commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

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, 1000001000000; 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


🤖 Generated with Claude Code

https://claude.ai/code/session_01QbfCrj3X9FfGL7VRZYmrn4

…zone interplay

The reader contract stated that no auto-compaction threshold is documented and
stopped there, which read 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.

Name all three in the reader contract, each verified 2026-08-17 against two
independent pools (the official settings reference and the shipped binary's
schema strings, v2.1.233):

- autoCompactWindow (settings.json, 100,000-1,000,000 tokens, no numeric
  default; written by /autocompact, one-launch --autocompact flag)
- CLAUDE_CODE_AUTO_COMPACT_WINDOW (environment, highest precedence)
- autoCompactEnabled / DISABLE_AUTO_COMPACT (off switch, distinct from
  DISABLE_COMPACT)

Add the bands-below-the-trigger rule with its rationale: a firing means the
boundary decision was reached too late, since auto-compact offers no steering
hook. Only the diagnostic half of that stance is adopted — auto-compact stays
enabled as a last-resort safety net, because unattended sessions have no human
at the boundary and a degraded continuation beats a hard stall.

Record the vendored Boris section 64 rot figure as a named practitioner anchor
carrying its Opus 5 amendment, never as an adopted number.

Give the evidence-degraded marker's trigger field consumer guidance: the values
were documented, but not what to do with them. Consumers deliberately do not
differentiate on trigger (evidence degradation is trigger-independent); the
track-on-event condition that would revisit that stance is recorded, with the
field itself as the observable.

Documentation only; no behavior change. Verified against the hooks' emitted
strings rather than their header comments.

Closes #2995

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QbfCrj3X9FfGL7VRZYmrn4
@claude

claude Bot commented Aug 19, 2026

Copy link
Copy Markdown

Claude finished @kyle-sexton's task in 4m 55s —— View job


Claude Code Review

  • Gather context (PR diff, CLAUDE.md, REVIEW.md)
  • Check skip gate — not applicable (open PR, not a draft, substantive 85-line doc change)
  • Review changed files for correctness/maintainability
  • Post findings

Scope: Documentation-only change (reader-contract.md, README.md, CHANGELOG.md, version bump in plugin.json). No code/behavior changes, so security-lane checks and most REVIEW.md "always check" items (audit logging, multi-record atomicity) don't apply here.

What I verified independently

I fetched the live upstream docs (code.claude.com/docs/en/settings, .../env-vars, .../model-config) to spot-check the factual claims in the new "three surfaces" table, rather than taking the PR's stated verification on faith. These all matched verbatim:

  • autoCompactWindowsettings.json key, 100,000–1,000,000 tokens, no numeric default, written by /autocompact / --autocompact.
  • CLAUDE_CODE_AUTO_COMPACT_WINDOW — highest precedence over the command, flag, and setting.
  • DISABLE_COMPACT vs DISABLE_AUTO_COMPACT — the "disables all compaction" distinction is accurate.
  • The Boris §64 anchor and its Opus 5 amendment cross-checks against plugins/playbooks/skills/boris/reference/autonomy.md:67-71 and the aihero-course lane-3 record.

Finding posted inline

One Important finding on reference/reader-contract.md:299: the "three surfaces govern it" table omits CLAUDE_AUTOCOMPACT_PCT_OVERRIDE, a live, currently-documented env var that also moves the effective auto-compact trigger (percentage-of-window based, rather than token-based). Since this section's whole premise is an exhaustively verified enumeration of what tunes the trigger, and the same collision risk this section warns about (bands landing at or above the trigger) applies equally to this variable, it looks like a real gap rather than a deliberate scope limit. Detail and a fix-it link are on the inline comment.

No other correctness or maintainability issues found — the changelog entry placement, version bump, cross-references to docs/upstream/aihero-course.md, and the hook-behavior claims about hooks/post-compact-mark.sh (unconditional marker write, manual|auto regex capture, unknown default) all check out against the current source.

@claude

claude Bot commented Aug 19, 2026

Copy link
Copy Markdown

Claude finished @kyle-sexton's task in 33s —— View job


Security review — /review:security-review

  • Gather context (PR is docs-only: reader-contract.md, README.md, CHANGELOG.md, plugin.json)
  • Invoke /review:security-review and follow its instructions
  • Post findings / summary

Skip gate triggered — no security-relevant surface.

All four changed files are documentation/metadata:

  • plugins/context-guard/reference/reader-contract.md — new prose describing auto-compact config surfaces and consumer guidance
  • plugins/context-guard/README.md — a pointer sentence to the above
  • plugins/context-guard/CHANGELOG.md — new changelog entry
  • plugins/context-guard/.claude-plugin/plugin.json — version bump 0.7.150.7.16

No code, scripts, hooks, or GitHub Actions workflows are touched (git diff origin/main...HEAD confirms only these 4 files, +85/-2). There is no injection surface, no credential/token handling, no permission or trigger change, and no supply-chain-relevant dependency/action pin change. This matches the review's skip gate ("Change has no security-relevant surface after reading the diff") — nothing to report.

@github-actions

Copy link
Copy Markdown

Last security-reviewed head: da0fdc0845a6d5dc5a46a5ffb4acade28f10873f. On the next push, the relevance gate compares only the commits since this SHA; delete this comment to force a full re-review.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: da0fdc0845

ℹ️ 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".

Comment thread plugins/context-guard/reference/reader-contract.md Outdated
Comment thread plugins/context-guard/reference/reader-contract.md Outdated
@github-actions

github-actions Bot commented Aug 19, 2026

Copy link
Copy Markdown

Claude has reviewed this PR 3 times. The lane skips further automatic reviews after 5; deleting this comment resets the count.

…band comparison

Two review findings on #3042, both verified against live docs before acting.

1. The enumeration was incomplete. CLAUDE_AUTOCOMPACT_PCT_OVERRIDE is a live
   documented env var that moves the same trigger — a percentage (1-100) of the
   auto-compact window, lower-only, applying to subagents as well as the main
   conversation. Added as a fourth row; "three surfaces" corrected throughout.

2. The worked example equated quantities this very contract forbids equating.
   It compared a 400000-token window against the 400000 occupancy band, but
   occupancy is input+output and answers distance to quality loss, while the
   trigger is a fill threshold in the percentage shape's input-token accounting.
   The example now normalizes: a 400000-token window on a 1M-class model puts
   the trigger at 40% of the full window, inside the shipped smart band, so
   auto-compact fires while every zone still reads green. That is both correct
   and a sharper hazard than the original claim.

The re-verification surfaced two further facts worth recording:

- used_percentage always measures against the model's FULL context window, so
  once the auto-compact window is lowered the percentage no longer indicates
  when compaction will run. Directly load-bearing for a contract about reading
  that field.
- Upstream is now more specific than the "when approaching context limits"
  phrasing the existing paragraph quotes: unconfigured sessions compact at the
  model's context limit, with enumerated earlier-firing exceptions. A percentage
  default is implied by the new env var but still unpublished as a number, so
  the bands stay declared judgment defaults — but the trigger is model- and
  environment-dependent, so no single band set is correct everywhere.

Also records the env var's plain-integer-only parsing (500k reads as 500 and
clamps to the 100K minimum) and that DISABLE_COMPACT is binary-strings-sourced,
not confirmed on the env-vars page as of 2026-08-19.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QbfCrj3X9FfGL7VRZYmrn4
@claude

claude Bot commented Aug 19, 2026

Copy link
Copy Markdown

Claude finished @kyle-sexton's task in 5m 35s —— View job


Claude Code Review

  • Gather context (PR diff for the new commit da0fdc0..a416855, prior review threads, CLAUDE.md)
  • Independently verify the fix commit's new factual claims against live upstream docs
  • Review changed files for correctness/maintainability
  • Post findings

Scope: this push (a416855) is the fix commit addressing the two prior reviewers' feedback on da0fdc0 — Codex's percentage/occupancy conflation finding and my own earlier "missing fourth surface" finding. I reviewed that diff specifically (git diff da0fdc0..a416855), not the whole PR again, since the earlier content was already reviewed at da0fdc0.

Independent verification

I fetched the live docs (code.claude.com/docs/en/settings, .../env-vars, .../model-config, including the raw .md source for the env-var table to rule out a paraphrase error) rather than trusting the PR's stated verification. Everything new in this commit checked out except one completeness gap, and I also spotted an unrelated prose bug:

Confirmed accurate, verbatim or near-verbatim:

  • CLAUDE_AUTOCOMPACT_PCT_OVERRIDE spelling and behavior (percentage 1–100, lower-only, subagents included) — confirmed against the raw doc table, since a summarized fetch of the same page briefly hallucinated a CLAUDE_CODE_AUTOCOMPACT_PCT_OVERRIDE spelling that isn't real.
  • CLAUDE_CODE_AUTO_COMPACT_WINDOW's "500k reads as 500 and clamps to the 100K minimum" — verbatim from the env-vars page.
  • --autocompact's "not preempted by a higher-priority settings scope" (unlike /autocompact) — verbatim from model-config.
  • DISABLE_COMPACT correctly flagged as absent from the env-vars page as of 2026-08-19.
  • The normalized worked example: a 400,000-token window on a 1M model is 40% of the full window, inside the shipped smart band (≤ 50 per scripts/context-zone.sh) — arithmetic and band lookup both check out, and this correctly fixes the prior "exactly at the trigger" occupancy/percentage conflation.

Two findings posted inline:

  1. Nit (reader-contract.md:349) — "auto-compact" is split across a soft line break (auto- / compact), which GFM renders as "auto- compact" with a stray space.
  2. Important (reader-contract.md:290-299) — the new "enumerated exceptions" refinement names 3 of upstream's 5 documented exceptions to "compaction fires at the model's context limit" and omits that Sonnet 5 itself compacts at ~967K by default (below the 1M limit), per the docs' own "Sonnet 5 compacts at the threshold for its configuration" bullet.

No other correctness issues found in this commit — the CHANGELOG/README updates are consistent with the contract, no other file in the plugin still says "three surfaces," and markdown structure (headings, table columns) is intact.

Comment thread plugins/context-guard/reference/reader-contract.md Outdated
Comment thread plugins/context-guard/reference/reader-contract.md
…t compounds

Two review findings on #3042, both verified against the model-config page.

The refinement paragraph enumerated three of upstream's five documented
exceptions to "compaction fires at the model's context limit" and dropped
Sonnet 5's own. The docs state it compacts "at about 967K tokens by default" on
its 1M window — the one published number in the set, and worth naming precisely
because the paragraph exists to be more specific than the phrasing it replaces.
Recorded with the reading that matters here: at ~97% of the window it sits well
above the shipped dumb band, so unlike a lowered window it does not eat into the
bands-below-the-trigger margin.

Also rejoins "auto-compact" where it wrapped across a soft line break. GFM
collapses the newline to a space, so it rendered as "auto- compact". The same
defect existed pre-existing a few lines above, where "hard-stops" was split as
"hard" / "-stops"; fixed both, since leaving one repaired and one broken in
adjacent paragraphs would be worse than either.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QbfCrj3X9FfGL7VRZYmrn4
@claude

claude Bot commented Aug 19, 2026

Copy link
Copy Markdown

Claude finished @kyle-sexton's task in 1m 37s —— View job


Claude Code Review

  • Gather context (diff for the new commit a416855..7c88cee, prior review threads)
  • Independently verify the new commit's claims
  • Review changed files for correctness/maintainability
  • Post findings

Scope: This push (7c88cee) is the fix commit addressing the two remaining findings on a416855 — my own "Sonnet 5 exception missing" finding and my own "auto-compact hyphen split" nit. I reviewed that diff specifically (git diff a416855..7c88cee, touching CHANGELOG.md and reference/reader-contract.md only).

Independent verification

I re-fetched code.claude.com/docs/en/model-config directly rather than trust the PR's stated verification. Both new claims check out exactly:

  • "Default auto-compact thresholds" now lists Sonnet 5 as its own bullet: "Sonnet 5 compacts at the threshold for its configuration" — confirmed live on the docs page.
  • "Sonnet 5 context window" section: "Sessions auto-compact before the window fills, at about 967K tokens by default" — matches reader-contract.md:295-299 verbatim, including the derived "~97% of the window, above the shipped dumb band" framing, which is arithmetically correct (967/1000 ≈ 96.7%) and consistent with the file's own stated dumb band value.

Both prior findings are resolved

  1. Sonnet 5 exception — now the fifth enumerated exception alongside cloud sessions, the 200K-boundary combinations, CLAUDE_CODE_DISABLE_1M_CONTEXT=1, and unrecognized model IDs. The addition correctly explains why it doesn't change the bands (967K sits well above dumb) rather than just naming the number.
  2. auto-\ncompact split — reflowed; the line now reads "...shipped smart band (≤ 50), so auto-compact would fire..." with no mid-word break. I grepped the file for other split-hyphen line breaks (auto-$, hard$, etc.) and found none remaining.

Consistency check

  • README.md:61-62 already says "Four" implicitly by listing all four surfaces (autoCompactWindow, CLAUDE_CODE_AUTO_COMPACT_WINDOW, CLAUDE_AUTOCOMPACT_PCT_OVERRIDE, autoCompactEnabled/DISABLE_AUTO_COMPACT) — no stale "three surfaces" reference left anywhere in the plugin.
  • CHANGELOG.md's [0.7.16] entry was updated in the same commit to match the contract's new Sonnet 5 language and rewrapped prose — content is consistent between the two files.

No new issues found in this commit. Nothing further to report.

@kyle-sexton
kyle-sexton merged commit 606a308 into main Aug 19, 2026
51 checks passed
@kyle-sexton
kyle-sexton deleted the claude/pocock-steering-course-00zkvd branch August 19, 2026 21:02
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.

context-guard: document verified auto-compact-window interplay with zones

2 participants