Skip to content

Stage 1-r1: the pre-execution design layer, and the HOLD it reports - #835

Merged
MongLong0214 merged 11 commits into
mainfrom
cdeb-v5-stage1-r1
Aug 22, 2026
Merged

Stage 1-r1: the pre-execution design layer, and the HOLD it reports#835
MongLong0214 merged 11 commits into
mainfrom
cdeb-v5-stage1-r1

Conversation

@MongLong0214

Copy link
Copy Markdown
Owner

Replaces the Stage 1 draft that failed adversarial review with a distinct r1 preregistration, and builds the pre-execution layer the final PRD specifies. The verdict is HOLD — eleven of the fifteen acceptance criteria are satisfied by evidence, four are not, and under the PRD any unresolved P0/P1 is a hold. No measured episode has been run and none is authorized.

What is here

Module Gate
buildability-v5.ts G1 — closed reason list, exactly-one disposition, outcome-blind rows
firewall-v5.ts G3 — allowed/forbidden task-author inputs, task-frozen-before-oracle by digest, n-gram leakage detection
oracle-v5.ts G2 — control matrix, discrimination, oracle input restriction
runtime-lock-v5.ts G4 — 17 pinned fields, arm-drift naming
analysis-v5.ts ITT denominator, equal-weight estimand, candidate-within-repository bootstrap
effect-independence-v5.ts power rule and pilot gate, both refusing effect-bearing input
stage1-census-v5.ts runs the mechanical screens over the sealed bundles

The census

The screens ran against all four sealed bundles and refuted nothing. 61 of 62 decision scopes survive intact at the frozen snapshot, the 62nd partially, and every repository has an executable test command. So no candidate is refutable mechanically, and none is admissible mechanically either — BUILDABLE asserts a validated discriminating oracle, and none has been built.

All 62 rows carry disposition: null, and assertCensusComplete throws on the committed file. The runtime lock is the same shape: 17 null fields, assertRuntimeLockComplete throwing on it. The guards are proved against the real artifacts rather than fixtures, which is the only proof they fire where it matters.

A defect found while writing the power rule

The inverse-normal transcription dropped a term from the central denominator, so every quantile came out at roughly 1/400 of its value and the corpus appeared able to detect 0.1 percentage points. Fixed, exported, and pinned against published quantiles to five decimals. The failure mode flattered the design rather than breaking it.

What the corrected arithmetic says

Registered before any outcome exists: over 50 reserve candidates in four fixed strata at 8 repeats per arm, the detectable difference in Delta is 12.3 to 17.2 percentage points depending on between-candidate heterogeneity. Ten points needs 12 repeats and homogeneous candidates. Repeats cannot average heterogeneity away; only more candidates can, and the corpus is fixed at 62.

A null result from this study is therefore not evidence of no effect, and the preregistration says so.

Mutation ratchet

Nine new guards registered. The ratchet caught one of them inert on the first run — the pilot gate's effect check was covered by a test that accepted either error message, and every effect-named key is also an unregistered key, so the assertion passed with the guard disabled. Binding the test to the effect-specific diagnosis made it fail under mutation. 32 bound, up from 22.

What would close the HOLD

  • 62 frozen dispositions, each backed by a validated oracle or one of the seven registered reasons
  • for every buildable candidate: an oracle reading the final tree only, two structurally distinct compliant passing controls, at least one ruled-out passing control, shown to discriminate
  • for every buildable candidate: a task-author manifest whose inputs are the base tree and the maintenance need, and an oracle manifest at a later sequence carrying its digest
  • the 17 runtime fields pinned — an owner decision

The firewall cannot be satisfied from the context that built the corpus: whoever did has read all 241 records. It needs a record-blind author.

Verification

45 new tests, 3,641 across the suite; typecheck clean; ratchet reports 32 bound with no regression. Five suite failures under full parallel load — cdeb-smoke, doctor budget, secret-guard regex cost — pass when their files run alone.

measured product-effect rows   0
measured_run_allowed           false
buildability dispositions      0 of 62
oracles built                  0
tasks authored                 0
verdict                        HOLD

…s instrumented

Stage 1-r1 replaces the Stage 1 draft that failed adversarial review. This builds the
pre-execution layer the FINAL-PRD asks for -- buildability census machinery, the
task-author firewall, oracle validation, the frozen analysis, the runtime lock, the
power rule and the pilot gate -- and then reports HOLD, because four of the fifteen
acceptance criteria have nothing to be satisfied by yet.

The mechanical screens ran against all four sealed bundles and settled nothing:

    repository             candidates  screen-refuted  runner
    agent-control-plane            10               0  npm test
    agent-operator-score           17               0  npm test
    gitseed                        22               0  pytest
    logic-pro-mcp                  13               0  swift test

61 of 62 decision scopes survive intact at the frozen snapshot and the 62nd survives
partially. Every repository has an executable test command. So no candidate is
refutable by machinery, and none is admissible by it either: BUILDABLE asserts that an
oracle exists and discriminates, which is a claim about an artifact.

All 62 rows therefore carry `disposition: null`, and `assertCensusComplete` throws on
the file this commit adds. The same holds for the runtime lock: 17 null fields and
`assertRuntimeLockComplete` throwing on it. The guards are proved against the real
artifacts rather than against fixtures, which is the only proof that they fire where
it matters.

A defect was found in the power arithmetic while writing it. The inverse-normal
transcription dropped a term from the central denominator, so every quantile came out
at about 1/400 of its value and the corpus appeared able to detect 0.1 percentage
points. Fixed, exported, and pinned against published quantiles to five decimals. The
failure mode is worth naming: it flattered the design instead of breaking it.

The corrected arithmetic produced a finding, registered here before any outcome
exists. Over 50 reserve candidates in four fixed strata at 8 repeats per arm, the
detectable difference in Delta is 12.3 to 17.2 percentage points depending on
between-candidate heterogeneity. Ten points needs 12 repeats and homogeneous
candidates. Repeats cannot average heterogeneity away; only more candidates can, and
the corpus is fixed at 62.

Nine guards are registered in the mutation ratchet and the ratchet caught one of them
inert: the pilot gate's effect check was covered by a test that accepted either error
message, and every effect-named key is also an unregistered key, so the assertion
passed with the guard disabled. Binding the test to the effect-specific diagnosis made
it fail under mutation. 32 bound now, up from 22.

Record-Id: r-v5stage1r1designlayer
Provenance: authored
Certainty: firm
Blast: system
Undo: easy
Ruled-out: filling the runtime lock with plausible placeholder values | an unpinned runtime that reads as pinned is worse than an empty lock, because the next reader stops asking
Ruled-out: marking the 62 screen-surviving candidates BUILDABLE | the screens can only refute, and calling a candidate buildable without an oracle is the claim the census exists to check
Ruled-out: patching the six defects into the failed Stage 1 draft | its own section 7 says anything but the deferred N makes a change a new preregistration, so amending the document that defines amendment is the failure it guards
Ruled-out: reporting PASS on the eleven satisfied criteria | four unresolved P0/P1 is a HOLD under section 19, and a partial pass reads as readiness to whoever approves execution
Limit: the task-author firewall has still never run. Whoever built this corpus has read all 241 records, so the record-blind half cannot be satisfied from here -- it needs an author whose only inputs are the base tree and the maintenance need, with the manifest proving it
Limit: no oracle exists for any of the 62. Stage 0 recorded that reviewers thought one could be written; between that and a validated discriminating oracle sits the whole of G2, and nothing has crossed it
Limit: the between-candidate variance in the power table is a range I chose to bracket, not a measurement. The pilot supplies the real value, and only then does the detectable effect stop being a family of curves
Verified: 45 new tests pass and 3,641 across the suite; typecheck clean; the mutation ratchet reports 32 bound with no regression. assertCensusComplete and assertRuntimeLockComplete are proved by throwing on the committed artifacts, not on fixtures. The five suite failures under full parallel load -- cdeb-smoke, doctor budget, secret-guard regex cost -- pass when their files run alone
@github-actions

github-actions Bot commented Aug 22, 2026

Copy link
Copy Markdown

CommitLore — record lint

Trailers: clean — 11 commits in origin/main..6202b5d3a73012746dee46fa8357c0bf589b1c39
Active constraints: 152 limits · 184 ruled-out · 17 warnings — from 166 records over 31 changed paths

Active constraints for the paths this PR touches

