feat(lenses): the commit-truth lens, repo-facts, as Gate 4

Every claim in every commit message, and in the documentation the range
adds or changes, proven or gone. The lens's block kinds are text, doc and
slot: a message unit is keyed on its text, the base and the code up to its
commit (MessageDeps); a documentation unit on its file, its normalised
text, the base and the code of the whole range (DocKeyParts); a diffstat on
its text alone; whole:order and whole:absent are asked in slot passes of
its own, never stored. A documentation file's diff header and a part the
commit writes nothing in are a mechanical n/a. Budgets 60/40 for a text or
doc block, 50/35 for a slot; one read. Gate 4, after the proofs, so the
messages and documents are read once the code they describe has settled;
the owner's gate is 5.

The goldens that follow from the lens table are derived by
tests/Goldens/derive.py, which asserts that the recorded table still
reproduces the recorded entries before it writes.

Proven, with the opt-in commit after this one: the suite (26 passed); a dry
run of a scratch range (2 commits, a README with sections) by the previous
binary and this one with the three static lenses on and the rest off, 25
prompts and 4 system files byte for byte; with repo-facts on as well,
those files unchanged and 10 passes and 1 system file added.
The lens's firing proof in this pipeline is owed (the owner's go).
This commit is contained in:
Jorijn van der Graaf 2026-10-31 20:08:26 +01:00
commit febbfc3fcc
Signed by: jorijnvdgraaf
GPG key ID: 2937E59CDCC1BCFB
19 changed files with 2564 additions and 646 deletions

View file

