feat(config): modes - a mode is an artifact kind, the lenses it runs and its effort

The config defines the modes (modes.<name>): the kind of artifact the mode
reviews - reply, series or commits, the three shipped partitions; a kind
is a mode of its own name - the lenses it runs, in its kind's gate order,
and the effort it runs at, else the kind's default (max for a reply or a
series, xhigh for a commit range). `run --mode` names any of them, the
dump records mode and kind, and everything that decided by the mode's
name - the partition and hash, the prompts, the schemas, the disposition
and reuse-key rules, what the CLI requires - decides by the kind.

Every lens stays off until a mode lists it; lenses.<name>.run is retired
with a warning that says so, and a lens of another kind, a name that is
no lens, a lens listed twice and an unknown effort are config problems.
The defaults run no lens; the template ships the three kinds as modes
with every lens of their kind at the kind's effort, to trim (the owner's
ruling of 2026-11-01), and init says so as it writes it - a kept config
is the repository's own, and only one that lists no lens gets a step.

The readers of the retired key follow: the CI smoke config, the shipped
skill, the procedure (its description of the config as well as its
mechanics), the manifest template, the run's messages and the comments
that named the three modes. The run lock, the run numbers and the dump
names are the kind's, so one full run per hash holds across the modes
of a kind and their rounds count on together; the dump says which mode
ran. The database broker starts for a lens the mode runs, as every other
reader of the lenses off reads them. A named mode runs through the CLI
in the kernel-modes test.
This commit is contained in:
Jorijn van der Graaf 2026-11-01 01:31:40 +01:00
commit d5e54ffeb3
Signed by: jorijnvdgraaf
GPG key ID: 2937E59CDCC1BCFB
25 changed files with 1277 additions and 711 deletions

View file

