amicus 4.0.1 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/CHANGELOG.md +75 -0
  3. package/README.md +3 -3
  4. package/commands/council.md +6 -6
  5. package/package.json +1 -1
  6. package/schemas/council-run.schema.json +15 -1
  7. package/schemas/council-tally.schema.json +10 -1
  8. package/schemas/council-verdict.schema.json +10 -1
  9. package/schemas/error.schema.json +1 -1
  10. package/scripts/postinstall.js +6 -3
  11. package/skills/second-opinion/COUNCIL-DESIGN.md +40 -0
  12. package/skills/second-opinion/MANUAL-ORCHESTRATION.md +266 -0
  13. package/skills/second-opinion/MODEL-NOTES.md +21 -0
  14. package/skills/second-opinion/SEAT-BRIEFS.md +4 -0
  15. package/skills/second-opinion/SKILL.md +319 -333
  16. package/src/cli-handlers-council-run.js +9 -0
  17. package/src/cli-handlers-council.js +20 -2
  18. package/src/cli.js +8 -0
  19. package/src/council/briefings-debate.js +158 -0
  20. package/src/council/briefings-stage2.js +16 -9
  21. package/src/council/debate.js +98 -0
  22. package/src/council/ledger.js +2 -1
  23. package/src/council/parse-stage2.js +83 -1
  24. package/src/council/report-html.js +28 -1
  25. package/src/council/report.js +50 -2
  26. package/src/council/run-assemble.js +91 -9
  27. package/src/council/run-chair.js +145 -0
  28. package/src/council/run-debate.js +289 -0
  29. package/src/council/run-launch.js +27 -1
  30. package/src/council/run-stages.js +19 -7
  31. package/src/council/run.js +100 -110
  32. package/src/council/verdict.js +43 -2
  33. package/src/mcp-council-run.js +7 -0
  34. package/src/mcp-server.js +28 -3
  35. package/src/mcp-tools.js +22 -2
  36. package/src/utils/error-doc.js +2 -0
@@ -24,21 +24,23 @@ Four principles govern this skill:
24
24
 
25
25
  1. **Secondary tool.** By the time this skill runs, Claude has already given its opinion in the main conversation. The skill exists to bring in *independent outside* views — it does not replace or re-run Claude's upstream analysis.
26
26
  2. **The council is the non-Claude bench by default.** Council members are models from families other than the orchestrator (Gemini, DeepSeek, GPT, etc.). Claude is not a first-opinion council member unless the optional "Claude in the council" toggle is on — and even then it is judged but does not vote or chair.
27
- 3. **Claude orchestrates; Claude does not synthesize the verdict.** Claude preps material, recommends the council, anonymizes reviews, drives the stages, scores, and presents accept/deny decisions. A designated non-Claude chair model synthesizes the final verdict. Claude's role ends at presenting it.
27
+ 3. **Claude orchestrates; Claude does not synthesize the verdict.** Claude preps material, recommends the council, drives the run, presents accept/deny decisions, and applies them. A designated non-Claude chair model synthesizes the final verdict. Claude's role ends at presenting it.
28
28
  4. **The subject of cross-review is the other reviews, not the artifact again.** In the peer cross-review stage, models critique and rank *each other's reviews* — not re-review the original artifact. This is the mechanism that surfaces reviewer blind spots and inflated confidence.
29
29
 
30
+ **The engine runs the mechanics (v4.1).** Stages 1–3 and the deterministic Stage-5 artifacts are
31
+ ONE `amicus council run` call: the engine composes every model-facing briefing, runs the review
32
+ wave, validates and repairs findings blocks, anonymizes into the judge bundle, runs the
33
+ cross-review wave, optionally runs the rebuttal round, tallies (appending the reliability
34
+ ledger once), chairs, and writes `verdict.json` + `report.html`. Claude owns the human stages —
35
+ **Stage 0** (intake and briefing), **Stage 4** (tiered decisions), **Stage 5** (apply and present),
36
+ **Stage 6** (lessons). The hand-orchestrated mechanics still exist, in
37
+ **`MANUAL-ORCHESTRATION.md`** next to this file, as the documented fallback.
38
+
30
39
  Operating lessons from each run fold back into `MODEL-NOTES.md` (with approval), so the skill gets better at driving each model over time.
31
40
 
32
41
  **Before launching any model, READ `MODEL-NOTES.md`** (next to this file). It holds the operating rules and per-model quirks that decide whether a run succeeds or silently fails. These were learned the hard way; skipping them wastes runs and produces empty results that look like answers.
33
42
 
34
- **Transport rule — CLI not on PATH:** every command below assumes the `amicus` CLI. If `amicus` is not on PATH (typical for **plugin-only installs**), run the identical commands as `npx -y amicus@latest <args>` (e.g. `npx -y amicus@latest fanout --models "m1,m2,m3" --prompt-file <path> --json`), or use the equivalent MCP tools (`amicus_fanout`, `amicus_start`, `amicus_wait`, `amicus_status`, `amicus_read`, `amicus_council_tally`, `amicus_council_stats`, `amicus_verdict`) — council briefings are always self-contained (`--no-context`), so MCP transport is equivalent.
35
-
36
- **Headless contexts (v4.0):** CI and scripted environments with no Claude runtime can run the
37
- whole mechanical pipeline (Stages 1–3 plus the deterministic Stage-5 artifacts) as one command —
38
- `amicus council run --prompt-file <briefing.md> --models "a,b,c" --chair <model> --json` — see
39
- [docs/council.md](../../docs/council.md#amicus-council-run). This skill's staged, human-in-the-loop
40
- orchestration remains the interactive path: Stage 0 intake, Stage 4 decisions, and Stage 6 lessons
41
- are human stages the engine never automates.
43
+ **Transport rule — CLI not on PATH:** every command below assumes the `amicus` CLI. If `amicus` is not on PATH (typical for **plugin-only installs**), run the identical commands as `npx -y amicus@latest <args>` (e.g. `npx -y amicus@latest council run --prompt-file <path> --models "m1,m2,m3" --json`), or use the equivalent MCP tools (`amicus_council_run`, `amicus_wait`, `amicus_status`, `amicus_verdict`, `amicus_council_stats`, plus `amicus_fanout` / `amicus_start` / `amicus_read` for the manual fallback) — council briefings are always self-contained, so MCP transport is equivalent.
42
44
 
43
45
  ## When to use
44
46
 
@@ -57,311 +59,222 @@ are human stages the engine never automates.
57
59
 
58
60
  ## The council flow
59
61
 
60
- The flow runs as a **Stage 0 intake/prep step** followed by **three sequential review waves** (Stage 1 → Stage 2 → Stage 3), each wave dependent on the prior — plus an optional **Stage 2.5 rebuttal round** when debate mode is on. Within each wave, models run in parallel. Track the stages as todos and do not advance until the prior wave's outputs are in hand.
62
+ **Stage 0 (Claude + user)** **ONE `amicus council run`** (Stages 13 plus the deterministic
63
+ Stage-5 artifacts, all inside the engine) → **Stage 4 (Claude + user)** → **Stage 5 (Claude)** →
64
+ **Stage 6 (Claude + user)**.
65
+
66
+ Track those five steps as todos. Everything before and after the engine call is
67
+ human-in-the-loop; the engine call itself is one background command you do not poll.
61
68
 
62
69
  ### Stage 0 — Intake & prep
63
70
 
64
71
  Confirm the three inputs before doing anything else: **source material**, **the analysis** (the thing to be reviewed), and **the criteria** (what quality/correctness means for this material). Ask only for what is missing; don't re-ask for what is already provided.
65
72
 
66
73
  **Establish the run folder first:** `output/<stem>-council/` (or `./second-opinion/<stem>-council/`
67
- if no `output/` directory exists). Create it now — every temp file, briefing, review, and artifact
68
- in this run is written here. Use its absolute path in all `--prompt-file` arguments.
74
+ if no `output/` directory exists). Create it now — it is both your working directory and the
75
+ engine's `--out-dir`, so every briefing, leg, and artifact for this run lands in one place. Use
76
+ its absolute path in all path arguments.
69
77
 
70
78
  **Prepare material for council models:**
71
- - Large, linked, or heavily marked-up sources → extract clean text to a small, clearly-named temp
72
- file in the run folder (briefing hygiene: token cost and model focus). Reference its absolute
73
- path in the briefing, or inline it if small.
79
+ - Large, linked, or heavily marked-up sources → extract clean text to a small, clearly-named file
80
+ in the run folder (briefing hygiene: token cost and model focus). Reference its absolute path in
81
+ the briefing, or inline it if small.
74
82
  - Small, clean text → feed inline in the briefing.
