Skip to content

Commit 484aa19

Browse files
test+booking: real-pair assertions follow the suppression fix; row 8 and backlog updated
The output-form test's real-pair values were the PRE-fix signature by design (edit@31, 61 kB); post-suppression the pair diverges at 48 with a marker-sized residual (ttl-management relocation, not a defect), and the new upper-bound assertion turns a suppression regression into a red test. Matrix row and backlog book the build (c5d870d), the two spec corrections (output-guard owes no exemption; the literal acceptance criterion encoded a single-divergence assumption), and the named remainders: deploy step, five unclassified spliced pairs, three sibling migrations, consumer grep. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TZxGrF1LRBvmb7cFXmS2DH
1 parent c5d870d commit 484aa19

3 files changed

Lines changed: 68 additions & 53 deletions

File tree

BACKLOG.md

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -52,29 +52,38 @@ bullet, evidence pointer included.
5252
the metric newly exposes FIVE more output-spliced pairs (~0.6 MB,
5353
ordinals in the mitigation report) — classify against
5454
blockMigration after (c) lands, they may be a different mechanism.
55-
(c) READY,
56-
serialized behind (b) on tools/replay.mjs ownership — the BUILD:
57-
in insertion-normalization's positional rebuild, suppress the
58-
migrated standalone message when its content equals the pinned
59-
block after wrapper-normalization (the census's unwrap + string->
60-
block fold; the raw bytes differ by the <system-reminder> wrapper
61-
by observation); genuine change (normalized bytes differ) -> no
62-
suppression, forward + reset per the existing rule; suppression
63-
state rides the conversation sub-key; declared exemption in the
64-
live output-guard AND replay's safety gate (message-count change
65-
is deliberate — the tool_addition-announcement pattern); one
66-
event line per suppression to the insertion event log; red-green
67-
on the REAL pair: replaying the day's capture under new code must
68-
turn n=26->28 into outputPreserved:true / rebilledOut 0 with the
69-
safety gate green. Known residuals, accepted: a proxy restart
70-
drops suppression pins -> one bust per active migration at the
71-
boundary (row 3, stated at restart); post-restart first-seen form
72-
re-anchors. Deployment coupling: proxy/** -> dotfiles pin bump +
73-
restart at a stated session boundary + gate run (dev-loop).
55+
(c) DONE 2026-07-30 (c5d870d, sonnet build;
56+
dispatcher-verified: suites green, full-corpus gate 0/0/0/0 under
57+
boot-record gates, real pair edit@31 ~61 kB -> edit@48 ~5 kB).
58+
Two spec corrections booked from the build, both verified: the
59+
"declared exemption in the live output-guard" clause was written
60+
against a check that does not exist (output-guard has no
61+
message-count invariant BY DESIGN — its directive line 58; 0
62+
fires over 1190 requests) — no exemption owed; and the literal
63+
acceptance criterion "outputPreserved:true / rebilledOut 0" was
64+
unreachable by this fix alone — the residual divergence at 48 is
65+
ttl-management relocating its cache_control marker off the old
66+
tail (messages differ in ONLY that key, direct diff), expected
67+
behavior of a different extension. The stability gate needed the
68+
same declared exemption as the safety gate and the brief did not
69+
name it (67 false fires before the fix, caught by full-corpus
70+
replay) — lesson: a message-COUNT change gets checked against all
71+
four replay invariants, not the two a brief happens to name.
72+
Suppression is re-detected per request from the on-disk pin set
73+
(no new state file). Remaining, named: (1) DEPLOY — proxy/** ->
74+
dotfiles pin bump + restart at a stated session boundary + gate
75+
run (dev-loop); row 8 closes on the live non-event, not the
76+
build. (2) The five other output-spliced pairs are confirmed NOT
77+
block migrations (census post-fix: exactly 4, none of the five)
78+
— a different, still-unclassified mechanism, still open. (3) The
79+
three sibling migrations (n=105->107, 107->108, 108->109) were
80+
covered only by the aggregate gate, not individually verified.
81+
(4) grep for consumers of the new suppressed/suppressions stats
82+
fields not run (prior equivalent check on outputForm found none).
7483

7584
- **READY — replay warns on gateless runs of gated captures**
76-
(2026-07-29; serialized behind the suppress build on
77-
tools/replay.mjs). Design: replay.mjs already parses the boot
85+
(2026-07-29; was serialized behind the suppress build, now
86+
unblocked — tools/replay.mjs free). Design: replay.mjs already parses the boot
7887
record's `gates`; when the capture declares gates and none of them
7988
is set in the effective env, print one unmissable warning line
8089
("replaying DEFAULT gates; this traffic was served with N gates —

docs/directives/robustness-threat-matrix.md

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -367,24 +367,30 @@ cause classes. Coverage verdicts, each measured where possible:
367367
CORRECTED same day (sonnet probe + fingerprint check): the earlier
368368
"mitigation kind null, passed through" reading came from a replay
369369
under DEFAULT gates — the dev-loop's replay-the-serving-config
370-
violation, instrument error; under the capture's own boot-record
371-
gates the pair replays MITIGATED (normalized, 0 re-billed), the
372-
one mitigated row of 7. The serving process ran current code
370+
violation, instrument error; the serving process ran current code
373371
(source-fingerprint 8349b0e665c8 = /health = disk; note the
374372
fingerprint is sha256-content, NOT a git tree — comparing it to
375373
git hashes is the hand-rolled-identity error, made twice before
376-
being checked). cdf3179's positional canonical rebuild names this
377-
exact mechanism and absorbs it offline. OPEN, named precisely:
378-
live-unabsorbed vs replay-absorbed — a replay-fidelity gap; prime
379-
suspects: per-conversation state divergence (live proxy served a
380-
concurrent second session; cross-key interference is a known
381-
collision class) and pin state at n=26. Evidence for the state
382-
hypothesis: census (5cdf51b) finds FOUR block migrations in this
383-
session's capture, only ONE of which produced a worktime cold
384-
event — same shape, different live outcomes. Check: compare
385-
replay's n=28 output against the session-mirror's wire bytes at
386-
indices 30/31. Census annotation shipped: blockMigration on splice
387-
and edit rows (5cdf51b, red-tested, fires on all four).
374+
being checked). RESOLVED same evening (fidelity probe): replay is
375+
byte-faithful to the wire (outSha match), and "mitigated:true" was
376+
the METRIC's input-side blindness — the pipeline's real behavior
377+
was restore-the-pin AND forward the duplicate, a splice at 31 that
378+
re-billed 124k. MITIGATION BUILT 2026-07-30 (c5d870d, decision B
379+
pin-and-suppress): the positional rebuild suppresses a standalone
380+
message whose wrapper-normalized bytes equal a live pinned block;
381+
red-green on the real pair edit@31 ~61 kB -> edit@48 ~5 kB (the
382+
residual is ttl-management's cache_control relocation at the old
383+
tail — a different extension, expected); full-corpus gate under
384+
boot-record gates 0/0/0/0; declared exemptions in replay's safety
385+
AND stability gates (the stability one was unbriefed — found by
386+
full-corpus replay, 67 false fires before the fix); output-guard
387+
needs none (no message-count invariant by design, its directive
388+
line 58, 0 fires over 1190 requests). Census annotation shipped:
389+
blockMigration on splice and edit rows (5cdf51b, red-tested,
390+
fires on all four in this capture — only ONE produced a live cold
391+
event). BUILT, NOT YET SERVING: pending proxy restart (dotfiles
392+
pin bump, stated session boundary). Row closes on the live
393+
non-event, not on the build.
388394
- COVERED (mechanism now attributed) — mid-history nudge anchoring
389395
(#78660, #68140, #80604): row 4 above.
390396
- NEUTRALIZED BY CONFIG — subagent 5-minute TTL pinning (#74318): outcome

test/mitigation-output-form.test.mjs

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -177,28 +177,28 @@ test(
177177
// input-side self-report claims full mitigation.
178178
assert.equal(row.mitigated, true, "input-side self-report: normalized, 0 rebilled");
179179
assert.equal(row.rebilledBytes, 0);
180-
// Output-side reality: the forwarded prefix is stable through index 30
181-
// (fidelity report Fact 2/5 — n=26's own index 30 hash equals n=28's
182-
// reconstructed index 30) and diverges at 31, where the standalone
183-
// system message is spliced in ahead of n=26's carried-forward tail
184-
// (fidelity report "What's actually happening"). The census classifies
185-
// this specific pair as "replace/edit" rather than pure
186-
// "splice/insert-mid" — one of n=26's forwarded messages is entirely
187-
// ABSENT from n=28's output (missing=1, added=1: confirmed by a direct
188-
// set-membership diff of the two outHash arrays, independent of this
189-
// implementation's classification branch), so `outputForm` lands on
190-
// the `edit@N` branch rather than `splice@N` — both are the
191-
// non-append buckets the brief names as acceptable, and the load-
192-
// bearing fact is the INDEX (31) and non-append, not which of the two
193-
// labels.
180+
// Output-side reality with suppression active (c5d870d): the migrated
181+
// reminder duplicate that used to splice at 31 is suppressed, so the
182+
// forwarded arrays are byte-identical through index 47 and diverge at
183+
// 48 — n=26's message[48] carries ttl-management's cache_control
184+
// marker (it was the tail then), n=28's does not (the conversation
185+
// grew past it). The two messages differ ONLY in that key (direct
186+
// diff, suppression build report (c)4) — an expected relocation by a
187+
// different extension, not part of decision B, so the pair stays
188+
// non-append with a marker-sized residual instead of the 61 kB
189+
// reminder splice.
194190
assert.notEqual(row.outputForm, "append", "the output is NOT a clean tail append");
195191
assert.equal(
196192
row.outputForm,
197-
"edit@31",
198-
"byte evidence (fidelity report Fact 2/5 + missing-message diff): divergence at 31, not a pure splice",
193+
"edit@48",
194+
"post-suppression divergence is ttl-management's marker relocation at 48",
199195
);
200196
assert.equal(row.outputPreserved, false);
201-
assert.ok(row.rebilledOutBytes > 0, "the splice re-bills everything from index 31 on");
197+
assert.ok(row.rebilledOutBytes > 0, "the marker delta re-bills the tail from 48 on");
198+
assert.ok(
199+
row.rebilledOutBytes < 10 * 1024,
200+
"residual is marker-sized (~5 kB), not the 61 kB reminder splice — suppression regressed if this grows",
201+
);
202202
} finally {
203203
process.stderr.write = origStderr;
204204
for (const k of Object.keys(saved)) {

0 commit comments

Comments
 (0)