@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.
- package/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +384 -3
- package/README.md +1 -1
- package/dist/agent-src/commands/analyze/decision.md +7 -0
- package/dist/agent-src/commands/analyze/inbox.md +264 -10
- package/dist/agent-src/commands/analyze.md +1 -1
- package/dist/agent-src/commands/optimize/project.md +10 -0
- package/dist/agent-src/commands/roadmap/process-full.md +132 -4
- package/dist/agent-src/contexts/execution/roadmap-execution-contract.md +31 -0
- package/dist/agent-src/contexts/execution/roadmap-process-loop.md +161 -1
- package/dist/agent-src/rules/context-hygiene.md +2 -0
- package/dist/agent-src/rules/decision-revisit-gate.md +111 -7
- package/dist/agent-src/rules/fix-what-you-see.md +108 -0
- package/dist/agent-src/rules/no-roadmap-references.md +0 -5
- package/dist/agent-src/rules/recurring-criticism.md +110 -0
- package/dist/agent-src/rules/roadmap-progress-sync.md +1 -1
- package/dist/agent-src/rules/rule-type-governance.md +0 -2
- package/dist/agent-src/rules/self-repair-loop.md +17 -0
- package/dist/agent-src/rules/skill-quality.md +0 -2
- package/dist/agent-src/rules/source-confidentiality.md +37 -7
- package/dist/agent-src/scripts/archival_sweep.ts +117 -0
- package/dist/agent-src/scripts/archive_completed_roadmaps.ts +19 -3
- package/dist/agent-src/scripts/gate_budget.ts +282 -0
- package/dist/agent-src/scripts/gate_execute.ts +72 -31
- package/dist/agent-src/scripts/roadmap_gates.ts +74 -3
- package/dist/agent-src/scripts/update_roadmap_progress.ts +251 -7
- package/dist/agent-src/skills/adr-create/SKILL.md +25 -3
- package/dist/agent-src/skills/ai-council/SKILL.md +48 -807
- package/dist/agent-src/skills/ai-council/references/advanced-modes.md +320 -0
- package/dist/agent-src/skills/ai-council/references/cost-and-redaction.md +99 -0
- package/dist/agent-src/skills/ai-council/references/execution-modes.md +162 -0
- package/dist/agent-src/skills/ai-council/references/output-and-synthesis.md +125 -0
- package/dist/agent-src/skills/ai-council/references/procedure.md +143 -0
- package/dist/agent-src/skills/decision-review/SKILL.md +18 -0
- package/dist/agent-src/skills/quality-tools/SKILL.md +34 -326
- package/dist/agent-src/skills/quality-tools/references/js-ts-tools.md +113 -0
- package/dist/agent-src/skills/quality-tools/references/php-tools.md +222 -0
- package/dist/agent-src/skills/roadmap-management/SKILL.md +15 -409
- package/dist/agent-src/skills/roadmap-management/references/archival.md +226 -0
- package/dist/agent-src/skills/roadmap-management/references/authoring.md +107 -0
- package/dist/agent-src/skills/roadmap-management/references/dashboard.md +47 -0
- package/dist/agent-src/skills/roadmap-management/references/lifecycle.md +58 -0
- package/dist/agent-src/skills/skill-writing/SKILL.md +34 -570
- package/dist/agent-src/skills/skill-writing/references/procedure.md +275 -0
- package/dist/agent-src/skills/skill-writing/references/read-only-scripts.md +18 -0
- package/dist/agent-src/skills/skill-writing/references/section-patterns.md +298 -0
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/agent-src/templates/roadmaps.md +45 -2
- package/dist/agent-src/templates/scripts/telemetry/flush_sender.mjs +163 -0
- package/dist/agent-src/templates/scripts/telemetry/remote.ts +160 -7
- package/dist/agent-src/templates/scripts/telemetry/transport.ts +169 -0
- package/dist/cli/registry.js +1 -1
- package/dist/cli/registry.js.map +1 -1
- package/dist/cli-delegate/chunk-2GNWGMAL.js +172 -0
- package/dist/cli-delegate/{chunk-RLN73PR5.js → chunk-4VR4ORQ6.js} +10 -7
- package/dist/cli-delegate/chunk-6EOCNQAM.js +402 -0
- package/dist/cli-delegate/{chunk-XURJ4AQC.js → chunk-74E3TKWV.js} +381 -280
- package/dist/cli-delegate/{chunk-3UCJWMMP.js → chunk-7F3VYSM2.js} +4 -4
- package/dist/cli-delegate/{chunk-BKO2AZ7Z.js → chunk-B2ERU2VA.js} +1 -1
- package/dist/cli-delegate/{chunk-NXFWFAYV.js → chunk-G23AT6GD.js} +1 -0
- package/dist/cli-delegate/{chunk-63WSP6YZ.js → chunk-GJ5BVHXM.js} +72 -165
- package/dist/cli-delegate/{chunk-ZPSXJTLI.js → chunk-JZ4NR2TW.js} +353 -1
- package/dist/cli-delegate/chunk-MWRD5YOH.js +100 -0
- package/dist/cli-delegate/{chunk-GRRPEPRN.js → chunk-T7L2QK3K.js} +24 -5
- package/dist/cli-delegate/{chunk-EVTY7ISR.js → chunk-YM4GZDJG.js} +9 -1
- package/dist/cli-delegate/cmd_conformance.js +459 -709
- package/dist/cli-delegate/cmd_doctor.js +6 -6
- package/dist/cli-delegate/cmd_explain.js +1 -1
- package/dist/cli-delegate/cmd_export.js +7 -6
- package/dist/cli-delegate/cmd_handoff.js +6 -6
- package/dist/cli-delegate/cmd_packs_active.js +1 -1
- package/dist/cli-delegate/cmd_preflight.js +2 -2
- package/dist/cli-delegate/cmd_prune.js +7 -6
- package/dist/cli-delegate/cmd_session_recycle.js +840 -30
- package/dist/cli-delegate/cmd_settings_migrate.js +7 -6
- package/dist/cli-delegate/cmd_settings_set.js +1 -1
- package/dist/cli-delegate/cmd_sync.js +7 -6
- package/dist/cli-delegate/cmd_uninstall.js +9 -7
- package/dist/cli-delegate/cmd_update.js +1 -1
- package/dist/cli-delegate/cmd_upgrade.js +1 -1
- package/dist/cli-delegate/cmd_validate.js +7 -6
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +72 -29
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +4 -4
- package/dist/discovery/dormancy-report.md +1 -1
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +10 -8
- package/dist/discovery/trust-report.md +3 -3
- package/dist/discovery/workspaces.json +8 -6
- package/dist/hooks/dispatch.js +3127 -2022
- package/dist/install/claudePathsPlan.js +187 -0
- package/dist/install/claudePathsPlan.js.map +1 -0
- package/dist/install/hostLayerFingerprint.js +136 -0
- package/dist/install/hostLayerFingerprint.js.map +1 -0
- package/dist/install/install.mjs +553 -425
- package/dist/install/partitionEligibility.js +276 -0
- package/dist/install/partitionEligibility.js.map +1 -0
- package/dist/mcp/registry-manifest.json +3 -3
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +1744 -1191
- package/dist/router.json +1 -1
- package/dist/scripts/_lib/agent_src.js +41 -0
- package/dist/scripts/_lib/agent_src.js.map +1 -1
- package/dist/scripts/_lib/install_layout.js +83 -0
- package/dist/scripts/_lib/install_layout.js.map +1 -0
- package/dist/scripts/_lib/installed_lock.js +444 -0
- package/dist/scripts/_lib/installed_lock.js.map +1 -0
- package/dist/scripts/condense.js +13 -164
- package/dist/scripts/condense.js.map +1 -1
- package/dist/server/schemas/settings.js +4 -0
- package/dist/server/schemas/settings.js.map +1 -1
- package/docs/contracts/settings-classes.md +12 -6
- package/docs/guidelines/agent-infra/agent-interaction-and-decision-quality.md +8 -3
- package/docs/guidelines/agent-infra/context-hygiene-mechanics.md +26 -0
- package/docs/guidelines/agent-infra/engineering-memory-data-format.md +49 -0
- package/docs/guidelines/agent-infra/memory-access.md +17 -0
- package/docs/guidelines/agent-infra/recurring-criticism-mechanics.md +96 -0
- package/package.json +1 -1
- package/src/agent-src/scripts/archival_sweep.ts +117 -0
- package/src/agent-src/scripts/archive_completed_roadmaps.ts +19 -3
- package/src/agent-src/scripts/gate_budget.ts +282 -0
- package/src/agent-src/scripts/gate_execute.ts +72 -31
- package/src/agent-src/scripts/roadmap_gates.ts +74 -3
- package/src/agent-src/scripts/update_roadmap_progress.ts +251 -7
- package/src/agent-src/templates/scripts/telemetry/flush_sender.mjs +163 -0
- package/src/agent-src/templates/scripts/telemetry/remote.ts +160 -7
- package/src/agent-src/templates/scripts/telemetry/transport.ts +169 -0
- package/src/config/agent-settings.template.yml +27 -2
- package/src/config/ci-local-parity.yml +18 -0
- package/src/config/estate-count-budget.json +367 -3
- package/src/config/gate-violation-baselines.json +41 -41
- package/src/config/pack-size-budget.json +3 -2
- package/src/config/rule-activation-census.json +14 -6
- package/src/config/rule-stub-ceilings.json +19 -6
- package/src/install/claudePathsPlan.ts +196 -0
- package/src/install/hostLayerFingerprint.ts +145 -0
- package/src/install/partitionEligibility.ts +325 -0
- package/src/scripts/_cli/cmd_session_recycle.ts +9 -1
- package/src/scripts/_dispatch.bash +6 -1
- package/src/scripts/_lib/ac_heading.ts +30 -0
- package/src/scripts/_lib/agent_src.ts +42 -0
- package/src/scripts/_lib/bench_ab_pinned_repo.ts +162 -0
- package/src/scripts/_lib/bench_ab_workspace.ts +10 -1
- package/src/scripts/_lib/envelope_grounding.ts +38 -8
- package/src/scripts/_lib/installed_lock.ts +50 -5
- package/src/scripts/_lib/layer_overlap_notice.ts +85 -0
- package/src/scripts/_lib/md_section.ts +129 -0
- package/src/scripts/_lib/scope_guard.sh +86 -4
- package/src/scripts/_lib/self_repair.ts +19 -0
- package/src/scripts/_lib/self_repair_class_b.ts +171 -0
- package/src/scripts/_lib/subagent_capsule.ts +81 -1
- package/src/scripts/adr/regenerate_index.ts +13 -2
- package/src/scripts/adr_cite_check.ts +424 -0
- package/src/scripts/ai_council/cli_help.ts +55 -0
- package/src/scripts/before_complete_hook.ts +153 -28
- package/src/scripts/bench_ab_v2_complexity.ts +27 -7
- package/src/scripts/check_adr_frontmatter.ts +187 -1
- package/src/scripts/check_references.ts +60 -0
- package/src/scripts/check_release_published.ts +32 -11
- package/src/scripts/check_single_delivery.ts +517 -0
- package/src/scripts/ci_settle.ts +170 -0
- package/src/scripts/condense.ts +20 -170
- package/src/scripts/council_cli.ts +3 -3
- package/src/scripts/dispatch_r2_reviewer.ts +6 -14
- package/src/scripts/hook_manifest.json +1 -1
- package/src/scripts/hook_manifest.yaml +77 -14
- package/src/scripts/hooks/block_no_verify.ts +61 -10
- package/src/scripts/hooks/block_unauthorized_git.ts +1 -1
- package/src/scripts/hooks/concern_registry.ts +4 -0
- package/src/scripts/hooks/rtk_wrap_hook.ts +8 -3
- package/src/scripts/hooks/run_continuation_hook.ts +887 -68
- package/src/scripts/hooks/ship_diff_volume_hook.ts +81 -15
- package/src/scripts/hooks/source_first_gate_hook.ts +464 -0
- package/src/scripts/hooks/state_io.ts +782 -20
- package/src/scripts/hooks/subagent_ledger_hook.ts +44 -15
- package/src/scripts/hooks/telemetry_flush_hook.ts +139 -0
- package/src/scripts/hooks/telemetry_self_repair.ts +128 -0
- package/src/scripts/hooks/telemetry_usage_hook.ts +22 -4
- package/src/scripts/hooks/turn_end_gate_hook.ts +81 -15
- package/src/scripts/install.sh +12 -2
- package/src/scripts/install.ts +16 -11
- package/src/scripts/language_mirror_hook.ts +561 -25
- package/src/scripts/lint_framework_leakage_allowlist.json +2 -2
- package/src/scripts/lint_plan_risk_register.ts +4 -3
- package/src/scripts/lint_skill_router_head.ts +4 -4
- package/src/scripts/mcp_server/tools.ts +2 -2
- package/src/scripts/memory_consolidation.ts +189 -0
- package/src/scripts/memory_eviction.ts +384 -0
- package/src/scripts/new_roadmap.ts +136 -0
- package/src/scripts/pack_mcp_content.ts +20 -5
- package/src/scripts/release.ts +37 -38
- package/src/scripts/report_layer_overlap.ts +78 -0
- package/src/scripts/report_memory_pointers.ts +622 -0
- package/src/scripts/self_repair_hook.ts +37 -5
- package/src/scripts/session_register_hook.ts +115 -15
- package/src/scripts/skill_usage_collect.ts +11 -1
- package/src/scripts/skill_usage_report.ts +278 -8
- package/src/scripts/sync_pr_branch.ts +7 -0
- package/src/server/schemas/settings.ts +8 -0
- package/dist/cli-delegate/chunk-EJITJBJX.js +0 -172
- package/dist/cli-delegate/chunk-PZWRPRWP.js +0 -38
- /package/dist/cli-delegate/{chunk-RYNADUFG.js → chunk-LWTYTX6F.js} +0 -0
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
# ai-council — advanced modes
|
|
2
|
+
|
|
3
|
+
> Mode body of the [`ai-council`](../SKILL.md) skill (router-head retrofit,
|
|
4
|
+
> 2026-08-20). Content moved VERBATIM from SKILL.md — load this file when the
|
|
5
|
+
> mode table in SKILL.md routes here.
|
|
6
|
+
|
|
7
|
+
## Multi-round debate (`rounds:N`)
|
|
8
|
+
|
|
9
|
+
`consult(..., rounds=N)` enables 2-3 round critique loops. Round 1
|
|
10
|
+
runs the standard single-round flow. Round 2+ rebuilds the user
|
|
11
|
+
prompt as `<original artefact> + <prior round, anonymised>` so each
|
|
12
|
+
member can refine, agree, or push back on the previous critique
|
|
13
|
+
without seeing which provider produced which point.
|
|
14
|
+
|
|
15
|
+
The default round count comes from `defaults.min_rounds` in
|
|
16
|
+
`~/.event4u/agent-config/settings/.ai-council.yml` (default `2` so members critique each other
|
|
17
|
+
at least once before convergence). The host agent does **not** ask
|
|
18
|
+
"how many rounds?" when the requested count is `<= min_rounds` —
|
|
19
|
+
the settings owner already made that decision. Ask only when a
|
|
20
|
+
genuinely complex artefact justifies more depth than the default.
|
|
21
|
+
|
|
22
|
+
### Deep-reasoning tier (`council_depth: deep`)
|
|
23
|
+
|
|
24
|
+
Architecture review, refactoring proposals, and bug-diagnosis runs
|
|
25
|
+
benefit from an extra critique round. The deep tier is opt-in per
|
|
26
|
+
artefact:
|
|
27
|
+
|
|
28
|
+
1. The consuming **rule, skill, or command** declares
|
|
29
|
+
`council_depth: deep` in its frontmatter. The schema accepts
|
|
30
|
+
**only `deep`** — `standard` is the implicit default and is
|
|
31
|
+
rejected by the linter (every frontmatter byte costs context
|
|
32
|
+
window; see `scripts/schemas/{rule,skill,command}.schema.json`).
|
|
33
|
+
To return an artefact to default depth, **delete the key**.
|
|
34
|
+
2. The **host agent** reads that frontmatter when it dispatches the
|
|
35
|
+
council and passes `--depth deep` to `council_cli`. If multiple
|
|
36
|
+
active artefacts disagree, **deep wins** (max policy).
|
|
37
|
+
3. The **CLI** floors the round count at
|
|
38
|
+
`max(ai_council.deep_min_rounds, ai_council.min_rounds)` —
|
|
39
|
+
defaults to `3` and `2` respectively. Lowering `deep_min_rounds`
|
|
40
|
+
below `min_rounds` has no effect (defensive max).
|
|
41
|
+
|
|
42
|
+
The CLI itself has no knowledge of frontmatter; the contract is the
|
|
43
|
+
flag. Resolution chain (highest priority first):
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
--rounds N → explicit, any value (user override)
|
|
47
|
+
--depth deep → max(deep_min_rounds, min_rounds)
|
|
48
|
+
(no flag) → min_rounds (default 2)
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
| Property | Behaviour |
|
|
52
|
+
|---|---|
|
|
53
|
+
| Default count | `ai_council.min_rounds` (default `2`). Override per-invocation with `rounds:N` (or `--rounds N` to the CLI). |
|
|
54
|
+
| 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`. |
|
|
55
|
+
| Anonymisation | Provider/model identity is stripped. Reviewers are labelled `Reviewer A / B / C…` in input order. |
|
|
56
|
+
| Errored prior responses | Skipped — they reveal nothing useful and can leak provider error formats. |
|
|
57
|
+
| Cost budget | Accumulates across rounds. A round-2 call that breaches the cap fires `on_overrun` exactly like a round-1 breach. |
|
|
58
|
+
| Daily limit | Same — every billable round-2 call records spend in the rolling 24h ledger. |
|
|
59
|
+
| Return value | Final round only. Use `on_round_complete(round_idx, responses)` to capture intermediate rounds for rendering. |
|
|
60
|
+
|
|
61
|
+
> Iron Law: anonymisation is non-negotiable. If you ever need to
|
|
62
|
+
> surface "which model said what" between rounds, that is a different
|
|
63
|
+
> feature — debug-only, off by default, never enabled in user-facing
|
|
64
|
+
> output. The neutrality contract dies the moment a member learns it
|
|
65
|
+
> is talking to Claude vs GPT in round 2.
|
|
66
|
+
|
|
67
|
+
Pre-call estimate must surface the round count: total = `N × single-round cost`. Render inline:
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
External council call — billable · 2 rounds
|
|
71
|
+
Round 1: artefact only
|
|
72
|
+
Round 2: artefact + anonymised round 1 critiques
|
|
73
|
+
|
|
74
|
+
| member | per-round | × 2 |
|
|
75
|
+
|--------------------|----------:|--------:|
|
|
76
|
+
| anthropic/sonnet | $0.0176 | $0.0352 |
|
|
77
|
+
| openai/gpt-4o | $0.0121 | $0.0242 |
|
|
78
|
+
| **total** | | $0.0594 |
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Manual-mode parity
|
|
82
|
+
|
|
83
|
+
The orchestrator drives rounds the same way for `api` and `manual`
|
|
84
|
+
transports. One round = one full pass over every enabled member,
|
|
85
|
+
top-to-bottom, then `_augment_for_next_round()` folds the
|
|
86
|
+
anonymised critiques into the round-N+1 user prompt. For manual
|
|
87
|
+
mode this means: emit the round-1 block for member A → user
|
|
88
|
+
pastes A's reply → next member B → user pastes B's reply → host
|
|
89
|
+
agent consolidates round 1 → emit the round-2 block (now carrying
|
|
90
|
+
the anonymised round-1 critiques) for member A → … and so on
|
|
91
|
+
until the configured round count is reached. ManualClient's
|
|
92
|
+
internal "more feedback" follow-up loop (1 / 2 / 3 menu) is
|
|
93
|
+
**inside** a single member's chat thread and is orthogonal to the
|
|
94
|
+
orchestrator-level rounds.
|
|
95
|
+
|
|
96
|
+
### `/council debate` sub-command (progressive disclosure)
|
|
97
|
+
|
|
98
|
+
`/council debate <artefact> [--rounds N] [--continue-as-debate <session>]`
|
|
99
|
+
runs an **interactive** multi-round critique with a confirmation gate
|
|
100
|
+
between every round so the user can stop the spend at any point.
|
|
101
|
+
|
|
102
|
+
| Property | Behaviour |
|
|
103
|
+
|---|---|
|
|
104
|
+
| 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. |
|
|
105
|
+
| 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. |
|
|
106
|
+
| 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. |
|
|
107
|
+
| `--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. |
|
|
108
|
+
| Session files | One file per round under `agents/runtime/council/sessions/<slug>/debate-round-NN.md`. |
|
|
109
|
+
| Anonymisation | Identical to `rounds:N`. The continue-as-debate path also anonymises the seeded round-1 responses when building the round-2 prompt. |
|
|
110
|
+
|
|
111
|
+
Use this when the artefact is genuinely contentious and the user
|
|
112
|
+
wants to control depth interactively. For a fire-and-forget
|
|
113
|
+
multi-round run, prefer `consult(..., rounds=N)` or `--rounds N` on
|
|
114
|
+
`/council default`.
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
## Karpathy peer-review (opt-in)
|
|
118
|
+
|
|
119
|
+
After the final deliberation round, an optional **anonymous peer-review
|
|
120
|
+
pass** lets each member critique the *other* members' responses for
|
|
121
|
+
blind spots before synthesis. Inspired by Andrej Karpathy's "ask the
|
|
122
|
+
strongest models to review each other anonymously" pattern; see his
|
|
123
|
+
[talks / threads on inter-model critique](https://karpathy.ai/) and the
|
|
124
|
+
internal verdict in
|
|
125
|
+
`agents/runtime/council/sessions/2026-05-14-ai-council-redesign/round-2.md`
|
|
126
|
+
(R2 split: one approve-as-flag, one reject-as-default → opt-in only).
|
|
127
|
+
|
|
128
|
+
Pipeline order when every feature is active:
|
|
129
|
+
|
|
130
|
+
```
|
|
131
|
+
deliberation rounds → peer-review → consensus-scoring → synthesis
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Activation — two equivalent paths:
|
|
135
|
+
|
|
136
|
+
* CLI: `--peer-review` on `council:estimate` or `council:run`.
|
|
137
|
+
* Config: `ai_council.peer_review.enabled: true` in
|
|
138
|
+
`~/.event4u/agent-config/settings/.ai-council.yml`. Default is `false`.
|
|
139
|
+
|
|
140
|
+
Mechanics:
|
|
141
|
+
|
|
142
|
+
1. The final deliberation round's outputs are anonymised into
|
|
143
|
+
`Response-A`, `Response-B`, … in stable input order. Provider /
|
|
144
|
+
model identity is stripped (Iron-Law neutrality holds); empty or
|
|
145
|
+
errored deliberation responses are skipped.
|
|
146
|
+
2. Each member receives an N−1 view (its own response filtered out)
|
|
147
|
+
plus the Karpathy prompt: *strongest response*, *weakest blind
|
|
148
|
+
spot*, *what did everyone miss*, *refinement*.
|
|
149
|
+
3. The N critiques flow back into synthesis through a
|
|
150
|
+
"Peer-Review-Surfaced Blind Spots" addendum on the lens template.
|
|
151
|
+
4. **Advisor preserve-persona (R4 Q3, hard-coded):** when the
|
|
152
|
+
deliberation was an advisor-mode run (Phase 6), anonymisation
|
|
153
|
+
strips provider identity but **preserves the advisor persona
|
|
154
|
+
label**. Peer-review renders as `Response A (Contrarian)`, never
|
|
155
|
+
`Response A (Anthropic Opus)`. Plain-member runs strip identity
|
|
156
|
+
entirely.
|
|
157
|
+
|
|
158
|
+
Cost — adds exactly N billable calls (one per member) at the same
|
|
159
|
+
per-call cost as a deliberation call. The `council:estimate` table
|
|
160
|
+
surfaces the delta as a `+peer-review: +N calls (~+$X)` row.
|
|
161
|
+
|
|
162
|
+
Needs ≥ 2 distinct deliberation outputs; below that the round is a
|
|
163
|
+
no-op and nothing extra is billed. Self-review is structurally
|
|
164
|
+
impossible — a member never sees its own response.
|
|
165
|
+
|
|
166
|
+
## Thinking-style advisors (replace-mode)
|
|
167
|
+
|
|
168
|
+
Phase 6 introduces five **advisor personas** that the council can adopt
|
|
169
|
+
in *replace-mode*: an enabled advisor substitutes its bound member's
|
|
170
|
+
plain call with the same provider running the advisor's persona prompt.
|
|
171
|
+
Total call count stays the same as a plain run — only the system prompt
|
|
172
|
+
swaps. Five advisors mirror an external advisor set, each a substantial
|
|
173
|
+
persona file (not a tagline):
|
|
174
|
+
|
|
175
|
+
| Advisor | Default bound member | Focus |
|
|
176
|
+
|---|---|---|
|
|
177
|
+
| **Contrarian** | `anthropic` | strongest counterargument, hidden assumptions |
|
|
178
|
+
| **First-Principles** | `anthropic` | strip metaphor, derive from physics / math / cost |
|
|
179
|
+
| **Expansionist** | `openai` | adjacent opportunities, second-order effects |
|
|
180
|
+
| **Outsider** | `openai` | naive-but-sharp questions, beginner's-mind probes |
|
|
181
|
+
| **Executor** | `anthropic` | what ships this quarter, what blocks delivery |
|
|
182
|
+
|
|
183
|
+
Activation — edit `~/.event4u/agent-config/settings/.ai-council.yml` and flip the advisor's
|
|
184
|
+
`enabled: true`. Optional `model: <name>` overrides the bound member's
|
|
185
|
+
default model. Validation rule: an advisor referencing a disabled
|
|
186
|
+
member fails closed at config load — never silently skipped.
|
|
187
|
+
|
|
188
|
+
```yaml
|
|
189
|
+
advisors:
|
|
190
|
+
contrarian:
|
|
191
|
+
enabled: true # ← swap anthropic's plain call for contrarian
|
|
192
|
+
member: anthropic
|
|
193
|
+
# model: claude-opus-4 # optional pin
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
`council:estimate` surfaces every active swap on a dedicated line above
|
|
197
|
+
the cost table:
|
|
198
|
+
|
|
199
|
+
```
|
|
200
|
+
council:estimate · mode=prompt · members=2 (billable=2)
|
|
201
|
+
advisor: Contrarian on anthropic via claude-sonnet-4-5
|
|
202
|
+
anthropic/claude-sonnet-4-5: ~991 in + 256 out = $0.0068
|
|
203
|
+
openai/gpt-4o: ~208 in + 256 out = $0.0031
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
Cost-bounded guarantee — replace-mode never adds calls. The advisor
|
|
207
|
+
persona prompt is larger than a plain prompt (~1k extra input tokens
|
|
208
|
+
per swap), so the per-call estimate widens slightly. Output tokens and
|
|
209
|
+
call count are unaffected.
|
|
210
|
+
|
|
211
|
+
Peer-review interaction — when peer-review fires on an advisor-mode
|
|
212
|
+
run, anonymisation **preserves the advisor persona label** while
|
|
213
|
+
stripping provider identity: `Response A (Contrarian)` instead of bare
|
|
214
|
+
`Response A`. See §Karpathy peer-review point 4 for the contract.
|
|
215
|
+
|
|
216
|
+
One-per-provider invariant — two enabled advisors targeting the same
|
|
217
|
+
member is a config error (replace-mode runs exactly one advisor per
|
|
218
|
+
provider; the call plan never doubles up by accident).
|
|
219
|
+
|
|
220
|
+
## Decision-replay artefact (Phase 9, audit trail)
|
|
221
|
+
|
|
222
|
+
Every session that runs consensus scoring drops a
|
|
223
|
+
`decision-replay.md` next to the saved `responses.json`. Pure
|
|
224
|
+
projection of the consensus block plus the final-round per-member
|
|
225
|
+
texts — **no extra model calls, no extra spend**. Surfaces, per top
|
|
226
|
+
finding: verdict band (Strong/Moderate/Weak), evidence-quality bucket
|
|
227
|
+
(H/M/L), agree/dissent split, and one key argument per member.
|
|
228
|
+
|
|
229
|
+
Two render modes:
|
|
230
|
+
|
|
231
|
+
* **Full** (default) — per-member arguments attributed to
|
|
232
|
+
`provider:model`. Reasoning is traceable, vendor identity is
|
|
233
|
+
visible.
|
|
234
|
+
* **Redacted** — verdict + evidence-quality + counts only. Use for
|
|
235
|
+
surfaces where attributing reasoning to a specific model would leak
|
|
236
|
+
vendor-preference signal.
|
|
237
|
+
|
|
238
|
+
Toggles (config, see `ai-council-config § Decision-replay artefact`):
|
|
239
|
+
|
|
240
|
+
* `ai_council.decision_replay.enabled` — master switch (default
|
|
241
|
+
`true`).
|
|
242
|
+
* `ai_council.decision_replay.include_member_arguments` — flip to
|
|
243
|
+
`false` for redacted-by-default.
|
|
244
|
+
* `ai_council.lenses.<lens>.decision_replay.*` — per-lens override
|
|
245
|
+
beats the global block.
|
|
246
|
+
|
|
247
|
+
CLI:
|
|
248
|
+
|
|
249
|
+
* Written automatically by `council run` whenever the lens triggers
|
|
250
|
+
consensus scoring.
|
|
251
|
+
* `council replay <responses.json>` re-renders from a saved session;
|
|
252
|
+
`--redact-member-arguments` / `--include-member-arguments` flip the
|
|
253
|
+
view independent of config. Useful for sharing a redacted variant
|
|
254
|
+
of an already-paid run.
|
|
255
|
+
|
|
256
|
+
## Lightweight-QA fast-path (Phase 11)
|
|
257
|
+
|
|
258
|
+
Low-impact questions classified by Phase 10's impact router can route
|
|
259
|
+
to a restricted fast-path instead of the full debate loop. The
|
|
260
|
+
trade-off is explicit: **1 round · ≤2 members · $0.05/answer · 2500
|
|
261
|
+
tokens**. No advisors, no peer-review, no consensus scoring — the goal
|
|
262
|
+
is a quick answer with a transparency marker, not a deliberation.
|
|
263
|
+
|
|
264
|
+
### Iron Law
|
|
265
|
+
|
|
266
|
+
`high_impact` and `user_required` **never** route to the fast-path,
|
|
267
|
+
regardless of config. Schema validation rejects the override. The
|
|
268
|
+
fast-path only activates when:
|
|
269
|
+
|
|
270
|
+
1. `ai_council.enabled: true` AND
|
|
271
|
+
2. `decision_resolution.low_impact.mode: council` AND
|
|
272
|
+
3. At least one member has `participate_low_impact: true` (default
|
|
273
|
+
`false` — explicit opt-in per member).
|
|
274
|
+
|
|
275
|
+
Default route for `low_impact` is **`agent`** — nothing reaches the
|
|
276
|
+
council without an explicit two-knob opt-in (flip the class to
|
|
277
|
+
`council` *and* mark at least one member `participate_low_impact: true`).
|
|
278
|
+
See [`ai-council-config § Low-impact council opt-in`](../../../../../docs/contracts/ai-council-config.md#low-impact-council-opt-in)
|
|
279
|
+
for the worked YAML example, validation behaviour, and unavailable-marker
|
|
280
|
+
contract.
|
|
281
|
+
|
|
282
|
+
### Output marker (always surfaced)
|
|
283
|
+
|
|
284
|
+
* **Resolved** — `> Resolved via low-impact council (anthropic): <one-line answer>`
|
|
285
|
+
* **Split** — `> Low-impact council split — escalating to user (anthropic: X / openai: Y):`
|
|
286
|
+
* **Aborted** — `> Low-impact council aborted (token cap) — escalating to user:`
|
|
287
|
+
|
|
288
|
+
The marker is mandatory: the agent never silently substitutes a
|
|
289
|
+
fast-path verdict for its own answer.
|
|
290
|
+
|
|
291
|
+
### Session artefact
|
|
292
|
+
|
|
293
|
+
Every fast-path attempt appends one line to
|
|
294
|
+
`agents/runtime/council/sessions/<date>-<slug>/low-impact-resolutions.md`:
|
|
295
|
+
|
|
296
|
+
```
|
|
297
|
+
2025-05-14T10:00:00Z | resolved | members=2/2 | members(anthropic, openai) cost=$0.0034 | Q=Service vs Repository for this read path?
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
Append-only, one line per resolution. The parser tolerates free-form
|
|
301
|
+
section headers around the canonical lines, so the artefact may grow
|
|
302
|
+
human notes without breaking aggregation.
|
|
303
|
+
|
|
304
|
+
### `council replay --low-impact-stats`
|
|
305
|
+
|
|
306
|
+
Re-projection of the session log into a summary block:
|
|
307
|
+
|
|
308
|
+
```
|
|
309
|
+
$ council replay agents/runtime/council/sessions/2025-05-14-foo/responses.json --low-impact-stats
|
|
310
|
+
# Low-impact fast-path · session summary
|
|
311
|
+
|
|
312
|
+
- attempts: 4
|
|
313
|
+
- status: aborted=1 · resolved=2 · split=1
|
|
314
|
+
- members: anthropic=4 · openai=3
|
|
315
|
+
- total cost: $0.0096
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
No model calls — pure parse of the markdown log. Returns 0 when the
|
|
319
|
+
session had no fast-path entries (a clean session is not an error).
|
|
320
|
+
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# ai-council — cost awareness and redaction
|
|
2
|
+
|
|
3
|
+
> Mode body of the [`ai-council`](../SKILL.md) skill (router-head retrofit,
|
|
4
|
+
> 2026-08-20). Content moved VERBATIM from SKILL.md — load this file when the
|
|
5
|
+
> mode table in SKILL.md routes here.
|
|
6
|
+
|
|
7
|
+
## Redaction expectations
|
|
8
|
+
|
|
9
|
+
The bundler's redaction pass strips:
|
|
10
|
+
|
|
11
|
+
- Paths matching `~/.event4u/agent-config/*.key` and the legacy
|
|
12
|
+
`~/.config/agent-config/*.key`.
|
|
13
|
+
- Lines starting with `Authorization:`.
|
|
14
|
+
- `key = …`, `secret = …`, `token = …`, `password = …` assignments.
|
|
15
|
+
- `sk-ant-…` and `sk-…` token-like strings.
|
|
16
|
+
|
|
17
|
+
If your artefact contains other sensitive data (customer names,
|
|
18
|
+
internal hostnames, contractual prose) you are responsible for
|
|
19
|
+
scrubbing it before bundling. The redaction pass is a **floor**, not
|
|
20
|
+
a ceiling.
|
|
21
|
+
|
|
22
|
+
## Cost awareness
|
|
23
|
+
|
|
24
|
+
Every consultation hits a paid API. The orchestrator enforces
|
|
25
|
+
per-invocation caps from `ai_council.cost_budget`:
|
|
26
|
+
|
|
27
|
+
- `max_input_tokens` / `max_output_tokens` — token caps across all members.
|
|
28
|
+
- `max_total_usd` — per-invocation USD ceiling. `0` disables the USD ceiling (token caps still apply).
|
|
29
|
+
- `max_calls` — maximum number of council members per invocation.
|
|
30
|
+
- `daily_limit_usd` — rolling 24h spend cap across all `/council`
|
|
31
|
+
invocations. `0` disables. Persists in
|
|
32
|
+
`~/.event4u/agent-config/council-spend.jsonl` (mode 0600; legacy
|
|
33
|
+
`~/.config/agent-config/council-spend.jsonl` read as fallback). Breach
|
|
34
|
+
fires `on_overrun(event)` with `event.breach_kind == "daily"` and,
|
|
35
|
+
if the callback returns False or is absent, tags the member
|
|
36
|
+
`daily_budget_exceeded` instead of `cost_budget_exceeded`.
|
|
37
|
+
|
|
38
|
+
Prices come from `agents/runtime/.agent-prices.md` (gitignored, refreshed weekly).
|
|
39
|
+
The pricing module bootstraps it from `_default_prices.ts` on first
|
|
40
|
+
use and flags it stale when older than the most recent Monday 00:00
|
|
41
|
+
UTC.
|
|
42
|
+
|
|
43
|
+
### Pre-call estimate format
|
|
44
|
+
|
|
45
|
+
Before the cost gate, compute `orchestrator.estimate(question, members,
|
|
46
|
+
table)` and render a per-member table. Heuristic: `len(text) / 4` for
|
|
47
|
+
input, member's `max_tokens` ceiling for output (actual spend is
|
|
48
|
+
usually lower).
|
|
49
|
+
|
|
50
|
+
> External council call — billable
|
|
51
|
+
>
|
|
52
|
+
> Mode: roadmap · Target: `agents/roadmaps/<name>.md` (~3 KB after redaction)
|
|
53
|
+
>
|
|
54
|
+
> | member | est. in / out tokens | est. USD |
|
|
55
|
+
> |---------------------------------|---------------------:|---------:|
|
|
56
|
+
> | anthropic / claude-sonnet-4-5 | ~750 / 1024 | $0.0176 |
|
|
57
|
+
> | openai / gpt-4o | ~750 / 1024 | $0.0121 |
|
|
58
|
+
> | **total** | | **$0.0297** |
|
|
59
|
+
>
|
|
60
|
+
> Budget: 50k in / 20k out tokens · USD ceiling: $0.50
|
|
61
|
+
>
|
|
62
|
+
> 1. Run the consultation
|
|
63
|
+
> 2. Cancel
|
|
64
|
+
|
|
65
|
+
### Stale price-table gate
|
|
66
|
+
|
|
67
|
+
If `pricing.is_stale(table)` returns true, ask before proceeding:
|
|
68
|
+
|
|
69
|
+
> Price table is stale (last_updated: YYYY-MM-DD)
|
|
70
|
+
> 1. Refresh now (`./scripts-run src/scripts/update_prices`)
|
|
71
|
+
> 2. Continue with the stale table
|
|
72
|
+
> 3. Cancel
|
|
73
|
+
|
|
74
|
+
Do not silently auto-refresh — the user keeps control.
|
|
75
|
+
|
|
76
|
+
### Mid-flow overrun callback (`on_overrun`)
|
|
77
|
+
|
|
78
|
+
The orchestrator runs members **sequentially**. Before each member
|
|
79
|
+
whose projected spend would breach a cap, it invokes the
|
|
80
|
+
`on_overrun(event)` callback. The callback returns `True` to proceed
|
|
81
|
+
with that member (raises the effective ceiling for THIS call only)
|
|
82
|
+
or `False` to skip and record `cost_budget_exceeded`. The callback
|
|
83
|
+
fires again for every subsequent breaching member — the user keeps
|
|
84
|
+
control on each step.
|
|
85
|
+
|
|
86
|
+
> Cost budget overrun — pausing before next member
|
|
87
|
+
>
|
|
88
|
+
> Member: openai / gpt-4o (member 2 of 2)
|
|
89
|
+
> Already spent: ~620 in / ~480 out tokens · $0.0094
|
|
90
|
+
> Next call estimate: ~750 in / 1024 out tokens · $0.0121
|
|
91
|
+
> **Projected total after this call: $0.0215** (ceiling: $0.0150)
|
|
92
|
+
>
|
|
93
|
+
> 1. Continue with this member
|
|
94
|
+
> 2. Skip this member (records `cost_budget_exceeded`, continues with the rest)
|
|
95
|
+
|
|
96
|
+
Without `on_overrun`, breaching short-circuits all remaining members
|
|
97
|
+
(v1 fallback). Do not retry silently. Surface the partial result and
|
|
98
|
+
ask the user.
|
|
99
|
+
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
# ai-council — execution and degradation modes
|
|
2
|
+
|
|
3
|
+
> Mode body of the [`ai-council`](../SKILL.md) skill (router-head retrofit,
|
|
4
|
+
> 2026-08-20). Content moved VERBATIM from SKILL.md — load this file when the
|
|
5
|
+
> mode table in SKILL.md routes here.
|
|
6
|
+
|
|
7
|
+
## Execution modes
|
|
8
|
+
|
|
9
|
+
A council member can run in one of three transports. The neutrality
|
|
10
|
+
preamble is identical across all of them — only the path the bytes
|
|
11
|
+
travel changes.
|
|
12
|
+
|
|
13
|
+
| Mode | Client | Billable | Transport | Status |
|
|
14
|
+
|---|---|---|---|---|
|
|
15
|
+
| `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 |
|
|
16
|
+
| `manual` | `ManualClient` | no | `stdout` (prompt block) + `stdin` (user pastes the web-UI reply, terminated by a line containing only `END`) | shipped (Phase 2b) |
|
|
17
|
+
| `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) |
|
|
18
|
+
|
|
19
|
+
Resolution lives in `scripts/ai_council/modes.ts`:
|
|
20
|
+
`resolve_mode(name, invocation_mode, member_settings, global_mode)`
|
|
21
|
+
with precedence **invocation flag > per-member setting > global
|
|
22
|
+
setting > default (`manual`)**. Whitespace-and-case insensitive; empty
|
|
23
|
+
strings fall through; unknown values raise `InvalidModeError` with
|
|
24
|
+
the offending settings path (`ai_council.mode`,
|
|
25
|
+
`ai_council.members.<name>.mode`, or `/council mode=`).
|
|
26
|
+
|
|
27
|
+
### Manual-mode UX
|
|
28
|
+
|
|
29
|
+
`ManualClient` is the user-as-transport variant: the agent prints
|
|
30
|
+
one Markdown block per member (system prompt + handoff preamble +
|
|
31
|
+
artefact between two `═` rules), the user pastes it into a web
|
|
32
|
+
chat (Claude.ai, ChatGPT, Gemini), then pastes the reply back
|
|
33
|
+
ending with a line containing only `END`. After each reply, a 1/2/3
|
|
34
|
+
menu surfaces:
|
|
35
|
+
|
|
36
|
+
1. More feedback for this member (continue this thread)
|
|
37
|
+
2. Done with this member, move to the next
|
|
38
|
+
3. Abort the council run
|
|
39
|
+
|
|
40
|
+
`1` re-emits a follow-up block addressed to the **same chat
|
|
41
|
+
thread** (no system prompt repetition). `2` records the round and
|
|
42
|
+
moves to the next member. `3` returns `error="manual_aborted"` for
|
|
43
|
+
that member and the orchestrator stops the fan-out.
|
|
44
|
+
|
|
45
|
+
### CLI-mode UX
|
|
46
|
+
|
|
47
|
+
`mode: cli` runs the council through the vendor's local CLI
|
|
48
|
+
instead of the API. Authentication is delegated — the user logs
|
|
49
|
+
into each CLI once (`claude login`, `codex login`, `gemini`), and
|
|
50
|
+
the orchestrator inherits the subscription. No API key flows
|
|
51
|
+
through this process. `billable=False`, so the cost gate is
|
|
52
|
+
bypassed; the local `cli_call_budget.max_calls_per_day.<provider>`
|
|
53
|
+
quota (state at `~/.event4u/agent-config/cli-calls.json`, daily
|
|
54
|
+
UTC reset) is the only per-day brake.
|
|
55
|
+
|
|
56
|
+
Three vendor CLIs are wired:
|
|
57
|
+
|
|
58
|
+
- **Anthropic / Claude** — invokes `claude --print --output-format json`
|
|
59
|
+
and parses the standard envelope (`result` + `usage` + `session_id`
|
|
60
|
+
+ `total_cost_usd`). Token counts and reported cost survive to
|
|
61
|
+
`metadata` for audit.
|
|
62
|
+
|
|
63
|
+
```yaml
|
|
64
|
+
members:
|
|
65
|
+
anthropic:
|
|
66
|
+
enabled: true
|
|
67
|
+
mode: cli
|
|
68
|
+
model: claude-sonnet-4-5
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
- **OpenAI / Codex** — invokes `codex exec --json -` with the prompt piped on
|
|
72
|
+
stdin, and walks the newline-delimited JSON event stream, pulling text from
|
|
73
|
+
`item.completed` and tokens from `turn.completed`. Session id is preserved.
|
|
74
|
+
Unlike the Anthropic client, there is **no separate system-prompt channel**:
|
|
75
|
+
`codex exec` has no `--system` flag, so a system prompt is prepended to the
|
|
76
|
+
user prompt in the same payload.
|
|
77
|
+
|
|
78
|
+
```yaml
|
|
79
|
+
members:
|
|
80
|
+
openai:
|
|
81
|
+
enabled: true
|
|
82
|
+
mode: cli
|
|
83
|
+
model: gpt-5
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
- **Google / Gemini** — invokes `gemini --output-format json` with
|
|
87
|
+
the prompt piped on stdin, parses the `response` + `stats.models.<m>.tokens`
|
|
88
|
+
envelope. OAuth consent must be granted once interactively before
|
|
89
|
+
the CLI is usable from a non-interactive shell. Like Codex and unlike Claude,
|
|
90
|
+
it has **no system-prompt flag** — `--system` is rejected outright with
|
|
91
|
+
`Unknown argument: system` — so the system prompt is prepended to the piped
|
|
92
|
+
payload.
|
|
93
|
+
|
|
94
|
+
Two caveats before enabling it, both measured 2026-08-12 and neither resolved.
|
|
95
|
+
The CLI's own `--help` says `-p/--prompt` is what selects non-interactive
|
|
96
|
+
mode, and this invocation passes neither `-p` nor the `query` positional;
|
|
97
|
+
whether piped stdin alone keeps it headless is **unestablished**. And the
|
|
98
|
+
free tier now refuses this client outright with `IneligibleTierError`, so a
|
|
99
|
+
round-trip could not be completed here at all. Enable it only if you can
|
|
100
|
+
confirm both on your own account.
|
|
101
|
+
|
|
102
|
+
```yaml
|
|
103
|
+
members:
|
|
104
|
+
gemini:
|
|
105
|
+
enabled: false # see the two caveats above before flipping this
|
|
106
|
+
mode: cli
|
|
107
|
+
model: gemini-2.5-pro
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Auth-failure stderr from any vendor CLI surfaces as
|
|
111
|
+
`error="auth_expired"` with the original stderr tail in
|
|
112
|
+
`metadata.stderr_tail` so the user knows to re-login. A missing
|
|
113
|
+
binary at construction time fails fast with `CouncilDisabledError`
|
|
114
|
+
naming the binary and the YAML override path — never silently
|
|
115
|
+
substitutes.
|
|
116
|
+
|
|
117
|
+
`xai` + `perplexity` accept `mode: cli` from Phase 4 onward, but
|
|
118
|
+
their community CLIs DO consume the API key and DO NOT bypass
|
|
119
|
+
per-token billing — the contract doc warns explicitly.
|
|
120
|
+
|
|
121
|
+
Both take a single `-p <prompt>` and have no second channel, so the system
|
|
122
|
+
prompt is folded into that same value. Until 2026-08-12 it was **discarded**,
|
|
123
|
+
and these two members answered every question with no role, no neutrality
|
|
124
|
+
framing and no output contract while the run counted the reply as a peer
|
|
125
|
+
verdict. Two consequences worth knowing: their whole prompt travels on argv, so
|
|
126
|
+
a very large one can fail with `os_error: E2BIG` (the response carries a `hint`
|
|
127
|
+
saying so), and because their CLIs report no usage block, the input side of
|
|
128
|
+
their cost is an estimate rather than a provider figure.
|
|
129
|
+
|
|
130
|
+
### Cost-gate bypass for non-billable members
|
|
131
|
+
|
|
132
|
+
`ExternalAIClient.billable` is the contract. Clients with
|
|
133
|
+
`billable=False` (`ManualClient`, `AnthropicCliClient`,
|
|
134
|
+
`OpenAICliClient`, `GeminiCliClient`) bypass the cost gate entirely —
|
|
135
|
+
the orchestrator skips the
|
|
136
|
+
projection check, the `on_overrun` callback, and the USD-budget
|
|
137
|
+
short-circuit for that member, but still records the response's
|
|
138
|
+
token counts (from the manual-paste length heuristic or the
|
|
139
|
+
provider's reply, when available) for observability. Mixed runs
|
|
140
|
+
(one cli + one api) gate only the api members.
|
|
141
|
+
|
|
142
|
+
## Degradation modes
|
|
143
|
+
|
|
144
|
+
How the council behaves when fewer than two billable members are
|
|
145
|
+
reachable. The orchestrator never silently substitutes — degradation
|
|
146
|
+
is visible to the user.
|
|
147
|
+
|
|
148
|
+
| Reachable | Behaviour | Independence |
|
|
149
|
+
|---|---|---|
|
|
150
|
+
| **2+** | Full fan-out, multi-round debate. Default. | High — cross-provider diversity. |
|
|
151
|
+
| **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. |
|
|
152
|
+
| **0** | Council skipped. Surface the failure, proceed without external review. **Never** substitute the host or an unrequested manual pass. | None. |
|
|
153
|
+
|
|
154
|
+
Rejected anti-patterns (council convergence, 2026-05-06): persona
|
|
155
|
+
prompts (same model, same blind spots, more cost), temperature
|
|
156
|
+
spread (noise, not signal), host-as-fallback (Iron Law breach).
|
|
157
|
+
Supported single-provider strategy is **sibling models on the same
|
|
158
|
+
provider** (e.g. Sonnet ↔ Opus, gpt-4o ↔ o1) — different training
|
|
159
|
+
cutoffs / reasoning architectures within one provider family. Cost
|
|
160
|
+
is real (siblings price-tier higher); explicit opt-in per invocation,
|
|
161
|
+
not a default.
|
|
162
|
+
|