75
- - Write every briefing to a temp file (`_tmp-*.md` in the run folder) and pass it with
76
- `--prompt-file` never inline a briefing as a CLI argument. All `_tmp-*` files are cleaned up
77
- after the run.
78
- - **Inject the current date into every briefing when the artifact is time-sensitive** (resumes, dated
79
- plans, anything with start/end dates or 'present' ranges). Headless council models do not reliably
80
- know "today" and have raised false "future-dated" blockers; state the date explicitly, e.g.
81
- "Today's date is YYYY-MM-DD."
82
-
83
- **Pick the council.** Default: **3 models from different families (non-Claude)**. Recommend them ranked by fit, consulting both the reviewer-reliability data from `amicus council stats` (the authoritative quantitative source runs, avg peers-only street-cred, confirm-rate, fact-error rate) and the qualitative quirks in `MODEL-NOTES.md`. State the estimated cost. The estimate is the budget gate's pre-flight figure (per-$/Mtok pricing from the cached catalog; direct-provider legs without catalog pricing are disclosed as "cost unknown"). State it as an estimate, not a guarantee. **Disclose the run shape up front** before asking for confirmation — naming any enabled optional council elements and their cost impact (see the optional-elements menu below) — e.g.:
84
-
85
- **Free council (zero-cost).** If the user asks for a "free council" / "zero-cost council",
86
- read `councils.free` from `~/.config/amicus/config.json` and run
87
- `amicus fanout --council free --prompt-file <briefing>`. Free-tier handling:
88
- - Cost \$0 skip the paid-run cost framing (the budget gate is a no-op at zero price).
83
+
84
+ **Author ONE briefing file: `<run-folder>/briefing.md`.** This is the only briefing Claude
85
+ writes, and it carries only the *review request*:
86
+
87
+ - the material inline when small and clean, otherwise the **absolute path** of the extracted
88
+ clean-text file (Stage-1 seats run agentically in the invoking cwd and can read referenced files);
89
+ - the analysis request;
90
+ - the criteria;
91
+ - any material-specific cautions ("the appendix is out of scope", "treat the numbers as given").
92
+
93
+ **Do not restate output contracts in `briefing.md`.** The anti-sycophancy clause, the findings-JSON
94
+ schema, the judge tasks, the no-tools preambles, the chair packet and the verdict-scale addendum
95
+ are all the engine's (`briefings.js` templates) duplicated contracts drift and the engine's copy
96
+ wins anyway. Keep `briefing.md` (it is run provenance, not a temp file); the engine derives its
97
+ composed `briefing-stage1.md` from it.
98
+
99
+ **Temporal context.** State the artifact's temporal context when it matters (resumes, dated plans,
100
+ anything with start/end dates or "present" ranges) — but you no longer inject the current date by
101
+ hand: **the engine stamps** `Today's date is YYYY-MM-DD.` onto every model-facing briefing it
102
+ composes, which is what kills the false "future-dated" blocker class headless models used to raise.
103
+
104
+ **Pick the council.** Default: **3 models from different families (non-Claude)**. Recommend them ranked by fit, consulting both the reviewer-reliability data from `amicus council stats` (the authoritative quantitative source — runs, avg peers-only street-cred, confirm-rate, fact-error rate) and the qualitative quirks in `MODEL-NOTES.md`. State the estimated cost. The estimate is the budget gate's pre-flight figure (per-$/Mtok pricing from the cached catalog; direct-provider legs without catalog pricing are disclosed as "cost unknown"). State it as an estimate, not a guarantee.
105
+
106
+ **Pick the chair — it must NOT be a bench seat.** The engine refuses a chair that also reviews
107
+ (`chair '<m>' is a bench seat — the chair must not review`), so recommend a strong reasoner from
108
+ *outside* `--models`; the engine's own default is `deepseek`. Never put `claude` in `--models` or
109
+ `--chair` — it is a **reserved seat name** for the Claude-in-the-council review (§5.4), and on a
110
+ `--claude-review` run the engine rejects both outright. The engine needs at least **2 bench
111
+ seats**; a 1-model run is the scale-down path below, not an engine run.
112
+
113
+ **Free council (zero-cost bench, paid chair).** If the user asks for a "free council" /
114
+ "zero-cost council", read `councils.free` from `~/.config/amicus/config.json` and launch with
115
+ `--council free` instead of `--models`. Free-tier handling:
116
+ - Bench cost ≈ \$0 — skip the paid-run cost framing for the reviewer legs (the budget gate is a
117
+ no-op at zero price). **The chair is not free — do not pick a free model as chair.**
118
+ `--council free` resolves the bench live from the catalog (`suggestFreeCouncil`, capped at 3
119
+ seats, one `:free` model per vendor), so which vendors land in the bench isn't known until
120
+ launch; naming a free model as chair risks colliding with it and tripping the engine's
121
+ bench-seat guard (`chair '<m>' is a bench seat — the chair must not review`, pre-flight, exit 1
122
+ before any spend). Leave `--chair` unset — it defaults to `deepseek`, which resolves to the
123
+ **paid** `deepseek-v4-pro` route (a different model from any `deepseek:free` bench pick) — or
124
+ name another non-bench paid model the user prefers. Either way, **disclose the chair as a small
125
+ paid cost** even though the bench is \$0; state the estimate.
89
126
  - No reliability history: free models have no `amicus council stats` / `MODEL-NOTES` record,
90
- so don't rank on street-cred. Pick the most capable free model as chair and state lower confidence.
91
- - Weak structured output: small free models are less reliable at the strict findings JSON; expect
92
- more `validateFindings` repair-loop hits.
93
- - Throttled/truncated legs: a mid-stream 429 can yield a leg marked `complete` with a truncated,
94
- unparseable review. When a free-council leg is `complete` but `validateFindings` returns
95
- `NO_FENCED_BLOCK`/`NOT_PARSEABLE`, treat it as suspect/throttled — don't burn the repair loop on the
96
- same throttled model; disclose it and apply the ≥2-reviews-survive wave-degrade rule.
127
+ so don't rank the bench on street-cred; state lower confidence for the reviewers.
128
+ - Weak structured output: small free models are less reliable at the strict findings JSON; the
129
+ engine's bounded repair loop absorbs this and marks the seat's `conformance` accordingly.
130
+ - Throttled/truncated legs: a mid-stream 429 can yield a leg the engine records as degraded rather
131
+ than clean — read `run.json` and disclose it rather than presenting the run as full-strength.
97
132
  - Prerequisite: free models require enabling data-sharing in OpenRouter privacy settings
98
133
  (openrouter.ai/settings/privacy) or legs 404 at run time — catalog validation cannot catch this.
99
134
  State this up front.
100
135
 
101
- > This run uses 3 council models across 2 fanout waves + 1 chair call (~7 model runs), ~10 min.
102
-
103
- or, with elements enabled:
104
-
105
- > This run uses 3 council models across 2 fanout waves + 1 chair call, with **critic seat + debate mode ON** (~7 base runs + up to 6 rebuttal calls), ~15 min.
106
-
107
- Then **wait for confirmation**. Never launch without it. The budget gate enforces the cost guardrail in code: by default it refuses any leg whose price exceeds the per-$/Mtok threshold (the o3/o3-pro guard). To run an intentionally expensive model the user explicitly asked for by name, pass `--no-cost-gate`; to raise only the total ceiling, pass `--max-cost <$>`.
108
-
109
- **Scale-down is explicit — state which mode applies:**
110
- - **1 model** → thorough single pass; Stage 2 (cross-review) and Stage 3 (chair synthesis) are skipped entirely; Claude synthesizes directly. Transport: a single solo `amicus start --no-ui --json` (no fanout).
111
- - **2 models** → Stage 2 runs but the ranking is thin (one ranker per review); note this limitation.
112
- - **3 models (default)** → full deep council with meaningful cross-review and tie-breaking.
136
+ **Engine preflight probe run this before disclosing the run shape.** The fast path needs
137
+ `amicus council run`: CLI ≥ 4.1 for `--debate` / `--claude-review`, ≥ 4.0 for a plain run.
113
138
 
114
- The scale-down levels count **non-Claude judges**; enabling "Claude in the council" adds a judged review but not a judge, so it does not change these levels. If the bench drops below 2 surviving reviews during the run, apply the Stage-1 wave-degrade rule (offer re-run or a disclosed single-pass downgrade).
139
+ - **Shell contexts:** run `amicus --version`.
140
+ - **Cowork / no-Bash contexts:** confirm the `amicus_council_run` MCP tool is present.
141
+ - **Too old or missing →** run the identical command as `npx -y amicus@latest council run …`
142
+ (npx always resolves the current engine — which is exactly why the version probe is mandatory
143
+ rather than optional: a stale global install and a fresh npx cache can disagree).
144
+ - **npx unavailable too →** fall back to **`MANUAL-ORCHESTRATION.md`** and say so before launching.
115
145
 
116
146
  **Present the optional council elements (all default OFF — explicit opt-in only).** After the
117
147
  bench and chair are picked and before asking for launch confirmation, present this menu once
118
148
  (adjust the run-shape numbers to the actual bench):
119
149
 
120
- > Optional council elements — all OFF unless you name them. Reply with any you want (e.g. "1 and 3", "critic + debate mode", or "none"):
150
+ > Optional council elements — all OFF unless you name them. Reply with any you want (e.g. "1 and 3", "critic + debate mode", or "none"). Note the chair's **verdict scale is now standard** — the engine always makes the chair close with `VERDICT: Ship it | Fix these first | Fundamental rethink` plus its hard questions, so it is no longer something to opt into:
121
151
  >
122
- > 1. **Critic seat** — one reviewer swaps to an adversarial brief (adversarial pass, edge-case hunt, consistency check, executability test). Same review count; that seat runs as a solo call. Trade-off: that reviewer can recognize its own review during cross-review (disclosed in the report).
123
- > 2. **Expert lenses** — each reviewer gets a distinct expert perspective; you pick the panel domain (business, technical, customer, financial, custom). Same review count, launched as solo calls. Trade-offs: weakens cross-review anonymity (disclosed) and the run is not recorded to the reliability ledger.
124
- > 3. **Debate mode** — after cross-review, Contested and Disputed findings go back to their raisers to defend, amend, or withdraw, and the disputing judges re-vote before the final tally. Adds 1–2 short waves (up to ~2N extra calls, ~+5 min).
125
- > 4. **Chair verdict scale** — the chair ends its synthesis with `VERDICT: Ship it | Fix these first | Fundamental rethink` plus 3–5 hard questions. No extra calls.
126
- > 5. **Claude in the council** — I add my own fresh review to the bundle so the bench can rank and adjudicate it; I'm judged but do not vote (Stage 2) or chair (Stage 3), so the verdict stays independent. +1 review in the bundle, no extra council calls.
152
+ > 1. **Critic seat** (`--critic <model>`) — one reviewer, which must be one of the bench seats, swaps to an adversarial brief (adversarial pass, edge-case hunt, consistency check, executability test). Same review count. Trade-off: that reviewer can recognize its own review during cross-review (disclosed in the report).
153
+ > 2. **Expert lenses** (`--lenses s1,s2,s3`) — each reviewer gets a distinct expert perspective; you pick the panel domain (business, technical, customer, financial, custom), one lens per seat. Trade-offs: weakens cross-review anonymity (disclosed) and the run is **not** recorded to the reliability ledger.
154
+ > 3. **Debate mode** (`--debate`) — after cross-review, Contested and Disputed findings go back to their raisers to defend, amend, or withdraw, and the disputing judges re-vote before the final tally. Adds 1–2 short waves (up to ~2N extra calls, ~+5 min).
155
+ > 4. **Claude in the council** (`--claude-review`) I add my own fresh review to the bundle so the bench can rank and adjudicate it; I'm judged but do not vote or chair, so the verdict stays independent. +1 review in the bundle, no extra council calls.
127
156
 
128
157
  Rules for this menu:
129
158
 
130
159
  - **Never enable an element the user did not explicitly name.** Silence, "no", or "none" = all off. Do not infer opt-in from the nature of the material ("this doc could use a critic…") — offer, don't decide.
131
160
  - If elements were **pre-requested in the invoking command** (e.g. `/council … with a critic seat and debate mode`), confirm them back by name ("Critic seat and debate mode are ON per your request; the others are off") instead of re-asking.
