amicus 4.6.0 → 4.6.1

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "amicus",
3
- "version": "4.6.0",
3
+ "version": "4.6.1",
4
4
  "description": "Multi-model LLM Council + parallel AI window for Claude Code. Run structured council reviews across Gemini, GPT, DeepSeek and more — or fork a conversation to any model and fold the results back.",
5
5
  "author": {
6
6
  "name": "Christian Wagner"
package/CHANGELOG.md CHANGED
@@ -5,6 +5,48 @@ All notable changes to Amicus are documented here. Format follows
5
5
 
6
6
  ## [Unreleased]
7
7
 
8
+ ## [4.6.1] - 2026-08-03
9
+
10
+ ### Added
11
+
12
+ - **The MCP channel finally hears about new versions** (spec 2026-08-03). The MCP server now
13
+ runs the update check at startup and appends one flavor-aware notice block to the first
14
+ successful tool result of each server process (once per session, latched); `amicus_guide`
15
+ carries an always-on update line, and one `[amicus] update available` line lands in the
16
+ client's MCP log on stderr. The instruction is chosen config-first (`npx -y amicus@latest`
17
+ registrations are told a restart suffices; cached/pinned npx copies get the re-point-or-
18
+ clear-cache hint in the unverified voice; global installs get `npm install -g amicus`, from
19
+ where #33's stale-version warning takes over). Words only — no auto-update over MCP, no
20
+ periodic re-check; `NO_UPDATE_NOTIFIER=1` still disables the check entirely.
21
+ - **A lost Stage-1 seat gets one more chance (SL-2).** A council sub-wave that dies before
22
+ its legs exist, or a leg that ends with no usable output, is relaunched exactly once —
23
+ serially, after the surviving launches settle. Recovery announces in the one voice
24
+ (`Recovered: seat X reviewed on retry — …`, a `stage1-retry` heal on
25
+ `run.json`/`verdict.json` `degrades[]`) and the run stays exit 0; a seat still dead after
26
+ its retry degrades exactly as before, with both attempts named in the why. Unconditional;
27
+ gated on the run's `--max-cost` position (an over-budget run skips the retry and records
28
+ the loss byte-identically to v4.6.0). Retry legs and their spend-ledger rows carry
29
+ `retryOfWaveId`. A healed critic counts as seated in `verdict.seatLoss`.
30
+
31
+ ### Changed
32
+
33
+ - **The shipped second-opinion MODEL-NOTES seed was corrected and enriched** (owner-ruled
34
+ fold-back, PR #93): the haiku "hard-404" warning re-caused to the `ANTHROPIC_BASE_URL` `/v1`
35
+ convention split, GLM's stale reliability caution withdrawn on the v4.4.1 fence-extractor
36
+ replay evidence, pre-degrade-era claims re-grounded in the current announce/retry contract,
37
+ and three model sections plus the "peer consensus ≠ evidence on published numbers" rule added
38
+ from the field.
39
+
40
+ ### Removed
41
+
42
+ - **The unused `rebuildElectron` remediation hint** (owner ruling 2026-08-03, closing Plan 3's
43
+ queued hint-voice question). It had no live call site — `doctor --fix`, the in-place Electron
44
+ self-heal, is its stated convergence target — and its prose asserted unverified causes ("after
45
+ an ABI mismatch or partial unpack"). Absence-pinned in `tests/remediation-hints.test.js`; a
46
+ reintroduction must adopt the unverified-cause voice. The same ruling keeps
47
+ `sweepSessionIndexTmp`'s confident voice: its cause is definitional (an atomic-write tmp orphan
48
+ has no other producer), not a guess.
49
+
8
50
  ## [4.6.0] - 2026-08-02
9
51
 
10
52
  ### Added (v4.6 milestone — the degrade announcement invariant, plans 1-4)
package/README.md CHANGED
@@ -441,7 +441,7 @@ $ amicus status demo123 --json
441
441
  "taskId": "demo123",
442
442
  "status": "complete",
443
443
  "elapsed": "5m 0s",
444
- "version": "4.6.0",
444
+ "version": "4.6.1",
445
445
  "model": "google/gemini-2.5-flash",
446
446
  "phase": "terminal"
447
447
  }
package/docs/ROADMAP.md CHANGED
@@ -7,12 +7,14 @@ major jump, gated on funding/cofounder. The observability arc is split so the **
7
7
  first (v4.3)** and the **Electron "Council Workspace" (v4.4)** rides on top of it. `--dry-run` cost
8
8
  preview dropped to the backlog.
9
9
 
10
- Amicus is at **v4.5.0** (tagged 2026-07-28). Each 4.x rev below leads with the benefit, not the
10
+ Amicus is at **v4.6.0** (tagged 2026-08-02). Each 4.x rev below leads with the benefit, not the
11
11
  plumbing.
12
12
 
13
- **Status:** v4.0 through **v4.5.0** have **shipped** — everything down to the v4.6 heading is a
14
- record of what landed, not a plan. **v4.6 (composition + tagging + GUI ergonomics) is the next
15
- rev.** v5.0 remains forward-looking.
13
+ **Status:** v4.0 through **v4.6.0** have **shipped** — everything down to the v4.7 heading is a
14
+ record of what landed, not a plan. **v4.7 (composition + tagging + GUI ergonomics) is the next
15
+ planned rev** — that scope carried the number v4.6 here until the degrade-announcement-invariant
16
+ milestone took the v4.6.0 release (2026-08-02); renumbered, not descoped. v5.0 remains
17
+ forward-looking.
16
18
 
17
19
  > 📁 **Reading this from an npm install?** Some references below point at working documents that
18
20
  > live in the git repository and are deliberately **not** in the published package — anything under
