feat(review): the review is a gate - verdict in the file, CC engine, project memory

Ordre 5 (wave 1, P11 + P5), review_version 1.1.

- K7: `verdict: ALLOW | WARN | BLOCK` is required in review.md (strict
  error, soft warning for 1.0 reviews). New CLI lib/review/verdict-gate.mjs:
  0 = ALLOW/WARN, 1 = BLOCK, 2 = could not decide (never green); a verdict
  greener than the file's own BLOCKERs or JSON block is exit 2. Realpath
  main guard (the old file:// guard exits 0 under a symlink - measured).
- No finding is struck for length: succinctness trims only MINOR/SUGGESTION
  text (catalogue tier), keeps BLOCKER/MAJOR whole, counts trims; the
  coordinator lists what it declined to judge.
- Claude Code's /code-review and /security-review run as the engine via the
  Skill tool (never --fix/--comment/--post/ultra); lib/review/engine-findings.mjs
  turns their findings into a reviewer payload; two catalogue keys
  (CODE_REVIEW_DEFECT, SECURITY_REVIEW_VULNERABILITY), catalogue 12 -> 14.
  An engine that did not run forbids ALLOW.
- Every BLOCKER is written as a numbered `### Step R<n>` with its source
  finding (strict error REVIEW_MISSING_REMEDIATION_STEP).
- P5: lib/review/recurrence.mjs - a finding class in two review.md files
  (current + git history, no new store) becomes one proposal, routed by the
  catalogue's memory_route; written only between Voyage markers in
  .claude/rules/voyage-review-lessons.md under a size budget, CLAUDE.md gets
  a pointer only; the operator approves every line (Phase 8.7).
- Workflow substrate: catalogue enum in step; a missing reviewer or engine
  forbids ALLOW there too (it returned ALLOW on zero findings before).
- Fixtures review-run-A/B said WARN over a BLOCKER; now BLOCK.

Borrowed and credited in code: Superpowers (declined-to-judge), ai-native-sdlc
(cap only nits; mistake/fix/check), Spec Kit (managed block; converge steps),
Pocock (retro routing), Kiro (verdict file + gate; evidence per lesson),
Cherny (engine -> brief control order; review -> memory; budget).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Kjell Tore Guttormsen 2026-10-06 19:45:52 +02:00
commit d88245c06e
Signed by: ktg
SSH key fingerprint: SHA256:JakMjO6FTBBzN0Bhfj9saOoEjaFxlSdYuZQQpM/lF9Q
28 changed files with 2052 additions and 110 deletions

View file

@ -410,13 +410,29 @@ and a contracted **Handover 6 (review → plan)** so findings can be fed back in
`/trekplan --brief review.md` to produce a remediation plan — closing
the iteration loop without ad-hoc conventions.
**The review is a gate.** In this order: Claude Code's own `/code-review` and
`/security-review` find correctness and security defects (started through the
Skill tool, never with `--fix`); Voyage's control against the brief runs after
them and is the part that stops. The verdict is written in `review.md`
(`verdict: ALLOW | WARN | BLOCK`, required) and one command decides on it:
```bash
node lib/review/verdict-gate.mjs <dir>/review.md
# 0 = ALLOW or WARN · 1 = BLOCK · 2 = could not decide (never green)
```
No finding is struck for length: only MINOR/SUGGESTION text is trimmed, and
counted; what the coordinator set aside is listed under `## Declined to
Judge`. An engine that could not run (older Claude Code, no `origin` remote)
keeps the review from coming back `ALLOW`, and the summary says why.
### Modes
| Mode | Command | Description |
|------|---------|-------------|
| **Default** | `/trekreview --project <dir>` | brief-conformance + code-correctness reviewers in parallel, coordinator dedup + verdict, write `{dir}/review.md` |
| **Default** | `/trekreview --project <dir>` | Claude Code `/code-review` + `/security-review`, then brief-conformance + code-correctness reviewers in parallel, coordinator dedup + verdict, write `{dir}/review.md`, verdict gate |
| **Since ref** | `/trekreview --project <dir> --since <ref>` | Override "before" SHA for the diff range. Validated via `git rev-parse --verify` |
| **Quick** | `/trekreview --project <dir> --quick` | Skip brief-conformance reviewer; skip coordinator's reasonableness filter — fast correctness-only pass |
| **Quick** | `/trekreview --project <dir> --quick` | `/code-review` + code-correctness reviewer only; skip brief-conformance reviewer, `/security-review` and the coordinator's reasonableness filter — fast correctness-only pass |
| **Validate** | `/trekreview --project <dir> --validate` | Schema-only check on existing `review.md`. No LLM calls |
| **Dry run** | `/trekreview --project <dir> --dry-run` | Print discovered scope + triage map; skip writes |
| **Profile** | `/trekreview --profile <name> --project <dir>` | (v4.1.0) Pin model profile for the review phase. See [Profile system](#profile-system-v410). |
@ -430,7 +446,18 @@ the iteration loop without ad-hoc conventions.
- `## Findings (MINOR)` — nice-to-fix
- `## Findings (SUGGESTION)` — opinion-only
Required body sections: `## Executive Summary`, `## Coverage`, `## Remediation Summary`. The Coverage section enumerates which files were deep-reviewed, summary-only, or skipped (with reason) — explicit triage to avoid silent skips.
Required body sections: `## Executive Summary`, `## Coverage`, `## Remediation Summary`. The Coverage section enumerates which files were deep-reviewed, summary-only, or skipped (with reason) — explicit triage to avoid silent skips. Every BLOCKER is also written as a numbered plan step (`### Step R1: …` with Files, Source finding, Test first, Verify) under `## Remediation Steps`, ready to append to a plan.
### Project memory (recurring findings)
A finding class (the same rule) that shows up in two reviews in your repo
becomes one proposed line — **mistake · fix · how to check** — with both
findings as evidence. Mechanical classes name a check; judgement classes go
to `.claude/rules/voyage-review-lessons.md`, which Claude Code loads at
session start; `CLAUDE.md` only gets a one-line pointer. You approve every
line (Voyage asks). Voyage writes only between its own markers and stops at a
size budget — past it, the lessons belong in a skill, and that is your call.
The history is the `review.md` files your repo already has; no new store.
### Triage gate (deterministic)
@ -444,7 +471,7 @@ A path-pattern classifier produces `{file → deep-review|summary-only|skip}` be
/trekplan --brief <dir>/review.md
# → plan.md with `source_findings: [<id>, ...]` audit trail
# (BLOCKER + MAJOR findings become plan goals; MINOR + SUGGESTION skipped for v1.0)
# (BLOCKER + MAJOR findings become plan goals; MINOR + SUGGESTION skipped)
```
The plan's optional `source_findings:` frontmatter list is the audit trail back to consumed findings. See `docs/HANDOVER-CONTRACTS.md` for the full Handover 6 contract.