Skip to content

feat(devx): ratchet check:engine-double-contract's consumer-seam population - #10502

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-9708-engine-double-consumer-seam-ratchet
Aug 21, 2026
Merged

feat(devx): ratchet check:engine-double-contract's consumer-seam population#10502
os-zhuang merged 1 commit into
mainfrom
claude/issue-9708-engine-double-consumer-seam-ratchet

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

Fixes: #9708

SEAMS_DISCOVERED fires at zero and never at one-fewer-than-yesterday, and REFUSES iterates the discovered set — so a seam that leaves the set was judged by nothing. The card's own reproduction, re-measured on current main (a718ee3dd): deleting the remove() seam from packages/mcp/src/stdio-data-bridge.ts took the census 6 → 5 and left the script printing OK, exit 0.

The design act was decided on a measurement, not inherited

The card explicitly refused to inherit #9680's answer by reflex, so "vanished seam = error vs ledger row vs distinct verdict" was settled by replaying this file's own scanAllSeams, unmodified, over 58 daily trees of origin/main (one commit per day, 2026-06-25 → 2026-08-21):

58daily samples
3MEMBERSHIP changes: 2026-06-28 the protocol seams moved package (objectqlmetadata-protocol) · 2026-07-27 callData moved file (http-dispatcher.tsaction-execution.ts) · 2026-08-12 the MCP stdio bridge arrived, +2
2further changes were refusal-state transitions (localshared) — SHARED_ONLY already governs those and this ledger deliberately does not
0outright departures: every row that left a key reappeared under another one in the same sample

One event a fortnight, and a legitimate one costs a single --write commit. Against that, the loss it closes is a site of the #4435/#5138/#5581/#7867 family — four shipped instances of a receipt answered for a write that touched zero rows — silently ceasing to be judged. Cheap ratchet, expensive miss, so it is built. The reasoning and the numbers live in the gate's own header, not only here.

What landed

  • scripts/engine-double-contract.seams.json — the enumerated population, keyed (file, fn, verb). Not keyed on the line: a seam's line moves on every edit above it, and a ledger regenerated reflexively is the number nobody reads that this card exists to leave. Written by the same--write as the pinned ledger — two regeneration commands for one gate is how a second artifact goes stale while every message says "run --write".
  • SEAMS_RETAINED separates four loss worlds — file-removed, function-removed, unrecognised, sites-removed. unrecognised (the function is still declared and the scan no longer reads a seam in it) is the one that refuses the regeneration remedy the other three offer, because regenerating there would record a blind spot as intended.
  • The seam list now prints on every run, green or red. It used to print only after the failure branch, so the population was invisible exactly when a reader was looking hardest — and it is now the list a SEAMS_RETAINED error is about.
  • SEAM_VERBS is named once and read by both the scan and the ledger check, so an entry naming a verb the scan never reads is rejected instead of recording a population nothing checks.