132
- - **The launch confirmation must enumerate the enabled elements by name** — an element not named in the confirmation is off. Restate its cost/shape impact there (see the run-shape disclosure above).
133
- - Elements compose freely, with one exception: **critic seat + expert lenses together** means one bench member takes the critic brief and the *remaining* seats take lenses — never stack both briefs on one seat.
134
- - Briefing boilerplate for elements 1–4 lives in **`SEAT-BRIEFS.md`** next to this file — read it when any of them is toggled on.
135
-
136
- When Claude-in-the-council is off, Claude does not contribute a review and does not appear in the bundle. When on, see Stage 1 and §5.4.
137
-
138
- ---
139
-
140
- ### Stage 1 — Independent reviews
141
-
142
- Each council model reviews **the artifact** independently. Write one Stage-1 briefing file
143
- (`_tmp-briefing-stage1.md` in the run folder) and launch the whole wave as ONE background call:
144
-
145
- ```
146
- amicus fanout --models "<m1,m2,m3>" --prompt-file <run-folder>/_tmp-briefing-stage1.md --json \
147
- --agent Plan --no-context --summary-length verbose --timeout <minutes>
148
- ```
149
-
150
- Always quote the `--models` list — unquoted, PowerShell splits on commas and the CLI receives one mangled alias (instant arg-parse failure).
151
-
152
- Run it in the background (`run_in_background: true`); you are notified on completion — do not
153
- poll. `fanout` is headless by definition. The command exits when every leg is terminal and prints
154
- ONE JSON wave document on stdout (`schemaVersion: 2`; the wave's id field is `waveId`, each leg's id is `taskId`): check `status` (`complete` | `partial` |
155
- `error`), `counts`, and each leg in `legs[]` — a leg's `summary` field IS that model's review;
156
- `model`/`modelInput` identify the reviewer (`model` is the resolved id, `modelInput` the alias you passed — use the alias for `review-<model>.md` filenames); `status`/`error` identify failures. Exit code 0 =
157
- all legs complete, 2 = partial (apply the wave-degrade rules below), 1 = error/aborted. (To re-fetch a single leg later: `amicus read <taskId> --json`.)
158
-
159
- **Red-team variant:** fanout legs share a single prompt by design. When one model gets a distinct
160
- red-team brief, launch it as a separate concurrent solo run alongside the wave:
161
+ - **The launch confirmation must enumerate the enabled elements by name** — an element not named in the confirmation is off. Restate its cost/shape impact there.
162
+ - **Critic seat and expert lenses are mutually exclusive** the engine rejects both together, so pick one.
163
+ - Element *semantics* (what each brief actually asks for) live in **`SEAT-BRIEFS.md`** next to this file — read it when any of them is toggled on. The engine composes its own stricter-JSON variants of those templates; you do not paste them into `briefing.md`.
161
164
 
162
- ```
163
- amicus start --model <redteam-model> --no-ui --json \
164
- --prompt-file <run-folder>/_tmp-briefing-redteam.md \
165
- --agent Plan --no-context --summary-length verbose --timeout <minutes>
166
- ```
167
-
168
- Its stdout is a single run document; the `summary` field is the review.
169
-
170
- **Critic seat (optional element, when ON):** one bench member — recommended by Claude at Stage 0, typically a strong reasoner that is not the chair — receives the critic brief from `SEAT-BRIEFS.md § Critic seat brief` **instead of** the standard review brief. Launch it exactly like the red-team variant: a separate concurrent solo run (`_tmp-briefing-critic.md`) alongside the fanout wave of the remaining members — same total review count. Everything downstream is unchanged: same structured-output contract, same `council validate` + repair loop, same anonymization into the Stage-2 bundle (judges are never told a critic seat exists). Record `role: "critic"` on that seat's `runStats` entry. One standing disclosure for `report.md`: the critic model can recognize its own review in the Stage-2 bundle by its adversarial shape, so self-bias wash-out is weakened for that one seat.
171
-
172
- **Expert lenses (optional element, when ON):** every seat gets a distinct per-seat brief, so there is no shared-prompt wave — launch **all** legs as concurrent solo runs (`_tmp-briefing-lens-<slug>.md`, one per seat), using the lens templates and panel-scoping rules in `SEAT-BRIEFS.md § Expert lens briefs`. The lens↔model assignment is random and lives only in the private label map — no reviewer learns the other seats' lenses. Same structured-output contract and validation. Record `role: "lens:<slug>"` on each `runStats` entry. Two standing consequences, both disclosed in `report.md`: Stage-2 anonymity is weakened (each judge can spot its own lens-flavored review), and the Stage-2 tally runs `--no-ledger` (lens reviews are not comparable to standard reviews and must not feed cross-run reliability stats). Wave-degrade rules apply to these solos exactly as to fanout legs.
173
-
174
- **Cowork / no-Bash environments:** use the MCP tools instead — `amicus_fanout` (briefing via
175
- file) returns `{waveId, taskIds[]}` immediately. Preferred: call `amicus_wait` with the waveId —
176
- one blocking call per wave; re-call it while it returns `timedOut: true`. Fallback: poll
177
- `amicus_status`. Either way, `amicus_read` each leg when done. The council's briefings are always
178
- self-contained (`--no-context`), so MCP transport is equivalent.
179
- Council JSON returned by the MCP tools (`amicus_council_tally`, `amicus_council_stats`, `amicus_verdict`) arrives wrapped in the `<untrusted_sidecar_output>` fence since v4.0 — parse the JSON from inside the fence; CLI `--json` output remains unfenced.
180
-
181
- **Required structured output from every model.** Instruct each council model to produce:
182
-
183
- 1. A **prose review** — the reviewer's full narrative assessment of the artifact.
184
-
185
- 2. A **trailing fenced ` ```json ` block** immediately after the prose, containing:
186
- ```json
187
- {
188
- "overall": "one-paragraph take",
189
- "findings": [
190
- { "id": 1, "severity": "blocker",
191
- "claim": "…", "location": "…", "rationale": "…" }
192
- ]
193
- }
194
- ```
195
- - `id` — sequential integer within this review (`1..n`); at Stage-2 assembly Claude rewrites each into a **run-global label id** (`A1`, `B1`, …) by prefixing the review's anonymized label.
196
- - `severity ∈ {blocker, major, minor, nit}`
197
- - `claim`, `location`, `rationale` — non-empty strings.
198
-
199
- Instruct models to emit the structured JSON verbatim after the prose, without preamble, so it parses cleanly.
200
-
201
- **Every Stage-1 briefing — standard seats included — must contain the standard anti-sycophancy clause from `SEAT-BRIEFS.md` verbatim** (do not soften, lead with the most severe finding, no praise cushions, no padding — an empty severity category is a valid result). This is briefing hygiene, not an optional element.
165
+ **When "Claude in the council" is ON**, author `<run-folder>/review-claude.md` before launching: a
166
+ **fresh** structured Stage-1 review of the artifact — prose plus a trailing fenced ` ```json ` block
167
+ `{"overall": "…", "findings": [{"id": 1, "severity": "blocker", "claim": "…", "location": "…",
168
+ "rationale": "…"}]}` not a formalization of anything said upstream. The engine pre-flight-validates
169
+ this file and fails the run *before any spend* if it is malformed, so a bad file costs nothing but a
170
+ relaunch. See §5.4.
202
171
 
203
- Save each leg's full output (prose + findings block) to the run folder as `review-<model>.md`
204
- (one file per reviewer) before moving on.
172
+ **Disclose the run shape up front**, naming any enabled elements and their cost impact — e.g.:
205
173
 
206
- **After the wave returns, validate each leg's findings block** by running `amicus council validate <leg-file> --json` (a thin CLI wrapper over `validateFindings`, Unit A — `src/council/findings.js`). It reads the leg's saved `review-<model>.md` and prints `{ok, findings, errors}`. Exit codes are a **tri-state** contract: `0` when `ok:true` (well-formed, proceed), `2` when `ok:false` (validation failed — a distinct, scriptable outcome, not a crash), `1` (`BAD_ARGS`) for a missing/unreadable file. If a leg's JSON fails validation (`ok:false` / exit 2):
207
- 1. Issue a **solo `start --json`** re-prompt to that one model: "re-emit only the findings JSON, fixing: \<errors\>." Keep the first-pass prose. (Solo `start` passes through the **same budget gate** as `fanout`. If launching the wave required `--max-cost <$>` or `--no-cost-gate`, pass the **same flag on every repair re-prompt and on the chair call** — otherwise the gate can refuse a repair or the chair mid-council.)
208
- 2. If still malformed, retry **once more** (cap = **2** re-prompts total).
209
- 3. If still malformed after 2 retries, mark the review `unstructured` and hand-parse its prose into the schema. The review proceeds — never dropped for a formatting miss.
174
+ > This run uses 3 council models across 2 engine waves + 1 chair call (~7 model runs), ~10 min.
210
175
 