@@ -95,7 +97,7 @@ stops hiding. Design: `docs/superpowers/specs/2026-07-27-v4.5-save-and-share-des
95
97
  client best able to show it. *(S–M; the pieces exist — see the design notes below.)*
96
98
  - **Council policy packs + full run-profiles** (bench + lenses + options + briefing template, invoke by name) — B7/F5 *(M)*
97
99
  - **Briefing templates + library** (F9) *(S–M)* — the foundation packs reference; the `{{input}}`
98
- chaining variable and the `critique`/`refine` built-ins arrive with v4.6
100
+ chaining variable and the `critique`/`refine` built-ins arrive with the composition rev (now v4.7)
99
101
  - **Ride-along fixes** — FR-1 (a failed council seat can render perpetually live), the FR-2 ruling,
100
102
  RN-1/RN-5/RN-11 Workspace renderer fixes, TST-3 real-CDP abort pass *(S each; dispositions for
101
103
  all 17 open items are tabled in the design doc's §8)*
@@ -103,7 +105,37 @@ stops hiding. Design: `docs/superpowers/specs/2026-07-27-v4.5-save-and-share-des
103
105
  > Why here: save/share velocity multipliers that only pay off once councils are a command (v4.0)
104
106
  > and observable (v4.3/v4.4); auto-open makes the v4.4 surface discoverable on its best client.
105
107
 
