A repository that takes commits from people it cannot list has no way to freeze a range today: a null `authors` falls back to `git config user.email`, so every foreign author or committer fails. Null, or no key, now means neither is checked; the freeze warns that it did not check them and records `authors` as null. A list is checked as before. An empty list, which no commit could pass, is a config error that points at null. Released as 1.1.0.
7.5 KiB
Crafter Review
Adversarial review before a push or a send. A range of commits is frozen, cut into units, and every unit is read by review lenses - one claude --print process each - in a fixed order of gates. Each lens asks one question and reports defects with their evidence; a gate passes when its lenses find nothing, and the last gate is the owner, who approves the exact frozen hash. A static lens's clean read of a unit is kept and reused only once three rounds have read it clean.
It reviews three kinds of artifact:
commits: a commit range of one of your own repositories, before the push;series: a kernel patch series asgit format-patchexports it, with its cover letter, before the send;reply: a mailing-list reply draft.
Install
crafter-review ships as a Flatpak with its own git, Node and ripgrep, so every machine reviews with the same tools.
flatpak remote-add --if-not-exists catcrafts https://flatpak.catcrafts.net/catcrafts.flatpakrepo
flatpak install catcrafts net.catcrafts.CrafterReview
alias crafter-review='flatpak run net.catcrafts.CrafterReview'
The machine provides the rest:
| The Claude Code CLI | Proprietary, not bundled. Found through CLAUDE_BIN or REVIEW_GATES_CLAUDE_BIN, the PATH, an editor extension's bundled binary, ~/.claude/local or ~/.local/bin. |
| Seats | A dotenv file with CLAUDE_CODE_OAUTH_TOKEN1..6 or ANTHROPIC_API_KEY1..6: --env-file, else $SEATS_ENV_FILE, else the working directory's .env when it holds a seat or a placement setting, else ~/.config/crafter-review/env. Its seats go over the environment's; with none, your own login. The file's REVIEW_GATES_* placement settings count too. crafter-review seats probes them; every driver on the machine shares one seat board. |
| Chromium | For a lens with the browser: crafter-review browser install, once. |
| A local Supabase stack | For a lens with the database (supabase start, or the repository's own bring-up). The sql helper speaks the Postgres protocol itself; every call is one transaction, rolled back. |
| gpg | Only for signed commits: freeze reads the signatures through gnupg's keyboxd socket. |
Set a repository up
From the repository's toplevel:
crafter-review init
crafter-review config # edit .review-gates/config.json until it prints no problem
init writes .review-gates/config.json from the template when there is none, adds .review-gates/push/ and .review-gates/trees/ to .gitignore, and writes the /prepush skill to .claude/skills/prepush/. The skill is generated: it ignores itself in git, and a later init refreshes it. init writes nothing it did not make, unless --force.
.review-gates/config.json is committed. It says:
- what
freezechecks:authors(null: not checked),aiTrailers,requireSigned, and the branch a range is measured against (base,rangeFrom); modes.<name>: the kind of artifact, the lenses it runs and their effort. Every lens is off until a mode lists it;run --modepicks one;lenses.<name>: the environment a lens gets (none,browser,supabaseorbrowser+supabase) and, if the repository has one, itssection- a file of this repository's own appended to the lens's charter;functional,slots,supabase: how the application is started and reached, one stack or several, and where its database answers;allowDirty,gate0: the tracked paths the stack rewrites, and the commands Gate 0 runs by hand.
crafter-review doc config prints the template; crafter-review doc prepush prints the procedure the /prepush skill follows.
Run a review
crafter-review freeze --slug <branch> # Gate 0: the checks, the export, the hash - and the run line
crafter-review run … # the line freeze printed (run-line.txt), from a detached shell
Exit codes: 0 SEND-READY, 1 FIX FIRST, 2 run the same line again (INCOMPLETE, PARTIAL or CONFIRMING), 3 preflight. Every finding, note and coverage entry is in the dump, gate-state/commits-<hash8>-run-<n>.json. crafter-review stop --hash <hash8> kills a run's passes and writes its dump.
A directory can review other repositories: freeze --repo <path> --out <dir> --worktree, then the printed run line. The config, the seats and the records are the reviewing directory's.
The kernel modes take --subsystem <name>, whose journal (ledger.md, captures/) is the lenses' evidence, and the trees --trees names; lore.kernel.org is read through utilities/lore.py in the working directory. --reviewers "A B,C D" adds one maintainer persona per reviewer, calibrated on their own lore mail; clean gates without a persona pass are GATES CLEAN, not SEND-READY.
The lenses
Gates run in order, and each must pass before the next starts. The owner is the last gate of every mode.
commits - a commit range:
| Gate | Lens | Asks |
|---|---|---|
| 1 Approach | repo-better-solution |
the right mechanism, layer and commit shape? compatible with what users have? |
| 2 Functional | repo-functional (needs the browser) |
in the running application, does the range do what its code and messages say, and leave the flows next to it working? |
| 3 Proof | repo-bug-prover |
a demonstrated defect in the range's code |
| 3 Proof | repo-security |
a demonstrated gap in a protection the repository promises |
| 4 Commit truth | repo-facts |
every claim in every commit message and changed document, proven or gone |
series - a kernel patch series:
| Gate | Lens | Asks |
|---|---|---|
| 1 Structure | better-solution |
should the series be replaced: another mechanism, layer or shape? |
| 2 Code | code-quality |
the defects a careful subsystem maintainer finds: interactions, error and teardown paths, style |
| 2 Code | minimalism |
can it be done with less: fewer lines, hunks, patches, files? |
| 2 Code | bug-prover |
a demonstrable defect in the code the series produces |
| 3 Artifact truth | facts |
every claim in the cover letter, the messages and the notes, disproved or proven |
| 3 Artifact truth | consistency |
contradictions between the artifacts, the ledger and what was said on-list |
| 3 Artifact truth | process-docs |
the series against the kernel's own in-tree process documentation |
| 3 Artifact truth | etiquette |
how it lands with the humans on the thread: tone, attribution, conventions |
| 3 Artifact truth | conciseness |
the shorter text, every dropped clause accounted for |
| 4 Persona | maintainer-persona |
one named reviewer's reading of the final artifact (--reviewers) |
reply - a mailing-list reply: Gate 3, artifact truth, with facts, etiquette, consistency and conciseness, then the persona gate.
Commands
| Command | |
|---|---|
init, config, doc |
set a repository up; the merged config and its problems; the shipped texts |
freeze |
Gate 0: the checks, the export, the hash, the run line; --verify at push time |
run |
the gates of a mode (--mode); --dry-run launches nothing |
stop |
stop a run: its passes are killed, the dump written |
seats, slots |
every seat probed; how many stacks fit in free memory |
browser install |
the Chromium the Playwright MCP server drives |
sql, totp, inventory |
the helpers a lens runs; the partition of an artifact into units |
License
crafter-review is licensed under the GNU Affero General Public License v3.0 only (LICENSE).
Vendored files in the lib directory maintain their own license.
Copyright
Copyright (C) 2026 Catcrafts®