211
- Record per-model **conformance** (`clean` | `repaired` | `unstructured`) for inclusion in the tally input's `runStats` and the Stage-6 MODEL-NOTES note.
212
-
213
- **"Claude in the council" (when toggled on):** Claude also produces a **fresh** Stage-1 review on the artifact in the identical findings format — a new structured pass on the artifact, not a formalization of anything said upstream. This review is added to the bundle as one more anonymous entry. Claude does not rank or adjudicate in Stage 2 (it holds the label map), and does not chair in Stage 3. Save it as `review-claude.md`.
214
-
215
- **Wave-degrade rules (Stage 1).** Read failures from the wave document — never silently ignore
216
- them:
217
- - All legs `complete` → proceed normally.
218
- - A leg ends `error`/`timeout`/`crashed`/`aborted` but **≥ 2 reviews survive** → proceed with the
219
- survivors; name the dead leg and its `error` when presenting; the bench shrinks accordingly. If this leaves exactly 2 surviving reviews, the run is now effectively a 2-model council — apply the thin-ranking disclosure (Stage 0 / Stage 4) from here on.
220
- - **Fewer than 2 reviews survive** → offer the user a re-run of the dead leg(s) (solo
221
- `amicus start --json`, same briefing file) or a disclosed downgrade to single-pass mode
222
- (Stage 2 and Stage 3 skipped, per the scale-down rules).
223
-
224
- ---
225
-
226
- ### Stage 2 — Cross-review
227
-
228
- This is the peer-validation step. Claude builds one shared anonymized bundle, distributes it to every council model for ranking and finding adjudication, then de-anonymizes for scoring.
229
-
230
- **Build the shared anonymized bundle.** After all Stage-1 reviews are in hand, Claude:
231
- 1. Assigns stable labels: **Review A**, **Review B**, **Review C**, … (one per review, including Claude's if the toggle is on).
232
- 2. Keeps a **private label↔model map** (e.g., `Review A → deepseek`, `Review B → gemini`, `Review C → claude`) that is never sent to any sidecar model.
233
- 3. Assembles one bundle document containing all labeled reviews. The bundle is identical for every judge.
234
-
235
- Each model **unknowingly ranks and adjudicates its own review** — this is the anti-favoritism mechanism, not a bug. Because no model knows which review is its own, self-bias washes out symmetrically across judges.
236
-
237
- **Distribute the same bundle to every council model** — this is exactly fanout's shared-prompt
238
- model. Write the bundle + judging instructions to `_tmp-bundle-stage2.md` and launch one wave:
239
-
240
- ```
241
- amicus fanout --models "<m1,m2,m3>" --prompt-file <run-folder>/_tmp-bundle-stage2.md --json \
242
- --agent Plan --no-context --summary-length verbose --timeout <minutes>
243
- ```
244
-
245
- (Background, same JSON handling as Stage 1.) Each judge's leg `summary` is its ranking +
246
- adjudication response. **Stage-2 degrade:** a judge leg dies → tally over the surviving judges
247
- (≥ 1) and disclose the reduced bench in `crossreview-matrix.md`; tier definitions are unchanged
248
- (they already count "judges engaged").
249
-
250
- **Judge-briefing hardening (required).** Open `_tmp-bundle-stage2.md` with this preamble, verbatim, as its first line:
251
-
252
- > Do NOT use any tools or read any files; everything is in this message; begin immediately with A1:
253
-
254
- Plan-agent judges have wandered to tools mid-adjudication (reading files instead of judging and returning only narration), and a tool-capable judge can read the de-anonymized `review-<model>.md` files in the run folder — an anonymization leak. The preamble closes both. **Scratch-cwd (optional second layer):** launch the Stage-2 wave (and the Stage-3 chair call) with `--cwd <run-folder>/_scratch/` — create the empty directory first — so even a wandering agent finds nothing to read. Caveat: those legs' session records then live under `_scratch/.claude/amicus_sessions/`, so any later `amicus read <taskId>` for them needs the same `--cwd`.
255
-
256
- Each judge is asked to do two things on the bundle:
257
-
258
- **Task A — Rank.** Order the reviews from most to least accurate and insightful. End the response with a parseable block in exactly this format (no other text on those lines):
259
-
260
- ```
261
- FINAL RANKING:
262
- 1. Review C
263
- 2. Review A
264
- 3. Review B
265
- ```
266
-
267
- **Task B — Adjudicate findings.** For every finding in the bundle, state: `agree | dispute | neutral` plus one-line reason. Reference each finding as **review-label + finding-id** — for example, `A2` means Review A's 2nd finding, `B1` means Review B's 1st finding. An "I missed this — it's valid" counts as `agree`.
268
-
269
- **When critic seat or expert lenses are ON:** the bundle and judging instructions must not mention seats, lenses, or briefs — judges rank and adjudicate on accuracy and insight only. The element briefs are Stage-1 information; leaking them into Stage 2 tells every judge which review is which.
270
-
271
- As each judge's ranking + adjudication response returns, collect it (the raw per-judge responses are working intermediates, not separate run-folder artifacts). Once all are in, **assemble the de-anonymized tally input** and then call `amicus council tally`:
272
-
273
- **Stage-2 → tally assembly recipe (Claude's work before calling `tally`):**
274
- 0. **Build `meta` and `findings[]` first — `tally` requires both** (missing either fails with `BAD_ARGS: Cannot read properties of undefined (reading 'map')`):
275
- - `meta` = `{ "runId": "<run-folder stem>", "models": [<every reviewed model id, including "claude" when the toggle is on — this is the street-cred universe>], "chair": "<confirmed chair model id>", "claudeInCouncil": <Stage-0 toggle> }`. Optional extras: `runType`, `date`.
276
- - `findings[]` = one entry per finding across ALL reviews: `{ "id": "<run-global label id from step 1, e.g. A1>", "raiser": "<de-anonymized model that raised it>", "severity": "<from the review JSON>" }` (`claim` may be carried along but is not required).
277
- 1. **Rewrite finding ids to run-global label ids.** Each Stage-1 review's local integer ids (`1`, `2`, `3`…) become `A1`, `A2`, `A3`… (where `A` is that review's anonymized label). The label↔model map (`Review A → deepseek`, etc.) is the key.
278
- 2. **Build `adjudications`** — for every judge across all findings: `findingId` = run-global label id; `judge` = the model id (de-anonymized via the map); `verdict ∈ {agree, dispute, neutral}`. Include every judge's verdict on every finding. The raiser's own adjudication of its own finding is **included in the input** (the tally engine excludes it when computing peers-only tiers — do not pre-filter it).
279
- 3. **Translate each judge's `FINAL RANKING:` block** — convert the label order (`1. Review C / 2. Review A / 3. Review B`) into a model `order` array via the same map (e.g. `{C→mistral, A→deepseek, B→gpt}` ⇒ `order: ["mistral","deepseek","gpt"]`). This is each entry in `rankings[]`.
280
- 4. **Populate `runStats`** from the per-leg run documents emitted by `fanout --json` (and any solo red-team/chair `start --json` docs): copy `model`, `status`, `durationMs`, `usage` verbatim. Any leg with no run doc gets `durationMs: null` and `usage: null` — never invent a value. Attach `role` (`council` | `redteam` | `claude`), `wasChair`, and `conformance` (`clean` | `repaired` | `unstructured`) as council-domain labels.
281
-
282
- **Five-keys checklist — verify `tally-input.json` has ALL of:** `meta` (with `meta.models`), `findings`, `adjudications`, `rankings`, `runStats` (`runStats` may be `[]`; the other four are required). Do not call `tally` until all five are present.
283
-
284
- Then call, saving the printed `record` to `<run-folder>/tally.json` (Stage 5's `amicus council verdict` reads it back from disk):
285
-
286
- ```
287
- amicus council tally <run-folder>/tally-input.json --json > <run-folder>/tally.json
288
- ```
289
-
290
- **Ledger flags for optional elements:** when **expert lenses** are ON, always pass `--no-ledger` — lens runs never feed cross-run reliability stats. When **debate mode** is ON, this Stage-2 tally is *provisional* — pass `--no-ledger` here; the final, ledger-recorded tally happens at the end of Stage 2.5 (the critic seat and Claude-in-the-council change nothing about ledger handling).
291
-
292
- **Windows PowerShell 5.1 caveat:** that `>` redirect writes UTF-16 under legacy Windows PowerShell 5.1 (fine on pwsh 7+ or bash), which corrupts `tally.json` for Stage 5's `amicus council verdict` and surfaces as a confusing `BAD_ARGS` there instead of here — on 5.1 pipe through `| Out-File -Encoding utf8` (or run under pwsh 7+) instead of a bare `>`.
293
-
294
- The output `record` carries the deterministic tiers (Disputed / Confirmed / Contested / Singleton), `confidence` (`solid` | `thin`), both street-cred numbers (`withSelf` and `peersOnly`), the validated `runStats`, and `tierCounts`. **Claude may override a `thin`-confidence tier at the margins** before Stage 4 — record the override in `tierOverride: {from, to, reason}`; the matrix and `verdict.json` surface it. De-anonymize and write the tally results to `crossreview-matrix.md` — the adjudication grid plus the street-cred table. This data feeds Stage 3 (chair briefing) and is never re-anonymized or forwarded to any council model.
295
-
296
- ---
297
-
298
- ### Stage 2.5 — Rebuttal round ("debate mode", optional element — skip this entire stage when OFF)
299
-
300
- One structured challenge round on the findings the bench did not settle: every **Contested** and **Disputed** finding goes back to its raiser to defend, amend, or withdraw; the judges that disputed it re-vote; then the final tally. **Exactly ONE round, ever** — never iterate further; whatever remains unsettled after the re-vote keeps its final tier. Briefing templates are in `SEAT-BRIEFS.md § Rebuttal-round templates`; every rebuttal briefing opens with the no-tools preamble, same as Stage 2.
301
-
302
- The Stage-2 tally above ran `--no-ledger` (provisional). If it produced **zero Contested + Disputed findings**, skip the rebuttal waves entirely: re-run the tally on the unchanged input *without* `--no-ledger` to record it, note "debate mode: nothing to debate" for `report.md`, and proceed to Stage 3.
303
-
304
- **1. Defense mini-wave.** For each raiser with ≥ 1 Contested/Disputed finding, write `_tmp-rebuttal-<label>.md`: its findings (run-global ids and claims), each with the peers' dispute reasons — anonymized, no judge identities. Launch one concurrent solo run per raiser (same flags and budget-gate handling as the Stage-1 solos). Parse each response line: `<id>: DEFEND — …` | `<id>: AMEND — <replacement claim>` | `<id>: WITHDRAW`. A missing or unparseable line = the original claim stands undefended (original verdicts carry).
305
-
306
- **2. Re-vote mini-wave.** Build ONE shared `_tmp-revote-bundle.md` holding every defended or amended finding plus its (anonymous) defense. Send it as a single fanout wave to the judges that disputed at least one of those findings — judges that never disputed sit this round out. Parse verdict lines `<id>: agree | dispute | neutral — <reason>`; a judge's missing line = its original verdict stands.
176
+ or, with elements enabled:
307
177
 
308
- **3. Final tally.** Re-assemble the tally input: re-vote verdicts replace those judges' original adjudications on those findings; AMENDED claims replace the originals (`id`, `raiser`, and `severity` unchanged); WITHDRAWN findings **stay in `findings[]`** (they were raised) and take whatever tier the final cascade assigns. Run `amicus council tally` **without** `--no-ledger` (unless expert lenses are also ON lens runs never ledger) and save this record as the run's `tally.json`. This final record — not the provisional one — is what Stages 3–5 consume; the chair packet and `crossreview-matrix.md` are built from it, with verdict changes from the re-vote called out before/after.
178
+ > This run uses 3 council models across 2 engine waves + 1 chair call, with **critic seat + debate mode ON** (~7 base runs + up to 6 rebuttal calls), ~15 min.
309
179
 
310
- **Withdrawals downstream:** WITHDRAWN findings are auto-recorded in `decisions.json` as `{"id": …, "decision": "denied"}` — never presented for a user decision in Stage 4 — and listed in `report.md` under "Withdrawn by raiser (debate mode)".
180
+ Then **wait for confirmation**. Never launch without it.
311
181
 
312
- **Degrade rules:** a dead defense leg → all of that raiser's contested findings stand undefended. A dead re-vote leg that judge's original verdicts carry. Never re-run the round.
182
+ **Scale-down is explicit state which mode applies:**
183
+ - **1 model** → thorough single pass; cross-review and chair synthesis do not apply and Claude synthesizes directly. This is the one path that never touches the engine: a single solo `amicus start --no-ui --json --prompt-file <run-folder>/briefing.md --agent Plan --no-context --summary-length verbose`.
184
+ - **2 models** → a valid engine run, but the ranking is thin (one ranker per review); note this limitation.
185
+ - **3 models (default)** → full deep council with meaningful cross-review and tie-breaking.
313
186
 
314
- **Cost/shape:** adds up to 2 short waves (≤ N defense solos + 1 re-vote fanout), disclosed at Stage 0. If the actual rebuttal surface turns out much larger than estimated (many contested findings), say so before launching the mini-waves.
187
+ The scale-down levels count **non-Claude judges**; `--claude-review` adds a judged review but not a judge, so it does not change these levels.
315
188
 
316
189
  ---
317
190
 
318
- ### Stage 3Council-chair synthesis
319
-
320
- A designated **non-Claude** chair synthesizes the verdict across all reviews, rankings, and adjudications. The chair produces an independent verdict that Claude then presents — Claude does not paraphrase, edit, or re-synthesize it.
191
+ ### The engine run Stages 1–3 plus the Stage-5 artifacts
321
192
 
322
- **Chair selection (confirmed in Stage 0).** Default: Claude recommends the strongest reasoner in the council (guided by `amicus council stats` (peers-only street-cred) and the qualitative quirks in `MODEL-NOTES.md`) and the user confirms before the run launches. The chair may be a council member who already participated in Stages 1 and 2 — it receives the de-anonymized full bundle, all ranking outputs, and all adjudications so it has the complete picture.
193
+ ONE call. The engine executes the Stage-1 review wave, the per-leg findings validation and bounded
194
+ repair loop, anonymization and run-global finding-id rewriting, the identical judge bundle and
195
+ cross-review wave, the optional rebuttal round, the tally (which appends the reliability ledger
196
+ **once**), the chair synthesis with the verdict scale, and the deterministic
197
+ `verdict.json` + `report.html` — checkpointing `run.json` as it goes.
323
198
 
324
- **Fallback order if the chair fails:**
325
- 1. Re-run the chair call (transient failure — `MODEL-NOTES.md` mitigations apply).
326
- 2. Promote the next-best non-Claude council model as chair.
327
- 3. **Claude chairs only as last resort — with explicit disclosure** that the verdict is no longer fully independent of the orchestrator.
328
-
329
- **Chair briefing.** Write the chair packet to `_tmp-chair-packet.md` and send one solo run
330
- (background):
199
+ **Canonical launch (shell contexts):**
331
200
 
332
201
  ```
333
- amicus start --model <chair> --no-ui --json \
334
- --prompt-file <run-folder>/_tmp-chair-packet.md \
335
- --agent Plan --no-context --summary-length verbose --timeout <minutes>
202
+ amicus council run --prompt-file <run-folder>/briefing.md \
203
+ --models "<m1,m2,m3>" --chair <chair> --out-dir <run-folder> --json \
204
+ [--critic <m>] [--lenses s1,s2,s3] [--debate] \
205
+ [--claude-review <run-folder>/review-claude.md] \
206
+ [--max-cost <$> | --no-cost-gate] [--timeout <min>] [--gateway auto|direct|openrouter]
336
207
  ```
337
208
 
338
- (The budget gate applies to this solo call too if Stage 0 needed `--max-cost <$>` or `--no-cost-gate` to launch the wave, the chair call needs the same flag.)
339
-
340
- The run document's `summary` is the verdict. The packet contains:
341
- - All Stage-1 reviews (de-anonymized model attribution restored)
342
- - All cross-review ranking outputs (with model attribution)
343
- - All adjudication outputs (with model attribution and `agree | dispute | neutral` verdicts per finding)
344
-
345
- Open `_tmp-chair-packet.md` with the no-tools preamble, adjusted for the chair: *'Do NOT use any tools or read any files; everything is in this message; begin immediately with the verdict.'* The packet is complete by construction — the chair must never go looking for files.
346
-
347
- Instruct the chair to write a **synthesized verdict** that:
348
- - Weighs each reviewer's findings by their peer-validated standing (street-cred rank and adjudication pattern)
349
- - Distinguishes findings the bench broadly endorsed from contested or singleton claims
350
- - Arrives at an overall assessment of the artifact
351
-
352
- **Chair verdict scale (optional element, when ON):** append the addendum from `SEAT-BRIEFS.md § Chair verdict-scale addendum` to the chair packet — the chair must close with 3–5 **hard questions** the artifact's author probably hasn't asked themselves, then a final parseable line: `VERDICT: Ship it | Fix these first | Fundamental rethink`. Surface that line verbatim at the top of `report.md` and in the inline chat presentation. When debate mode is also ON, the chair packet is built from the *final* (post-rebuttal) tally and includes the defense/re-vote outcomes.
353
-
354
- Save the chair's output to the run folder as `verdict.md`.
209
+ Always quote the `--models` listunquoted, PowerShell splits on commas and the CLI receives one
210
+ mangled alias (instant arg-parse failure). For a free council, swap `--models "<m1,m2,m3>"` for
211
+ `--council free`. Run it in the background (`run_in_background: true`); you are notified on
212
+ completiondo not poll.
213
+
214
+ **Budget gate one flag for the whole run.** By default the gate refuses any leg whose price
215
+ exceeds the per-$/Mtok threshold (the o3/o3-pro guard). To run an intentionally expensive model the
216
+ user asked for by name, pass `--no-cost-gate`; to raise only the total ceiling, pass
217
+ `--max-cost <$>`. Either flag is forwarded to **every internal launch** the engine makes — the
218
+ Stage-1 wave, the repair re-prompts, the Stage-2 judge wave, the debate legs, and the chair call —
219
+ so a single invocation replaces the old per-call pass-through footgun entirely.
220
+
221
+ **Cowork / no-Bash environments:** use the MCP tools instead. `amicus_council_run`
222
+ `{briefingFile, models|council, chair, critic?, lenses?, debate?, claudeReviewFile?, outDir,
223
+ maxCost?|noCostGate?, timeoutMinutes?, gateway?}` returns `{runId, runDir}` immediately.
224
+ Preferred: call `amicus_wait` with the runId — one blocking call; re-call it while it returns
225
+ `timedOut: true`. Fallback: poll `amicus_status`, which shows stage progression. Then read the
226
+ run-folder artifacts with the host's file tools. Council JSON returned by the MCP tools arrives
227
+ wrapped in the `<untrusted_sidecar_output>` fence — parse the JSON from inside the fence; CLI
228
+ `--json` output remains unfenced. The council's briefings are always self-contained, so MCP
229
+ transport is equivalent.
230
+
231
+ **When the run returns, read `run.json` and the exit code — never present a degraded run as
232
+ clean.** The engine owns degradation; you own disclosure and the user's choice:
233
+
234
+ - **0 — full run.** Proceed to Stage 4.
235
+ - **2 — degraded but usable.** Read `run.json` `stages[]` (which leg or stage died, and its error),
236
+ `tally.json` (the `judged` flag), and `verdict.json` (`overallVerdict` is null when the chair
237
+ never produced one). Name every dead leg and its error when presenting. Apply the standing
238
+ disclosures: a run left with 2 surviving reviews is effectively a 2-model council (thin ranking —
239
+ say so from here on); a failed chair means the report carries no chair verdict, so offer a solo
240
+ re-chair via `MANUAL-ORCHESTRATION.md` or proceed report-only; debate degradations are summarized
241
+ in `run.json`'s `debate` block. Then proceed to Stage 4 with what exists.
242
+ - **1 — nothing usable.** Quorum, cost ceiling, or validation failed and the error doc says which.
243
+ Present it and offer: re-run (possibly with a smaller bench), a raised `--max-cost`, or the
244
+ manual/single-pass fallback.
245
+ - **130 / 143 — aborted** (Ctrl-C or terminated). Offer a resume-as-a-new-run; the partial run
246
+ folder stays on disk for inspection.
247
+
248
+ **If the engine itself is the thing misbehaving** — or you need a fully custom per-seat brief
249
+ beyond `--critic`/`--lenses`, or deliberate mid-stage inspection — switch to
250
+ **`MANUAL-ORCHESTRATION.md`** and tell the user you are doing so.
355
251
 
356
252
  ---
357
253
 
358
254
  ### Stage 4 — Tiered decisions (peer-validated)
359
255
 
360
- All findings from the bundle are sorted into tiers based on the **peer-confidence tier assigned by `amicus council tally`** (see *Key mechanics → §5.2 Scoring* in COUNCIL-DESIGN.md for the full cascade): **Disputed** (strong peer pushback — `d ≥ 2` and `d > a`), **Confirmed** (≥ 2 peer agreements, agrees dominate), **Contested** (at least one live dispute), **Singleton** (at most one endorsement, no pushback). `confidence: thin` cells `(0,0)/(1,0)/(0,1)` are override-eligible (Claude records any override in `tierOverride`). Present the tiers in this order: Confirmed first (bulk decision), then Disputed and Contested and Singleton individually in the judgment tier.
361
-
362
- **Scale-down:** In a 1-model run, Stage 2 was skipped — there is no peer-confidence data, so present every finding individually for decision (no tiers). In a 2-model run, the Confirmed tier rests on thin cross-review (one ranker per review, per Stage 0) — say so when presenting it.
363
-
364
- **Debate mode:** the tiers below come from the *final* (post-rebuttal) tally. Findings WITHDRAWN by their raiser in Stage 2.5 are already recorded as `denied` do not present them for decision; note them as withdrawn when walking the tiers.
256
+ Read **two** run-folder artifacts and join them on each finding's `id` (the run-global label,
257
+ e.g. `A1`): `tally.json` for the tier, the `basis` counts, the `adjudications` and any `debate`
258
+ decoration, and `tally-input.json` for the `claim` and `location` text. The claim lives **only**
259
+ in `tally-input.json` — `tally.json` findings carry `id, raiser, severity, tier, basis,
260
+ confidence, tierOverride, adjudications` and no claimso every "show the claim" instruction
261
+ below needs both sides of the join.
262
+
263
+ Every finding already carries the **peer-confidence tier** the
264
+ engine's tally computed (see *Key mechanics → §5.2 Scoring*, and COUNCIL-DESIGN.md for the full
265
+ cascade): **Disputed** (strong peer pushback — `d ≥ 2` and `d > a`), **Confirmed** (≥ 2 peer
266
+ agreements, agrees dominate), **Contested** (at least one live dispute), **Singleton** (at most one
267
+ endorsement, no pushback). `confidence: thin` cells `(0,0)/(1,0)/(0,1)` are override-eligible —
268
+ record any override in `tierOverride: {from, to, reason}` on that finding's decision entry. Present
269
+ the tiers in this order: Confirmed first (bulk decision), then Disputed and Contested and Singleton
270
+ individually in the judgment tier.
271
+
272
+ **Scale-down:** In a 1-model run there is no peer-confidence data, so present every finding individually for decision (no tiers). In a 2-model run the Confirmed tier rests on thin cross-review (one ranker per review, per Stage 0) — say so when presenting it.
273
+
274
+ **Debate mode:** the tiers come from the *final* (post-rebuttal) tally. A finding whose raiser
275
+ withdrew it in the rebuttal round (`findings[].debate.action === 'withdrawn'` in `tally.json`) is
276
+ **auto-recorded `denied` in `decisions.json` and never presented for a user decision** — just note
277
+ it as withdrawn when walking the tiers.
365
278
 
