remove(messages-cache-breakpoint): superseded by canonical content identity — DRAFT, stacks on #272, review alongside it - #281
Draft
Gunther-Schulz wants to merge 8 commits into
Conversation
Gunther-Schulz
force-pushed
the
pr/retire-messages-cache-breakpoint
branch
from
July 30, 2026 04:27
52ea721 to
7eb27a7
Compare
Contributor
Author
|
Rebased onto #272's new tip (c713d0e, the duplicate-suppression addition) — no changes to this PR's own commit; still stacks on #272, review alongside it. 🤖 Generated with Claude Code |
Gunther-Schulz
added a commit
to Gunther-Schulz/claude-code-cache-fix
that referenced
this pull request
Jul 30, 2026
…ls-less tree skips, not dies The static harvest.mjs import defeated the file's own slice-portability idiom: in trees carrying only the extension (upstream cnighswonger#272/cnighswonger#278/cnighswonger#281) the whole file failed at module load, so the real-pair check never reached the skip it was designed to hit. The reader now loads like replayTools — dynamically, inside the test — and the fixture branch requires it, so tools-less trees skip with COULD NOT VERIFY. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TcivCe2iLnKZxpB4qTXzEb
Gunther-Schulz
force-pushed
the
pr/retire-messages-cache-breakpoint
branch
from
July 30, 2026 12:37
7eb27a7 to
b07c0dc
Compare
Contributor
Author
|
Rebased onto the current #272 tip (force-with-lease; the retire commit rides on top unchanged as b07c0dc). Tests at the new base: 67 pass / 1 designed skip / 0 fail. Merge order dependency unchanged: this lands after #272. 🤖 Generated with Claude Code |
…story rewrites stop busting the cache Claude Code re-serializes <system-reminder> hook blocks inside otherwise-stable user messages later in the session — moving one into its own message or merging it into a neighbour — which edits history mid-prefix and re-bills everything after the edit (reported independently as anthropics/claude-code#76606; measured here as the splice/insert-mid class, ~40 kB re-billed per unmitigated hit on a real session). The extension keeps a per-conversation canonical model of the message history keyed by content identity (message-hash.mjs: content hash + occurrence ordinal — position-independent, so repeated identical reminders stay distinct). Incoming volatile blocks are pinned to their first-seen serialization: when CC re-shapes an old reminder, the forwarded bytes keep the canonical form and the prefix survives. A history that stops matching the model (compaction, true rewrites) resets honestly rather than forcing a stale canon — pins survive the reset, order assumptions do not. Gated off by default: CACHE_FIX_INSERTION_NORMALIZE=1 enables normalization, CACHE_FIX_VOLATILE_PIN=1 the pinning. State persists under the state dir and survives proxy restarts. Measured on live traffic (513-request session, 2026-07-28): every observed splice/insert-mid pair forwarded with 0 re-billed bytes; the canonical-order invariant, cross-request stability and sequence gates all report 0 violations over 2.5 GB of captures. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…lete the pin (anthropics/claude-code#76606) When CC migrates a hook reminder out of its tool_result into a standalone system message mid-history, the pin restores the first-seen inline form — but the migrated copy still forwarded, splicing the same content in twice (measured live: ~61 kB splice, 124k tokens re-billed on one turn). Now a standalone message whose wrapper-normalized bytes equal a live pinned block is suppressed: never forwarded, never given a canonical identity. Genuine changes (normalized bytes differ) still forward and reset per the existing rule; assistant-role messages are excluded on principle. Suppression is re-detected each request from the pin set — no new state file. One event line per suppression rides the insertion event log. The real-pair red-green check in the new test file needs the replay tooling and capture; in this slice it skips, and runs where the tools land (cnighswonger#276). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TZxGrF1LRBvmb7cFXmS2DH
…ture (slice of fork 2dfe0f0) Path-scoped slice of fork commit 2dfe0f0: only the insertion-suppression real-pair test and the pinned fixture it falls back to. The same commit's harvest-pin.test.mjs and mitigation-output-form.test.mjs changes belong to the verification-tools slice (cnighswonger#276) and are not part of this PR. Co-Authored-By: Claude opus-5 <noreply@anthropic.com>
…pinned blocks — the 587k's shape CC sometimes migrates ALL of a message's volatile blocks out together, joined into one standalone message (both hook reminders, wrapper-stripped, joined with "\n\n"), rather than one standalone per block. The existing single-block suppression set could never match that shape. Each pinned entry with >=2 volatile blocks now also registers a join-hash — its blocks' unwrapped texts, in wire order, joined with the one observed separator — and findSuppressibleDuplicate checks it as a second pass. No subset-merges, no speculative separators: only the one shape measured live (capture s-633915a8, msg863/864, and independently confirmed on a second real occurrence at msg640/641 the same session). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> (cherry picked from commit 78940a0)
…cate is payload (insertion slice of fork e0f8fcb) Path-scoped slice of fork commit e0f8fcb: the insertion-normalization tail guard and its tests. The same commit's output-guard assistant-terminal invariant (proxy/extensions/output-guard.mjs, test/output-guard.test.mjs) belongs to the output-guard slice (cnighswonger#278) and is not part of this PR. Co-Authored-By: Claude opus-5 <noreply@anthropic.com>
… fork da9bf8c Makes the file slice-portable: without tools/ the real-pair check now reaches its designed skip instead of dying at module load. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TcivCe2iLnKZxpB4qTXzEb
…test reads (fork b1f7c58) The merge-suppression test does a top-level read of this harvested, sanitized fixture (16KB, no addresses); without it the file dies at load. The fork-only exclusion list names only LEDGER-*.json — this fixture is public on the fork and rides with its test. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TcivCe2iLnKZxpB4qTXzEb
…entity messages-cache-breakpoint pinned index 0 against head mutation (CC#47098). insertion-normalization recognises a message across re-serializations by content identity instead of pinning its position, which covers that rationale without spending the 4th breakpoint slot — CC occupies three of the API's four; this extension took the last. Holding that slot is not free even when the extension behaves: any future consumer of the 4th breakpoint silently starves, and on our fork the starvation MASKED a defective mid-history rung scheme for a full day — removing the breakpoint first, in isolation, armed it (measured: 57 self-inflicted stability violations before the scheme itself was retired). Hence one rule this removal carries: retire any breakpoint-dependent scheme BEFORE freeing the slot. Measured after removal on two full-session corpora, replaying the real pipeline: 0 stability, 0 safety, 0 sequence violations; the 4th slot stays deliberately empty. A stale reference comment in the ttl-tier pipeline test goes with it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Gunther-Schulz
added a commit
to Gunther-Schulz/claude-code-cache-fix
that referenced
this pull request
Aug 1, 2026
…t and verified; cnighswonger#276 scope discovery Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016y33RMV399iYMXFEbAfQCk
Gunther-Schulz
force-pushed
the
pr/retire-messages-cache-breakpoint
branch
from
August 1, 2026 13:51
b07c0dc to
fb63f61
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.
Why remove it
The honest trade-off
messages-cache-breakpointships enabled; #272's replacement is gated off by default. Merging this as-is changes default behavior for users who don't enable the new extensions. Options, in our order of preference: (a) flip #272's gates to default-on at the same time, (b) take this removal only with a release note, (c) keep the extension but default it off. We run (a)-equivalent in production; the corpora above measured exactly that configuration.🤖 Generated with Claude Code