the-high-council 0.7.7 → 0.7.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/.env.example +5 -0
  2. package/CONTRIBUTING.md +3 -3
  3. package/PERSONAS.md +4 -0
  4. package/README.md +166 -28
  5. package/TROUBLESHOOTING.md +22 -2
  6. package/chains/mock-tiered.json +43 -0
  7. package/chains/plan-daily-7.json +43 -0
  8. package/chains/plan-highest-7.json +45 -0
  9. package/chains/verify.json +1 -1
  10. package/package.json +4 -3
  11. package/schemas/report-v1.json +37 -4
  12. package/src/api.js +23 -11
  13. package/src/chain-lint.js +190 -6
  14. package/src/chain-name.js +18 -0
  15. package/src/chain.js +495 -105
  16. package/src/cli.js +294 -71
  17. package/src/context-files.js +47 -0
  18. package/src/cost.js +124 -8
  19. package/src/criteria-kinds.js +7 -1
  20. package/src/deep-dive.js +143 -0
  21. package/src/denied-models.js +19 -6
  22. package/src/dissent-digest.js +4 -0
  23. package/src/fence.js +28 -1
  24. package/src/mcp/server.js +140 -35
  25. package/src/outbound-scan.js +59 -0
  26. package/src/outcome.js +2 -1
  27. package/src/partial-deliverable.js +5 -0
  28. package/src/policy.js +6 -1
  29. package/src/pricing.json +74 -15
  30. package/src/providers.js +117 -1
  31. package/src/quote-check.js +27 -4
  32. package/src/rematch.js +45 -20
  33. package/src/report-shape.js +41 -2
  34. package/src/roles.js +126 -6
  35. package/src/run-state.js +4 -1
  36. package/src/run-status.js +7 -0
  37. package/src/secret-patterns.js +11 -6
  38. package/src/security-review.js +1 -1
  39. package/src/spans.js +25 -5
  40. package/src/stage-contract.js +6 -1
  41. package/src/terminal-safe.js +14 -0
  42. package/src/tools.js +8 -0
  43. package/src/ui/app.js +26 -22
  44. package/src/ui/server.js +40 -8
  45. package/src/verdict-diff.js +6 -1
  46. package/src/withdrawal-ledger.js +9 -4
  47. package/types/index.d.ts +6 -1
  48. package/src/http-server.js +0 -349
package/.env.example CHANGED
@@ -16,3 +16,8 @@ ZAI_API_KEY=
16
16
  # resumes with a higher ceiling. Unset means $7. Use --max-usd none to run
17
17
  # without a ceiling.
18
18
  MAX_USD_PER_RUN=7
19
+
20
+ # Optional settings (README "Setup" lists them all): COUNCIL_WORKDIR and
21
+ # COUNCIL_MAX_USD_LIMIT for the MCP server, COUNCIL_ALLOW_LOOPBACK_KEY_HOST=1
22
+ # for a local proxy in front of a keyed provider, OLLAMA_API_KEY,
23
+ # COUNCIL_PERSONAS_FILE, AUDIT_HMAC_KEY_FILE.
package/CONTRIBUTING.md CHANGED
@@ -14,9 +14,9 @@ discussion first.
14
14
  in `node --test`, real calls are opt-in and cost real money.
15
15
 
16
16
  2. **A new chain config** (`chains/*.json`). A chain is data, not code - it names which seats run
17
- which stages. `council doctor` validates any chain you add against every shipped-provider's key
18
- presence and prices it worst-case with zero network calls; run that against your new file
19
- before opening a PR. Look at `chains/plan-debate.json` or `chains/verify.json` as a starting
17
+ which stages. `council doctor --chain chains/<yours>.json` lints it (the same rules every run
18
+ applies, including the denied-model and `key-host` rules), and `council doctor` prices it
19
+ worst-case, both with zero network calls; run both against your new file before opening a PR. Look at `chains/plan-debate.json` or `chains/verify.json` as a starting
20
20
  shape depending on whether you want a debate-and-panel chain or a single-critic chain.
21
21
 