366
279
  **Consensus tier — Confirmed findings** (≥ 2 peer agreements, agrees dominate)
367
280
 
@@ -380,9 +293,15 @@ This is one tier with three sub-types presented separately. Present each finding
380
293
  - **Contested** (`d ≥ 1` with a meaningful split): For each finding show the claim and severity, which model raised it, who agreed, who disputed, and the one-line reasons from the adjudications. Ask for a decision before proceeding to the next: **accept / deny / modify**.
381
294
  - **Singleton** (only the original raiser; all other judges were neutral or silent — `d = 0` and `a < 2`): For each finding show the claim and severity and that no other judge engaged with it. Name the sole raiser. Ask for a decision before proceeding to the next: **accept / deny / modify**.
382
295
 
383
- **Recording decisions.** Keep a running decision log throughout this stage — every finding's outcome (accepted / denied / modified, with any modification noted). This log feeds Stage 5 (only accepted changes go into the reviewed copy) and Stage 6 (the run-folder report).
296
+ **Recording decisions.** Keep a running decision log throughout this stage — every finding's
297
+ outcome (accepted / denied / modified, with any modification noted) — and write it to
298
+ `<run-folder>/decisions.json` as a **JSON array**, one object per finding:
299
+ `{id, decision, applied?, duplicateOf?, tierOverride?}`. `id` is the run-global label id (e.g. `A1`);
300
+ `decision` is the Stage-4 outcome (accepted / denied / modified / deferred); `applied` (optional
301
+ bool) marks whether the accepted change was actually applied in Stage 5; `duplicateOf` (optional)
302
+ links to another finding's id; `tierOverride` (optional) carries any `{from, to, reason}` override.
384
303
 