@ -3,9 +3,10 @@
Scope: every push of a commit range from a repository set up for this
pipeline (`crafter-review init`) — a release channel with real users, where a push (or
the pull request it opens) is the next release. The `/prepush` skill drives
this file. The mechanics: freeze → hash → gates → the owner; four lenses,
this file. The mechanics: freeze → hash → gates → the owner; five lenses,
the functional one as Gate 2 (Jorijn, 2026-10-15), the security lens beside
the bug-prover in Gate 3 (2026-10-22).
the bug-prover in Gate 3 (2026-10-22), the commit-truth lens as Gate 4
(2026-10-31).
Nothing is pushed without the owner's explicit approval of the exact frozen
hash. Local commits parked unpushed are fine and normal.
@ -15,7 +16,7 @@ Terms: *the pipeline* is crafter-review, the Flatpak
`flatpak run net.catcrafts.CrafterReview <command>`, because the Bash tool sees no
alias (a native build is run by its path instead). *The repository* is the
consumer checkout the driver runs in; *the owner* is whoever approves the
hash at Gate 4.
hash at Gate 5.
## Inputs — what the lenses see, and nothing else
@ -231,7 +232,7 @@ therefore the hash: re-freeze with `--replace` into the same dir
the new HEAD before the rerun. A fix during a run happens in another
worktree, never in the tree the lenses read.
## Gates 1–3 (the driver) and Gate 4 (the owner)
## Gates 1–4 (the driver) and Gate 5 (the owner)
| Gate | Lens | Question |
|---|---|---|
@ -239,7 +240,8 @@ therefore the hash: re-freeze with `--replace` into the same dir
| 2 Functional | `repo-functional` (whole pass gating code blocks; the `browser` or `browser+supabase` environment; absent when the config turns it off) | in the running application, does the range do what its code and messages say, and does it leave the flows next to it working? |
| 3 Proof | `repo-bug-prover` (code blocks, static; with the `supabase` environment a proof may also be run in the database) | a demonstrated functional defect in the range's code |
| 3 Proof | `repo-security` (code blocks, static, beside the bug-prover; with the `supabase` or a browser environment a demonstration may also be run in the database or the application) | a demonstrated gap in a protection the repository promises: a check, policy or grant the range's code lacks, weakens or removes |
| 4 | the owner | approves this exact hash, then the push happens |
| 4 Commit truth | `repo-facts` (message blocks, documentation blocks and the `whole:order` / `whole:absent` slots, static) | every claim in every commit message, and in the documentation the range adds or changes, proven or gone |
| 5 | the owner | approves this exact hash, then the push happens |
Every lens runs on Opus 5.5 at effort `xhigh` (`--effort` overrides).
There is no width of the machine by default (2026-10-31, Jorijn: "there is
@ -299,15 +301,17 @@ passes; coverage is fail-closed per inventory unit (`inventory commits`:
outputs after a kill, budgets, `--only` / `--units` test-only runs (PARTIAL,
never a pass), the dump at `gate-state/commits-<hash8>-run-<n>.json`.
**Who reads what.** The four lenses read code: hunks, file headers and (the
static lenses) the per-commit slots `pK:outside` and `pK:absent`. The
text units — subjects, messages, diffstats — and the units of documentation
files (`*.md`) are read by no lens of this pipeline (the facts lens was
removed, 2026-10-15); the dump lists them under `coverage.notReviewed` and
the summary says so. A lens the config turns off (`lenses.<name>.run =
false`) reads nothing: the units only it would have read (its whole slot —
`whole:behaviour` for the functional lens) are listed there too, never as
holes. The functional lens plans no pass on a diff header, on a
**Who reads what.** The four code lenses read code: hunks, file headers and
(the static lenses) the per-commit slots `pK:outside` and `pK:absent`. The
commit-truth lens reads the prose: the text units — subjects, messages,
diffstats — and the units of documentation files (`*.md`), each
heading-delimited part of a hunk on its own, and it asks `whole:order` and
`whole:absent` in slot passes of its own; a documentation file's diff header
and a part the commit writes nothing in are a mechanical `n/a`. A lens the
config turns off (`lenses.<name>.run = false`) reads nothing: the units only it would have read (its whole slot —
`whole:behaviour` for the functional lens; the prose for the commit-truth
lens) are listed under `coverage.notReviewed`, never as holes, and the
summary says so. The functional lens plans no pass on a diff header, on a
unit of a file matching `functional.exclude`, or on the per-commit slots (its
whole pass judges adjacent flows and missing deliveries range-wide): each is
a mechanical `n/a` with its basis.
@ -334,6 +338,16 @@ the functional lens):
range changed, or when a documentation file of their commit is added,
deleted or renamed (`absent` also when the commit gains or loses its body).
The commit's position is in the key;
- a message (`pK:subject`, `pK:msg`), for the commit-truth lens: its own
text, the base and the code of the range up to and including its commit —
a fix to the code a message describes asks the message again; a diffstat
its own text alone;
- a unit of a documentation file, for the commit-truth lens: its file and
its own text (normalised like a hunk), the base and the code of the whole
range — a sentence must hold for the code as its commit leaves it and as
the range leaves it;
- the commit-truth lens's slot passes (`whole:order`, `whole:absent`): never
stored, bought every run;
- both whole passes: the code of every commit of the range in order, which
commits have a body and which documentation files each touches. No message
text and no documentation text. A whole pass that returned a finding is
@ -371,7 +385,7 @@ from the previous rounds get run again until they reach x"; x is 3
again after a finished run is the next round.
- All gates clean with reads still owed is `CONFIRMING — NOT SEND-READY`
(exit 2); run the same line again, on the same hash, until it says
SEND-READY. Gate 4 is asked for a hash only then.
SEND-READY. Gate 5 is asked for a hash only then.
- Every finding in the dump carries `read`, the number of the read that
found it.
@ -401,7 +415,7 @@ Each entry is dated, names what it `supersedes`, binds to a hash, records
grounds, and lists the artifact `anchors` its grounds depend on with the
count of occurrences at binding. The register is
`<out>/gate-state/dispositions.json` — the authority and the record; the
manifest's rounds table names each discharge with its grounds for Gate 4.
manifest's rounds table names each discharge with its grounds for Gate 5.
Carry across a hash change
is mechanical: an entry is in force when bound to the current hash, carried
when `carry` is true and every anchor still occurs its recorded count of
@ -419,7 +433,7 @@ the push, the rest are banked per kind.
A new disposition in force re-keys every unit, so a waiver costs every static
code unit its three reads again.
## Gate 4 — the owner, then the push
## Gate 5 — the owner, then the push
Present the frozen patches themselves (never summaries), the rounds table,
every discharged finding with its grounds, every contest, every `unverified`
@ -592,3 +606,6 @@ repository.
5-hour column. Then (Jorijn: "there is no need to do a global cap anymore,
the cap should be 128 per available account") the machine-wide width
went: `--concurrency` caps only when given.
- 2026-10-31 — **the commit-truth lens as Gate 4** (Jorijn: "fix that in
Crafter.Review"). The owner's gate is 5. Its firing proof in this pipeline
is owed (the owner's go).