docs: the README
Install, what the machine provides, setting a repository up with init,
moving a repository off the review-gates submodule, running and stopping a
review, the commands, what the sandbox gets (--filesystem=host is a
convenience, not an isolation boundary), the board several drivers share,
building from source, the licence and nlohmann/json's.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 16:18:42 +01:00
# Crafter Review
2026-11-02 12:01:40 +01:00
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.
docs: the README
Install, what the machine provides, setting a repository up with init,
moving a repository off the review-gates submodule, running and stopping a
review, the commands, what the sandbox gets (--filesystem=host is a
convenience, not an isolation boundary), the board several drivers share,
building from source, the licence and nlohmann/json's.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 16:18:42 +01:00
2026-11-02 12:01:40 +01:00
It reviews three kinds of artifact:
docs: the README
Install, what the machine provides, setting a repository up with init,
moving a repository off the review-gates submodule, running and stopping a
review, the commands, what the sandbox gets (--filesystem=host is a
convenience, not an isolation boundary), the board several drivers share,
building from source, the licence and nlohmann/json's.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 16:18:42 +01:00
2026-11-02 12:01:40 +01:00
- `commits` : a commit range of one of your own repositories, before the push;
- `series` : a kernel patch series as `git format-patch` exports it, with its cover letter, before the send;
- `reply` : a mailing-list reply draft.
docs: the README
Install, what the machine provides, setting a repository up with init,
moving a repository off the review-gates submodule, running and stopping a
review, the commands, what the sandbox gets (--filesystem=host is a
convenience, not an isolation boundary), the board several drivers share,
building from source, the licence and nlohmann/json's.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 16:18:42 +01:00
## Install
2026-11-02 12:01:40 +01:00
crafter-review ships as a Flatpak with its own git, Node and ripgrep, so every machine reviews with the same tools.
docs: the README
Install, what the machine provides, setting a repository up with init,
moving a repository off the review-gates submodule, running and stopping a
review, the commands, what the sandbox gets (--filesystem=host is a
convenience, not an isolation boundary), the board several drivers share,
building from source, the licence and nlohmann/json's.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 16:18:42 +01:00
```bash
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'
```
2026-11-02 12:01:40 +01:00
The machine provides the rest:
docs: the README
Install, what the machine provides, setting a repository up with init,
moving a repository off the review-gates submodule, running and stopping a
review, the commands, what the sandbox gets (--filesystem=host is a
convenience, not an isolation boundary), the board several drivers share,
building from source, the licence and nlohmann/json's.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 16:18:42 +01:00
2026-11-02 12:01:40 +01:00
| | |
|---|---|
| **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` . |
feat(seats): an API seat's cycle starts on its own grant day
The ledger reset every API seat's spend on one
REVIEW_GATES_API_CYCLE_DAY and cleared every credit-out, an OpenRouter
key's too, at that reset. Each API seat's cycle starts on its
ANTHROPIC_API_KEY<n>_GRANT_DAY now (1..31, a day past a month's end its
last), else the cycle day, also 1..31. A credit-out carries across the
rollover, and the run's probe tries a key held out on credit again, as
`seats` does an API key: an ok lifts the mark - an API key's is new
credits, its cycle restarting from the grant day, or from today when
that day is over a week back; an OpenRouter key keeps its cycle's spend,
and a key that answers with its cycle's budget spent stays out on that
budget. A probe that finds a key out of credit records it, unless the
ledger already has it out. Both are decided in one locked update on the
file's entry, a mark another driver made since the probe started
standing, and the ledger's stamps carry their UTC offset so marks are
ordered by instant.
`seats` shows the probe's reading beside the driver's verdict (the
`probe` and `driver` columns replace `state` and `ledger: out`), each
seat's grant day and when its next credits are due, and notes on what
the probe changed in the ledger or why the driver's verdict stands; the
run logs the days.
2026-11-02 13:58:29 +01:00
| **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; `ANTHROPIC_API_KEY<n>_GRANT_DAY` sets the day an API seat's cycle starts. `crafter-review seats` probes them; every driver on the machine shares one seat board. |
2026-11-02 12:01:40 +01:00
| **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. |
docs: the README
Install, what the machine provides, setting a repository up with init,
moving a repository off the review-gates submodule, running and stopping a
review, the commands, what the sandbox gets (--filesystem=host is a
convenience, not an isolation boundary), the board several drivers share,
building from source, the licence and nlohmann/json's.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 16:18:42 +01:00
2026-11-02 12:01:40 +01:00
## Set a repository up
docs: the README
Install, what the machine provides, setting a repository up with init,
moving a repository off the review-gates submodule, running and stopping a
review, the commands, what the sandbox gets (--filesystem=host is a
convenience, not an isolation boundary), the board several drivers share,
building from source, the licence and nlohmann/json's.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 16:18:42 +01:00
From the repository's toplevel:
```bash
crafter-review init
crafter-review config # edit .review-gates/config.json until it prints no problem
```
2026-11-02 12:01:40 +01:00
`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` .
docs: the README
Install, what the machine provides, setting a repository up with init,
moving a repository off the review-gates submodule, running and stopping a
review, the commands, what the sandbox gets (--filesystem=host is a
convenience, not an isolation boundary), the board several drivers share,
building from source, the licence and nlohmann/json's.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 16:18:42 +01:00
2026-11-02 12:01:40 +01:00
`.review-gates/config.json` is committed. It says:
docs: the README
Install, what the machine provides, setting a repository up with init,
moving a repository off the review-gates submodule, running and stopping a
review, the commands, what the sandbox gets (--filesystem=host is a
convenience, not an isolation boundary), the board several drivers share,
building from source, the licence and nlohmann/json's.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 16:18:42 +01:00
2026-11-02 13:57:20 +01:00
- what `freeze` checks: `authors` (null: not checked), `aiTrailers` , `requireSigned` , and the branch a range is measured against (`base` , `rangeFrom` );
2026-11-02 12:01:40 +01:00
- `modes.<name>` : the kind of artifact, the lenses it runs and their effort. Every lens is off until a mode lists it; `run --mode` picks one;
- `lenses.<name>` : the environment a lens gets (`none` , `browser` , `supabase` or `browser+supabase` ) and, if the repository has one, its `section` - 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.
docs: the README
Install, what the machine provides, setting a repository up with init,
moving a repository off the review-gates submodule, running and stopping a
review, the commands, what the sandbox gets (--filesystem=host is a
convenience, not an isolation boundary), the board several drivers share,
building from source, the licence and nlohmann/json's.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 16:18:42 +01:00
2026-11-02 12:01:40 +01:00
`crafter-review doc config` prints the template; `crafter-review doc prepush` prints the procedure the `/prepush` skill follows.
docs: the README
Install, what the machine provides, setting a repository up with init,
moving a repository off the review-gates submodule, running and stopping a
review, the commands, what the sandbox gets (--filesystem=host is a
convenience, not an isolation boundary), the board several drivers share,
building from source, the licence and nlohmann/json's.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 16:18:42 +01:00
2026-11-02 12:01:40 +01:00
## Run a review
docs: the README
Install, what the machine provides, setting a repository up with init,
moving a repository off the review-gates submodule, running and stopping a
review, the commands, what the sandbox gets (--filesystem=host is a
convenience, not an isolation boundary), the board several drivers share,
building from source, the licence and nlohmann/json's.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 16:18:42 +01:00
```bash
2026-11-02 12:01:40 +01:00
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
docs: the README
Install, what the machine provides, setting a repository up with init,
moving a repository off the review-gates submodule, running and stopping a
review, the commands, what the sandbox gets (--filesystem=host is a
convenience, not an isolation boundary), the board several drivers share,
building from source, the licence and nlohmann/json's.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 16:18:42 +01:00
```
2026-11-02 12:01:40 +01:00
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.
docs: the README
Install, what the machine provides, setting a repository up with init,
moving a repository off the review-gates submodule, running and stopping a
review, the commands, what the sandbox gets (--filesystem=host is a
convenience, not an isolation boundary), the board several drivers share,
building from source, the licence and nlohmann/json's.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 16:18:42 +01:00
2026-11-02 12:01:40 +01:00
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.
docs: the README
Install, what the machine provides, setting a repository up with init,
moving a repository off the review-gates submodule, running and stopping a
review, the commands, what the sandbox gets (--filesystem=host is a
convenience, not an isolation boundary), the board several drivers share,
building from source, the licence and nlohmann/json's.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 16:18:42 +01:00
2026-11-02 12:01:40 +01:00
## The lenses
feat(run): the repository under review is the freeze record's, not the working directory's
A directory can review repositories other than itself: a workbench whose
config, env file and records serve several, freezing each with --repo and
--out. The run took the working directory for the repository under review:
the prompt named it, the calibration was kept under it, and --trees fell
back to it. The run now reads the repository from the artifact's
freeze.json - the prompt names it and the calibration is kept under it -
and --trees defaults to what the record says: the worktree, else the
repository when it is not the working directory, else `.`, the same rule
that builds the printed run line. The working directory keeps its roles:
the config, the env file, the slots, the lens processes' cwd and every
logged path. A damaged record stops the run at preflight.
2026-10-31 21:31:48 +01:00
2026-11-02 12:01:40 +01:00
Gates run in order, and each must pass before the next starts. The owner is the last gate of every mode.
feat(run): the repository under review is the freeze record's, not the working directory's
A directory can review repositories other than itself: a workbench whose
config, env file and records serve several, freezing each with --repo and
--out. The run took the working directory for the repository under review:
the prompt named it, the calibration was kept under it, and --trees fell
back to it. The run now reads the repository from the artifact's
freeze.json - the prompt names it and the calibration is kept under it -
and --trees defaults to what the record says: the worktree, else the
repository when it is not the working directory, else `.`, the same rule
that builds the printed run line. The working directory keeps its roles:
the config, the env file, the slots, the lens processes' cwd and every
logged path. A damaged record stops the run at preflight.
2026-10-31 21:31:48 +01:00
2026-11-02 12:01:40 +01:00
**`commits` ** - a commit range:
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
2026-11-02 12:01:40 +01:00
| 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 |
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
2026-11-02 12:01:40 +01:00
**`series` ** - a kernel patch series:
docs: the README
Install, what the machine provides, setting a repository up with init,
moving a repository off the review-gates submodule, running and stopping a
review, the commands, what the sandbox gets (--filesystem=host is a
convenience, not an isolation boundary), the board several drivers share,
building from source, the licence and nlohmann/json's.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 16:18:42 +01:00
2026-11-02 12:01:40 +01:00
| 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 | |
docs: the README
Install, what the machine provides, setting a repository up with init,
moving a repository off the review-gates submodule, running and stopping a
review, the commands, what the sandbox gets (--filesystem=host is a
convenience, not an isolation boundary), the board several drivers share,
building from source, the licence and nlohmann/json's.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 16:18:42 +01:00
|---|---|
2026-11-02 12:01:40 +01:00
| `init` , `config` , `doc` | set a repository up; the merged config and its problems; the shipped texts |
docs: the README
Install, what the machine provides, setting a repository up with init,
moving a repository off the review-gates submodule, running and stopping a
review, the commands, what the sandbox gets (--filesystem=host is a
convenience, not an isolation boundary), the board several drivers share,
building from source, the licence and nlohmann/json's.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 16:18:42 +01:00
| `freeze` | Gate 0: the checks, the export, the hash, the run line; `--verify` at push time |
2026-11-02 12:01:40 +01:00
| `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 |
docs: the README
Install, what the machine provides, setting a repository up with init,
moving a repository off the review-gates submodule, running and stopping a
review, the commands, what the sandbox gets (--filesystem=host is a
convenience, not an isolation boundary), the board several drivers share,
building from source, the licence and nlohmann/json's.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 16:18:42 +01:00
## License
2026-11-02 10:51:39 +00:00
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.
docs: the README
Install, what the machine provides, setting a repository up with init,
moving a repository off the review-gates submodule, running and stopping a
review, the commands, what the sandbox gets (--filesystem=host is a
convenience, not an isolation boundary), the board several drivers share,
building from source, the licence and nlohmann/json's.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 16:18:42 +01:00
## Copyright
Copyright (C) 2026 Catcrafts®