385
- Do not advance to Stage 5 until every finding in both tiers has a recorded decision.
304
+ Do not advance to Stage 5 until every finding has a recorded decision.
386
305
 
387
306
  ---
388
307
 
@@ -397,35 +316,68 @@ Do not advance to Stage 5 until every finding in both tiers has a recorded decis
397
316
  - Do not attempt to produce a modified copy.
398
317
  - Write a **standalone reviewed report** instead: the full decision log, the chair's verdict, and clear callouts of what should be changed and where — formatted so the user can apply the changes manually.
399
318
 
400
- **Run-folder artifacts always write these** regardless of source type. The full artifact set and naming conventions are defined in the *Output & naming* section of this skill; write every artifact specified there. The canonical run-folder files are:
401
- - `review-<model>.md` × N (already saved in Stage 1)
402
- - `crossreview-matrix.md` — the de-anonymized adjudication grid and street-cred table
403
- - `verdict.md` (already saved in Stage 3)
404
- - `verdict.json` — write by running `amicus council verdict <run-folder>/tally.json --decisions <run-folder>/decisions.json -o <run-folder>/verdict.json` (a thin CLI wrapper over `buildVerdict(record, decisions)` + `writeVerdictAtomic`, `src/council/verdict.js`). `<run-folder>/tally.json` is the `record` saved from the Stage-2 `amicus council tally` call. `<run-folder>/decisions.json` is a **JSON array**, one object per finding: `{id, decision, applied?, duplicateOf?, tierOverride?}` — `id` is the run-global label id (e.g. `A1`); `decision` is the Stage-4 outcome (accepted / denied / modified / deferred); `applied` (optional bool) marks whether the accepted change was actually applied to the artifact in Stage 5; `duplicateOf` (optional) links to another finding's id when Claude identified a duplicate; `tierOverride` (optional) carries any `{from, to, reason}` override recorded in Stage 2. Save this array to `<run-folder>/decisions.json` first, then run the command — it parses the tally record and the decisions file, calls `buildVerdict`, and writes the schema-stamped machine-readable record to the run folder via the same atomic tmp+rename convention the function always used.
405
- - `report.md` — the chair's synthesis + the full Stage-4 decision log + a summary of what was
406
- applied (+ the "How Claude's review fared" readout when "Claude in the council" is on) + an
407
- **Optional elements** section whenever any element was ON: which elements ran; the chair's
408
- `VERDICT:` line verbatim at the top of the report (chair verdict scale); the "Withdrawn by
409
- raiser (debate mode)" list and re-vote verdict changes (debate mode); and the standing
410
- disclosures — critic self-identification in cross-review (critic seat), weakened anonymity +
411
- non-comparable street-cred + `--no-ledger` (expert lenses) + a
412
- **run-stats table**: one row per model call **stage** (which stage you launched the call for)
413
- plus **model, status, durationMs, and cost** read from the wave/run JSON `usage`
414
- block. Cost is `usage.cost.amount` (USD); mark it with its `usage.cost.source`
415
- exact for `reported`, `~` for `estimated`, `?` for `unknown` and never
416
- invent a figure. Add a wave **total cost** row from the wave document's
417
- `usage.cost` (`source: reported|estimated|mixed|unknown`). Any leg with no run doc → `durationMs: null`, `usage: null`; never invent a value.
418
- - **Renderer:** once `verdict.json` is written, run
419
- `amicus council report <run-folder>/verdict.json --html > <run-folder>/report.html` — a
420
- **separate, deterministic** artifact, not report.md itself. **`report.html` is the default
421
- final artifact to hand the user** a self-contained, shareable page. This emits the
422
- adjudication matrix (finding × judge), the peers-only street-cred table, the
423
- findings-by-tier groupings (Disputed-first), and the per-model + wave cost
424
- deterministic data only. To assemble report.md, also run
425
- `amicus council report <run-folder>/verdict.json --md` (no redirect read its stdout) and
426
- paste that Markdown into report.md as one section; reserve the rest of report.md's prose for
427
- the chair's synthesis and the decision log. Prefer the renderer's Markdown over
428
- hand-assembling the matrix by hand.
319
+ **Run-folder artifacts.** The engine already wrote the deterministic set (see *Output & naming*).
320
+ Two artifacts are yours:
321
+
322
+ - `verdict.json` the engine wrote an **undecided** verdict; replace it with the decided one:
323
+
324
+ ```
325
+ amicus council verdict <run-folder>/tally.json --decisions <run-folder>/decisions.json -o <run-folder>/verdict.json --render
326
+ ```
327
+
328
+ a thin CLI wrapper over `buildVerdict(record, decisions)` + `writeVerdictAtomic`
329
+ (`src/council/verdict.js`). `<run-folder>/tally.json` is the record the engine's tally wrote;
330
+ `<run-folder>/decisions.json` is the Stage-4 array. It parses both, calls `buildVerdict`, and
331
+ writes the schema-stamped machine-readable record via the same atomic tmp+rename convention the
332
+ function always used. The chair's `overallVerdict` is **carried forward automatically** from the
333
+ run folder the engine's `verdict.json` first, else the closing `VERDICT:` line of
334
+ `chair-output.md` because those are its only two homes (`tally.json` and `run.json` carry no
335
+ copy) and this command overwrites the first of them. A chair that produced no verdict stays
336
+ `null`; nothing is ever invented.
337
+
338
+ `--render` then refreshes `report.html` from the decided verdict without
339
+ it you would hand the user a stale, pre-decision page. In Cowork this is **two `amicus_verdict`
340
+ calls, not one** (the tool is pure/stateless and writes nothing unless `render: true` *and*
341
+ `outDir` are both given): first call it with `record` (parsed `tally.json`) and `decisions`
342
+ (parsed `decisions.json`) and `overallVerdict` read that last one from the engine's
343
+ `<run-folder>/verdict.json` before you overwrite it (`null` when the chair produced none); the
344
+ MCP tool receives `record` inline and has no run folder to recover it from, so unlike the CLI it
345
+ cannot carry it forward for you. With `render` omitted it returns the decided verdict as fenced JSON;
346
+ write that JSON to `<run-folder>/verdict.json` yourself with the host's file tools, since the
347
+ tool does not persist it. Then call it again with the same `record`/`decisions`/`overallVerdict` plus
348
+ `render: true` and `outDir: <run-folder>` — this refreshes `<outDir>/report.html` on disk and
349
+ returns the Markdown rendering for `report.md` below; it still does **not** write `verdict.json`.
350
+ - `report.md` — Claude-authored: the chair's synthesis (read verbatim from
351
+ `<run-folder>/chair-output.md`, including its closing `VERDICT:` line at the top of the report) +
352
+ the full Stage-4 decision log (one row per finding: `id` + claim + decision — the claim text
353
+ comes from `tally-input.json`, joined on `id` exactly as in Stage 4, since `decisions.json`
354
+ and `tally.json` both carry only the id) + a summary of what was applied (+ the "How Claude's
355
+ review fared"
356
+ readout when "Claude in the council" is on) + an **Optional elements** section whenever any
357
+ element was ON: which elements ran; the "Withdrawn by raiser (debate mode)" list and re-vote
358
+ verdict changes; and the standing disclosures — critic self-identification in cross-review
359
+ (critic seat), weakened anonymity + non-comparable street-cred + no ledger entry (expert
360
+ lenses) + a **run-stats table**: one row per model call — **stage**, **model, status,
361
+ durationMs, and cost** read from `run.json` / `tally.json` `runStats`. Cost is
362
+ `usage.cost.amount` (USD); mark it with its `usage.cost.source` — exact for `reported`, `~` for
363
+ `estimated`, `?` for `unknown` — and never invent a figure. Add a **total cost** row from
364
+ `run.json`'s `usage.cost`. Any entry with no run doc → `durationMs: null`, `usage: null`; never
365
+ invent a value.
366
+ - **Renderer:** the `--render` flag above already refreshed `<run-folder>/report.html` from the
367
+ decided verdict — a **separate, deterministic** artifact, not report.md itself (explicit
368
+ equivalent: `amicus council report <run-folder>/verdict.json --html > <run-folder>/report.html`).
369
+ To assemble report.md, also run `amicus council report <run-folder>/verdict.json --md`
370
+ (no redirect — read its stdout) and paste that Markdown into report.md as one section; reserve
371
+ the rest of report.md's prose for the chair's synthesis and the decision log. Prefer the
372
+ renderer's Markdown over hand-assembling the matrix by hand. **`report.html` is the default
373
+ final artifact to hand the user** — a self-contained, shareable page carrying the adjudication
374
+ matrix (finding × judge), the peers-only street-cred table, the findings-by-tier groupings
375
+ (Disputed-first), the debate round when `--debate` was on, and the per-model + total cost.
376
+
377
+ The fast path retires the manual path's two hand-written artifacts: there is no
378
+ `crossreview-matrix.md` (the adjudication grid and street-cred table are rendered into
379
+ `report.html`/`report.md`) and no `verdict.md` (the chair's prose is `chair-output.md`, written by
380
+ the engine). Do not recreate them — `MANUAL-ORCHESTRATION.md` is where they still live.
429
381
 
430
382
  Tell the user exactly which files were written and where, leading with `report.html`, **and present the verdict inline in chat** — the chair's overall assessment (verbatim or lightly trimmed) plus the tier counts (Confirmed/Disputed/Contested/Singleton) and what was applied. Never hand over only file paths.
431
383
 
@@ -438,13 +390,21 @@ This stage updates `MODEL-NOTES.md` to make future runs better. **Nothing is wri
438
390
  The `MODEL-NOTES.md` **next to this file** is your machine-local run ledger: npm updates never overwrite it (it is installed only if missing), so lessons accumulate per machine. Durable, machine-independent lessons get folded back into the version-controlled copy in the amicus repo at release time (see the release checklist in `docs/publishing.md`).
439
391
 
440
392
  **Reflect on this run.** Review the run for:
441
- - Failures, near-misses, and mitigations that worked (poller traps, empty responses, timeout issues, briefing problems)
442
- - Briefing wording that produced **richer or poorer** structured output than expected
393
+ - Failures, near-misses, and mitigations that worked (dead legs, empty responses, timeouts, briefing problems — all visible in `run.json`)
394
+ - Briefing wording that produced **richer or poorer** structured output than expected; per-model `conformance` (`clean` | `repaired` | `unstructured`) is in `run.json` / `tally.json` `runStats`
443
395
  - Chair or council model behavior worth noting
444
396
 
445
397
  Draft new or updated entries for the per-model sections of `MODEL-NOTES.md` that capture what was learned.
446
398
 
447
- **Ledger auto-append (automatic no approval required).** Running `amicus council tally` (the finalize call — Stage 2, or the Stage-2.5 final tally when debate mode is on; skipped entirely on expert-lens runs, which always pass `--no-ledger`) appends one row per (run × model) to the append-only `council-ledger.jsonl` under `getConfigDir()` — no separate step is needed. Pass `--no-ledger` to compute a tally record *without* recording it (e.g. a re-tally that shouldn't double-count). The run summary shows the appended row. This is a deterministic, content-free model-level record (no finding text, no claim strings, no artifact body content). The quantitative reviewer-reliability data in `MODEL-NOTES.md` is now sourced entirely from `amicus council stats` (which aggregates the ledger) — **do not hand-edit reliability numbers in MODEL-NOTES**.
399
+ **Ledger — already appended; do not touch it.** The engine's finalize tally appended one row per
400
+ (run × model) to the append-only `council-ledger.jsonl` under `getConfigDir()` as part of the run
401
+ (expert-lens runs are deliberately excluded). **In the fast path, never run `council tally`
402
+ yourself.** The ledger is append-only, so a second tally over the same run double-appends and
403
+ permanently skews every model's lifetime reliability averages — a double-append cannot be undone.
404
+ Everything you would have wanted from it (tiers, both street-cred numbers, `runStats`,
405
+ `tierCounts`) is already in `<run-folder>/tally.json`. The quantitative reviewer-reliability data
406
+ in `MODEL-NOTES.md` is sourced entirely from `amicus council stats` (which aggregates the ledger) —
407
+ **do not hand-edit reliability numbers in MODEL-NOTES**.
448
408
 
449
409
  **Compose the proposed MODEL-NOTES diff.** Combine the run-lessons updates and the reviewer-reliability table updates into a single proposed diff (old → new for every changed section). **Write the full diff to a file in the run folder** — `_tmp-proposed-model-notes-update.md` — so the user can open and review it before deciding. Presenting the diff as chat text alone is **not sufficient**: an approval dialog can hide the chat transcript, so the user may be asked to decide on a diff they never saw.
450
410
 
@@ -462,59 +422,81 @@ If the user approves, write the changes. If they say "edit", incorporate their c
462
422
 
463
423
  ### §5.1 Anonymization
464
424
 
465
- Stage 2 distributes a single anonymized bundle; this section details the mechanics that make that safe and fair.
466
-
467
- After all Stage-1 reviews are in hand, Claude assembles **one shared bundle** — every review relabeled with stable letter identifiers: **Review A**, **Review B**, **Review C**, and so on. Claude keeps a **private label↔model map** (e.g., `Review A deepseek`, `Review B → gemini`, `Review C → claude`) that is never shared with any sidecar model.
425
+ The engine assembles **one shared bundle** every review relabeled with stable letter identifiers:
426
+ **Review A**, **Review B**, **Review C**, and so on — and keeps the label↔model map in orchestrator
427
+ memory and `run.json`, never in any judge-visible file. The judge legs run in a `_scratch/`
428
+ subdirectory of the run folder precisely so a wandering judge cannot read the de-anonymized
429
+ `review-<model>.md` files sitting next to it.
468
430
 
469
431
  The **identical** bundle goes to every judge. Because no judge can tell which review is its own, each model unknowingly ranks and adjudicates its own review — this is the anti-favoritism mechanism, not a bug. Self-bias washes out symmetrically across judges rather than systematically inflating any one model.
470
432
 
471
- Claude **de-anonymizes only** at two points: when computing scores and when writing `crossreview-matrix.md` and `report.md`. The label↔model map is never re-forwarded to any council model after de-anonymization.
433
+ De-anonymization happens only when scoring and when rendering `report.html` / `report.md`. The map is never forwarded to any council model.
472
434
 
473
- **When "Claude in the council" is on:** Claude's own Stage-1 review enters the **same** bundle alongside the other reviews. Claude holds the label map and therefore cannot judge blind; see §5.4 for how this asymmetry is handled. Claude **never ranks or adjudicates** in Stage 2.
435
+ **When "Claude in the council" is on:** the `review-claude.md` you authored enters the **same**
436
+ bundle as one more labeled entry. Claude never judges (no judge leg is launched for it) and never
437
+ chairs; see §5.4.
474
438
 
475
439
  ---
476
440
 
477
441
  ### §5.2 Scoring
478
442
 
479
- `amicus council tally` computes the two scoring signals from the assembled tally input. Claude's role is to assemble the input (Stage-2 assembly recipe in Stage 2 above) and to exercise judgment on `thin`-confidence overrides.
443
+ The engine's tally stage computes the two scoring signals and writes them to
444
+ `<run-folder>/tally.json`. Claude's job is to read them and to exercise judgment on
445
+ `thin`-confidence overrides.
480
446
 
481
447
  **Street-cred** — computed two ways:
482
448
  - **withSelf** = each model's mean rank position across **all** judges' `FINAL RANKING:` blocks (lower is better).
483
449
  - **peersOnly** = mean rank excluding the model's own ranking of itself.
484
450
 
485
- Both are surfaced in `crossreview-matrix.md` and `report.md`. The ledger and Stage-0 bench recommendations use **peersOnly** only.
451
+ Both are surfaced in `report.html` and `report.md`. The ledger and Stage-0 bench recommendations use **peersOnly** only.
486
452
 
487
- **Per-finding peer-confidence tier** — assigned by the peers-only cascade in `amicus council tally` (see COUNCIL-DESIGN.md §5.2 for the full table): **Disputed** → **Confirmed** → **Contested** → **Singleton**. The raiser's own adjudication is excluded from the cascade. `confidence: thin` when total engaged peers `a + d ≤ 1` — cells `(0,0)`, `(1,0)`, `(0,1)`. **Claude may override a `thin` tier at the margins** before presenting Stage 4 — the override is recorded in `tierOverride: {from, to, reason}` and surfaced in the matrix and `verdict.json`.
453
+ **Per-finding peer-confidence tier** — assigned by the peers-only cascade (see COUNCIL-DESIGN.md §5.2 for the full table): **Disputed** → **Confirmed** → **Contested** → **Singleton**. The raiser's own adjudication is excluded from the cascade. `confidence: thin` when total engaged peers `a + d ≤ 1` — cells `(0,0)`, `(1,0)`, `(0,1)`. **Claude may override a `thin` tier at the margins** before presenting Stage 4 — the override is recorded in `tierOverride: {from, to, reason}` and surfaced in `verdict.json`.
488
454
 
489
455
  ---
490
456
 
491
457
  ### §5.3 Chair selection & fallback
492
458
 
493
- The default is for Claude to **recommend a non-Claude chair** from the council — typically the model with the strongest reasoning capability or the best peers-only street-cred from `amicus council stats` — and the user confirms this recommendation before the run launches (Stage 0). The chair **may** be a council member who already participated in Stages 1 and 2; it receives the full de-anonymized picture (all reviews with model attribution, all rankings, all adjudications) so it can synthesize from a complete view.
459
+ Claude **recommends a non-Claude chair** — typically the strongest reasoner available or the best
460
+ peers-only street-cred from `amicus council stats` — and the user confirms it before launch
461
+ (Stage 0). In the fast path the chair **must not be a bench seat**: the engine rejects
462
+ `--chair <m>` when `<m>` is in `--models`, because a chair that also reviewed would be synthesizing
463
+ over its own work. It still receives the full de-anonymized picture (all reviews with attribution,
464
+ all rankings, all adjudications) in the chair packet.
494
465
 
495
- **Fallback chain if the chair call fails:**
466
+ **Fallback chain, run by the engine when the chair call fails:**
496
467
 
497
- 1. Re-run the chair call — transient provider failures are common; apply the mitigation from `MODEL-NOTES.md`.
498
- 2. Promote the next-best non-Claude council model to chair.
499
- 3. **Claude chairs only as last resort with explicit disclosure** that the verdict is no longer fully independent of the orchestrator. State this clearly in the report.
468
+ 1. Retry the same chair once — transient provider failures are common.
469
+ 2. Promote the best non-bench model from the reliability ledger (never the reserved `claude` seat).
470
+ 3. Give up: the run finishes degraded (exit 2) with `overallVerdict: null` and no `chair-output.md`.
500
471
 
472
+ On (3), disclose it and offer either a solo re-chair via `MANUAL-ORCHESTRATION.md` or a report-only
473
+ outcome. **Claude chairing is a last resort that requires explicit disclosure** that the verdict is
474
+ no longer independent of the orchestrator — it is never automatic, and the engine will not do it.
501
475
  Never silently degrade to Claude-chairs without informing the user.
502
476
 
503
477
  ---
504
478
 
505
479
  ### §5.4 Claude in the council (default off)
506
480
 
507
- Enabling this toggle lets the bench judge Claude's own take, so you can see how it compares to the independent council.
481
+ Enabling this element lets the bench judge Claude's own take, so you can see how it compares to the independent council.
482
+
483
+ **Asymmetric by design.** Claude is the orchestrator and holds the label↔model map, so it cannot judge blind. The rule is therefore **asymmetric**: Claude contributes a review to be judged by the council but does **not** vote or chair. Claude participates on the supply side only; the verdict remains independent of the orchestrator.
508
484
 
509
- **Asymmetric by design.** Claude is the orchestrator and holds the label↔model map, so it cannot judge blind. The rule is therefore **asymmetric**: Claude contributes a review to be judged by the council but does **not** vote (Stage 2) or chair (Stage 3). Claude participates on the supply side only; the verdict remains independent of the orchestrator.
485
+ **Always fresh.** Claude performs a new structured review on the artifact a fresh pass in the required findings format, not a formalization or summary of anything said earlier in the main conversation. Upstream feedback does not seed or constrain this review. The engine cannot verify freshness; this is a skill-side rule and it is on you.
510
486
 
511
- **Always fresh.** When the toggle is on, Claude performs a new structured Stage-1 review on the artifact a fresh pass in the required findings format, not a formalization or summary of anything said earlier in the main conversation. Upstream feedback does not seed or constrain this review.
487
+ **Mechanics.** Author `<run-folder>/review-claude.md` at Stage 0 and pass
488
+ `--claude-review <run-folder>/review-claude.md`. The engine validates it before any spend, enters
489
+ its findings as one more labeled review, sets `meta.claudeInCouncil: true`, adds `claude` to
490
+ `meta.models` (the street-cred universe), and records a `runStats` row with `durationMs: null` /
491
+ `usage: null` — nothing was launched, and the never-invent rule holds. On such a run `claude` is a
492
+ reserved seat name and the engine's pre-flight rejects it in `--models` or `--chair` (and therefore
493
+ in `--critic`, which must be a bench seat) with `council_claude_review_invalid`.
512
494
 
