@event4u/agent-config 14.5.0 → 14.7.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.
Files changed (203) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/CHANGELOG.md +384 -3
  3. package/README.md +1 -1
  4. package/dist/agent-src/commands/analyze/decision.md +7 -0
  5. package/dist/agent-src/commands/analyze/inbox.md +264 -10
  6. package/dist/agent-src/commands/analyze.md +1 -1
  7. package/dist/agent-src/commands/optimize/project.md +10 -0
  8. package/dist/agent-src/commands/roadmap/process-full.md +132 -4
  9. package/dist/agent-src/contexts/execution/roadmap-execution-contract.md +31 -0
  10. package/dist/agent-src/contexts/execution/roadmap-process-loop.md +161 -1
  11. package/dist/agent-src/rules/context-hygiene.md +2 -0
  12. package/dist/agent-src/rules/decision-revisit-gate.md +111 -7
  13. package/dist/agent-src/rules/fix-what-you-see.md +108 -0
  14. package/dist/agent-src/rules/no-roadmap-references.md +0 -5
  15. package/dist/agent-src/rules/recurring-criticism.md +110 -0
  16. package/dist/agent-src/rules/roadmap-progress-sync.md +1 -1
  17. package/dist/agent-src/rules/rule-type-governance.md +0 -2
  18. package/dist/agent-src/rules/self-repair-loop.md +17 -0
  19. package/dist/agent-src/rules/skill-quality.md +0 -2
  20. package/dist/agent-src/rules/source-confidentiality.md +37 -7
  21. package/dist/agent-src/scripts/archival_sweep.ts +117 -0
  22. package/dist/agent-src/scripts/archive_completed_roadmaps.ts +19 -3
  23. package/dist/agent-src/scripts/gate_budget.ts +282 -0
  24. package/dist/agent-src/scripts/gate_execute.ts +72 -31
  25. package/dist/agent-src/scripts/roadmap_gates.ts +74 -3
  26. package/dist/agent-src/scripts/update_roadmap_progress.ts +251 -7
  27. package/dist/agent-src/skills/adr-create/SKILL.md +25 -3
  28. package/dist/agent-src/skills/ai-council/SKILL.md +48 -807
  29. package/dist/agent-src/skills/ai-council/references/advanced-modes.md +320 -0
  30. package/dist/agent-src/skills/ai-council/references/cost-and-redaction.md +99 -0
  31. package/dist/agent-src/skills/ai-council/references/execution-modes.md +162 -0
  32. package/dist/agent-src/skills/ai-council/references/output-and-synthesis.md +125 -0
  33. package/dist/agent-src/skills/ai-council/references/procedure.md +143 -0
  34. package/dist/agent-src/skills/decision-review/SKILL.md +18 -0
  35. package/dist/agent-src/skills/quality-tools/SKILL.md +34 -326
  36. package/dist/agent-src/skills/quality-tools/references/js-ts-tools.md +113 -0
  37. package/dist/agent-src/skills/quality-tools/references/php-tools.md +222 -0
  38. package/dist/agent-src/skills/roadmap-management/SKILL.md +15 -409
  39. package/dist/agent-src/skills/roadmap-management/references/archival.md +226 -0
  40. package/dist/agent-src/skills/roadmap-management/references/authoring.md +107 -0
  41. package/dist/agent-src/skills/roadmap-management/references/dashboard.md +47 -0
  42. package/dist/agent-src/skills/roadmap-management/references/lifecycle.md +58 -0
  43. package/dist/agent-src/skills/skill-writing/SKILL.md +34 -570
  44. package/dist/agent-src/skills/skill-writing/references/procedure.md +275 -0
  45. package/dist/agent-src/skills/skill-writing/references/read-only-scripts.md +18 -0
  46. package/dist/agent-src/skills/skill-writing/references/section-patterns.md +298 -0
  47. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  48. package/dist/agent-src/templates/roadmaps.md +45 -2
  49. package/dist/agent-src/templates/scripts/telemetry/flush_sender.mjs +163 -0
  50. package/dist/agent-src/templates/scripts/telemetry/remote.ts +160 -7
  51. package/dist/agent-src/templates/scripts/telemetry/transport.ts +169 -0
  52. package/dist/cli/registry.js +1 -1
  53. package/dist/cli/registry.js.map +1 -1
  54. package/dist/cli-delegate/chunk-2GNWGMAL.js +172 -0
  55. package/dist/cli-delegate/{chunk-RLN73PR5.js → chunk-4VR4ORQ6.js} +10 -7
  56. package/dist/cli-delegate/chunk-6EOCNQAM.js +402 -0
  57. package/dist/cli-delegate/{chunk-XURJ4AQC.js → chunk-74E3TKWV.js} +381 -280
  58. package/dist/cli-delegate/{chunk-3UCJWMMP.js → chunk-7F3VYSM2.js} +4 -4
  59. package/dist/cli-delegate/{chunk-BKO2AZ7Z.js → chunk-B2ERU2VA.js} +1 -1
  60. package/dist/cli-delegate/{chunk-NXFWFAYV.js → chunk-G23AT6GD.js} +1 -0
  61. package/dist/cli-delegate/{chunk-63WSP6YZ.js → chunk-GJ5BVHXM.js} +72 -165
  62. package/dist/cli-delegate/{chunk-ZPSXJTLI.js → chunk-JZ4NR2TW.js} +353 -1
  63. package/dist/cli-delegate/chunk-MWRD5YOH.js +100 -0
  64. package/dist/cli-delegate/{chunk-GRRPEPRN.js → chunk-T7L2QK3K.js} +24 -5
  65. package/dist/cli-delegate/{chunk-EVTY7ISR.js → chunk-YM4GZDJG.js} +9 -1
  66. package/dist/cli-delegate/cmd_conformance.js +459 -709
  67. package/dist/cli-delegate/cmd_doctor.js +6 -6
  68. package/dist/cli-delegate/cmd_explain.js +1 -1
  69. package/dist/cli-delegate/cmd_export.js +7 -6
  70. package/dist/cli-delegate/cmd_handoff.js +6 -6
  71. package/dist/cli-delegate/cmd_packs_active.js +1 -1
  72. package/dist/cli-delegate/cmd_preflight.js +2 -2
  73. package/dist/cli-delegate/cmd_prune.js +7 -6
  74. package/dist/cli-delegate/cmd_session_recycle.js +840 -30
  75. package/dist/cli-delegate/cmd_settings_migrate.js +7 -6
  76. package/dist/cli-delegate/cmd_settings_set.js +1 -1
  77. package/dist/cli-delegate/cmd_sync.js +7 -6
  78. package/dist/cli-delegate/cmd_uninstall.js +9 -7
  79. package/dist/cli-delegate/cmd_update.js +1 -1
  80. package/dist/cli-delegate/cmd_upgrade.js +1 -1
  81. package/dist/cli-delegate/cmd_validate.js +7 -6
  82. package/dist/discovery/deprecation-report.md +1 -1
  83. package/dist/discovery/discovery-manifest.json +72 -29
  84. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  85. package/dist/discovery/discovery-manifest.summary.md +4 -4
  86. package/dist/discovery/dormancy-report.md +1 -1
  87. package/dist/discovery/orphan-report.md +1 -1
  88. package/dist/discovery/packs.json +10 -8
  89. package/dist/discovery/trust-report.md +3 -3
  90. package/dist/discovery/workspaces.json +8 -6
  91. package/dist/hooks/dispatch.js +3127 -2022
  92. package/dist/install/claudePathsPlan.js +187 -0
  93. package/dist/install/claudePathsPlan.js.map +1 -0
  94. package/dist/install/hostLayerFingerprint.js +136 -0
  95. package/dist/install/hostLayerFingerprint.js.map +1 -0
  96. package/dist/install/install.mjs +553 -425
  97. package/dist/install/partitionEligibility.js +276 -0
  98. package/dist/install/partitionEligibility.js.map +1 -0
  99. package/dist/mcp/registry-manifest.json +3 -3
  100. package/dist/mcp/server.json +2 -2
  101. package/dist/mcp/server.mjs +1744 -1191
  102. package/dist/router.json +1 -1
  103. package/dist/scripts/_lib/agent_src.js +41 -0
  104. package/dist/scripts/_lib/agent_src.js.map +1 -1
  105. package/dist/scripts/_lib/install_layout.js +83 -0
  106. package/dist/scripts/_lib/install_layout.js.map +1 -0
  107. package/dist/scripts/_lib/installed_lock.js +444 -0
  108. package/dist/scripts/_lib/installed_lock.js.map +1 -0
  109. package/dist/scripts/condense.js +13 -164
  110. package/dist/scripts/condense.js.map +1 -1
  111. package/dist/server/schemas/settings.js +4 -0
  112. package/dist/server/schemas/settings.js.map +1 -1
  113. package/docs/contracts/settings-classes.md +12 -6
  114. package/docs/guidelines/agent-infra/agent-interaction-and-decision-quality.md +8 -3
  115. package/docs/guidelines/agent-infra/context-hygiene-mechanics.md +26 -0
  116. package/docs/guidelines/agent-infra/engineering-memory-data-format.md +49 -0
  117. package/docs/guidelines/agent-infra/memory-access.md +17 -0
  118. package/docs/guidelines/agent-infra/recurring-criticism-mechanics.md +96 -0
  119. package/package.json +1 -1
  120. package/src/agent-src/scripts/archival_sweep.ts +117 -0
  121. package/src/agent-src/scripts/archive_completed_roadmaps.ts +19 -3
  122. package/src/agent-src/scripts/gate_budget.ts +282 -0
  123. package/src/agent-src/scripts/gate_execute.ts +72 -31
  124. package/src/agent-src/scripts/roadmap_gates.ts +74 -3
  125. package/src/agent-src/scripts/update_roadmap_progress.ts +251 -7
  126. package/src/agent-src/templates/scripts/telemetry/flush_sender.mjs +163 -0
  127. package/src/agent-src/templates/scripts/telemetry/remote.ts +160 -7
  128. package/src/agent-src/templates/scripts/telemetry/transport.ts +169 -0
  129. package/src/config/agent-settings.template.yml +27 -2
  130. package/src/config/ci-local-parity.yml +18 -0
  131. package/src/config/estate-count-budget.json +367 -3
  132. package/src/config/gate-violation-baselines.json +41 -41
  133. package/src/config/pack-size-budget.json +3 -2
  134. package/src/config/rule-activation-census.json +14 -6
  135. package/src/config/rule-stub-ceilings.json +19 -6
  136. package/src/install/claudePathsPlan.ts +196 -0
  137. package/src/install/hostLayerFingerprint.ts +145 -0
  138. package/src/install/partitionEligibility.ts +325 -0
  139. package/src/scripts/_cli/cmd_session_recycle.ts +9 -1
  140. package/src/scripts/_dispatch.bash +6 -1
  141. package/src/scripts/_lib/ac_heading.ts +30 -0
  142. package/src/scripts/_lib/agent_src.ts +42 -0
  143. package/src/scripts/_lib/bench_ab_pinned_repo.ts +162 -0
  144. package/src/scripts/_lib/bench_ab_workspace.ts +10 -1
  145. package/src/scripts/_lib/envelope_grounding.ts +38 -8
  146. package/src/scripts/_lib/installed_lock.ts +50 -5
  147. package/src/scripts/_lib/layer_overlap_notice.ts +85 -0
  148. package/src/scripts/_lib/md_section.ts +129 -0
  149. package/src/scripts/_lib/scope_guard.sh +86 -4
  150. package/src/scripts/_lib/self_repair.ts +19 -0
  151. package/src/scripts/_lib/self_repair_class_b.ts +171 -0
  152. package/src/scripts/_lib/subagent_capsule.ts +81 -1
  153. package/src/scripts/adr/regenerate_index.ts +13 -2
  154. package/src/scripts/adr_cite_check.ts +424 -0
  155. package/src/scripts/ai_council/cli_help.ts +55 -0
  156. package/src/scripts/before_complete_hook.ts +153 -28
  157. package/src/scripts/bench_ab_v2_complexity.ts +27 -7
  158. package/src/scripts/check_adr_frontmatter.ts +187 -1
  159. package/src/scripts/check_references.ts +60 -0
  160. package/src/scripts/check_release_published.ts +32 -11
  161. package/src/scripts/check_single_delivery.ts +517 -0
  162. package/src/scripts/ci_settle.ts +170 -0
  163. package/src/scripts/condense.ts +20 -170
  164. package/src/scripts/council_cli.ts +3 -3
  165. package/src/scripts/dispatch_r2_reviewer.ts +6 -14
  166. package/src/scripts/hook_manifest.json +1 -1
  167. package/src/scripts/hook_manifest.yaml +77 -14
  168. package/src/scripts/hooks/block_no_verify.ts +61 -10
  169. package/src/scripts/hooks/block_unauthorized_git.ts +1 -1
  170. package/src/scripts/hooks/concern_registry.ts +4 -0
  171. package/src/scripts/hooks/rtk_wrap_hook.ts +8 -3
  172. package/src/scripts/hooks/run_continuation_hook.ts +887 -68
  173. package/src/scripts/hooks/ship_diff_volume_hook.ts +81 -15
  174. package/src/scripts/hooks/source_first_gate_hook.ts +464 -0
  175. package/src/scripts/hooks/state_io.ts +782 -20
  176. package/src/scripts/hooks/subagent_ledger_hook.ts +44 -15
  177. package/src/scripts/hooks/telemetry_flush_hook.ts +139 -0
  178. package/src/scripts/hooks/telemetry_self_repair.ts +128 -0
  179. package/src/scripts/hooks/telemetry_usage_hook.ts +22 -4
  180. package/src/scripts/hooks/turn_end_gate_hook.ts +81 -15
  181. package/src/scripts/install.sh +12 -2
  182. package/src/scripts/install.ts +16 -11
  183. package/src/scripts/language_mirror_hook.ts +561 -25
  184. package/src/scripts/lint_framework_leakage_allowlist.json +2 -2
  185. package/src/scripts/lint_plan_risk_register.ts +4 -3
  186. package/src/scripts/lint_skill_router_head.ts +4 -4
  187. package/src/scripts/mcp_server/tools.ts +2 -2
  188. package/src/scripts/memory_consolidation.ts +189 -0
  189. package/src/scripts/memory_eviction.ts +384 -0
  190. package/src/scripts/new_roadmap.ts +136 -0
  191. package/src/scripts/pack_mcp_content.ts +20 -5
  192. package/src/scripts/release.ts +37 -38
  193. package/src/scripts/report_layer_overlap.ts +78 -0
  194. package/src/scripts/report_memory_pointers.ts +622 -0
  195. package/src/scripts/self_repair_hook.ts +37 -5
  196. package/src/scripts/session_register_hook.ts +115 -15
  197. package/src/scripts/skill_usage_collect.ts +11 -1
  198. package/src/scripts/skill_usage_report.ts +278 -8
  199. package/src/scripts/sync_pr_branch.ts +7 -0
  200. package/src/server/schemas/settings.ts +8 -0
  201. package/dist/cli-delegate/chunk-EJITJBJX.js +0 -172
  202. package/dist/cli-delegate/chunk-PZWRPRWP.js +0 -38
  203. /package/dist/cli-delegate/{chunk-RYNADUFG.js → chunk-LWTYTX6F.js} +0 -0
