Skip to content

Release 1.2.1 — seven advisories leave the tree - #869

Merged
MongLong0214 merged 7 commits into
mainfrom
release-1.2.1
Sep 7, 2026
Merged

Release 1.2.1 — seven advisories leave the tree#869
MongLong0214 merged 7 commits into
mainfrom
release-1.2.1

Conversation

@MongLong0214

Copy link
Copy Markdown
Owner

Six recorded commits plus the release. main requires its checks against the current base, so every merge invalidates every other open PR's checks — five sequential merges would have cost five full CI cycles and bought no evidence that one branch carrying five recorded commits does not. This supersedes #861, #862, #863, #864 and #868.

What ships

Seven advisories leave the tree, and two of them were being shipped.

package severity tree how
fast-uri high (×4 GHSA) runtime — bundled and installed already on main via #866
qs moderate (×2) runtime already on main via #866
esbuild chain 1 critical, 4 others dev vitest 2 → 4 on this branch

npm audit is now silent with and without --omit=dev.

The push hook no longer reports records that do not exist as unsent (#865). On a failed notes mirror the line claimed "the records for these commits are still only local" without checking. The check is ref-scoped, not commit-scoped: the mirror publishes refs/notes/commitlore whole, so a record against an already-pushed commit is still unsent, and a commit-scoped check would call that "nothing waiting" — wrong in the dangerous direction. Three existing tests encode that shape and rejected the first attempt.

commitlore sync keeps one row per remote (#865). Git answers an unreachable remote with two lines and both went into a column that promises one, so the row broke in half and the trailing fatal: read as a bare error above the table.

Upgrades. vitest 4.1.11, MCP SDK 1.30.0, js-yaml 5.4.1, upload-artifact v7.0.1, download-artifact v8.0.1.

Verified locally

  • check-release-version.mjs v1.2.1seven sources agree
  • npm audit 0 vulnerabilities, both surfaces
  • pinned linux/amd64 canonical build; artifact:verify exits 0 at 26e55355…
  • 3164 tests passed, 4 skipped, 164 files; tsc --noEmit and check-engines clean

Review found two things this branch would not have

gpt-5.6-sol, read-only, asked to disprove rather than approve. Three passes: the dependency batch, the artifact-action upgrade, and this branch before tagging.

  1. server.json still advertised 1.2.0 — version, installer command, release URL — and the release gate does not read that file, so the gate passed. That is the note above .codex-plugin/plugin.json in check-release-version.mjs, one file and one release later. Bumped and enrolled in the gate, its fixture harness and the repository self-check.
  2. REMOTE_NOT_FOUND was too wide. It also matched repository metadata not found, and describeSync parses detail for ETIMEDOUT while execGit appends timeouts to partial stderr — so the relabel could have erased the only part anything reads and reported a missing fork for a slow remote. Bounded to git's two phrasings; a timeout now outranks the classification; a classification test replaces the shape-only one.

The success line also now builds itself from versionSources instead of naming them by hand — it printed "version consistent" without mentioning server.json even once server.json was being compared.

Earlier passes recorded their own limits and those stand: neither could rerun the Docker build, and neither dispatched canonical-merge.yml.

Not changed, deliberately

#858 was measured and closed rather than fixed. At one distinctive token the corroboration strength is structurally 1.00 whatever the token is — the corpus weight that separates a rare redis from an ordinary read is divided out by its own denominator. Every rule that removes the false positive also removes add a Redis clientshared Redis cache, a documented true positive. The issue carries the measurements.

One exception, recorded

#866 was merged without a cross-provider review. It was the security fix, and leaving two advisories in the runtime tree to wait for a reviewer is the worse trade. The CHANGELOG says so, the way 1.2.0's entry said it had no review at all.

dependabot Bot and others added 7 commits September 7, 2026 12:52
Bumps the actions group with 2 updates: [actions/upload-artifact](https://github.com/actions/upload-artifact) and [actions/download-artifact](https://github.com/actions/download-artifact).


Updates `actions/upload-artifact` from 4.6.2 to 7.0.1
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](actions/upload-artifact@ea165f8...043fb46)

Updates `actions/download-artifact` from 4.3.0 to 8.0.1
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](actions/download-artifact@d3f86a1...3e5f45b)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: 7.0.1
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: actions
- dependency-name: actions/download-artifact
  dependency-version: 8.0.1
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: actions
...

Signed-off-by: dependabot[bot] <support@github.com>
…w per remote

Two reports in #865, both about a line asserting something nobody checked.

**The push line.** #632 asked "is there a local note waiting?" and #656 answered
it unconditionally with yes: on a failed mirror the hook said "the records for
these commits are still only local" whether or not any record existed. A field
report on v1.2.0 got that line for a repository with no notes ref at all, ran
`commitlore sync` on its instruction, and found nothing to send.

What the remote holds cannot be known once the remote has stopped answering.
Whether this clone holds anything is local and cannot time out, so the hook now
measures that first and only claims records are waiting when it found some.

The granularity is the ref, not the commit, and that was not the first attempt.
A commit-scoped check -- "do the commits in this push carry records" -- reads the
sentence's own subject and is wrong in the dangerous direction: the mirror
publishes `refs/notes/commitlore` whole, so a record written against a commit the
remote already has is still unsent, and the commit-scoped check calls that
"nothing waiting". Three existing tests in `test/pre-push-hook.test.ts` write a
record and then advance the branch, which is exactly that shape, and they failed
against the first attempt. They are the reason this is ref-scoped.

**The sync table.** `SyncResult.detail` promises one line and git does not: an
unreachable remote answers with `remote: Repository not found.` and
`fatal: repository '...' not found`, and both went into the detail column. The
row broke in half and the second line read as a bare `fatal:` standing above the
next remote's row rather than as that remote's result. Collapsing happens in
`failure()`, the one place a git diagnostic becomes a detail, so the table, the
JSON and the hook all inherit the promise. Reproduced before and after against a
repository with a deleted remote.

Record-Id: r-pushlinemeasures
Follows: r-cdebmanifest
Provenance: authored
Certainty: firm
Blast: module
Undo: easy
Ruled-out: checking only the commits in this push | it matches the sentence's subject but not the mirror's granularity -- a record for an already-pushed commit is still unsent, and this would report it as nothing waiting; three existing pre-push tests encode that shape and failed against it
Ruled-out: filtering the fatal line out of the detail text | the multi-line value is the defect, not the wording; collapsing at the point of construction fixes every consumer instead of one renderer
Limit: the reassuring sentence only fires when the notes ref is absent; a clone that has records but has already published them is still told they may be waiting, because that cannot be decided without reaching the remote
Verified: 3162 tests passed and 4 skipped across 164 files; both behaviours reproduced through the built binary in a scratch repository -- the table now renders one row per remote, and a push with no notes ref reports nothing waiting while one with a record keeps the cautious sentence
Unverified: CI has not run this branch; the canonical manifest is regenerated separately once this rebases onto the audit fix, since src/ is a source input
…ch have their own

Dependabot opened #862 (js-yaml 5.2.3 -> 5.4.1, dev) and #863
(@modelcontextprotocol/sdk 1.29.0 -> 1.30.0, runtime) separately, and both failed
`check` for the reason r-cdebmanifest describes: `package-lock.json` is in
`SOURCE_INPUTS`, so any bump moves the manifest's source checksum.

They cannot be repaired independently. Each repair regenerates
`installer/canonical-artifact.json`, so whichever merged first would invalidate
the other's manifest and force a second rebuild, a second review and a second
30-minute CI run for a change already made. Batching is not a convenience here;
separate branches would have produced a conflict by construction.

Both were verified together rather than assumed to compose: the SDK is a runtime
dependency and is bundled, js-yaml is not, and the rebuilt bundle carries only
the SDK's change. The artifact digest moves to
8ca06b24a111ad6e28e6f6319af53cf4140d0f31fcb791879d8844d784b0dbe0.

Record-Id: r-depsbatchbump
Follows: r-fasturiqsaudit
Provenance: authored
Certainty: firm
Blast: module
Undo: easy
Ruled-out: repairing #862 and #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
Ruled-out: 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
Limit: says nothing about behaviour changes inside SDK 1.30.0 itself; the suite covers this repository's use of the SDK, not the SDK
Verified: npm audit --omit=dev reports 0 vulnerabilities; the pinned linux/amd64 build produced the committed dist and artifact:verify exits 0; typecheck and check-engines clean; 3157 tests passed and 4 skipped across 164 files
Unverified: CI has not run this branch yet
Bumps [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) from 2.1.9 to 4.1.11.
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Changelog](https://github.com/vitest-dev/vitest/blob/main/docs/releases.md)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.1.11/packages/vitest)

---
updated-dependencies:
- dependency-name: vitest
  dependency-version: 4.1.11
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
…ner can meet

The upgrade is not currency. After the fast-uri and qs fix, every advisory left
in this tree is `esbuild <=0.24.2` reached through `vite` -> `@vitest/mocker` and
`vite-node` — vitest 2.1.9's own dependency tree, including the one rated
critical. vitest 4 resolves `vite@8.2.2` and dedupes onto the `esbuild@0.28.2`
this repository already depends on directly, and `npm audit` goes quiet.

Three things had to move with it.

**`--reporter=basic` no longer exists.** vitest 4 treats an unknown reporter name
as a module path and dies at startup: `Failed to load custom Reporter from basic`.
`ci.yml`'s PRD-F2 perf step used it. It is `--reporter=default` now.

**Changing `ci.yml` breaks the reviewed-workflow lock, deliberately.**
`EXPECTED_CI_WORKFLOW_SHA256` pins the workflow body the release gate has read,
because the Actions API can attest that a job ran but not what it ran — without
the lock, replacing every job with `true` would still look like a green release.
Its comment says to update it with the workflow when the reviewed contract
changes, so it moves to d29daccf... here. Worth knowing for anyone who sees 21
release-gate tests fail after a one-line workflow edit: that is this lock working,
not the edit's subject matter.

**The 5s default test timeout no longer fits.** vitest 4 runs each file through
vite 8's module runner and the per-file startup costs more wall clock. This suite
is unusually exposed: most tests spawn a real `node`, `git` or installer process
and wait on it. Measured on the same tree and machine:

    default parallelism   35 failed   12 of them "timed out in 5000ms"
    --maxWorkers=4         7 failed   all 7 "timed out in 5000ms"
    testTimeout 20s        2 failed   one hook, two synchronous corpus sweeps
    + hookTimeout 30s and explicit timeouts on the sweeps   0 failed

Every failure was a timeout; not one was an assertion, and `guard.test.ts` passes
72/72 when run alone. The two `guard-insufficiency` sweeps take about two minutes
each and are synchronous, so vitest 2 never interrupted them; they now carry their
own 300s timeouts rather than pushing the global default up to cover them.

Record-Id: r-vitest4timeouts
Follows: r-cdebmanifest
Provenance: authored
Certainty: firm
Blast: module
Undo: easy
Ruled-out: raising the global testTimeout far enough to cover the corpus sweeps | it would let a genuinely hung test sit for three minutes everywhere to accommodate two tests that are legitimately long; those two say so themselves instead
Ruled-out: pinning vitest at 2.x and living with the advisories | the esbuild chain is only reachable through vitest's tree, so there is no fix that keeps 2.x, and one of the five is rated critical
Ruled-out: lowering parallelism instead of raising the timeout | measured, and it only moved the line — 7 failures remained, all still timeouts
Limit: the timings are from one machine; CI runners are slower on wall clock and faster on I/O, so the margins differ there even though the failures were reproducible here
Verified: npm audit reports 0 vulnerabilities on this branch; 3157 tests passed and 4 skipped across 164 files under vitest 4.1.11; the three release-gate suites pass 78/78 with the updated digest; typecheck clean
Unverified: CI has not run this branch; the perf step's output format changed with the reporter, and nothing downstream parses it
Seven advisories leave the tree with this release, and two of them were being
shipped: `fast-uri` (high, four GHSAs, through `ajv`) and `qs` (moderate, two,
through the MCP SDK's `express`) were both in the runtime tree — the one bundled
into `dist/commitlore.mjs` and installed. The other five, one of them critical,
were `esbuild <=0.24.2` reachable only through vitest 2's dependencies, and the
vitest 4 upgrade on this branch is what removes them. `npm audit` is now silent
with and without `--omit=dev`.

The version moves in the six places `check-release-version.mjs` compares, and the
script is run here rather than trusted to CI: tag, `package.json`, both plugin
manifests, both `package-lock.json` fields, and `dist/commitlore.mjs --version`
all read 1.2.1.

`dist/` moves by six files, which is not the version bump — the bundle carries no
version string, and the 1.2.0 release commit left `dist/` untouched for that
reason. It is `r-pushlinemeasures` earlier on this branch: that commit changed
`src/hooks/pre-push.ts` and `src/core/sync.ts` and deliberately left the canonical
rebuild to the branch's single rebuild, so this is where those sources reach the
artifact. The manifest is regenerated once, over everything.

The four READMEs and both installers carry `v1.2.0` in their copy-paste install
lines, so they move too; that is the same set the 1.2.0 release commit touched.

Record-Id: r-release121
Follows: r-vitest4timeouts
Provenance: authored
Certainty: firm
Blast: system
Undo: costly
Ruled-out: 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
Ruled-out: 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
Limit: 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
Verified: check-release-version.mjs v1.2.1 passes across all six sources; npm audit reports 0 vulnerabilities with and without --omit=dev; the pinned linux/amd64 build produced the committed dist and artifact:verify exits 0 at 584bff7a...; typecheck and check-engines clean; 3162 tests passed and 4 skipped across 164 files
Unverified: CI has not run this branch; the release workflow's own gates — exact-head-ci, canonical-artifact, install-gate — have not run, because they only run on the tag
…ier that was too wide

Neither of these would have been caught by anything on this branch. Both came
from the pre-tag review (`gpt-5.6-sol`, read-only, asked to disprove rather than
approve), and both are recorded here because *review caught them* is the part
worth keeping.

**`server.json` still advertised 1.2.0** — its `.version`, its installer command
and its release URL — while every source `check-release-version.mjs` reads said
1.2.1 and the gate passed. This is the note above `.codex-plugin` in that script,
one file later and one release later: an MCP registry entry is how a stranger
finds this, and it would have pointed at the previous tag. Fixed, and enrolled in
the gate, its fixture harness and the repository self-check, because bumping it
without enrolling it only moves the next occurrence.

The success line was rewritten to build itself from `versionSources` rather than
naming the sources by hand. It printed "version consistent" without mentioning
`server.json` even after `server.json` was being compared — a line that can
enumerate a set the loop did not check is the same defect one level up.

**`REMOTE_NOT_FOUND` matched more than git's phrasing.** `repository .*not found`
also takes `repository metadata not found` and `repository credentials not found`.
Worse: `describeSync` reads `detail` for `ETIMEDOUT` to say *why* the mirror
failed, and `execGit` appends that to whatever partial stderr the child wrote — so
a message can carry both, and the replacement would have erased the only part
anything parses and reported a missing fork for a remote that simply did not
answer. The expression is bounded to git's two phrasings now and a timeout
outranks the classification. The test that came with the original change checked
one-line shape and not classification, which is why it passed; there is a
classification test now.

Record-Id: r-reviewcaughtserverjson
Follows: r-release121
Provenance: authored
Certainty: firm
Blast: system
Undo: easy
Ruled-out: 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
Ruled-out: 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
Ruled-out: 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
Limit: 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
Verified: check-release-version.mjs v1.2.1 names all seven sources and passes; classification test covers both git phrasings, a false-positive phrase, and a message carrying ETIMEDOUT; 3164 tests passed and 4 skipped across 164 files; canonical build reproduced and artifact:verify exits 0 at 26e55355...
Unverified: CI has not run this branch; the release workflow's own gates run only on the tag
@github-actions

github-actions Bot commented Sep 7, 2026

Copy link
Copy Markdown

CommitLore — record lint

Trailers: clean — 7 commits in origin/main..c7debaf92259b4fa365e3043b85fd30830d7095c
Active constraints: 434 limits · 701 ruled-out · 138 warnings — from 519 records over 31 changed paths

Active constraints for the paths this PR touches

Limits (434)

  • 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-vitest4timeouts accbcda — the timings are from one machine; CI runners are slower on wall clock and faster on I/O, so the margins differ there even though the failures were reproducible here
  • 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-pushlinemeasures 2f495b5 — the reassuring sentence only fires when the notes ref is absent; a clone that has records but has already published them is still told they may be waiting, because that cannot be decided without reaching the remote
  • 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-cdebmanifest d64b006 — reproducibility is established for one run on one machine against the pinned image digest. The contract's own comment notes node:24-bookworm is mutable, and this says nothing about a rebuild on a different date
  • 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-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-reqchecksfixture 17a580b — the fixtures now agree with REQUIRED_CHECKS by construction, so a job that should be required but was never added to that list is still invisible here; the list itself remains the single named site
  • 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-ocimatrixci 6c738c8 — the matrix runs on the GitHub-hosted Linux runner and says nothing about Podman, rootless Docker, or any other runtime an operator might use. The refusals it observes are this daemon's, and the PRD's claim boundary should say so
  • 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-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-cifaningateguards a22353e — the refined rule accepts exactly the string always(). A semantically equivalent expression -- ${{ always() }}, or always() && true -- is refused, which is stricter than the property being asserted and will read as arbitrary to whoever writes one
  • 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-democopycanonicalbuild 8ce56bc — the bundle changed only because one output string did; nothing about the build is different
  • 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-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-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-handoffgraph b1c0e29 — the script trusts the two shas it is given, so it is only as good as the caller resolving them from GitHub rather than from the bundle
  • r-t1503revert 0c047a7 — merge-commit-only is still a sentence in a pull request body rather than a repository setting, so a squash remains one click away and would leave the source pull request open
  • r-t1503mode 34af906 — the mode is chosen from the pull request's changed paths, so a pull request that carries the artifact unchanged from base is checked in full and one that carries none is not checked against a committed bundle at all
  • 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-etimeout 09a1890 — only ETIMEDOUT is rewritten, so a transport that hangs without setting that code still surfaces its raw detail
  • r-t1502body 1cdb0ae — the canonical pull request asks for a merge commit and cannot enforce one -- squash and rebase are both enabled and the button remembers the last method used, which is how Release 1.1.3 #760 closed five of six as merged
  • 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-mergemethod 36a301e — the merge method is stated and asserted in the body, not enforced -- a squash merge of a canonical pull request still works, it just leaves the contributor's pull request open, and nothing fails when somebody does it
  • 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-macosevidence c2d0256 — the fixture and the assertions were exercised locally, so what is proven is that this mechanism fails under the restored defect on Darwin -- the job itself has still only ever run in this pull request
  • r-macosupgrade c9b0fca — the ubuntu twin is not added, and the review that suggested it was working from a claim in Committing dist is what makes the checkout the product — and what makes every second PR rebuild #719 that does not hold -- test/install-script.test.ts spawns the real installer, plants a current symlink and asserts readlinkSync plus the stray-link absence, so the GNU path is already pinned end to end
  • 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-jobboundary 38e2030 — the window between the moved-main check and the push is narrowed rather than closed -- if main lands something in it, the opened pull request is red on its own check rather than silently wrong, because build:canonical there will not match
  • 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-mintfrombase d723918 — this contains the credential, not the runner -- a pull request can still execute arbitrary code during npm ci, which is inherent to rebuilding somebody else's change, and the remaining exposure is the runner and the network it can reach rather than this repository's App
  • r-canonmergewf 47c8ed1 — this leaves pull requests still carrying dist/ when they choose to -- T-1503 is what stops requiring it, and until then a source-only pull request is a contributor's option rather than the rule
  • 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-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-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-plantmore722 f698236 — a shim that exits 0 for everything proves a branch was reached, not that the real host would agree -- these are detection assertions, not integration ones
  • r-plantmore722 f698236 — gemini-cli, windsurf and opencode still rest on the cursor fixture's shape rather than their own rows
  • 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-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-plantedexit722 b6e28a9 — the second case's non-zero code is asserted, not its value -- a change from 1 to 2 passes here
  • r-plantedhost722 b6e28a9 — one host of seven, on one platform. gemini-cli, windsurf and opencode take the same JSON path and are not planted; codex, hermes and claude-code take different ones and are not covered at all
  • r-plantedhost722 b6e28a9 — this executes wiring, not a real agent -- a planted shim is a file the job wrote, and it says nothing about what Cursor itself does with the registration
  • 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-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-dead691 6680425 — install.ps1 line coverage is unchanged -- what ran before still runs
  • r-pend710 b452535 — the wording is checked, not the severity — an abandoned draft still warns
  • 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-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-660plug 5d0e422 — already installed is the upgrade case, never a skip
  • 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-readmecache653 359e0f1 — only the English README carries this sentence; the three translations do not, so nothing is left inconsistent by correcting it alone
  • 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-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-prepush617 ec55144 — Notes sync must not block a branch push indefinitely
  • r-dupnote1 a73a1bc — preserve attaches only records absent from the merge message
  • 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-assertfile1 8a859c6 — this checks the report validate produced; it does not re-derive the range, so a range that silently covered nothing would pass here
  • 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-dogfoodref1 f605dbb — this asserts the two checks validate performs; a third class added later is not required by name until somebody adds it here
  • r-mslquote1 5b23c44 — this is the second quoting layer in this step; a third -- a value with a double quote in it -- would need a different mechanism than more escaping
  • 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-readyhosts1 9db3c4d — the new jobs establish that an install runs and answers on those hosts, not that every command behaves identically there
  • 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-codexunver1 980d747 — presence is read from the marketplace name, so a Codex that reports neither a source nor a listing this can parse is treated as absent and one is added under a name that may already be taken
  • 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-mcpproc01 db1363d — this establishes that a host which surfaces MCP instructions can capture without a skill; a host that ignores that field still needs --agents-md, and nothing here 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-ceiling01 543453b — this bounds the scan and not the command -- process startup, path resolution and rendering are outside it, so a repository whose single cheap pass is slower than the budget still exceeds it by that much
  • r-gatefixture1 a59df3f — this covers the manifests the gate reads today; nothing here makes a manifest added later visible to either the gate or these fixtures
  • r-clocktest1 6ac2b44 — the injected clock proves the loop stops and resumes correctly; it does not measure that a real budget corresponds to any particular wall-clock pause, which stays a measurement rather than a test
  • r-codexgate1 2a5dc53 — this compares versions that exist; a fourth manifest added later is invisible here until somebody adds it, which is the same gap being closed rather than a rule against 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-hookbudget1 e09014c — the budget bounds the wait, not the answer -- a repository large enough to trip it keeps getting a partial view until somebody runs init, and the notice is the only thing that makes that visible
  • 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-scanall1 62a6fbf — the scanner remains a heuristic, so this closes the exemption and not the gap behind it -- a payload that trips no pattern still reaches the agent
  • r-wrongtag1 99667f3 — PowerShell cannot be run here, so this is reasoned from the shared design and proven against the shell twin; only the windows-latest job is evidence for install.ps1
  • 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-structk1 a7bee10 — this closes the exemption, not the heuristic behind it -- a payload that trips no pattern still passes, and the scanner remains a speed bump rather than a boundary
  • r-ownfail01 8de1326doctor can say the setting is unreadable and cannot say what its author meant by it, so the repository is held to the stronger mode until a person decides
  • r-expwall01 e7ddd92 — the cache cannot notice an expiry that falls between two reads inside the same day -- a record expiring at noon is still delivered until the day rolls over, which is the granularity the determinism is bought with
  • r-codexerr1 a6d0fab — the first line of Codex's output is not always the cause -- a wrapper that prints a banner before its error will have the banner reported instead, and the full output is still only visible by running the command directly
  • 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-initmcp1 e601ad3 — this registers for hosts that read a repository-scoped .mcp.json; a host keeping its configuration elsewhere still needs its own installation, and this cannot tell whether any host ever loaded the file
  • 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-mintid01 1e5f500 — deterministic minting can reserve only identities visible in this repository; independently diverged history can still introduce a collision
  • r-notes512a ce937c9 — the observation is as old as the last doctor --fix; a mirror pushed upstream after it is not visible here, and an empty answer will read as a true empty until the next probe
  • r-autotrue2 6cc5032 — a host may be registered and never call the tool, or be configured outside the repository entirely, so this distinguishes wired from unwired and never observed from unobserved
  • r-autotrue1 70b7e06 — a host integration may still be installed or selected outside the repository, so operators must ensure it supplies the session transcript before committing; the core cannot observe or enforce that host-side action
  • 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-coldpath1 0412f81 — a genuinely cold fallback still reads the whole history once, because repository-wide lifecycle folding cannot be scoped to a path without changing what the answer means
  • r-coldpath1 0412f81 — nothing outside index and init builds the index now, so a repository whose derived file was deleted stays on the scan path until one of them is run
  • r-autoswitch b8497b8 — the prompt defaults to yes and a bare Enter takes it, so a reflexive Enter costs a team-wide consent — the file is committed, and every clone captures with nobody in the loop until someone runs auto off
  • 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-mcpexit506 f1b1fb0 — a process killed with SIGKILL still writes nothing, so the log shows a start with no exit -- that case is inferred from the absence of a line rather than reported, and stays the way MCP tools for commitlore vanish mid-session (ToolSearch returns zero results despite server reported connected) #424's original observation had to be made
  • r-demostory505 8016424 — the demo is one scenario, so it shows supersession and not expiry, path scope, or trust grading; a reader who wants those still has to read past the image
  • 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-pindigest c5a7cfa — pinning fixes the tree, not its behaviour -- a pinned action still runs with the job's token and can read this repository, and upgrading now requires deliberately resolving a new digest rather than inheriting one
  • r-filters471 c7572f6 — a filtered run reports honestly about what it ran and says nothing about what it skipped, so a repository whose only failure sits outside the selection reads as healthy-for-the-selection with no hint that the unexamined rows exist
  • r-envelope469 0162b73installSource is declared and derived per surface only where a test asserts that surface; an unasserted surface reports unknown rather than a guess, so the field is honest and incomplete rather than complete and unverified
  • r-effects476 43eb4aaenv and the clock are injected but process.cwd and the filesystem are still reached for directly inside some checks, so a check that reads a path can be pointed at a fixture but not at a purely synthetic tree
  • r-headline470 55b810cinit keeps the checks-only renderer, so the headline a doctor run shows is absent from the install path where a first-time user is most likely to meet a finding
  • r-budget472 8ea15f1 — 13.2x headroom over the measured baseline is sized to survive a contended shared runner, so it catches an order-of-magnitude regression and would not notice doctor becoming three times slower
  • r-dsplit467 b24e371 — the split is by responsibility, not by dependency direction -- runner, registry and renderer all still reach into the model, which is correct for a shared vocabulary and would not catch a model that grew behaviour
  • r-pubprereq 8ffb31c — the gates qualify the commit and its CI, not the tag's authorship or timing -- anyone who can push a v* tag to a qualified commit on main can still publish, and expiring or re-pointing a tag after these jobs pass is outside what any of them observe
  • r-vergate492 5b7a823 — the gate now covers every versioned manifest that exists today, found by searching for "version" across the tree -- a manifest added later is not covered until someone adds it here, which is the same standing every declaration in this repository has
  • r-collapse466 d24a284 — only two edges are declared -- inject-version on inject-runtime, and the §2.2 checks on the capture chain -- so a dependency nobody wrote down still surfaces as an independent finding
  • 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-evidence465 e1a3c92 — evidence answers what was observed, not whether the observation was the right one to make -- 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's wrong count would now be visible in a field rather than prevented
  • r-queryroute 4ae1f6f — the sweep covered ?? against an options field in src/commands, which is the shape that produced both defects; an option whose default is consumed some other way would not have shown up
  • 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-skipreason 85aa8d6 — the union has six members because ten sites needed six, and the next check that skips will need a seventh rather than one of these stretched to fit
  • 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-registry463 ddf5592 — the registry is data but nothing filters it yet, so the ordering guarantees are tested and unused until the --only ticket
  • r-checkmodel 9cbed57 — evidence is {} on every row until the ticket that populates it, so the field exists and proves nothing yet
  • r-doctorpend 458bcec — the check reads staleness, so a capture whose base commit is still HEAD reports ok even if it has been waiting long enough that nobody remembers preparing 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-trust415 a030e93 — this changes what a fresh install delivers, so M1 and M5 remain measurements of [claim]-graded delivery and their numbers do not transfer to the directive path
  • 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-mcplife424 8cd3c6d — the tool registration that was lost belongs to the client, so nothing in this repository can detect the loss from inside a session or restore it
  • 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-drafted30 b126176 — a commit message is immutable, so a drafted record is never upgraded in place -- promotion is a later record that Supersedes it, and that half is not in this change
  • r-amendid430 4c450ebcommit-msg gets no argument, environment variable or ref that distinguishes an amend from an ordinary commit
  • r-hookver433 a3b92d7 — nothing here can update anything -- the plugin cache is the client's, so the only move available is to say what is true
  • r-binx428 b9d1ea8 — the allowlist accepts .mjs/.js paths, which are exactly the files most likely to carry a shebang and no execute bit
  • r-recurse422 418734c — git runs pre-push on every push including one a pre-push hook makes, so any push from inside the hook must opt out of hooks explicitly
  • r-busy420 9555569 — a full rebuild on a large repository takes longer than any timeout a hook can afford to wait, so the scan fallback stays reachable by design
  • r-sync416 deb21d2 — git neither fetches nor pushes notes by default, so a mirror only moves when something configures or invokes it
  • r-mention408 ec314cd — paraphrase space is unbounded and this table cannot see semantic rewording, so blocked remains a speed bump and the grade remains the load-bearing control
  • r-schema406 22b2c35 — an index is derived state with no migration path, so a meaning change can only be handled by discarding the file
  • r-note409 0dff3e4 — the notes ref is an ordinary ref with no signature requirement, so authorship there is a claim about who wrote the text and not proof of it
  • r-backfillclosed 00de5fa — the guard reads the mirror state at invocation, so a fetch completing mid-run is not observed
  • r-initunfetched 889d191 — it reports the state as it was before init ran, so a mirror fetched between the capture and the report would be named wrongly; that window is the four steps of one command
  • r-mirrorunread 8e4bdc5 — the caveat can only fire where notesAvailability returns unfetched, so a refspec added after cloning and never fetched through still builds silently -- the distinction config alone cannot carry, recorded on that function under r-fetchowed
  • 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-pinskew 007ccbf — the comparison reads the package.json above the recorded path rather than running it with --version, so a pin whose manifest and bundle disagree is reported by its manifest
  • 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-secondtie 998bf18 — committed_ts is %ct at one-second resolution and the index stores no ordinal that orders two commits inside one second, so a tie on that path can be made deterministic but never topological
  • r-dedupviol 18ad9c1 — the key includes line, so two detectors that locate one finding differently -- one with a line, one without -- would still print it twice; today both resolve the line through the same locateTrailerLines/lineForViolation path
  • 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-owntmproot 6543870 — the demo still defaults to the shared tmpdir, so concurrent commitlore demo runs still create sibling directories there -- that is deliberate, and it is safe only because nothing now asserts over that namespace
  • r-diffdefault 4ac8163 — the test reads the option string out of the source rather than out of --help output, so a change to how commander renders descriptions would not be caught
  • r-shallowlast 0913821 — the spawn still happens once per validate that has a dangling ref, which is the case where the answer is actually needed
  • r-exitonemeans 89f7af8 — a shallow clone cannot tell a reference that resolves below the boundary from one that resolves nowhere, so neither verdict is available and the check can only name the question it could not answer
  • 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-notereach 1e72a28 — reachability is decided against HEAD alone, so a record mirrored onto a live branch that is not checked out is not served until it is
  • 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-fetchowed 11f04b4 — config alone cannot separate a refspec that was fetched through from one that was only written, so the availability verdict cannot carry that distinction
  • r-guarddisclose 8a4d0c7 — a disclosure asserted by tool name covers the tool that is named, and the ADR's requirement is about every surface that exposes the behaviour
  • 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-refspecfetch 936d206 — configuring a refspec is not fetching through it, and a state machine that conflates the two turns its own remedy into a way of hiding the problem
  • r-actionsleak a6fbb4b — a code path that no test and no first-party workflow exercises is the one an outside adopter takes by default, and its absence from CI is not evidence it is unused
  • r-actionsleak a6fbb4b — a trust label the caller must act on is worthless unless the value it describes is actually withheld at the point the data is built
  • 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-recordgate335 a83ebe3 — a denylist cannot decide whether something is a record, because the keys nobody has claimed are unbounded; that question needs the vocabulary, and the two must not be answered by one filter
  • r-recordgate335 a83ebe3Verified: in a release note is indistinguishable from Verified: in a record, and no context signal separates them without risking real records
  • r-draftfirst329 0506a5d — a usage error that names the wrong input costs an invocation and points the reader away from the fault; ordering is part of the message
  • 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-uninstall1123 4ddac0d — the installers write five agent configs, not the four the ticket's measured inventory lists; the fifth is Windsurf at .codeium/windsurf/mcp_config.json
  • r-uninstall1123 4ddac0d — opencode's entry is shaped differently from the other three -- the command is an array -- so one recogniser cannot serve all of them
  • r-uninstall1123 4ddac0d — a checkout is 1366 files at this head, not the 1206 the ticket measured at 6e1d46d; any assertion bound to that count is stale
  • r-winsupported1124 6333251 — repositories that installed the hook before Windows: the commit-msg hook hangs instead of returning, and #71's containment can never match there #321 keep the old stub and must re-run commitlore hooks install; a corrected release does not reach them, and this row's claim is about a working install
  • r-winderive1124 282693b — a diagnostic that retypes the code it describes goes stale silently, because nothing fails when the two drift apart -- it has to be read out of the artifact that ships
  • r-winbound1124 156deed — an unbounded hang is not evidence; it is a job that dies at the runner timeout having printed nothing, so every hook-invoking commit here has to carry its own bound
  • r-winassert1124 616005d — an assertion whose only oracle is an absent side effect cannot distinguish "refused" from "the mechanism never worked", so each one needs a positive control that fires before the attack
  • r-winshell1124 aa68a9a — a GitHub Actions bash step is invoked as bash -eo pipefail, so set -uo pipefail inside the step does not clear -e and any bare command that fails ends the step at that line
  • r-winpath1127 bdf4ac0 — the stub is written to .git/hooks at install time, so a repository installed before this fix keeps the old text and must re-run commitlore hooks install; installing a corrected release is not enough
  • r-winpath1127 bdf4ac0${dir%/*} returns its input unchanged when no separator remains, so a loop that tests for emptiness never terminates at a drive root
  • r-winpath1127 bdf4ac0 — neither dirname nor ${var%/*} finds a parent in a backslash-separated path; both answer .
  • 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-ps1scope282 72f23df — the hook-runtime probe spawns /bin/sh, so it cannot report on a Windows hook at all until T-1124 changes it

Truncated: 952 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 e3e9472 into main Sep 7, 2026
24 checks passed
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