Skip to content

The demo claimed something the product does not (README SSOT, PR 1) - #794

Merged
MongLong0214 merged 9 commits into
mainfrom
readme-assets-and-demo-truth
Aug 19, 2026
Merged

The demo claimed something the product does not (README SSOT, PR 1)#794
MongLong0214 merged 9 commits into
mainfrom
readme-assets-and-demo-truth

Conversation

@MongLong0214

Copy link
Copy Markdown
Owner

Blocked only on CI. PR 1 of three from the README SSOT. Touches no README on purpose — the English rewrite is PR 2, and a README referencing an asset that does not exist is what the SSOT forbids.

Cross-provider review unavailable (grok 402, codex over quota). Same-family reviews were run on the CDEB branches today and reversed my conclusions twice, so treat this as gate-green only.

The product told a lie in the first thing people run

commitlore demo ended with:

The superseded reuse decision is filtered out — the agent cannot revive it.

CommitLore controls what is delivered. Whether a model then proposes the same idea from its own reasoning is outside anything this tool touches. It now says:

The superseded reuse decision remains in Git, but is not delivered as current guidance.

Nothing owned that sentence, which is why it survived every run until a reader caught it. Twelve tests own it now, including the absolutes it must never regain (cannot revive, prevents, never forgets, blocks the edit).

Assets

file what it is
commitlore-mark.svg brand symbol — one branch continues, one stops
demo.gif 46 KB · 11.1 s · 1100×820 · 26px
demo.tape the reproducible path, with a header explaining the GIF's provenance

How the GIF was made, stated plainly

Not by the tape committed beside it. vhs needs ttyd, and Homebrew on this machine refuses every ffmpeg-dependent formula because a third-party tap is registered and untrusted. Granting that trust is a decision about somebody's machine, not a build step, so it was not made. VHS itself was taken from its official release rather than the tap.

The GIF is rendered from the bytes commitlore demo actually printed, wrapped the way a 65-column terminal wraps them, at the font, palette and framerate the tape specifies. Nothing in it is authored by hand. With vhs available, vhs assets/readme/demo.tape regenerates it from the live command — the tape says all of this in a header comment.

A first render at 1100px cut every line at 87 characters, including the corrected sentence — the one thing this change exists for. I looked at the frame rather than trusting the byte count. Wrapping instead of shrinking keeps the font at 26px and loses nothing.

Asset contract

Existence, GIF magic and ≤4 MB, no active content or external references in either SVG, and a screen-reader label on both. Negative control: replacing the GIF with nine bytes of text and stripping the mark's accessibility attributes while adding a <script> fails exactly those three tests.

Not done here

The hero is still 840×340 with 18px labels — SSOT §7 wants 720×360 and a 24px floor. It moves to How it works in PR 2, so it is redesigned there with the section it belongs to.

`commitlore demo` ended with "the agent cannot revive it". CommitLore controls
what is delivered; whether a model then proposes the same idea from its own
reasoning is outside anything this tool touches. The demo is the first thing
many people run, so it is the last place to overstate. It now says the
superseded record remains in Git and is not delivered as current guidance,
which is what actually happens.

Nothing owned that sentence, which is why it survived every run until a reader
caught it. Twelve tests own it now, including the absolutes it must never
regain.

Also here, the two README assets that do not need a recording tool:
`commitlore-mark.svg`, a brand symbol where one branch continues and one stops;
and the asset contract itself -- existence, GIF magic and size, no active
content or external references in either SVG, and a screen-reader label on
both.

**The GIF was not produced by the tape committed beside it.** `vhs` needs
`ttyd`, and Homebrew on this machine refuses every ffmpeg-dependent formula
because a third-party tap is registered and untrusted; granting that trust is a
decision about somebody's machine rather than a build step, so it was not
made. The GIF is rendered from the bytes `commitlore demo` actually printed,
wrapped the way a 65-column terminal wraps them, at the font, palette and
framerate the tape specifies. Nothing in it is authored by hand. The tape is
committed because it is the reproducible path and because a recording whose
source is thrown away cannot be checked against what it claims to show; the
tape says all of this in a header comment.

A first render at 1100px cut every line at 87 characters, including the
corrected sentence -- the one thing the change exists for. Wrapping rather
than shrinking keeps the font at 26px and loses nothing.

