feat(core): the data home, the lens texts, and --version naming both
process/ holds the procedure, the five lens texts, the templates and the
skill under process/skill/prepush/. A lens text's sha256 is part of every
reuse key and the texts are part of every prompt, so they carry no SPDX
header; --version prints the charter hashes: 1728bd4c, 148d5c4c,
c7ffef44 and 2b9a5f83 for the four charters.
Home() finds them: CRAFTER_REVIEW_HOME, natively only (a host setting
must not swap the Flatpak's texts for a checkout's), then
<exe>/../share/crafter-review, then the checkout the binary was built in.
Main() hands `__supervise` to the supervisor before anything else, then
decides the sandbox once.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 05:51:37 +01:00
---
name: prepush
2026-10-31 20:09:07 +01:00
description: Pre-push gates for a repository set up for crafter-review (`crafter-review init` ). Runs the pipeline's procedure end to end — Gate 0 build/tests + freeze (identity, trailers by the config's rule, clean tree, no merges, fast-forward), the application and the database under test brought up from the frozen tree, the driver run of the lenses the config turns on - every lens is off until it does (repo-better-solution → repo-functional with the Playwright MCP → repo-bug-prover and repo-security side by side → repo-facts, the commit truth) via crafter-review, the fix/rerun loop, the owner's approval of the hash, verify, push. Nothing is pushed unreviewed or unapproved.
feat(core): the data home, the lens texts, and --version naming both
process/ holds the procedure, the five lens texts, the templates and the
skill under process/skill/prepush/. A lens text's sha256 is part of every
reuse key and the texts are part of every prompt, so they carry no SPDX
header; --version prints the charter hashes: 1728bd4c, 148d5c4c,
c7ffef44 and 2b9a5f83 for the four charters.
Home() finds them: CRAFTER_REVIEW_HOME, natively only (a host setting
must not swap the Flatpak's texts for a checkout's), then
<exe>/../share/crafter-review, then the checkout the binary was built in.
Main() hands `__supervise` to the supervisor before anything else, then
decides the sandbox once.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 05:51:37 +01:00
---
Follow the pipeline's procedure, `prepush.md` , EXACTLY — read it now, in
full, before anything else: `flatpak run net.catcrafts.CrafterReview doc
--path prepush` prints where it is; read that file with the Read tool.
Every command below is spelled `flatpak run net.catcrafts.CrafterReview
<command>`: the Bash tool sees no alias. This skill only adds the mechanics
of running it:
1. **Identify ** the repository root (the driver runs from there), the range
(`git log --oneline @{u}..HEAD` , or `$(git merge-base HEAD <config base>)..HEAD`
for a branch that tracks nothing yet), the slug (the branch or release
name), and the config: `flatpak run net.catcrafts.CrafterReview config`
2026-10-31 20:09:07 +01:00
must print no problem (every lens is off until `lenses.<name>.run = true`
turns it on: turn on the ones this repository runs).
feat(core): the data home, the lens texts, and --version naming both
process/ holds the procedure, the five lens texts, the templates and the
skill under process/skill/prepush/. A lens text's sha256 is part of every
reuse key and the texts are part of every prompt, so they carry no SPDX
header; --version prints the charter hashes: 1728bd4c, 148d5c4c,
c7ffef44 and 2b9a5f83 for the four charters.
Home() finds them: CRAFTER_REVIEW_HOME, natively only (a host setting
must not swap the Flatpak's texts for a checkout's), then
<exe>/../share/crafter-review, then the checkout the binary was built in.
Main() hands `__supervise` to the supervisor before anything else, then
decides the sandbox once.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 05:51:37 +01:00
2. **Gate 0 ** : run the config's `gate0` commands on that HEAD and keep their
output. Then freeze:
```
flatpak run net.catcrafts.CrafterReview freeze --slug <slug> [--worktree]
```
It refuses on any failed check — fix the commits, never the check. It
prints the hash and the exact run command, also in
`.review-gates/push/<slug>/run-line.txt` .
3. **The application and the database under test ** (when a lens that runs
has the browser — `browser` , `browser+supabase` ; the functional lens by
default — or the database — `supabase` , `browser+supabase` ; nothing to
start when none does): start them from the tree the lenses read (the
checkout itself for `--trees .` , the worktree for `--worktree` ) with the
config's `functional.start` (or `supabase.start` when no lens drives the
application), and confirm `functional.appUrl` answers. The login fixture
named in `functional.login.fixtures` must exist (the stack's seeder
writes it). A lens with the browser drives Playwright's Chromium: when the
first browser pass cannot start it, run
`flatpak run net.catcrafts.CrafterReview browser install` once. With
`slots.*` , start slot 1 (`slots.start` with n = 1), then run
`flatpak run net.catcrafts.CrafterReview slots --artifact
.review-gates/push/<slug>/`: it says how many slots fit in free memory
and prints the start commands for the missing ones — run those side by
side and wait for every one to finish (`<slots.dir>/<n>/slot.json`
appears when a slot is up). After `freeze --replace` , stop the slots
(`slots.stop` ) and bring them up again from the new HEAD. The driver refuses a gate while the database at
`supabase.dbUrl` does not answer or its applied migrations are not
HEAD's: reset the stack from the frozen tree, after every
`freeze --replace` too. Do not edit that tree while the run is on.
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).
2026-10-31 20:08:26 +01:00
4. **Gates 1– 4 ** : run the printed command from the repository root in a
feat(core): the data home, the lens texts, and --version naming both
process/ holds the procedure, the five lens texts, the templates and the
skill under process/skill/prepush/. A lens text's sha256 is part of every
reuse key and the texts are part of every prompt, so they carry no SPDX
header; --version prints the charter hashes: 1728bd4c, 148d5c4c,
c7ffef44 and 2b9a5f83 for the four charters.
Home() finds them: CRAFTER_REVIEW_HOME, natively only (a host setting
must not swap the Flatpak's texts for a checkout's), then
<exe>/../share/crafter-review, then the checkout the binary was built in.
Main() hands `__supervise` to the supervisor before anything else, then
decides the sandbox once.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 05:51:37 +01:00
detached background shell (`setsid nohup … > <log> 2>&1 < /dev/null &` );
poll `~/.cache/review-gates/<hash8>-run-<n>/progress.json` and `log.txt` .
Add `--context-paths` for the evidence dirs the messages' claims rest on.
To stop a run: `flatpak run net.catcrafts.CrafterReview stop <its scratch
dir>` (the last word of its gate-0 log), never a kill of a pid — inside
the Flatpak the pid it shows is not the driver. Exit 0 = push-ready / 1 FIX
FIRST / 2 INCOMPLETE, PARTIAL or CONFIRMING (gates clean, static code units
still owe clean reads of 3 — run the SAME command again on the same hash,
it is the next round, until SEND-READY) / 3 preflight; the dump path is
the last stdout line.
5. **On FIX FIRST ** — per undischarged finding exactly one disposition
(prepush.md §Verdicts): FIX it (amend/rebase the commit in another
worktree, `freeze --replace` into the same dir, restart the application
and the stack from the new HEAD, rerun — clean units are reused automatically), REFUTE
it with a fact (register a `refuted` entry), else an OWNER ASK — batched,
one message per gate stop (finding, evidence, proposed grounds, cost of
fixing instead), blocking until they rule; their ruling becomes a
`waiver-owner` entry (dated, `supersedes` , `anchors` with counts,
`grounds` , `carry` ). A `contests` entry is a lens claim: re-check its cited
evidence first; a surviving contest on an owner entry goes to the owner.
Notes never block — bank each per its kind; an `unverified` note names a
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).
2026-10-31 20:08:26 +01:00
manual check the owner sees at Gate 5. INCOMPLETE is never a pass: rerun.
feat(core): the data home, the lens texts, and --version naming both
process/ holds the procedure, the five lens texts, the templates and the
skill under process/skill/prepush/. A lens text's sha256 is part of every
reuse key and the texts are part of every prompt, so they carry no SPDX
header; --version prints the charter hashes: 1728bd4c, 148d5c4c,
c7ffef44 and 2b9a5f83 for the four charters.
Home() finds them: CRAFTER_REVIEW_HOME, natively only (a host setting
must not swap the Flatpak's texts for a checkout's), then
<exe>/../share/crafter-review, then the checkout the binary was built in.
Main() hands `__supervise` to the supervisor before anything else, then
decides the sandbox once.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 05:51:37 +01:00
6. **Rounds ** go in `.review-gates/push/<slug>/manifest.md`
(`flatpak run net.catcrafts.CrafterReview doc manifest` prints the
template; test runs with `--only` /`--units` never).
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).
2026-10-31 20:08:26 +01:00
7. **Gate 5 — the owner ** : present the frozen patches themselves, the rounds
feat(core): the data home, the lens texts, and --version naming both
process/ holds the procedure, the five lens texts, the templates and the
skill under process/skill/prepush/. A lens text's sha256 is part of every
reuse key and the texts are part of every prompt, so they carry no SPDX
header; --version prints the charter hashes: 1728bd4c, 148d5c4c,
c7ffef44 and 2b9a5f83 for the four charters.
Home() finds them: CRAFTER_REVIEW_HOME, natively only (a host setting
must not swap the Flatpak's texts for a checkout's), then
<exe>/../share/crafter-review, then the checkout the binary was built in.
Main() hands `__supervise` to the supervisor before anything else, then
decides the sandbox once.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 05:51:37 +01:00
table, the discharged findings with grounds, every contest, all notes —
then STOP. Nothing is pushed until they explicitly approve that exact hash.
8. **Push ** : `flatpak run net.catcrafts.CrafterReview freeze --slug <slug>
--verify` → MATCH; ` git push` (and the pull request where the flow is a
PR); `approved:` / `pushed:` in the manifest; stop the application and the
stack (`functional.stop` , `supabase.stop` ) when they were started; `git worktree remove .review-gates/trees/<repo>-<hash8>`
when one was used.