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.
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +75 -0
- package/README.md +3 -3
- package/commands/council.md +6 -6
- package/package.json +1 -1
- package/schemas/council-run.schema.json +15 -1
- package/schemas/council-tally.schema.json +10 -1
- package/schemas/council-verdict.schema.json +10 -1
- package/schemas/error.schema.json +1 -1
- package/scripts/postinstall.js +6 -3
- package/skills/second-opinion/COUNCIL-DESIGN.md +40 -0
- package/skills/second-opinion/MANUAL-ORCHESTRATION.md +266 -0
- package/skills/second-opinion/MODEL-NOTES.md +21 -0
- package/skills/second-opinion/SEAT-BRIEFS.md +4 -0
- package/skills/second-opinion/SKILL.md +319 -333
- package/src/cli-handlers-council-run.js +9 -0
- package/src/cli-handlers-council.js +20 -2
- package/src/cli.js +8 -0
- package/src/council/briefings-debate.js +158 -0
- package/src/council/briefings-stage2.js +16 -9
- package/src/council/debate.js +98 -0
- package/src/council/ledger.js +2 -1
- package/src/council/parse-stage2.js +83 -1
- package/src/council/report-html.js +28 -1
- package/src/council/report.js +50 -2
- package/src/council/run-assemble.js +91 -9
- package/src/council/run-chair.js +145 -0
- package/src/council/run-debate.js +289 -0
- package/src/council/run-launch.js +27 -1
- package/src/council/run-stages.js +19 -7
- package/src/council/run.js +100 -110
- package/src/council/verdict.js +43 -2
- package/src/mcp-council-run.js +7 -0
- package/src/mcp-server.js +28 -3
- package/src/mcp-tools.js +22 -2
- 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,
|
|
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
|
|
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
|
-
|
|
62
|
+
**Stage 0 (Claude + user)** → **ONE `amicus council run`** (Stages 1–3 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 —
|
|
68
|
-
|
|
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
|
|
72
|
-
|
|
73
|
-
|
|
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
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
**
|
|
86
|
-
|
|
87
|
-
`
|
|
88
|
-
|
|
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
|
|
91
|
-
- Weak structured output: small free models are less reliable at the strict findings JSON;
|
|
92
|
-
|
|
93
|
-
- Throttled/truncated legs: a mid-stream 429 can yield a leg
|
|
94
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
123
|
-
> 2. **Expert lenses** — each reviewer gets a distinct expert perspective; you pick the panel domain (business, technical, customer, financial, custom)
|
|
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. **
|
|
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
|
|
133
|
-
-
|
|
134
|
-
-
|
|
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
|
-
|
|
164
|
-
|
|
165
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
**
|
|
180
|
+
Then **wait for confirmation**. Never launch without it.
|
|
311
181
|
|
|
312
|
-
**
|
|
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
|
-
|
|
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
|
-
###
|
|
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
|
-
|
|
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
|
-
**
|
|
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
|
|
334
|
-
--
|
|
335
|
-
--
|
|
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
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
209
|
+
Always quote the `--models` list — unquoted, 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
|
+
completion — do 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
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
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 claim — so 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
|
|
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
|
|
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
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
- `verdict.
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
—
|
|
416
|
-
|
|
417
|
-
`
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
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 (
|
|
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
|
|
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
|
-
|
|
466
|
-
|
|
467
|
-
|
|
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
|
-
|
|
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:**
|
|
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
|
-
|
|
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 `
|
|
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
|
|
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
|
-
|
|
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
|
|
466
|
+
**Fallback chain, run by the engine when the chair call fails:**
|
|
496
467
|
|
|
497
|
-
1.
|
|
498
|
-
2. Promote the
|
|
499
|
-
3.
|
|
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
|
|
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
|
-
**
|
|
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
|
-
**
|
|
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.**
|
|
514
|
-
- Claude's street-cred rank
|
|
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
|
|
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,
|
|
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
|
|
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),
|
|
541
|
-
- `
|
|
542
|
-
- `
|
|
543
|
-
- `
|
|
544
|
-
- `
|
|
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
|
|
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
|
-
-
|
|
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` —
|
|
559
|
-
- `COUNCIL-DESIGN.md` — the design spec this skill implements (
|
|
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.
|