Skip to content

fix: bound the guard to the prompt's window, and name the runtimes still writing (#884, #885) - #886

Merged
MongLong0214 merged 3 commits into
mainfrom
fix/bounded-guard-and-runtime-visibility
Sep 8, 2026
Merged

fix: bound the guard to the prompt's window, and name the runtimes still writing (#884, #885)#886
MongLong0214 merged 3 commits into
mainfrom
fix/bounded-guard-and-runtime-visibility

Conversation

@MongLong0214

Copy link
Copy Markdown
Owner

Closes #884
Closes #885

Source only — no dist/, no installer/canonical-artifact.json. Please run canonical-merge.yml against this number and merge the canonical PR with a merge commit.

#884capture died with a fatal V8 error on a large transcript

Exit 133, zero bytes of stdout, on a 74,173,844-byte session. Not a refusal — an engine abort, which escapes the structural-outcome contract entirely: a wrapper careful enough to branch on staged / empty / rejected instead of $? had nothing to read.

1.2.3 bounded the prompt (#873) and did not bound the guard beside it. prepareValues passed the whole transcript to computeGuardAdvisory on one line and windowed it to 256 KiB on the next. guard normalises its proposal through normalizeForMatch, whose \p{Script=Latin}\p{M}* global replace collects one match per letter into a single array; past ~69 MB that array crosses V8's 2^27 FixedArray ceiling.

The failing frame was measured, not inferred. A static read of this path nominates the mapped += char accumulator two lines below — the more obvious suspect, and not what fails. The native stack:

Builtins_StringPrototypeReplace
  Builtins_RegExpReplace
    Runtime_RegExpExecMultiple
      FixedArrayBuilder::EnsureCapacity
        NewFixedArrayWithHoles(134217728)

A preload wrapping String.prototype.replace confirms it from the other side: the last subject over 1 MB before the abort is the whole transcript under /\p{Script=Latin}\p{M}*/gu, reached via tokenize from guard.

computeGuardAdvisory documents that it never throws and degrades failures to a recorded gap. That contract could not hold while the input was unbounded, because a fatal engine abort is not catchable — so the input stopped being unbounded rather than the catch growing.

What changes

  • The guard reads the same window the prompt carries. A narrowing, and the more honest alignment: the advisory is rendered beside the prompt, so computing it over a whole session could warn about a decision the prompt does not contain.
  • The window is computed once and handed to both, so a large transcript is split once rather than twice.
  • It says when it did so — a new proposal-windowed gap whenever the window dropped part of the session. An empty matches array then says something about the window rather than about the transcript.

Not fixed, deliberately

Verification still reads the whole transcript on purpose, so a quote from outside the window still verifies, and its scan() builds per-character structures over the whole file to do it. That survives 74 MB and would fail somewhere past ~134 M characters. Bounding it would break the guarantee that a locator names a line of the file it is checked against — the property #873 went out of its way to keep.

#885 — an upgrade does not reach live sessions

doctor reported three distinct live runtimes answering MCP while every registration on the machine was correct. It was right: those were live processes that outlived the upgrade, because a host resolves the launcher once at session start and holds that runtime for the life of the session.

Those runtimes write. Records captured by a session started two days earlier come from the build it started on, and nothing on the commit says which. The row named three versions and stopped, so an operator could not tell whether that was cosmetic. The scan already knew all five pids and discarded them on the way to a deduplicated identity string — the reporter had to run ps themselves.

What changes

  • The row groups pids by identity and names every one, says each runtime keeps writing records with the build it started on, and offers the action that actually helps: restart the host sessions owning those pids, because an upgrade cannot reach an already-running process. Reinstalling is not the fix and the row no longer implies it is.
  • It deliberately does not label any runtime the stale one. r-liveruntime660 ruled that out — a copied or stale install can report the same version as a current one — and a test asserts the row says no such thing.
  • Severity stays warn and needsAttention stays false. This observes the machine, not the checkout; init.test.ts fails on any machine with a stale CommitLore MCP server running #750 is the measured cost of letting another process decide a repository command's exit code.

Incidental, from the same report

upgrade said latest v1.2.3 on a machine running 1.2.5, plus "this is the newest release". The lookup was never wrong — the answer is cached for a day and only upgrade acting clears it, so a release installed any other way leaves yesterday's answer standing and the command reports a tag older than the binary printing it. A latest older than the running version cannot be the latest; that case now re-asks. Equality still serves from the cache, or the cache would never serve the case it exists for.

Not addressed — needs its own decision

#885 also asks that the producing runtime be recorded on the record. That cannot use CommitLore-Version: — SPEC §8 defines it as the protocol version a record targets, and every fixture carries 2.0.0, unrelated to the v1.2.x build. It needs a new trailer, which would appear on every future record and is a wider decision than a patch release should make.

Evidence

Reproduced on a generated transcript matched to the report's profile — 74,450,108 bytes / 49,881 lines / 1,493 bytes per line, against the reporter's 74,173,844 / 49,549 / ~1,497.

case before after
capture --json --unattended on 74 MB exit 133, 0 bytes stdout, fatal V8 abort exit 0, outcome: empty + nonce, 0.7 s
the same with --draft exit 133 exit 0, outcome: staged
advisory on a truncated session claimed nothing gaps: ["proposal-windowed"]
doctor runtime mismatch 3 versions, no pids, no action 5 pids grouped by identity, plus an action
upgrade with a stale cached latest reports the older tag as newest re-asks and reports the newer one

The #884 tests assert by where a reviving phrase sits, not by any byte count — a size-only test would pass against the old code. Negative controls: restoring proposal: transcript fails the one case that proves the binding while the other three still pass; dropping the pids fails the pid case; removing the stale-cache re-ask fails the cache case.

Full suite 3205 passed, 4 skipped, 0 failed; tsc --noEmit exit 0; dogfood green against these three commits.

Release

release: 1.2.6 is the third commit — 36 pins across 11 files, bumped by parsing the JSON manifests. The dependency a text replacement would have corrupted moved since last release: 1.2.4 had rolldown at ~1.2.4, 1.2.5 has get-intrinsic at ^1.2.5, twice. That is why the rule is to parse rather than to remember which dependency to avoid.

MongLong0214 and others added 3 commits September 8, 2026 21:48
`capture` died on a 74,173,844-byte session with `Fatal JavaScript invalid size
error 134217728`, exit 133, and no JSON at all. Not a refusal — an engine abort.
The command reports outcomes structurally so a caller branches on `staged` /
`empty` / `rejected` rather than on the exit code, and this escaped that
contract entirely: a wrapper careful enough to read the outcome had nothing to
read. Reproduced on 1.2.3 too, so it was a standing limit and not something the
last release introduced.

1.2.3 bounded the prompt (#873) and did not bound the guard beside it.
`prepareValues` passed the whole transcript to `computeGuardAdvisory` on one
line and windowed it to 256 KiB on the next. `guard` normalises its proposal
through `normalizeForMatch`, and its `\p{Script=Latin}\p{M}*` global replace
collects one match per letter into a single array; past roughly 69 MB that array
crosses V8's 2^27 FixedArray ceiling.

The frame that dies was measured, not inferred. A static read of this path
nominates the `mapped += char` accumulator two lines below, which is the more
obvious suspect and is not what fails. The native stack is unambiguous:

    Builtins_StringPrototypeReplace
      Builtins_RegExpReplace
        Runtime_RegExpExecMultiple
          FixedArrayBuilder::EnsureCapacity
            NewFixedArrayWithHoles(134217728)

A preload wrapping `String.prototype.replace` confirms it from the other side:
the last subject over 1 MB before the abort is the whole transcript under
`/\p{Script=Latin}\p{M}*/gu`, reached through `tokenize` from `guard`.

`computeGuardAdvisory` documents that it never throws and degrades any failure
to a recorded gap. That contract could not hold while the input was unbounded,
because a fatal engine abort is not catchable — so the input stopped being
unbounded rather than the catch growing.

The guard now reads the same window the prompt carries. That narrows what the
advisory sees, and it is also the more honest alignment: the advisory is
rendered beside the prompt, so computing it over a whole session could warn
about a decision the prompt does not contain. The window is computed once and
handed to both, so a large transcript is split once rather than twice.

A truncated scan must not read as a complete one, so the advisory carries a new
`proposal-windowed` gap whenever the window dropped part of the session. An
empty `matches` array then says something about the window rather than about the
transcript.

Not fixed here, and deliberate: verification still reads the whole transcript,
so a quote from outside the window still verifies, and `scan()` builds
per-character structures over the whole file to do it. That survives 74 MB and
would fail somewhere past ~134 M characters. Bounding it would break the
guarantee that a locator names a line of the file it is checked against, which
is the property #873 went out of its way to keep.

Verified on a generated transcript matched to the report's profile —
74,450,108 bytes, 49,881 lines, 1,493 bytes/line against the reporter's
74,173,844 / 49,549 / ~1,497. Before: exit 133, zero bytes of stdout. After:
exit 0, `outcome: empty` with a nonce in prompt-only mode and `outcome: staged`
with a draft, 0.7 s end to end. The new tests assert by where a reviving phrase
sits rather than by any byte count, because a size-only test would pass against
the old code; the negative control restores `proposal: transcript` and fails the
one case that proves the binding while the other three still pass.

Closes #884

Record-Id: r-guardwindow884
Provenance: authored
Ruled-out: chunk normalizeForMatch so the whole session is still scanned | it is the anti-injection normaliser -- NFKC, invisibles, confusables -- and a fold straddling a chunk boundary is a security regression traded for a performance fix
Ruled-out: refuse above a transcript size and report it as a rejection | the reporter offered this as strictly better than a crash and it is, but it leaves large sessions with no advisory at all when a bounded one is available
Ruled-out: bound guard() itself against any oversized proposal | the MCP route can hand it text with no ARG_MAX ceiling, so the class is real, but no caller has reported reaching it and the fix belongs where the unbounded input is produced
Limit: verification is still unbounded by design and its per-character scan would fail past ~134 M characters; this moves the ceiling for capture, it does not remove it
Limit: a decision raised early in a long session is no longer matched at all, because neither the guard nor the model can see it
Warn: the advisory and the prompt must keep reading the same bytes; passing a different window to either reintroduces an advisory that describes text the model was never shown
Blast: module
Undo: easy
Certainty: firm
Verified: 14/14 in test/capture-prompt-budget.test.ts, full suite 3205 passed 4 skipped 0 failed, tsc exit 0
Verified: the reporter's repro shape run against the built CLI before and after -- exit 133 with 0 bytes, then exit 0 staging a record from the same 74 MB file
Unverified: the exact byte threshold between the 69 MB that worked and the 74 MB that did not; it depends on letter density rather than size alone and was not narrowed
Co-Authored-By: Claude <noreply@anthropic.com>
…a stale latest

`doctor` reported three distinct live CommitLore runtimes answering MCP on a
machine where every registration was correct. It was right. The old runtimes
were live processes that outlived an upgrade: a host resolves the launcher once
at session start and holds that runtime for the life of the session, and the
sessions there ran for days.

Those runtimes write. Records captured by a session started two days earlier
come from the build that session started on, while the operator believes the
repository is on the release they installed, and nothing on the commit says
which produced it. The row named three versions and stopped, so an operator
could not tell whether that was cosmetic or whether half their records came from
old code. The scan already knew all five process ids and dropped them on the way
to a deduplicated identity string, so the reporter ran `ps` themselves to find
the processes behind the names.

The row now groups pids by identity and names every one, states that each
runtime keeps writing records with the build it started on, and offers an
action aimed at the actual remedy: restart the host sessions that own those
pids, because an upgrade cannot reach a process that is already running.
Reinstalling is not the fix and the row no longer implies it is.

It deliberately does not label any runtime the stale one. r-liveruntime660 ruled
that out — a copied or stale install can report the same version as a current
one, so a version comparison here proves nothing about identity — and a test
asserts the row and its action say no such thing. Severity stays `warn` and
`needsAttention` stays false: this observes the machine, not the checkout, and
#750 is what happens when a repository command fails over another process.

`upgrade` had a smaller version of the same blindness. On a machine running
1.2.5 it reported `latest v1.2.3` and added "this is the newest release". The
lookup was never wrong: the answer is cached for a day in
`~/.cache/commitlore/latest-release.json`, and only `upgrade` acting calls
`forgetCachedRelease`, so a release installed any other way — install.sh, the
plugin marketplace, a manual checkout — leaves the previous answer standing and
the command reports a tag older than the binary printing it.

A `latest` older than the version already running cannot be the latest. That
case now drops the cache and re-asks. Equality is left alone deliberately: "you
are up to date" is the answer the cache exists to hold, and re-asking there would
make it decorative.

Not addressed, and left for its own decision: #885 also asks that the producing
runtime be recorded on the record itself, so a mixed-version repository is
legible after the fact rather than only while the processes are alive. That
cannot use `CommitLore-Version:` — SPEC §8 defines it as the protocol version a
record targets, and every fixture carries 2.0.0, unrelated to the v1.2.x build.
It needs a new trailer, which is a protocol surface that would appear on every
future record and is a wider decision than this makes.

Closes #885

Record-Id: r-runtimevis885
Provenance: authored
Ruled-out: stamp the producing runtime on the record now | it needs a new trailer rather than CommitLore-Version, and a permanent addition to what a record looks like should not ride along with a diagnostic fix
Ruled-out: name the newest runtime and call the others stale | r-liveruntime660 ruled that out because a copied or stale install can report the same version as a current one, so the ranking would be a guess presented as a fact
Ruled-out: raise the row to fail, or have it claim attention | it observes the machine rather than the checkout, and #750 is the measured cost of letting another process decide a repository command's exit code
Ruled-out: re-ask whenever the cached latest is not newer than the running version | that includes the equal case, which is every up-to-date machine, and would spawn git ls-remote on every upgrade
Limit: only `upgrade` re-asks a provably stale cache; `latestReleaseSync` and its other callers still serve the day-long answer
Limit: the row names the processes but cannot restart them, and doctor --fix does not act on this check
Warn: the fix text is rendered with newlines collapsed, so it must stay one sentence
Blast: module
Undo: easy
Certainty: firm
Verified: 7/7 in test/runtime-identity-action.test.ts, 10/10 in test/update-command.test.ts, 4/4 in test/init-machine-scope.test.ts, full suite 3205 passed 4 skipped 0 failed, tsc exit 0
Verified: negative controls -- dropping the pids from the row fails the pid case, and removing the stale-cache re-ask fails the cache case, each while the rest still pass
Unverified: whether a host that respawns the launcher picks up a new runtime, which is #885's third suggestion; the reported symptom is sessions that never respawn, so it was not measured
Co-Authored-By: Claude <noreply@anthropic.com>
A long session killed the process outright, and an upgrade nobody could see had
already happened: #884, #885.

Thirty-six version pins across eleven files, bumped by parsing the JSON
manifests rather than replacing text. The dependency that a text replacement
would have corrupted moved since the last release — 1.2.4 had `rolldown` at
`~1.2.4`, and 1.2.5 has `get-intrinsic` at `^1.2.5`, twice — which is the reason
the rule is to parse rather than to remember which dependency to avoid. The
script re-reads every file it touched and reports each remaining occurrence of
the old version, so the two that are supposed to remain were seen rather than
assumed.

Record-Id: r-release126
Provenance: authored
Ruled-out: text-replacing the version across the manifests | it also matches dependencies genuinely at that version, and which dependency that is changes from release to release
Ruled-out: bumping every v1.2.5 in the READMEs | the install shapes are the only pins; README.md's release-boundary prose is a historical statement no test guards
Limit: dist/ and installer/canonical-artifact.json are absent by design, so artifact:verify fails on this tree -- canonical-merge.yml rebuilds them on linux/amd64, where a macOS esbuild output would not match
Blast: system
Undo: easy
Certainty: firm
Verified: 109/109 across manifest, readme, release-version and check-release-version tests
Verified: the only remaining 1.2.5 strings in the eleven touched files are package-lock.json's two get-intrinsic constraints
Unverified: the install one-liners cannot be exercised until the tag exists, because install.sh clones a pinned tag
Co-Authored-By: Claude <noreply@anthropic.com>
@github-actions

github-actions Bot commented Sep 8, 2026

Copy link
Copy Markdown

CommitLore — record lint

Trailers: clean — 3 commits in origin/main..55e8d79fa85c6b21e5a7a159e17297b12c5cc0f1
Active constraints: 216 limits · 360 ruled-out · 71 warnings — from 241 records over 20 changed paths

Active constraints for the paths this PR touches

Limits (216)

  • r-release126 55e8d79 — dist/ and installer/canonical-artifact.json are absent by design, so artifact:verify fails on this tree -- canonical-merge.yml rebuilds them on linux/amd64, where a macOS esbuild output would not match
  • r-runtimevis885 0261b5f — only upgrade re-asks a provably stale cache; latestReleaseSync and its other callers still serve the day-long answer
  • r-runtimevis885 0261b5f — the row names the processes but cannot restart them, and doctor --fix does not act on this check
  • r-guardwindow884 30482b5 — verification is still unbounded by design and its per-character scan would fail past ~134 M characters; this moves the ceiling for capture, it does not remove it
  • r-guardwindow884 30482b5 — a decision raised early in a long session is no longer matched at all, because neither the guard nor the model can see it
  • r-release125 9d03977 — dist/ and installer/canonical-artifact.json are not in this commit, so artifact:verify fails on this tree by design -- canonical-merge.yml rebuilds them on linux/amd64, where a macOS esbuild output would not match
  • r-reviewcaughtserverjson c7debaf — the gate now reads server.json's .version; the installer command and release URL inside it are strings nothing compares, exactly as the four READMEs and two installers are
  • r-release121 9845d44 — npm audit is a claim about advisories published now, not about the code; and the canonical build was reproduced on one machine against the pinned image digest, which CI repeats twice but no one has repeated on another date
  • r-depsbatchbump 42013a6 — says nothing about behaviour changes inside SDK 1.30.0 itself; the suite covers this repository's use of the SDK, not the SDK
  • r-fasturiqsaudit 1752273 — an audit is a claim about advisories published at this moment, not about the code; a clean run says nothing about tomorrow's disclosures
  • r-cdebremoval 36ae3ab — four documents still mention CDEB and are deliberately kept -- ADR-0033, the archived readiness SSOT, an archived handoff, and two CHANGELOG lines. They are the record of decisions that were made, and rewriting them would be deleting evidence rather than code
  • r-cdebremoval 36ae3ab — one full-suite run in the middle of this work reported a single failure that the next two runs did not reproduce, with no relevant change between them. Its name was not captured before the output was discarded, so it is recorded as an unidentified flake rather than as something this commit fixed
  • 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-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-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-readmeparity dc89a2e — parity is asserted here by four counts that happen to agree, not by a test. Nothing stops the next English edit from separating them again, which is the same hole this commit is closing and the reason the assertion is worth writing next
  • r-fieldreportgenre 631150c — one run, one repository, one installer, and no method was recorded by whoever ran it. The section says so in its first sentence, but a reader who skims headings still meets a story next to a study, and no label fully removes that
  • r-readmerunningcost 9abb092 — the token bullet states the budget cap, not what a payload actually costs in a given repository. The cap is what the code guarantees; the fill depends on record density and path scope, and nothing here measures that
  • r-brandmarklifecycle 96a366e — CSS keyframes inside an -embedded SVG are renderer behaviour rather than a guarantee; a client that renders SVG without CSS gets the static logo, which is the intended fallback but is not the animated one. The reversal of The README asks a cold reader for four minutes before it earns one #450's limits-before-evidence order is a judgement made against a recorded decision, and should be reversed if the reason for The README asks a cold reader for four minutes before it earns one #450 still holds
  • r-releasereviewstatus 37a0670 — this records the absence of a review, which is not the same as recording what a review would have found. It says the gate was the only thing that ran
  • 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-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-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-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-oneblock 308be65 — the block moved out of the surface most readers see, so a benchmark number now costs one click to reach
  • 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-onepointer a3d3b95 — a reader in the upgrade section now has no inline route to the generation table, only to the command that names the affected repositories
  • r-ssotfive 9cff5ac — the translated sections were written to match the English contract rather than translated from it, so a later edit to one has no mechanical way of reaching the other three
  • 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-koregdrift ca4f99b — nothing checks this -- the rule lives in the PR that established it and in a comment, and the next section written in the wrong register will land the same way these did, from a branch that never touched the file the rule was recorded on
  • r-kohumanize 8e9cb09 — terminology is still doubled in places (path/경로, host/호스트, wiring/배선), and that is translation-consistency work that has to move ja and zh at the same time; one connective comma survives behind bold markers where splitting would make the span cross a sentence
  • r-heromeaning 9c85ad4 — nothing checks that the hero and the payload block below it stay consistent -- the test asserts the inversion is absent, not that the two describe the same record
  • 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-protoown cac5cde — the evidence block is the other four-way duplicate and is untouched here -- check-readme-numbers.mjs still owns it in all four READMEs, and moving it is its own change with its own negative control
  • r-heroalt22 19969c7 — the two contracts are still enforced in separate files, so nothing fails if one of them is deleted -- the note is what connects them, and a note is weaker than a check
  • r-onevisual 5833281 — at 375px the README embeds at width="100%", so the 840px canvas scales by 0.446 and the 18px labels land near 8px -- better than the 1200px canvas it replaces (7.5px) and still under the 12px a caption usually needs; three columns and this copy do not fit under a 700px canvas, so the canvas question is unresolved rather than answered
  • 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-currentlink735 49ca9ff — unlink-and-rename is not atomic, so a reader resolving current in that window sees it missing -- chosen over silently keeping the old target
  • r-currentlink735 49ca9ff — this fixes the report and the rename; a host that genuinely cannot symlink still falls through to the versioned-path note, unchanged
  • r-readmewin111 b396de9 — the claim is Codex, Gemini CLI and Hermes on one machine at 1.1.1 -- claude-code is still notDetected there with its config present, and the READMEs do not promise otherwise
  • r-clogherm111 1915356 — the release body for v1.1.1 was already corrected and republished; this brings the in-repository record to match
  • 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-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-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-dead691 6680425 — install.ps1 line coverage is unchanged -- what ran before still runs
  • r-rdupgr a3e04db — an upgrade path is documented where the install path is
  • r-rel102 25c11ed — an installer-boundary fix reaches nobody until it is released
  • r-adr22nm 31f6cf5 — a norm the product serves is not a capability the product claims
  • r-v102doc 597dad7 — the file a reader trusts for a fact must hold the current fact
  • 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-660plug 5d0e422 — already installed is the upgrade case, never a skip
  • 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-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-liveruntime660 6a221dbps is the seam, so this reports nothing on win32 and says so rather than claiming a clean machine
  • r-readmecache653 359e0f1 — only the English README carries this sentence; the three translations do not, so nothing is left inconsistent by correcting it alone
  • r-herosvg643 fc1009b — this renders in the README's first screen, so required wording must stay legible at mobile width
  • r-readmefact643 fc1009b — section order, demo asset and exposure table are cross-file contracts over four language files
  • 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-epipe595 0d60c75 — the negative control could not be reproduced outside CI -- with the handler removed the suite still passes locally and in a linux container, because the probe reaches its five-second timeout instead of losing the race
  • r-hostsay595 0d60c75 — this surfaces what the host command said; it does not diagnose a command that says nothing, and that case is now named as unknown rather than guessed at
  • r-draft615 cd3be7a — this checks shape only -- whether a record is supported by its evidence is still the verifier's judgement and still reported as data rather than as an error
  • r-oid613 202913c — a source guard allows core/types.ts and rejects a local length copy anywhere else, so a future reader writing its own regex fails rather than silently reintroducing the class
  • r-sha256oid 202913c — git object ids are hex, abbreviation 4, full SHA-1 40 or SHA-256 64
  • r-522idx1 b0fa907 — a truncated scan must never render as a complete answer; unreadCommits is the existing channel
  • r-522idx1 b0fa907 — --no-index and a filesystem that cannot write to .git still fall back to a scan
  • r-provsha1 6d82fcc — is a git object id — 4 hex digits (git's shortest abbreviation) through 64 (a full SHA-256), either case
  • r-cap543ex 2197283 — validate's exit codes shipped in v0.8.1 and must not move
  • r-answerown1 3547382warn distinguishes ours from not-ours by the command string, and does not execute anything -- a wrapper that really is a CommitLore server still reads as unverified, which is the safe direction but not a probe
  • r-pretag01 86e0153registers_commitlore reads the key, so a config that registers under a different key -- a host with its own naming -- still reads as unregistered and is wired again
  • 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-dropfake01 06961d3 — the runtime's presence proves this installer wrote the directory, not that its contents are unmodified since
  • r-secondcopy1 01ebee5 — the budget bounds the two scans, not the command -- process startup, path resolution and rendering still sit outside it
  • r-staleclaim1 59cb5d9 — withholding uses the same pattern table as every other route, so a payload that trips nothing still passes; this closes a route that had no grading at all, not the heuristic behind it
  • 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-observed01 43cfa5e — existence is not identity -- a path that resolves to something other than this tool still reads as a working registration, which is doctor reports a registered MCP command as working without establishing its identity #572
  • r-ownsemver1 fcc6e4a — the evidence is a directory this installer wrote, so an install whose data directory was deleted is now refused rather than upgraded -- a refusal naming the file, against silently destroying it
  • r-saywhat01 56444db — entailment is still unchecked, and this narrows the claim rather than closing the gap -- the protection remains that no drafted record is ever delivered as a directive
  • r-bynottname1 8beaa6d — an entry whose command is launchable but wrong still counts as a registration; the check establishes that a host could start something, not that what it starts is this tool
  • r-winstall1 0b4e551 — this pins what the repository says about itself, and cannot check that the tag it names has been published -- the install gate does that, after the tag exists
  • r-vbind001 2c88d24 — this binds the requested tag to the runtime that answers, not the tag to its content -- a tag moved after publication installs whatever it now points at, which is a signing question rather than a version-binding one
  • r-insttxn1 afb7bfb — this establishes that the installed tree is complete and its commands run on this machine at this moment -- not that the machine will still have a working node tomorrow, and not that any agent host will load what was installed
  • r-authdir01 ae2a66f — in the default mode a directive establishes that the commit's author string matched a configured one, and nothing about who produced the commit
  • r-authdir01 ae2a66f — in signature mode a verified signature establishes that a key the verifier trusts signed this commit -- not that its holder has authority over this repository, and not that the record's content is true or safe
  • r-mcpdir01 a9886b5 — neither route can tell a caller whether the trusted-author configuration reflects anyone's actual identity -- it reports what the repository decided, and the decision is a local git config value
  • r-codexreg1 5933aa4 — an entry can be correct when the installer reads it and wrong afterwards -- a later install, a moved data root or a hand edit all leave the name intact, and nothing revisits it until the installer runs again
  • r-codexplug e5fe95a — a plugin can put a skill in front of a session; it cannot make the session follow it, and nothing here reports whether one did
  • r-readme001 7f82d47 — the README still cannot tell a reader whether their particular host will follow a written procedure; only the hosts with a plugin or an installer have that answered by a mechanism rather than by hope
  • r-hermesx01 2eb8176hermes skills inspect resolves remote sources only in this Hermes version, so discovery was verified through hermes skills list --source all in a fresh isolated profile rather than from inside a live conversation; that a session then follows the procedure is not something an installer can establish
  • r-codexwire 955f290 — an instruction file is guidance, not enforcement -- a host may ignore it, summarise it away, or never read it, and nothing here can tell whether any session followed the procedure
  • 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-unattshadow b7b532a — together the two features measure how often an unattended pipeline would have written, and remove the asking from the writing -- neither half can say whether what gets written is worth a reader's attention, so shadow's number for an unattended repository is a volume, not a value
  • r-unattended511 f6679e1 — with nobody in the loop, the pipeline decides on its own what is worth recording, and every record it keeps spends a future reader's attention without asking anyone first -- the switch is a repository consenting to that cost, and nothing in this change reduces it
  • r-retireserena c1171ef — the preregistration fixes claims before numbers exist, so what it says about the calibration cannot move to match later tree state
  • r-shadow511 d093bef — shadow measures commits whose transcripts are gone, so its numbers describe the substitution of a committed message and patch for a transcript -- they say nothing about what capture would record over a live session, and no shadow output may be read as a pipeline baseline
  • r-readmeorder 383f77d — the hook leads with the headline number, so a reader who stops there has the effect without the conditions on it; the section naming those conditions is now two screens up rather than at the end, which is a shorter path than before but still a path
  • r-m5sources b910dba — the seven shards are declared individually, so a shard added later is invisible to this block until someone lists it -- which is the property the declaration was built for and the cost that comes with it
  • 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-numgate b770054 — the README's behaviour claim and the generated block below it now describe different studies until The README's generated numbers block still publishes M4; M5 measured the thing the README leads with #480 lands
  • r-readmem5 6d04c0b — the README now leads its behaviour claim with a [claim]-tier number while shipping a [directive] tier nobody has measured, and that gap will widen until something measures it
  • r-clog070 172fa3d — the entry stays under ## Unreleased and names no version, because the version bump belongs to the release commit and a changelog that pre-announces a number can be wrong about it
  • r-readmecold 08efdff — only README.md is reordered, so the ko, ja and zh-CN readers still meet the evidence first until the follow-up lands
  • r-selfaudit cd0068f — the page is maintained by hand, so an entry can go stale against the code it describes; the closing line says so and asks for an issue when it does
  • 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-capmode30 40818c2stage cannot check consent, so auto records what is certainly true -- no prompt was shown -- instead of asserting what it cannot know
  • r-claimsmatch 506ada4 — this fixes the sentences an external reviewer found; no systematic pass was made over every claim in the four files against every published measurement
  • 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-priorart 507ae24 — the comparison is against Lore's README and its abstract; the full paper was not read, so a lifecycle described only in the PDF would have been missed
  • r-scaleproof 4c093f2 — the 100,000-commit figures come from a synthetic repository built by the deterministic harness, not from a real codebase of that size, so they describe the index's shape rather than any particular project
  • r-extbaseline 064daf6 — the band is four Python repositories chosen for having enough revert history to backfill from, so it is evidence about large long-lived Python projects rather than about repositories in general
  • 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-ledgerresult bc31c90 — both sides are byte-derived proxies under CHARS_PER_TOKEN=4 rather than a provider tokenizer, so the ratio cancels a uniform error and not a differential one between diff text and prose
  • r-ledgerresult bc31c90 — break-even in reads assumes reads land on the evaluation set the way the delivery run's per-path average describes, and real editing concentrates on a few files
  • r-surfacedeliv fae9e1e — every figure in the table is measured on this repository measuring itself, which is the weakest part of the evidence and is stated in the paragraph rather than left for a reader to discover
  • 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-pipesplit b4fa571 — test/dogfood.test.ts validates every record in this history, so a new violation class is only available if it rejects none of the 620 Ruled-out: values already written
  • r-gcunstageable 5cd6b8f — ADR-0021 fixes the pending format and stamps expires_at at stage only, so giving these phases an expiry earlier is a format change rather than a fix
  • r-gcunstageable 5cd6b8f — gc runs only when capture gc is invoked -- nothing schedules it, so a leaked file goes at the next run rather than at the 24-hour mark
  • r-gcunstageable 5cd6b8f — staleness is derived from base_head against HEAD; a transaction whose staged diff moved while HEAD did not is equally unstageable and is still kept, which is the conservative half of the same test
  • r-gcunstageable 5cd6b8f — a staged transaction that is never applied is still kept for ever -- the hook skips it once expires_at passes and gc protects the phase -- which is a separate leak this change deliberately does not touch
  • r-readmesplit344 7314a03 — three checks bind content to a position in the README, so the complete record example, the protocol vocabulary table and the generated benchmark block could not move
  • r-failopen abc54ea — with the gate installed and no CLI resolvable, commits are still refused -- that is the one hook holding a verdict back, and this change does not reach it
  • r-heropolish f6144bc — README.ko.md still switches from 존댓말 to 해라체 below the hero; that split is older than this change and belongs to the restructure in README still carries the reference manual it should be linking to #344
  • r-pluginpath353 e364f3a — a plugin manifest has no way to add anything to PATH, so no plugin-side change can make the documented commands resolve
  • r-realoutput f9efea0 — a README block introduced as what the tool prints is a behavioural claim, and inventing its shape is the same defect as inventing a number
  • 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-heroinherit 89b13ac — a headline that implies detection commits the product to guard's numbers, and guard is an advisory measured at 22% recall
  • 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-fieldreport 753f4e7 — this section reports one engineer's day on one repository; it is evidence that the mechanism works there, not a measured effect size, and the wording has to keep those apart
  • r-readmefinal 40aeae0 — a mutation oracle anchored on a claim that can become false will silently stop testing when the claim is removed; the needle has to be asserted present
  • 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-compat1122 e7d8516 — a non-empty guard does not detect deletion; each table's row keys have to be asserted as a set or the statement can silently shrink to one row
  • r-compat1122 e7d8516 — substring comparison hides a narrowing -- ./ is inside ../ and Edit|Write is inside Edit|Write|MultiEdit|NotebookEdit -- so cells are compared as their rendered form
  • r-compat1122 e7d8516 — a sentinel containing \0 makes git treat the file as binary, which costs it diff, blame and log -p permanently
  • r-compat1122 e7d8516 — the plugin path needs bash, because scripts/commitlore-run.sh carries a #!/bin/bash shebang, and no install script checks for it
  • r-muslbullet1126 04ac181 — this ticket owns four bullets and not the tests that read the section around them, so a check that breaks here means a region was taken that was not allocated
  • r-ps1stderr282 e37b4d3 — Windows PowerShell 5.1 turns a native command's stderr into a terminating error under $ErrorActionPreference = Stop, so no native call in this script may merge stderr into its output
  • r-t1120nodeinst 14deeb4 — git and node are hard prerequisites now, so a host without them installs nothing and says which one is missing
  • r-t1110policy 9e7b37a — only a repository-local policy file is read -- PRD-F13 requirement 11 permits either one location or a stated precedence, and an ambiguous precedence is worse than a missing feature
  • r-gateb3rev a2e38b9 — the shipped install.sh downloads a platform asset, so no document may describe it as Node-only until the installer itself changes
  • 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-instverify256 3715677 — the root cause of the signal kill is unestablished; this makes the installer honest about it rather than fixing it, and Documented install exits 137 on upgrade: a killed verification turns a successful install into a failure #256 stays open for the cause
  • r-rel040pins b76c40b — the pin names a tag that does not exist until the tag is pushed; between this merge and that push the documented command refers forward
  • 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-lb0xl89a 236229e — the static contract uses explicit placeholder text for TRANSCRIPT and DIFF rather than omitting those sections, because the prompt text references them by name
  • r-t1016svg 321c6f1 — byte-exactness is verified on this platform; a different platform's Node could in principle render differently, and nothing here proves it does not
  • r-t1021known 8dfffc1 — the figures are measured against one archived 417-decision corpus, which is deliberately hard and is not deployment prevalence
  • r-t1002prep 3e2c8c1 — the prompt contract is a string this phase emits; nothing verifies the agent honoured it until verify runs
  • r-t1001pend 0f5ef32 — the test proves monotonic transitions but cannot prove absence of TOCTOU between read and rename on a loaded filesystem; atomic rename is the kernel-level guarantee
  • r-t1001pend 0f5ef32 — the first attempt's Record-Id used hyphens, which the r-[a-z0-9]{6,} format rejects; both the lint action and the dogfood test caught it
  • r-pin030readme 504b54e — install.sh must already support tag-based download for the one-liner to work; verified that the URL resolves to a tagged tree
  • r-notes030 a289ca5 — the density denominator is named here and in the handoff, not in the harness that emits it, so the next run reproduces the same ambiguity
  • r-hero172a bc0d971 — Stale-exposure benchmark is one corpus, one query, and one pinned embedding model at a fixed two-record budget
  • r-be140cost 8c01bd5 — no per-turn provider token ledger or observed avoided-work cost exists yet
  • r-readme129 ab5f210 — the break-even rests on tokens estimated from bytes at the product's own four-characters-per-token constant, so it moves with that assumption
  • r-m4basis 5e2d2cb — the guard question stays unanswered until the exposure instrument is verified and M4 is rerun on it
  • r-m4withdraw e5f9b73 — the guard question is now unanswered rather than answered null
  • r-instpath119 9e1fce7 — a user who ignores the printed line still gets "not found" on the next command
  • r-readmeux1 b664205 — interactive record building does not exist, so the honest answer is still "an agent writes it or you do"
  • r-rel021a a79e350 — v0.2.0 remains on the remote with no release attached
  • r-expreadme1 9e69abe — bench/VERDICT-M4.md still cites the Fisher figure; the two disagree until the verdict records why the number was withdrawn from the README
  • r-expomerge1 d6ad014 — M4's existing rows have no exposure field and must read as unknown, not as not-exposed — backfilling by inference would erase the finding
  • r-f61a2c 9114cf0 — the matcher remains deterministic and lexical; no embedding or semantic service is available to distinguish paraphrases
  • r-rdme96a 9c9371c — scripts/check-readme-numbers.mjs's withdrawal-notice and stray-statistic checks constrain what can appear outside the (absent, here) generated benchmark block — re-checked after every edit, not just at the end
  • r-fix92dupid 7f41a6e — cross-references between two blocks declared by the same commit (a Follows:/Supersedes: naming a sibling block's id) are still reported as dangling rather than resolved against the sibling -- unchanged from before this fix, and called out in validate.ts's own comment as future work
  • 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-distrace88 d118a73 — the fix insulates bench-ablation.test.ts from the race; it does not remove the underlying design (four test files independently, redundantly rebuilding one shared dist/ in their own beforeAll). A fifth file doing the same thing, or a future check elsewhere that also depends on dist/'s mid-run stability, can still race the same way.
  • r-parsemulti 6d39d25parse has no git-commit context (no sha, no notes mirror) — its identityCollision check is local to the one message being parsed and cannot detect a Record-Id that collides with something already committed elsewhere in history the way context's fold does.
  • r-multirec01 92aeb24 — parseRecordBlocks only recognizes a non-final block by its declared Record-Id, so an unidentified inherited record beyond the first stays recoverable in the plan that computed it but not in a later re-parse of stored text; squash-preserve orders unidentified blocks last so the common case (at most one) is unaffected.
  • r-multirec01 92aeb24 — multi-block reference checking (Follows:/Supersedes:) does not resolve one block's reference against a sibling block declared by the same commit; each block is still checked against every earlier commit in history.
  • r-exit065 e545dee — any new command's exit codes must be drawn from SPEC §10, not invented locally
  • r-fix70a1 d707fc7 — one encoding layer and explicit lexical forms in the four published languages; semantic paraphrases, nested encodings, and split payloads remain outside coverage
  • r-shallow66 60a8659 — a depth-1 clone can only inspect its reachable commit history
  • r-det058 695cdf6 — the suite must need no model, agent, network or uncommitted benchmark input
  • r-fix055 43b40f8 — harvest-verify makes no model call, so semantic entailment is outside its contract
  • 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-9c07e2 9c4d25a — the plugin still needs Node for the CLI — the protocol does not, but guard, the index and the MCP server do (T-706 · Bundle the CLI as a single file — run from a clone alone #38)
  • r-9c2f74 d653153 — the ablation arms cannot discriminate on these fixtures -- no-grade and no-lifecycle are byte-identical to the treatment in 9 of 10 tasks, because the seeds carry one reconstructed record and one task with a lifecycle trailer between them
  • r-9c2f74 d653153 — the harness assembles its own projection rather than calling the shipped injector, so what is measured is the harness's rendering of the records, not src/core/inject.ts (issue B-08 · Replace the benchmark harness injector with the actual src/core/inject.ts #36)
  • 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-6e1a72 5e09846npx commitlore is the first thing a reader will try, and it fails until the package is published
  • r-7e5f02 e5f5e00 — npm installs through an engine mismatch, so the ecosystem's own signal cannot be relied on to stop anything
  • r-9a5e17 6d68703 — five workers on one repository share npm test and tsc, so file ownership alone does not prevent one worker from "fixing" another's half-written code -- verification scope had to be split too
  • r-7f0e39 76f3f2d — literal substitution only catches the exact strings you list, so the same term written with a different separator survives
  • 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-9d31b7 4ac6e30 — the example lives in four translated files, so any fix that is not mechanically enforced will drift again on the next edit
  • 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
  • r-a8f3c1 ef48843 — Rename must land before any code exists -- after 27 tickets it would touch spec, fixtures, index, hooks and every doc

Ruled out (360)

  • r-release126 55e8d79 — text-replacing the version across the manifests | it also matches dependencies genuinely at that version, and which dependency that is changes from release to release
  • r-release126 55e8d79 — bumping every v1.2.5 in the READMEs | the install shapes are the only pins; README.md's release-boundary prose is a historical statement no test guards
  • r-runtimevis885 0261b5f — stamp the producing runtime on the record now | it needs a new trailer rather than CommitLore-Version, and a permanent addition to what a record looks like should not ride along with a diagnostic fix
  • r-runtimevis885 0261b5f — name the newest runtime and call the others stale | r-liveruntime660 ruled that out because a copied or stale install can report the same version as a current one, so the ranking would be a guess presented as a fact
  • r-runtimevis885 0261b5f — raise the row to fail, or have it claim attention | it observes the machine rather than the checkout, and init.test.ts fails on any machine with a stale CommitLore MCP server running #750 is the measured cost of letting another process decide a repository command's exit code
  • r-runtimevis885 0261b5f — re-ask whenever the cached latest is not newer than the running version | that includes the equal case, which is every up-to-date machine, and would spawn git ls-remote on every upgrade
  • r-guardwindow884 30482b5 — chunk normalizeForMatch so the whole session is still scanned | it is the anti-injection normaliser -- NFKC, invisibles, confusables -- and a fold straddling a chunk boundary is a security regression traded for a performance fix
  • r-guardwindow884 30482b5 — refuse above a transcript size and report it as a rejection | the reporter offered this as strictly better than a crash and it is, but it leaves large sessions with no advisory at all when a bounded one is available
  • r-guardwindow884 30482b5 — bound guard() itself against any oversized proposal | the MCP route can hand it text with no ARG_MAX ceiling, so the class is real, but no caller has reported reaching it and the fix belongs where the unbounded input is produced
  • r-release125 9d03977 — text-replacing the version across all manifests | it also matches four dependencies genuinely at that version, and no test reads them
  • r-release125 9d03977 — bumping every v1.2.4 found in the READMEs | README.md's release-boundary prose is a historical statement, and moving it makes the document say something false that no test checks
  • r-reviewcaughtserverjson c7debaf — bumping server.json without adding it to the gate | the bump fixes this release and nothing else; the gate not reading it is the defect, and the Codex manifest note in that same script is the record of what happens when only the bump is done
  • r-reviewcaughtserverjson c7debaf — anchoring REMOTE_NOT_FOUND but leaving the timeout to fall through it | a tightened expression still cannot see that ETIMEDOUT is present and load-bearing; the precedence has to be explicit or the next phrasing that slips through erases it again
  • r-reviewcaughtserverjson c7debaf — amending the earlier commits so the branch reads as if this was right the first time | the review finding is the evidence that the gate has a hole, and rewriting it away would leave the hole documented nowhere
  • r-release121 9845d44 — releasing the security fix alone and holding the rest | it was already merged and the remaining advisories are only reachable through the vitest upgrade, so a fix-only release would have left five of the seven, one critical, in a tree that says it is production ready
  • r-release121 9845d44 — one branch per remaining pull request | main requires its checks against the current base, so each merge invalidates the others and costs a full 45-minute cycle; five sequential merges buy no evidence that one branch carrying five recorded commits does not
  • r-depsbatchbump 42013a6 — repairing chore(deps-dev): bump js-yaml from 5.2.3 to 5.4.1 in the dev-dependencies group #862 and chore(deps): bump @modelcontextprotocol/sdk from 1.29.0 to 1.30.0 #863 on their own branches | each regenerates the same manifest file, so the first to merge invalidates the second; the cost is a rebuild and a full CI cycle per bump for no additional evidence
  • r-depsbatchbump 42013a6 — npm audit fix --force alongside these | the remaining advisories are dev-only and its breaking upgrades are the vitest major question, which is a separate decision with a measured cost
  • r-fasturiqsaudit 1752273 — fixing this on each dependency pull request instead | the advisories are on main, so each branch would carry an identical lockfile and dist change and the three would conflict with each other on merge
  • r-fasturiqsaudit 1752273 — npm audit fix --force | it also rewrites the dev tree through breaking upgrades, which is the vitest major question and not a security fix; the five remaining advisories are dev-only and outside what CI's --omit=dev gate asserts
  • r-cdebremoval 36ae3ab — archiving bench/cdeb to a tag or an orphan branch instead of deleting | the instruction was to discard it, and the history already holds every version; a tag would be a second place to keep something nobody is to consult
  • r-cdebremoval 36ae3ab — keeping guard-mutations and pointing its registry at product tests | it had never guarded a product test, so re-aiming it would be new work introduced under a removal, and it belongs in its own change if it is wanted
  • r-cdebremoval 36ae3ab — leaving the two jobs in ci.yml as no-ops so the workflow digest and REQUIRED_CHECKS could stay | a required check that cannot fail is the shape this repository's release gate exists to reject
  • 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-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-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-readmeparity dc89a2e — retranslating from scratch | the existing Korean, Japanese and Chinese prose is better than a fresh pass would be, and the divergence was structural rather than a translation problem
  • r-readmeparity dc89a2e — a parity assertion in this change | it would be written against the shape this commit just produced, so it would pass by construction rather than by checking; it belongs in its own change where it can be made to fail first
  • r-fieldreportgenre 631150c — keeping it out entirely | the page already asserts the loop in unlabelled prose, so exclusion protected nothing and removed the only account of it
  • r-fieldreportgenre 631150c — a copy under ## Evidence or in docs/evidence.md ## Measured | that is the collapse the original objection was about, and evidence.md already has one field report in that slot
  • r-fieldreportgenre 631150c — pasting the report as written | its ROUND 1 / ROUND 2 protocol voice is study language, which is what would have made a reader file it as a result
  • r-readmerunningcost 9abb092 — quoting the report's per-file token payloads (785 / 800 / 818) | they are one budget's cap observed three times, and the cap is the fact worth stating
  • r-readmerunningcost 9abb092 — quoting the report's 594ms and 2.13s index timings | one machine, two repositories, no stated method; the mechanism is reproducible here and the timing is not
  • r-readmerunningcost 9abb092 — citing the report's two-round agent trial as evidence | n=1 on a constructed repository, and putting it beside a registered study invites it to be read as one
  • r-currentlink735 49ca9ff — keep mv -f and only add the readback | the readback would then correctly report failure on every BSD upgrade, which is honest and still broken
  • r-readmewin111 b396de9 — leave the row and add a Windows-only footnote | the row is what a reader checks first, and a footnote does not repair a sentence that reads as exclusion
  • r-clogherm111 1915356 — leave it and correct it in 1.1.2 | a note that misreports which hosts work is read by everyone deciding whether to upgrade, and it was wrong in the direction of underselling a fix that landed
  • 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-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-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-dead691 6680425 — keep the blocks until a Windows machine confirms wiring | they sit after an unconditional exit, so no run can distinguish their presence from their absence
  • 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-readmecache653 359e0f1 — wait for the F-001 follow-ups to avoid a conflict | main states something false about when a record can be trusted, and every hour of waiting is an hour of holding it
  • 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-readmefact643 fc1009b — Restructure the English product entry page alone | T-1015 and T-1016 enforce four-file consistency and the translations belong to The README cites a checker that does not cover its headline numbers, and they disagree with the generated block #590
  • 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-epipe595 0d60c75 — swallowing the write failure silently | the probe would then wait out its full timeout for a command already known to be gone, and report a timeout rather than the closed input that actually happened
  • r-hostsay595 0d60c75 — letting stderr flow straight to the terminal | it interleaves with the wrapper's own output and is lost entirely when a caller captures only stdout, which is how this went unnoticed
  • r-install595 0d60c75 — presence-only registration checks | they allow dead commands to report installation success
  • r-linuxcwd595 0d60c75 — changing installer runtime verification | Linux evidence showed the smoke-test failure came from the linked-worktree test cwd
  • r-draft615 cd3be7a — reusing parseDraft at the MCP boundary | it re-parses a string the boundary has already decoded, and its per-record rejections are data the repair loop reads rather than caller errors
  • r-draft615 cd3be7a — a JSON Schema framework for the decoded shape | the shape is one interface with two arrays, and a second schema dialect would then need its own drift guard against DraftRecord
  • r-oid613 202913c — keeping one {4,64} predicate and calling resolveRevision first at every site | the predicate is what persists, and a call-order convention that must hold at eleven sites is a habit rather than a contract
  • r-oid613 202913c — tightening the Provenance trailer grammar to full ids here | that invalidates records already written and needs a SPEC and schema revision, which is a different review from a bug fix
  • r-sha256oid 202913c — a second full-id regex of 40-or-64 | that is a third definition, and the remaining sites stayed 40-only because they did not share the first one
  • r-522idx1 b0fa907 — leave context on the no-build scan fallback | a second call on hermes-agent was 271s and index.db was still absent
  • r-provsha1 6d82fcc — generating the schema pattern from types.ts at build time | there is no schema codegen step, and verify.sh reads the JSON file directly; a test that the two strings are identical is the lock this repo already uses for SPEC vs types
  • r-provsha1 6d82fcc — making grade.ts load the JSON schema | the hook path must not grow an ajv dependency to answer a question a regex already answers
  • r-cap543ex 2197283 — failing the hook when capture returns 3 or 4 | a hook that aborts a commit because the recorder broke is worse than a missed record
  • r-cap543ex 2197283 — a custom Error subclass for each kind | the repository forbids class X extends Error; a marker property is the same shape as commitloreMissingInstalledFile
  • r-5c84a1 b3eb1b4 — excluding applied alongside consumed | the record hash is stamped before the commit object exists, so an aborted commit leaves an applied transaction whose decision really was lost
  • 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-ownsemver1 fcc6e4a — keeping the semver rule and warning instead | the failure is destructive and silent, and a warning printed after the file is gone is not a warning
  • r-vbind001 2c88d24 — deleting a checkout that fails the version check | a directory the installer cannot identify may not be its own, and refusing costs an operator one command while destroying it may cost them something unrecoverable
  • r-insttxn1 afb7bfb — treating "verification could not run" as fatal | it fails a good install over a missing optional tool, which is the failure the non-fatal policy was introduced to stop
  • r-authdir01 ae2a66f — requiring signatures by default | it would demote every existing repository's records for a risk this project is not currently exposed to, and a silent capability removal on upgrade is its own kind of dishonesty
  • r-authdir01 ae2a66f — deleting the directive tier to make the claims true | the tier is how a record says it is a constraint, and removing it would resolve the wording by removing the feature
  • r-mcpdir01 a9886b5 — having runQuery read the trusted authors itself | it would fix these two call sites and silently change every other one, including tests that mean to grade without trust
  • r-relfix01 96102b4 — keeping "floor, measured" and footnoting it | the sentence is the claim a reader takes away, and a footnote that contradicts it is worse than either alone
  • r-codexreg1 5933aa4 — replacing any entry named commitlore | a user may run their own server under that name, and taking it because the name matched is the failure this fix is about, pointed the other way
  • r-readme001 7f82d47 — deleting the evidence and audit material to shorten the page | the willingness to publish unflattering results is the asset, and shortening by removing it would trade the strongest thing here for a faster read
  • r-hermesx01 2eb8176 — writing the bundle into the profile directory and regenerating its manifest | it would be undone by the next sync and disagree with the manifest until then
  • r-codexwire 955f290 — a Codex-specific integration | the instruction surface is shared, and writing one integration per host would leave the same gap open for the next five
  • 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-unattshadow b7b532a — keeping the unattended branch's inline prepare body | the shadow refactor exists so both entry points share one side-effect-free half, and two copies of the same hashing and policy logic would drift the first time either changed
  • r-unattshadow b7b532a — checking unattended consent in the live path only | the refusal for mode "off" already lives in the shared half of prepare, and a consent check that guards one door but not the other is no guard for the next entry point added
  • r-unattended511 f6679e1 — putting unattended into the default policy identity hash | the default is a fixed false, and hashing it would refuse every capture in flight across the upgrade in every repository that never opted in -- a policy change that never happened, the exact false positive the hash exists to avoid
  • r-unattended511 f6679e1 — checking consent at stage instead of prepare | stage receives a nonce and nothing else by design, and cannot observe whether a declaration was made; consent checked nowhere it can be observed is checked nowhere
  • r-unattended511 f6679e1 — ignoring "unattended": true outside auto mode | a consent the mode cannot honour would become a silent no-op, and a user who believes a setting applied is worse than one told it did not
  • r-retireserena c1171ef — rewriting the evidence documents to match the retirement | the transcripts and the preregistration report what the recorded runs saw, and a published claim the evidence does not support is the defect class docs/SELF-AUDIT.md exists to catalogue
  • r-retireserena c1171ef — keeping the ignore entry and the test guard as cheap insurance | the record that justified them said the directory comes back while the tool runs; it no longer runs, and a guard for a tool nobody uses guards nothing
  • r-retireserena c1171ef — editing r-strayserena in place | a record lives in the commit that declared it; retirement is a new record that names the old one
  • r-shadow511 d093bef — quoting the historical-run numbers | they measure a committed message substituted for a missing transcript, and a number from the wrong instrument becomes a baseline the moment anyone repeats it
  • r-shadow511 d093bef — backfilling records from shadow's output | the draft is an approximation no agent judgment ever stood behind, and publishing it as lore would launder a substitution into the thing lore exists to prevent
  • r-shadow511 d093bef — deleting the instrument because its first question failed | the failure belongs to history's missing transcript, not to the pipeline, and a live session supplies what the first run could not
  • r-readmeorder 383f77d — cutting the positioning prose rather than moving it | it answers the second question a reader has, and a document that only shows the example leaves them without the frame for it
  • r-readmeorder 383f77d — keeping "Known limitations" as the heading to avoid touching the test | the heading is the reason the section went unread, and a test that pins a name is meant to keep the disclosure honest rather than to keep the name
  • r-m5sources b910dba — globbing bench/results for m5-*.jsonl | the file next to them is a withdrawn design log, and a glob is how the wrong dataset gets published without anyone deciding to
  • r-m5sources b910dba — reporting only the 1,160 and dropping the row count | the rows are on disk and a reader who counts them would find the block understating; naming both and the reason is what makes either checkable
  • 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

Truncated: 326 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.

@MongLong0214
MongLong0214 merged commit a5c96e9 into main Sep 8, 2026
10 of 13 checks passed
MongLong0214 added a commit that referenced this pull request Sep 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant