the-high-council 0.7.5 → 0.7.6

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 (76) hide show
  1. package/.env.example +2 -3
  2. package/README.md +159 -28
  3. package/chains/cheap-7-v2.json +98 -0
  4. package/chains/cheap-7.json +93 -0
  5. package/chains/coder-gate-v1.json +56 -0
  6. package/chains/coder-gate-v2.json +55 -0
  7. package/chains/gp-judge-v1.json +31 -7
  8. package/chains/idea-open-c2.json +2 -13
  9. package/chains/mock-dispute.json +47 -0
  10. package/chains/mock-partitioned.json +62 -0
  11. package/chains/mock-patch-fallback.json +41 -0
  12. package/chains/mock-patch.json +41 -0
  13. package/chains/mock-proposals.json +4 -2
  14. package/chains/mock-security-review.json +45 -0
  15. package/chains/plan-auto-mistral.json +6 -6
  16. package/chains/plan-auto.json +2 -2
  17. package/chains/plan-debate-c2.json +1 -1
  18. package/chains/plan-debate-open-c2.json +2 -13
  19. package/chains/plan-debate-roles-c1.json +22 -7
  20. package/chains/plan-debate.json +1 -1
  21. package/chains/plan-open-7.json +93 -0
  22. package/chains/plan-premium-7.json +113 -0
  23. package/chains/seven.json +1 -6
  24. package/chains/us-only.json +2 -7
  25. package/chains/verify.json +1 -1
  26. package/package.json +24 -4
  27. package/src/audit.js +11 -5
  28. package/src/board-export.js +40 -1
  29. package/src/budget.js +18 -6
  30. package/src/buys.js +8 -0
  31. package/src/cache-integrity.js +39 -16
  32. package/src/canary.js +47 -6
  33. package/src/chain-lint.js +427 -11
  34. package/src/chain.js +1561 -130
  35. package/src/cli.js +1083 -180
  36. package/src/cost.js +79 -3
  37. package/src/council-replay.js +122 -0
  38. package/src/denied-models.js +139 -0
  39. package/src/disagreement-groups.js +54 -0
  40. package/src/dissent-digest.js +105 -0
  41. package/src/fence.js +145 -0
  42. package/src/http-server.js +1 -1
  43. package/src/key-redaction.js +15 -45
  44. package/src/mcp/server.js +205 -53
  45. package/src/metrics.js +5 -1
  46. package/src/name-lint.js +54 -9
  47. package/src/outcome.js +29 -0
  48. package/src/partial-deliverable.js +29 -4
  49. package/src/patch-revise.js +91 -0
  50. package/src/peer-claim.js +65 -13
  51. package/src/policy.js +140 -3
  52. package/src/preflight.js +119 -8
  53. package/src/pricing.json +126 -18
  54. package/src/progress-spans.js +72 -0
  55. package/src/providers.js +326 -34
  56. package/src/quote-check.js +134 -0
  57. package/src/rematch.js +70 -0
  58. package/src/report-shape.js +119 -0
  59. package/src/role-diagnostics.js +10 -3
  60. package/src/roles.js +453 -37
  61. package/src/run-lock.js +106 -0
  62. package/src/run-state.js +54 -0
  63. package/src/run-status.js +84 -0
  64. package/src/scope-freeze.js +19 -3
  65. package/src/seat-role.js +5 -1
  66. package/src/secret-patterns.js +113 -0
  67. package/src/security-review.js +201 -0
  68. package/src/shape-rounds.js +5 -1
  69. package/src/spans.js +84 -0
  70. package/src/spend.js +44 -8
  71. package/src/stage-contract.js +46 -10
  72. package/src/superseded.js +73 -0
  73. package/src/tools.js +288 -24
  74. package/src/verdict-diff.js +63 -0
  75. package/src/verdict-stats.js +63 -22
  76. package/src/version.js +18 -0
package/.env.example CHANGED
@@ -3,7 +3,6 @@
3
3
  ANTHROPIC_API_KEY=
4
4
  OPENAI_API_KEY=
5
5
  GOOGLE_API_KEY=
6
- XAI_API_KEY=
7
6
  MISTRAL_API_KEY=
8
7
  DEEPSEEK_API_KEY=
9
8
  GROQ_API_KEY=
@@ -14,6 +13,6 @@ ZAI_API_KEY=
14
13
 
15
14
  # Default per-run spend ceiling in USD. Overridden per run by --max-usd.
16
15
  # A run stops cleanly before any stage that could take it past this, and
17
- # resumes with a higher ceiling. Unset means $5. Use --max-usd none to run
16
+ # resumes with a higher ceiling. Unset means $7. Use --max-usd none to run
18
17
  # without a ceiling.
19
- MAX_USD_PER_RUN=5
18
+ MAX_USD_PER_RUN=7
package/README.md CHANGED
@@ -1,24 +1,29 @@
1
1
  # The High Council
2
2
 
3
- [![Test](https://github.com/muad-yasin/the-high-council-mcp/actions/workflows/test.yml/badge.svg)](https://github.com/muad-yasin/the-high-council-mcp/actions/workflows/test.yml)
3
+ > **Repository status (2026-09-22): going private until the open-source release.** Development
4
+ > continues in a private repository, and the public open-source release is planned for later this
5
+ > year. Until then, the published npm package `the-high-council` (0.7.6) stays installable as it
6
+ > is, and the `npx github:...` lines below only work for someone with access to this repository.
7
+ > The licence of everything already released stays MIT.
4
8
 
5
9
  See it work right now - no keys, no setup, no cost:
6
10
 
7
- npx github:muad-yasin/the-high-council-mcp council demo
11
+ npx the-high-council council demo
8
12
 
9
13
  Add it to Claude Code as an MCP server the same way:
10
14
 
11
- claude mcp add council -- npx -y github:muad-yasin/the-high-council-mcp council --mcp
15
+ claude mcp add council -- npx -y the-high-council council --mcp
12
16
 
13
- *(An npm package is coming - not yet published. Both lines above work today, straight from this
14
- GitHub repo, no npm account needed.)*
17
+ *(With access to this repository, `npx github:muad-yasin/the-high-council-mcp council demo` runs
18
+ the current source instead of the published package.)*
15
19
 
16
20
  A planning harness that runs one idea past several AI models from different labs, makes them
17
21
  argue about it on the record, and stops at a checkable result.
18
22
 
19
23
  Runs as an **MCP server** (so an agent like Claude Code can drive it) or as a **CLI**. Bring your
20
- own API keys. Nothing is resold, nothing is hosted for you, and no key ever leaves your machine.
21
- Run `npx github:muad-yasin/the-high-council-mcp council doctor` to see which of your own keys are
24
+ own API keys. Nothing is resold, nothing is hosted for you, and your keys go only to the
25
+ providers you choose, never to us.
26
+ Run `npx the-high-council council doctor` to see which of your own keys are
22
27
  set, which shipped chains you can already run with them, and what each would cost - before
23
28
  spending anything.
24
29
 
@@ -76,6 +81,15 @@ anything on top of a run, read that instead. Do not parse the markdown.
76
81
  "replies": [ { "id": "DEEPSEEK-1", "action": "keep|amend|withdraw",
77
82
  "text": "...", "replaced_by": "GLM-1" } ]
78
83
  },
84
+ // Only on chains with `alternatives: { enabled: true }`: one whole architecture per lab, written
85
+ // blind before the skeleton, and the same post/reply board the proposals get.
86
+ "alternatives": {
87
+ "items": [ { "id": "GLM-ALT", "lab": "glm", "model": "...", "name": "...", "shape": "...",
88
+ "key_tradeoffs": "...", "bad_at": "...", "amended": true, "withdrawn": false } ],
89
+ "posts": [ { "by": "qwen", "on": "GLM-ALT", "stance": "object|support|merge", "text": "..." } ],
90
+ "replies": [ { "id": "GLM-ALT", "action": "keep|amend|withdraw", "text": "..." } ],
91
+ "dropouts": [ { "lab": "...", "model": "...", "stage": "alternatives", "reason": "..." } ]
92
+ },
79
93
  "signoff": [ { "provider": "qwen", "model": "...", "signedOff": false,
80
94
  "objections": [ { "criterion": "...", "problem": "...", "fix": "..." } ] } ],
81
95
  "lastCritique": { "meets": false, "failures": [ { "criterion": "...", "lab": "qwen" } ] },
@@ -136,11 +150,31 @@ Fill in `.env` with only the keys your chosen chain needs. Supported providers:
136
150
 
137
151
  `ANTHROPIC_API_KEY` · `OPENAI_API_KEY` · `GOOGLE_API_KEY` · `MISTRAL_API_KEY` ·
138
152
  `DEEPSEEK_API_KEY` · `GROQ_API_KEY` · `TOGETHER_API_KEY` · `COHERE_API_KEY` ·
139
- `OPENROUTER_API_KEY` · `ZAI_API_KEY` · `XAI_API_KEY`
153
+ `OPENROUTER_API_KEY` · `ZAI_API_KEY`
154
+
155
+ xAI/Grok and Kimi/Moonshot are never seated, and neither is a router id (`openrouter/auto`, the
156
+ Pareto Code router) that could route to them: chain-lint refuses such a chain and the run itself
157
+ refuses such a seat, with no override. There is no `xai` provider.
140
158
 
141
159
  The CLI refuses to start if any seat in the chosen chain is missing its key, rather than failing
142
160
  halfway through a paid run. `ollama` (below) is the one exception - it needs no key at all.
143
161
 
162
+ ### Standalone binaries (build them yourself)
163
+
164
+ There are no published binary downloads yet. From a clone you can build a single-file `council`
165
+ that needs no Node install to run: a Linux binary, a Linux AppImage, and a Windows `.exe`, all
166
+ built on Linux.
167
+
168
+ ```bash
169
+ npm run build:bin # dist/the-high-council-linux, dist/the-high-council-win.exe
170
+ npm run build:appimage # dist/the-high-council-x86_64.AppImage (downloads a pinned appimagetool)
171
+ npm run smoke:bin -- dist/the-high-council-linux # demo + an MCP session, offline, $0
172
+ ```
173
+
174
+ Stated plainly: the `.exe` is tested under Wine on Linux, not on a real Windows machine, and none
175
+ of the binaries are code-signed, so Windows SmartScreen will warn. Put `.env` in the directory you
176
+ run the binary from.
177
+
144
178
  ### Local models (Ollama, LM Studio, ...)
145
179
 
146
180
  A seat can run on a model you're hosting yourself instead of a paid API. Set its provider to
@@ -165,6 +199,15 @@ example chain with every seat local. As with every other seat in this project: B
165
199
  BYO-compute here, and no efficacy claim is made about local models versus hosted ones - nothing
166
200
  has been measured.
167
201
 
202
+ ### Final security-review gate
203
+
204
+ `"security_review": { "enabled": true }` adds one read-only reviewer as the last stage of a chain,
205
+ after the build and everything else. It returns typed findings, and any critical or high finding
206
+ fails the run (exit 7). A reviewer with no usable verdict fails it too (exit 8); that never counts
207
+ as a pass. The default reviewer is `anthropic/claude-fable-5-1` (your key, priced, capped);
208
+ `seats.security_reviewer` can be any seat, including a local `ollama` one as an offline option.
209
+ Full details: [docs/security-review-gate.md](docs/security-review-gate.md).
210
+
168
211
  ## Quick start (CLI)
169
212
 
170
213
  A task file is the request the council plans against: plain prose, written by you. There is no
@@ -187,6 +230,34 @@ them stay on your machine - if you fork this repo, you will not accidentally pub
187
230
 
188
231
  `verify` is the cheap default: two labs, a hard two-round cap. Start there.
189
232
 
233
+ ### Exit codes
234
+
235
+ Each outcome has its own code, so a script or CI job can branch on it:
236
+
237
+ | Code | Meaning |
238
+ |---|---|
239
+ | 0 | Finished: a deliverable and `report.json` were written. |
240
+ | 1 | The chain failed lint, or an input is missing (no task file, a resume from the wrong directory). |
241
+ | 2 | Usage error: a flag is missing its value or has an invalid one. |
242
+ | 3 | Paused at an external seat: answer `NEEDS-<stage>.md`, then `--resume`. |
243
+ | 4 | Stopped at the per-run spend cap before the next stage was paid for; resume with a higher `--max-usd`. |
244
+ | 5 | A provider key the chain needs is missing (degradable: set it and run again). |
245
+ | 6 | Fatal: the chain file cannot be parsed, or the audit key cannot be loaded. |
246
+ | 7 | Finished, but the final security review blocked the deliverable. |
247
+ | 8 | Finished, but the final security review could not judge it (never a pass). |
248
+ | 9 | Artifact gate: the task names files whose content it never includes (`BLOCKED-ARTIFACTS.md`). |
249
+ | 10 | Preflight: a seat objected to the task description itself (`STOPPED-preflight.md`). |
250
+ | 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`. |
251
+ | 12 | `policy.json` refused the chain. |
252
+ | 13 | Another process is already running this run folder. |
253
+ | 14 | The task file changed since the run started and `AMENDMENTS.md` does not cover it. |
254
+ | 15 | `--resume` of a run that already finished (it has a `report.json`); nothing is run or spent. |
255
+ | 16 | The run stopped at an unexpected error (a seat that could not be reached, a crash); `STOPPED-error.md` says what, and `--resume` continues from the completed stages. |
256
+ | 17 | A draft (build, revise, dispute, final edit or handoff) was cut off at its token cap, and its one larger-cap retry was cut off too; the fragment is never graded or shipped (`STOPPED-truncated.md`). |
257
+
258
+ Codes 9-17 were split out or added on 2026-09-23. Before that, several of these outcomes shared a code (2, 5,
259
+ 6 or 1).
260
+
190
261
  ### Telling the council what your build session can actually use
191
262
 
192
263
  One optional convention, worth the four lines it costs. If your task file ends with a section
@@ -211,7 +282,7 @@ before building it."*
211
282
 
212
283
  ### The spend cap
213
284
 
214
- Every run has a per-run ceiling in USD. It defaults to **$5**, and is checked *before* each paid
285
+ Every run has a per-run ceiling in USD. It defaults to **$7**, and is checked *before* each paid
215
286
  stage - a stage that could take the run past the ceiling is never called, so the cap holds rather
216
287
  than reporting the overspend afterwards.
217
288
 
@@ -230,6 +301,14 @@ with a higher ceiling - completed stages replay from disk and cost nothing the s
230
301
  node src/cli.js --resume runs/<id> --max-usd 10
231
302
  ```
232
303
 
304
+ A stage replays only if it would be asked the same thing again: the task text, the chain config
305
+ and the stage's own prompt must all match what it answered. If one changed (you edited the chain,
306
+ or an earlier stage came out differently this time), the stage runs again and its old files move
307
+ into `superseded/` inside the run folder. What the old answer cost still counts toward the ceiling,
308
+ `--spend` and `report.json`'s `totals.usd` (shown separately as `totals.supersededUsd`), so a resume
309
+ cannot spend past the cap. An answer you wrote for an external stage is never re-used against a
310
+ changed prompt: it is set aside the same way and the run asks you again.
311
+
233
312
  The cap governs one run. To see what you have spent across all of them:
234
313
 
235
314
  ```bash
@@ -262,12 +341,16 @@ node src/cli.js --resume runs/<id>
262
341
 
263
342
  ## Quick start (MCP)
264
343
 
265
- Register the server with your MCP client. No clone needed - straight from GitHub:
344
+ Register the server with your MCP client. No clone needed - from the published npm package:
266
345
 
267
346
  ```bash
268
- claude mcp add council -- npx -y github:muad-yasin/the-high-council-mcp council --mcp
347
+ claude mcp add council -- npx -y the-high-council council --mcp
269
348
  ```
270
349
 
350
+ With access to this repository (private until the open-source release), the same line with
351
+ `npx -y github:muad-yasin/the-high-council-mcp` runs the current source instead. The clone and
352
+ plugin-marketplace routes below need that access too.
353
+
271
354
  Or from a clone of this repo:
272
355
 
273
356
  ```bash
@@ -277,7 +360,25 @@ claude mcp add high-council -- node /absolute/path/to/the-high-council-mcp/src/m
277
360
  **The path must be absolute.** The client starts the server from its own working directory, not
278
361
  from this one, so a relative path resolves somewhere unexpected and the server never starts.
279
362
 
280
- An npm package is coming - not yet published, no date. Once it lands:
363
+ Or as a Claude Code plugin, which registers the same server and also installs the skills in
364
+ [`skills/`](skills/README.md):
365
+
366
+ ```bash
367
+ claude plugin marketplace add muad-yasin/the-high-council-mcp
368
+ claude plugin install the-high-council@the-high-council
369
+ ```
370
+
371
+ Claude Code copies the plugin into its plugin cache and runs `npm ci` there itself, so the first
372
+ install takes a little longer. Start a new session (or run `/reload-plugins`) and the server shows
373
+ up in `claude mcp list` as `plugin:the-high-council:high-council`. Remove it with
374
+ `claude plugin uninstall the-high-council@the-high-council`. If you add the marketplace from a
375
+ local clone instead (`claude plugin marketplace add /path/to/clone`), the server runs from the
376
+ clone itself, so run `npm install` in it first.
377
+
378
+ Registering with a client other than Claude Code (DeepSeek Harness, OpenHands, Cline, goose,
379
+ Continue): [docs/mcp-clients.md](docs/mcp-clients.md) has the real config for each.
380
+
381
+ An npm package is also live:
281
382
 
282
383
  ```bash
283
384
  claude mcp add high-council -- npx -y the-high-council --mcp
@@ -324,7 +425,7 @@ for anyone with a subscription, since the project's cost story depends on it.
324
425
 
325
426
  ## Chains
326
427
 
327
- 31 chain configs live in `chains/`. Each one is plain JSON - the seat roster, which models fill
428
+ 48 chain configs live in `chains/`. Each one is plain JSON - the seat roster, which models fill
328
429
  which seat, the round cap, and whether proposals/debate/handoff stages run. They are meant to be
329
430
  copied and edited.
330
431
 
@@ -334,7 +435,8 @@ A few worth knowing:
334
435
  - **`cheap`** - small models throughout. For testing the harness itself, not for real work.
335
436
  - **`plan-debate`** - five labs propose blind, debate each other's proposals anonymised, then a
336
437
  blind panel grades the integrated draft.
337
- - **`plan-auto`** - the full open-scope chain, every seat on a real API, runs unattended end to end.
438
+ - **`plan-auto`** - the full open-scope chain with every seat on a real API, so no stage waits for
439
+ an external session. It still pauses once for your answers to its questions.
338
440
  - **`plan-unanimous`** - every critic must independently sign off on the *same* draft. Three rounds
339
441
  here means up to fifteen critic calls, not five.
340
442
 
@@ -386,8 +488,9 @@ Read a chain's `description` field before running it; they say what they cost yo
386
488
  review round can't run), or a seat naming a provider this codebase doesn't know. The same check
387
489
  also runs automatically, fail-loud, the moment you try to actually run a broken chain - before
388
490
  any paid call.
389
- - **`council doctor --scan-artifacts`** - scans your `tasks/` and `chains/` for API-key-shaped
390
- strings before you commit or share them. Reports the file and line, never the matched text.
491
+ - **`council doctor --scan-artifacts`** - scans your `tasks/` and `chains/` for the key formats
492
+ listed in `src/secret-patterns.js` before you commit or share them. A format not on that list is
493
+ not caught. Reports the file and line, never the matched text.
391
494
  - **`council --forecast-cost --chain <name> [--days N]`** - a realistic-case USD range for a
392
495
  chain, built from its own historical runs on your machine and repriced at today's rates -
393
496
  distinct from `--dry-run`'s worst-case estimate from a chain's declared token assumptions.
@@ -395,7 +498,7 @@ Read a chain's `description` field before running it; they say what they cost yo
395
498
  verdict as one self-contained HTML file. No external assets, no server, `<details>` sections.
396
499
  - **`council replay --run <folder> [--json]`** - a numbered, step-by-step transcript of a run's
397
500
  reasoning in your terminal, with a `--json` mode for scripting.
398
- - **A structured error catalog** (`COUNCIL-E001`-`COUNCIL-E004`, see [TROUBLESHOOTING.md](TROUBLESHOOTING.md))
501
+ - **A structured error catalog** (`COUNCIL-E001`-`COUNCIL-E005`, see [TROUBLESHOOTING.md](TROUBLESHOOTING.md))
399
502
  for the hard-fail paths this project actually has - a missing key, an unpriced model, a
400
503
  malformed chain file, an unreadable stage reply - each with a plain-words cause, a concrete fix
401
504
  naming the real file, and a doc pointer. Degradable conditions exit 5; fatal ones exit 6.
@@ -444,13 +547,21 @@ No claim is made here that any of this produces better plans. It has not been me
444
547
 
445
548
  ## Skills
446
549
 
447
- `skills/` carries two Claude Code skill files shipped alongside this harness, not part of it:
448
- `backend-developer` and `frontend-developer` - general backend and frontend engineering rules
449
- (contract-first design, save/persistence integrity, accessibility, verification discipline) that
450
- apply to any codebase, not just this one. Same MIT/BYOK ethos as the harness itself. They don't
451
- claim to make code better; they describe what each rule guards against and why. Point Claude Code
452
- at this repo's `skills/` directory (or copy the two folders into your own project's
453
- `.claude/skills/`) to use them.
550
+ `skills/` carries a small set of Claude Code skills shipped alongside this harness, not part of
551
+ it - usable in any project, with or without the harness, and needing no API key:
552
+
553
+ - **Core agentic work:** `task-scoping`, `research-and-sourcing`, `verification-and-critique`,
554
+ `context-and-handoff`, `tool-and-action-discipline` - the work around the work, for any agent
555
+ task, including setups where several models propose, critique, and hand off to each other.
556
+ - **Building software:** `backend-developer`, `frontend-developer`, `ux-design`, `visual-craft`.
557
+ - **Writing:** `good-news-writing`.
558
+
559
+ The full catalog, with when to use each and what it guards against, is
560
+ [`skills/README.md`](skills/README.md); a shareable presentation page is `docs/skills.html`. Both
561
+ are checked by the test suite against the real `skills/` folder. Same MIT/BYOK ethos as the
562
+ harness: the skills don't claim to make results better - nothing has been measured - they describe
563
+ what each rule guards against and why. Copy the folders you want into your project's
564
+ `.claude/skills/`, or point Claude Code at this repo's `skills/` directory.
454
565
 
455
566
  ## Known limits, stated plainly
456
567
 
@@ -463,6 +574,17 @@ at this repo's `skills/` directory (or copy the two folders into your own projec
463
574
  for `unpriced` before trusting a ceiling. `ollama` seats are the one deliberate exception: they
464
575
  price at an explicit $0 for any model name (they are genuinely free to run), so they never show
465
576
  up in that `unpriced` list and never need a pricing.json entry.
577
+ - A call that fails **after** it reached the provider - the connection drops while a 200 reply is
578
+ being read, a 200 carries a body that is not JSON, or the request times out waiting for headers -
579
+ is not retried, because the generation was probably already billed. Its real usage cannot be
580
+ read, so it is counted toward the per-run cap at its worst-case projection. It leaves no
581
+ `<label>.usage.json`, so `council --spend` does not see it.
582
+ - Some hosted reasoning models stop at a provider-side reasoning ceiling well below the seat's own
583
+ cap, before writing any answer (seen 2026-09-23: `deepseek/deepseek-v4.1-flash` via OpenRouter, 6 of
584
+ 28 calls stopped at ~4.2k tokens, all reasoning, under a 36k cap). A bigger cap cannot fix that, so
585
+ such a reply is recorded as `REASONING_EXHAUSTED` and is not retried: the seat abstains, which
586
+ blocks unanimity and never counts as consent. Whether to change a chain's reasoning settings for it
587
+ is a roster decision, not something the harness does for you.
466
588
  - Prices in `src/pricing.json` are hand-maintained list prices, last verified 2026-09-06. They are
467
589
  estimates, not invoices. Your provider's bill is the real number.
468
590
  - Chains with many labs and high round caps get expensive quickly. `plan-unanimous` at three rounds
@@ -473,6 +595,10 @@ at this repo's `skills/` directory (or copy the two folders into your own projec
473
595
  produce sign-offs that mean nothing - the quality of the run depends heavily on the quality of
474
596
  the criteria stage.
475
597
  - Some chains pause for human input by design. They are not stuck.
598
+ - The audit log (`audit.jsonl`) detects an edited line or a cut-off end, but **with no HMAC key,
599
+ which is the default, it does not detect a full rewrite**: anyone who can edit the file can
600
+ recompute every hash. Set `AUDIT_HMAC_KEY_FILE` to a key kept outside the run folder if the log
601
+ has to stand up to that.
476
602
 
477
603
  ## Privacy
478
604
 
@@ -484,16 +610,21 @@ collect nothing. Stated plainly, not as a claim about quality:
484
610
  your own keys (`ANTHROPIC_API_KEY`, `OPENROUTER_API_KEY`, and so on) - and only when you start
485
611
  a real run with a non-mock, non-external seat. `council doctor` and `council demo` make zero
486
612
  network calls; both are implemented to read only local files and environment variable names.
487
- - The GitHub Pages site (`docs/`) ships no JavaScript and loads no third-party resource - see
613
+ - The landing page (`docs/`, moving from GitHub Pages to sower-industries.de while this
614
+ repository is private) ships no JavaScript and loads no third-party resource - see
488
615
  `test/landing-page.test.js`, which fails the build if either ever changes.
489
616
  - Everything a run produces - the task, the debate, the deliverable, the cost - is written to a
490
617
  folder on your own disk (`runs/<id>/`) and nowhere else. Deleting that folder deletes the
491
618
  record. See `src/spend.js`'s own documentation for why spend accounting is derived from those
492
619
  folders rather than kept in a separate log.
620
+ - If you opt in to the audit export (`"audit": true`, and on automatically whenever a `policy.json`
621
+ exists), each run also writes `audit.jsonl` into its own folder: signed, hash-chained lines (each carries the previous line's hash) that
622
+ `verifyAuditLog` in `src/audit.js` checks offline. Seat, cost and timing only, never task or
623
+ prompt text. Format: `docs/audit-schema.md`.
493
624
 
494
625
  ## Accessibility
495
626
 
496
- The GitHub Pages site (`docs/`) uses only native HTML elements for interaction - `<a href>`
627
+ The landing page (`docs/`) uses only native HTML elements for interaction - `<a href>`
497
628
  links and `<details>/<summary>` for the expandable demo sections - specifically because those
498
629
  are keyboard-operable by the browser itself, with no custom JavaScript to get wrong. Tested by
499
630
  hand, 2026-09-13, on the live site:
@@ -515,8 +646,8 @@ hand, 2026-09-13, on the live site:
515
646
 
516
647
  ## Reporting a bug
517
648
 
518
- Open an issue: [github.com/muad-yasin/the-high-council-mcp/issues](https://github.com/muad-yasin/the-high-council-mcp/issues).
519
- Or write to [contact@sower-industries.de](mailto:contact@sower-industries.de).
649
+ Write to [contact@sower-industries.de](mailto:contact@sower-industries.de). (GitHub issues open
650
+ again with the public release; while the repository is private, email is the only route.)
520
651
 
521
652
  ## If this makes you money
522
653
 
@@ -0,0 +1,98 @@
1
+ {
2
+ "name": "cheap-7-v2",
3
+ "description": "Seven independent labs vote, none of them the author's, all on current-generation models through one OpenRouter key: OpenAI GPT-5.6 Luna, Google Gemini 3.8 Flash, DeepSeek v4.1 Flash, Z.ai GLM 5.3 Flash, Qwen 3.7 Plus, MiniMax M3, Mistral Medium 3.5. Blind proposals, debate, unanimous signoff, with a round cap of 7 and a stall rule: if the same objections from the same labs survive two rounds running, the revise loop stops rather than buying more rounds of the same argument, and the unresolved dissent is recorded at the top of the deliverable. A run that ends that way reports no consensus - the dispute stage records disagreement, it never resolves it. Anthropic Sonnet 5 writes the skeleton, the draft, every revision and the handoff and holds NO panel seat; Meta Llama 4 Maverick writes the criteria and also holds no panel seat, so neither the lab that drafts nor the lab that sets the bar votes on whether the bar was cleared. This is the revision of cheap-7 after its first real run, where one lab held the criteria, skeleton, builder, reviser and handoff seats AND a critic seat, voted on its own draft, and a claim it wrote survived to the deliverable. Anthropic is deliberately absent from the panel: plans from this chain are read by a Claude session before anything is built, so that review happens downstream rather than inside the vote. Kimi K3 is deliberately absent too - a seat that may route through another lab is not an independent seat. Every seat gets a 36000-token ceiling and reasoning is left on: a debate is not squeezed to a short answer, and a reply cut off at the ceiling is retried once, then the seat is re-asked alone - it is never counted as agreement. The cap is a ceiling, not a price; only generated tokens are billed. Prices are from src/pricing.json, refreshed against OpenRouter's live model list on 2026-09-20 - price a real task with `npm run dry` before running.",
4
+ "maxRounds": 7,
5
+ "signoff": "unanimous",
6
+ "dispute": {
7
+ "enabled": true,
8
+ "stall_rounds": 2
9
+ },
10
+ "proposals": {
11
+ "parts": 3,
12
+ "maxTokens": 4000
13
+ },
14
+ "debate": true,
15
+ "canary": { "enabled": true, "sampleRate": 0.1 },
16
+ "handoff": true,
17
+ "estimate": {
18
+ "promptTokens": 10000,
19
+ "draftTokens": 10000,
20
+ "critiqueTokens": 5000
21
+ },
22
+ "seats": {
23
+ "criteria": {
24
+ "provider": "openrouter",
25
+ "model": "meta-llama/llama-4-maverick",
26
+ "maxTokens": 36000,
27
+ "lab": "llama4-maverick"
28
+ },
29
+ "skeleton": {
30
+ "provider": "openrouter",
31
+ "model": "anthropic/claude-sonnet-5",
32
+ "maxTokens": 36000,
33
+ "lab": "sonnet5"
34
+ },
35
+ "builder": {
36
+ "provider": "openrouter",
37
+ "model": "anthropic/claude-sonnet-5",
38
+ "maxTokens": 36000,
39
+ "lab": "sonnet5"
40
+ },
41
+ "reviser": {
42
+ "provider": "openrouter",
43
+ "model": "anthropic/claude-sonnet-5",
44
+ "maxTokens": 36000,
45
+ "lab": "sonnet5"
46
+ },
47
+ "handoff": {
48
+ "provider": "openrouter",
49
+ "model": "anthropic/claude-sonnet-5",
50
+ "maxTokens": 36000,
51
+ "lab": "sonnet5"
52
+ },
53
+ "critics": [
54
+ {
55
+ "provider": "openrouter",
56
+ "model": "openai/gpt-5.6-luna",
57
+ "maxTokens": 36000,
58
+ "lab": "gpt5.6-luna"
59
+ },
60
+ {
61
+ "provider": "openrouter",
62
+ "model": "google/gemini-3.8-flash",
63
+ "maxTokens": 36000,
64
+ "lab": "gemini3.8-flash"
65
+ },
66
+ {
67
+ "provider": "openrouter",
68
+ "model": "deepseek/deepseek-v4.1-flash",
69
+ "maxTokens": 36000,
70
+ "lab": "deepseek-v4.1-flash"
71
+ },
72
+ {
73
+ "provider": "openrouter",
74
+ "model": "z-ai/glm-5.3-flash",
75
+ "maxTokens": 36000,
76
+ "lab": "glm5.3-flash"
77
+ },
78
+ {
79
+ "provider": "openrouter",
80
+ "model": "qwen/qwen3.7-plus",
81
+ "maxTokens": 36000,
82
+ "lab": "qwen3.7-plus"
83
+ },
84
+ {
85
+ "provider": "openrouter",
86
+ "model": "minimax/minimax-m3",
87
+ "maxTokens": 36000,
88
+ "lab": "minimax-m3"
89
+ },
90
+ {
91
+ "provider": "openrouter",
92
+ "model": "mistralai/mistral-medium-3-5",
93
+ "maxTokens": 36000,
94
+ "lab": "mistral-medium3.5"
95
+ }
96
+ ]
97
+ }
98
+ }
@@ -0,0 +1,93 @@
1
+ {
2
+ "name": "cheap-7",
3
+ "description": "SUPERSEDED by cheap-7-v2, and deliberately left failing chain-lint's self-review check, so it will not run - kept unmodified as the record of what the 2026-09-20 run actually used. Sonnet 5 holds the criteria, skeleton, builder, reviser and handoff seats AND a critic seat here, so it voted on its own draft under unanimous signoff; that is the defect cheap-7-v2 fixes. Do not add \"selfReview\": \"allowed\" to make this runnable again - use cheap-7-v2. Original description follows. Seven labs' small/cheap models, one seat each, all through one OpenRouter key: Anthropic Sonnet 5, OpenAI GPT-5 mini, Google Gemini 3.7 Flash, DeepSeek v3.2, Z.ai GLM 5.3 Flash, Qwen 3.5 Plus, MiniMax M3. Blind proposals, debate, unanimous signoff. Every seat gets a 36000-token ceiling and reasoning is left on: a debate is not squeezed to a short answer, and a reply cut off at the ceiling is retried once, then the seat is re-asked alone - it is never counted as agreement. The cap is a ceiling, not a price; only generated tokens are billed. Sonnet 5 builds and revises. For small questions where every model should still get a say; the frontier equivalent is reserved for questions worth its price. Prices are from src/pricing.json - price a real task with `npm run dry` before running.",
4
+ "maxRounds": 3,
5
+ "signoff": "unanimous",
6
+ "proposals": {
7
+ "parts": 3,
8
+ "maxTokens": 4000
9
+ },
10
+ "debate": true,
11
+ "handoff": true,
12
+ "estimate": {
13
+ "promptTokens": 10000,
14
+ "draftTokens": 10000,
15
+ "critiqueTokens": 5000
16
+ },
17
+ "seats": {
18
+ "criteria": {
19
+ "provider": "openrouter",
20
+ "model": "anthropic/claude-sonnet-5",
21
+ "maxTokens": 36000,
22
+ "lab": "sonnet5"
23
+ },
24
+ "skeleton": {
25
+ "provider": "openrouter",
26
+ "model": "anthropic/claude-sonnet-5",
27
+ "maxTokens": 36000,
28
+ "lab": "sonnet5"
29
+ },
30
+ "builder": {
31
+ "provider": "openrouter",
32
+ "model": "anthropic/claude-sonnet-5",
33
+ "maxTokens": 36000,
34
+ "lab": "sonnet5"
35
+ },
36
+ "reviser": {
37
+ "provider": "openrouter",
38
+ "model": "anthropic/claude-sonnet-5",
39
+ "maxTokens": 36000,
40
+ "lab": "sonnet5"
41
+ },
42
+ "handoff": {
43
+ "provider": "openrouter",
44
+ "model": "anthropic/claude-sonnet-5",
45
+ "maxTokens": 36000,
46
+ "lab": "sonnet5"
47
+ },
48
+ "critics": [
49
+ {
50
+ "provider": "openrouter",
51
+ "model": "anthropic/claude-sonnet-5",
52
+ "maxTokens": 36000,
53
+ "lab": "sonnet5"
54
+ },
55
+ {
56
+ "provider": "openrouter",
57
+ "model": "openai/gpt-5-mini",
58
+ "maxTokens": 36000,
59
+ "lab": "gpt5-mini"
60
+ },
61
+ {
62
+ "provider": "openrouter",
63
+ "model": "google/gemini-3.7-flash",
64
+ "maxTokens": 36000,
65
+ "lab": "gemini3.7-flash"
66
+ },
67
+ {
68
+ "provider": "openrouter",
69
+ "model": "deepseek/deepseek-v3.2",
70
+ "maxTokens": 36000,
71
+ "lab": "deepseek-v3.2"
72
+ },
73
+ {
74
+ "provider": "openrouter",
75
+ "model": "z-ai/glm-5.3-flash",
76
+ "maxTokens": 36000,
77
+ "lab": "glm5.3-flash"
78
+ },
79
+ {
80
+ "provider": "openrouter",
81
+ "model": "qwen/qwen3.5-plus-20260420",
82
+ "maxTokens": 36000,
83
+ "lab": "qwen3.5-plus"
84
+ },
85
+ {
86
+ "provider": "openrouter",
87
+ "model": "minimax/minimax-m3",
88
+ "maxTokens": 36000,
89
+ "lab": "minimax-m3"
90
+ }
91
+ ]
92
+ }
93
+ }
@@ -0,0 +1,56 @@
1
+ {
2
+ "name": "coder-gate-v1",
3
+ "description": "MLLM Coder v1 (relay/runs/2026-09-14T16-14-10-757Z/deliverable.md). The governed unit is one diff against one pre-named file/hunk, not prose. The `propose` seat is external: THCMCP never writes code itself, it hands the change-request task file to an outside coding session and gets one fenced diff back (docs/coder-gate-diff-format.md). The `builder` seat is also external, held to the same session, and must return the proposal's diff verbatim as this chain's draft - there is no second, independent code-writing step; `builder` exists only because every chain needs one to reach a draft, not because a second author writes anything. `verify` (config.verify.enabled: true) wires the existing run_tests mechanism, but `verify.tools` ships empty here by design, not oversight: runVerification runs before any change-request/diff exists, and this repo has no `{{...}}` templating to inject a per-run target file/test command into a static chain config - a filled-in entry as specced would be inert. No test command runs automatically today (see test/coder-gate-verify.test.js's IN-3 fixture for how the mechanism works when a real, per-run `verify.tools` entry IS supplied downstream). No write-capable tool is used anywhere - applying the diff to a real working tree stays a human/external action. Built from existing stage types (proposal, critic, unanimous signoff); `debate: true` is set for forward compatibility but is currently unreachable - with one proposer and `proposals.parts: 1`, at most one proposal ever exists, and `runChain`'s debate stage only runs when `proposals.length > 1`, so v1 has no live debate today. No change to src/chain.js or src/tools.js.",
4
+ "maxRounds": 2,
5
+ "signoff": "unanimous",
6
+ "proposals": {
7
+ "parts": 1,
8
+ "maxTokens": 4000
9
+ },
10
+ "estimate": {
11
+ "promptTokens": 3000,
12
+ "draftTokens": 3000,
13
+ "critiqueTokens": 1000
14
+ },
15
+ "seats": {
16
+ "criteria": {
17
+ "provider": "anthropic",
18
+ "model": "claude-sonnet-5",
19
+ "maxTokens": 2000
20
+ },
21
+ "skeleton": {
22
+ "provider": "anthropic",
23
+ "model": "claude-sonnet-5",
24
+ "maxTokens": 1000
25
+ },
26
+ "proposers": [
27
+ {
28
+ "provider": "external",
29
+ "model": "claude-code-session",
30
+ "lab": "external-proposer"
31
+ }
32
+ ],
33
+ "builder": {
34
+ "provider": "external",
35
+ "model": "claude-code-session"
36
+ },
37
+ "critics": [
38
+ {
39
+ "provider": "anthropic",
40
+ "model": "claude-sonnet-5",
41
+ "maxTokens": 8000
42
+ },
43
+ {
44
+ "provider": "openai",
45
+ "model": "gpt-5",
46
+ "maxTokens": 8000
47
+ }
48
+ ]
49
+ },
50
+ "debate": true,
51
+ "handoff": false,
52
+ "verify": {
53
+ "enabled": true,
54
+ "tools": []
55
+ }
56
+ }