Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 28 additions & 1 deletion docs/plans/2026-10-24-code-rules-reach-the-reviewer.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
canonical: decisions:docs/plans/2026-10-24-code-rules-reach-the-reviewer.md
phases: [2]
phases: [2, 4]
status: done
---
# Code rules reach the reviewer (pointer)
Expand All @@ -26,3 +26,30 @@ The `Candidates:` block (phase 4) comes in a later PR.
- approve-with-changes, then approve-with-changes on the Delta. Fixed: the reviewer contract's no-corpus case, exit 1 named, the repeated lines kept, the Delta's fresh RULES line.
- deliberate: the Delta step does not yet say "none in a repository with no `.adr.yaml`"; phase 4's dotfiles PR edits this same paragraph for the `Candidates:` block and adds it.
- 41k + 44k tokens.

## Phase 4

This repository carries Phase 4's skill and agent edits:
- F4b's brief lists the `<<<CANDIDATES …>>>` block that amont-agent 3.3.0 prints;
- step 3 and the Delta paste that block verbatim into the reviewer's prompt, after the RULES line;
- the implementation-review contract adds a `Candidates:` block ruling on every listed id, which the push check reads; the output word cap leaves that block out;
- the no-corpus exception goes, since `review-brief` now handles a repository with no `.adr.yaml`.

The Delta's "none in a repository with no `.adr.yaml`" note (Phase 2's deliberate) lands here.

### Verification (phase 4)

Input → expected → actual:
- amont-agent#144's implementation reviewer, given the inline `<<<CANDIDATES … n=18>>>` block → a `Candidates:` block ruling on every listed id → 18/18 in round 1 and 18/18 in the delta (including the one new id), each `fine` with a quoted rule-body clause.
- `amont-agent review-brief` 3.3.0 in this repository, which has no `.adr.yaml` → exit 0, no RULES line, a "no aval corpus" section, a CANDIDATES block → exit 0, as expected, `n=0`.

A deployed Round-1 review whose `Candidates:` block the push check reads without a "left without a ruling" entry can only run after `chezmoi apply`, on the next code branch. It is recorded in the decisions PR that records phase 4.

### Implementation review (phase 4)