Record-Id: r-demotruthandassets
Provenance: authored
Certainty: firm
Blast: local
Undo: easy
Limit: this is PR 1 of the README SSOT and touches no README. The hero is still 840x340 with 18px labels, the mark is not referenced anywhere yet, and the GIF sits unused until the English README lands -- deliberately, because a README referencing an asset that does not exist is what the SSOT forbids
Verified: negative control -- replacing the GIF with nine bytes of text, and stripping the mark's accessibility attributes while adding a script tag, fails exactly the three tests that exist for those. The GIF was read back frame by frame and looked at rather than measured: 46 KB, 11.1 s, GIF89a, and the full text legible with nothing cut
CommitLore-Version: 2.0.0
`dist/` is tracked and the artifact manifest records its hashes, so a change
under `src/` is not finished without them. Split from the previous commit
because the demo fix landed before this ran, which is the same order that has
put a red `check` on three pull requests today.

Provenance: authored
Certainty: firm
Blast: system
Undo: easy
Record-Id: r-democopycanonicalbuild
Limit: the bundle changed only because one output string did; nothing about the build is different
Verified: `artifact:verify` reports the hash the regenerated manifest records
CommitLore-Version: 2.0.0
@github-actions

github-actions Bot commented Aug 19, 2026

Copy link
Copy Markdown

CommitLore — record lint

Trailers: clean — 9 commits in origin/main..631150c5bed3d7e7ab364ef9b25063c1fd7a1463
Active constraints: 330 limits · 521 ruled-out · 111 warnings — from 405 records over 14 changed paths

Active constraints for the paths this PR touches

