amicus 2.0.0 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +108 -0
- package/README.md +16 -4
- package/bin/amicus.js +11 -93
- package/commands/council.md +14 -6
- package/package.json +1 -1
- package/skills/second-opinion/COUNCIL-DESIGN.md +68 -4
- package/skills/second-opinion/MODEL-NOTES.md +35 -2
- package/skills/second-opinion/SEAT-BRIEFS.md +190 -0
- package/skills/second-opinion/SKILL.md +78 -16
- package/skills/sidecar/SKILL.md +17 -14
- package/src/cli-handlers-abort.js +244 -0
- package/src/cli-handlers-doctor.js +13 -53
- package/src/cli-handlers-resume-continue.js +103 -0
- package/src/cli-handlers-run.js +5 -4
- package/src/cli-handlers.js +5 -120
- package/src/cli.js +20 -0
- package/src/mcp-server.js +8 -5
- package/src/mcp-tools.js +31 -21
- package/src/sidecar/continue.js +23 -8
- package/src/sidecar/resume.js +23 -8
- package/src/utils/abort-result.js +36 -0
- package/src/utils/cli-preflight.js +43 -0
- package/src/utils/doctor-mcp-checks.js +84 -0
- package/src/utils/input-validators.js +52 -1
- package/src/utils/mcp-discovery.js +51 -14
- package/src/utils/result-schema-version.js +14 -0
- package/src/utils/result-schema.js +10 -10
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "amicus",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
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,114 @@ All notable changes to Amicus are documented here. Format follows
|
|
|
5
5
|
|
|
6
6
|
## [Unreleased]
|
|
7
7
|
|
|
8
|
+
## [2.2.0] - 2026-07-14
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **Optional council elements** (second-opinion skill): four new opt-in behaviors, presented
|
|
13
|
+
together with Claude-in-the-council as a single numbered Stage-0 menu — all default OFF, enabled
|
|
14
|
+
only when the user names them, and the launch confirmation must enumerate what's on:
|
|
15
|
+
- **Critic seat** — one bench member swaps to a four-pass adversarial brief (adversarial pass,
|
|
16
|
+
edge-case hunt, consistency check, executability test), launched as a concurrent solo beside
|
|
17
|
+
the fanout wave (`role: "critic"`). Its findings enter the same anonymized bundle and are
|
|
18
|
+
peer-adjudicated like any other seat's — the council disciplines the critic.
|
|
19
|
+
- **Expert lenses** — each seat reviews through a distinct expert perspective (panel domain
|
|
20
|
+
scoped with the user: business/technical/customer/financial/custom). Lens runs always tally
|
|
21
|
+
`--no-ledger` and the report discloses the weakened cross-review anonymity.
|
|
22
|
+
- **Debate mode** — a new Stage 2.5 rebuttal round: Contested/Disputed findings go back to their
|
|
23
|
+
raisers to DEFEND / AMEND / WITHDRAW, disputing judges re-vote, then the final ledger-recorded
|
|
24
|
+
tally. Exactly one round; withdrawn findings are auto-denied and listed in the report.
|
|
25
|
+
- **Chair verdict scale** — the chair closes with 3–5 hard questions and a final parseable
|
|
26
|
+
`VERDICT: Ship it | Fix these first | Fundamental rethink` line, surfaced at the top of the
|
|
27
|
+
report.
|
|
28
|
+
- New `skills/second-opinion/SEAT-BRIEFS.md` — briefing boilerplate for the elements plus a
|
|
29
|
+
standard anti-sycophancy clause now required in **every** Stage-1 briefing. Critic and lens
|
|
30
|
+
methodologies adapted from the `/critic` and `/debate` agents in John Renaldi's product-kit
|
|
31
|
+
(MIT), with deliberate deviations documented (no findings quota; verdict moved to the chair).
|
|
32
|
+
- Zero engine changes: free-form `runStats[].role` labels, tally-input re-assembly, and the
|
|
33
|
+
existing `--no-ledger` flag cover all four elements.
|
|
34
|
+
|
|
35
|
+
### Changed
|
|
36
|
+
|
|
37
|
+
- `COUNCIL-DESIGN.md` gains §12 documenting the elements, their caveats (critic
|
|
38
|
+
self-identification in cross-review; lens anonymity/ledger trade-offs), and parallel panels as
|
|
39
|
+
future work. The `/council` command accepts pre-requested elements in its arguments.
|
|
40
|
+
- MODEL-NOTES seed: fold-back of the v2.2.0 verification council — claim-class dedup
|
|
41
|
+
adjudication limit, minimax debut (strong critic seat), qwen-coder debut.
|
|
42
|
+
|
|
43
|
+
### Fixed
|
|
44
|
+
|
|
45
|
+
- Resurrected both Windows e2e integration suites, silently dead since before the rebrand:
|
|
46
|
+
Node's `spawn()` cannot execute `node_modules/.bin` `.cmd` shims on Windows, so the Electron
|
|
47
|
+
toolbar suite (electron shim) and the OpenCode server test helper ENOENT'd without a visible
|
|
48
|
+
error. The helper now uses the shared `ensureNodeModulesBinInPath()` (which adds the platform
|
|
49
|
+
`opencode.exe` dirs to PATH) and the toolbar suite spawns the real binary via
|
|
50
|
+
`require('electron')`. Also refreshed two stale pins the dead suites never caught: the wave
|
|
51
|
+
document's `schemaVersion` (now pinned to the shared `SCHEMA_VERSION` constant instead of a
|
|
52
|
+
literal `1`) and the pre-rebrand `Sidecar` toolbar brand assertion (now `Amicus`).
|
|
53
|
+
|
|
54
|
+
## [2.1.0] - 2026-07-04
|
|
55
|
+
|
|
56
|
+
### Added
|
|
57
|
+
|
|
58
|
+
- `--json` on `resume`, `continue`, and `abort`. `amicus resume <id> --no-ui --json` and
|
|
59
|
+
`amicus continue <id> --prompt "..." --no-ui --json` emit the same versioned run document as
|
|
60
|
+
`start --json` (a `continue` run's document carries the new continuation task id, not the old
|
|
61
|
+
one). `amicus abort <id|--all> --json` emits a new `type: 'abort'` document
|
|
62
|
+
(`{ schemaVersion, type, ok, scope, taskId, aborted, count }`) covering single-session, wave, and
|
|
63
|
+
`--all` aborts, success and failure alike — stdout carries exactly one parseable document either
|
|
64
|
+
way, and non-`--json` human output is unchanged (byte-identical pinned messages still hold).
|
|
65
|
+
- Did-you-mean suggestions for unknown CLI commands: a near-miss typo like `amicus contnue` now
|
|
66
|
+
prints `Unknown command: contnue` followed by `Did you mean: continue` on stderr (still exits 1).
|
|
67
|
+
Suggestions are capped at 3 and only shown within edit-distance 2 of a known command; unrelated
|
|
68
|
+
garbage input gets no suggestion.
|
|
69
|
+
|
|
70
|
+
### Changed
|
|
71
|
+
|
|
72
|
+
- Agent-facing polling guidance now recommends `amicus_wait` first across every headless-flow
|
|
73
|
+
reminder, tool description, and guide section (MCP system-reminders, `amicus_start`/`amicus_resume`/
|
|
74
|
+
`amicus_continue`/`amicus_fanout` descriptions, `amicus_guide`'s headless workflow, and the
|
|
75
|
+
`second-opinion`/`sidecar` skill docs) — one blocking call replaces the sleep+status poll loop.
|
|
76
|
+
`sleep 25` + `amicus_status` polling remains documented as the explicit fallback for clients
|
|
77
|
+
without the `amicus_wait` tool; it is never presented as the only mechanism.
|
|
78
|
+
|
|
79
|
+
### Fixed
|
|
80
|
+
|
|
81
|
+
- `amicus doctor`'s MCP registration check no longer false-negatives on a healthy Claude Code
|
|
82
|
+
registration. The check's only signal was `discoverClaudeCodeMcps()`, which always strips every
|
|
83
|
+
`amicus`/`sidecar`-shaped entry as its own recursive-spawn guard — so the check could never see
|
|
84
|
+
its own registration and warned "not registered in Claude Code" even when one existed. The check
|
|
85
|
+
now reads the same config sources directly (unstripped) to answer "is amicus registered?".
|
|
86
|
+
|
|
87
|
+
### CI / Security
|
|
88
|
+
|
|
89
|
+
- `council-review.yml`: both fanout legs (review wave and synthesis) now request
|
|
90
|
+
`--summary-length normal` instead of `verbose`. `--summary-length` only shapes the prompt (there is
|
|
91
|
+
no engine-side output-token cap), so `verbose` was asking every model in the wave — on a paid CI
|
|
92
|
+
key — for maximally long output on every PR.
|
|
93
|
+
- `council-review.yml`: the model-to-model handoff from the review wave into the synthesis leg is
|
|
94
|
+
now neutralized. The synthesis briefing previously concatenated raw model review text
|
|
95
|
+
(`reviews.md`) straight into another model's prompt with no sanitization; it now runs the same
|
|
96
|
+
neutralization (byte-identical sed rules, duplicated into the synthesis step's own shell) used on
|
|
97
|
+
the human-facing PR comment, and wraps the reviews in an explicit untrusted-data block before
|
|
98
|
+
handing them to the synthesis model. The comment path itself is unchanged.
|
|
99
|
+
- `ci.yml`: the `quality` job now runs [actionlint](https://github.com/rhysd/actionlint) (pinned to
|
|
100
|
+
v1.7.7) over `.github/workflows/`, which also shellchecks every `run:` block via ubuntu-latest's
|
|
101
|
+
preinstalled shellcheck. Verified locally with the actionlint + shellcheck Windows binaries before
|
|
102
|
+
landing; both are clean against all 5 workflows (0 findings), so no suppression config was needed.
|
|
103
|
+
|
|
104
|
+
### Documentation
|
|
105
|
+
|
|
106
|
+
- Corrected the `--agent` default docs in `skills/sidecar/SKILL.md`: the flag defaults to `Chat`
|
|
107
|
+
only in interactive mode — headless (`--no-ui`) runs default to `Build`, since `chat` stalls
|
|
108
|
+
without user interaction. The file previously claimed an unqualified "defaults to Chat" in
|
|
109
|
+
several spots while also correctly documenting the headless-`Build` default elsewhere,
|
|
110
|
+
contradicting itself; `docs/usage.md` was already correct and unchanged.
|
|
111
|
+
- Corrected `commands/council.md`'s description of the council pipeline order: `amicus council
|
|
112
|
+
validate` runs per-leg during Stage 1 (independent reviews), and `amicus council tally` runs
|
|
113
|
+
after Stage 2 (cross-review) and before Stage 3 (chair synthesis) — not, as previously worded,
|
|
114
|
+
both after all three review waves.
|
|
115
|
+
|
|
8
116
|
## [2.0.0] - 2026-07-03
|
|
9
117
|
|
|
10
118
|
Amicus's first major release: the **`sidecar*` shim removal** (#19). v1.x carried a full
|
package/README.md
CHANGED
|
@@ -53,6 +53,10 @@ Claude is the orchestrator. The council and chat skills run *on top of* the engi
|
|
|
53
53
|
|
|
54
54
|

|
|
55
55
|
|
|
56
|
+
The council skill in one picture — independent review, before cross-review or the verdict, with Claude Opus seated among the models it's judging:
|
|
57
|
+
|
|
58
|
+

|
|
59
|
+
|
|
56
60
|
---
|
|
57
61
|
|
|
58
62
|
## Quick start
|
|
@@ -209,11 +213,19 @@ Everything you need before your first run, and what's optional.
|
|
|
209
213
|
findings-by-tier, cost — no chair prose). This is the default artifact handed to the user.
|
|
210
214
|
- For an **editable source**, the accepted edits land in `<stem>-reviewed.<ext>` next to the original.
|
|
211
215
|
|
|
212
|
-
**
|
|
216
|
+
**Optional council elements** (v2.2.0, all default off): five opt-in behaviors, offered once as a menu at launch — nothing turns on unless you name it, and the confirmation lists exactly what's on.
|
|
217
|
+
|
|
218
|
+
- **Critic seat** — one reviewer swaps to a four-pass adversarial brief (adversarial pass, edge-case hunt, consistency check, executability test). Its findings enter the same anonymized bundle as everyone else's, so the bench disciplines the critic: manufactured negativity lands Disputed and dies in the tally.
|
|
219
|
+
- **Expert lenses** — each reviewer takes a distinct expert perspective; you pick the panel domain (business, technical, customer, financial, or custom). Lens runs never feed the reliability ledger, and the report discloses the weakened cross-review anonymity.
|
|
220
|
+
- **Debate mode** — after cross-review, every Contested or Disputed finding goes back to its raiser to **defend, amend, or withdraw**, and the disputing judges re-vote. Exactly one rebuttal round, then the final tally.
|
|
221
|
+
- **Chair verdict scale** — the chair closes with 3–5 hard questions and one parseable line: `VERDICT: Ship it | Fix these first | Fundamental rethink`.
|
|
222
|
+
- **Claude in the council** — Claude adds its own fresh review to the bundle so the bench ranks and adjudicates it. Claude is *judged* but never votes or chairs, so the verdict stays independent.
|
|
223
|
+
|
|
224
|
+
The critic and lens methodologies are adapted from the `/critic` and `/debate` agents in [John Renaldi's product-kit](https://github.com/jrenaldi79/plugin-marketplace) (MIT); the briefing boilerplate lives in [`skills/second-opinion/SEAT-BRIEFS.md`](./skills/second-opinion/SEAT-BRIEFS.md).
|
|
213
225
|
|
|
214
|
-
**Cost is disclosed up front.** Before any model launches, you see the run shape — for example:
|
|
226
|
+
**Cost is disclosed up front.** Before any model launches, you see the run shape — including any enabled optional elements — for example:
|
|
215
227
|
|
|
216
|
-
> This run uses 3 council models across 2 fanout waves + 1 chair call (~7
|
|
228
|
+
> This run uses 3 council models across 2 fanout waves + 1 chair call, with critic seat + debate mode ON (~7 base runs + up to 6 rebuttal calls).
|
|
217
229
|
|
|
218
230
|
Then the council waits for your confirmation.
|
|
219
231
|
|
|
@@ -311,7 +323,7 @@ $ amicus status demo123 --json
|
|
|
311
323
|
"taskId": "demo123",
|
|
312
324
|
"status": "complete",
|
|
313
325
|
"elapsed": "5m 0s",
|
|
314
|
-
"version": "2.
|
|
326
|
+
"version": "2.2.0",
|
|
315
327
|
"model": "google/gemini-2.5-flash",
|
|
316
328
|
"phase": "terminal"
|
|
317
329
|
}
|
package/bin/amicus.js
CHANGED
|
@@ -11,12 +11,12 @@
|
|
|
11
11
|
const { loadCredentials } = require('../src/utils/env-loader');
|
|
12
12
|
loadCredentials();
|
|
13
13
|
|
|
14
|
-
const { parseArgs, getUsage } = require('../src/cli');
|
|
15
|
-
const { validateTaskId } = require('../src/utils/validators');
|
|
16
|
-
const { resolveModelFromArgs, validateFallbackModel } = require('../src/utils/start-helpers');
|
|
14
|
+
const { parseArgs, getUsage, getCommandNames } = require('../src/cli');
|
|
17
15
|
const { handleSetup, handleAbort, handleUpdate, handleMcp, handleKey } = require('../src/cli-handlers');
|
|
18
16
|
const { handleStart, handleFanout, handleRead } = require('../src/cli-handlers-run');
|
|
17
|
+
const { handleResume, handleContinue } = require('../src/cli-handlers-resume-continue');
|
|
19
18
|
const { isOneShotCommand, armExitWatchdog } = require('../src/utils/lifecycle');
|
|
19
|
+
const { suggestCommand } = require('../src/utils/input-validators');
|
|
20
20
|
const { logger } = require('../src/utils/logger');
|
|
21
21
|
|
|
22
22
|
const VERSION = require('../package.json').version;
|
|
@@ -124,7 +124,7 @@ async function main() {
|
|
|
124
124
|
await handleKey(args);
|
|
125
125
|
break;
|
|
126
126
|
case 'abort':
|
|
127
|
-
await handleAbort(args);
|
|
127
|
+
exitCode = await handleAbort(args);
|
|
128
128
|
break;
|
|
129
129
|
case 'mcp':
|
|
130
130
|
await handleMcp();
|
|
@@ -132,10 +132,16 @@ async function main() {
|
|
|
132
132
|
case 'update':
|
|
133
133
|
await handleUpdate();
|
|
134
134
|
break;
|
|
135
|
-
default:
|
|
135
|
+
default: {
|
|
136
136
|
console.error(`Unknown command: ${command}`);
|
|
137
|
+
// suggestCommand honors a cap-3 contract (up to 3 candidates, closest
|
|
138
|
+
// first) — print all of them, not just the closest, matching the
|
|
139
|
+
// join precedent in src/cli-handlers.js.
|
|
140
|
+
const candidates = suggestCommand(command, getCommandNames());
|
|
141
|
+
if (candidates.length > 0) { console.error(`Did you mean: ${candidates.join(', ')}`); }
|
|
137
142
|
console.log(getUsage());
|
|
138
143
|
process.exit(1);
|
|
144
|
+
}
|
|
139
145
|
}
|
|
140
146
|
} catch (err) {
|
|
141
147
|
console.error(`Error: ${err.message}`);
|
|
@@ -166,94 +172,6 @@ async function handleList(args) {
|
|
|
166
172
|
});
|
|
167
173
|
}
|
|
168
174
|
|
|
169
|
-
/**
|
|
170
|
-
* Handle 'sidecar resume' command
|
|
171
|
-
* Spec Reference: §4.3
|
|
172
|
-
*/
|
|
173
|
-
async function handleResume(args) {
|
|
174
|
-
const taskId = args._[1];
|
|
175
|
-
|
|
176
|
-
if (!taskId) {
|
|
177
|
-
console.error('Error: task_id is required for resume');
|
|
178
|
-
console.error('Usage: amicus resume <task_id>');
|
|
179
|
-
process.exit(1);
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
const taskIdCheck = validateTaskId(taskId);
|
|
183
|
-
if (!taskIdCheck.valid) {
|
|
184
|
-
console.error(taskIdCheck.error);
|
|
185
|
-
process.exit(1);
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
const { resumeAmicus } = require('../src/index');
|
|
189
|
-
|
|
190
|
-
return await resumeAmicus({
|
|
191
|
-
taskId,
|
|
192
|
-
project: args.cwd,
|
|
193
|
-
headless: args['no-ui'],
|
|
194
|
-
timeout: args.timeout
|
|
195
|
-
});
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
/**
|
|
199
|
-
* Handle 'sidecar continue' command
|
|
200
|
-
* Spec Reference: §4.4
|
|
201
|
-
*/
|
|
202
|
-
async function handleContinue(args) {
|
|
203
|
-
const taskId = args._[1];
|
|
204
|
-
|
|
205
|
-
if (!taskId) {
|
|
206
|
-
console.error('Error: task_id is required for continue');
|
|
207
|
-
console.error('Usage: amicus continue <task_id> --prompt "..."');
|
|
208
|
-
process.exit(1);
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
const taskIdCheck = validateTaskId(taskId);
|
|
212
|
-
if (!taskIdCheck.valid) {
|
|
213
|
-
console.error(taskIdCheck.error);
|
|
214
|
-
process.exit(1);
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
// BL-1: accept --prompt-file (XOR --prompt) so the MCP handler can pass a long
|
|
218
|
-
// follow-up prompt via file, dodging the ~32KB Windows command-line cap.
|
|
219
|
-
if (args['prompt-file'] !== undefined) {
|
|
220
|
-
const { resolvePromptSource } = require('../src/utils/prompt-source');
|
|
221
|
-
const promptRes = resolvePromptSource(args);
|
|
222
|
-
if (promptRes.error) {
|
|
223
|
-
console.error(promptRes.error);
|
|
224
|
-
process.exit(1);
|
|
225
|
-
}
|
|
226
|
-
args.prompt = promptRes.prompt;
|
|
227
|
-
delete args['prompt-file'];
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
if (!args.prompt && !args.briefing) {
|
|
231
|
-
console.error('Error: --prompt is required for continue');
|
|
232
|
-
process.exit(1);
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
// F5: an explicitly passed --model gets the same resolution+validation as start.
|
|
236
|
-
if (args.model !== undefined) {
|
|
237
|
-
const { model, alias } = resolveModelFromArgs(args);
|
|
238
|
-
args.model = model;
|
|
239
|
-
args.model = await validateFallbackModel(args, alias);
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
const { continueAmicus } = require('../src/index');
|
|
243
|
-
|
|
244
|
-
return await continueAmicus({
|
|
245
|
-
taskId,
|
|
246
|
-
newTaskId: args['task-id'],
|
|
247
|
-
briefing: args.prompt || args.briefing,
|
|
248
|
-
model: args.model,
|
|
249
|
-
project: args.cwd,
|
|
250
|
-
contextTurns: args['context-turns'],
|
|
251
|
-
contextMaxTokens: args['context-max-tokens'],
|
|
252
|
-
headless: args['no-ui'],
|
|
253
|
-
timeout: args.timeout
|
|
254
|
-
});
|
|
255
|
-
}
|
|
256
|
-
|
|
257
175
|
// Run main
|
|
258
176
|
main().catch(err => {
|
|
259
177
|
console.error(`Fatal error: ${err.message}`);
|
package/commands/council.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
description: Run a structured multi-model LLM council review of the given material — wraps the second-opinion skill (independent reviews → anonymous cross-review → non-Claude chair verdict → accept/deny decisions).
|
|
3
|
-
argument-hint: [material, path, or URL] [analysis request + criteria]
|
|
3
|
+
argument-hint: [material, path, or URL] [analysis request + criteria] [optional elements — e.g. "with a critic seat", "debate mode", "expert lenses", "chair verdict scale"]
|
|
4
4
|
disable-model-invocation: true
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -17,8 +17,16 @@ the **analysis request**, and the **criteria**. If any of the three is missing o
|
|
|
17
17
|
ambiguous, ask for it before launching any model (the skill's Stage 0 covers this —
|
|
18
18
|
don't re-ask for what is already present).
|
|
19
19
|
|
|
20
|
-
Then follow the second-opinion skill end to end: Stage 0
|
|
21
|
-
setup, council selection with a cost estimate
|
|
22
|
-
|
|
23
|
-
`amicus council
|
|
24
|
-
|
|
20
|
+
Then follow the second-opinion skill end to end, in pipeline order: Stage 0
|
|
21
|
+
intake/prep and run-folder setup, then council selection with a cost estimate
|
|
22
|
+
and explicit user confirmation; Stage 1 independent reviews, running
|
|
23
|
+
`amicus council validate` on each leg's findings block as it lands; Stage 2
|
|
24
|
+
cross-review, followed by `amicus council tally` once cross-review settles;
|
|
25
|
+
Stage 3 council-chair synthesis; Stage 4 the accept/deny decision pass; and
|
|
26
|
+
Stage 5, which runs `amicus council verdict` to write the final `verdict.json`.
|
|
27
|
+
|
|
28
|
+
The user may also name **optional council elements** in the arguments (critic seat,
|
|
29
|
+
expert lenses, debate mode, verdict scale, Claude in the council). All elements
|
|
30
|
+
default OFF; the skill's Stage-0 menu is the single opt-in point. If the user named
|
|
31
|
+
elements here, carry them into Stage 0 as pre-requested — confirm them back by name
|
|
32
|
+
instead of re-asking — and never enable an element the user did not explicitly name.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "amicus",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
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": [
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# Second Opinion v3 — "LLM Council" Design
|
|
2
2
|
|
|
3
3
|
_Status: implemented (v3). v2 (2026-06-03) added the council mechanics; v3 (2026-06-10) swapped the
|
|
4
|
-
transport onto the Amicus fanout/JSON engine primitives.
|
|
5
|
-
(`V2-COUNCIL-DESIGN.md`, deleted at v3)._
|
|
4
|
+
transport onto the Amicus fanout/JSON engine primitives; v3.1 (2026-07-14) added the optional
|
|
5
|
+
council elements (§12). v2 history lives in git (`V2-COUNCIL-DESIGN.md`, deleted at v3)._
|
|
6
6
|
_Design for `SKILL.md` and `MODEL-NOTES.md` of the `second-opinion` skill._
|
|
7
7
|
|
|
8
8
|
## 1. Intent
|
|
@@ -224,6 +224,70 @@ The append-only `council-ledger.jsonl` (consumed via `amicus council stats`) is
|
|
|
224
224
|
four qualitative tiers, if tiers prove too coarse in practice.
|
|
225
225
|
|
|
226
226
|
## 11. Implementation surface
|
|
227
|
-
- `SKILL.md` — the Stage 0–6 council flow on the v3 transport (WS-3: findings contract, tally assembly recipe, `amicus council tally/stats`, `verdict.json`, ledger auto-append).
|
|
227
|
+
- `SKILL.md` — the Stage 0–6 council flow on the v3 transport (WS-3: findings contract, tally assembly recipe, `amicus council tally/stats`, `verdict.json`, ledger auto-append). v3.1 adds the Stage-0 optional-elements menu, the Stage-1 critic/lens launch blocks, Stage 2.5, and the chair verdict-scale addendum.
|
|
228
|
+
- `SEAT-BRIEFS.md` — v3.1 briefing boilerplate for the optional elements + the standard anti-sycophancy clause.
|
|
228
229
|
- `MODEL-NOTES.md` — qualitative per-model quirks, structural-conformance notes, cost guardrail, Stage-2 briefing tips. Quantitative reliability data now generated by `amicus council stats` (ledger). Engine workarounds that F1/F2/F4 made obsolete were pruned at v3.
|
|
229
|
-
- `src/council/` — the deterministic helpers (`findings.js`, `tally.js`, `verdict.js`, `ledger.js`). No other files.
|
|
230
|
+
- `src/council/` — the deterministic helpers (`findings.js`, `tally.js`, `verdict.js`, `ledger.js`). No other files. **v3.1 required zero engine changes**: `runStats[].role` labels are free-form, the rebuttal round is a tally-input re-assembly, and `--no-ledger` already existed.
|
|
231
|
+
|
|
232
|
+
## 12. Optional council elements (v3.1)
|
|
233
|
+
|
|
234
|
+
The `/critic` and `/debate` behaviors from John Renaldi's product-kit plugin (MIT — the
|
|
235
|
+
elite-advisor and expert-debate-facilitator agents), grafted onto the council. Both source
|
|
236
|
+
agents are single-model theater: one model playing an adversarial reviewer or a panel of
|
|
237
|
+
disagreeing experts, with no external check on manufactured negativity or fake disagreement.
|
|
238
|
+
The council supplies exactly that check — independent models and deterministic peer-validated
|
|
239
|
+
tiers — so the methodologies port over as *optional elements* whose output is disciplined by
|
|
240
|
+
Stage-2 adjudication.
|
|
241
|
+
|
|
242
|
+
**Opt-in contract.** All elements default OFF. They are presented once, as a single numbered
|
|
243
|
+
menu at Stage 0 (after bench/chair selection, before launch confirmation); the user must name
|
|
244
|
+
an element to enable it — silence means off, and the launch confirmation enumerates enabled
|
|
245
|
+
elements by name. "Claude in the council" (§5.4, semantics unchanged) is presented as one item
|
|
246
|
+
of the same menu so there is exactly one opt-in point per run. Elements compose freely except
|
|
247
|
+
critic + lenses on one seat (the critic takes one seat; lenses take the rest).
|
|
248
|
+
|
|
249
|
+
### 12.1 Critic seat
|
|
250
|
+
One bench member swaps its standard brief for an adversarial four-pass brief (adversarial
|
|
251
|
+
pass, edge-case hunt, consistency check, executability test — `SEAT-BRIEFS.md`). Launches as
|
|
252
|
+
a concurrent solo run (the red-team variant pattern); same findings contract; `role: "critic"`.
|
|
253
|
+
Judges are never told the seat exists. Two deliberate deviations from the source agent: the
|
|
254
|
+
minimum-10-findings quota is dropped (quotas force invented findings, which waste the bench's
|
|
255
|
+
adjudication capital — the anti-padding rule replaces it), and the hard questions +
|
|
256
|
+
Ship/Fix/Rethink verdict moved to the chair (§12.4). Known cost: the critic model can
|
|
257
|
+
self-identify its review in the Stage-2 bundle by shape, weakening self-bias wash-out for that
|
|
258
|
+
one seat — disclosed in the report. A single-seat brief variant is judged acceptable to record
|
|
259
|
+
to the ledger (precedent: the red-team variant records normally).
|
|
260
|
+
|
|
261
|
+
### 12.2 Expert lenses
|
|
262
|
+
Each seat gets a distinct expert-perspective brief (panel domain scoped with the user:
|
|
263
|
+
business/technical/specialty/customer/financial/custom). All legs launch as concurrent solos
|
|
264
|
+
(no shared-prompt wave); lens↔model assignment is random and private; `role: "lens:<slug>"`.
|
|
265
|
+
Two standing caveats, both disclosed: (a) **anonymity leak** — every judge can spot its own
|
|
266
|
+
lens-flavored review, so self-bias wash-out is weakened bench-wide; (b) **ledger pollution** —
|
|
267
|
+
lens reviews are not comparable to standard reviews (street-cred and confirm-rate assume a
|
|
268
|
+
shared task), so lens-run tallies always pass `--no-ledger`. The bench-wide task change is what
|
|
269
|
+
separates lenses (no ledger) from the single-seat critic (ledger ok).
|
|
270
|
+
|
|
271
|
+
### 12.3 Debate mode (Stage 2.5 rebuttal round)
|
|
272
|
+
The debate agent's challenge/stress-test rounds, grounded in findings instead of persona
|
|
273
|
+
prose: the Stage-2 tally runs `--no-ledger` (provisional); every Contested/Disputed finding
|
|
274
|
+
goes back to its raiser (defense mini-wave — solo per raiser: DEFEND / AMEND / WITHDRAW), the
|
|
275
|
+
disputing judges re-vote on defended/amended findings (one shared fanout), and the final tally
|
|
276
|
+
runs with the ledger. Exactly one round — the source agent's open-ended rounds become a fixed
|
|
277
|
+
convergence step, or cost is unbounded. Withdrawn findings stay in `findings[]` and are
|
|
278
|
+
auto-recorded `denied` (never presented for user decision). Missing/unparseable rebuttal or
|
|
279
|
+
re-vote lines mean the original claim/verdict stands. No new decision vocabulary and no engine
|
|
280
|
+
changes: `buildVerdict` and the renderer see a normal tally record.
|
|
281
|
+
|
|
282
|
+
### 12.4 Chair verdict scale
|
|
283
|
+
A chair-packet addendum: the chair closes with 3–5 hard questions plus a final parseable
|
|
284
|
+
`VERDICT: Ship it | Fix these first | Fundamental rethink` line, surfaced verbatim at the top
|
|
285
|
+
of `report.md` and in chat. Gives the council the single overall call its tier counts never
|
|
286
|
+
provided. Possible later engine touch: an `overallVerdict` field in `verdict.json` + a
|
|
287
|
+
renderer line (not needed for the prose version).
|
|
288
|
+
|
|
289
|
+
### 12.5 Future work — parallel panels
|
|
290
|
+
The debate agent's parallel-panels + cross-panel synthesis maps to two full council runs over
|
|
291
|
+
different benches or lens-sets plus a super-chair synthesis of where the panels agree,
|
|
292
|
+
disagree, and what each missed. Deferred: cost doubles and the run-folder conventions need
|
|
293
|
+
namespacing. Revisit if lens runs prove valuable.
|
|
@@ -4,8 +4,8 @@ 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-
|
|
8
|
-
|
|
7
|
+
_Last updated: 2026-07-14 (v2.2.0 fold-back: v3.1 optional council elements verified live;
|
|
8
|
+
claim-class dedup adjudication limit; minimax and qwen-coder debut notes; see changelog)._
|
|
9
9
|
|
|
10
10
|
## Global operating rules (all models)
|
|
11
11
|
- **Council runs are headless by design** (autonomous batch work): `fanout` is headless by
|
|
@@ -54,6 +54,19 @@ injection, long-read failures, judge tool-wander; see changelog)._
|
|
|
54
54
|
no-tools preamble is now mandatory in SKILL.md Stage 2/3 — keep it verbatim.
|
|
55
55
|
- The tally input needs **all five keys** (`meta` incl. `meta.models`, `findings`, `adjudications`,
|
|
56
56
|
`rankings`, `runStats`) — see the SKILL.md Stage-2 recipe step 0.
|
|
57
|
+
- **Claim-class dedup glosses rationale errors.** When several reviews raise the same claim, judges
|
|
58
|
+
adjudicate the class ("same as A3 — agree") and skip verifying each finding's own rationale text:
|
|
59
|
+
a direction-inverted arithmetic detail inside an otherwise-correct finding drew unanimous agrees
|
|
60
|
+
despite an explicit "dispute material factual errors in the rationale" instruction. If
|
|
61
|
+
rationale-level precision matters, instruct judges to independently verify the numbers in each
|
|
62
|
+
finding; otherwise expect class-level adjudication and let the chair reconcile details (a chair
|
|
63
|
+
has caught and corrected such an error unprompted).
|
|
64
|
+
- **Optional council elements (v2.2.0) verified live:** critic seat (solo-alongside-fanout;
|
|
65
|
+
`role: "critic"` passes through `council tally` untouched), debate mode's nothing-to-debate path
|
|
66
|
+
(provisional `--no-ledger` tally → skip rebuttals → final ledger-recorded tally), and the chair
|
|
67
|
+
verdict scale (parseable `VERDICT:` line + hard questions) all behaved per SEAT-BRIEFS. **Debate
|
|
68
|
+
mode's defense/re-vote waves remain unexercised** — an all-Confirmed consensus run has no
|
|
69
|
+
rebuttal surface; exercise them on a contentious artifact before trusting that path blind.
|
|
57
70
|
|
|
58
71
|
## Per-model notes
|
|
59
72
|
|
|
@@ -102,6 +115,21 @@ injection, long-read failures, judge tool-wander; see changelog)._
|
|
|
102
115
|
### Claude (in-council, when toggle on)
|
|
103
116
|
- 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.
|
|
104
117
|
|
|
118
|
+
### minimax (`--model minimax` → via OpenRouter)
|
|
119
|
+
- Fast (~2 min review legs), cheap, `clean` findings-JSON conformance on debut.
|
|
120
|
+
- Took the **critic seat** brief exceptionally well: unanimously ranked #1 by its bench, full
|
|
121
|
+
coverage on a ground-truth test, zero padded findings under the anti-padding rule. A strong
|
|
122
|
+
default critic-seat candidate.
|
|
123
|
+
- **Quirks:** occasional CJK character intrusions mid-English prose (cosmetic; the findings JSON
|
|
124
|
+
is unaffected); can invert the direction of an arithmetic detail inside an otherwise-correct
|
|
125
|
+
rationale — see the claim-class-dedup tip in Stage-2 briefing tips.
|
|
126
|
+
|
|
127
|
+
### qwen-coder (`--model qwen-coder` → via OpenRouter; distinct from `qwen`)
|
|
128
|
+
- Very fast (16–22 s legs, review and judging alike), `clean` conformance, competent
|
|
129
|
+
core-blocker coverage on prose/PRD artifacts.
|
|
130
|
+
- Ranked last on its debut bench — misses the offline, interruption-handling, and
|
|
131
|
+
test-methodology gap classes stronger seats catch. Fine budget-bench filler; do not chair it.
|
|
132
|
+
|
|
105
133
|
### (others — add as used)
|
|
106
134
|
- Opus / o-series etc. are reachable via amicus **if their API keys are configured**. Add notes
|
|
107
135
|
here the first time each is used.
|
|
@@ -160,3 +188,8 @@ This section keeps only per-model **qualitative quirks** and **structural-confor
|
|
|
160
188
|
GUI-hangs-on-this-machine rule (resolved 2026-06-10; headless stays the council default by
|
|
161
189
|
design). Config path updated to `~/.config/amicus/.env`.
|
|
162
190
|
- **2026-07-02** — Folded back field lessons from runs 4-7 (AV-receiver, pork-shoulder, resume, novel ×2 councils): PowerShell `--models` quoting; current-date injection; long-read model selection; judge no-tools preamble; severity-inflation-justifies-dispute; five-keys tally schema; new Grok/Kimi/Mistral/Claude-in-council sections. Quantitative history stays in the ledger (`amicus council stats`).
|
|
191
|
+
- **2026-07-14 (v2.2.0)** — Optional council elements shipped and verified on a planted-flaw
|
|
192
|
+
ground-truth council (critic seat, debate mode nothing-to-debate path, chair verdict scale;
|
|
193
|
+
expert lenses defined but not yet field-run). New lessons: claim-class dedup glosses
|
|
194
|
+
rationale-level errors in Stage-2; minimax debut (strong critic seat, CJK-intrusion quirk);
|
|
195
|
+
qwen-coder debut (fast budget filler). Debate mode's defense/re-vote waves still unexercised.
|