513
- **"How Claude's review fared" readout.** Included in both `crossreview-matrix.md` and `report.md` when the toggle is on:
514
- - Claude's street-cred rank among peers (its `peersOnly` average rank position in the judges' `FINAL RANKING:` blocks — `withSelf == peersOnly` for Claude since it never casts rankings).
495
+ **"How Claude's review fared" readout.** Include in `report.md`:
496
+ - Claude's peers-only street-cred rank (`withSelf == peersOnly` for Claude, since it casts no rankings).
515
497
  - The Disputed / Confirmed / Contested / Singleton split of Claude's findings — how many of its claims the bench pushed back on, endorsed, disputed, or ignored.
516
498
 
517
- **Integrity.** When Claude presents results — including the bench's assessment of its own review — it reports the verdict at face value. Claude does not defend, contextualize away, or re-litigate findings the bench disputed or ranked poorly. The point of the toggle is an honest external read on Claude's review; undermining that defeats the purpose.
499
+ **Integrity.** When Claude presents results — including the bench's assessment of its own review — it reports the verdict at face value. Claude does not defend, contextualize away, or re-litigate findings the bench disputed or ranked poorly. The point of the element is an honest external read on Claude's review; undermining that defeats the purpose.
518
500
 
519
501
  ---
520
502
 
@@ -526,34 +508,38 @@ Use these together with `amicus council stats` (the ledger — authoritative qua
526
508
  - **Reasoning-heavy critique, structured argument evaluation, citations** → favor a strong reasoner (e.g., DeepSeek, GPT, Opus) that will interrogate claims rather than accept them.
527
509
  - **Code review** → favor a code-strong model (e.g., DeepSeek, GPT, Opus); general-purpose models often miss implementation-level issues.
528
510
  - **Independence matters** → pick models from **different families**; two models from the same family produce correlated opinions and reduce the value of the cross-review.
529
- - **Contrarian / red-team value** → when material is persuasive, consensus-prone, or high-stakes, assign one model an explicit red-team brief: argue against the others, hunt for what they will miss. This is especially valuable when the default council is likely to agree.
511
+ - **Contrarian / red-team value** → when material is persuasive, consensus-prone, or high-stakes, turn on the critic seat (`--critic <model>`): that seat argues against the others and hunts for what they will miss. This is especially valuable when the default council is likely to agree.
530
512
  - **Consult `amicus council stats`** — a model's historical confirm-rate and avg peers-only street-cred (from the ledger) are the best predictors of council value for a given run type.
531
513
 
532
514
  Always **rank recommendations by fit**, state the trade-off for each option, and surface the estimated cost (an estimate, not a guarantee; unpriced legs disclosed as "cost unknown"). Never present a single option without explanation.
533
515
 
534
- **Model naming for council members.** Name bench members by alias (`gemini`, `gpt`, `deepseek`, `opus`, …) or by full `provider/model` id — both work with `--models`/`amicus_fanout`. A bare canonical id (e.g. `anthropic/claude-opus-4.8`) is policy-routed **direct-first**: Amicus uses the user's direct provider key when one is configured, falling back to OpenRouter automatically. `openrouter/provider/model` is an explicit force-OpenRouter override — reach for it only when the user deliberately wants a specific member to run through OpenRouter (e.g. to use a free-tier variant), or for gateway-only vendors with no direct integration. A per-run `--gateway auto|direct|openrouter` (also on `amicus_fanout`/`amicus_start`) overrides routing for the whole wave if the user asks for it; leave it unset (`auto`) by default.
516
+ **Model naming for council members.** Name bench members by alias (`gemini`, `gpt`, `deepseek`, `opus`, …) or by full `provider/model` id — both work with `--models`. A bare canonical id (e.g. `anthropic/claude-opus-4.8`) is policy-routed **direct-first**: Amicus uses the user's direct provider key when one is configured, falling back to OpenRouter automatically. `openrouter/provider/model` is an explicit force-OpenRouter override — reach for it only when the user deliberately wants a specific member to run through OpenRouter (e.g. to use a free-tier variant), or for gateway-only vendors with no direct integration. A per-run `--gateway auto|direct|openrouter` overrides routing for the whole run if the user asks for it; leave it unset (`auto`) by default.
535
517
 
536
518
  ---
537
519
 
538
520
  ## Output & naming
539
521
 
540
- - Run folder: `output/<stem>-council/` (or `./second-opinion/<stem>-council/` if no `output/` exists), containing:
541
- - `review-<model>.md` ×N raw Stage 1 reviews (plus `review-claude.md` when "Claude in the council" is on)
542
- - `crossreview-matrix.md` — adjudication grid + de-anonymized street-cred table
543
- - `verdict.md` — the chair's synthesis (prose)
544
- - `verdict.json` schema-stamped machine-readable record: tally output + Stage-4 decisions, written via `amicus council verdict` at Stage 5
522
+ - Run folder: `output/<stem>-council/` (or `./second-opinion/<stem>-council/` if no `output/` exists), passed to the engine as `--out-dir`. After a fast-path run it holds:
523
+ - `briefing.md` — the Stage-0 review request Claude authored (run provenance, not a temp file)
524
+ - `review-claude.md` — Claude's own fresh review, only when "Claude in the council" is on
525
+ - `run.json` — the engine's run manifest: stage log, wave ids, degradation, `runStats`, cost
526
+ - `review-<model>.md` ×N and `judge-<model>.md` ×N the raw engine legs
527
+ - `briefing-stage1.md`, `bundle-stage2.md`, `chair-packet.md` — the model-facing briefings the engine composed
528
+ - `tally-input.json` and `tally.json` — the assembled input and the tiered record (plus `tally-provisional.json` and `debate.json` when `--debate` was on)
529
+ - `rebuttal-<model>.md` ×(raisers) and `revote-bundle.md` + `revote-<model>.md` ×(disputing judges) — the debate round's raw defense and re-vote leg outputs plus the shared re-vote prompt, only when `--debate` was on
530
+ - `chair-output.md` — the chair's synthesis prose, verbatim from the chair model
531
+ - `decisions.json` — the Stage-4 decision array Claude writes
532
+ - `verdict.json` — schema-stamped machine-readable record: tally output + Stage-4 decisions, written via `amicus council verdict` at Stage 5 (replacing the engine's undecided version)
545
533
  - `report.md` — Claude-authored; full contract defined once in *Stage 5 → Run-folder artifacts* above (chair's synthesis + Stage-4 decision log + run-stats table).
546
- - `report.html` — a **separate, deterministic** artifact generated by the `amicus council report <verdict.json> --html` renderer directly from `verdict.json` (no chair prose, no decision-log narrative — see Stage 5's *Renderer* note); the default artifact to share.
534
+ - `report.html` — a **separate, deterministic** artifact rendered from `verdict.json` (no chair prose, no decision-log narrative — see Stage 5's *Renderer* note); the default artifact to share.
547
535
  - Reviewed copy: `<stem>-reviewed.<ext>`, next to the source.
548
- - Temp working files (`_tmp-*.md`: extracts, stage briefings, red-team brief, critic/lens seat briefs
549
- (`_tmp-briefing-critic.md`, `_tmp-briefing-lens-<slug>.md`), rebuttal briefs (`_tmp-rebuttal-<label>.md`,
550
- `_tmp-revote-bundle.md`), bundle, chair packet, proposed MODEL-NOTES diff) live in the run folder and are
551
- cleaned up at the end of the run — the proposed-diff file only after the Stage-6 approval decision is resolved.
536
+ - The only working file Claude writes in the fast path is the Stage-6 proposed MODEL-NOTES diff (`_tmp-proposed-model-notes-update.md`), cleaned up once the approval decision is resolved. The manual fallback's `_tmp-*.md` files are documented in `MANUAL-ORCHESTRATION.md`.
552
537
 
553
538
  ---
554
539
 
555
540
  ## Files
556
541
 
542
+ - `MANUAL-ORCHESTRATION.md` — the **fallback path**: the hand-driven Stage 1/2/2.5/3 mechanics and the Stage-5 artifacts the engine replaced. **Read it when the engine is unavailable, too old, or misbehaving; when a seat needs a fully custom brief beyond `--critic`/`--lenses`; or when you need to inspect or intervene mid-stage.**
557
543
  - `MODEL-NOTES.md` — operating rules, per-model qualitative quirks, cost guardrail, and structural-conformance notes. **Read it before Stage 0 (council selection and launch); update qualitative notes (with approval) in Stage 6.** Quantitative reliability data (runs, avg street-cred, confirm-rate, fact-error rate) comes from `amicus council stats`, not this file. This copy is machine-local (never overwritten on update); the shipped seed lives in the amicus repo and absorbs durable lessons at release time.
558
- - `SEAT-BRIEFS.md` — briefing boilerplate for the optional council elements (critic seat, expert lenses, rebuttal round, chair verdict scale) plus the standard anti-sycophancy clause every Stage-1 briefing carries. **Read it whenever any element is toggled on at Stage 0** (the anti-sycophancy clause applies to every run).
559
- - `COUNCIL-DESIGN.md` — the design spec this skill implements (v3 + WS-3; §12 covers the optional council elements). Consult it if a mechanics question arises that the skill prose does not resolve.
544
+ - `SEAT-BRIEFS.md` — the semantics of the optional council elements (critic seat, expert lenses, rebuttal round, chair verdict scale) plus the standard anti-sycophancy clause. The engine composes its own stricter-JSON variants of these headlessly; this file stays authoritative for the manual path and for what each element *means*. **Read it whenever any element is toggled on at Stage 0.**
545
+ - `COUNCIL-DESIGN.md` — the design spec this skill implements (§12 covers the optional council elements). Consult it if a mechanics question arises that the skill prose does not resolve.