22
22
  3. **A new mock fixture** (`src/providers.js`'s `callMock`, exercised from `test/*.test.js`). If
package/PERSONAS.md CHANGED
@@ -24,6 +24,10 @@ from the same public-domain legend and is not itself claimed as anyone's tradema
24
24
  here is a secondary association in a reader's mind, not a legal one - worth having on the record,
25
25
  not worth revisiting a decision already made.
26
26
 
27
+ A `role.persona` key that is not in the set in use is sent as a bare name, with no voice
28
+ directive. `plan-premium-7` seats two such keys, `hypatia` and `avicenna`, next to the five
29
+ defaults: without a persona file of your own they reach the debate prompt as those names alone.
30
+
27
31
  **You can replace the whole set.** `loadPersonas()` in `src/personas.js` reads an operator-supplied
28
32
  JSON file (path via the `COUNCIL_PERSONAS_FILE` environment variable, or passed directly) and uses
29
33
  it in place of the default five entirely - nothing in this repo needs editing to do that. A
package/README.md CHANGED
@@ -1,9 +1,16 @@
1
1
  # The High Council
2
2
 
3
- A planning harness that runs one idea past several AI models from different labs, makes them
4
- argue about software engineering, architecture, specific features, roadmaps and philosophy, and
5
- stops at a checkable result at an estimated price, with a variable number of debate rounds, model
6
- seats and labs (except xAI) and variable token limits per response and model.
3
+ A planning harness that runs one idea past several AI models from different labs and makes
4
+ them argue about software engineering, architecture, specific features, roadmaps and
5
+ philosophy. It stops at a checkable result, at a price estimated before you spend anything.
6
+ You choose the number of debate rounds, the seats and labs (any lab except xAI), and the token
7
+ limit for each model's replies.
8
+
9
+ We recommend our own chains: `cheap-7-v2`, `plan-premium-7` and `plan-highest-7` (the top
10
+ models, GPT-6 Astra, Claude Opus 5.5, DeepSeek V4 Pro
11
+ and GLM-5.3, write the alternative
12
+ architectures and are the only seats that vote; cheaper seats write the proposals and the debate). You can also edit a chain to suit yourself, or run every seat on
13
+ your own machine with `local-ollama`.
7
14
 
8
15
  See it work right now - no keys, no setup, no cost:
9
16
 
@@ -15,17 +22,48 @@ amended, a panel that splits in round 1 and signs off in round 2, and the handof
15
22
  model reply in it is written in advance; what is real is the code that runs the stages around
16
23
  them.
17
24
 
25
+ **What it costs.** You pay the model providers directly, with your own API keys. The demo,
26
+ `doctor`, `init` and the `mock` chains cost $0 and make no network call. `--dry-run` prints a
27
+ run's worst-case price before anything is called, and every run stops before any stage that could
28
+ take it past its spend cap ($7 unless you set `--max-usd`). Most runs cost less than the worst
29
+ case: a panel that signs off early skips the remaining rounds.
30
+
31
+ Three commands from nothing to a priced run of your own idea (no key needed until you drop
32
+ `--dry-run`; [Your first ten minutes](#your-first-ten-minutes) walks through them):
33
+
34
+ npx the-high-council demo # $0: every stage, scripted replies, no network
35
+ npx the-high-council init # writes tasks/my-first-task.md for your idea, plus a $0 mock run
36
+ npx the-high-council --task tasks/my-first-task.md --chain cheap-7-v2 --dry-run
37
+
38
+ **Which chain.** Worst-case prices as `council doctor` prints them, from the shipped price table
39
+ (prices as of 2026-09-06) and the default task-size estimate; a long task costs more.
40
+
41
+ | Chain | Who does what | Needs | Worst case |
42
+ |---|---|---|---|
43
+ | `cheap-7-v2` | Claude Sonnet 5 writes the plan; low-cost models from seven other labs review it, and all seven must sign off. Up to 7 rounds. | one OpenRouter key | $5.38 |
44
+ | `plan-premium-7` | A Claude Code session writes the plan; a seven-lab panel of larger models (GPT-6 Astra, Claude Fable 5.1, Gemini 3.8 Flash, Muse Spark 1.2, Qwen 3.8 Max, DeepSeek V4 Pro, GLM-5.3) proposes, debates and reviews. | OpenRouter key + a Claude Code session | $22.30 |
45
+ | `plan-highest-7` | Seven low-cost models propose and debate; four top models write whole architectures and are the only reviewers; one deep-dive seat checks the first draft against the task. **Untested with real models.** | OpenRouter key + a Claude Code session | $11.21 |
46
+ | `local-ollama` | Every seat on your own machine, through Ollama. | Ollama and the models pulled | $0 |
47
+
48
+ `plan-premium-7` and `plan-highest-7` cost more than the default cap, so give them a `--max-usd` at
49
+ or above their dry-run price. Their writer seats are [external](#quick-start-mcp): the run pauses
50
+ and a Claude Code session (or you) writes that stage, at no API cost. Nothing about any chain's
51
+ output quality has been measured.
52
+
18
53
  Add it to Claude Code as an MCP server:
19
54
 
20
55
  claude mcp add council -- npx -y the-high-council council --mcp
21
56
 
57
+ It is also listed in the official MCP Registry as `io.github.muad-yasin/the-high-council`, and
58
+ there is a one-file Claude Desktop bundle ([Quick start (MCP)](#quick-start-mcp)).
59
+
22
60
  Runs as an **MCP server** (so an agent like Claude Code can drive it) or as a **CLI**. Bring your
23
61
  own API keys. Nothing is resold, nothing is hosted for you, and your keys go only to the
24
62
  providers you choose, never to us.
25
63
 
26
64
  Run `npx the-high-council council doctor` to see which of your own keys are
27
65
  set, which shipped chains you can already run with them, and what each would cost - before
28
- spending anything.
66
+ spending anything. Where it falls short: [Known limits](#known-limits-stated-plainly).
29
67
 
30
68
  > **On what this does and doesn't claim.** This repo publishes the mechanism: the chains, the seat
31
69
  > rosters, the stage order. It does not claim to produce better plans than a single good model
@@ -112,6 +150,10 @@ A run moves through fixed stages. Which stages fire depends on the chain you pic
112
150
  again, up to the chain's round cap.
113
151
  8. **Handoff** - a `HANDOFF.md` written for whoever executes the result.
114
152
 
153
+ Some chains add optional stages to this: whole alternative architectures written blind before
154
+ the skeleton, a deep-dive check of the first draft, a dispute stage that records unresolved
155
+ objections at the top of the plan, and a final security review.
156
+
115
157
  Every run writes a folder: the deliverable, `BOARD.md` (the full debate - every post, every
116
158
  withdrawal), `HANDOFF.md`, a per-lab scoreboard, and the real token/cost accounting.
117
159
 
@@ -124,7 +166,7 @@ which are experimental, and how versions change: [docs/report-format.md](docs/re
124
166
 
125
167
  ```jsonc
126
168
  {
127
- "schemaVersion": 1, "runId": "...", "chain": "...", "passed": false, "maxUsd": 5,
169
+ "schemaVersion": 1, "runId": "...", "chain": "...", "passed": false, "maxUsd": 7,
128
170
  "criteria": [ "each acceptance criterion, as written before the debate" ],
129
171
  "questions": [ { "question": "...", "why": "...", "default": "..." } ], // null if the chain skipped them
130
172
  "proposals": [ { "id": "DEEPSEEK-1", "lab": "deepseek", "model": "...",
@@ -136,7 +178,11 @@ which are experimental, and how versions change: [docs/report-format.md](docs/re
136
178
  "posts": [ { "by": "deepseek", "on": "QWEN-1", "stance": "object|support|merge",
137
179
  "text": "...", "merge_with": "GLM-2" } ],
138
180
  "replies": [ { "id": "DEEPSEEK-1", "action": "keep|amend|withdraw",
139
- "text": "...", "replaced_by": "GLM-1" } ]
181
+ "text": "...", "replaced_by": "GLM-1" } ],
182
+ // Since 0.7.8 (experimental): posts and replies the harness rejected, counted per lab and
183
+ // reason (unknown_target, own_proposal, bad_stance, not_own_proposal, not_posted_on,
184
+ // bad_action, unreadable). [] when nothing was dropped.
185
+ "dropped": [ { "stage": "debate|replies", "by": "qwen", "reason": "unknown_target", "count": 1 } ]
140
186
  },
141
187
  // Only on chains with `alternatives: { enabled: true }`: one whole architecture per lab, written
142
188
  // blind before the skeleton, and the same post/reply board the proposals get.
@@ -189,6 +235,11 @@ those plus `text` and may carry more (an `amend` often brings a `how`). `replace
189
235
  when the action is `withdraw`. `proposals[]` likewise carries `withdrawn` / `amended` /
190
236
  `replaced_by` only when they apply. Read defensively: check for a field, do not assume it.
191
237
 
238
+ Chains with newer, opt-in stages add their own fields (`deep_dive`, `notQuorate`, `dispute`,
239
+ `security_review`, ...); [docs/report-format.md](docs/report-format.md) lists which are stable and
240
+ which experimental. With the majority guard on, a withdrawal that does not quote the argument it
241
+ concedes to carries `unargued: true` in `debate.replies[]` and its proposal stays for the builder.
242
+
192
243
  `signoff[].lab` is the seat's lab; `signoff[].provider` holds the same value under an older,
193
244
  misleading name and is deprecated (kept until the report format's version 2).
194
245
  `signoff[].objections` is why a seat declined, on the seat's own record. `signedOff: null` means
@@ -225,13 +276,30 @@ ones. Put only the keys your chosen chain needs in that `.env`, one `NAME=value`
225
276
  `DEEPSEEK_API_KEY` · `GROQ_API_KEY` · `TOGETHER_API_KEY` · `COHERE_API_KEY` ·
226
277
  `OPENROUTER_API_KEY` · `ZAI_API_KEY`
227
278
 
228
- xAI/Grok and Kimi/Moonshot are never seated, and neither is a router id (`openrouter/auto`, the
229
- Pareto Code router) that could route to them: chain-lint refuses such a chain and the run itself
230
- refuses such a seat, with no override. There is no `xai` provider.
279
+ xAI/Grok is never seated, and neither is a router id (`openrouter/auto`, the Pareto Code router)
280
+ that could route to it: chain-lint refuses such a chain and the run itself refuses such a seat,
281
+ with no override. There is no `xai` provider. Kimi/Moonshot models are not in any chain this
282
+ package ships, but you may seat one in a chain of your own.
231
283
 
232
284
  The CLI refuses to start if any seat in the chosen chain is missing its key, rather than failing
233
285
  halfway through a paid run. `ollama` (below) is the one exception - it needs no key at all.
234
286
 
287
+ A keyed seat sends its key only to its own provider's https API. A chain that points a keyed
288
+ seat's `baseUrl` anywhere else is refused before any call (see
289
+ [Local models](#local-models-ollama-lm-studio-)).
290
+
291
+ Other settings, all optional, read from the environment or `.env`:
292
+
293
+ | Variable | What it does |
294
+ |---|---|
295
+ | `MAX_USD_PER_RUN` | The default per-run spend cap (`7` when unset). `--max-usd` overrides it for one run. |
296
+ | `COUNCIL_WORKDIR` | MCP server only: the folder for `tasks/` and `runs/`, when the client starts the server somewhere else. |
297
+ | `COUNCIL_MAX_USD_LIMIT` | MCP server only: a cap the MCP client cannot raise or remove through `max_usd`. |
298
+ | `COUNCIL_ALLOW_LOOPBACK_KEY_HOST` | `1` lets a keyed seat use a loopback `baseUrl` (a local proxy in front of the provider). Nothing else. |
299
+ | `OLLAMA_API_KEY` | Sent to an `ollama` seat's server only if you set it. |
300
+ | `COUNCIL_PERSONAS_FILE` | Your own persona set for debate seats ([PERSONAS.md](PERSONAS.md)). |
301
+ | `AUDIT_HMAC_KEY` / `AUDIT_HMAC_KEY_FILE` | Signs the opt-in audit log (see [Privacy](#privacy)). |
302
+
235
303
  ### From source
236
304
 
237
305
  ```bash
@@ -279,6 +347,12 @@ If your local runner listens somewhere else (LM Studio, a different port, a remo
279
347
  { "provider": "ollama", "model": "mistral", "baseUrl": "http://localhost:1234/v1" }
280
348
  ```
281
349
 
350
+ Put a local or self-hosted server on an `ollama` seat, as above. A seat with a keyed provider
351
+ (`openrouter`, `openai`, ...) sends that provider's key to its `baseUrl`, so chain lint refuses
352
+ one whose `baseUrl` is anything but that provider's own https API address (`key-host`), and the
353
+ CLI lints before every run and every resume. For a local proxy in front of the provider, set
354
+ `COUNCIL_ALLOW_LOOPBACK_KEY_HOST=1` in your environment: it allows a loopback address, nothing else.
355
+
282
356
  A local seat prices at $0 in every estimate and run report - `dry_run` shows it as priced, not
283
357
  "unpriced," and it can never trip the spend cap. See `chains/local-ollama.json` for a full
284
358
  example chain with every seat local. As with every other seat in this project: BYOK is really
@@ -318,6 +392,16 @@ will not accidentally publish them.
318
392
  `verify` is the default when you name no chain: a panel of two labs, a hard two-round cap. It
319
393
  needs three keys (Anthropic, OpenAI and Google, one account each). With one OpenRouter key, start
320
394
  with `cheap-7-v2` instead; `council doctor` lists every chain that runs on the keys you have.
395
+ `--chain` takes a chain's name (`cheap-7-v2`), never a file path: a `chains/<name>.json` of your
396
+ own in the working directory is found by its name.
397
+
398
+ **If your task names files.** A task that names a file (`src/app.js`) without including its
399
+ content is stopped before any call (exit 9, `BLOCKED-ARTIFACTS.md`), because the seats would
400
+ otherwise plan against code they never saw. Put the real content in with
401
+ `council fence --task tasks/x.md --repo <path to your repo> src/app.js` (it appends each file,
402
+ fenced and labelled, and refuses to write if it finds a key), read the task file, then run.
403
+ If a name is only a location, pass `--allow-unfenced` for the whole task or
404
+ `--allow-unfenced app.js` for named files. Everything in the task file goes to every seat.
321
405
 
322
406
  ### Exit codes
323
407
 
@@ -327,7 +411,7 @@ Each outcome has its own code, so a script or CI job can branch on it:
327
411
  |---|---|
328
412
  | 0 | Finished: a deliverable and `report.json` were written. |
329
413
  | 1 | The chain failed lint, or an input is missing (no task file, a resume from the wrong directory). |
330
- | 2 | Usage error: a flag is missing its value or has an invalid one. |
414
+ | 2 | Usage error: a flag is missing its value or has an invalid one, `--chain` is not a chain name, a `--context` file is not a regular file or is over 2 MB, or `--rematch`/`--replay` of a run given `--criteria`. |
331
415
  | 3 | Paused at an external seat: answer `NEEDS-<stage>.md`, then `--resume`. |
332
416
  | 4 | Stopped at the per-run spend cap before the next stage was paid for; resume with a higher `--max-usd`. |
333
417
  | 5 | A provider key the chain needs is missing (degradable: set it and run again). |
@@ -336,7 +420,7 @@ Each outcome has its own code, so a script or CI job can branch on it:
336
420
  | 8 | Finished, but the final security review could not judge it (never a pass). |
337
421
  | 9 | Artifact gate: the task names files whose content it never includes (`BLOCKED-ARTIFACTS.md`). |
338
422
  | 10 | Preflight: a seat objected to the task description itself (`STOPPED-preflight.md`). |
339
- | 11 | PII gate (`--pii-gate hard-stop`): the input matches a PII shape or one of the key formats listed in `src/secret-patterns.js`. |
423
+ | 11 | Something in the input must not be sent: a prompt matches one of the key formats listed in `src/secret-patterns.js` (checked by default; `--allow-secret-shaped` overrides), or, under `--pii-gate hard-stop`, a PII shape. |
340
424
  | 12 | `policy.json` refused the chain. |
341
425
  | 13 | Another process is already running this run folder. |
342
426
  | 14 | The task file changed since the run started and `AMENDMENTS.md` does not cover it. |
@@ -377,14 +461,16 @@ than reporting the overspend afterwards.
377
461
 
378
462
  ```bash
379
463
  council --task tasks/x.md --max-usd 2 # this run stops at $2
380
- council --task tasks/x.md --max-usd none # no ceiling
464
+ council --task tasks/x.md --max-usd none # no ceiling (0 is refused: it used to mean this)
381
465
  export MAX_USD_PER_RUN=20 # change the default
382
466
  ```
383
467
 
384
468
  A run that hits the ceiling stops cleanly and writes `STOPPED-budget.md` saying what it spent, which
385
469
  stage it stopped at, and what that stage would have cost. Nothing is half-written: it produces no
386
- `deliverable.md` and no `report.json`, so a stopped run never reads as a finished one. Continue it
387
- with a higher ceiling - completed stages replay from disk and cost nothing the second time:
470
+ `deliverable.md` and no `report.json`, so a stopped run never reads as a finished one. What it did
471
+ get through is in `report-partial.json` and `BOARD-partial.md`
472
+ ([docs/report-format.md](docs/report-format.md)). Continue it with a higher ceiling - completed
473
+ stages replay from disk and cost nothing the second time:
388
474
 
389
475
  ```bash
390
476
  council --resume runs/<id> --max-usd 10
@@ -463,6 +549,17 @@ up in `claude mcp list` as `plugin:the-high-council:high-council`. Remove it wit
463
549
  local clone instead (`claude plugin marketplace add /path/to/clone`), the server runs from the
464
550
  clone itself, so run `npm install` in it first.
465
551
 
552
+ **Claude Desktop:** download `the-high-council-<version>.mcpb` from the
553
+ [GitHub Releases](https://github.com/muad-yasin/the-high-council-mcp/releases) page (its SHA-256
554
+ is next to it) and open it. Claude Desktop shows a settings form: a council folder for tasks and
555
+ runs, a per-run spend ceiling that Claude cannot raise or remove from a chat, and one optional
556
+ field per provider key (marked sensitive, so the app keeps them in the OS keychain). The bundle is unsigned. How it is built:
557
+ [mcpb/README.md](mcpb/README.md).
558
+
559
+ **MCP Registry:** the server is listed in the official registry as
560
+ `io.github.muad-yasin/the-high-council` (npm package, stdio). A client that installs from the
561
+ registry runs the same `npx` command as above.
562
+
466
563
  Registering with a client other than Claude Code (DeepSeek Harness, OpenHands, Cline, goose,
467
564
  Continue): [docs/mcp-clients.md](docs/mcp-clients.md) has the real config for each.
468
565
 
@@ -472,6 +569,13 @@ own takes precedence over the bundled ones. In a git project, add `.env` (and `r
472
569
  ideas are private) to `.gitignore` before an agent commits everything; `council doctor` warns
473
570
  when `.env` is not ignored.
474
571
 
572
+ The server only works inside that directory. `dry_run` and `start_run` take a chain by name.
573
+ Every path `start_run` is given (`task`, `draft`, `context`, `from_run`, and each file inside a
574
+ `context` folder or `from_run` run folder) must resolve inside the working directory, after
575
+ symlinks, and must not be on the secret/credential denylist; outside `tasks/`, `runs/` and
576
+ `context/` a gitignored file is refused too. Set `COUNCIL_MAX_USD_LIMIT` in the server's
577
+ environment to cap what the client's `max_usd` can ask for.
578
+
475
579
  To run it by hand:
476
580
 
477
581
  ```bash
@@ -485,18 +589,18 @@ Then drive it with these tools:
485
589
  | `list_chains` | Available chains with descriptions and worst-case price |
486
590
  | `write_task` | Write the request the harness plans against |
487
591
  | `dry_run` | Price a run before spending anything |
488
- | `start_run` | Start a run in the background (`max_usd` sets its ceiling) |
592
+ | `start_run` | Start a run in the background (`max_usd` sets its ceiling). `chain` is a chain name; `task`, `draft`, `context` and `from_run` must be inside the working directory |
489
593
  | `run_status` | Stage reached, panel verdicts, scoreboard, cost, budget remaining |
490
594
  | `spend_report` | What every run has cost across a window of days, plus `session_cost_today` (calendar-day, per-model breakdown), derived from disk |
491
595
  | `verdict_stats` | How the debate mechanism itself is doing, per chain and per lab: sign-off rate, rounds, objections, dropouts, cost/wall time, largest prompt files - derived from disk |
492
596
  | `metrics_report` | Descriptive telemetry only (never an evaluation or baseline): amendment rate, withdrawal rate, objection-follow-through rate, tool-call usage, consensus-induced-regression count - derived from disk. See [`docs/paid-comparison-run.md`](docs/paid-comparison-run.md) for what a *real* comparison against a single model would need - not built, not this metric |
493
- | `external_prompt` | The prompt a paused external stage is waiting on - **read it with this, not by opening the file**; the prompts are routinely tens of thousands of tokens and most clients silently truncate a file read |
597
+ | `external_prompt` | The prompt a paused external stage is waiting on - **read it with this, not by opening the file**; the prompts are routinely tens of thousands of tokens and most clients silently truncate a file read. `waiting` lists every stage the run waits on (a panel of external critics pauses together); pass `stage` for another one's prompt |
494
598
  | `prepare_stage_prompt` | Write a self-contained bundle for a paused stage, so a driving session doing other work at the same time can dispatch it to a fresh subagent instead of authoring it inline - see [`docs/dispatch-pattern.md`](docs/dispatch-pattern.md) |
495
- | `submit_stage` | Answer a paused stage and resume. Optional `claimed_by` records who's answering; a second submission for an already-answered stage no longer errors - it's kept as `<stage>.late.md` with a warning instead of being rejected |
599
+ | `submit_stage` | Answer a paused stage; the run resumes once every stage it waits on has an answer. Optional `claimed_by` records who's answering; a second submission for an already-answered stage no longer errors - it's kept as `<stage>.late.md` with a warning instead of being rejected |
496
600
  | `resume_run` | Resume a paused run, or raise `max_usd` on one the cap stopped |
497
- | `read_run_file` | Read any file from a run folder |
601
+ | `read_run_file` | Read any file from a run folder (`report-partial.json` for a run the cap stopped) |
498
602
  | `list_runs` | Past runs |
499
- | `plan_outline` | Outline pass |
603
+ | `plan_outline` | Section tree of a run's deliverable (or a `.md` file in the working directory) with word counts |
500
604
 
501
605
  **External vs. API-backed seats.** `{ "provider": "external" }` pauses a run at that seat so a
502
606
  Claude Code session on a flat-rate subscription plays it - free at the point of use, since the
@@ -509,13 +613,23 @@ for anyone with a subscription, since the project's cost story depends on it.
509
613
 
510
614
  ## Chains
511
615
 
512
- 49 chain configs live in `chains/`. Each one is plain JSON - the seat roster, which models fill
616
+ 52 chain configs live in `chains/`. Each one is plain JSON - the seat roster, which models fill
513
617
  which seat, the round cap, and whether proposals/debate/handoff stages run. They are meant to be
514
618
  copied and edited.
515
619
 
516
- A few worth knowing:
517
-
518
- - **`verify`** - two labs, two rounds. The recommended starting point.
620
+ The four recommended ones (`cheap-7-v2`, `plan-premium-7`, `plan-highest-7`, `local-ollama`) are
621
+ in the table at the top. A few more worth knowing:
622
+
623
+ - **`verify`** - two labs, two rounds. The default when you name no chain; needs Anthropic, OpenAI
624
+ and Google keys.
625
+ - **`plan-open-7`** - the `cheap-7-v2` panel, with a Claude Code session writing the plan instead
626
+ of a paid seat.
627
+ - **`plan-daily-7`** - `plan-highest-7`'s stages at a lower price, for planning one feature:
628
+ Claude Opus 5.5 on your Claude subscription (an external seat), GPT-6 Luna and DeepSeek V4 Pro
629
+ write the architectures and alone vote; seven low-cost labs propose and debate. Two Claude Code
630
+ sessions answer its external seats: Opus 5.5 every stage whose label contains `opus5.5-sub`
631
+ (including `-retry` and `-reask1`/`-reask2` forms), Sonnet 5 the writer stages. $1.90 worst case.
632
+ **Run once with real models (2026-09-28); nothing about it has been measured.**
519
633
  - **`cheap`** - small models throughout. For testing the harness itself, not for real work.
520
634
  - **`plan-debate`** - five labs propose blind, debate each other's proposals anonymised, then a
521
635
  blind panel grades the integrated draft.
@@ -544,6 +658,17 @@ Read a chain's `description` field before running it; they say what they cost yo
544
658
  source-level guard, not just an intention. A chain with no `role` set is byte-identical to
545
659
  before. **No efficacy claim**: this ships the mechanism, not evidence that it helps - see
546
660
  CHANGELOG.md's 0.6.0 entry.
661
+ - **`quorum: { "minHeard": N }`** - opt-in, unanimous chains only, set in no shipped chain. A
662
+ round's sign-off counts only when at least N reviewers gave a verdict (signed off or objected);
663
+ a round short of it is recorded as `notQuorate`, the run does not pass, and the loop stops.
664
+ - **Tiered councils (experimental, used by `plan-highest-7`, `plan-daily-7` and `mock-tiered`).**
665
+ `seats.alternatives` names who writes the whole alternative architectures, separately from the
666
+ proposers. `deep_dive` + `seats.deep_dive` add one non-voting seat with its own dollar cap
667
+ (`usd`, required) inside the run's cap. `majority_guard.enabled` shows each author every
668
+ argument once, with no lab name or count, and keeps a proposal whose withdrawal does not quote
669
+ the argument it gives in to. chain-lint refuses a tiered chain where a lab or model sits
670
+ both among the proposers and among the reviewers or architecture authors, or where the deep-dive seat shares a lab or model with a reviewer. See
671
+ CHANGELOG.md's 0.7.8 entry.
547
672
 
548
673
  ## How this was built
549
674
 
@@ -618,8 +743,16 @@ what each rule guards against and why. Copy the folders you want into your proje
618
743
  such a reply is recorded as `REASONING_EXHAUSTED` and is not retried: the seat abstains, which
619
744
  blocks unanimity and never counts as consent. Whether to change a chain's reasoning settings for it
620
745
  is a roster decision, not something the harness does for you.
621
- - Prices in `src/pricing.json` are hand-maintained list prices, last verified 2026-09-06. They are
622
- estimates, not invoices. Your provider's bill is the real number.
746
+ - Prices in `src/pricing.json` are hand-maintained list prices. Its `asOf` date (2026-09-06: the
747
+ oldest date every entry was last checked) is printed by `council doctor` and `--dry-run`, with a
748
+ warning once it is more than 60 days old. The spend cap and every estimate use these static
749
+ prices. They are estimates, not invoices. Your provider's bill is the real number.
750
+ - `plan-highest-7` has not been run with real models, and `plan-daily-7` has run once
751
+ (2026-09-28). None of the tiered councils' mechanisms (tiers, the deep-dive seat, the majority
752
+ guard) has been measured. Their dry-run prices are projections.
753
+ - Seats marked `external` (the writer seats in `plan-premium-7`, `plan-highest-7`,
754
+ `plan-daily-7` and `plan-open-7`, and the Opus 5.5 anchor seat in `plan-daily-7`) pause the run until someone answers them, and are $0 only because a Claude Code
755
+ session on a subscription writes them. Nothing checks who wrote the answer.
623
756
  - Chains with many labs and high round caps get expensive quickly. `plan-unanimous` at three rounds
624
757
  is fifteen critic calls; `plan-auto` runs several frontier models over multiple rounds. Price
625
758
  before you run.
@@ -632,6 +765,10 @@ what each rule guards against and why. Copy the folders you want into your proje
632
765
  which is the default, it does not detect a full rewrite**: anyone who can edit the file can
633
766
  recompute every hash. Set `AUDIT_HMAC_KEY_FILE` to a key kept outside the run folder if the log
634
767
  has to stand up to that.
768
+ - The outbound key scan matches **key shapes only**, the formats in `src/secret-patterns.js`; a
769
+ password written in prose is not detectable. Generic shapes (a password inside a URL or an
770
+ assignment) are checked in your inputs before the run; text the models write is checked only for
771
+ distinctive key formats.
635
772
 
636
773
  ## Privacy
637
774
 
@@ -669,8 +806,9 @@ hand, 2026-09-13, on the live site:
669
806
  - No custom widget on any page (`index.html`, `board.html`, `demo.html`) uses a `<div>` or
670
807
  `<span>` with a click handler in place of a real interactive element - checked directly in the
671
808
  page source, not inferred.
672
- - No image ships anywhere in `docs/` (checked directly - zero `<img>` tags across all three
673
- pages), so there is no informative image that could be missing alt text.
809
+ - The only image in `docs/` is the local logo (`logo-diamond.png`): the header copy carries alt
810
+ text, the faint background copy on `index.html` has an empty `alt=""` as decoration.
811
+ `test/landing-page.test.js` checks both on every page.
674
812
  - Primary body text (`#8d8a84`/`#b9b5ad`) against the page background (`#0a0a0b`) measures
675
813
  roughly 5.7:1 contrast by the WCAG relative-luminance formula, above the 4.5:1 AA threshold
676
814
  for normal text.
@@ -96,8 +96,28 @@ local chains as runnable because they need no key, not because the server is up.
96
96
  ### A run stopped with `STOPPED: per-run spend cap reached` (exit 4)
97
97
 
98
98
  The next stage's worst case would have crossed the cap. Nothing past the cap was spent, and no
99
- plan was written yet. `council --resume runs/<id> --max-usd <higher>` continues from where it
100
- stopped. The run tells you at the start when a chain's worst case is above your cap.
99
+ plan was written yet; what the run got through is in `report-partial.json` and `BOARD-partial.md`.
100
+ `council --resume runs/<id> --max-usd <higher>` continues from where it stopped. The run tells you
101
+ at the start when a chain's worst case is above your cap. `plan-premium-7` and `plan-highest-7`
102
+ are above the default $7 cap before they start: price them with `--dry-run` and pass a
103
+ `--max-usd` at or above that.
104
+
105
+ ### `BLOCKED: ... file(s) named but never fenced` (exit 9)
106
+
107
+ The task names a file (`src/app.js`, `package.json`) but does not include its content, so the
108
+ seats would plan against code they never saw. Nothing was called. Either append the real files
109
+ with `council fence --task tasks/x.md --repo <path> <file> ...` and read the task file before
110
+ running, or, if the names are only locations, run with `--allow-unfenced` (whole task) or
111
+ `--allow-unfenced a.js,b.ts` (those files). `BLOCKED-ARTIFACTS.md` in the run folder lists the
112
+ names it found.
113
+
114
+ ### `--chain` refused, or a chain lint error naming `key-host`
115
+
116
+ `--chain` takes a chain's name (`cheap-7-v2`, or `my-chain` for your own `chains/my-chain.json`),
117
+ never a path; anything else is a usage error (exit 2). `key-host` means a seat with a keyed
118
+ provider has a `baseUrl` that is not that provider's own https API, and its key would go there.
119
+ Move a local or self-hosted server to an `ollama` seat, or, for a local proxy in front of the
120
+ provider, set `COUNCIL_ALLOW_LOOPBACK_KEY_HOST=1` (loopback addresses only).
101
121
 
102
122
  ### `.env holds your API keys and git would commit it`
103
123
 
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "mock-tiered",
3
+ "description": "Offline. A tiered council at $0 (tiered councils, 2026-09-26): mass seats (seats.proposers) propose parts, debate them and post on the architectures; anchor seats (seats.alternatives) write the whole architectures and reply; the anchor panel (seats.critics) alone votes. The majority guard is on: authors see arguments without lab letters or counts, and a withdrawal that quotes no argument (mock-yield-unargued, mock-alt-withdraw) stays for the builder while one that does (mock-yield-argued) is honoured. A deep-dive seat reads the task in 1000-character chunks, once per focus entry, under its own cap and maxCalls, and the reviser answers its findings before the panel's first review.",
4
+ "maxRounds": 2,
5
+ "signoff": "unanimous",
6
+ "dispute": { "enabled": true, "stall_rounds": 2 },
7
+ "proposals": { "parts": 2, "maxTokens": 400 },
8
+ "debate": true,
9
+ "decisions": { "enabled": true },
10
+ "alternatives": { "enabled": true, "debaters": "all" },
11
+ "majority_guard": { "enabled": true },
12
+ "canary": { "enabled": true, "sampleRate": 1 },
13
+ "deep_dive": {
14
+ "enabled": true,
15
+ "job": "sources",
16
+ "focus": ["Every requirement in the excerpt.", "Every number in the excerpt."],
17
+ "usd": 1,
18
+ "maxCalls": 5,
19
+ "chunkChars": 1000
20
+ },
21
+ "handoff": true,
22
+ "estimate": { "promptTokens": 1000, "draftTokens": 1000, "critiqueTokens": 300 },
23
+ "seats": {
24
+ "criteria": { "provider": "mock", "model": "mock-criteria" },
25
+ "skeleton": { "provider": "mock", "model": "mock-skeleton" },
26
+ "builder": { "provider": "mock", "model": "mock-builder" },
27
+ "reviser": { "provider": "mock", "model": "mock-builder" },
28
+ "proposers": [
29
+ { "provider": "mock", "model": "mock-yield-argued", "lab": "mass-a" },
30
+ { "provider": "mock", "model": "mock-yield-unargued", "lab": "mass-b" },
31
+ { "provider": "mock", "model": "mock-proposer-a", "lab": "mass-c" }
32
+ ],
33
+ "alternatives": [
34
+ { "provider": "mock", "model": "mock-alt-a", "lab": "anchor-a" },
35
+ { "provider": "mock", "model": "mock-alt-withdraw", "lab": "anchor-b" }
36
+ ],
37
+ "critics": [
38
+ { "provider": "mock", "model": "mock-critic-a", "lab": "anchor-a" },
39
+ { "provider": "mock", "model": "mock-critic-b", "lab": "anchor-b" }
40
+ ],
41
+ "deep_dive": { "provider": "mock", "model": "mock-deep", "lab": "deep-a", "maxTokens": 128000 }
42
+ }
43
+ }
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "plan-daily-7",
3
+ "description": "daily7 (the owner's name, 2026-09-27: cheap API seats, and the expensive Opus 5.5 seat runs on a local Claude Code session). Tiered council for planning ONE feature cheaply (Muad, 2026-09-27: \"Opus 5.5 on a local sub that does the important tasks from the highest7 setup ... all together ~1$ per council run\"). Same stages and flags as plan-highest-7 (alternatives, debate, decision records, deep dive, majority guard ON, canary, dispute, handoff); only the seats and the deep-dive cap differ. ANCHOR SEATS write the whole alternative architectures (seats.alternatives), answer the posts on them, and are the only panel that votes, unanimously (seats.critics): Claude Opus 5.5 on the owner's Claude subscription (provider external, model subscription:opus-5.5, lab opus5.5-sub: $0 API, a separate Opus 5.5 Claude Code session answers its paused stages), GPT-6 Luna and DeepSeek V4 Pro through OpenRouter. MASS SEATS (seats.proposers, seven labs from the strong and low-cost part of arena.ai's agent leaderboard, fetched 2026-09-27): Tencent Hy4 preview, Gemini 3.8 Flash, DeepSeek V4.1 Flash, GLM 5.2, Muse Spark 1.3, Qwen 3.8 Max, Mistral Medium 3.5 (kept on the owner's word) write the blind proposals and every debate post and reply, and post on the anchors' architectures (alternatives.debaters \"all\"); they argue, they never vote. DEEP-DIVE SEAT: DeepSeek V4.1 Flash, a mass-tier model (a different model from the voting V4 Pro, so chain-lint deep-dive-votes passes), under its own $0.50 cap: a feature-sized task is one 40,000-character call, and a $4 sub-cap would be larger than this chain's whole worst case. Criteria: Llama 4 Maverick, which holds no other seat. WRITER SEATS (skeleton, build, deep-dive-revise, revise-N, dispute, handoff) are a Claude Code session running Sonnet 5, which builds and holds no panel seat. The Opus 5.5 panel seat is a DIFFERENT Anthropic model in a separate session: the owner's plan-highest-7 exception (an Anthropic model reviews a draft another Claude writes), not selfReview - no model writes and votes. ROUTING, because a NEEDS file names only its label: every label containing opus5.5-sub goes to the Opus 5.5 session (alternative-, alt-debate-, alt-reply-, panel-N-, including the suffixed forms panel-N-opus5.5-sub-retry, -reask1, -reask2 and alternative-opus5.5-sub-retry); skeleton, build, deep-dive-revise, revise-N, dispute and handoff go to the Sonnet 5 session. Nothing checks who wrote an answer. Dry run on a one-page feature task (2026-09-27, GPT-6 Luna in place of GPT-6 Sol on the owner's word: \"GPT 6 Sol is too expensive, take GPT 6 luna\"): $1.90 worst case at 7 rounds; under the default $7 cap. No Kimi, no xAI. Run once with real models (2026-09-28); none of its mechanisms has been measured. Price your task with `npm run dry` and get an explicit go before any paid run.",
4
+ "maxRounds": 7,
5
+ "signoff": "unanimous",
6
+ "dispute": { "enabled": true, "stall_rounds": 2 },
7
+ "proposals": { "parts": 3, "maxTokens": 4000 },
8
+ "debate": true,
9
+ "decisions": { "enabled": true },
10
+ "alternatives": { "enabled": true, "debaters": "all" },
11
+ "deep_dive": { "enabled": true, "job": "sources", "usd": 0.5, "maxCalls": 24, "chunkChars": 40000 },
12
+ "majority_guard": { "enabled": true },
13
+ "canary": { "enabled": true, "sampleRate": 0.1 },
14
+ "handoff": true,
15
+ "estimate": { "promptTokens": 10000, "draftTokens": 10000, "critiqueTokens": 5000 },
16
+ "seats": {
17
+ "criteria": { "provider": "openrouter", "model": "meta-llama/llama-4-maverick", "maxTokens": 36000, "lab": "llama4-maverick" },
18
+ "skeleton": { "provider": "external", "model": "claude-code-session" },
19
+ "builder": { "provider": "external", "model": "claude-code-session" },
20
+ "reviser": { "provider": "external", "model": "claude-code-session" },
21
+ "handoff": { "provider": "external", "model": "claude-code-session" },
22
+ "proposers": [
23
+ { "provider": "openrouter", "model": "tencent/hy4-preview", "maxTokens": 36000, "lab": "hy4-preview" },
24
+ { "provider": "openrouter", "model": "google/gemini-3.8-flash", "maxTokens": 36000, "lab": "gemini3.8-flash" },
25
+ { "provider": "openrouter", "model": "deepseek/deepseek-v4.1-flash", "maxTokens": 36000, "lab": "deepseek-v4.1-flash" },
26
+ { "provider": "openrouter", "model": "z-ai/glm-5.2", "maxTokens": 36000, "lab": "glm5.2" },
27
+ { "provider": "openrouter", "model": "meta/muse-spark-1.3", "maxTokens": 36000, "lab": "muse-spark1.3" },
28
+ { "provider": "openrouter", "model": "qwen/qwen3.8-max-0902", "maxTokens": 36000, "lab": "qwen3.8-max" },
29
+ { "provider": "openrouter", "model": "mistralai/mistral-medium-3-5", "maxTokens": 36000, "lab": "mistral-medium3.5" }
30
+ ],
31
+ "alternatives": [
32
+ { "provider": "external", "model": "subscription:opus-5.5", "lab": "opus5.5-sub" },
33
+ { "provider": "openrouter", "model": "openai/gpt-6-luna", "maxTokens": 36000, "lab": "gpt6-luna" },
34
+ { "provider": "openrouter", "model": "deepseek/deepseek-v4-pro", "maxTokens": 64000, "lab": "deepseek-v4-pro" }
35
+ ],
36
+ "critics": [
37
+ { "provider": "external", "model": "subscription:opus-5.5", "lab": "opus5.5-sub" },
38
+ { "provider": "openrouter", "model": "openai/gpt-6-luna", "maxTokens": 36000, "lab": "gpt6-luna" },
39
+ { "provider": "openrouter", "model": "deepseek/deepseek-v4-pro", "maxTokens": 64000, "lab": "deepseek-v4-pro" }
40
+ ],
41
+ "deep_dive": { "provider": "openrouter", "model": "deepseek/deepseek-v4.1-flash", "maxTokens": 36000, "lab": "deepseek-v4.1-flash" }
42
+ }
43
+ }
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "plan-highest-7",
3
+ "description": "Tiered council, Muad's design (2026-09-26): the highest models for the highest tasks, the cheapest models for the mass work. MASS SEATS (seats.proposers, the cheap-7-v2 roster: GPT-5.6 Luna, Gemini 3.8 Flash, DeepSeek V4.1 Flash, GLM 5.3 Flash, Qwen 3.7 Plus, MiniMax M3, Mistral Medium 3.5) write the blind proposals and all the proposal debate posts and replies, and post on the anchors' architectures (alternatives.debaters \"all\"). ANCHOR SEATS: GPT-6 Astra and Claude Opus 5.5 (Muad's pick 2026-09-26, in place of Fable 5.1; still his deliberate exception: an Anthropic model reviews a draft a Claude Code session writes), DeepSeek V4 Pro and GLM-5.3 write the whole alternative architectures (seats.alternatives), answer the posts on them, and form the review panel that must sign off unanimously (seats.critics). The mass seats argue; only the anchors vote, so a cheap majority can never out-vote them. DEEP-DIVE SEAT (seats.deep_dive, DeepSeek V4.1 Flash, a mass-tier model: it must not share a lab with a voting anchor, chain-lint deep-dive-votes): one job, checking the first draft against every part of the task, 40,000 characters per call at a 36k output cap, up to 24 calls under its OWN $4 cap inside the run's; it does not vote, and the reviser answers its findings before the anchors' first review. The MAJORITY GUARD is ON (majority_guard, Muad's go 2026-09-26; off in every other shipped chain but mock-tiered): authors see each argument once with no lab letter or count, the reply prompts carry an evidence bar, and a withdrawal that does not quote the argument it concedes to is kept for the builder. Criteria move to Llama 4 Maverick, which holds no other seat. Same Claude Code writer seats and stages as plan-premium-7, including decision records and the dispute stage. No Kimi, no xAI. Untested with real models: price it with `npm run dry` and get an explicit go before any paid run.",
4
+ "maxRounds": 7,
5
+ "signoff": "unanimous",
6
+ "dispute": { "enabled": true, "stall_rounds": 2 },
7
+ "proposals": { "parts": 3, "maxTokens": 4000 },
8
+ "debate": true,
9
+ "decisions": { "enabled": true },
10
+ "alternatives": { "enabled": true, "debaters": "all" },
11
+ "deep_dive": { "enabled": true, "job": "sources", "usd": 4, "maxCalls": 24, "chunkChars": 40000 },
12
+ "majority_guard": { "enabled": true },
13
+ "canary": { "enabled": true, "sampleRate": 0.1 },
14
+ "handoff": true,
15
+ "estimate": { "promptTokens": 10000, "draftTokens": 10000, "critiqueTokens": 5000 },
16
+ "seats": {
17
+ "criteria": { "provider": "openrouter", "model": "meta-llama/llama-4-maverick", "maxTokens": 36000, "lab": "llama4-maverick" },
18
+ "skeleton": { "provider": "external", "model": "claude-code-session" },
19
+ "builder": { "provider": "external", "model": "claude-code-session" },
20
+ "reviser": { "provider": "external", "model": "claude-code-session" },
21
+ "handoff": { "provider": "external", "model": "claude-code-session" },
22
+ "proposers": [
23
+ { "provider": "openrouter", "model": "openai/gpt-5.6-luna", "maxTokens": 36000, "lab": "gpt5.6-luna" },
24
+ { "provider": "openrouter", "model": "google/gemini-3.8-flash", "maxTokens": 36000, "lab": "gemini3.8-flash" },
25
+ { "provider": "openrouter", "model": "deepseek/deepseek-v4.1-flash", "maxTokens": 36000, "lab": "deepseek-v4.1-flash" },
26
+ { "provider": "openrouter", "model": "z-ai/glm-5.3-flash", "maxTokens": 36000, "lab": "glm5.3-flash" },
27
+ { "provider": "openrouter", "model": "qwen/qwen3.7-plus", "maxTokens": 36000, "lab": "qwen3.7-plus" },
28
+ { "provider": "openrouter", "model": "minimax/minimax-m3", "maxTokens": 36000, "lab": "minimax-m3" },
29
+ { "provider": "openrouter", "model": "mistralai/mistral-medium-3-5", "maxTokens": 36000, "lab": "mistral-medium3.5" }
30
+ ],
31
+ "alternatives": [
32
+ { "provider": "openrouter", "model": "openai/gpt-6-astra", "maxTokens": 36000, "lab": "gpt6-astra" },
33
+ { "provider": "openrouter", "model": "anthropic/claude-opus-5.5", "maxTokens": 36000, "lab": "opus5.5", "estimate": { "critiqueTokens": 10000 } },
34
+ { "provider": "openrouter", "model": "deepseek/deepseek-v4-pro", "maxTokens": 64000, "lab": "deepseek-v4-pro" },
35
+ { "provider": "openrouter", "model": "z-ai/glm-5.3", "maxTokens": 64000, "lab": "glm5.3" }
36
+ ],
37
+ "critics": [
38
+ { "provider": "openrouter", "model": "openai/gpt-6-astra", "maxTokens": 36000, "lab": "gpt6-astra" },
39
+ { "provider": "openrouter", "model": "anthropic/claude-opus-5.5", "maxTokens": 36000, "lab": "opus5.5", "estimate": { "critiqueTokens": 10000 } },
40
+ { "provider": "openrouter", "model": "deepseek/deepseek-v4-pro", "maxTokens": 64000, "lab": "deepseek-v4-pro" },
41
+ { "provider": "openrouter", "model": "z-ai/glm-5.3", "maxTokens": 64000, "lab": "glm5.3" }
42
+ ],
43
+ "deep_dive": { "provider": "openrouter", "model": "deepseek/deepseek-v4.1-flash", "maxTokens": 36000, "lab": "deepseek-v4.1-flash" }
44
+ }
45
+ }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "verify",
3
- "description": "The recommended default. Two labs, a hard 2-round cap: the smallest cross-lab review, and the cheapest.",
3
+ "description": "The CLI default when --chain is not given. Two labs, a hard 2-round cap: the smallest cross-lab review. For a first real council, start with cheap-7-v2 (one OpenRouter key); see the README's chain table.",
4
4
  "maxRounds": 2,
5
5
  "stopOnPass": true,
6
6
  "estimate": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "the-high-council",
3
- "version": "0.7.7",
3
+ "version": "0.7.9",
4
4
  "mcpName": "io.github.muad-yasin/the-high-council",
5
5
  "description": "The High Council: a multi-model planning harness. One builder, independent critics from other labs, checkable acceptance criteria, a debate on the record, and a hard stop.",
6
6
  "type": "module",
@@ -49,11 +49,11 @@
49
49
  },
50
50
  "dependencies": {
51
51
  "@modelcontextprotocol/sdk": "^1.30.0",
52
- "express": "^4.22.2",
53
52
  "zod": "^4.6.4"
54
53
  },
55
54
  "files": [
56
55
  "src/",
56
+ "!src/http-server.js",
57
57
  "chains/",
58
58
  "schemas/",
59
59
  "types/",
@@ -84,6 +84,7 @@
84
84
  ],
85
85
  "devDependencies": {
86
86
  "@yao-pkg/pkg": "6.22.0",
87
- "ajv": "^8.20.0"
87
+ "ajv": "^8.20.0",
88
+ "express": "^4.22.2"
88
89
  }
89
90
  }