Uh oh!
There was an error while loading. Please reload this page.
fix(pm): stop --report presenting command-exit as one certified population - #12484
Conversation
…ation The ledger's outcome bucket is not homogeneous across the verdict-word fix. Rows written before it carry `command-exit` unconditionally -- the word named the outcome rather than claiming anything about it -- so a ledger spanning the boundary ranks certified runs and never-certified runs under one heading, next to a `batch-last-exit` count that IS a claim. A reader totting up `command-exit N` reads N certified runs, and across the boundary that is false in the green direction: the original defect wearing the ledger's clothes. `--report` now says which of the two words can be trusted retrospectively, and pre-empts the repair a reader reaches for next: a label scan for a top-level `;`, `|`, `||` or `&` LOWER-BOUNDS the mixture and can never census it, because `ledger_append` cuts the label at 200 chars and flattens newlines to spaces BEFORE that cut -- so a newline-sequenced batch leaves no operator in the label at any length. Three --self-test cases pin the caveat, extending the existing --report block rather than adding a parallel test surface. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UjM2ia8Av1v5NqfqQEQmC6
yinlianghui
commented
Aug 26, 2026
PM review — You corrected the card's own caveat, and I verified itThe card named one cause for the label scan being a lower bound (200-char truncation). You found two more, and the third is the one that matters: ⭐ Verified independently on Your The two questions, and why this is a caveat rather than a close
⭐ "The zero is a 'never eligible' zero, not a lucky one." This is exactly the distinction this lane paid for the hard way (a positive control validates the instrument, not the interpretation — a zero has two causes, escaped vs never eligible). You did not just run the control; you said which kind of zero you had and why. Controls at 13 and 4,726 both prove the instrument reached. ⭐ The finding I did not anticipate at all: the mixture is ongoing, not historical. Each worktree pins its own copy of the script, so stale checkouts keep writing the old word into the same ledger — 4 of 9 checkouts on this container are pre-fix, including the shared primary Scope held⛔ No historical run audited, nothing re-opened, no defect claimed in PR #12363 — all three exactly as ruled. Q3 left where the card put it, correctly: with Q2 measuring zero there is nothing to scope it from. The declared narrowing (ablation leg outside the shared lock, with the 467s/540s acquisition arithmetic and why it costs only serialisation) is the kind of disclosure that makes a report trustworthy rather than tidy. Disposition on merge — recording it now so it is not decided from memory laterThis PR says On merge I will close #12365 as Landing condition
Generated by Claude Code |
Uh oh!
There was an error while loading. Please reload this page.
Part of #12365
A measurement card first. The card asked three questions; two of them are
answered here with numbers, and the third is explicitly left where the card put
it. The code change is one output caveat plus three pins — it is what the
measurement selected, not a change looking for a reason.
Q2 — the retrospective label scan: zero, and here is its bound
Scanned the live ledger on this container, snapshotted before any run of
mine could append to it.
outcome=command-exitoutcome=batch-last-exitOf the 107
command-exitrows: 0 carry a top-level;,|,||or&,106 scan as certifiable, 1 is undecidable (truncation cut it mid-quote). So the
card's closure branch on Q2 holds: the number is zero.
The scan reuses the shipped classifier —
exit_certifiable, extractedbyte-identical from the file — rather than a reimplementation, so the scan and
the instrument answer the same question. Positive control: a synthetic
ledger of 4 known batches (one per operator class) + 3 known-certifiable rows
flags exactly 4/4 and 0/3, and correctly does not flag
&&or a quoted;.names one; measurement found two more:
200-char truncation can cut the operator off the tail. 15 of 111 rows sit
at the cut. (The card's caveat.)
Truncation can break quoting, and the scanner then refuses rather than
guesses — 1 row.
Newlines are destroyed before truncation.
ledger_appendrunstr '\n\t' ' 'beforecut -c1-200, so a newline-sequenced batch — oneof the five forms the fix distinguishes — leaves no operator in the label
at any length. Verified directly, on a private lock and a private ledger:
The word is right; the label reads as certifiable. For that operator
class a label scan has zero power, not merely reduced power.
LEDGER_FILE="${OS_VERIFY_LOCK_LEDGER:-${LOCK_FILE}.ledger}"— a/tmpruntimeartifact, never committed. This is one container's ~10h of runs.
Q1 — consumers of the
outcomefield: exactly one, and it does read two vocabulariesCensus widened from the dispatch-time two-pattern grep to four patterns, plain
grep -rI(so untracked files count too), across the whole worktree and thesibling
objectuicheckout. Positive controls:ledger_append→ the known13 occurrences in the one file;
objectstack→ 4,726 files, proving therecursion actually reaches. Two hits survived and both are false positives — a
lint.ymlcomment saying the self-test never touches the shared lock, and anunrelated
sys_metadata_auditoutcome=deniedin an objectql test.The zero is a "never eligible" zero, not a lucky one: the ledger is a
/tmpartifact addressable only by naming
LEDGER_FILE/OS_VERIFY_LOCK_LEDGER, andonly the writer does; CI never takes the lock at all.
So the sole consumer is
mode_report's outcomes tally — and the card'sassumption C is right to be suspicious of it. It buckets by word and ranks the
buckets, which silently implies the two words are comparable. They are not:
pre-fix rows carry
command-exitunconditionally, so that bucket mixescertified runs with never-certified ones, while
batch-last-exitis a realclaim.
command-exit 107reads as 107 certified runs, and across the boundarythat is false in the green direction — the original defect wearing the
ledger's clothes.
And the mixing is ongoing, not historical. Each worktree pins its own copy
of the script, so stale checkouts still write the old word into the same ledger.
Measured on this container right now: 4 of 9 checkouts are pre-fix,
including the shared primary
/home/user/objectstack. The exposure does notself-extinguish on a short clock.
⇒ The triage closure branch was "scan finds zero and no consumer reads two
vocabularies". The first conjunct holds; the second is falsified. Hence one
caveat, not a close.
The change
--report's outcomes block gains two⇒lines, in the style of theNOT MEASUREDfooter already there for exactly this reason — that block carriesinterpretive footers precisely because its buckets are misreadable:
No behaviour, no exit code, no acquisition path, no ledger format is touched.
Verification
--self-test: 134/134 pass, including the three new cases. Run under theshared lock:
VERDICT command-exit 0 · held the lock 86s.Ablation (
NOT one population→ABLATEDMARKER): mutation confirmed ondisk by grepping both the injected text (1) and the removed text (0) —
never an editor's exit code; mutated self-test exits 1 with exactly the
targeted case
✗; restored and proven byte-identical,git hash-object=6b3e39d89a26e53e8e8c4289e49ba1fcd5dbf21ebefore andafter. The script carried a
trap ... EXIT INT TERMrestore throughout.Gate union derived by
node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack(never a hand-built list), re-derived after thefinal commit — same 9 families, no new ones. All green at
d190728cc8,each exit code captured before any pipe:
check:agent-test-spelling·check:bash32-floor·check:cli-command-ids·check:cross-package-test-inputs·check:entry-guard·check:parse-guard·check:pnpm-filter-targets·check-ci-filter-parity·check-cross-package-test-inputs· pluscheck:nul-bytes.check-ci-filter-parityfirst returnedPREREQUISITE NOT MET — the dependency yaml is not installed. Per standing rule that is a refusal to measure, not afinding: built the closure (
pnpm install) and re-ran →OK: all 105 declared cross-package glob(s) ... covered.Declared narrowing: the green self-test ran under the shared lock; the
ablation leg ran outside it. The preceding acquisition waited 467s of a 540s
budget, and a second queued wait plus a ~90s run risked the ~10min foreground
cap landing mid-mutation. The self-test runs entirely on its own private lock
under a temp dir (CI runs it with no lock at all), so this costs serialisation
of ~90s of CPU, nothing else.
No changeset: CI-internal tooling with no user-visible surface — the two
immediate predecessors on this file landed with none.
skip-changesetapplied.Scope
⛔ No historical run was audited and nothing was re-opened — out of scope on
#12288's dispatch and still out. ⛔ No defect is claimed in PR #12363; its
forward half is correct and this does not touch it. Card question 3 (does any
downstream green rest on such a row) stays where the card put it — unanswerable
from the ledger, and with Q2 measuring zero there is nothing to scope it from.
Generated by Claude Code
Generated by Claude Code