Limits (152)

  • r-v5guardnamestale 6202b5d — nothing prevents the next rename from doing this again. The ratchet catches it on the following CI run rather than at the moment of the rename, and that is the guarantee available
  • r-v5oraclefirstattempt 8d158c6 — one candidate of 62. The mechanism predicts that well-implemented decisions are the least usable, and a mechanism that predicts more is not a measurement of more
  • r-v5oraclefirstattempt 8d158c6 — the two revivals I built are mine. A more inventive agent might find a shape the validator admits, and the honest reading is that I could not find one, not that none exists
  • r-v5oraclefirstattempt 8d158c6 — 61 candidates remain undecided, so nothing here says whether the corpus can clear the SSOT 7.3 floors of 8 buildable per repository and 24 in the reserve
  • r-v5taskchainfirstpair 74176cb — the oracle half has not been built for any candidate, so gate G2 is untouched and no candidate can be BUILDABLE yet
  • r-v5taskchainfirstpair 74176cb — zero four-gram overlap is a lexical floor. It cannot rule out a paraphrase that shares no four-word run, and nothing here tests for one
  • r-v5taskchainfirstpair 74176cb — one candidate, one model, one run of each half. Nothing yet says the other 61 behave the same way, and the leak screen already suggests some will not
  • r-v5needscoutfirstrun 7a4967f — one candidate, one scout, one model. FUNCTIONAL-AUTHOR has not run, so no manifest pair exists and the record-blind-before-record-aware ordering is still unproven end to end
  • r-v5needscoutfirstrun 7a4967f — zero four-gram overlap cannot rule out a paraphrase that shares no four-word run. The lexical check is a floor, not a proof of independence
  • r-v5needscoutfirstrun 7a4967f — the encouraging part -- a need landing on the decision boundary -- is one observation and says nothing yet about whether the other 61 behave the same way
  • r-v5firewallleakscreen c5d47eb — the screen measures shared wording, not disclosure. A reason that names a function shares wording with the code defining it without saying what was ruled out, and nothing here weighs where the hit landed
  • r-v5firewallleakscreen c5d47eb — the direction is not established. Record and code were often written together, so wording in common does not say which explains which
  • r-v5firewallleakscreen c5d47eb — two candidates are refuted outright by Record-Id presence, and the other 32 need per-candidate reading that has not happened. No disposition has been frozen for any of them
  • r-v5ssotreconciliation d3981ab — the 9.3 gate passes under an assumption the study cannot test. Nothing establishes the true between-candidate variance, the 12-candidate pilot cannot estimate one, and the corpus is fixed at 62 so no budget reduces it
  • r-v5ssotreconciliation d3981ab — the nine registered reasons are now the closed list, but no candidate has been disposed under any of them -- all 62 remain undecided pending oracle construction
  • r-v5stage1r1reviewfixes 87cacec — the pilot-gate custody gap is open and needs role separation -- execution, custody of arm-coded outcomes, and continuation held by different parties. That is an owner decision and it has to be settled before the pilot, not after
  • r-v5stage1r1reviewfixes 87cacec — the firewall now names who produced the maintenance need and refuses a producer not declared record-blind, but a declaration is not evidence. Making it evidence needs an attestable isolated authoring environment this layer does not have
  • r-v5stage1r1reviewfixes 87cacec — tau_squared_bound = 0.06 is a frozen assumption, not a measurement. It is conservative in the direction that matters -- lower true heterogeneity means the study detects more than promised -- but nothing here establishes the true value
  • r-v5stage1r1designlayer 28699d8 — the task-author firewall has still never run. Whoever built this corpus has read all 241 records, so the record-blind half cannot be satisfied from here -- it needs an author whose only inputs are the base tree and the maintenance need, with the manifest proving it
  • r-v5stage1r1designlayer 28699d8 — no oracle exists for any of the 62. Stage 0 recorded that reviewers thought one could be written; between that and a validated discriminating oracle sits the whole of G2, and nothing has crossed it
  • r-v5stage1r1designlayer 28699d8 — the between-candidate variance in the power table is a range I chose to bracket, not a measurement. The pilot supplies the real value, and only then does the detectable effect stop being a family of curves
  • r-833multiblocknotice fe84c6b — this makes the cost audible, it does not remove it. A merge commit written from a multi-block draft still carries records that git-native tooling will not report as trailers, and --target remains the only way to have every record visible on both channels
  • r-v4qualification b8ff1b9 — G3 and G4 were judged from the commit message, the changed paths and the ruling. Neither reviewer read the current code or ran a test, so both are informed judgements about a maintenance task rather than measurements of one. G5 classifies whether an oracle could be written; none was built
  • r-v4qualification b8ff1b9 — this says nothing about whether recording decisions helps an agent. It says the four surveyed repositories cannot supply gold that is independent of the records being tested, which is a fact about these repositories and this gate
  • r-v3manifestsync c195b48 — this proves the manifest matches this checkout. It does not prove the pinned image produced the committed dist on any other machine, which is what the pinned digest is for
  • r-v3terminalseal 7754f1a — the placeholder row remains in the ledger and always will. This makes it legible, not absent, and a reader who takes digests on faith rather than reading the deviation is still misled
  • r-v3terminalseal 7754f1a — the canonical digest binds the artifact list it is given. A transition that names too few artifacts is bound to a partial set, and nothing here decides what the right set is for a future study
  • r-v3terminalseal 7754f1a — guard coverage is unchanged -- thirteen exclusion kinds remain uncovered and one scan inert, recorded in the mutation baseline
  • r-guardratchet 26b1989 — the baseline is a floor. A guard can bind its claim against the one mutation recorded for it and still miss a different violation of the same claim
  • r-guardratchet 26b1989 — the reasons are written by the same author as the claims, so a gap reasoned narrowly can look more settled than it is
  • r-guardratchet 26b1989 — thirteen exclusion kinds remain uncovered and one scan inert; this records them and repairs neither
  • r-guardmutation 551921d — a mutation proves a guard reacts to one specific edit. A guard can bind its claim for that edit and miss a different violation of the same claim, so coverage here is a floor and not a proof
  • r-guardmutation 551921d — the claims were written by the same author as the guards, so a claim stated too narrowly produces a control that passes for a property nobody wanted
  • r-guardmutation 551921d — thirteen exclusion-index kinds remain inert; this change makes that visible and does not repair it
  • r-coauthoredcasing 06354f9 — the exemption stays a fixed pair. A standardised trailer this repository has not met -- Reviewed-by:, say -- is still refused as unknown-key, which is deliberate but will read as the same bug to whoever hits it next
  • r-democopycanonicalbuild 8ce56bc — the bundle changed only because one output string did; nothing about the build is different
  • r-release120 b073960 — the passive notice only speaks once a check has landed, so the first invocation after this install says nothing however out of date the next release finds it. That is the trade the zero-latency design buys, and the answer arrives on the following command
  • r-lazysignaturemode f7dc7ef — a scan that reads even one commit still asks, so the cost returns on any invocation that has catching up to do. That is the invocation that can afford it
  • r-rebuildworknobodyreads 1a66b26 — the deadline is still only checked between batches and before the expensive half of one, so a late batch of 1024 commits can overshoot by whatever that batch costs -- bounded by one batch rather than by the whole scan. And an unsigned-mode index now carries '' where it carried git's verdict, so a reader wanting the cached status without turning signature mode on no longer gets it; none exists
  • - 1ca0ac9 — the other tracked dist files auto-merged rather than conflicting, and a line-wise merge of generated JavaScript is not something to trust on its own -- the canonical rebuild is what makes them correct, not git's resolution
  • r-rebuildopensdamaged 70dc155 — this covers a full-text table that will not rebuild. Damage that makes createSchema or the first meta read fail still surfaces through the open's own catch, which is where it belonged already; nothing here widens that
  • r-initsayswhatitpinned c7de40d — the report names the pinned version and the newer one, but not whether the pinned checkout is intact -- doctor compares the running build against the pinned one and is where that question belongs
  • r-upgradeperforms b1e75c9 — nothing here can tell a current that resolves to the right tag over a checkout whose contents are wrong. install.sh verifies a reused checkout's manifest and tag, and doctor compares the running build against the pinned one; step 4's failure text names doctor for exactly that reason
  • r-doctorreleasefreshness 174e120latestReleaseSync cannot signal a process group, so a git that spawns an SSH client which then hangs is bounded by spawnSync's timeout on the child alone. The async path exists because the notice cannot afford that and this report can
  • r-passiveupdatenotice a783a95 — the notice speaks only when a check has already landed, so on a cold cache the first invocation says nothing however out of date it is. That is the trade the zero-latency property buys, and the answer arrives on the next command rather than the first
  • r-upgradereadonly ccc634cupgrade accepts --check but performs no upgrade in this build, and --check is therefore the only behaviour. T-1606 makes the bare form act; until then the command names the install line rather than running it
  • r-integrityoffread 2584678commitlore index --rebuild still cannot open a structurally damaged index -- openIndex rebuilds the FTS table on open and throws first (commitlore index --rebuild cannot open the index it is meant to rebuild #785). That predates this change and the documented remedy has never run in that state; test/index-corruption.test.ts opens the database directly to work around it and says so
  • r-pluginawaredelivery 46c4169 — this does not clean up dual installs already on disk -- somebody in that state keeps paying twice until they remove one by hand. It also reads Claude Code's private state, which has already changed shape once (the registry is on version: 2); when that breaks, it breaks toward writing the hook, which is the direction chosen on purpose
  • r-hookmatcherunify fa4373d — neither installer knows the other exists -- init writes the settings.json hook unconditionally, so a user who follows the README to the plugin and then runs commitlore init carries two PreToolUse hooks running the same command. Unifying does not create that double fire, but it widens the overlap from Edit and Write to all five; the partial overlap it replaces was worse to diagnose, because the same user saw records twice on an edit and once on a read
  • r-rebuildschema a6d577e — this recreates the file whenever the recorded version differs, so a downgrade discards an index a newer build wrote rather than reading what it can from it
  • r-partialsilence 9553e2c — this says the scan was cut short, not which records were missed -- the payload cannot name what it never read
  • r-rel114 9692b6d — the README restructure and the mobile hero redesign are not in this release, so the four READMEs remain long and the hero's labels remain small at 375px
  • r-builderpin cb1515f — nothing checks that the pinned digest still exists upstream, so a digest deleted from the registry surfaces as a build failure rather than as a clear message
  • r-canonmerge761 6a88f2f — this proves the bundle matches this tree; whether this tree is what a reviewer wants is what the pull request is for
  • r-rel113 17a1301#749 question 1 stays open -- a fix that lives in the hook reaches a repository only on its next visit, and nothing on this machine knows which repositories exist
  • r-machinescope e46af2a — this is one check's classification, not a scope field -- another machine-scoped check added later will default to claiming attention again, and nothing here would notice
  • r-upgraderebind 49765af — this reaches a repository only when its stub already carries the arm, so one installed before this still needs hooks install once -- the same boundary After an upgrade the hook says "cannot find the CLI" when the CLI is fine and containment refused it #746 recorded, and the reason that command stays the named remedy
  • r-746message 5dda01b — the stub is written into .git/hooks at install time, so a repository wired before this keeps the old text and gets the old sentence until hooks install runs there; installing a corrected release is not enough
  • r-746narrow 5dda01bcommitlore.node is only tested for -x, so a recorded interpreter that exists but cannot run this bundle still reaches neither arm and falls through to the absence message
  • r-rel112 ad6fee3 — the readback confirms the link, not that the interpreter behind it runs -- doctor remains the check for that
  • r-rel112 ad6fee3 — this repairs the installer; a machine already upgraded to 1.1.0 or 1.1.1 keeps its stale current until the installer is re-run, which is why the note names the command to check
  • r-detectrule728 f1784ce — this records the rule, it does not enforce it -- a new host added with the wrong test still compiles, and Plant a host fixture in Windows CI so this class can't hide behind an empty runner #722's planted fixture is where that could be caught
  • r-detectwhy728 f1784ce — still recorded, not enforced -- a new host added with the wrong test compiles
  • r-rel111 8c29f5d — Hermes still fails on that machine for a cause that is not this one and is not yet named (Windows: every detected host fails to wire — the temp filename carries the whole path, and hasCommand cannot see a .cmd #716)
  • r-rel111 8c29f5d — a zero-byte .cursor/mcp.json on the tester's machine is a user file; the installer read the file it says it reads and reported the true reason
  • r-rel111why 8c29f5d — this changes the note, not the behaviour -- the behaviour shipped in the merged branch and is already covered by artifact:verify
  • r-canon720 7bf5b82 — this adds no judgement about the Windows behaviour -- it makes the branch buildable, and the live evidence on the pull request is still the only evidence for that path
  • r-canon720b 7bf5b82 — this rebuilds, it does not judge -- the Windows behaviour still rests on the live evidence recorded on the pull request, and Hermes and the first-run probe timeout are still open on Windows: every detected host fails to wire — the temp filename carries the whole path, and hasCommand cannot see a .cmd #716
  • r-winargv716 7bf5b82 — Does not change executable-only Claude detection or the pre-existing MCP probe shell path; a new canonical dist rebuild is not included from Windows
  • r-winexec716 7bf5b82 — Does not change MCP probing or rebuild generated artifacts.
  • r-rel110 d9a041f — this release does not make host wiring work on Windows -- detection still cannot see a .cmd and spawn still cannot run one (Windows: every detected host fails to wire — the temp filename carries the whole path, and hasCommand cannot see a .cmd #716)
  • r-rel110 d9a041f — 1.0.0 through 1.0.2 have no CHANGELOG entries; a pointer to the releases page stands in rather than reconstructing them
  • r-rellock110 d9a041f — nineteen version surfaces was already wrong before this -- the lockfile makes it twenty-one, and the count is only ever known after the gate says so
  • r-relmanifest110 d9a041f — this is the release commit's own repair, not a fix -- the next release will need the same regeneration for the same reason
  • r-namefile716 f728e69 — only failures name their file; a successful wire still reports no path
  • r-namefile716 f728e69 — this makes the cursor question answerable on the next Windows run -- it does not answer it, and the outcome (failed) was never in doubt
  • r-overlay709 7e08cbf — unattended is an input to the effective digest but not to the defaults digest -- M-UX: capture leaves the user's workflow #511's exclusion rests on a file's identity being its own bytes, which an overlay breaks
  • r-overlay709 7e08cbf — a broken overlay falls back to the built-in defaults, not to the committed file -- layering onto a policy nobody could read states an effective policy no file states
  • r-wintmp716 f0ed513 — this fixes the write, not the detection -- codex, hermes and claude-code failed for the second cause and still will
  • r-wintmp716 f0ed513 — no Windows machine has run this fix; the guard proves the name, not the install
  • r-pend710 b452535 — the wording is checked, not the severity — an abandoned draft still warns
  • r-rel102 25c11ed — an installer-boundary fix reaches nobody until it is released
  • r-codexok 9021dd9 — a requested integration that failed is not a healthy host
  • r-697codx ae6245f — one owner per host step, in the place both installers call
  • r-693curr 14909c3 — a hook records a path that does not name a release
  • r-693mut2 14909c3 — a rejection test names what does the rejecting
  • r-rel101 b65e34f — a distribution-boundary fix reaches nobody until it is released
  • r-689host c0e909b — a host is wired or reported undetected, never absent
  • r-686skil adbe186 — a permanent config never records a path that belongs to one invocation
  • r-682herm 2e64424 — recognition is by field, never by formatting
  • r-680ver 47359a1 — an assertion that reads the source it checks proves nothing
  • r-rel100 47359a1 — a published install URL must resolve the moment it is published
  • r-status550 de514ea — a setting and a behaviour never share one word
  • r-590gate 63e48fa — the preregistered verdict is the authority for published M5 figures
  • r-g1build 63e48fa — identity travels as version and digest, never as a path
  • r-g1e2e1 63e48fa — parity is only measured across process boundaries
  • r-gateplan 63e48fa — a plan that lives only in a session is lost at the next compaction
  • r-631cov 92c1b37 — coverage describes the index, history describes the sources
  • r-638bnd 2607bae — git reports the message's origin, not the commit's
  • r-cleanrebuild664 da8948d — the manifest binds dist to committed source, so any uncommitted edit anywhere in src makes a local verification meaningless — this is a property of the check, not of this branch
  • r-formatnotmachine661 2cc274d — verified locally only; whether the warning list's numbering also shifts when the check flips is a question only CI answers, because the runners are where the two runs actually diverged
  • r-selfscan661 ccab7f4 — ancestry is only knowable while the ancestor lives; a server orphaned by a doctor that has already exited is indistinguishable from any other session's, and is correctly counted as one
  • r-liveruntime660 6a221dbps is the seam, so this reports nothing on win32 and says so rather than claiming a clean machine
  • r-committedat650 f077870 — this pins the spelling, not the clock; nothing here makes two gits agree about anything else in %cI
  • r-prosetrailer647 30e40c7 — this changes the advice, not the outcome; the commit is still refused, which is correct while git reads the line as a trailer
  • r-repointsays629 c7ab87e — this reports the move, it does not verify the new target runs — hooks status owns that check and is unchanged here
  • r-childtreediag640 69c98a0 — the diagnosis is printed, not asserted — the next failure explains itself but the step still cannot say which outcome is acceptable
  • r-childtreepre640 69c98a0 — windows-latest is the only evidence for this path; nothing here was verified locally
  • r-coldstart640 69c98a0 — this measures the launcher's own child; it does not measure when cmd.exe started, so a stall before node is attributed to the same interval
  • r-launchernode640 69c98a0 — the earlier commit raising the probe budget to 15s stands on its own measurement — a healthy probe used 4478ms of 5000ms — but its message claimed that budget explained this flakiness, and it did not
  • r-launcherwhy640 69c98a0 — the deadline explanation is two independent diagnoses and a margin measurement, not a reproduction — the confirming evidence is the next run's own output
  • r-mcpidentity572 69c98a0 — Windows behaviour here rests on windows-latest runs and nothing else; a slower machine than three times the measured passing case will still be told it could not be verified, which is at least true
  • r-nodedrive640 69c98a0 — this reproduces the spawn, not the whole probe; a silent result narrows the cause without naming the fix
  • r-probefacts572 69c98a0 — the close-stdin outcome is measured, not guaranteed by the shell -- a platform whose shell defers the redirect past the parent's first write would produce the timeout code instead, and this case would then need its own seam rather than a looser assertion
  • r-proberace572 69c98a0 — this leaves one outcome unpinned, so a regression that swapped closed-input for timed-out on that fixture would not be caught here -- the four other cases still pin their codes exactly
  • r-reclaimnogate640 69c98a0 — windows-latest is the only evidence for this path, and one green run does not settle a race — this needs to hold across runs before The MCP probe's Windows behaviour is unverified: PATHEXT resolution and child-tree cleanup #640 can be called closed
  • r-sawinput640 69c98a0 — this records the arrival, not the response; if bytes arrive and nothing comes back, the next question is the probe's reader
  • r-slownotbroken640 69c98a0 — fifteen seconds is calibrated against one Windows runner's measurement; a machine slower than three times that will still be told it could not be verified, which is at least now true
  • r-mirrorsays632 aafd5ab — this states the retry, it does not verify it — nothing here checks that the following push actually published the note
  • r-keyringgen653 8b066c7 — the generation identifies the keys the verifier can list, not every reason git might reach a different verdict; expiry and revocation are outside what this binds
  • r-preflight002 0dca998 — MCP capture advertisement requires package manifest, SPEC, and schema to be available in the active runtime
  • r-recheck002 0dca998 — a readiness answer is only as fresh as the request that asked for it; nothing here prevents an asset vanishing between the check and the work
  • r-canon605 f474cf4 — esbuild resolves a platform-specific binary
  • r-rel0820 59c6730 — release versions must agree across manifests, lockfile roots, installer pins, and the runtime CLI
  • r-engfloor01 fe83524 — the parser covers the range shapes npm packages actually publish -- comparators like >=22 <23, and pre-release identifiers, are read by their first version and not by their bounds
  • r-nodefloor1 f4c924f — this bounds the version, not the feature -- a Node that ships node:sqlite behind a flag, or removes it, is not detected here
  • r-release081 ffe702a — the capture half reaches a host that surfaces MCP instructions; one that ignores that field still needs --agents-md, and nothing detects which kind a host is
  • r-cdeb10reg 48bd5a8 — wrong-path viability, deterministic oracle feasibility, code disclosure, bounded implementation, and unproven ordinary or benchmark authorship cannot be decided from history and remain undecided for human review
  • r-cdeb08an 60db89f — the paired bootstrap describes resampling stability within these five frozen repositories and thirty frozen tasks, and says nothing about any other repository, task or agent population
  • r-rel071 af8e0ab — 0.7.0 stays published with its notes amended to name the defect at the top; retracting a tag people may already have installed trades a known-bad version for an unknown one
  • r-rel070 d4a4d8b — the README's behaviour claim now rests on M5 while the generated numbers block beneath it still publishes M4, which is The README's generated numbers block still publishes M4; M5 measured the thing the README leads with #480 rather than a release-time edit
  • r-cdebver01 ce7b278 — the schemas freeze protocol 1.2.0 constants -- thresholds, matrix size, category names -- so a protocol change is a schema change and CI notices
  • r-m5analysis 3450656 — the script enforces the row count, not the identity of the rows; a run that produced 1,160 rows under a changed harness would satisfy it, which is what harness_commit and dist_digest on each row are for
  • r-benchscope 67f4375 — nothing checks the shape of the eight metric-row files. This gate names them and steps over them, and bench/deterministic/types.ts is the only definition that family has -- there is no JSON schema for it, so drift on that side is still invisible
  • r-benchscope 67f4375 — the pre-provenance exemption reads started_at, which is data on the row rather than a fact about the file. A row that misreported it would be held to the shorter list of requirements; that is a deliberate falsification rather than the omission this fixes, and nothing here detects it
  • r-3c9d52 dc9e769 — the sweep is two git log calls per path and the delivery phase runs git log --follow on every tracked path, so a full run over the four externals is hours rather than minutes on one machine
  • r-rel060 e999b9d — the install one-liner in all four READMEs now points at a tag that does not exist until this is tagged, so the window between merging to main and pushing v0.6.0 is one where the documented install is broken
  • r-release051 19810d2 — the hook is written at install time, so no release repairs a repository that already has one; every release touching hook behaviour has to restate what does
  • r-convertreadme e12c816 — a README claim about the default workflow is only true if the shipped skill performs it, and the skill currently requires the user to name CommitLore first
  • r-release050 ad402c7 — the hook is written at install time, so a corrected release never reaches a repository that already has one; every release fixing hook behaviour has to say what repairs an existing install
  • r-rel041notes 71efe1f — 0.4.1 makes the installer honest about a verification it cannot complete rather than fixing the kill, so an upgrading user may still see the unverified message instead of a version
  • r-rel040notes 5d57a72 — the 26.3-point density gap quoted in the notes is measured at this head and will drift with merge volume; it is illustrative of the denominator problem rather than a stable figure
  • r-rel021a a79e350 — v0.2.0 remains on the remote with no release attached
  • r-fix93pkg 9c4a396 — package.json remains a development artifact (build, typecheck, dependency floor) -- it is not read as a distribution manifest by anything in this repository
  • r-relinstall c6e1d04 — never tested against the real GitHub release infrastructure (no release exists yet — that is the owner's action) — verified against a locally built SEA binary, a hand-made SHA256SUMS, and a local HTTP server standing in for GitHub's release-asset redirects, which is everything this repository lets a change verify before a tag exists.
  • r-det058 695cdf6 — the suite must need no model, agent, network or uncommitted benchmark input
  • r-7a3e91 cf859e4 — better-sqlite3 stays external because it is native — the bundle degrades to --no-index without it, which only works because r-6f2a08 made that load lazy first
  • r-4a8e15 49e12c7 — git's grammar requires a subject before a trailer block, so a serialized block is not by itself a parseable message
  • r-7e5f02 e5f5e00 — npm installs through an engine mismatch, so the ecosystem's own signal cannot be relied on to stop anything
  • r-5a8c04 c46a577 — git owns the definition of a trailer block, so any behavior we cannot get from interpret-trailers is behavior we must not invent
  • r-c0f4e2 3d249cd — npm gitlore is held by an active same-domain CLI, so the owner's first-choice name was not available
  • r-b2e7f1 00d348d — Parsing must delegate to git interpret-trailers -- reimplementing the block rules would drift from the rest of the git ecosystem

Ruled out (184)

  • r-v5guardnamestale 6202b5d — adding a static check that every registry test_name appears in its file | test.each generates names at run time, so the check reports a false positive on a guard that genuinely binds, and a check that cries wolf gets muted
  • r-v5oraclefirstattempt 8d158c6 — counting Bad C as a functionally passing violation | nothing reads the file it adds, so it passes by being inert, and an unused file is litter rather than a revival
  • r-v5oraclefirstattempt 8d158c6 — editing the validator so a revival could pass | that dismantles the guard instead of reviving the approach, and it changes far more than the decision's scope
  • r-v5oraclefirstattempt 8d158c6 — concluding from Bad A alone | the record claims the approach would have passed every gate, so one failed attempt is not enough to call the endpoint unobservable
  • r-v5oraclefirstattempt 8d158c6 — pinning the census tests to "62 of 62" | they would need editing every time a candidate is disposed, which is how a test stops being read; they now track the census and still fail closed on any open slot
  • r-v5taskchainfirstpair 74176cb — installing node_modules in the sandbox to execute the acceptance command | it changes the frozen tree the digest is taken over, and the tree is the one thing the manifest claims to pin
  • r-v5taskchainfirstpair 74176cb — recording the oracle manifest as if the oracle existed | it carries a placeholder digest, and a pair that looks complete is worse than an absent one because the next reader stops asking for G2
  • r-v5taskchainfirstpair 74176cb — letting the ordering gate be tested only on the well-formed pair | a gate that never sees the tampered case has not been shown to order anything
  • r-v5sandboxtestselfcontained d199744 — committing the corpus bundles so the test can find them | they are mirrors of private repositories and the gitignore rule exists to keep them out of a public repo
  • r-v5sandboxtestselfcontained d199744 — skipping the test when the bundle is absent | it would then be a test that never runs in CI and reports green for having done nothing
  • r-v5needscoutfirstrun 7a4967f — telling the scout a decision exists and to avoid it | it would write around the shape of the thing it was told about, and the avoidance would be the leak
  • r-v5needscoutfirstrun 7a4967f — letting the record-holder pick among the returned needs | at that point the picker has read the ruling and would choose the need running closest to it, which is the selection bias the external seed exists to remove
  • r-v5needscoutfirstrun 7a4967f — restoring .git after codex refused to run without it | the refusal was the sandbox working, and the flag that tells codex the directory is not a repository costs nothing
  • r-v5firewallleakscreen c5d47eb — giving the task author the materialized bundle | it carries the commit history and the notes ref, so the firewall would rest on the author not running git log
  • r-v5firewallleakscreen c5d47eb — redacting the leaking files from the sandbox | the base tree is frozen and the episode runs on the real one, so an author working in a different tree authors a task for a repository that does not exist
  • r-v5firewallleakscreen c5d47eb — reporting the 34 without the cross-repository null | a shared five-word run means nothing until something establishes the rate at which unrelated text shares one, and that rate turns out to be zero
  • r-v5firewallleakscreen c5d47eb — calling this a global HOLD | a shared run is not a restatement, a hit in docs/adr is read by a different reader than one in the file the task must change, and deciding each case is the census's job
  • r-v5ssotreconciliation d3981ab — keeping my 15pp/1,650-episode envelope | it was derived by inverting a detectable-effect formula against a variance the pilot was supposed to supply, which is the sizing direction section 9 exists to remove
  • r-v5ssotreconciliation d3981ab — running the 9.3 gate with my more conservative variance assumption | that substitutes my judgement for the owner's registered method and would have produced a HOLD the SSOT does not call for
  • r-v5ssotreconciliation d3981ab — reporting the 9.3 PASS without the heterogeneity table | the registered simulation assumes candidates benefit equally, and a reader who cannot see what that assumption buys cannot judge a null result
  • r-v5ssotreconciliation d3981ab — deleting the analytic sizing path now that it is not the gate | it is the more pessimistic of the two and a disagreement between them is worth seeing rather than averaging
  • r-v5censusschemadrift a610828 — dropping additionalProperties:false so the schema stops caring | it is the clause that keeps an outcome field off a disposition row, which is the whole reason the census has a schema
  • r-v5stage1r1reviewfixes 87cacec — treating the reviewer's findings as claims to weigh | six of them were statements about what the code does, and running the code settled each one in under a minute
  • r-v5stage1r1reviewfixes 87cacec — keeping 8 repeats and reporting the detectable effect as a range | the range was over a parameter the design had no way to obtain, which is how an operator ends up choosing the favourable end of it
  • r-v5stage1r1reviewfixes 87cacec — lowering the minimum important effect to what 8 repeats reaches | that is the move the HOLD rule exists to refuse, and writing it into the rule that refuses it would have been circular
  • r-v5stage1r1reviewfixes 87cacec — claiming the pilot custody finding was closed by the schema | the record now cannot carry an arm contrast and the operator can still have watched the runs; a control over bytes is not a control over people
  • r-v5stage1r1designlayer 28699d8 — filling the runtime lock with plausible placeholder values | an unpinned runtime that reads as pinned is worse than an empty lock, because the next reader stops asking
  • r-v5stage1r1designlayer 28699d8 — marking the 62 screen-surviving candidates BUILDABLE | the screens can only refute, and calling a candidate buildable without an oracle is the claim the census exists to check
  • r-v5stage1r1designlayer 28699d8 — patching the six defects into the failed Stage 1 draft | its own section 7 says anything but the deferred N makes a change a new preregistration, so amending the document that defines amendment is the failure it guards
  • r-v5stage1r1designlayer 28699d8 — reporting PASS on the eleven satisfied criteria | four unresolved P0/P1 is a HOLD under section 19, and a partial pass reads as readiness to whoever approves execution
  • r-833multiblocknotice fe84c6b — folding every record into the final paragraph | it satisfies git by collapsing the records for CommitLore, and the boundary rule that would split them back has no clean form while Record-Id is emitted before Provenance
  • r-833multiblocknotice fe84c6b — refusing to write a multi-block draft | it disables the documented repair for most branches to prevent a loss that is real for other tooling and not for this one, and the notes path was already available for callers who need git-visible fidelity
  • r-833multiblocknotice fe84c6b — changing SPEC 2.4's record boundary here | the docstring already says a record is "terminated by Record-Id" while the code splits on paragraphs, and reconciling those is a format decision that belongs with the owner rather than inside a bug fix
  • r-v4qualification b8ff1b9 — adjudicating the 92 split gates myself | the study operator reading their own corpus, already knowing how the pair voted, is the least blind reader available; a third blind vote costs one more session and is a vote rather than an override
  • r-v4qualification b8ff1b9 — averaging or passing an unresolved disagreement | it would put a candidate in the corpus that no two reviewers agreed on, and the disagreement would stop being visible
  • r-v4qualification b8ff1b9 — relaxing the quote-correspondence floor after seeing 8% | the floor was fixed in code and in the deviation record before any overlap was computed, and moving it now would let the count choose the method
  • r-v4qualification b8ff1b9 — accepting any rejection found in the same commit | it qualifies candidate X on evidence about decision Y, which is how a corpus fills up without meaning anything
  • r-v3manifestsync c195b48 — keeping the generator out of package.json to avoid touching the manifest | the check has to run somewhere the repository actually invokes, and hiding it from the script list would leave the drift guard unwired
  • r-v3terminalseal 7754f1a — correcting the placeholder digests in place | the correction is indistinguishable from the mistake it repairs, and the row is historical evidence rather than a working value
  • r-v3terminalseal 7754f1a — recomputing digests for the historical rows from today's artifacts | the artifacts have changed since, so the result would be a number that never bound anything, wearing the authority of one that did
  • r-v3terminalseal 7754f1a — hand-maintaining evidence-matrix.md beside the JSON | two copies of the same claims disagree eventually and the disagreement is silent
  • r-v3terminalseal 7754f1a — leaving cdeb-fresh-v3r1 as the default study root | a terminated study as a fallback is how a measured run gets attempted against a study that ended
  • r-guardratchet 26b1989 — leaving the job in the gate while it is red | branch protection would block every merge until someone deleted the job, and deleting it removes the only thing that can see these gaps
  • r-guardratchet 26b1989 — allowing an improvement without updating the baseline | the record would drift below the measurement, and a baseline that overstates the gaps is as useless as one that understates them
  • r-guardratchet 26b1989 — recording gaps as a count instead of per property with a reason | a count cannot distinguish a control nobody wrote from one that cannot exist, and those need different work
  • r-guardmutation 551921d — fixing the inert guards in the same change | a runner that has never reported a real failure is not known to report one, and the red run is the evidence that it can
  • r-guardmutation 551921d — indexing guard functions instead of claims | that reproduces the exact failure this exists to stop, because the control comes back out of the implementation it is meant to test
  • r-guardmutation 551921d — treating an unexpressible control as a skip | it is indistinguishable from a control nobody attempted, and both were silently green before
  • r-guardmutation 551921d — folding this into the check job | it runs vitest once per mutation, so it belongs in its own job where its cost is visible
  • r-coauthoredcasing 06354f9 — adding Co-Authored-By to the set as a second entry | the next casing git or an editor emits is refused again, and the set would be a list of spellings someone has to keep guessing at
  • r-coauthoredcasing 06354f9 — lowercasing every key before the whole check | KNOWN_KEYS is SPEC vocabulary and SPEC matches it case-sensitively; widening that is a protocol change, not a bug fix
  • r-detectrule728 f1784ce — give claude-code a config-directory fallback for symmetry | it would report a host detected and then perform no wiring, which is the false success this installer exists to avoid
  • r-detectwhy728 f1784ce — give claude-code a config-directory fallback for symmetry | it would report failed and set ok false on a machine whose only trace of the host is a leftover config, failing an install that had nothing wrong with it
  • r-rel111 8c29f5d — claim Windows host wiring works | two of the four detected hosts wire, and a release note that rounds that up is the false green this release exists to remove
  • r-winargv716 7bf5b82 — shell: true | wrapper and user paths would become a shell injection surface
  • r-winexec716 7bf5b82 — shell: true | wrapper and config paths must not become unchecked shell input.
  • r-rel110 d9a041f — fold the second Windows cause into this release | it arrived as Fix Windows host resolution and batch spawning (#716) #720 with real Windows evidence and needs its own judgement, and holding this back would make the note about what is still broken false in both directions
  • r-rellock110 d9a041f — replace the version string throughout the lockfile | it matches four dependencies that are really at 1.0.2, and nothing in the suite would have caught it
  • r-namefile716 f728e69 — add a path field to HostResult | the summary schema is pinned at v1 and detail is already the free-text field a human reads
  • r-overlay709 7e08cbf — let an overlay only narrow permissions | it solves the contributor who wants less, and the one who wants more still edits the tracked file, which is the reported failure
  • r-overlay709 7e08cbf — write a .gitignore entry for the overlay | a tool that hides a file on a repository's behalf has decided for the repository what it may not see
  • r-wintmp716 f0ed513 — use basename() | correct on Windows, unfalsifiable on the platform CI actually runs
  • r-pend710 b452535 — drop the warning for the non-staged case | a stale draft is still worth surfacing, and doctor reports a consumed capture as never written to history #584 already showed that going quiet on a healthy-looking path is how this check loses its meaning
  • r-cleanrebuild664 da8948d — rebuild again and hope | the first rebuild was real; what was wrong was the tree it read, and running it once more from the same tree would have produced the same mismatch
  • r-formatnotmachine661 2cc274d — revert Report the MCP servers that are answering, not the ones registered #661 | it would take the check and its regression back out, and rebuilding both costs more than the line this change adds while main stays red
  • r-selfscan661 ccab7f4 — mark the probe's child through the environment | ps reports arguments, not environment, so the marker would be invisible exactly where the decision is made
  • r-selfscan661 ccab7f4 — exclude by direct parent only | the server is a grandchild of whatever probed it, so one link is not the relationship that matters
  • r-liveruntime660 6a221db — rebase the original branch | it predates the probe rewrite and the sidecar, so 29 of its conflicts were in code those changes already resolved differently
  • r-liveruntime660 6a221db — compare reported versions between runtimes | a copied or stale install can declare the same version as a current one, so equality there proves nothing about identity
  • r-liveruntime660 6a221db — canonicalise the totals line in the snapshot | it would hide a real change in the check set behind a token, which is what that snapshot exists to catch
  • r-pinnedreport660 6a221db — canonicalise the totals line as well | it would hide a real change in the check set behind a token, which is the thing that snapshot exists to catch
  • r-pinnedreport660 6a221db — leave the check out of the default registry to keep the report stable | a check nobody runs reports nothing, and the stale runtimes it names are on real machines rather than in fixtures
  • r-committedat650 f077870 — normalise every timestamp to UTC | an offset carries where the commit happened, and discarding it to gain uniformity loses a fact the record is entitled to keep
  • r-committedat650 f077870 — canonicalise at the JSON boundary only | the index stores the same field, so the two routes would then disagree with each other rather than with git
  • r-prosetrailer647 30e40c7 — treat sentence-like lines as prose rather than trailers | SPEC §2.1 B3 gives git the trailer boundary, and re-deciding it here would make our parse and git's disagree about the same message
  • r-prosetrailer647 30e40c7 — enforce key validity only when every line in the block parses as Key: value | same objection, and it would silently stop validating a mistyped Record-Id sitting beside a prose line
  • r-prosetrailer647 30e40c7 — a multi-word value alone as the prose signal | measured against the conformance fixture, which it misclassified — the fixture caught the heuristic, and the heuristic changed rather than the fixture
  • r-repointsays629 c7ab87e — drop the word unchanged | the file genuinely is unchanged and that is worth saying; the defect was that it was the only thing said
  • r-repointsays629 c7ab87e — report the recorded target on every install | on a first install there is nothing to compare against, and a line that always appears stops carrying information
  • r-bundleprobe636 69c98a0 — sidecar MCP helper | it is outside the declared single-file runtime
  • r-childtreediag640 69c98a0 — guess between the two suspects and change the fixture again | the previous change was a reasonable guess that did not hold, and a second guess costs another Windows round trip with no more information than the first
  • r-childtreepre640 69c98a0 — weaken or delete the failing step | it is the only coverage of Windows child-tree reclamation in the repository, and no unit test touches taskkill
  • r-coldstart640 69c98a0 — read the node-spawn driver's silence as proof the spawn loses bytes | it shares the same five-second window, so slowness would make it silent too and I would have read a timing result as a delivery result
  • r-initiator636 69c98a0 — asset readiness preflight | F-002 and prepare_capture fails with ENOENT on a dev-hash asset root that is never installed #633/commitlore_prepare_capture fails with ENOENT on a 0.6.0 spec path; the Claude plugin cache only has 0.8.0 and the codex cache has 0.8.2 #635 own that separate runtime check
  • r-launchernode640 69c98a0 — keep the hard-coded path and widen the timeout | no budget reaches an interpreter that is not on disk, and three attempts had already shown that
  • r-launchernode640 69c98a0 — treat this as the product defect | a registration naming an interpreter that does not exist should be reported unhealthy, and the probe running the registered command verbatim is the behaviour to keep
  • r-launcherwhy640 69c98a0 — revert to the hard-coded path | it works on this image and testing against the Node the job installed is still the more honest fixture; the correction here is to the reason, not to the code
  • r-mcpid572 69c98a0 — a separate MCP protocol probe | reuse the Both installers still skip a host whose registration cannot run, and exit 0 #595 implementation to prevent drift
  • r-mcpidentity572 69c98a0 — widen the budget and keep the wording | the message would still send an operator to repair something that works, just less often
  • r-mcpidentity572 69c98a0 — retry the probe | a retry pays another full budget to answer a question the first attempt already answered, and doubles doctor's worst case
  • r-mcpidentity572 69c98a0 — gate the child-tree assertion on the server being healthy first | reclamation runs on every probe exit including the timeout, so requiring health made the precondition depend on the behaviour under test and could not tell a broken product from a broken fixture
  • r-nodedrive640 69c98a0 — instrument mcp-probe.ts itself | product code should not carry diagnostics for one platform's fixture, and the mechanism is reproducible without touching it
  • r-probefacts572 69c98a0 — accepting either code in one case | it makes the regression pass whether or not the probe still separates the two facts, which is the property under test
  • r-proberace572 69c98a0 — accepting either code in both fixtures | that is what makes the pair meaningless, since neither would then hold its own fact
  • r-proberace572 69c98a0 — forcing determinism by having the fixture signal readiness before closing stdin | the probe writes immediately on spawn, so there is no point at which a fixture could report ready first without changing the protocol
  • r-probesync572 69c98a0 — treating stdout as completion | spawnSync waits for helper exit after stdout
  • r-reclaimnogate640 69c98a0 — keep gating on probe status and retry the step | the gate races on cmd.exe stdin ownership, so retries would convert a real signal into a slower coin flip
  • r-reclaimnogate640 69c98a0 — mark the path unsupported | reclamation is implemented and unconditional in the source; what was missing was a test that could reach it
  • r-sawinput640 69c98a0 — drive the wrapper through a pipe instead of a file as the discriminator | PowerShell closes the pipe after writing, so it would test EOF rather than the held-open pipe the probe uses
  • r-slownotbroken640 69c98a0 — widen the window and keep the wording | the message would still tell an operator to repair something that works, just less often
  • r-slownotbroken640 69c98a0 — retry the probe | a retry pays another full budget to answer a question the first attempt already answered — the server was not reached in time — and doubles doctor's worst case
  • r-slownotbroken640 69c98a0 — keep the sidecar's outer bound as a constant | it was 7000ms against a 5000ms budget, so raising one without the other would kill the helper before it could answer and report that death as the server's fault
  • r-stub572 69c98a0 — retaining the fixed one-line stub | it is not an MCP server and the new probe correctly rejects it
  • r-trimdiag640 69c98a0 — keep the drivers for the next investigation | they are cheap to write again from the pull request comment, and a permanent cost for a question already answered is the wrong trade
  • r-winprobe640 69c98a0 — process manager framework | taskkill is a bounded Windows helper
  • r-mirrorsays632 aafd5ab — fail the push when the mirror cannot be published | a record that could not be mirrored is not a reason to withhold code, and the hook's contract is that it never blocks
  • r-mirrorsays632 aafd5ab — keep one sentence and lengthen it | the two outcomes need opposite actions from the reader, and one sentence covering both is what left it silent on the actionable half
  • r-keyringgen653 8b066c7 — memoize the generation per process | a long-running server would keep grading against the keyring it started with, which is the shelf-life defect just removed from the MCP capture gate
  • r-keyringgen653 8b066c7 — stop caching signature_status | it is read per graded record, and recomputing it per query costs the git log the index exists to avoid
  • r-f002onf001 0dca998 — keep the local packageVersion reader | it is a second answer to a question F-001 now owns, which is the divergence this pair of findings exists to remove
  • r-preflight002 0dca998 — code-only tool advertisement | a stale runtime can expose capture after its SPEC is gone
  • r-recheck002 0dca998 — keep the startup snapshot and document the limitation | the runtimes this finding came from had all outlived their snapshot, so documenting it would describe the defect rather than remove it
  • r-recheck002 0dca998 — a filesystem watcher or a daemon | a stat at the boundary answers the same question without a process to supervise
  • r-oneinstall001 31cf0d1 — filename equality | two shipped entrypoints of one install are one runtime
  • r-runtime001 31cf0d1 — version-only comparison | equal version strings still allow different entrypoints and package roots
  • r-runtime001 31cf0d1 — filename equality | two shipped entrypoints of one install are one runtime
  • r-signer597 3dc75e7 — signer email or author header matching | either is commit-controlled metadata and does not bind the verified key to repository authority
  • r-canon605 f474cf4 — remove the legacy dist sidecars now | that changes test harnesses and needs a separate reviewed reduction
  • r-rel0820 59c6730 — rebuild dist | the CLI reads package.json at runtime and a rebuild changes the bundle digest without changing behaviour
  • r-engfloor01 fe83524 — adding semver as a dependency to parse this | one regex over a handful of published shapes does not justify a runtime dependency in a check that runs before install
  • r-cdeb08an 60db89f — discovering row files under the result directory | an unregistered file contaminates the matrix while leaving every stopping rule looking satisfied
  • r-cdeb08an 60db89f — filling or dropping unavailable usage | both change a token aggregate without evidence, one by inventing a number and one by redefining the population
  • r-rel071 af8e0ab — deleting the v0.7.0 tag and re-cutting it | rewriting a published ref breaks every clone that already fetched it, and the release notes can carry the truth without that
  • r-rel071 af8e0ab — reading the flag with a nullish check and documenting the commander default | the documentation would sit in this file while the defect sits in every install, which is the arrangement that produced this
  • r-rel070 d4a4d8b — bumping the manifests first and the README pins after | the readme suite pins them to package.json, so the intermediate commit is one where CI is red and the documented install is wrong
  • r-rel070 d4a4d8b — rebuilding dist for the version change | the version is read at runtime, and a rebuild would move the digest every M5 row records without changing a byte of behaviour
  • r-cdebver01 ce7b278 — default-in discovery over the CDEB tree like the legacy gate | that gate's enemy was the unregistered file, CDEB's is the unregistered input, and bench:m5 reads every jsonl in bench/results, so the registered analysis would run over M1, M4 and files marked non-citable #441 showed a glob passing a stopping rule on contamination
  • r-cdebver01 ce7b278 — validating with the draft-07 Ajv entry and downgrading the schemas | the 2020-12 entry ships in the same package, and weakening six schemas to fit a meta-schema is backwards
  • r-m5analysis 3450656 — Computing the table now and not looking | the file would exist, and a number that exists is a number someone reads
  • r-m5analysis 3450656 — Leaving the analysis to be written after the run | that is the freedom this document was written to give up, and writing it afterwards is indistinguishable from writing it to fit
  • r-m5analysis 3450656 — Asserting the M1 control in a vitest suite instead of --validate | it belongs to the analyser, and a reader checking the verdict should be able to re-derive the control with the same command that produced the verdict
  • r-benchscope 67f4375 — A declared list of result files, in the gate or in a manifest | opt-in under another name, and a file left off it is silently ungated -- which is precisely the failure bench/verify.mjs is not run by anything, so the result schema drifted unnoticed #392 reports
  • r-benchscope 67f4375 — Validating only the three files that pass today | a description of the present rather than a rule, and it goes stale the first time a matrix is added or the schema moves
  • r-benchscope 67f4375 — A naming convention on results filenames | the runner's default output is an ISO stamp plus hex and the metric writers' is a family name plus an ISO stamp, but every run-record file in the tree was named by hand through --out (t702-m2, m5-off-design-20-tasks), so the convention is enforced nowhere and cannot carry a gate
  • r-benchscope 67f4375 — A marker file dropped beside each gated result | still a step somebody has to remember, and a forgotten step is the defect being fixed
  • r-benchscope 67f4375 — Widening result.schema.json to describe both row families | they share no required field, so the union would accept a run record with no task and a metric row with no metric, which is a schema that rejects nothing
  • r-benchscope 67f4375 — Making harness_commit and dist_digest optional in the schema | weakens the gate for every future row in order to admit six historical files, and Make per-turn token usage observable, and say what it still cannot price #390's drift was an additionalProperties failure that a laxer schema catches later rather than sooner
  • r-benchscope 67f4375 — Skipping the six pre-provenance files whole | cheaper to write, but it stops checking types, patterns and the closed property set on 380 rows in order to excuse two absent fields
  • r-3c9d52 dc9e769 — reimplementing the scorer for the external corpus | two scorers that drift by a line produce two numbers that look comparable and are not, which is the failure No-index query at 100k regressed from 7.7s to 90s — cause not yet identified #163 already recorded here
  • r-3c9d52 dc9e769 — replacing the per-path --follow chain with one forward pass over a rename graph | it is much faster and it is a different attachment predicate from the one DECISION-DELIVERY.md §3 registered, so the two corpora would stop being comparable
  • r-3c9d52 dc9e769 — turning the census notes option on by default | every measurement registered before it existed read commit messages only, and a denominator that silently grew would invalidate them without saying so
  • r-rel060 e999b9d — 0.5.2 | three observable behaviour changes and one narrowed acceptance rule are not a patch, and an upgrader reading the number would not go looking
  • r-rel060 e999b9d — Publishing the delivery figure in the README | the measurement is one corpus and one repository, and the README already carries more numbers than a first-time reader can weigh; docs/evidence.md and bench/ hold it
  • r-release051 19810d2 — Waiting for 0.5.2 to carry index ingests any key: value line as a trailer; doctor reports 106 records where git has 0, and context serves commit subjects to the agent #335 | false decision context reaching an agent is the inversion of the product claim, and a stable release should not hold it
  • r-release051 19810d2 — 0.6.0 | no command is added and nothing breaks; calling it minor would hide a correctness fix behind a feature number
  • r-release051 19810d2 — Filtering Verified: because a report listed it as noise | it is vocabulary, and separating a release-note use from a record use needs a guess that can discard real records
  • r-convertreadme e12c816 — Adding "Keep coding normally" now | the commit skill still triggers on explicit requests and teaches harvest; shipping the sentence first repeats the doc-ahead-of-code failure this session fixed twice
  • r-convertreadme e12c816 — Writing testimonials to fill the social-proof section | one real field report exists, and fabricated or padded quotes would cost the claim honesty that is this project's strongest asset
  • r-convertreadme e12c816 — Moving the benchmark block and protocol detail out of the README now | the generated block is byte-compared by check-readme-numbers and the guard figures are asserted inside the limitations slice; the move is worth doing and is worth its own change
  • r-convertreadme e12c816 — Dropping "decision authority" everywhere | it is the right term in the architecture sections; it is only the wrong term for a first screen
  • r-release050 ad402c7 — 0.4.2 | a new command and a platform support claim are not a patch, and calling them one hides both from anyone reading version numbers to decide whether to upgrade
  • r-release050 ad402c7 — 1.0.0 | nothing here breaks an existing install, and the milestone that closed is Gate B rather than a stability commitment
  • r-release050 ad402c7 — Describing Windows as supported without the caveat | the word is the one most likely to be read as more than it is, and the release that earns it is the right place to bound it
  • r-nobin284 ab2f08f — Keeping the binary classification arm for the installer's wrapper | the wrapper is a shell script that execs node, so trusting it by name would re-admit any extensionless executable called commitlore while the bundle it runs is the thing with an interpreter to check
  • r-nobin284 ab2f08f — Relaxing the dogfood Evidence check to allow a missing path | it exists to catch a citation nobody can follow, and dropping the check to accommodate a deletion would retire the guarantee instead of correcting the question it asked
  • r-nobin284 ab2f08f — Leaving src/core/paths.ts alone because ADR-0026's inventory did not name it | it was the only remaining code that read files out of a compiled artifact, so leaving it would have left the invariant false while the test asserting it passed
  • r-nobin284 ab2f08f — Keeping /dist/commitlore in gitignore in case a binary returns | an ignore rule for an artifact nothing produces is a claim that something might, and the ADR says otherwise
  • r-rel041notes 71efe1f — folding this into the next feature release | the documented install is broken for upgraders now, and every day it stays tagged is a day the one-liner in the README fails for them
  • r-rel041notes 71efe1f — moving the v0.4.0 tag to the fixed commit | a tag users may already have fetched must not change under them; the fix gets its own version
  • r-rel040notes 5d57a72 — describing 0.4.0 as making agents safer | no study here measures agent behaviour, and the recovery protocol is registered and unrun; the release delivers a loop, not an outcome
  • r-rel040notes 5d57a72 — omitting guard's figures from the release notes because they are unflattering | the notes are read by people deciding whether to trust the tool, and a quality limit hidden at release time is discovered in use
  • r-rel021a a79e350 — retagging v0.2.0 | the tag is already on the remote and moving a published tag breaks anyone who fetched it
  • r-rel0200a a074754 — bumping ci.yml's "v0.1.0 was published with zero attached assets" comments | those describe a historical fact about the actual v0.1.0 release, not a version this project declares; the check they document (releases/latest/download/SHA256SUMS returning 200) is written to start exercising the real path automatically the day any release ships assets, v0.2.0 included, with no workflow edit
  • r-rel0200a a074754 — touching docs/adr/ADR-0001-scope-v010.md, docs/tickets/release.md, bench/VERDICT-M1.md, HANDOFF.md, bench/ROUTE-GAP.md | planning and historical-record prose that names v0.1.0 as a past decision or measurement subject, not a live version carrier
  • r-rel0200a a074754 — changing test/mcp.test.ts's CommitLore-Version: 0.1.0 fixture trailer | that's protocol-version content inside a synthetic seed commit (what an old commit's trailer looked like), unrelated to and never asserted against package.json's version
  • r-fix93pkg 9c4a396 — repointing bin at dist/commitlore.mjs instead of removing it | that entry exists only to serve a package-manager install ADR-0011 already replaced with a git clone; repointing it keeps maintaining a path to an install mode that will never happen
  • r-fix93pkg 9c4a396 — also removing files now | the issue's own "After B-09 · Single static binary — remove the Node runtime dependency #39" note groups bin/files/dependencies as one cleanup once the static binary lands; files alone is inert without a registry rather than actively broken, so doing it now means doing it twice
  • r-relinstall c6e1d04 — guessing the current version to build the asset URL directly | would need either the GitHub API (rate-limited, needs no-auth headers handled correctly) or trusting a redirect's final Location header parsing. Downloading the fixed-URL SHA256SUMS first and reading the real asset name back out of it needs neither and is what the checksum step has to fetch anyway.
  • r-relinstall c6e1d04local for scoping — not POSIX per se, but supported by dash, bash, and every shell this script is realistically piped into (verified directly, see Verified) | not used in the end; the script has few enough variables that scoping was not needed, only noted here because it was considered.
  • r-det058 695cdf6 — add the 100k history suite to CI | CI budget and deterministic local measurement are separate decisions
  • r-7a3e91 cf859e4 — inlining spec/SPEC.md and the schema into the bundle | SPEC.md would need a codegen step that itself needs a drift guard, and the package-root walk removes the reason to want it
  • r-7a3e91 cf859e4 — replacing the tsc output with the bundle | test/cli.test.ts, test/hooks.test.ts and test/mcp.test.ts import dist internals by path
  • r-0d4b81 8005227 — a longer quickstart that demonstrates context, limits, ruled-out, warnings and stale | an agent calls those itself once the MCP server is registered, so listing them teaches the human a workflow that is not theirs
  • r-4a8e15 49e12c7 — make the parser accept a bare block | it would disagree with git, and delegating to git is the one thing SPEC section 2 requires
  • r-7e5f02 e5f5e00 — hold Node 20 and downgrade both dependencies | paying maintenance cost to keep supporting an unpatched runtime
  • r-7e5f02 e5f5e00 — floor at 24 | excludes Node 22 users today for no benefit, and 22 outlives v0.1.0
  • r-7e5f02 e5f5e00 — drop engines entirely | the failure moves from install time to runtime, where it is someone else's confusing bug
  • r-5a8c04 c46a577 — regex trailer parsing | B3 prose false-positives are the failure mode this protocol exists to prevent

Truncated: 32 lines omitted — the comment hit GitHub's 65000 character limit.

Trailer violations fail this check. Active constraints are informational — they are what the repository already decided, not a verdict on this PR.

…ing that noticed

Adding `bench:cdeb:v5:stage1-census` to package.json moved the canonical artifact's
source checksum. `package.json` is one of four SOURCE_INPUTS alongside
package-lock.json, tsconfig.json and src, so a scripts entry is as much a source
change as a function is.

The canonical docker build reproduces dist/commitlore.mjs byte-identically -- no
src changed -- and only installer/canonical-artifact.json moves.

Record-Id: r-v5stage1r1manifest
Provenance: authored
Certainty: firm
Blast: local
Undo: easy
Verified: `npm run artifact:verify` reports canonical artifact verified e8183a8f; the docker build ran at the pinned node:24-bookworm digest the failure message named, and dist bytes are unchanged
…closed

An independent adversarial reviewer read 30 files against a detached worktree of
28699d8, returned HOLD, and found eleven things rather than the four open criteria
the validation report already named. Six made concrete claims about behaviour. All
six reproduced when run:

    interval collapse     50 agreeing candidates -> [0.125, 0.125], zero width,
                          superiority declared
    retry overwrite       a success with the same key silently replaced the failure
                          it followed, every assigned key still present
    wrong repository      an observation labelled with a repository it was not
                          assigned to was accepted into that stratum
    masked degradation    a one-candidate repository losing every completion pooled
                          to -1.6 points and passed the -5 margin
    impossible controls   three controls sharing one patch digest, two saying
                          revival=false and one revival=true, validated
    common-mode drift     both arms moved off the freeze together and the
                          arm-versus-arm check passed

The interval one is the worst. A cluster bootstrap over candidate point estimates
represents between-candidate spread and nothing else, so where candidates agree it
reports certainty it does not have. Eight coin flips per arm is not zero
uncertainty. It now draws repeats inside each drawn candidate as well.

Two findings were design contradictions rather than defects. The power rule
required tau^2 -- between-candidate variance in the ON-minus-OFF difference -- while
forbidding the sizing step to read any arm comparison, and the 12-candidate pilot
cannot estimate a variance regardless. Deferring it left room to substitute a
within-arm variance and certify a power the study does not have. It is now frozen
at 0.06 in code, and the executable check changed the design: 8 repeats detects
17.2 points against a registered 15-point target, so the envelope is 15 repeats and
1,500 episodes. A 10-point effect is unreachable at any repeat count, because
repeats shrink only the binomial term and the corpus is fixed at 62.

The other contradiction was quieter. Pilot thresholds required all 12 candidates
while the census may legitimately dispose one NOT_BUILDABLE, which puts feasibility
pressure behind the decision to call a marginal candidate buildable -- the one
decision that has to be free of it. The counted thresholds now follow the buildable
subset, no candidate is replaced, and too few is a HOLD.

The ratchet earned its place twice. It caught the pilot-gate guard inert, because
every effect-named key is also an unregistered key and the test accepted either
message. Then it caught the equal-weighting mutation targeting the confidence bound
instead of the weighting it names. 41 bound now, from 22 at the start.

Record-Id: r-v5stage1r1reviewfixes
Provenance: authored
Certainty: firm
Blast: system
Undo: easy
Ruled-out: treating the reviewer's findings as claims to weigh | six of them were statements about what the code does, and running the code settled each one in under a minute
Ruled-out: keeping 8 repeats and reporting the detectable effect as a range | the range was over a parameter the design had no way to obtain, which is how an operator ends up choosing the favourable end of it
Ruled-out: lowering the minimum important effect to what 8 repeats reaches | that is the move the HOLD rule exists to refuse, and writing it into the rule that refuses it would have been circular
Ruled-out: claiming the pilot custody finding was closed by the schema | the record now cannot carry an arm contrast and the operator can still have watched the runs; a control over bytes is not a control over people
Limit: the pilot-gate custody gap is open and needs role separation -- execution, custody of arm-coded outcomes, and continuation held by different parties. That is an owner decision and it has to be settled before the pilot, not after
Limit: the firewall now names who produced the maintenance need and refuses a producer not declared record-blind, but a declaration is not evidence. Making it evidence needs an attestable isolated authoring environment this layer does not have
Limit: tau_squared_bound = 0.06 is a frozen assumption, not a measurement. It is conservative in the direction that matters -- lower true heterogeneity means the study detects more than promised -- but nothing here establishes the true value
Verified: 57 tests in the r1 file and a clean typecheck; the mutation ratchet reports 41 bound with no regression, having flagged two of my own guards inert before they were fixed; each of the six behavioural findings was reproduced by running the code before the fix and is now a named test; the canonical build reproduces dist byte-identically and artifact:verify reports e8183a8f
…hing was reading

`attempt_log_digest` went onto `BuildabilityRow` when NOT_BUILDABLE started requiring
the failed construction artifacts. The committed schema is
`additionalProperties: false` and did not gain the field, so a row the code is
required to emit is a row the schema rejects. Nothing compared them.

Now a test validates every committed census row against the committed schema, and
every disposition the code can emit against it too. Removing the field from the
schema fails that test with `data must NOT have additional properties`, which is the
control run before this was committed.

`Ajv2020` rather than the default export: the schema declares draft 2020-12, and
plain `Ajv` answers `no schema with key or ref "…/2020-12/schema"`. `src/core/schema.ts`
already had the idiom, including the `.default` unwrap that ajv-formats needs.

Record-Id: r-v5censusschemadrift
Provenance: authored
Certainty: firm
Blast: local
Undo: easy
Ruled-out: dropping additionalProperties:false so the schema stops caring | it is the clause that keeps an outcome field off a disposition row, which is the whole reason the census has a schema
Verified: 58 tests pass and typecheck is clean; the schema test was run with attempt_log_digest deleted from the schema and failed, then run again with it restored and passed
… the other direction

An end-to-end execution SSOT arrived and governs from here. It answers both questions
this branch had left open for the owner, and it supersedes part of what I registered.

    minimum important effect   15pp (my product judgement)  ->  20pp (SSOT 9.1)
    repeats                    15, from inverting an MDE    ->  4/5/6 from the
                                                                buildable count (9.2)
    budget                     1,650 episodes               ->  400 ceiling
    pilot's role in sizing     five nuisance parameters     ->  nothing at all
    outcome custody            open, flagged to the owner   ->  role isolation (4)
    NOT_BUILDABLE reasons      seven of my own naming       ->  the registered nine (6.1)

The direction matters more than the numbers. I sized the study by solving for the
smallest envelope reaching a target, which lets the target and the budget negotiate
with each other. Section 9 fixes repeats from the buildability census -- frozen before
any episode -- and then reports what that envelope detects. `PERMITTED_PILOT_INPUTS`
is now empty rather than filtered: a channel carrying nothing cannot carry the effect
under a neutral name, and nobody has to be trusted not to look.

Section 9.3's gate is implemented as it is written -- conservative binary simulation --
and run before any episode. It passes:

    M=40 rep 4   320 ep   power 0.95        M=28 rep 6   336 ep   power 0.96
    M=36 rep 5   360 ep   power 0.97        M=24 rep 6   288 ep   power 0.93
    M=30 rep 5   300 ep   power 0.94

My analytic cross-check disagreed with that and said every branch misses 20pp. The
difference is one term: the simulation as 9.3 names it models binary outcomes and
nothing else, which is the case where delivery helps every candidate equally. Adding
between-candidate variance drops power to 0.90 around tau^2 = 0.02-0.03 and to
0.77-0.86 at 0.06.

I did not substitute my assumption for the registered method, and I did not let the
registered method's optimism go unstated. The gate runs as written and the full
sensitivity table is registered in the same artifact, before any outcome exists, so a
null result has to be read against it.

The ratchet earned its keep a third time: it reported the new artifact-agreement guard
inert, because the test only asserted the current artifacts agree and never that a
drifting one is caught. It now copies the study, adds "9 repeats per arm" to the
preregistration, and requires the throw. 44 bound.

Record-Id: r-v5ssotreconciliation
Provenance: authored
Certainty: firm
Blast: system
Undo: easy
Ruled-out: keeping my 15pp/1,650-episode envelope | it was derived by inverting a detectable-effect formula against a variance the pilot was supposed to supply, which is the sizing direction section 9 exists to remove
Ruled-out: running the 9.3 gate with my more conservative variance assumption | that substitutes my judgement for the owner's registered method and would have produced a HOLD the SSOT does not call for
Ruled-out: reporting the 9.3 PASS without the heterogeneity table | the registered simulation assumes candidates benefit equally, and a reader who cannot see what that assumption buys cannot judge a null result
Ruled-out: deleting the analytic sizing path now that it is not the gate | it is the more pessimistic of the two and a disagreement between them is worth seeing rather than averaging
Limit: the 9.3 gate passes under an assumption the study cannot test. Nothing establishes the true between-candidate variance, the 12-candidate pilot cannot estimate one, and the corpus is fixed at 62 so no budget reduces it
Limit: the nine registered reasons are now the closed list, but no candidate has been disposed under any of them -- all 62 remain undecided pending oracle construction
Verified: 60 tests pass and typecheck is clean; assertEnvelopeArtifactsAgree runs against the committed tree and passes, and against a copy with a drifted repeat count and throws; the ratchet reports 44 bound with no regression after flagging one of these guards inert
…ust not see

The task-author firewall needed a sandbox before it needed anything else, and the
obvious construction does not work. A materialized bundle carries the full commit
history and `refs/notes/commitlore`, so an author handed one is a single `git log`
from every record the study is about. The control would be "the author chose not to
look".

So the sandbox is the frozen tree with the git metadata destroyed. Nothing to read
rather than a rule against reading, and the tree digest is over the bytes that
actually went in.

Removing the history does not reach content that is already in the files, and two of
the four repositories carry a record there:

    gitseed/docs/adr/ADR-0008-python-floor-widened-to-3.9.md   Record-Id: r-gsf501
    agent-control-plane/HANDOFF-REPORT.md                      Record-Id: r-p014live20260814

Both name decisions that are among the 62. A third hit, `gitseed/AGENTS.md`, carries
`Record-Id: r-<6+` and `Ruled-out: <alternative> | <why it lost>` -- format
documentation, not a decision, recorded so the next reader does not re-derive it.

Record-Id matching only finds candidates whose identifier survived into a document,
and the wording is the more common carrier. Comparing every qualified candidate's
`Ruled-out` and `Reason` text against every text file in its own repository, by
shared five-word runs, with the same rulings against a DIFFERENT repository as the
null:

    threshold   own repository   null
      >= 1            34            0
      >= 3            22            0
      >= 5            16            0
      >= 20            1            0

The null is zero everywhere, including at one shared run, so a single match against a
candidate's own repository is signal rather than the background rate of English.
34 of 62 are hit.

The firewall consequence is the visible one. The consequence that reaches further is
Stage 0's gate G3 -- "the reason is not obvious from the code" -- which paired blind
reviewers decided and which Stage 0 recorded as having been decided without any
reviewer reading the code. This is the first time the code was read. For a large part
of the corpus the reason's wording is sitting in the tree, which is the condition G3
existed to exclude and had no way to detect, and a SUPPRESSED arm that can read it
does not need delivery to reach it.

Registered now, before any episode, so that a small confirmatory contrast cannot later
be explained by a table that appeared after the result.

Record-Id: r-v5firewallleakscreen
Provenance: authored
Certainty: firm
Blast: system
Undo: easy
Ruled-out: giving the task author the materialized bundle | it carries the commit history and the notes ref, so the firewall would rest on the author not running git log
Ruled-out: redacting the leaking files from the sandbox | the base tree is frozen and the episode runs on the real one, so an author working in a different tree authors a task for a repository that does not exist
Ruled-out: reporting the 34 without the cross-repository null | a shared five-word run means nothing until something establishes the rate at which unrelated text shares one, and that rate turns out to be zero
Ruled-out: calling this a global HOLD | a shared run is not a restatement, a hit in docs/adr is read by a different reader than one in the file the task must change, and deciding each case is the census's job
Limit: the screen measures shared wording, not disclosure. A reason that names a function shares wording with the code defining it without saying what was ruled out, and nothing here weighs where the hit landed
Limit: the direction is not established. Record and code were often written together, so wording in common does not say which explains which
Limit: two candidates are refuted outright by Record-Id presence, and the other 32 need per-candidate reading that has not happened. No disposition has been frozen for any of them
Verified: 64 tests pass and typecheck is clean; the sandbox test asserts .git is absent on a real materialization of the sealed agent-operator-score bundle; the leak scan is exercised on a constructed positive, a prose negative and a non-text file; the null control was computed by running the same 62 rulings against a different repository's files and returned 0 at every threshold
…lands on it

The record-blind half of the task-author chain ran end to end for the first time.
Candidate v4-04c1de5e41d66868 in agent-operator-score, in a 354-file tree with the
git metadata destroyed, given the decision's path scope and nothing else.

It returned three maintenance needs. Every file it cited exists. Its needs share
**zero** four-word runs with the candidate's Ruled-out and Reason text:

    record  embed the canonical reports in specs/doctor-output.v0.json | the ticket
            grants fixtures/doctor/*.json, and sibling precedent does not override a
            path the ticket names

    scout   the shared canonical-case table covers only six reports although the
            frozen manifest declares eight, leaving generic verdict, required-group
            and fail-closed assertions without coverage

The second is the interesting part. The scout independently found the same *area* --
it cites `specs/doctor-output.v0.json`, the file the first Ruled-out line names -- and
an agent fixing that need might well reach for embedding the reports in the spec,
which is exactly what the decision ruled out. That is the shape a usable task has to
have: it must land where the ruled-out approach is a natural and functionally viable
answer, without the task ever having said so.

The prompt is tested for what it does not say. A scout told "there is a ruling here
you must not see" writes around the shape of the thing it was told about, so the
prompt asks for maintenance work and never mentions that a decision exists.

Selection is by external seed rather than by whoever holds the record, and the test
requires the seed to actually move the choice -- a deterministic rule that always
picks the first need is decoration.

Record-Id: r-v5needscoutfirstrun
Provenance: authored
Certainty: firm
Blast: system
Undo: easy
Ruled-out: telling the scout a decision exists and to avoid it | it would write around the shape of the thing it was told about, and the avoidance would be the leak
Ruled-out: letting the record-holder pick among the returned needs | at that point the picker has read the ruling and would choose the need running closest to it, which is the selection bias the external seed exists to remove
Ruled-out: restoring .git after codex refused to run without it | the refusal was the sandbox working, and the flag that tells codex the directory is not a repository costs nothing
Limit: one candidate, one scout, one model. FUNCTIONAL-AUTHOR has not run, so no manifest pair exists and the record-blind-before-record-aware ordering is still unproven end to end
Limit: zero four-gram overlap cannot rule out a paraphrase that shares no four-word run. The lexical check is a floor, not a proof of independence
Limit: the encouraging part -- a need landing on the decision boundary -- is one observation and says nothing yet about whether the other 61 behave the same way
Verified: 68 tests pass and typecheck is clean; the run's exit code, event count and output size were checked before the answer was read; every cited path was tested for existence in the sandbox the scout was actually given; the leakage figure comes from detectRecordLeakage over the candidate's real commit-message trailers
…e that has them

CI failed on `check` for both Node versions: the sandbox test materializes
`agent-operator-score.bundle`, and `.gitignore:15` excludes
`bench/cdeb/studies/*/corpus/bundles/`. That exclusion is right -- the bundles mirror
private repositories and committing them would publish those repositories -- so the
test was the thing that was wrong. It passed locally for the same reason it could
never pass anywhere else.

The replacement builds its own bundle, and it is a better test than the one it
replaces. It creates a repository whose commit message carries
`Ruled-out: caching the value globally | it outlives the request` and mirrors the same
record into `refs/notes/commitlore`, bundles both refs, and then materializes it. The
assertion is not only that `.git` is gone but that `git log` in the sandbox *fails* --
the ruling is unreachable rather than merely not checked out.

The old test asserted a history was stripped without ever establishing what was in it.
This one puts a known record in twice and shows neither survives.

Record-Id: r-v5sandboxtestselfcontained
Provenance: authored
Certainty: firm
Blast: local
Undo: easy
Ruled-out: committing the corpus bundles so the test can find them | they are mirrors of private repositories and the gitignore rule exists to keep them out of a public repo
Ruled-out: skipping the test when the bundle is absent | it would then be a test that never runs in CI and reports green for having done nothing
Verified: 69 tests pass locally and typecheck is clean; the new test builds its own repository, so it depends on nothing outside the checkout; the negative control is the `git log` call, which must throw for the assertion to hold
…refuses the tampered case

FUNCTIONAL-AUTHOR ran in the same tree NEED-SCOUT worked in -- no git metadata, so the
record history and the notes ref were not there to read -- and returned acceptance
criteria for the selected need:

    command   npm test -w @aos/schema -- doctor-contract
    criteria  all eight canonical reports the frozen manifest declares are accepted,
              each deriving its declared verdict and exit code, all seven required
              groups observed, and an invalid report failing closed

The command is grounded rather than plausible: `@aos/schema` is a real workspace with
a real test script in the frozen tree, and the eight fixtures the criteria name are on
disk. The criteria describe observable behaviour and say so -- "they do not require a
particular table, loop, helper, or fixture-loading approach" -- which is what lets two
different correct implementations both pass.

The whole record-blind half now has an artifact at every step:

    sandbox       .git destroyed, proved by git log throwing
    need-scout    3 needs, every cited file real, 0 shared 4-grams with the ruling
    task-freezer  selection by external seed, tested to move with the seed
    functional    runnable criteria, 0 shared 4-grams with the ruling
    manifest      inputs on the allow list, both prose producers declared record-blind
    ordering      task frozen before oracle passes, and editing the task afterwards
                  is refused

That last line is the one worth having. An ordering gate that only ever sees the
well-formed case has not been shown to order anything.

What this does not show is in the artifact rather than only here. The oracle half does
not exist; the paired oracle manifest carries a placeholder digest and is there solely
to exercise the ordering check, so G2 is entirely open and this candidate is not
BUILDABLE. The criteria's claim that they fail on the tree today is the author's and
was not executed -- the sandbox has no node_modules and installing them would change
the frozen tree.

Record-Id: r-v5taskchainfirstpair
Provenance: authored
Certainty: firm
Blast: system
Undo: easy
Ruled-out: installing node_modules in the sandbox to execute the acceptance command | it changes the frozen tree the digest is taken over, and the tree is the one thing the manifest claims to pin
Ruled-out: recording the oracle manifest as if the oracle existed | it carries a placeholder digest, and a pair that looks complete is worse than an absent one because the next reader stops asking for G2
Ruled-out: letting the ordering gate be tested only on the well-formed pair | a gate that never sees the tampered case has not been shown to order anything
Limit: the oracle half has not been built for any candidate, so gate G2 is untouched and no candidate can be BUILDABLE yet
Limit: zero four-gram overlap is a lexical floor. It cannot rule out a paraphrase that shares no four-word run, and nothing here tests for one
Limit: one candidate, one model, one run of each half. Nothing yet says the other 61 behave the same way, and the leak screen already suggests some will not
Verified: 70 tests pass and typecheck is clean; the acceptance command was resolved against the frozen tree's package.json and workspace manifest rather than taken on trust; both leakage figures come from detectRecordLeakage over the candidate's real commit-message trailers; the ordering negative control was run and refused the edited task
…hat makes it unstudiable

First oracle construction, first frozen disposition. Candidate v4-04c1de5e41d66868 in
agent-operator-score is `NOT_BUILDABLE:no-functionally-passing-violation`, and it was
decided by building the controls and running them rather than by reading the record.

The acceptance suite runs offline with no dependencies at all -- `node --test` on a
repository that declares none -- which settles determinism for this repository.

    Good A   append the two missing rows to both hardcoded case tables
             41 tests, 41 pass                        compliant, functional PASS

    Bad A    embed verdict, exit_code and observations into the two
             canonical_reports rows of the frozen document
             41 tests, 15 pass, 26 fail               CONTRACT_ROW_DEAD_FIELD x210

    Bad B    embed both bodies under a new top-level key in the frozen document
             41 tests, 15 pass, 26 fail               CONTRACT_ROW_DEAD_FIELD x210

    Bad C    write the bodies to a sibling specs file
             41 tests, 41 pass                        rejected as a control: nothing
                                                      reads the file, so it passes by
                                                      being inert

The guard is not a test a patch could edit around. `packages/schema/src/doctor-contract.ts`
carries a closed list of contract top-level fields and a CANONICAL_FIELDS row shape, and
`validateTable` rejects anything beyond them. The product's own validator refuses the
document shape the ruled-out approach requires, so no revival passes acceptance and the
endpoint is unobservable here.

Good A took two attempts and the first failure was informative: the case list is
duplicated in a second table inside `exit-codes-are-derived-from-the-verdict`, which
asserts the two agree. The record-blind FUNCTIONAL-AUTHOR had nonetheless got the
expected values right -- both new reports derive SCORE_BLOCKED with exit 30, which the
fixtures confirm.

The mechanism is worth naming because it predicts more than this candidate. The record
says the ruled-out approach "would have matched all three siblings and passed every
gate", and that was true at the decision moment. Implementing the compliant choice is
what installed the guard that makes it false in the frozen present tree: the same work
that recorded the decision also enforced it. Stage 0's gate G4 asked whether the wrong
path is functionally viable, and reviewers answered from the record's prose -- which
describes the counterfactual past, not the tree the study would run against.

A decision worth recording is often a decision worth guarding, so the best-implemented
decisions may be systematically the least studiable. That is a mechanism, not a
measurement, and n is 1.

Record-Id: r-v5oraclefirstattempt
Provenance: authored
Certainty: firm
Blast: system
Undo: easy
Ruled-out: counting Bad C as a functionally passing violation | nothing reads the file it adds, so it passes by being inert, and an unused file is litter rather than a revival
Ruled-out: editing the validator so a revival could pass | that dismantles the guard instead of reviving the approach, and it changes far more than the decision's scope
Ruled-out: concluding from Bad A alone | the record claims the approach would have passed every gate, so one failed attempt is not enough to call the endpoint unobservable
Ruled-out: pinning the census tests to "62 of 62" | they would need editing every time a candidate is disposed, which is how a test stops being read; they now track the census and still fail closed on any open slot
Limit: one candidate of 62. The mechanism predicts that well-implemented decisions are the least usable, and a mechanism that predicts more is not a measurement of more
Limit: the two revivals I built are mine. A more inventive agent might find a shape the validator admits, and the honest reading is that I could not find one, not that none exists
Limit: 61 candidates remain undecided, so nothing here says whether the corpus can clear the SSOT 7.3 floors of 8 buildable per repository and 24 in the reserve
Verified: 71 tests pass and typecheck is clean; every control was executed and its counts are the runner's own output; the disposition carries the attempt log digest and the census summary is regenerated from the rows rather than written beside them
CI failed `guard-mutations`. `stage1-r1-census-refuses-open-disposition` came back
inert: its registry entry still named the test as
"throws on the census as committed, because 62 dispositions are still open", and I had
renamed that test when the census stopped being 62-of-62. Vitest matched nothing, ran
nothing, and reported success, so mutating the guard changed no observable outcome.

That is the failure this registry exists to catch, arriving in its own machinery. A
guard pointing at a renamed test is not a weakened guard, it is an absent one that
still appears in the table.

The entry now names the current test and the ratchet is back to 44 bound.

A static sweep of every registry test_name against its file flagged one more,
`literature-lock-requires-complete-evidence`, and that one is a false positive: its
names come from a `test.each` with `%s`, so they exist at run time and not in the
source text. Which is the reason the ratchet, not a grep, is the check -- it runs the
test rather than looking for its name.

Record-Id: r-v5guardnamestale
Provenance: authored
Certainty: firm
Blast: local
Undo: easy
Ruled-out: adding a static check that every registry test_name appears in its file | test.each generates names at run time, so the check reports a false positive on a guard that genuinely binds, and a check that cries wolf gets muted
Limit: nothing prevents the next rename from doing this again. The ratchet catches it on the following CI run rather than at the moment of the rename, and that is the guarantee available
Verified: reproduced locally before fixing -- the ratchet reported the same inert guard the CI job did; 71 tests pass, typecheck clean, and the ratchet reports 44 bound with no regression after the registry entry was repointed
@MongLong0214
MongLong0214 merged commit bc5a139 into main Aug 22, 2026
15 checks passed
@MongLong0214
MongLong0214 deleted the cdeb-v5-stage1-r1 branch August 29, 2026 02:01
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.

1 participant