- approve-with-changes (4 findings), then approve on the Delta.
- Fixed:
- the Delta always carries the CANDIDATES block, and only the RULES line is absent without a corpus;
- the contract no longer says the brief is "hand-built";
- step 3 asks for `Candidates:` only when the block lists an id.
- 34k + 38k tokens.
19 changes: 15 additions & 4 deletions dot_claude/agents/implementation-review.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@ never waive a rule, and never approve on the author's behalf.
Your prompt carries, in order: the review block
(`<<<TREE repo=<name> sha=<64 hex>>>>` — the tree you are reading, which
the hook will check against the push), `Round 1.` or `Delta.`, the
`<<<RULES sha=…>>>` line, the brief `amont-agent review-brief` built (inline,
`<<<RULES sha=…>>>` line, the `<<<CANDIDATES …>>>` block, the brief
`amont-agent review-brief` built (inline,
or its path to read in full), and this contract. In a repository with no
`.adr.yaml` there is no RULES line and the brief is hand-built: that is not a
defect. Read the plan at the path the brief
`.adr.yaml` there is no RULES line and the brief says it has no decided code
rules: that is not a defect. Read the plan at the path the brief
names first, then the diff the brief carries (or the files its stat names,
when the diff was too large to inline). Open at most 10 more files or
1,500 lines: the files the diff touches, then their tests.
Expand Down Expand Up @@ -65,7 +66,7 @@ Every finding needs evidence: a `file:line` in the diff, or a line of the
plan. A finding without one is a question, and belongs under "Would still
check by hand".

## Output (at most 350 words)
## Output (at most 350 words, not counting the `Candidates:` block)

The first line is the verdict, exactly as below, because the hook reads it.

Expand All @@ -74,8 +75,18 @@ Verdict: approve | approve-with-changes | rework
Findings:
1. [blocking|high|medium|low] <the problem>. Evidence: <file:line>. Rule: <id or —>. Edit: <the concrete change>.
Would still check by hand: <one to three things a person should look at that a diff cannot show>
Candidates:
<id or its first 12 hex> violation: <the finding, as in Findings>
<id or its first 12 hex> fine: <one clause quoted from that rule's body>
```

The `Candidates:` block rules on every id the prompt's CANDIDATES block
lists, and only those: `violation:` when the line breaks the rule (and the
same problem is a finding above), `fine:` with the clause of the rule body
that makes it fine. The push check reads this block and journals any id left
without a ruling. With `<<<CANDIDATES unavailable>>>`, or `n=0`, there is no
block to write.

`rework` only when the implementation cannot ship as written: a ticked
phase that is not there, a recorded verification that cannot be true, or
a blocking constraint violation whose fix changes the design. A blocking
Expand Down
22 changes: 15 additions & 7 deletions dot_claude/skills/worktree-task/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -182,22 +182,25 @@ below names one of them.
It prints, in order:
- the `<<<TREE repo=… sha=…>>>` block (the same as `tree-sha --block`:
`HEAD` without `docs/plans/`) and a `<<<RULES sha=…>>>` line;
- the `<<<CANDIDATES sha=… n=…>>>` block (amont-agent 3.3.0 and
adr-lint 0.3.0): one line per candidate line the diff adds, ending
`<<<END CANDIDATES>>>`, or `<<<CANDIDATES unavailable>>>` when adr-lint
could not run;
- the plan's Verification section;
- the diff stat, and the full diff under 60 KB;
- the code rules in full;
- the constraint index;
- the decisions that apply to the changed paths, each resolved;
- a `## Candidates` section with each candidate's pattern and line;
- the plan's Non-goals.

For a pointer plan, pass the canonical plan's path. The merge-base is
the remote's default branch; pass `--base <ref>` for a stacked branch.
Exit 1 means the repository or its base could not be read: pass
`--base <ref>` (a stacked or local-only branch). Exit 3 means aval
failed and nothing was printed; fix aval, never hand-build the brief
instead. One exception, until review-brief
handles it: a repository with no `.adr.yaml` has no decided code
rules, and aval exits 3 there. Build that brief by hand from the
parts above, with no rules section and no RULES line.
instead. A repository with no `.adr.yaml` has no decided code rules:
the brief says so and carries no RULES line (amont-agent 3.3.0).
2b. **Interface review** (advisory; skipped unless the diff touches the
repository's UI). Trigger: the `ui` areas from `aval traits`, matched
against `git diff --name-only <base>..HEAD`; no match, no step. Build
Expand All @@ -216,8 +219,12 @@ below names one of them.
3. Launch the `implementation-review` agent once, in the foreground,
with, in order: the TREE line verbatim; `Round 1.`; the RULES line
verbatim (the push check journals a review whose prompt lacks it, or
carries a stale one); the brief, inline or as its path with "read it
in full" (an inline brief repeats both lines at its top; leave them);
carries a stale one); the CANDIDATES block verbatim, from its first
line to `<<<END CANDIDATES>>>` (the push check reads the ids from the
prompt, not from a file); the brief, inline or as its path with "read
it in full" (an inline brief repeats these lines at its top; leave
them); when the block lists any id, "Your result must carry a
`Candidates:` block ruling on every listed id";
"Read the plan and the diff. Open at most 10 more files or 1,500
lines. Follow your output contract." A background launch counts only
after its completion notification.
Expand All @@ -236,7 +243,8 @@ below names one of them.
6. `approve`, or `approve-with-changes` with every finding fixed or
named deliberate: continue to F5. A fix that changes code returns to
F1, and the **second** pass through F4b is the `Delta`: a fresh block
for the new tree, `Delta.`, the RULES line from a fresh
for the new tree, `Delta.`, the RULES line (absent in a repository
with no `.adr.yaml`) and the CANDIDATES block from a fresh
`review-brief`, the round-1 findings, the diff since,
"answer resolved / not resolved / new blocker for each". The Delta may
resume the same reviewer with `SendMessage` (the block first in the
Expand Down
Loading