Limits (330)

  • 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-wordmarkplexregular 4c59761 — this is taste settled by looking, not a measurement. The one measurable claim behind Condensed -- more cap height per unit width -- was true and is being traded away deliberately
  • r-wordmarkrealtype 2bfe96a — the outlines are frozen at one size. Re-cutting the wordmark means re-running the conversion, and the parameters to do that live only in this message and the file's comment -- face, SemiBold, cap 52.6, tracking 0.05em, fontTools
  • 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-heromobilereadable 4c34cf1 — still one image doing the work of a paragraph, and a reader with images disabled gets only the desc. That text is written to carry the whole claim on its own, which is the most this format allows
  • r-democopycanonicalbuild 8ce56bc — the bundle changed only because one output string did; nothing about the build is different
  • r-demotruthandassets f6424c7 — this is PR 1 of the README SSOT and touches no README. The hero is still 840x340 with 18px labels, the mark is not referenced anywhere yet, and the GIF sits unused until the English README lands -- deliberately, because a README referencing an asset that does not exist is what the SSOT forbids
  • 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-blockpins e94b948 — the search was for one marker string, so a test asserting the block by some other means would still be found by CI rather than by me
  • 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-canonmerge761 6a88f2f — this proves the bundle matches this tree; whether this tree is what a reviewer wants is what the pull request is for
  • r-rel113 17a1301#749 question 1 stays open -- a fix that lives in the hook reaches a repository only on its next visit, and nothing on this machine knows which repositories exist
  • r-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-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-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-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-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-rel111 8c29f5d — Hermes still fails on that machine for a cause that is not this one and is not yet named (Windows: every detected host fails to wire — the temp filename carries the whole path, and hasCommand cannot see a .cmd #716)
  • r-rel111 8c29f5d — a zero-byte .cursor/mcp.json on the tester's machine is a user file; the installer read the file it says it reads and reported the true reason
  • r-rel111why 8c29f5d — this changes the note, not the behaviour -- the behaviour shipped in the merged branch and is already covered by artifact:verify
  • r-canon720 7bf5b82 — this adds no judgement about the Windows behaviour -- it makes the branch buildable, and the live evidence on the pull request is still the only evidence for that path
  • r-canon720b 7bf5b82 — this rebuilds, it does not judge -- the Windows behaviour still rests on the live evidence recorded on the pull request, and Hermes and the first-run probe timeout are still open on Windows: every detected host fails to wire — the temp filename carries the whole path, and hasCommand cannot see a .cmd #716
  • r-winargv716 7bf5b82 — Does not change executable-only Claude detection or the pre-existing MCP probe shell path; a new canonical dist rebuild is not included from Windows
  • r-winexec716 7bf5b82 — Does not change MCP probing or rebuild generated artifacts.
  • r-rel110 d9a041f — this release does not make host wiring work on Windows -- detection still cannot see a .cmd and spawn still cannot run one (Windows: every detected host fails to wire — the temp filename carries the whole path, and hasCommand cannot see a .cmd #716)
  • r-rel110 d9a041f — 1.0.0 through 1.0.2 have no CHANGELOG entries; a pointer to the releases page stands in rather than reconstructing them
  • r-rellock110 d9a041f — nineteen version surfaces was already wrong before this -- the lockfile makes it twenty-one, and the count is only ever known after the gate says so
  • r-relmanifest110 d9a041f — this is the release commit's own repair, not a fix -- the next release will need the same regeneration for the same reason
  • r-namefile716 f728e69 — only failures name their file; a successful wire still reports no path
  • r-namefile716 f728e69 — this makes the cursor question answerable on the next Windows run -- it does not answer it, and the outcome (failed) was never in doubt
  • r-overlay709 7e08cbf — unattended is an input to the effective digest but not to the defaults digest -- M-UX: capture leaves the user's workflow #511's exclusion rests on a file's identity being its own bytes, which an overlay breaks
  • r-overlay709 7e08cbf — a broken overlay falls back to the built-in defaults, not to the committed file -- layering onto a policy nobody could read states an effective policy no file states
  • r-wintmp716 f0ed513 — this fixes the write, not the detection -- codex, hermes and claude-code failed for the second cause and still will
  • r-wintmp716 f0ed513 — no Windows machine has run this fix; the guard proves the name, not the install
  • r-pend710 b452535 — the wording is checked, not the severity — an abandoned draft still warns
  • r-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-heroconsist 788a9db — the card text is 19-20 units, so at a 360-pixel mobile render it falls below the legible threshold; the headline and the alt text carry the message there, and the same content is in the Markdown below, but the card itself is decoration at that width
  • 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-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-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-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-gcwiring f21f28e — the guard against this class is four CLI-level tests; nothing structurally prevents a future subcommand from colliding with a parent option again
  • r-flake221fix 2b21ed9 — checkInjectRuntime ENOENT does not block init
  • 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-c44a1edb 71f5197 — src/core/pending-gc.ts -- gc must never remove a staged or applied file regardless of expiry; T-1018 post-commit may still finalise them
  • r-0ll5sxk0 2853a22 — consumption happens after commit succeeds, exactly once; consuming earlier loses the record on failed commits, consuming twice lets one record attach to two commits
  • r-t1009stage b5fcf4e — the nonce pattern check bounds what a caller can send, but a caller holding a valid nonce for its own repository can stage repeatedly until the record is consumed
  • r-t1005gates 15421c0 — policy identity is compared as a hash, so a policy edit that produces the same hash is indistinguishable from no edit
  • 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-t1006cli d22580b — the command composes the phases in one process, so a crash between verify and stage leaves a verified pending record that only garbage collection will clean up
  • r-t1008mcp ab00b54 — src/mcp/server.ts: readOnlyHint must be false for verify_capture — the tool writes verification results to the pending transaction
  • r-t1007mcp b6ef112 — commitlore_prepare_capture uses readOnlyHint: false because it writes a pending transaction
  • r-t1013verbose205 294ec82 — --verbose only selects the formatter; it does not change runInit logic, step order, exit codes, or --json output
  • r-t1022sig e0c641d — the first pushed attempt asserted one header string in the test and built another in the formatter; CI caught the mismatch and the formatter was aligned to the asserted string, which is the one that states the measured figures on the output surface
  • r-t1022sig e0c641d — focused-test evidence for this change is CI's, not local; test/guard.test.ts reports zero tests and stalls on this machine at dev with no changes applied
  • r-t1024bc 023f6d9 — response shape is exactly five fields per CEO amendments and ADR-0020 confidence-separation constraint | adding a sixth field or letting context inherit guard_confidence violates the acceptance criteria
  • r-t1021known 8dfffc1 — the figures are measured against one archived 417-decision corpus, which is deliberately hard and is not deployment prevalence
  • r-t1011demo 1c0fc0c — the scene is one fixed pair of decisions, so it demonstrates the mechanism rather than measuring how often it matters
  • r-t1020desc dd12b42 — the test asserts on the exact precision and recall figures; a future re-measurement changes both the description and the test
  • r-t1020desc dd12b42 — 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-initresult204 ea4a08e — --verbose flag not wired yet (T-1013)
  • r-t1030diag 344ada0 — the heuristic uses a regex on the first line of stderr; an error that prints no stack frame and no "not found" string will be reported as cause unclear even if a human could classify 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-fix191amb cb94448 — the same-message test still passes by accident of collectRecords returning one record per commit; the divergent-notes test is what exercises the actual suppression path
  • r-fix187val 40f2436 — the tip-scan adds one full-history git-log call per range invocation; acceptable for a lint-time check but visible in benchmarks at scale
  • r-hero172a bc0d971 — Stale-exposure benchmark is one corpus, one query, and one pinned embedding model at a fixed two-record budget
  • r-dupsucceed 6f77fcf — supersession is resolved within one repository's history, so a record superseded in a fork that was never merged still grades as current here
  • r-dupsuccorder f46c02d — a successor before a later duplicate cannot resolve that later collision
  • r-dupsucc729 5a6b238 — published dev history cannot be rewritten
  • r-valdup145 bcb9563 — the same-message check sees only the message, so two commits each declaring the same id separately are still caught by the reference check rather than here
  • r-convtrail150 57e89d2 — the denylist answers a different question from isRecordKey's allowlist, so a conventional trailer this protocol later claims would need removing from one and adding to the other
  • r-epipe2026 d9ee9ff — spawnSync may report EPIPE after git exits while its input pipe is being written
  • r-doctorepipe 0420f5c — the new deterministic tests exercise evaluateInjectRun with a synthetic spawnSync result rather than forcing the live race, because no payload this check sends is large enough to make the write block deterministically the way an artificially large one does in the reproduction above
  • r-init107 f485f07 — the generated dist artifacts are rebuilt from TypeScript source
  • r-survsplit e73aed5 — path-reachability is measured against git's rename detection, so the figure moves with git's similarity threshold rather than with anything here
  • r-be140cost 8c01bd5 — no per-turn provider token ledger or observed avoided-work cost exists yet
  • r-probepath 51f6446 — the probe still only runs a command it recognises, so a hand-edited but equivalent hook reports not-checked rather than a verdict
  • 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-doctorprobe ed94491 — the probe runs only a command it recognises, so a user who hand-edits the hook into an equivalent but different form gets not-checked rather than a verdict
  • 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-readmeux1 b664205 — interactive record building does not exist, so the honest answer is still "an agent writes it or you do"
  • 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-init96a 913c7e3 — doctor's own exit-code contract treats warn as non-fatal by design (SPEC §10, commitlore-setup skill) — init deliberately diverges from it for its own summary, and that divergence is the one thing most likely to look like a bug on a future read of this diff
  • 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-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-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-shwt66 5efa206 — git rev-parse --git-path may return a repository-relative path, so resolve it against cwd
  • r-merge66 40e7987 — Generated dist files were resolved only by npm run build and npm run bundle
  • r-fix760 fb8ba45 — Git remains the authority on trailer recognition; diagnostics must not loosen the parser
  • r-refint74 572f573 — validate cannot perform conservation checks because it has no before state
  • r-warn75 24c7cc8 — exit-code semantics remain owned by guard's exit 2 means blocked; everywhere else in the same CLI exit 2 means bad usage #65
  • r-shallow66 60a8659 — a depth-1 clone can only inspect its reachable commit history
  • r-doctor72 996bcde — generated dist artifacts must come from npm run build and npm run bundle, not a hand merge
  • r-fix067 a915af0 — PreToolUse hook failures must always exit 0 and never change stdout's hookSpecificOutput contract
  • r-fix063 0b8c496 — doctor performs remote probes; an unreachable remote reports could not verify instead of ok
  • r-fix053 ecc4b90 — QueryResult.notes remains repository-level availability and is independent from whether one record was mirrored
  • r-fix055 43b40f8 — harvest-verify makes no model call, so semantic entailment is outside its contract
  • r-fix054 664d4e2 — notes-only metadata must survive folding; a mirror is one record, not two
  • r-fix056 55cb8bc — blocked output may retain only validated structural values that cannot carry prose
  • 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-6e1a72 5e09846npx commitlore is the first thing a reader will try, and it fails until the package is published
  • r-7f0e39 76f3f2d — literal substitution only catches the exact strings you list, so the same term written with a different separator survives
  • 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-a8f3c1 ef48843 — Rename must land before any code exists -- after 27 tickets it would touch spec, fixtures, index, hooks and every doc

Ruled out (521)

  • 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-wordmarkplexregular 4c59761 — IBM Plex Sans Condensed SemiBold | taller cap in the same width, but tighter counters; the owner chose the regular cut on the rendered comparison
  • r-wordmarkrealtype 2bfe96a — Nutlope/logocreator | raster PNG output and a Together AI key, which cannot satisfy the animated-SVG, reduced-motion and dual-theme contract
  • r-wordmarkrealtype 2bfe96a — keeping hand-drawn stroke skeletons | no stem contrast or optical correction, and it is what the owner rejected
  • r-detectrule728 f1784ce — give claude-code a config-directory fallback for symmetry | it would report a host detected and then perform no wiring, which is the false success this installer exists to avoid
  • r-detectwhy728 f1784ce — give claude-code a config-directory fallback for symmetry | it would report failed and set ok false on a machine whose only trace of the host is a leftover config, failing an install that had nothing wrong with it
  • r-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-rel111 8c29f5d — claim Windows host wiring works | two of the four detected hosts wire, and a release note that rounds that up is the false green this release exists to remove
  • r-winargv716 7bf5b82 — shell: true | wrapper and user paths would become a shell injection surface
  • r-winexec716 7bf5b82 — shell: true | wrapper and config paths must not become unchecked shell input.
  • r-rel110 d9a041f — fold the second Windows cause into this release | it arrived as Fix Windows host resolution and batch spawning (#716) #720 with real Windows evidence and needs its own judgement, and holding this back would make the note about what is still broken false in both directions
  • r-rellock110 d9a041f — replace the version string throughout the lockfile | it matches four dependencies that are really at 1.0.2, and nothing in the suite would have caught it
  • r-namefile716 f728e69 — add a path field to HostResult | the summary schema is pinned at v1 and detail is already the free-text field a human reads
  • r-overlay709 7e08cbf — let an overlay only narrow permissions | it solves the contributor who wants less, and the one who wants more still edits the tracked file, which is the reported failure
  • r-overlay709 7e08cbf — write a .gitignore entry for the overlay | a tool that hides a file on a repository's behalf has decided for the repository what it may not see
  • r-wintmp716 f0ed513 — use basename() | correct on Windows, unfalsifiable on the platform CI actually runs
  • r-pend710 b452535 — drop the warning for the non-staged case | a stale draft is still worth surfacing, and doctor reports a consumed capture as never written to history #584 already showed that going quiet on a healthy-looking path is how this check loses its meaning
  • r-cleanrebuild664 da8948d — rebuild again and hope | the first rebuild was real; what was wrong was the tree it read, and running it once more from the same tree would have produced the same mismatch
  • r-formatnotmachine661 2cc274d — revert Report the MCP servers that are answering, not the ones registered #661 | it would take the check and its regression back out, and rebuilding both costs more than the line this change adds while main stays red
  • r-selfscan661 ccab7f4 — mark the probe's child through the environment | ps reports arguments, not environment, so the marker would be invisible exactly where the decision is made
  • r-selfscan661 ccab7f4 — exclude by direct parent only | the server is a grandchild of whatever probed it, so one link is not the relationship that matters

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

840x340 with 18px section labels renders those labels at roughly 8px on a
375px screen, which is where a GitHub README is most often opened. The
diagram was carrying the product's central idea at a size nobody could read
it.

720x360 with a 24px floor on every string. Two stages rather than three
columns: history on the left, what reaches the next edit on the right, and one
arrow between them.

`Ruled out` sits inside the delivered card, beside `Limit`, while `SUPERSEDED`
stays on the history side. That placement is the point of the picture -- the
alternative a decision ruled out travels *with* that decision, and is not
itself the superseded thing. Drawing them together on the left would say the
opposite.

Record-Id: r-heromobilereadable
Provenance: authored
Certainty: firm
Blast: local
Undo: easy
Limit: still one image doing the work of a paragraph, and a reader with images disabled gets only the `desc`. That text is written to carry the whole claim on its own, which is the most this format allows
Verified: rendered and looked at rather than measured -- nothing overlaps, nothing is cut, and every string is legible at the source size. The smallest declared font is 24px, checked by parsing the file rather than by reading the diff
CommitLore-Version: 2.0.0
@MongLong0214

Copy link
Copy Markdown
Owner Author

Hero redesign added — PR 1 is now complete against SSOT §5, §6 and §7.

840×340 with 18px section labels renders those labels at roughly 8px on a 375px screen, which is where a GitHub README is most often opened. The diagram was carrying the product's central idea at a size nobody could read.

Now 720×360 with a 24px floor on every string, two stages instead of three columns.

One placement decision worth naming

Ruled out sits inside the delivered card, beside Limit, while SUPERSEDED stays on the history side.

§7.5 warns against drawing it so Ruled-out reads as the superseded thing. The alternative a decision ruled out travels with that decision — putting them together on the left would say the opposite of what the product does.

Checked by looking

Both the GIF and the hero were rendered and read, not measured. That is how the GIF's first cut was caught: 46 KB and 11.1 s looked correct while every line was truncated at 87 characters, including the corrected sentence the change exists for.

PR 1 acceptance from the SSOT:

  • demo overclaim removed ✓
  • GIF from the actual command, under the size limit ✓
  • mark accessible ✓
  • hero mobile-readable ✓
  • no README change yet ✓

…orward

`README:BRAND` was an 88px glyph. It is now a 440px lockup whose left mark is
the decision model itself: a history rail with three committed nodes, a dashed
spur that diverges and stops at a hollow node, and a green segment carrying the
one decision still in force to the node being delivered now.

Only the in-force half moves. A 17-unit dash travels the green segment on a
2.8s loop and the delivered node breathes 1.00 -> 1.07 on a 2.6s loop; the
superseded spur has no animation at all. That is the point rather than an
omission -- the difference between active and superseded is carried by whether
the thing moves, so the mark still states it when a reader turns motion off.

Two greens, not one. #3FB950 is 2.56:1 on white, too little for a 5px rail, so
the rail is #2EA043 (3.45:1 light, 5.47:1 dark) and #3FB950 is kept for the
node and the travelling dash, where it reads as the accent. The wordmark is
#6E7781 -- 4.55:1 on white, 4.17:1 on #0D1117 -- so no `prefers-color-scheme`
swap is needed. A scheme query inverts wrongly for a reader running GitHub
light on a dark OS, which is a real configuration rather than a hypothetical.

The canvas is 720x116, not the suggested 720x180. At 180 the ink filled 39 of
110 rendered pixels and the mark read small inside its own box. Glyph scale is
unchanged by that, since it follows width/viewBox alone.

`commitlore-mark.svg` is removed. Its only references were the README line and
three test lists, all retargeted.

The rest of this commit is the README rewrite finishing what it started. It
went 560 lines to 388 and dropped facts on the way: the #167 exposure table,
that Git does not fetch `refs/notes/*` so a note-backed record is absent from
an ordinary clone, that a host handles returned context under its own policy,
the guard precision and recall, and the install promise. All are back.

T-1015 pinned limits ahead of evidence (#450). The 2026-08-19 redesign puts
evidence first and this commit follows the redesign, because the boundary #450
wanted a reader to meet first is now carried inside the evidence section --
as a column on every row, and as the sentence saying the study establishes no
universal model effect. What is still asserted is that neither section may
precede the automation boundary.

Record-Id: r-brandmarklifecycle
Provenance: authored
Certainty: firm
Blast: local
Undo: easy
Limit: CSS keyframes inside an <img>-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 #450's limits-before-evidence order is a judgement made against a recorded decision, and should be reversed if the reason for #450 still holds
Verified: rendered and looked at rather than measured -- light and dark at 440, 343 and 288, and the README top at 768 beside demo.gif. getAnimations() reports both keyframes running with the delivered node holding centre at (176,46) while it scales. Reduced motion checked by forcing the same declarations to `@media all`: the result is a complete static logo. Each new assertion was broken in turn and observed to fail; the first `<title>` control passed and was rejected, because replacing `<title` with `<titlex` still contains `<title`
CommitLore-Version: 2.0.0
COMMITLORE was ten stroked skeletons on a 48-unit grid -- letter-shaped, but
without the stem contrast, joins or optical corrections that make type read as
type. Side by side against any real face it was the amateur one, and the mark
beside it inherited that.

It is now IBM Plex Sans Condensed SemiBold, set at cap height 52.6 with 0.05em
tracking and converted to outlines with fontTools. The file still loads no font
and depends on nothing at render time -- the outlines are paths, not text --
so the constraint the hand-drawn version existed to satisfy is unchanged. Plex
Condensed over Plex, Archivo and Public Sans on two counts: it carries more
character at the same width, and its condensed set gives cap 52.6 rather than
45-48 in the same 480-unit box, which is what a 320px reader sees.

The symbol was hanging low, not sitting small. Its mass is below its rail --
the superseded spur descends -- so centring the rail on the wordmark centred
the wrong thing. The group is lifted 11 units until the symbol's own ink
centres on the wordmark's, and the two now read as one lockup. Weights went up
with the wordmark: rail 6 to 7, active 7 to 8, nodes 7 to 7.5, delivered node
11 to 12. History grey moved #8B949E to #7D8590 so the wordmark stays the
strongest neutral on a dark ground as well as a light one.

Ruled out: generating the logo with Nutlope/logocreator. It emits raster PNG
(its own README lists SVG export as future work) and calls FLUX through
Together AI, which needs an API key. A PNG cannot carry `@keyframes`,
`prefers-reduced-motion`, or a transparent ground that holds on both GitHub
themes -- it would have cost the whole motion and accessibility contract to
buy a picture.

Record-Id: r-wordmarkrealtype
Provenance: authored
Certainty: firm
Blast: local
Undo: easy
Ruled-out: Nutlope/logocreator | raster PNG output and a Together AI key, which cannot satisfy the animated-SVG, reduced-motion and dual-theme contract
Ruled-out: keeping hand-drawn stroke skeletons | no stem contrast or optical correction, and it is what the owner rejected
Limit: the outlines are frozen at one size. Re-cutting the wordmark means re-running the conversion, and the parameters to do that live only in this message and the file's comment -- face, SemiBold, cap 52.6, tracking 0.05em, fontTools
Verified: rendered and looked at rather than measured -- light and dark at 440, and at 343 and 288 where COMMITLORE stays legible. getAnimations() reports both keyframes still running with the delivered node holding centre at x=176. Reduced motion re-checked on the new file by forcing the same declarations to `@media all`: a complete static logo, no frozen dash. Five candidate faces were built and compared as rendered images before choosing, not from their names
CommitLore-Version: 2.0.0
Isaac picked from the three rendered candidates. Recording which and why the
previous choice fell, because the reasoning that produced Condensed is still
in the record one commit back and would otherwise read as current.

Condensed was chosen for cap height: 52.6 against 48 in the same 480-unit box,
which is the difference a 320px reader sees. That argument stands on its own
and was not wrong -- it was outweighed. Plex Sans has open apertures and even
colour where the condensed cut tightens the counters, and at 440px, which is
where nearly every reader meets this, the regular width is the calmer lockup.
Legibility at 288px was re-checked on the regular cut rather than assumed:
COMMITLORE still reads.

Nothing else moves. Same conversion route -- SemiBold, 0.05em tracking,
fontTools outlines, no font loaded at render time -- same 480-unit width, same
symbol, same two animations. Only the face and the cap height it implies.

Record-Id: r-wordmarkplexregular
Provenance: authored
Certainty: firm
Blast: local
Undo: easy
Ruled-out: IBM Plex Sans Condensed SemiBold | taller cap in the same width, but tighter counters; the owner chose the regular cut on the rendered comparison
Limit: this is taste settled by looking, not a measurement. The one measurable claim behind Condensed -- more cap height per unit width -- was true and is being traded away deliberately
Verified: rendered and looked at on the installed file -- light and dark at 440, and 343 and 288 where COMMITLORE stays legible. getAnimations() reports cl-flow and cl-alive running with the delivered node holding x=176. Reduced motion re-checked on this face by forcing the same declarations to `@media all`: a complete static logo. 140 README and asset assertions pass
CommitLore-Version: 2.0.0
A field report from someone installing v1.2.0 on a repository that is not this
one measured three things the README had no answer for. Each is stated here
only after checking it against this source, because a number measured on
someone else's machine is a report, not a property of the product.

**Delivery spends tokens on every matching tool call**, and the README said
nothing about it. Worse, the one place tokens appear is the #167 exposure table,
whose own caveat reads "not token cost" -- so the document named the gap and
left it. The hook fires on `Read` (`src/core/path-tools.ts`), not only on the
editing tools, so it runs far more often than an agent commits, and each fire
spends up to `DEFAULT_BUDGET_TOKENS = 800` (`src/core/inject.ts:254`, `--budget`
at `src/commands/inject.ts:398`). The bullet says plainly that this cost arrives
with adoption rather than with installation: a repository holding no records
spends nothing, which is also why nobody hits it while evaluating.

**Index build time follows records, not commits.** The report saw 6,691 commits
with no records index faster than 1,128 commits carrying 7,282 trailers. The
mechanism is in this repository rather than in that measurement:
`index-db.ts:825` says `explodeRecordBlocks` spawns a process per record. The
README states the shape and keeps the 496 ms p50 figure, which is measured here;
the field numbers are not quoted, because they are one machine and two
repositories and this README does not carry numbers it cannot reproduce.

**An existing hook is chained, not overwritten.** The report had recorded this
as a blocking objection -- that `husky` would conflict -- and then withdrew it
after testing. That it was believed at all is a documentation defect: the
behaviour has existed and been tested throughout. `resolveHooksDir` asks git for
`rev-parse --git-path hooks` (`hooks.ts:124`), so `core.hooksPath` is honoured;
a foreign hook moves to `<hook>.commitlore-chained` and runs first; uninstall
"restores exactly what was moved aside" (`hooks.ts:11`). Twelve assertions in
`test/hooks.test.ts` and `test/init.test.ts` already hold it.

Record-Id: r-readmerunningcost
Provenance: authored
Certainty: firm
Blast: local
Undo: easy
Ruled-out: 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
Ruled-out: 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
Ruled-out: 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
Limit: 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
Verified: each claim traced to the source before writing it, not after -- path-tools.ts for the matcher, inject.ts:254 for the default, index-db.ts:825 for the per-record pass, hooks.ts:124 and :11 for hooksPath and restore. 143 README and asset assertions pass, and the three suites that pin README facts by exact string were run against the edited file rather than assumed unaffected
CommitLore-Version: 2.0.0
I had kept a field report out of this README on the grounds that an n=1 trial
sitting near a preregistered study gets read as evidence and drags the study
down with it. A blind review refuted that, and checking its three claims against
this repository showed it was right on all three.

The refutation that landed: exclusion was not the cautious option, because the
page already makes the claim. Line 155 says "You do not need to name CommitLore
on every commit" and line 238 says users on skill hosts do not need to ask for a
record — two unlabelled assertions of an unattended loop, with no table on the
page behind either. `docs/MEASUREMENT-PROTOCOL.md:3` says the pilot is
"registered 2026-07-29; pilot not yet run", so the fresh-session half has no
measurement at all. Removing the one out-of-sample account of it left the
assertions standing alone, which is worse than a labelled account beside them.

My contamination rule was also applied unevenly, and against myself in the wrong
direction: `docs/evidence.md:209` already files a Swift field report under
`## Measured`, which is the worse slot. Refusing this one while that stands was
not a standard.

So it goes in, between `## What happens automatically` and `## Unlike memory
storage`, titled so the genre is the heading rather than a footnote: "A field
report, not a measurement". It opens by saying nothing was measured and that it
is not in the evidence logs, and it is not repeated under `## Evidence` or in
`docs/evidence.md`.

Cut from the source material, because the voice was the contaminant rather than
the content: the two-round protocol framing, the full trailer dump, the second
agent's closing flourish, and every sentence that scored the outcome. What is
left states what happened. Two lines are kept because nothing else on the page
carries them -- a `Warn` the human never dictated, and `Provenance: drafted`
grading the record `claim` rather than an instruction.

Record-Id: r-fieldreportgenre
Provenance: authored
Certainty: firm
Blast: local
Undo: easy
Ruled-out: keeping it out entirely | the page already asserts the loop in unlabelled prose, so exclusion protected nothing and removed the only account of it
Ruled-out: 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
Ruled-out: 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
Limit: 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
Verified: every claim the review made was checked against this tree before acting on it -- README.md:155 and :238 for the unlabelled assertions, docs/evidence.md:86 and :209 for the field report already filed under Measured, docs/MEASUREMENT-PROTOCOL.md:3 for the unrun pilot. 143 README and asset assertions pass, and the inserted section was grepped for rates, sample sizes and outcome verbs, which it contains none of
CommitLore-Version: 2.0.0
@MongLong0214
MongLong0214 merged commit 26e6150 into main Aug 19, 2026
12 checks passed
@MongLong0214
MongLong0214 deleted the readme-assets-and-demo-truth branch August 19, 2026 07:34
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