The demo claimed something the product does not (README SSOT, PR 1) - #794
Conversation
`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
CommitLore — record lintTrailers: clean — 9 commits in Active constraints for the paths this PR touchesLimits (330)
Ruled out (521)
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
|
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
§7.5 warns against drawing it so Checked by lookingBoth 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:
|
…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
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 demoended with: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:
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
commitlore-mark.svgdemo.gifdemo.tapeHow the GIF was made, stated plainly
Not by the tape committed beside it.
vhsneedsttyd, 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 demoactually 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. Withvhsavailable,vhs assets/readme/demo.taperegenerates 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 worksin PR 2, so it is redesigned there with the section it belongs to.