106
- ## v4.6 — "Compose your councils" *(specced after v4.5 shipsanti-rot rule)*
108
+ ## v4.6 — "A loss announces itself" *(the degrade announcement invariant)*✅ SHIPPED v4.6.0, 2026-08-02
109
+ **Benefit:** a council run can no longer degrade quietly — every loss states what was lost, why,
110
+ and what it does to the run, in one voice, on every surface (stderr, `run.json`, `verdict.json`,
111
+ the report, `doctor`). The north star made mechanical: a correct-but-silent degrade fails the bar
112
+ as hard as a crash.
113
+ - **The ten-channel degrade announcement contract** — every loss routes through one sink
114
+ (`src/council/run-degrade.js`, the only code allowed to flip `degraded.value`, enforced by a
115
+ source-scan invariant test) and lands with mandatory what/why/effect on every surface, including
116
+ the report's new **"What was lost"** section — #85 *(L)*
117
+ - **`verdict.seatLoss` derived from the degrade records** (#84 — a dead critic *leg* finally flips
118
+ `criticSeated`; the v4.5.2 seatLoss suites passed byte-unedited) + **Stage-2 judge legs get
119
+ `runStats` cost rows** (#83 — per-leg attribution for ~38% of a run's spend that had none) *(M)*
120
+ - **`doctor` speaks the vocabulary** — `doctor --json` gains additive `degrades[]`, `--fix` prints
121
+ `Recovered:` lines in the one voice, and the engine hints state causes as **unverified** instead
122
+ of asserting an antivirus guess *(M)*
123
+ - **Workspace discoverability from the CLI** — `watch` usage names `--ui` (#80), a CLI council run
124
+ with Electron present prints how to open the live Workspace (#81), `watch --ui` against an
125
+ `--out-dir` run names its cause (#82), and the Stage-5 verdict rebuild preserves
126
+ `seatLoss`/`degrades[]` (#87) *(S each)*
127
+ - **Deliberate behavior changes** — dropped preset members and shared-server acquisition failures
128
+ now exit degraded (2) on every transport; judge rows raise reported cost totals vs v4.5.x
129
+ (`runStats` consumers keying by model must exclude `role: 'judge'`).
130
+ - **Docs** — the full record is `CHANGELOG.md` §4.6.0; spec
131
+ `docs/superpowers/specs/2026-08-01-degrade-announcement-invariant-design.md`; plans 1–4 under
132
+ `docs/superpowers/plans/` (`2026-08-0*-v4.6-degrade-invariant-plan-*.md`).
133
+ > Why it jumped the queue (2026-08-01): the v4.5.x field reports showed the engine was not losing
134
+ > legs (11 four-seat council runs on v4.5.4, 10 clean) — but when a seat *was* lost, nothing told
135
+ > the user which one. That silent-degrade class was ruled a north-star violation and took the rev
136
+ > number; the composition scope below moved to v4.7.
137
+
138
+ ## v4.7 — "Compose your councils" *(renumbered from v4.6, 2026-08-02 — spec + fresh plan at kickoff per the anti-rot rule)*
107
139
  **Benefit:** councils chain — generate → critique → refine with no manual copy-paste — and history
108
140
  becomes navigable.
109
141
  - **Composable/chained waves** (`--input-from <id>` / `--prompt-file -` pipe + per-source digests) —
@@ -115,8 +147,8 @@ becomes navigable.
115
147
  remainder of TST-7
116
148
  - **README + docs update** *(S)*
117
149
  > The 2026-07-19 combined spec (`2026-07-19-v4.5-policy-packs-composition-design.md`) holds the
118
- > approved chaining/tagging/F10 design detail and is the primary input to the v4.6 brainstorm; it
119
- > is NOT executed as-written — v4.6 gets its own spec + fresh plan once v4.5 ships.
150
+ > approved chaining/tagging/F10 design detail and is the primary input to the v4.7 brainstorm; it
151
+ > is NOT executed as-written — v4.7 gets its own spec + fresh plan at kickoff.
120
152
 
121
153
  ### Deferred out of v4.4.1 into v4.5 (2026-07-27)
122
154
 
@@ -48,7 +48,7 @@ Provenance is implied under trusted publishing.
48
48
 
49
49
  Run top-to-bottom before `npm version`:
50
50
 
51
- 1. **MODEL-NOTES fold-back:** diff the machine-local ledger (`~/.claude/skills/second-opinion/MODEL-NOTES.md`) against the shipped seed (`skills/second-opinion/MODEL-NOTES.md`); port durable, machine-independent lessons into the shipped file (merge/prune, keep it tight — no run-ledger numbers, those live in `amicus council stats`).
51
+ 1. **MODEL-NOTES fold-back:** diff the machine-local ledger (`~/.claude/skills/second-opinion/MODEL-NOTES.md`) against the shipped seed (`skills/second-opinion/MODEL-NOTES.md`); cherry-pick generalizable lessons from the local ledger into the shipped seed — **per-section judgment, both directions, never a bulk copy** (the divergence is two-directional: adopt seed-side corrections back into the local ledger too). Merge/prune, keep it tight — no run-ledger numbers, those live in `amicus council stats`. Standing practice per the owner's ruling, 2026-08-03: shipped = curated seed, local = lab notebook.
52
52
  2. `npm test` green; `npm run lint` clean.
53
53
  3. **Integration tier, both rails:**
54
54
  - `npm run test:integration` (keyless) — must be **0 failures**. This is the same thing the `integration` job in `ci.yml` runs on every push, so it should already be green.
package/docs/usage.md CHANGED
@@ -443,7 +443,7 @@ $ amicus status demo123 --json
443
443
  "taskId": "demo123",
444
444
  "status": "complete",
445
445
  "elapsed": "5m 0s",
446
- "version": "4.6.0",
446
+ "version": "4.6.1",
447
447
  "model": "google/gemini-2.5-flash",
448
448
  "phase": "terminal"
449
449
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "amicus",
3
- "version": "4.6.0",
3
+ "version": "4.6.1",
4
4
  "mcpName": "io.github.BourbonDog/amicus",
5
5
  "description": "Multi-model LLM Council + parallel AI window for Claude Code. Run structured council reviews across Gemini, GPT, DeepSeek and more — or fork a conversation to any model and fold the results back.",
6
6
  "keywords": [
@@ -4,8 +4,10 @@ This file is the `second-opinion` skill's evolving memory of **how to actually d
4
4
  well**. Read it before Stage 0 (council selection and launch); update it, with the user's
5
5
  approval, at the end of each run (Stage 6). Keep it tight — merge and prune rather than append.
6
6
 
7
- _Last updated: 2026-07-26 (v4.4.0 fold-back: alias-resolution hygiene, `council run --run-id`,
8
- debate defense/re-vote waves now exercised, haiku and glm notes; see changelog)._
7
+ _Last updated: 2026-08-03 (per-section fold-back, both directions the haiku "hard-404"
8
+ re-diagnosed as a `/v1`-less `ANTHROPIC_BASE_URL`, pre-degrade-era claims re-grounded in the
9
+ announcement contract (`degrades[]`/`seatLoss`/exit 2/one Stage-1 retry), three model sections and
10
+ the peer-consensus≠evidence rule upstreamed from the field ledger; see changelog)._
9
11
 
10
12
  ## Global operating rules (all models)
11
13
  - **Fast path:** `council run` applies `--agent Plan` / `--no-context` / `--summary-length
@@ -22,14 +24,33 @@ debate defense/re-vote waves now exercised, haiku and glm notes; see changelog).
22
24
  defined in SKILL.md Stage 0) — no size cap, no shell-quoting hazards. Never inline a briefing as
23
25
  a CLI argument.
24
26
  - **Run in the background (`run_in_background: true`); you're notified on completion. Don't poll.**
27
+ - **A stale MCP server kills councils with a distinctive signature — zero output on every leg.**
28
+ If any amicus MCP tool result carries the "Amicus was upgraded on disk (running vX, on-disk vY).
29
+ Restart your MCP client" notice, do NOT launch councils through the MCP tools — relaunch via the
30
+ CLI (`amicus council run`, a fresh process) or restart the client first. A version-skewed server
31
+ has timed out an entire Stage-1 wave with literally zero output bytes on every leg; that
32
+ all-legs-zero-output shape is what distinguishes it from model/provider failures, which produce
33
+ partial output or errors.
25
34
  - **Read results from the JSON documents** (`--json`): a wave's `legs[].summary` / a run's
26
35
  `summary` is the model's output; `status`/`error`/`counts` are ground truth for failures. Never
27
36
  scrape stderr logs to judge success.
28
37
  - **Transient provider errors** (502s, connection drops): re-run the affected leg (solo
29
38
  `amicus start --json`, same briefing file) or the wave — see per-model notes for
30
39
  model-specific signals. Never present a half-finished run as an answer.
40
+ - **Seat losses are announced, retried once, and exit-coded — read the surfaces, don't diff
41
+ finding counts.** Every lost seat/leg is announced in one voice on stderr and recorded in
42
+ `run.json.degrades[]`, `verdict.json.degrades[]`, the report's **"What was lost"** section, and
43
+ `verdict.seatLoss`, and the run exits degraded (2). A Stage-1 wave or leg that dies is relaunched exactly once (serially, after the
44
+ surviving launches settle; skipped when the run is already over `--max-cost`): a heal announces
45
+ as a `Recovered:` line and the run stays exit 0; a seat still dead after its retry is recorded
46
+ with both attempts named in the why. A dead route still doesn't stop a council — it shrinks it —
47
+ but the shrinkage is no longer silent: confirm the bench you paid for from
48
+ `seatLoss`/`degrades[]` after every run, because a shrunken bench weakens the tiers (fewer
49
+ corroborators per finding).
31
50
  - **Credentials:** keys live in `~/.config/amicus/.env`. The legacy `~/.config/sidecar/.env`
32
- fallback was removed in v2.0.0 (see `docs/SHIMS.md`). Configure with `amicus setup`.
51
+ fallback was removed in v2.0.0 (see `docs/SHIMS.md`). Configure with `amicus setup`. If
52
+ `ANTHROPIC_BASE_URL` is set anywhere in the environment, it must carry its `/v1` suffix for
53
+ direct-Anthropic legs — see the haiku section for the full diagnosis.
33
54
  - **PowerShell `--models` quoting (Windows):** always quote comma-separated model lists —
34
55
  `--models "gemini,gpt,deepseek"`. Unquoted, PowerShell splits on commas and amicus receives one
35
56
  mangled alias → instant arg-parse failure. (Now baked into every SKILL.md example.)
@@ -40,18 +61,50 @@ debate defense/re-vote waves now exercised, haiku and glm notes; see changelog).
40
61
  gpt/deepseek/grok have handled 82k-word agentic reads; gemini(-flash) and kimi stalled (narrate-
41
62
  stall / 25-min timeout / poller "Incomplete"). Pre-select proven long-read models or inline the
42
63
  text for large-context models.
64
+ - **Long agentic reads can "narrate-then-never-deliver" even on capable models that DO finish
65
+ reading — bake the anti-narration hardening into the FIRST attempt, not the retry.** Models have
66
+ done a genuine full chunked read (confirmed by realistic input-token counts) and then ended the
67
+ turn with only process narration ("Continuing…"), never producing the review + JSON: the read
68
+ completed, but the turn budget ran out before the switch from reading mode to writing mode.
69
+ Whenever the task requires many sequential file-read tool calls before writing, the briefing
70
+ needs an explicit preamble: *"this is headless with no follow-up turn; you must produce the
71
+ complete deliverable by the end of THIS response; if running low on room, stop reading early and
72
+ write from what you have rather than deliver nothing."*
73
+ - **Multi-FILE agentic reads stub out like long single reads — even WITH the anti-narration
74
+ preamble baked in.** Weaker readers have returned narration stubs of roughly 60–100 chars on a
75
+ multi-file packet despite the standard preamble. Treat a many-file briefing as a long-read task:
76
+ expect stubs, retry solo once with the identical briefing, then substitute the model — or
77
+ pre-concatenate the packet into one file for weaker readers.
78
+ - **`--agent Plan` can trigger a literal, hard "planning mode — cannot execute" refusal on some
79
+ models** (terse, near-zero-token responses), not just the intended read-only tool restriction —
80
+ and prompt wording alone has not fixed it; switching that model to `--agent Build` has, immediately.
81
+ On the manual path, Stages 2-3 never touch the source file (the briefing is self-contained plus a
82
+ no-tools preamble), so `--agent Build` is safe there; reserve `--agent Plan` for Stage-1 legs
83
+ that read the source, and fall back to Build per-model on a hard refusal.
43
84
  - **Debate mode rarely fires on correctness questions — design for it or expect a no-op.**
44
85
  `--debate` only engages findings the tally marked Contested or Disputed, and judges agree far
45
86
  more than expected: **2 disputes in 123 adjudications across four councils** (gemini/gpt/qwen).
46
87
  Three of those four runs produced zero debatable findings, so the round never ran. Bug hunts
47
88
  converge — a race condition either exists or it does not. If you want a rebuttal round, brief a
48
89
  genuine judgement call (architecture, tradeoffs, "is this over-engineered"), not a defect hunt.
90
+ - **Peer consensus is not evidence on published, checkable numbers — verify against a primary
91
+ source before applying such a finding, especially from the Confirmed tier and findings that
92
+ survived debate.** In one paid council, 2 of 23 findings were factually wrong about published
93
+ specs and BOTH sat in the tiers that are supposed to signal reliability: one reached Confirmed
94
+ on two peer agreements, the other hardened after a debate round in which a correct dispute was
95
+ talked out of its objection. A rebuttal is a rhetorical performance — judges re-voting on a
96
+ persuasive defense have no more access to the spec sheet than they did the first time. Any
97
+ finding that asserts a published figure (spec, capacity, rating, dimension, date) gets a
98
+ verification pass before you act on it.
49
99
  - **Read spend from `run.json`, never from a provider credit balance.** `usage.cost.amount` is the
50
100
  run total; per-leg costs are in `runStats[].usage.cost`. Only OpenRouter-routed legs move the
51
101
  OpenRouter balance — gemini/gpt/anthropic bill directly against their own keys, so inferring cost
52
102
  from that balance under-reports it badly (observed: ~6x low). A 3-model bench + chair + debate is
53
103
  roughly **$0.60-0.80 per run**, not cents; budget `--max-cost` accordingly or the chair gets
54
- skipped mid-run (exit 2, degraded) when the debate legs push the total past the ceiling.
104
+ skipped mid-run (exit 2, degraded) when the debate legs push the total past the ceiling. As of
105
+ v4.6, `runStats` also carries Stage-2 judge rows (judge-tagged), so totals read higher than
106
+ pre-4.6 runs for the same bench; anything keying `runStats` by model should exclude
107
+ `role: 'judge'`.
55
108
  - **Expect agreement inflation in Stage-2 adjudication.** The judge contract defines `agree` by
56
109
  worked example ("an 'I missed this — it's valid' counts as agree") but gives no example for
57
110
  `dispute` and no positive definition of `neutral`, while requiring a verdict on EVERY finding —
@@ -105,7 +158,9 @@ debate defense/re-vote waves now exercised, haiku and glm notes; see changelog).
105
158
  **rescope** mechanism rather than a defense — raisers overwhelmingly AMEND (downgrade an
106
159
  overstated severity, narrow a scope) rather than DEFEND, and amendments are re-confirmed on the
107
160
  re-vote. Expect high-amend / low-defend; the idea usually survives, the severity claim often does
108
- not.
161
+ not. In ideation councils, **cross-lens convergence** (independent lenses proposing the same
162
+ idea) is the strongest priority signal — compute it yourself when clustering; it is
163
+ complementary to, not the same as, the tally's agree/dispute tiers.
109
164
 
110
165
  ## Per-model notes
111
166
 
@@ -118,61 +173,115 @@ debate defense/re-vote waves now exercised, haiku and glm notes; see changelog).
118
173
  - **Red-team:** takes an adversarial brief well — high variance by design; use when consensus risk is high.
119
174
  - **Blind self-votes are inconsistent** (self-#1 in some runs, self-last in others) → discount self-votes either way.
120
175
  - Alias has resolved to **flash** tiers: fast, shallowest coverage, yet a recurring sharp fact/consistency checker (it alone refuted a bench-wide date error). Cheap cross-check value.
176
+ - **Asserts quantitative "corrections" (timings, capacities) with unearned confidence** — one such
177
+ "severely wrong" correction was disputed 3-0, including its own blind self-dispute. Cross-check
178
+ its numeric claims before weighting; its honest blind self-disputes are a useful calibration tell.
121
179
  - **Unreliable on long agentic reads** (see global rule) — inline the text or swap models for book-length material.
122
180
 
123
181
  ### DeepSeek (`--model deepseek` → via OpenRouter)
124
182
  - **Strengths:** resilient; produces strong, well-structured, well-cited critical analysis. A good
125
183
  default reviewer and a proven chair.
126
184
  - **Quirk:** occasional transient 502 mid-run → re-run the leg.
127
- - Proven chair (5 clean chairings) — decisive, well-structured synthesis.
185
+ - Proven chair (many clean chairings) — decisive, well-structured synthesis.
128
186
  - As a Stage-1 reviewer of human-facing documents it **over-escalates severity** (typos/tenure → "blocker"); discount its blocker labels against peers. Prune its self-retractions when tallying.
129
187
  - **"Agree-with-the-adversary" lean:** it has been the lone endorser of a red-team's harshest claims, turning them Contested — cross-check before treating its lone agreements as consensus.
188
+ - **Stub-on-fanout / clean-on-solo-retry:** its Stage-1 fanout leg has returned a sub-100-char
189
+ narration stub despite the anti-narration preamble, then produced a full review on a plain solo
190
+ retry with the identical briefing — retry solo before substituting the model.
130
191
 
131
192
  ### GPT (`--model gpt` → via OpenRouter)
132
193
  - **Strengths:** reachable via the OpenRouter key; resilient; very thorough structured critique
133
194
  (25 findings on a 1-page framework). Cleanly separates the review criteria.
134
195
  - **Quirks:** verbose — peers dinged it for volume-over-judgment (good coverage, lower
135
196
  discrimination); **self-ranked its own review #1** in cross-review → discount self-votes.
136
- - Ranked genuine #1 by all judges (incl. non-self) in one run — thoroughness is real, not a self-vote artifact. Handled an 82k-word agentic read cleanly.
197
+ - Ranked genuine #1 by all judges (incl. non-self) in one run — thoroughness is real, not a self-vote artifact. Handled an 82k-word agentic read cleanly — but a later similar-size read delivered only narration until retried with the anti-narration preamble; apply the preamble to gpt by default, not just to weaker models.
137
198
  - **Asserts context-dependent facts (dates, "is this future?") without verifying** — and self-confirms them in adjudication. Cross-check any time-dependent claim it raises.
138
- - A good calibration anchor in cross-review: confirms observational findings, disputes interpretive overreach.
199
+ - A good calibration anchor in cross-review: confirms observational findings, disputes interpretive overreach. A repeatable role: the seat most likely to catch **confidence inflation** in an otherwise-correct argument (theoretical risk asserted as demonstrated mechanism, proxies used as pseudo-diagnostics).
200
+ - **When gpt disputes a specific numeric claim, weight that dispute heavily before a debate round erodes it** — it has been right and then talked out of the objection by a persuasive rebuttal (see the peer-consensus rule).
139
201
 
140
202
  ### Grok (`--model grok` → via OpenRouter)
141
203
  - Very fast legs; credible judge and chair (rejected its own weak findings as chair; honest blind self-rank).
142
204
  - Strong red-team fit; handled an 82k-word agentic read. Weight its **observational** catches heavily and its **interpretive** verdicts cautiously (bench pattern: the former confirmed, the latter disputed).
143
205
  - Stage-1 non-red-team reviews skew to scope-inflated "missing content" majors.
206
+ - Has **hard-refused under `--agent Plan`** ("Plan mode active… cannot execute"; near-zero tokens)
207
+ where `--agent Build` worked immediately — prefer Build for grok legs (see the global Plan-refusal rule).
208
+ - **Fabrication risk on long-document tasks:** one fast, suspiciously low-fresh-token response
209
+ contained an invented "major"-severity finding plus unsupported flavor details, verified false
210
+ against the source. A later run under Build (genuine read, no fabrications on spot-check)
211
+ partially rebuilt confidence — usable for red-team slots under Build **with the spot-check
212
+ discipline**: verify its most specific/surprising claims against the source before letting them
213
+ into a council.
144
214
 
145
215
  ### Kimi (`--model kimi` → via OpenRouter)
146
216
  - The bench's sharpest adjudicator (caught strawmen and misreads other judges waved through).
147
- - **Very slow legs (5-7 min)** it gates wave wall-clock; budget timeouts around it.
148
- - Stalls on long agentic reads (poller "Incomplete" with only a preamble). Reserve for short-artifact adjudication.
217
+ - Repeatedly the **top-ranked reviewer on consumer-practical, safety-heavy artifacts** (food
218
+ safety, mechanical advice) top-ranked in two such runs (unanimous in one), with the most
219
+ granular findings on the bench and genuine structural catches.
220
+ - Its specificity is also its risk: it reaches for **exhaustive quantitative claims ("every",
221
+ "all", "none") that are directionally right and literally wrong** — and it has successfully
222
+ DEFENDED one in a debate round against a correct dispute. Verify its universal quantifiers
223
+ against a primary source (see the peer-consensus rule).
224
+ - **Very slow legs (4-8× its peers)** — it gates wave wall-clock; budget timeouts around it.
225
+ - Stalls on long agentic reads (poller "Incomplete" with only a preamble). Reserve for short-artifact work.
149
226
 
150
227
  ### Mistral (`--model mistral` → via OpenRouter)
151
228
  - Fast, broad coverage, catches real issues.
152
229
  - **Hallucination risk is real:** has invented non-existent product models/specs, disputed independently by two judges. Cross-check every specific model number or product claim it introduces.
153
230
 
154
231
  ### Claude (in-council, when toggle on)
155
- - Consistently the most *calibrated* reviewer (no severity inflation; findings overwhelmingly Confirmed; bench-best street-cred in recent runs) but sometimes the least *original* — it can miss the boldest single catch. Treat as a reliability floor, not a discovery engine.
156
-
157
- ### haiku (`--model haiku`) — **verify before using; it has been hard-404ing**
158
- - The direct-Anthropic route (`anthropic/claude-haiku-4-5-20251001`) returned a hard `Not Found`
159
- on **every** invocation of a recent paid corpus 3 of 3 legs across two separate runs, both as
160
- **chair** (twice, incl. the fallback retry) and as a **bench seat**in ~2 s with zero tokens.
161
- - Both runs degraded *around* it silently rather than failing: one fell back to another chair, the
162
- other collapsed its bench from 3 seats to 2 and exited 2. **A dead alias does not stop a council;
163
- it shrinks it.** In the bench-seat case every finding came out `confidence: "thin"` with a single
164
- peer corroborator, purely because the bench had halved and nothing in `verdict.json` said so.
165
- - Resolve the alias against the catalog (`amicus models --check`) before putting it on a paid
166
- bench, and re-check the bench roster in `run.json` against what you asked for afterwards.
167
-
168
- ### GLM (`--model glm` z-ai via OpenRouter)
169
- - Cheap and fast, and ranked best-by-peers on a clean debut — but a later run produced **35 KB of
170
- prose with `conformance: unstructured` and 0 parsed findings**, twice. Its structured-output
171
- reliability is **not** established; treat the debut as low-N.
172
- - Useful behavioural note: when its structured output failed it **refused to fabricate** on the
173
- repair attempts. Honest but an honest refusal still costs you the seat, so a bench that leans
174
- on `glm` for quorum can silently adjudicate a seat short while still paying for its tokens.
175
- Watch `conformance` per seat, not just the finding count.
232
+ - Consistently the most *calibrated* reviewer (no severity inflation; findings overwhelmingly Confirmed; bench-best street-cred in recent runs) but sometimes the least *original* — it can miss the boldest single catch. Treat as a reliability floor, not a discovery engine — though on some benches its findings have anchored the entire Confirmed tier.
233
+ - Its own checkable, arithmetic-style claims deserve the same **mechanical verification** as everyone else's: one calendar-consistency claim in a Claude first-pass review was a genuine reasoning error, caught only by computing the dates programmatically before submission (see General).
234
+
235
+ ### haiku (`--model haiku`) **the "hard-404" was the environment, not the model**
236
+ - **The model was never the problem.** The direct-Anthropic route returned an instant `Not Found`
237
+ (~2 s, zero tokens) on every invocation of a paid corpus3 of 3 legs across two runs, as chair
238
+ and as bench seat and the standing diagnosis was a rotten alias. It is not: the cause is an
239
+ **`ANTHROPIC_BASE_URL` set in host form, without its `/v1` suffix**. Anthropic SDKs (including
240
+ Claude Code itself) treat the var as a HOST and append `/v1` themselves; OpenCode's provider
241
+ layer treats it as the full prefixso a value that is correct for the host app kills every
242
+ direct-Anthropic leg amicus launches. Proven by control pair: an identical `fanout --models
243
+ opus` call fails "Not Found" on the host form and completes with `/v1` appended.
244
+ - **Symptom signature:** instant "Not Found", zero tokens, direct-Anthropic routes only —
245
+ OpenRouter-routed legs in the same run are unaffected. It hits every direct-Anthropic alias
246
+ equally (haiku, opus, sonnet, claude; `fable` is OpenRouter-only and unaffected), so a "dead"
247
+ cheap seat and a "dead" frontier chair with this signature share one cause.
248
+ - **The check:** inspect `ANTHROPIC_BASE_URL` in the environment amicus actually runs in — the var
249
+ can live only in a parent process's env (e.g. the host app), absent from every shell profile and
250
+ settings file on disk. If it lacks `/v1`, that is the kill. A doctor check for this is filed on
251
+ the backlog; until it ships, check by hand before blaming a model or an alias.
252
+ - Seat-loss mechanics for a dead route are the same as any other loss — announced in one voice,
253
+ exit 2 if still dead. A dead Stage-1 seat gets the one retry; a dead CHAIR walks the chair's own
254
+ chain instead — same-chair retry, then promotion of the best non-bench model from the ledger —
255
+ with the actual chair checkpointed into `run.json` (see the seat-loss bullet in Global
256
+ operating rules).
257
+
258
+ ### GLM (`--model glm` → `glm-5.1` via OpenRouter; the recent observations below are from the explicit `openrouter/z-ai/glm-5.2` id)
259
+ - The v4.4.0-era "structured-output reliability not established" warning is **withdrawn as
260
+ wrong-cause**: its `unstructured`-conformance results and repair refusals traced to two
261
+ since-fixed engine defects (the unanchored fence extractor that truncated any JSON quoting a
262
+ code fence, and repair prompts that omitted the artifact under repair — both fixed in v4.4.1),
263
+ not to the model. Conformance has been `clean` in subsequent paid runs.
264
+ - Cheap and fast; **ranked best-by-peers on an ideation-bench debut** — a focused,
265
+ fewest-findings reviewer whose findings land. Promising budget-to-mid bench member.
266
+ - **First recorded confident fact error:** it asserted an engine spec that the primary source (the
267
+ owner's manual) contradicts outright — and the finding reached Confirmed on two peer agreements,
268
+ denied only by a post-council verification pass. Treat glm's confident factual assertions as
269
+ unverified until checked (the peer-consensus rule exists because of findings like this one).
270
+ - Honest under pressure both ways: it refused to fabricate on repair attempts, and it has
271
+ withdrawn a contested finding cleanly in debate. An honest refusal still costs the seat — watch
272
+ `conformance` per seat, not just the finding count.
273
+
274
+ ### Qwen (`--model qwen` → qwen3.7-max via OpenRouter; distinct from `qwen-coder`)
275
+ - Very large context (1M tokens per catalog). As a red-team substitute it has produced a thorough,
276
+ well-organized adversarial review with accurate, specific line citations and genuinely unique
277
+ catches that verified true against the source — weight its specific, cited claims heavily.
278
+ - Same observational-vs-interpretive split as grok: its cited observational findings get
279
+ confirmed; its "blocker"-severity interpretive claims get disputed as genre-normative. Weight
280
+ its severity labels on broad interpretive claims cautiously.
281
+ - **Do not assign qwen Stage-1 multi-file reads.** Its proven mode is single-file reads and
282
+ short-artifact work: a book-length single-file read succeeded on retry with the anti-narration
283
+ preamble, but multi-file packets have produced narration stubs twice in one run — with the
284
+ preamble present, under both Plan and Build. It narrates rather than refuses under Plan.
176
285
 
177
286
  ### minimax (`--model minimax` → via OpenRouter)
178
287
  - Fast (~2 min review legs), cheap, `clean` findings-JSON conformance on debut.
@@ -189,6 +298,21 @@ debate defense/re-vote waves now exercised, haiku and glm notes; see changelog).
189
298
  - Ranked last on its debut bench — misses the offline, interruption-handling, and
190
299
  test-methodology gap classes stronger seats catch. Fine budget-bench filler; do not chair it.
191
300
 
301
+ ### GPT-5.6-Terra (`openrouter/openai/gpt-5.6-terra`)
302
+ - Debut (one paid ideation run): `clean` conformance, thorough — the most findings on its bench.
303
+ Handled an inlined ~13K-token digest cleanly under `--agent Build`.
304
+ - The priciest leg on its bench (~5× the cheap seats) and it self-ranked #1 (discount self-votes,
305
+ as always) while peers ranked it lower — thoroughness did not convert to peer standing. Low-N;
306
+ re-confirm before leaning on it.
307
+
308
+ ### Gemini 3.1 Pro (`openrouter/google/gemini-3.1-pro-preview` — the PRO tier; the bare `gemini` alias resolves to flash)
309
+ - Debut (one paid ideation run): `clean` conformance, mid-bench peer standing.
310
+ No narration or stall — but the material was INLINED, not an agentic read (where gemini-flash
311
+ historically stalls); don't extend the result to agentic reads untested.
312
+ - Use the shipped `gemini-pro` alias when you want a real Pro reviewer — it live-resolves to the
313
+ current Pro tier, falling back to `openrouter/google/gemini-3.1-pro-preview`; the bare `gemini`
314
+ alias gives you flash.
315
+
192
316
  ### (others — add as used)
193
317
  - Opus / o-series etc. are reachable via amicus **if their API keys are configured**. Add notes
194
318
  here the first time each is used.
@@ -209,7 +333,7 @@ This section keeps only per-model **qualitative quirks** and **structural-confor
209
333
 
210
334
  - **deepseek** — strong synthesis, resilient; occasional transient 502 → re-run the leg. Proven chair. Conforms cleanly.
211
335
  - **gpt** — thorough but verbose; peers have dinged it for volume-over-judgment. Self-ranked its own review #1 in the 2026-06-04 run → the peers-only street-cred rule (now enforced by `tally`) mitigates this. Conforms cleanly. Accessible via OpenRouter.
212
- - **gemini** — fast, very large context; tends toward absolute severity labels ("blocker" inflation vs peers). Conforms cleanly; watch for preamble narration — instruct it to emit the JSON block verbatim after the prose.
336
+ - **gemini** — fast, very large context; the bare alias resolves to flash tiers (shallow coverage, cheap fact-checks); asserts numeric "corrections" with unearned confidence — cross-check them. Conforms cleanly; watch for preamble narration — instruct it to emit the JSON block verbatim after the prose.
213
337
 
214
338
  ## Free-tier models (OpenRouter `:free`)
215
339
  - Heavily rate-limited (shared daily pool); a 3-leg parallel wave + cross-review can 429 mid-run.
@@ -229,6 +353,12 @@ This section keeps only per-model **qualitative quirks** and **structural-confor
229
353
  ## General
230
354
  - Model citations are usually real but **verify any load-bearing reference before publishing**;
231
355
  watch for loosely-attached attributions (e.g., a real paper cited for the wrong claim).
356
+ - **Checkable, arithmetic-style claims (calendar/date consistency, counts, named specific facts)
357
+ deserve a mechanical verification pass before publishing — including claims from Claude's own
358
+ review, not just other models'.** One calendar-consistency claim in a Claude first-pass review
359
+ was wrong; running the actual dates through a real calendar caught it before it reached the
360
+ council or the author. This class of claim is cheap to verify mechanically and expensive to get
361
+ wrong in a document going to a human — don't re-reason it a second time; compute it.
232
362
  - Prefer models from **different families** for genuinely independent opinions.
233
363
 
234
364
  ## Lessons changelog
@@ -237,7 +367,7 @@ This section keeps only per-model **qualitative quirks** and **structural-confor
237
367
  its occasional transient 502.
238
368
  - **2026-06-03** — v2 council upgrade: added cross-review (Stage-2 anonymized peer ranking +
239
369
  per-finding adjudication) and reviewer-reliability tracking.
240
- - **2026-06-04** — Trusst messaging-framework council (Gemini + GPT + DeepSeek + Claude-in-council;
370
+ - **2026-06-04** — B2B messaging-framework council (Gemini + GPT + DeepSeek + Claude-in-council;
241
371
  DeepSeek chair). First GPT use → per-model note. First scored reviewer-reliability rows
242
372
  (deepseek 2.33/100%, gpt 2.67/92%, gemini 3.67/89%; 1–4 scale).
243
373
  - **2026-06-10** — v3 migration: transport moved to `fanout --json` + `--prompt-file` (F4); pruned
@@ -254,11 +384,28 @@ This section keeps only per-model **qualitative quirks** and **structural-confor
254
384
  a bench seat; `council run` prints nothing until terminal, so pin `--run-id` when backgrounding.
255
385
  Debate's defense/re-vote waves exercised for the first time — they work, and behave as a rescope
256
386
  (amend-heavy) rather than a defense. New per-model notes: **haiku** hard-404ed 3/3 legs across two
257
- runs and both councils silently degraded around it; **glm** returned `unstructured` conformance
387
+ runs and both councils silently degraded around it *(both halves since superseded: the 404 was a
388
+ `/v1`-less `ANTHROPIC_BASE_URL`, not the alias — see the haiku section — and the silent-degrade
389
+ era ended with the v4.5.2→v4.6 announcement contract)*; **glm** returned `unstructured` conformance
258
390
  with 0 findings twice after a clean debut, and honestly refused to fabricate on repair — which
259
- still costs the seat.
391
+ still costs the seat *(since re-diagnosed: both results were v4.4.0 engine defects, fixed in
392
+ v4.4.1 — see the GLM section)*.
260
393
  - **2026-07-14 (v2.2.0)** — Optional council elements shipped and verified on a planted-flaw
261
394
  ground-truth council (critic seat, debate mode nothing-to-debate path, chair verdict scale;
262
395
  expert lenses defined but not yet field-run). New lessons: claim-class dedup glosses
263
396
  rationale-level errors in Stage-2; minimax debut (strong critic seat, CJK-intrusion quirk);
264
397
  qwen-coder debut (fast budget filler). Debate mode's defense/re-vote waves still unexercised.
398
+ - **2026-08-03 (fold-back, both directions — owner's ruling)** — Per-section reconciliation with
399
+ the machine-local field ledger after six release-cycle deferrals. Corrections: the haiku
400
+ "hard-404" re-diagnosed (a `/v1`-less `ANTHROPIC_BASE_URL` in host form — the model was never
401
+ the problem; control pair: identical `fanout --models opus` fails host-form, completes with
402
+ `/v1`); glm's `unstructured` era re-attributed to the since-fixed v4.4.1 fence-extractor and
403
+ repair-prompt defects; every pre-degrade-era "silent shrink" claim re-grounded in the current
404
+ contract (one-voice announcement on stderr + `degrades[]` + `seatLoss`, exit 2, one Stage-1
405
+ retry with `Recovered:` heals). Upstreamed from the field: the peer-consensus≠evidence rule
406
+ (2 of 23 findings factually wrong inside high-trust tiers, caught only by primary-source
407
+ verification), the anti-narration-preamble and multi-file-stub rules, the Plan-hard-refusal
408
+ fallback, the stale-MCP-server signature, three model sections (qwen, gpt-5.6-terra,
409
+ gemini-3.1-pro), and gemini/deepseek/gpt/grok/kimi/Claude enrichments. Standing practice: each
410
+ release cherry-picks generalizable lessons per-section (docs/publishing.md release checklist),
411
+ never a bulk copy.
@@ -94,6 +94,10 @@ function createLaunchers(deps = {}) {
94
94
  // part of that allowance in the meantime. This is the CLAIM that settles
95
95
  // it — synchronous by contract, so two callers can never interleave.
96
96
  ...(reserveBudget ? { reserveBudget: (est) => reserveBudget(opts.waveId, est) } : {}),
97
+ // SL-2: a Stage-1 retry names the wave it replaces; fanout threads this
98
+ // onto every leg and its spend-ledger row (v4.3 --retry-failed machinery).
99
+ // Spread-guarded so a normal launch's transport call stays byte-identical.
100
+ ...(opts.retryOfWaveId ? { retryOfWaveId: opts.retryOfWaveId } : {}),
97
101
  models: opts.models.join(','),
98
102
  prompt: opts.prompt,
99
103
  promptMeta: { source: 'council-engine', file: null, chars: opts.prompt.length },
@@ -0,0 +1,74 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * @module council/run-retry-notes
5
+ * Pure note-builders for the SL-2 Stage-1 retry pass (split out of
6
+ * run-retry.js for the 300-line gate — same rationale as run-stage2.js
7
+ * splitting off run-stages.js, v4.4.1 Task 2). No I/O, no ctx: each function
8
+ * takes plain data and returns a still-dead note ready for
9
+ * `ctx.degrade.note(...)` (D5 final-failure granularity, spec §5). The heal
10
+ * note is built inline in run-retry.js's orchestrator (it is the one place
11
+ * that decides recovery, and stays small).
12
+ */
13
+
14
+ /** D-effect parity: still-dead leg notes reuse today's count phrasing, with the
15
+ * FIRST attempt's counts — the why carries the retry story (spec §5). */
16
+ const legEffect = (counts) =>
17
+ `${counts.reviewed} of ${counts.total} seats reviewed; `
18
+ + 'the run continues with the bench that did and will exit degraded (2)';
19
+
20
+ /** Wave-origin, retry wave died wholesale (D5 wave granularity). */
21
+ function waveStillDeadNote(w, unit) {
22
+ return { channel: 'dead-wave',
23
+ what: `Stage-1 wave ${w.waveId} (${(w.models || []).join(', ') || 'no models'}) produced NO legs`,
24
+ // Coordinator-review MINOR-7c: a falsy w.reason must not render as the
25
+ // literal string "undefined" in the why text.
26
+ why: `${w.reason || 'no reason recorded'}; the once-only retry wave also produced no legs`,
27
+ effect: 'Those seats are NOT in this council. The run continues with the bench that did '
28
+ + 'launch and will exit degraded (2)',
29
+ data: { waveId: w.waveId, models: w.models, reason: w.reason, retryWaveId: unit.waveId } };
30
+ }
31
+
32
+ /** Leg-origin, retry wave died wholesale (bench-batch case). */
33
+ function srcLegStillDeadNote(leg, unit, counts) {
34
+ const seat = leg.modelInput || leg.model;
35
+ return { channel: 'dead-leg', what: `seat ${seat} did not review`,
36
+ why: `the leg ended '${leg.status}'${leg.error ? `: ${leg.error}` : ''} with no usable output; `
37
+ + 'its once-only retry wave produced no legs',
38
+ effect: legEffect(counts),
39
+ data: { seat, status: leg.status, reason: leg.error || null, retryWaveId: unit.waveId } };
40
+ }
41
+
42
+ /** Either origin, the retry produced legs but THIS seat's retry leg died. */
43
+ function retryLegStillDeadNote(seat, ff, retryLeg, unit, counts) {
44
+ const why = ff && ff.class === 'wave'
45
+ ? `its first wave ${ff.waveId} produced no legs (${ff.reason}); `
46
+ + `its once-only retry leg ended '${retryLeg.status}' with no usable output`
47
+ : `the leg ended '${ff ? ff.status : 'unknown'}'${ff && ff.reason ? `: ${ff.reason}` : ''} `
48
+ + `with no usable output; its once-only retry also ended '${retryLeg.status}'`;
49
+ return { channel: 'dead-leg', what: `seat ${seat} did not review`, why,
50
+ effect: legEffect(counts),
51
+ data: { seat, status: retryLeg.status, reason: retryLeg.error || null,
52
+ firstFailure: ff, retryWaveId: unit.waveId } };
53
+ }
54
+
55
+ /**
56
+ * CRITICAL fix (coordinator review): a launched seat can be missing a leg
57
+ * record ENTIRELY from the retry response — a partial wave return (unit
58
+ * models [a,b], the wave comes back with only a's leg). This is distinct
59
+ * from `retryLegStillDeadNote` (the seat's retry leg came back but was
60
+ * unusable) — here there is no retry-attempt status/error to report at all,
61
+ * only the ORIGINAL first-failure fact plus the fact that nothing came back
62
+ * this time.
63
+ */
64
+ function missingLegStillDeadNote(seat, ff, unit, counts) {
65
+ const fact = ff && ff.class === 'wave'
66
+ ? `its first wave ${ff.waveId} produced no legs (${ff.reason})`
67
+ : `the leg ended '${ff ? ff.status : 'unknown'}'${ff && ff.reason ? `: ${ff.reason}` : ''} with no usable output`;
68
+ return { channel: 'dead-leg', what: `seat ${seat} did not review`,
69
+ why: `${fact}; its once-only retry produced no leg for this seat`,
70
+ effect: legEffect(counts),
71
+ data: { seat, status: null, reason: null, firstFailure: ff, retryWaveId: unit.waveId } };
72
+ }
73
+
74
+ module.exports = { waveStillDeadNote, srcLegStillDeadNote, retryLegStillDeadNote, missingLegStillDeadNote };