Ablations (all confirmed on disk, never by an editor's exit code)

Each mutation was verified with a grep -c on the text being changed, before and after; the gate reads source, so no build is involved.

#mutation (on-disk confirmation)result
1delete the remove() member — the card's own repro (async remove(object, id) 1 → 0, 21292 → 20685 bytes)red, exit 1, SEAMS_RETAINED [delete] … declares no function named remove() any more
2keep the function, break discovery: receipt key successacknowledged (success: true 1 → 0, remove( still 1)red, world unrecognised, message refuses --write
3a new seam-shaped function in packages/mcp/src/ (330 bytes on disk)red, SEAMS_RETAINED … the seam ledger does not record it
3bthe same arrival with a shared-envelope refusalred on SEAMS_RETAINED alone, REFUSES silent — the population verdict is independent of the refusal verdict
4neuter the object-literal arm of the declaration walker--self-testred, naming 6 assertions, 4 of them live rows

Restores after 1–3: byte count back to 21292, git status --porcelain empty, gate green.

Ablation 4 is the anti-vacuity control the #8999 lesson asks for. Blinded, the walker turns ablation 2's tree into declares no function named remove() — the quieter story told about the louder defect — which is why the self-test drives it against the real tree and not only fixtures. What it deliberately does not assert is that the ledger on disk matches the tree: that is the verdict of the run the self-test gates, and duplicating it would make a genuine seam removal surface as a self-test failure.

Positive control for the population, and what it cannot see

The instrument was proved to find known-present members before any count was claimed: the scratch probe (this gate's file, unmodified except for one CLI line) reproduced all 6 live rows — same files, lines, functions, refusal spellings — before it was pointed at a single historical tree.

Asked what makes the census return a false empty: productionFiles() walks packages/ only, while the double side of the same gate walks SCAN_ROOTS (packages, examples). Re-run with the walk widened to examples, apps, skills and scripts (2026-08-21): the same rows, zero extra — a controlled zero, since the widened walk still returns all six rather than silently returning nothing. Filed as #10496 rather than folded in here — widening changes the invariant's subject and buys zero rows today, and it is recorded in the gate header as a stated scope boundary rather than left undeclared.

Gates

Derived with node scripts/pm/dispatch-gates.mjs (no path arguments) against the real diff, then run on the head commit 1df4d7c382:

check:engine-double-contract --self-test exit 0
check:engine-double-contract exit 0
consumer seams: 6 in 3 source file(s) — 6 refusing through recordNotFoundError, 0 …
consumer-seam population: 6 row(s), ratcheted against the SEAMS ledger (#9708)
check-engine-double-contract: OK — 340 pinned, 133 in the DEBT ledger, 2 exempt.
check:cross-package-test-inputs exit 0 (OK: 12 package(s) read outside themselves, all declared)
check:nul-bytes exit 0 (scanned 6147 text file(s); no raw ASCII control bytes)
check:merge-driver exit 0 (the new artifact needs no .gitattributes entry — the pinned ledger has none either)

No changeset: the diff is scripts/** only and publishes nothing (skip-changeset).


Generated by Claude Code

…lation (#9708)
`SEAMS_DISCOVERED` fires at zero and never at one-fewer-than-yesterday, and
`REFUSES` iterates the discovered set — so a seam that LEAVES the set was
judged by nothing. Measured by ablation on the card: deleting the `remove()`
seam from packages/mcp/src/stdio-data-bridge.ts took the census down one and
left the script printing OK, exit 0.
The shape was chosen on a measurement rather than inherited from #9680: this
file's own scanAllSeams, unmodified, replayed over 58 daily trees of main
(2026-06-25..2026-08-21) found 3 membership changes — two moves and one
arrival — 2 refusal-state transitions SHARED_ONLY already governs, and 0
outright departures. One event a fortnight against a site of the
#4435/#5138/#5581/#7867 family silently ceasing to be judged.
- scripts/engine-double-contract.seams.json: the enumerated population, keyed
(file, fn, verb) — not on the line, so an unrelated edit above a seam cannot
churn it. Written by the same `--write` as the pinned ledger.
- SEAMS_RETAINED separates four loss worlds; `unrecognised` (the function is
still declared and the scan no longer reads a seam in it) refuses the
regeneration remedy the other three offer, because regenerating there would
record a blind spot as intended.
- The seam list now prints on every run, green or red, and says the population
is ratcheted rather than merely counted.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DdCnBGcHeufjrq7drTD3wt
@os-zhuangos-zhuang added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Aug 21, 2026 — with Claude
@os-zhuang
os-zhuang marked this pull request as ready for review August 21, 2026 02:09
@os-zhuang
os-zhuang added this pull request to the merge queueAug 21, 2026
Merged via the queue into main with commit 7c7c0a7Aug 21, 2026
27 of 28 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-9708-engine-double-consumer-seam-ratchet branch August 21, 2026 02:49
This was referenced Aug 21, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/lskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

2 participants

@os-zhuang@claude