@@ -203,353 +203,48 @@ Anonymising the host as "Reviewer C" is worse than excluding it — the
203
203
  user is told they got an outside vote when they did not. Externals
204
204
  down → surface and skip; never substitute the host as a reviewer.
205
205
 
206
- ### Neutrality — context-handoff
206
+ ## Modes
207
207
 
208
- External reviewers do better critique when they know **what the
209
- project is**, not just what the artefact looks like. The council
210
- ships a neutral **handoff preamble** (modelled on `/agent-handoff`)
211
- in front of every member's system prompt, assembled by
212
- `prompts.handoff_preamble(project, original_ask)`:
208
+ This skill is a router head. Everything above is true in every mode and stays
209
+ here: which decision classes reach the council at all, what to do when it cannot
210
+ answer, the user-global configuration fact, the necessity self-check, and the
211
+ neutrality Iron Law. So does the output format below — it is an ordered MUST that
212
+ a pointer cannot carry. The operational manuals live in `references/`; load the
213
+ one the task calls for, not the set.
213
214
 
214
- | Carried | Forbidden |
215
- |---|---|
216
- | Project name (from `composer.json` / `package.json` / repo dir) | Host-agent identity (Augment, Claude Code, Cursor, Cline, Windsurf, Copilot agent) — stripped line-by-line before send |
217
- | Stack one-liner inferred from manifest files | Host-agent reasoning, prior turns, internal analysis |
218
- | One paragraph of repo purpose from `README.md` (max 400 chars) | Host-agent framing language ("I think this looks weak", "the user probably wants…") |
219
- | The user's **original ask** verbatim (the free-form sentence that triggered `/council`) | Anything the host agent generated about the artefact |
220
-
221
- `detect_project_context()` in `scripts/ai_council/project_context.ts`
222
- reads only the manifest files + root README; missing fields collapse
223
- to `None` and the preamble silently omits the line. With both
224
- `project=None` and `original_ask=""`, the preamble degrades to the
225
- bare `NEUTRALITY_PREAMBLE` (v1 shape — back-compat for callers that
226
- have not migrated yet).
227
-
228
- ## Execution modes
229
-
230
- A council member can run in one of three transports. The neutrality
231
- preamble is identical across all of them — only the path the bytes
232
- travel changes.
233
-
234
- | Mode | Client | Billable | Transport | Status |
235
- |---|---|---|---|---|
236
- | `api` | `AnthropicClient` / `OpenAIClient` / `GeminiClient` / `XAIClient` / `PerplexityClient` | yes | provider SDK + key from `~/.event4u/agent-config/<provider>.key` (legacy `~/.config/agent-config/<provider>.key` read as fallback) | shipped |
237
- | `manual` | `ManualClient` | no | `stdout` (prompt block) + `stdin` (user pastes the web-UI reply, terminated by a line containing only `END`) | shipped (Phase 2b) |
238
- | `cli` | `AnthropicCliClient` / `OpenAICliClient` / `GeminiCliClient` | no (subscription-authed) | local subprocess against the vendor CLI (`claude`, `codex`, `gemini`); auth delegated to the CLI's own session, no API key flows through this process | shipped (anthropic/openai/gemini · Phase 3) |
239
-
240
- Resolution lives in `scripts/ai_council/modes.ts`:
241
- `resolve_mode(name, invocation_mode, member_settings, global_mode)`
242
- with precedence **invocation flag > per-member setting > global
243
- setting > default (`manual`)**. Whitespace-and-case insensitive; empty
244
- strings fall through; unknown values raise `InvalidModeError` with
245
- the offending settings path (`ai_council.mode`,
246
- `ai_council.members.<name>.mode`, or `/council mode=`).
247
-
248
- ### Manual-mode UX
249
-
250
- `ManualClient` is the user-as-transport variant: the agent prints
251
- one Markdown block per member (system prompt + handoff preamble +
252
- artefact between two `═` rules), the user pastes it into a web
253
- chat (Claude.ai, ChatGPT, Gemini), then pastes the reply back
254
- ending with a line containing only `END`. After each reply, a 1/2/3
255
- menu surfaces:
256
-
257
- 1. More feedback for this member (continue this thread)
258
- 2. Done with this member, move to the next
259
- 3. Abort the council run
260
-
261
- `1` re-emits a follow-up block addressed to the **same chat
262
- thread** (no system prompt repetition). `2` records the round and
263
- moves to the next member. `3` returns `error="manual_aborted"` for
264
- that member and the orchestrator stops the fan-out.
265
-
266
- ### CLI-mode UX
267
-
268
- `mode: cli` runs the council through the vendor's local CLI
269
- instead of the API. Authentication is delegated — the user logs
270
- into each CLI once (`claude login`, `codex login`, `gemini`), and
271
- the orchestrator inherits the subscription. No API key flows
272
- through this process. `billable=False`, so the cost gate is
273
- bypassed; the local `cli_call_budget.max_calls_per_day.<provider>`
274
- quota (state at `~/.event4u/agent-config/cli-calls.json`, daily
275
- UTC reset) is the only per-day brake.
276
-
277
- Three vendor CLIs are wired:
278
-
279
- - **Anthropic / Claude** — invokes `claude --print --output-format json`
280
- and parses the standard envelope (`result` + `usage` + `session_id`
281
- + `total_cost_usd`). Token counts and reported cost survive to
282
- `metadata` for audit.
283
-
284
- ```yaml
285
- members:
286
- anthropic:
287
- enabled: true
288
- mode: cli
289
- model: claude-sonnet-4-5
290
- ```
291
-
292
- - **OpenAI / Codex** — invokes `codex exec --json -` with the prompt piped on
293
- stdin, and walks the newline-delimited JSON event stream, pulling text from
294
- `item.completed` and tokens from `turn.completed`. Session id is preserved.
295
- Unlike the Anthropic client, there is **no separate system-prompt channel**:
296
- `codex exec` has no `--system` flag, so a system prompt is prepended to the
297
- user prompt in the same payload.
298
-
299
- ```yaml
300
- members:
301
- openai:
302
- enabled: true
303
- mode: cli
304
- model: gpt-5
305
- ```
306
-
307
- - **Google / Gemini** — invokes `gemini --output-format json` with
308
- the prompt piped on stdin, parses the `response` + `stats.models.<m>.tokens`
309
- envelope. OAuth consent must be granted once interactively before
310
- the CLI is usable from a non-interactive shell. Like Codex and unlike Claude,
311
- it has **no system-prompt flag** — `--system` is rejected outright with
312
- `Unknown argument: system` — so the system prompt is prepended to the piped
313
- payload.
314
-
315
- Two caveats before enabling it, both measured 2026-08-12 and neither resolved.
316
- The CLI's own `--help` says `-p/--prompt` is what selects non-interactive
317
- mode, and this invocation passes neither `-p` nor the `query` positional;
318
- whether piped stdin alone keeps it headless is **unestablished**. And the
319
- free tier now refuses this client outright with `IneligibleTierError`, so a
320
- round-trip could not be completed here at all. Enable it only if you can
321
- confirm both on your own account.
322
-
323
- ```yaml
324
- members:
325
- gemini:
326
- enabled: false # see the two caveats above before flipping this
327
- mode: cli
328
- model: gemini-2.5-pro
329
- ```
330
-
331
- Auth-failure stderr from any vendor CLI surfaces as
332
- `error="auth_expired"` with the original stderr tail in
333
- `metadata.stderr_tail` so the user knows to re-login. A missing
334
- binary at construction time fails fast with `CouncilDisabledError`
335
- naming the binary and the YAML override path — never silently
336
- substitutes.
337
-
338
- `xai` + `perplexity` accept `mode: cli` from Phase 4 onward, but
339
- their community CLIs DO consume the API key and DO NOT bypass
340
- per-token billing — the contract doc warns explicitly.
341
-
342
- Both take a single `-p <prompt>` and have no second channel, so the system
343
- prompt is folded into that same value. Until 2026-08-12 it was **discarded**,
344
- and these two members answered every question with no role, no neutrality
345
- framing and no output contract while the run counted the reply as a peer
346
- verdict. Two consequences worth knowing: their whole prompt travels on argv, so
347
- a very large one can fail with `os_error: E2BIG` (the response carries a `hint`
348
- saying so), and because their CLIs report no usage block, the input side of
349
- their cost is an estimate rather than a provider figure.
350
-
351
- ### Cost-gate bypass for non-billable members
352
-
353
- `ExternalAIClient.billable` is the contract. Clients with
354
- `billable=False` (`ManualClient`, `AnthropicCliClient`,
355
- `OpenAICliClient`, `GeminiCliClient`) bypass the cost gate entirely —
356
- the orchestrator skips the
357
- projection check, the `on_overrun` callback, and the USD-budget
358
- short-circuit for that member, but still records the response's
359
- token counts (from the manual-paste length heuristic or the
360
- provider's reply, when available) for observability. Mixed runs
361
- (one cli + one api) gate only the api members.
362
-
363
- ## Degradation modes
364
-
365
- How the council behaves when fewer than two billable members are
366
- reachable. The orchestrator never silently substitutes — degradation
367
- is visible to the user.
368
-
369
- | Reachable | Behaviour | Independence |
215
+ | Task | Mode body | Covers |
370
216
  |---|---|---|
371
- | **2+** | Full fan-out, multi-round debate. Default. | High — cross-provider diversity. |
372
- | **1** | Single-voice critique with a degraded-run warning. Multi-round mode lets the model see its own anonymised reply, but convergence ≠ correctness. | Low — shared blind spots. |
373
- | **0** | Council skipped. Surface the failure, proceed without external review. **Never** substitute the host or an unrequested manual pass. | None. |
374
-
375
- Rejected anti-patterns (council convergence, 2026-05-06): persona
376
- prompts (same model, same blind spots, more cost), temperature
377
- spread (noise, not signal), host-as-fallback (Iron Law breach).
378
- Supported single-provider strategy is **sibling models on the same
379
- provider** (e.g. Sonnet ↔ Opus, gpt-4o ↔ o1) — different training
380
- cutoffs / reasoning architectures within one provider family. Cost
381
- is real (siblings price-tier higher); explicit opt-in per invocation,
382
- not a default.
217
+ | Pick an execution mode, or handle a degraded one | [`references/execution-modes.md`](references/execution-modes.md) | Manual-mode and CLI-mode UX, the cost-gate bypass for non-billable members, degradation modes |
218
+ | Run a session end to end | [`references/procedure.md`](references/procedure.md) | The neutrality context-handoff, the numbered procedure, the convener-skeptic stance, why a mechanism claim needs a probe rather than a second opinion, what this is NOT |
219
+ | Place the artefact, or render the synthesis | [`references/output-and-synthesis.md`](references/output-and-synthesis.md) | Output path convention with its forbidden and exempt sets, lens-aware synthesis templates, the `--prose-synthesis` escape hatch, renderer lens resolution |
220
+ | Estimate or gate the spend, or check what is redacted | [`references/cost-and-redaction.md`](references/cost-and-redaction.md) | Redaction expectations, cost awareness, the pre-call estimate format, the stale price-table gate, the mid-flow overrun callback |
221
+ | Multi-round debate, deep tier, advisors, replay, low-impact fast-path | [`references/advanced-modes.md`](references/advanced-modes.md) | `rounds:N` debate, the deep-reasoning tier and its manual-mode parity, `/council debate`, Karpathy peer-review, thinking-style advisors, the decision-replay artefact, the Lightweight-QA fast-path with its own Iron Law and output markers |
222
+
223
+ Two of those bodies carry obligations a pointer cannot summarise: the
224
+ output-path convention is enforced by CI, and the Lightweight-QA fast-path
225
+ markers are required verbatim by
226
+ [`fast-path-marker-visibility`](../../rules/fast-path-marker-visibility.md).
227
+ Load the body before acting in either mode rather than working from memory of it.
383
228
 
384
229
  ## Procedure
385
230
 
386
- 1. **Resolve target.** Identify the artefact mode (`prompt`, `roadmap`,
387
- `diff`, `files`) and locate the source. Refuse to proceed if the
388
- target is ambiguous.
389
- 2. **Bundle + redact.** Call `scripts/ai_council/bundler.ts` to produce
390
- a redacted artefact bundle. If `BundleTooLarge` fires, surface the
391
- size and ask the user to narrow scope — do NOT truncate silently.
392
- 3. **Clear the spend bound.** The council is standing-authorized — there is
393
- no per-invocation approval. What still binds is a *bound*, resolved in
394
- this order:
395
- - **No billable member** (every member is `mode: cli` under
396
- subscription auth — `billable=False`) → nothing is spent. Render the
397
- estimate table as information and fan out. No gate.
398
- - **Billable members with a configured ceiling** (`cost_budget.max_total_usd`
399
- non-zero, or `daily_limit_usd` non-zero) → the ceiling **is** the
400
- authorization the user already gave. Render the estimate and fan out.
401
- `on_overrun` still fires per member on breach (below) — that is where
402
- the user regains the decision.
403
- - **Billable members with no ceiling at all** (`max_total_usd: 0` AND
404
- `daily_limit_usd: 0`) → unbounded paid spend, so surface the estimate
405
- and require an explicit `1`. Nothing bounds the call, so the user must.
406
-
407
- Autonomy settings do not *create* a bound and do not lift the last case.
408
- Consumers who want the old per-run gate back set a small
409
- `cost_budget.max_total_usd`: every call then breaches and `on_overrun`
410
- asks, per member.
411
- 4. **Fan out.** Dispatch the bundle to each enabled council member via
412
- `scripts/ai_council/orchestrator.ts`. Each member receives the
413
- neutrality preamble from `prompts.ts` plus the artefact — nothing
414
- from the host agent's prior reasoning.
415
- 5. **Render results.** Stack each member's response under its own
416
- provider-attributed heading. Never merge or paraphrase responses
417
- into the host agent's voice.
418
- 6. **Summarise.** Write a `Convergence / Divergence` block listing
419
- agreements, disagreements, and unique insights — provider-attributed.
420
- 7. **Critically evaluate** every finding before it leaves the host
421
- (see *Critical evaluation* below). The host is the convener **and**
422
- the skeptic — never a reviewer of the artefact itself, but always a
423
- reviewer of the **council's output**.
424
- 8. **Translate validated findings to options.** Convert each finding
425
- the host accepts (or accepts with modification) into a concrete
426
- numbered option for the user. Tag every option with the host's
427
- verdict so the user sees the agent's reasoned position, not the
428
- council's raw output. The user decides; the council advises; the
429
- host filters.
430
-
431
- ## Critical evaluation — convener-skeptic stance
432
-
433
- ```
434
- COUNCIL CONVERGENCE IS NOT CORRECTNESS.
435
- DO NOT BLINDLY ACCEPT FINDINGS. DO NOT BLINDLY REJECT THEM.
436
- EVERY FINDING GETS A REASONED VERDICT BEFORE IT REACHES THE USER.
437
- ```
438
-
439
- ### Mechanism claims need a probe, not a second opinion
440
-
441
- ```
442
- A MECHANISM CLAIM IN A COUNCIL ARTEFACT IS MARKED `unverified:` UNTIL A PROBE COVERS IT.
443
- A VERDICT RESTING ON AN UNVERIFIED MECHANISM CLAIM DOES NOT BIND.
444
- SEVERAL MODELS AGREEING MULTIPLIES PLAUSIBILITY. IT DOES NOT PRODUCE EVIDENCE.
445
- ```
446
-
447
- A **mechanism claim** asserts how the machine behaves: "this toggle removes the
448
- cost", "that gate scans X", "the host reads the router". The council deliberates
449
- over **arguments**, never against the running system — it cannot execute a command,
450
- so it has no way to falsify one. Marking such a claim `unverified:` in the artefact
451
- keeps the reader from mistaking a well-argued mechanism for a measured one, and the
452
- non-binding clause means the fix for a wrong claim is a probe, not a re-vote.
453
-
454
- **Case zero (2026-07-29).** An accepted ADR claimed a compile-time toggle gave
455
- "zero-cost dormancy" because the rule was dropped from `dist/router.json`. Two
456
- council members praised the reasoning; neither could check it. A one-line `grep`
457
- later showed the toggle was read by the router compiler and by **nothing in the
458
- projector**, so the rule's body kept shipping as a file — and the host reads the
459
- file. The claim was half wrong, the verdict that rested on it was void, and what
460
- caught it was a probe, not a third opinion.
461
-
462
- The council is **uninformed about the codebase, ADRs, locked
463
- contracts, prior decisions, and project history** — it sees only the
464
- artefact + neutrality preamble. That is the source of its diversity
465
- **and** its blind spots. Convergence between members can mean shared
466
- generic best-practice priors, not project-specific correctness.
467
-
468
- The host applies a critical lens to **every finding** (convergence
469
- **and** divergence) before surfacing it as a numbered option:
470
-
471
- | Check | Question | Tool |
472
- |---|---|---|
473
- | **Codebase fit** | Does the finding match the actual code, files, signatures, conventions? | `view` / `codebase-retrieval` / `grep` |
474
- | **Locked-decision conflict** | Does it contradict an ADR, kernel rule, contract under `docs/contracts/`, or `docs/decisions/`? | `view` |
475
- | **Already addressed** | Is it a generic best-practice already covered by an existing rule, skill, or test? | `view` / `grep` |
476
- | **Cost / benefit** | Is the change worth the diff size, churn, and review cost vs. the marginal benefit? | reasoning |
477
- | **Hallucination** | Does the finding cite a file, function, or behavior that does not exist? | `view` |
478
-
479
- Each finding receives one of three verdicts:
480
-
481
- - **`accept`** — codebase fits, no locked-decision conflict, benefit clears cost. Surface as a normal numbered option.
482
- - **`accept-with-modification`** — core insight valid, but the proposed shape needs adjusting (wrong file, contradicts ADR detail, scope creep). Surface with the **modified** patch and a one-line note.
483
- - **`reject`** — finding is wrong (hallucinated reference, contradicts a locked decision, already addressed, generic noise). Surface as a **Rejected by host** entry with a one-line reason. Still visible — the user can override.
484
-
485
- The verdict is the host's **own** reasoning, not the council's.
486
- Pretending convergence equals correctness, or paraphrasing council
487
- output as host analysis, both breach the [`direct-answers`](../../rules/direct-answers.md)
488
- no-invented-facts rule. When the host cannot reach a confident
489
- verdict on a finding (mixed evidence, ambiguous scope), it surfaces
490
- the finding as `needs-input` with the open question — the user
491
- decides, the host does not guess.
492
-
493
- ### What this is NOT
494
-
495
- - **Not a re-review by the host.** The host did not write the artefact independently and cannot critique it independently — that boundary still holds.
496
- - **Not a vote against the council.** Rejecting a finding requires evidence (file, line, contract reference), not preference.
497
- - **Not silent filtering.** Every finding reaches the user with its verdict and reason. The user can pick a `reject` option and override the host.
498
-
499
- ## Output path convention
500
-
501
- Council artefacts (questions, responses, sessions) are **dev-time
502
- scratch** — gitignored in both the package repo and consumer repos
503
- and auto-pruned after `ai_council.session_retention_days` (default
504
- 7). They inform a decision; they are not the durable contract. The
505
- durable contract lives in the roadmap / ADR / skill body that cites
506
- the council's convergence inline.
507
-
508
- **Linking to a specific council file is forbidden by
509
- [`no-roadmap-references`](../../rules/no-roadmap-references.md)
510
- (council clause)** — gitignored, not in the cloned repo, gone after
511
- the retention window. Inline the convergence with date + members
512
- instead.
513
-
514
- Three directories, three modes:
515
-
516
- | Mode | Path | Format |
517
- |---|---|---|
518
- | **Topic-anchored question** (paired with a roadmap or ADR) | `agents/runtime/council/questions/<topic-slug>.md` | Markdown |
519
- | **Topic-anchored response** (paired with the question above) | `agents/runtime/council/responses/<topic-slug>.json` | JSON from `council:run --output` |
520
- | **Ad-hoc session** (no durable artefact yet) | `agents/runtime/council/sessions/<UTC-timestamp>.json` | JSON from `council:run --output` |
521
-
522
- `<topic-slug>` is kebab-case and **must match** the corresponding
523
- roadmap / ADR slug if one exists (e.g. `path-fixes` mirrors the
524
- matching `road-to-<topic-slug>` roadmap under `agents/roadmaps/`).
525
-
526
- ### Forbidden
527
-
528
- - Files at `agents/` root (e.g. `agents/runtime/council/question-foo.md`).
529
- - Dot-prefix scratch (e.g. `agents/.council-question-foo.md`).
530
- - Any other directory below `agents/` (e.g. `agents/scratch/`,
531
- `agents/evidence/notes/`). Operator scratch belongs under
532
- `agents/runtime/tmp/` (gitignored).
533
- - Cross-references from any artefact to specific council files —
534
- see [`no-roadmap-references`](../../rules/no-roadmap-references.md)
535
- (council clause). Inline the convergence summary instead, with
536
- date and member list for traceability (`Council (claude-sonnet-4-5
537
- + gpt-4o, YYYY-MM-DD) reviewed N candidate strategies; converged
538
- on …`).
539
-
540
- ### Exempt
541
-
542
- - `agents/evidence/audits/` — historical audit bundles. The canonical
543
- council dirs are gitignored; audit bundles are tracked,
544
- cohesive narratives that may include council artefacts as
545
- part of their evidence trail (e.g. `audits/2026-05-14-north-star/`
546
- bundling its triggering question, raw responses, and synthesis
547
- alongside the audit's findings). The layout linter
548
- (`scripts/check_council_layout.ts`) skips this directory.
549
-
550
- `scripts/check_council_layout.ts` is the mechanical check for the
551
- output path convention — wire it into the package's CI pipeline so
552
- violations break the build.
231
+ 1. **Inspect first.** Run the necessity self-check above and read the artefact
232
+ you are about to hand over. It is cheaper to not convene than to convene and
233
+ discard.
234
+ 2. **Confirm availability** — `agent-config council:status`, never an inference
235
+ from the project tree (see § Configuration is ALWAYS user-global).
236
+ 3. **Pick the execution mode** from
237
+ [`references/execution-modes.md`](references/execution-modes.md).
238
+ 4. **Run the session** per the numbered procedure in
239
+ [`references/procedure.md`](references/procedure.md), under the neutrality
240
+ Iron Law above — the preamble is not optional and the question is never
241
+ authored toward a conclusion.
242
+ 5. **Estimate the spend before the call** per
243
+ [`references/cost-and-redaction.md`](references/cost-and-redaction.md).
244
+ 6. **Write the artefact** in the output format below, at the path
245
+ [`references/output-and-synthesis.md`](references/output-and-synthesis.md)
246
+ fixes, then apply the convener-skeptic verdict yourself — convergence is not
247
+ correctness.
553
248
 
554
249
  ## Output format
555
250
 
@@ -596,69 +291,6 @@ attributed to the host.
596
291
  > counting council votes. Mirrored in `code-review` so the boundary is
597
292
  > grep-checkable from both sides.
598
293
 
599
- ## Synthesis templates (lens-aware)
600
-
601
- The **Convergence / Divergence** slot in `council:render` output is
602
- populated with a lens-specific synthesis prompt. The host agent reads
603
- this prompt and writes the summary in the shape it dictates. The five
604
- templates live in `scripts/ai_council/prompts.ts::_SYNTHESIS_TABLE`
605
- and are exposed via `synthesis_template(mode)`.
606
-
607
- **R4 Q4 split** — decision lenses get a structured Karpathy-style
608
- template; creative lenses keep an open-ended prose body. **Every lens
609
- now closes with two required verdict-discipline sections** — **Kill
610
- criteria** (observable falsifiers with a threshold or event, checkable
611
- without re-convening the council) and **Concrete next step** (exactly
612
- one artefact-producing action) — added so no synthesis ships an
613
- unfalsifiable verdict (road-to-opt-council-deliberation Phase 0):
614
-
615
- | Lens | Class | Synthesis sections |
616
- |---|---|---|
617
- | `default` | decision | Agreement · Clashes · Blind spots · Recommendation · **Kill criteria · Concrete next step** |
618
- | `pr` | decision | Consensus · Conflicts · Must-fix before merge · Recommendation · **Kill criteria · Concrete next step** |
619
- | `analysis` | decision | Top-10 by consensus · Supporting · Outliers · **Kill criteria · Concrete next step** |
620
- | `design` | creative | open prose body + **Kill criteria · Concrete next step** |
621
- | `optimize` | creative | open prose body + **Kill criteria · Concrete next step** |
622
-
623
- Input modes (`prompt` / `roadmap` / `diff` / `files`) inherit the
624
- `default` decision template — they are bundling shapes, not lenses.
625
-
626
- **Source citations:**
627
- * Template shape — Round 2 council verdict
628
- (`agents/runtime/council/sessions/2026-05-14-ai-council-redesign/round-1.md`,
629
- Opus's lens-adaptive synthesis proposal).
630
- * Decision/creative split — Round 4 Q4 verdict
631
- (`agents/runtime/council/sessions/2026-05-14-ai-council-redesign/round-3-responses.json`).
632
- R4 reframed `optimize` as creative because perf trade-offs resist
633
- pre-templated shape — Performance-wins / Trade-offs /
634
- Implementation-order is too rigid for the variety of optimize-lens
635
- artefacts. R4 reframed `design` for the same reason — design
636
- critiques are inherently narrative.
637
-
638
- ### `--prose-synthesis` escape hatch (R4 Q4)
639
-
640
- Both `council:run` and `council:render` accept symmetric escape-hatch
641
- flags on top of the lens table:
642
-
643
- * `--prose-synthesis` — force creative-lens passthrough (bare slot)
644
- regardless of lens. Use when the user on `default`/`pr`/`analysis`
645
- prefers a narrative recommendation over the structured template.
646
- * `--no-prose-synthesis` — force the `default` structured template
647
- even on a creative lens. Use when a `design` or `optimize` artefact
648
- has a one-shot need for Karpathy-style structure.
649
-
650
- The flag is mutually exclusive — picking one disables the other on
651
- the same invocation. When `council:run` records either flag in the
652
- output JSON, `council:render` honours it unless the renderer is
653
- called with an explicit flag of its own.
654
-
655
- ### Renderer lens resolution
656
-
657
- `council:render <responses.json>` resolves the active lens in this
658
- order: explicit `--prompt-mode` flag > `prompt_mode` field in the
659
- payload > `mode` field in the payload > `None` (default decision
660
- template). The `--prose-synthesis` / `--no-prose-synthesis` flag
661
- overrides the table regardless of how the lens resolved.
662
294
 
663
295
  ## Do NOT
664
296
 
@@ -704,412 +336,21 @@ Real failure modes seen in the wild:
704
336
  | Reject a finding on preference, not evidence. | "I don't like this" is not a verdict. | Cite the file, line, ADR, or contract that justifies the rejection — or surface as `needs-input`. |
705
337
  | Paraphrase council output into the host's own analysis to defend a verdict. | Strips attribution, breaches `direct-answers` no-invented-facts. | Verdict cites host evidence (file:line); council output stays attributed in the per-member sections. |
706
338
 
707
- ## Redaction expectations
708
-
709
- The bundler's redaction pass strips:
710
-
711
- - Paths matching `~/.event4u/agent-config/*.key` and the legacy
712
- `~/.config/agent-config/*.key`.
713
- - Lines starting with `Authorization:`.
714
- - `key = …`, `secret = …`, `token = …`, `password = …` assignments.
715
- - `sk-ant-…` and `sk-…` token-like strings.
716
-
717
- If your artefact contains other sensitive data (customer names,
718
- internal hostnames, contractual prose) you are responsible for
719
- scrubbing it before bundling. The redaction pass is a **floor**, not
720
- a ceiling.
721
-
722
- ## Cost awareness
723
-
724
- Every consultation hits a paid API. The orchestrator enforces
725
- per-invocation caps from `ai_council.cost_budget`:
726
-
727
- - `max_input_tokens` / `max_output_tokens` — token caps across all members.
728
- - `max_total_usd` — per-invocation USD ceiling. `0` disables the USD ceiling (token caps still apply).
729
- - `max_calls` — maximum number of council members per invocation.
730
- - `daily_limit_usd` — rolling 24h spend cap across all `/council`
731
- invocations. `0` disables. Persists in
732
- `~/.event4u/agent-config/council-spend.jsonl` (mode 0600; legacy
733
- `~/.config/agent-config/council-spend.jsonl` read as fallback). Breach
734
- fires `on_overrun(event)` with `event.breach_kind == "daily"` and,
735
- if the callback returns False or is absent, tags the member
736
- `daily_budget_exceeded` instead of `cost_budget_exceeded`.
737
-
738
- Prices come from `agents/runtime/.agent-prices.md` (gitignored, refreshed weekly).
739
- The pricing module bootstraps it from `_default_prices.ts` on first
740
- use and flags it stale when older than the most recent Monday 00:00
741
- UTC.
742
-
743
- ### Pre-call estimate format
744
-
745
- Before the cost gate, compute `orchestrator.estimate(question, members,
746
- table)` and render a per-member table. Heuristic: `len(text) / 4` for
747
- input, member's `max_tokens` ceiling for output (actual spend is
748
- usually lower).
749
-
750
- > External council call — billable
751
- >
752
- > Mode: roadmap · Target: `agents/roadmaps/<name>.md` (~3 KB after redaction)
753
- >
754
- > | member | est. in / out tokens | est. USD |
755
- > |---------------------------------|---------------------:|---------:|
756
- > | anthropic / claude-sonnet-4-5 | ~750 / 1024 | $0.0176 |
757
- > | openai / gpt-4o | ~750 / 1024 | $0.0121 |
758
- > | **total** | | **$0.0297** |
759
- >
760
- > Budget: 50k in / 20k out tokens · USD ceiling: $0.50
761
- >
762
- > 1. Run the consultation
763
- > 2. Cancel
764
-
765
- ### Stale price-table gate
766
-
767
- If `pricing.is_stale(table)` returns true, ask before proceeding:
339
+ ## Redaction and cost
768
340
 
769
- > Price table is stale (last_updated: YYYY-MM-DD)
770
- > 1. Refresh now (`./scripts-run src/scripts/update_prices`)
771
- > 2. Continue with the stale table
772
- > 3. Cancel
341
+ Both moved verbatim to
342
+ [`references/cost-and-redaction.md`](references/cost-and-redaction.md): what the
343
+ bundler's redaction pass strips, the cost-awareness rules, the pre-call estimate
344
+ format, the stale price-table gate, and the mid-flow overrun callback. A breach
345
+ without `on_overrun` short-circuits the remaining members — surface the partial
346
+ result and ask, never retry silently.
773
347
 
774
- Do not silently auto-refresh — the user keeps control.
775
-
776
- ### Mid-flow overrun callback (`on_overrun`)
777
-
778
- The orchestrator runs members **sequentially**. Before each member
779
- whose projected spend would breach a cap, it invokes the
780
- `on_overrun(event)` callback. The callback returns `True` to proceed
781
- with that member (raises the effective ceiling for THIS call only)
782
- or `False` to skip and record `cost_budget_exceeded`. The callback
783
- fires again for every subsequent breaching member — the user keeps
784
- control on each step.
785
-
786
- > Cost budget overrun — pausing before next member
787
- >
788
- > Member: openai / gpt-4o (member 2 of 2)
789
- > Already spent: ~620 in / ~480 out tokens · $0.0094
790
- > Next call estimate: ~750 in / 1024 out tokens · $0.0121
791
- > **Projected total after this call: $0.0215** (ceiling: $0.0150)
792
- >
793
- > 1. Continue with this member
794
- > 2. Skip this member (records `cost_budget_exceeded`, continues with the rest)
795
-
796
- Without `on_overrun`, breaching short-circuits all remaining members
797
- (v1 fallback). Do not retry silently. Surface the partial result and
798
- ask the user.
799
-
800
- ## Multi-round debate (`rounds:N`)
801
-
802
- `consult(..., rounds=N)` enables 2-3 round critique loops. Round 1
803
- runs the standard single-round flow. Round 2+ rebuilds the user
804
- prompt as `<original artefact> + <prior round, anonymised>` so each
805
- member can refine, agree, or push back on the previous critique
806
- without seeing which provider produced which point.
807
-
808
- The default round count comes from `defaults.min_rounds` in
809
- `~/.event4u/agent-config/settings/.ai-council.yml` (default `2` so members critique each other
810
- at least once before convergence). The host agent does **not** ask
811
- "how many rounds?" when the requested count is `<= min_rounds` —
812
- the settings owner already made that decision. Ask only when a
813
- genuinely complex artefact justifies more depth than the default.
814
-
815
- ### Deep-reasoning tier (`council_depth: deep`)
816
-
817
- Architecture review, refactoring proposals, and bug-diagnosis runs
818
- benefit from an extra critique round. The deep tier is opt-in per
819
- artefact:
820
-
821
- 1. The consuming **rule, skill, or command** declares
822
- `council_depth: deep` in its frontmatter. The schema accepts
823
- **only `deep`** — `standard` is the implicit default and is
824
- rejected by the linter (every frontmatter byte costs context
825
- window; see `scripts/schemas/{rule,skill,command}.schema.json`).
826
- To return an artefact to default depth, **delete the key**.
827
- 2. The **host agent** reads that frontmatter when it dispatches the
828
- council and passes `--depth deep` to `council_cli`. If multiple
829
- active artefacts disagree, **deep wins** (max policy).
830
- 3. The **CLI** floors the round count at
831
- `max(ai_council.deep_min_rounds, ai_council.min_rounds)` —
832
- defaults to `3` and `2` respectively. Lowering `deep_min_rounds`
833
- below `min_rounds` has no effect (defensive max).
834
-
835
- The CLI itself has no knowledge of frontmatter; the contract is the
836
- flag. Resolution chain (highest priority first):
837
-
838
- ```
839
- --rounds N → explicit, any value (user override)
840
- --depth deep → max(deep_min_rounds, min_rounds)
841
- (no flag) → min_rounds (default 2)
842
- ```
843
-
844
- | Property | Behaviour |
845
- |---|---|
846
- | Default count | `ai_council.min_rounds` (default `2`). Override per-invocation with `rounds:N` (or `--rounds N` to the CLI). |
847
- | Deep floor | `ai_council.deep_min_rounds` (default `3`). Activated by `council_depth: deep` in artefact frontmatter (host translates to `--depth deep`) or explicit `--depth deep` on the CLI. Floored at `min_rounds`. |
848
- | Anonymisation | Provider/model identity is stripped. Reviewers are labelled `Reviewer A / B / C…` in input order. |
849
- | Errored prior responses | Skipped — they reveal nothing useful and can leak provider error formats. |
850
- | Cost budget | Accumulates across rounds. A round-2 call that breaches the cap fires `on_overrun` exactly like a round-1 breach. |
851
- | Daily limit | Same — every billable round-2 call records spend in the rolling 24h ledger. |
852
- | Return value | Final round only. Use `on_round_complete(round_idx, responses)` to capture intermediate rounds for rendering. |
853
-
854
- > Iron Law: anonymisation is non-negotiable. If you ever need to
855
- > surface "which model said what" between rounds, that is a different
856
- > feature — debug-only, off by default, never enabled in user-facing
857
- > output. The neutrality contract dies the moment a member learns it
858
- > is talking to Claude vs GPT in round 2.
859
-
860
- Pre-call estimate must surface the round count: total = `N × single-round cost`. Render inline:
861
-
862
- ```
863
- External council call — billable · 2 rounds
864
- Round 1: artefact only
865
- Round 2: artefact + anonymised round 1 critiques
866
-
867
- | member | per-round | × 2 |
868
- |--------------------|----------:|--------:|
869
- | anthropic/sonnet | $0.0176 | $0.0352 |
870
- | openai/gpt-4o | $0.0121 | $0.0242 |
871
- | **total** | | $0.0594 |
872
- ```
873
-
874
- ### Manual-mode parity
875
-
876
- The orchestrator drives rounds the same way for `api` and `manual`
877
- transports. One round = one full pass over every enabled member,
878
- top-to-bottom, then `_augment_for_next_round()` folds the
879
- anonymised critiques into the round-N+1 user prompt. For manual
880
- mode this means: emit the round-1 block for member A → user
881
- pastes A's reply → next member B → user pastes B's reply → host
882
- agent consolidates round 1 → emit the round-2 block (now carrying
883
- the anonymised round-1 critiques) for member A → … and so on
884
- until the configured round count is reached. ManualClient's
885
- internal "more feedback" follow-up loop (1 / 2 / 3 menu) is
886
- **inside** a single member's chat thread and is orthogonal to the
887
- orchestrator-level rounds.
888
-
889
- ### `/council debate` sub-command (progressive disclosure)
890
-
891
- `/council debate <artefact> [--rounds N] [--continue-as-debate <session>]`
892
- runs an **interactive** multi-round critique with a confirmation gate
893
- between every round so the user can stop the spend at any point.
894
-
895
- | Property | Behaviour |
896
- |---|---|
897
- | Round flow | Same orchestrator as `rounds:N` (`run_debate()`), but each round prints its responses then pauses on a y/n prompt before launching the next round. |
898
- | Cost gate | After every round the CLI prints `Spent so far: $X · Next round: ~$Y · Cap: $Z`. `n` exits cleanly with partial results; `y` continues. |
899
- | Hard cap | If the projected next-round cost would breach `max_total_usd`, `run_debate()` raises `DebateCapExceeded` and the CLI exits with the partial transcript. No silent overrun. |
900
- | `--continue-as-debate` | Seeds round 1 from an existing `/council default` (or analysis lens) session. No round-1 API calls are billed; round 2+ run normally. Member list must match. |
901
- | Session files | One file per round under `agents/runtime/council/sessions/<slug>/debate-round-NN.md`. |
902
- | Anonymisation | Identical to `rounds:N`. The continue-as-debate path also anonymises the seeded round-1 responses when building the round-2 prompt. |
903
-
904
- Use this when the artefact is genuinely contentious and the user
905
- wants to control depth interactively. For a fire-and-forget
906
- multi-round run, prefer `consult(..., rounds=N)` or `--rounds N` on
907
- `/council default`.
908
-
909
-
910
- ## Karpathy peer-review (opt-in)
911
-
912
- After the final deliberation round, an optional **anonymous peer-review
913
- pass** lets each member critique the *other* members' responses for
914
- blind spots before synthesis. Inspired by Andrej Karpathy's "ask the
915
- strongest models to review each other anonymously" pattern; see his
916
- [talks / threads on inter-model critique](https://karpathy.ai/) and the
917
- internal verdict in
918
- `agents/runtime/council/sessions/2026-05-14-ai-council-redesign/round-2.md`
919
- (R2 split: one approve-as-flag, one reject-as-default → opt-in only).
920
-
921
- Pipeline order when every feature is active:
922
-
923
- ```
924
- deliberation rounds → peer-review → consensus-scoring → synthesis
925
- ```
926
-
927
- Activation — two equivalent paths:
928
-
929
- * CLI: `--peer-review` on `council:estimate` or `council:run`.
930
- * Config: `ai_council.peer_review.enabled: true` in
931
- `~/.event4u/agent-config/settings/.ai-council.yml`. Default is `false`.
932
-
933
- Mechanics:
934
-
935
- 1. The final deliberation round's outputs are anonymised into
936
- `Response-A`, `Response-B`, … in stable input order. Provider /
937
- model identity is stripped (Iron-Law neutrality holds); empty or
938
- errored deliberation responses are skipped.
939
- 2. Each member receives an N−1 view (its own response filtered out)
940
- plus the Karpathy prompt: *strongest response*, *weakest blind
941
- spot*, *what did everyone miss*, *refinement*.
942
- 3. The N critiques flow back into synthesis through a
943
- "Peer-Review-Surfaced Blind Spots" addendum on the lens template.
944
- 4. **Advisor preserve-persona (R4 Q3, hard-coded):** when the
945
- deliberation was an advisor-mode run (Phase 6), anonymisation
946
- strips provider identity but **preserves the advisor persona
947
- label**. Peer-review renders as `Response A (Contrarian)`, never
948
- `Response A (Anthropic Opus)`. Plain-member runs strip identity
949
- entirely.
950
-
951
- Cost — adds exactly N billable calls (one per member) at the same
952
- per-call cost as a deliberation call. The `council:estimate` table
953
- surfaces the delta as a `+peer-review: +N calls (~+$X)` row.
954
-
955
- Needs ≥ 2 distinct deliberation outputs; below that the round is a
956
- no-op and nothing extra is billed. Self-review is structurally
957
- impossible — a member never sees its own response.
958
-
959
- ## Thinking-style advisors (replace-mode)
960
-
961
- Phase 6 introduces five **advisor personas** that the council can adopt
962
- in *replace-mode*: an enabled advisor substitutes its bound member's
963
- plain call with the same provider running the advisor's persona prompt.
964
- Total call count stays the same as a plain run — only the system prompt
965
- swaps. Five advisors mirror an external advisor set, each a substantial
966
- persona file (not a tagline):
967
-
968
- | Advisor | Default bound member | Focus |
969
- |---|---|---|
970
- | **Contrarian** | `anthropic` | strongest counterargument, hidden assumptions |
971
- | **First-Principles** | `anthropic` | strip metaphor, derive from physics / math / cost |
972
- | **Expansionist** | `openai` | adjacent opportunities, second-order effects |
973
- | **Outsider** | `openai` | naive-but-sharp questions, beginner's-mind probes |
974
- | **Executor** | `anthropic` | what ships this quarter, what blocks delivery |
975
-
976
- Activation — edit `~/.event4u/agent-config/settings/.ai-council.yml` and flip the advisor's
977
- `enabled: true`. Optional `model: <name>` overrides the bound member's
978
- default model. Validation rule: an advisor referencing a disabled
979
- member fails closed at config load — never silently skipped.
980
-
981
- ```yaml
982
- advisors:
983
- contrarian:
984
- enabled: true # ← swap anthropic's plain call for contrarian
985
- member: anthropic
986
- # model: claude-opus-4 # optional pin
987
- ```
988
-
989
- `council:estimate` surfaces every active swap on a dedicated line above
990
- the cost table:
991
-
992
- ```
993
- council:estimate · mode=prompt · members=2 (billable=2)
994
- advisor: Contrarian on anthropic via claude-sonnet-4-5
995
- anthropic/claude-sonnet-4-5: ~991 in + 256 out = $0.0068
996
- openai/gpt-4o: ~208 in + 256 out = $0.0031
997
- ```
998
-
999
- Cost-bounded guarantee — replace-mode never adds calls. The advisor
1000
- persona prompt is larger than a plain prompt (~1k extra input tokens
1001
- per swap), so the per-call estimate widens slightly. Output tokens and
1002
- call count are unaffected.
1003
-
1004
- Peer-review interaction — when peer-review fires on an advisor-mode
1005
- run, anonymisation **preserves the advisor persona label** while
1006
- stripping provider identity: `Response A (Contrarian)` instead of bare
1007
- `Response A`. See §Karpathy peer-review point 4 for the contract.
1008
-
1009
- One-per-provider invariant — two enabled advisors targeting the same
1010
- member is a config error (replace-mode runs exactly one advisor per
1011
- provider; the call plan never doubles up by accident).
1012
-
1013
- ## Decision-replay artefact (Phase 9, audit trail)
1014
-
1015
- Every session that runs consensus scoring drops a
1016
- `decision-replay.md` next to the saved `responses.json`. Pure
1017
- projection of the consensus block plus the final-round per-member
1018
- texts — **no extra model calls, no extra spend**. Surfaces, per top
1019
- finding: verdict band (Strong/Moderate/Weak), evidence-quality bucket
1020
- (H/M/L), agree/dissent split, and one key argument per member.
1021
-
1022
- Two render modes:
1023
-
1024
- * **Full** (default) — per-member arguments attributed to
1025
- `provider:model`. Reasoning is traceable, vendor identity is
1026
- visible.
1027
- * **Redacted** — verdict + evidence-quality + counts only. Use for
1028
- surfaces where attributing reasoning to a specific model would leak
1029
- vendor-preference signal.
1030
-
1031
- Toggles (config, see `ai-council-config § Decision-replay artefact`):
1032
-
1033
- * `ai_council.decision_replay.enabled` — master switch (default
1034
- `true`).
1035
- * `ai_council.decision_replay.include_member_arguments` — flip to
1036
- `false` for redacted-by-default.
1037
- * `ai_council.lenses.<lens>.decision_replay.*` — per-lens override
1038
- beats the global block.
1039
-
1040
- CLI:
1041
-
1042
- * Written automatically by `council run` whenever the lens triggers
1043
- consensus scoring.
1044
- * `council replay <responses.json>` re-renders from a saved session;
1045
- `--redact-member-arguments` / `--include-member-arguments` flip the
1046
- view independent of config. Useful for sharing a redacted variant
1047
- of an already-paid run.
1048
-
1049
- ## Lightweight-QA fast-path (Phase 11)
1050
-
1051
- Low-impact questions classified by Phase 10's impact router can route
1052
- to a restricted fast-path instead of the full debate loop. The
1053
- trade-off is explicit: **1 round · ≤2 members · $0.05/answer · 2500
1054
- tokens**. No advisors, no peer-review, no consensus scoring — the goal
1055
- is a quick answer with a transparency marker, not a deliberation.
1056
-
1057
- ### Iron Law
1058
-
1059
- `high_impact` and `user_required` **never** route to the fast-path,
1060
- regardless of config. Schema validation rejects the override. The
1061
- fast-path only activates when:
1062
-
1063
- 1. `ai_council.enabled: true` AND
1064
- 2. `decision_resolution.low_impact.mode: council` AND
1065
- 3. At least one member has `participate_low_impact: true` (default
1066
- `false` — explicit opt-in per member).
1067
-
1068
- Default route for `low_impact` is **`agent`** — nothing reaches the
1069
- council without an explicit two-knob opt-in (flip the class to
1070
- `council` *and* mark at least one member `participate_low_impact: true`).
1071
- See [`ai-council-config § Low-impact council opt-in`](../../../docs/contracts/ai-council-config.md#low-impact-council-opt-in)
1072
- for the worked YAML example, validation behaviour, and unavailable-marker
1073
- contract.
1074
-
1075
- ### Output marker (always surfaced)
1076
-
1077
- * **Resolved** — `> Resolved via low-impact council (anthropic): <one-line answer>`
1078
- * **Split** — `> Low-impact council split — escalating to user (anthropic: X / openai: Y):`
1079
- * **Aborted** — `> Low-impact council aborted (token cap) — escalating to user:`
1080
-
1081
- The marker is mandatory: the agent never silently substitutes a
1082
- fast-path verdict for its own answer.
1083
-
1084
- ### Session artefact
1085
-
1086
- Every fast-path attempt appends one line to
1087
- `agents/runtime/council/sessions/<date>-<slug>/low-impact-resolutions.md`:
1088
-
1089
- ```
1090
- 2025-05-14T10:00:00Z | resolved | members=2/2 | members(anthropic, openai) cost=$0.0034 | Q=Service vs Repository for this read path?
1091
- ```
1092
-
1093
- Append-only, one line per resolution. The parser tolerates free-form
1094
- section headers around the canonical lines, so the artefact may grow
1095
- human notes without breaking aggregation.
1096
-
1097
- ### `council replay --low-impact-stats`
1098
-
1099
- Re-projection of the session log into a summary block:
1100
-
1101
- ```
1102
- $ council replay agents/runtime/council/sessions/2025-05-14-foo/responses.json --low-impact-stats
1103
- # Low-impact fast-path · session summary
1104
-
1105
- - attempts: 4
1106
- - status: aborted=1 · resolved=2 · split=1
1107
- - members: anthropic=4 · openai=3
1108
- - total cost: $0.0096
1109
- ```
348
+ ## Advanced modes
1110
349
 
1111
- No model calls — pure parse of the markdown log. Returns 0 when the
1112
- session had no fast-path entries (a clean session is not an error).
350
+ Multi-round debate, the deep-reasoning tier, Karpathy peer-review, thinking-style
351
+ advisors, the decision-replay artefact and the Lightweight-QA fast-path moved
352
+ verbatim to [`references/advanced-modes.md`](references/advanced-modes.md). Each
353
+ is opt-in and each prices higher than a single round; none is a default.
1113
354
 
1114
355
  ## See also
1115
356