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.
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +42 -0
- package/README.md +1 -1
- package/docs/ROADMAP.md +40 -8
- package/docs/publishing.md +1 -1
- package/docs/usage.md +1 -1
- package/package.json +1 -1
- package/skills/second-opinion/MODEL-NOTES.md +182 -35
- package/src/council/run-launch.js +4 -0
- package/src/council/run-retry-notes.js +74 -0
- package/src/council/run-retry.js +280 -0
- package/src/council/run-stages.js +41 -11
- package/src/council/verdict.js +8 -1
- package/src/mcp-server.js +17 -2
- package/src/mcp-tools.js +5 -1
- package/src/utils/degrade.js +1 -0
- package/src/utils/remediation-hints.js +15 -11
- package/src/utils/update-notice.js +171 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "amicus",
|
|
3
|
-
"version": "4.6.
|
|
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
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.
|
|
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.
|
|
14
|
-
record of what landed, not a plan. **v4.
|
|
15
|
-
rev
|
|
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.
|
|
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 — "
|
|
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.
|
|
119
|
-
> is NOT executed as-written — v4.
|
|
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
|
|
package/docs/publishing.md
CHANGED
|
@@ -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`);
|
|
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
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "amicus",
|
|
3
|
-
"version": "4.6.
|
|
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-
|
|
8
|
-
|
|
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 (
|
|
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
|
-
-
|
|
148
|
-
|
|
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
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
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 corpus — 3 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 prefix — so 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;
|
|
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** —
|
|
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
|
|
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 };
|