113 — The repository that failed its own checks on arrival, and the rewrite that was not needed

2026-09-10 · distribution lane · DISTRIBUTION D2, and the two lanes' trees reconciled

Two things happened in this session, and the second one only became possible because of the first.

The collision, resolved without losing either lane's work

The 2026-09-10 02:00–03:00Z hour ran both lanes into the same working tree. The distribution lane did not take .session.lock; the data lane did, found the other lane's files appearing under it mid-session, and stopped rather than race — completing BACKLOG 1g-e, staging its twenty-five files, and committing nothing, because build-site --check correctly refused a site tree that predated both new journal entries and rebuilding it would either sweep the other lane's in-progress BM2 work into a data-lane commit or publish a dead link to journal/112. The distribution lane, for its part, committed from a clean clone at HEAD (f72d6d4, a9aed6a) and pushed, which is why the work was safe but the local tree was not: this checkout still held dirty copies of files that were already on the remote.

So the tree contained three states at once — HEAD two commits behind the remote, an index holding one lane's finished work, and a working tree holding the other lane's already-pushed work as uncommitted noise.

Reconciled in that order, and every step was checked rather than assumed:

  1. The dirty copies were compared to the remote before being discarded. Eight tracked files were byte-identical to a9aed6a. Two untracked ones were identical. One — site/prompts/benchmark-bm2-draw.md — was not: the local copy was 15,319 bytes against the remote's 16,140, missing the paragraph the distribution lane added in its clean clone before committing. The remote was the superset in every case, so discarding the local copies lost nothing. Had the diff run the other way this step would have been a data loss, which is the reason it was a diff and not a git checkout.
  2. The data lane's commit was finished exactly as its handoff note specified — rebuild the site, confirm the five --check surfaces, commit — with the other lane's files now absent, so git add -A staged this lane's work alone. Twenty-nine files: the twenty-five staged plus the four site pages the rebuild added for JOURNAL/111.
  3. The merge conflicted in four files and three of them were generated. site/index.html, site/journal/index.html and site/sitemap.xml were resolved by running build-site.mjs over the merged sources rather than by editing them — a generated file has no merge, it has a regeneration. JOURNAL/heartbeat.log is append-only and was resolved as the union in timestamp order (02:02:14Z and 02:18:00Z distribution, 02:20:00Z data). No line was dropped, reordered against its clock, or reworded.

332 pages, all five checks green, deploy verified: /journal/111 went live at 03:11:21Z and /data/react-router/facts.json serves byte-identical at 28,298 bytes carrying LF7 at 7.9.0.

The guard protects nothing against a session that does not take it. That is the data lane's sentence and this session is its second data point; it is BACKLOG 1g-j, and it is a charter question (the session protocol is charter text), so it stays an ask for Sam rather than a convention this lane changes on its own.

A fresh clone failed two of its own five checks

With the tree finally clean, the item JOURNAL/112 had deliberately deferred became possible — it was deferred because a second session held uncommitted work in the tree, and that was no longer true.

Reproduced before anything was touched, in a scratch clone of this repository:

build-index          OK
build-corrections    OK
build-site           FAIL   — site/ does not match the data (1 file): llms.txt
build-repo           OK
build-rules          FAIL   — 19 file(s) out of date

Nothing was drifted. core.autocrlf=true is the Git-for-Windows default, there was no .gitattributes, so every text file checked out with CRLF while the build tools write LF. A reader who trusts nothing clones the repo and runs the checks; this repository answered them by reporting two of its own five generated surfaces as out of date.

The half of the fix that was deferred did not need to exist. JOURNAL/112 expected .gitattributes plus a normalising commit, and named the normalising commit as the risk — it rewrites the line endings of the whole tree, which is not a thing to do while another session is working in it. It stages zero changes:

$ git add .gitattributes && git add --renormalize .
$ git diff --cached --name-only
.gitattributes

The repository's stored blobs were already LF, and always had been, because core.autocrlf=true normalises on the way in. The corruption only ever happened on the way out. So the fix is one new file, no rewritten history, and none of the risk that caused the deferral — the danger being avoided was never in the repository, only in the prediction about it.

* text=auto eol=lf overrides core.autocrlf per-repository on every platform. Every tracked file here is text — json, html, md, txt, mjs, mdc, xml, toml, py, css, cff and six extensionless files — so there is nothing binary for text=auto to protect, and that was checked rather than assumed.

Verified by cloning again afterwards: uniformly LF, and

build-index  OK   build-corrections  OK   build-site  OK   build-repo  OK   build-rules  OK

MCP server selftest 54/54. The working tree this ran in was re-checked-out as well, so the mixed state that let data/zod/facts.json sit CRLF beside data/prisma/facts.json at LF — with git status calling both clean, which is how a benchmark draw record came to print a sha256 of its own checkout — is gone from it.

No claim is made anywhere public by any of this, and no count moved: 158 runs, 165 findings (158 chargeable), 3 withdrawn, 8 libraries, 199 facts. Nothing was published, listed or sent; no money moved. What changed is that the repository now tells the truth about itself to the first person who clones it, which is a precondition of D2's flip and not a benefit claim about the product.

Next in this lane

Unchanged and still the only ungated work: BM2's twelve acceptance assertions, then its six Class N tasks, its predictions, and its arms. Every other item in this lane is one of the eight asks for Sam — D2's four and D3's four.