@ -43,7 +43,7 @@ crafter-review config # edit .review-gates/config.json until it prints no
```
`init` does four things:
- it writes `.review-gates/config.json` from the template when there is none - every lens off: turn on the ones this repository runs;
- it writes `.review-gates/config.json` from the template when there is none - the three artifact kinds as modes with every lens of their kind: trim each to what this repository runs;
- it adds `.review-gates/push/` and `.review-gates/trees/` to `.gitignore`;
- it writes the `/prepush` skill to `.claude/skills/prepush/SKILL.md`, which a later `init` refreshes (the line after its frontmatter marks it as init's);
- it prints the next steps.
@ -52,7 +52,8 @@ It writes nothing in a subdirectory, in your home directory (`--force` when that
`.review-gates/config.json` is committed. It says what the pipeline must know about the repository:
- who may author its commits, and which branch a range is measured against;
- which lenses run (every lens is off until `lenses.<name>.run` is true) and the environment each gets (`none`, `browser`, `supabase` or `browser+supabase`);
- its modes (`modes.<name>`): each an artifact kind (`reply`, `series`, `commits`; a kind is a mode of its own name), the lenses it runs (every lens is off until a mode lists it; they run in their kind's gate order - the table above for commits, the kernel modes' gates below for a series or a reply) and the effort it runs at; `run --mode` names one;
- the environment each lens gets (`none`, `browser`, `supabase` or `browser+supabase`);
- each lens's own section (`lenses.<name>.section`), a file in the repository appended to that lens's shipped charter, for the calibration entries and conventions that are this repository's rather than the lens's (the reuse keys carry the combined text's hash); a lesson general to the lens goes into the shipped charter;
- how its application is started and reached: one stack, or several side by side (`slots`);
- where its local database answers;
@ -66,7 +67,7 @@ It writes nothing in a subdirectory, in your home directory (`--force` when that
2. `git submodule deinit -f review-gates && git rm review-gates`
3. `crafter-review init`. If `.claude/skills/prepush` is the old link into `review-gates/`, it removes the link, never writing through it, and makes a real directory with the skill.
`config.json` keeps working unchanged. So do the reuse keys: a range reviewed before the move is reused, not bought again.
An existing `config.json` needs one change since 2026-11-01: `lenses.<name>.run` is retired, so list the lenses in `modes.commits.lenses` (`config` names what is missing, and `freeze`, `run` and `slots` refuse until it is there). The reuse keys keep working: a range reviewed before the move is reused, not bought again.
## Running a review
@ -91,14 +92,14 @@ A directory can review repositories other than itself: a workbench whose config,
### The kernel modes: a patch series, a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review a kernel contributor's workbench keeps: `--mode series` over a `git format-patch` export with its cover letter, and `--mode reply` over a mail draft (a reply's gate-state sits beside the draft). Both take `--subsystem <name>`, whose journal - `journal/<name>/ledger.md`, `captures/`, `captures/threads/` - is the lenses' evidence, and the trees `--trees` names (default `work/linux,work/milos-linux`; history only in the full clone). lore.kernel.org is reached through `python3 utilities/lore.py` in the working directory, which also prefetches every reference the artifact cites into `gate-state/refs/` before the gates run. The series gates are structure (better-solution), code (code-quality, minimalism, bug-prover) and artifact truth (facts, consistency, process-docs, etiquette, conciseness); a reply runs artifact truth alone. `--reviewers "A B,C D"` adds the persona gate after them: one instance of the maintainer-persona lens per reviewer, calibrated on their own lore mail, its whole pass gating its blocks and pruning the units that are not theirs (`--persona-blocks all` keeps them). Gates clean without a persona pass is GATES CLEAN, not SEND-READY. These lenses are off until the config turns them on, like every other; the effort defaults to max, and a reply's units are read once.
Beside the push gates, crafter-review runs the pre-send review a kernel contributor's workbench keeps: `--mode series` over a `git format-patch` export with its cover letter, and `--mode reply` over a mail draft (a reply's gate-state sits beside the draft). Both take `--subsystem <name>`, whose journal - `journal/<name>/ledger.md`, `captures/`, `captures/threads/` - is the lenses' evidence, and the trees `--trees` names (default `work/linux,work/milos-linux`; history only in the full clone). lore.kernel.org is reached through `python3 utilities/lore.py` in the working directory, which also prefetches every reference the artifact cites into `gate-state/refs/` before the gates run. The series gates are structure (better-solution), code (code-quality, minimalism, bug-prover) and artifact truth (facts, consistency, process-docs, etiquette, conciseness); a reply runs an artifact truth of its own alone (facts, etiquette, consistency, conciseness). `--reviewers "A B,C D"` adds the persona gate after them: one instance of the maintainer-persona lens per reviewer, calibrated on their own lore mail, its whole pass gating its blocks and pruning the units that are not theirs (`--persona-blocks all` keeps them). Gates clean without a persona pass is GATES CLEAN, not SEND-READY. These lenses are off until the config turns them on, like every other; the effort defaults to max, and a reply's units are read once.
To stop a run, run `crafter-review stop <its scratch dir>`, or `crafter-review stop --hash <hash8>` for every live run of a hash. Its running passes are killed, no later gate starts and the dump is written. A run takes its passes with it however it ends, SIGKILL included: each pass runs under a supervisor that kills its whole tree, the MCP server and Chromium included. `flatpak kill net.catcrafts.CrafterReview` is the hard stop.
| Command | What it does |
|---|---|
| `freeze` | Gate 0: the checks, the export, the hash, the run line; `--verify` at push time |
| `run` | the gates of the mode (`--mode commits`, `series` or `reply`): the lenses, the dump; `--dry-run` launches nothing |
| `run` | the gates of the mode (`--mode`: `commits`, `series`, `reply` or one of the repository's own, as the config defines it): the lenses, the dump; `--dry-run` launches nothing |
| `slots` | how many stacks fit in free memory, and the commands for the missing ones |
| `config` | the merged config and its problems |
| `seats` | every seat probed: both windows, their resets, the drivers running |