@event4u/agent-config 8.11.0 → 8.13.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 (87) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/AGENTS.md +1 -0
  3. package/CHANGELOG.md +64 -266
  4. package/README.md +2 -2
  5. package/dist/agent-src/commands/pr/create.md +26 -0
  6. package/dist/agent-src/commands/team/adversarial.md +96 -0
  7. package/dist/agent-src/commands/team/delegate.md +109 -0
  8. package/dist/agent-src/commands/team/review.md +84 -0
  9. package/dist/agent-src/commands/team/status.md +92 -0
  10. package/dist/agent-src/commands/team.md +147 -0
  11. package/dist/agent-src/contexts/execution/roadmap-ci-steps-mechanics.md +117 -0
  12. package/dist/agent-src/contexts/execution/roadmap-process-loop.md +106 -94
  13. package/dist/agent-src/rules/architecture.md +6 -51
  14. package/dist/agent-src/rules/code-comment-discipline.md +10 -94
  15. package/dist/agent-src/rules/decision-revisit-gate.md +9 -77
  16. package/dist/agent-src/rules/improve-before-implement.md +8 -65
  17. package/dist/agent-src/rules/no-roadmap-references.md +13 -77
  18. package/dist/agent-src/rules/persona-governance.md +5 -47
  19. package/dist/agent-src/rules/provider-lifecycle-discipline.md +6 -32
  20. package/dist/agent-src/rules/roadmap-ci-steps-policy.md +21 -104
  21. package/dist/agent-src/rules/untrusted-input-defense.md +3 -75
  22. package/dist/agent-src/skills/agent-docs-writing/SKILL.md +83 -0
  23. package/dist/agent-src/skills/decision-review/SKILL.md +86 -0
  24. package/dist/agent-src/skills/module-detect-on-the-fly/SKILL.md +58 -1
  25. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  26. package/dist/agent-src/templates/contexts/knowledge-card.md +12 -0
  27. package/dist/discovery/deprecation-report.md +1 -1
  28. package/dist/discovery/discovery-manifest.json +159 -21
  29. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  30. package/dist/discovery/discovery-manifest.summary.md +3 -3
  31. package/dist/discovery/orphan-report.md +1 -1
  32. package/dist/discovery/packs.json +11 -6
  33. package/dist/discovery/trust-report.md +2 -2
  34. package/dist/discovery/workspaces.json +10 -5
  35. package/dist/install/install.mjs +38 -0
  36. package/dist/mcp/registry-manifest.json +2 -2
  37. package/dist/router.json +1 -1
  38. package/dist/server/schemas/settings.js +7 -0
  39. package/dist/server/schemas/settings.js.map +1 -1
  40. package/docs/CLAIMS.md +31 -3
  41. package/docs/architecture.md +2 -2
  42. package/docs/archive/CHANGELOG-pre-8.12.0.md +304 -0
  43. package/docs/benchmark.md +39 -0
  44. package/docs/catalog.md +10 -4
  45. package/docs/command-flows.md +6 -1
  46. package/docs/contracts/ai-council-config.md +9 -4
  47. package/docs/contracts/ai-team-config.md +191 -0
  48. package/docs/contracts/command-clusters.md +1 -0
  49. package/docs/contracts/persona-schema.md +49 -0
  50. package/docs/contracts/provider-lifecycle.md +29 -4
  51. package/docs/decisions/ADR-120-council-chairman-mode.md +70 -0
  52. package/docs/decisions/ADR-121-knowledge-sensitivity-classes.md +90 -0
  53. package/docs/decisions/INDEX.md +2 -0
  54. package/docs/design/council-vs-solo-baseline.md +92 -0
  55. package/docs/design/utilization-window-criteria.md +51 -0
  56. package/docs/featured-skills.md +1 -1
  57. package/docs/getting-started-by-role.md +3 -1
  58. package/docs/getting-started.md +31 -1
  59. package/docs/guidelines/agent-infra/agent-interaction-and-decision-quality.md +68 -0
  60. package/docs/guidelines/agent-infra/rule-body-migration-inventory.md +241 -0
  61. package/docs/guidelines/agent-infra/untrusted-input-spotlighting.md +80 -3
  62. package/docs/guidelines/code-clarity.md +86 -1
  63. package/docs/maintainers/branch-protection.md +105 -0
  64. package/docs/maintainers/system-map.md +85 -0
  65. package/docs/proof.md +15 -4
  66. package/package.json +1 -1
  67. package/src/config/agent-settings.template.yml +49 -0
  68. package/src/scripts/_cli/cmd_doctor.ts +291 -1
  69. package/src/scripts/_lib/claude_plugin.ts +39 -4
  70. package/src/scripts/_lib/knowledge_global.ts +44 -0
  71. package/src/scripts/_lib/knowledge_global_promote.ts +150 -0
  72. package/src/scripts/ai_council/orchestrator.ts +188 -1
  73. package/src/scripts/ai_team/config.ts +162 -0
  74. package/src/scripts/bench_persona_placebo.ts +308 -0
  75. package/src/scripts/bench_quality_rerun.ts +357 -0
  76. package/src/scripts/build_proof.ts +9 -0
  77. package/src/scripts/check_artefact_count_messaging.ts +56 -0
  78. package/src/scripts/check_knowledge_cards.ts +33 -4
  79. package/src/scripts/check_portability.ts +1 -0
  80. package/src/scripts/complexity_report.ts +776 -0
  81. package/src/scripts/consumer_matrix.ts +251 -12
  82. package/src/scripts/council_cli.ts +56 -1
  83. package/src/scripts/explain_run.ts +593 -0
  84. package/src/scripts/install.ts +39 -0
  85. package/src/scripts/knowledge_global_cli.ts +234 -45
  86. package/src/scripts/rule_backlinks.ts +350 -0
  87. package/src/server/schemas/settings.ts +17 -0
@@ -0,0 +1,191 @@
1
+ ---
2
+ stability: beta
3
+ keep-beta-until: 2026-10-10
4
+ ---
5
+
6
+ # AI-Team Config (`ai_team` block)
7
+
8
+ **Purpose.** Lock the schema, validation, and quota rules for the `/team`
9
+ cross-model review family — one strong external model (via the codex CLI,
10
+ subscription-authed) reviewing inside the repo. Team mode is the **depth**
11
+ complement to the council's **breadth**; this contract is the boundary that
12
+ prevents drift across the settings template, the loader, the `/team`
13
+ wrappers, and the quota counter.
14
+
15
+ **Audience.** Authors of `src/scripts/ai_team/config.ts`, the `/team`
16
+ command family, the doctor `team` section, and the setup wizard. Also
17
+ reviewers checking that new team features keep the schema intact.
18
+
19
+ **Status.** Internal-locked. Changes require a contract version bump and a
20
+ revision entry in the consuming roadmap.
21
+
22
+ ## File location
23
+
24
+ Unlike the council (ALWAYS user-global `.ai-council.yml` — see
25
+ [ai-council-config.md](ai-council-config.md)), the `ai_team` block lives in
26
+ the **project settings cascade**:
27
+
28
+ ```
29
+ <project>/.agent-settings.yml → ai_team: { … }
30
+ ```
31
+
32
+ read via `load_agent_settings` (`src/scripts/_lib/agent_settings.ts`) and
33
+ validated by `src/scripts/ai_team/config.ts:load_ai_team_config`. Team mode
34
+ is a per-project posture (default-off), not a per-developer credential
35
+ store — the codex CLI carries the subscription auth itself, so there is
36
+ nothing secret to centralize. The shipped defaults live in
37
+ `src/config/agent-settings.template.yml` and are mirrored by the wizard
38
+ schema (`src/server/schemas/settings.ts`, enforced by the schema↔template
39
+ parity test).
40
+
41
+ ## Schema
42
+
43
+ ```yaml
44
+ ai_team:
45
+ enabled: <bool> # master switch, default false
46
+ model: <string> # default 'auto'
47
+ allow_delegate: <bool> # second opt-in for the write path, default false
48
+ max_calls_per_day: <int >= 0> # default 50; counts into the shared openai bucket
49
+ suppress_setup_hint: <bool> # default false; cosmetic wizard-hint suppression
50
+ ```
51
+
52
+ | Key | Type | Default | Semantics |
53
+ |---|---|---|---|
54
+ | `enabled` | bool | `false` | Master switch. `false` = `/team` commands are never suggested and every invocation refuses with an enable pointer — byte-identical to pre-feature behavior. `true` = the family is live; per-command gates below still apply. |
55
+ | `model` | string | `'auto'` | Model handed to the codex CLI. `'auto'` = pass **no** `--model` flag; the codex CLI's own default applies. Any other value passes through **verbatim** as `--model <value>`. |
56
+ | `allow_delegate` | bool | `false` | Second opt-in for the **only** wrapper that delegates write access (`/team:delegate`). Refuses with an enable pointer until BOTH `enabled` and `allow_delegate` are `true`. |
57
+ | `max_calls_per_day` | int ≥ 0 | `50` | Per-day ceiling on team calls, read against the **shared** `cli_call_budget` openai bucket (see § Quota). `0` blocks all team calls. |
58
+ | `suppress_setup_hint` | bool | `false` | Suppress the one-line wizard/init recommendation to install the codex plugin on Claude-Code hosts. Cosmetic only. |
59
+
60
+ ### Why `model: 'auto'` instead of a pinned ID
61
+
62
+ A hardcoded model ID rots silently (the council's own CLI default is a
63
+ deliberate, documented *pin* — `DEFAULT_OPENAI_CLI_MODEL` in
64
+ `src/scripts/ai_council/clients.ts`, see
65
+ [ai-council-config.md](ai-council-config.md)). Team mode inverts that:
66
+ under a subscription the *strongest* available model is the rational
67
+ default, and only the codex CLI knows what that currently is. `'auto'`
68
+ therefore delegates the choice to the CLI; a set value is a user pin and
69
+ passes through verbatim — the loader never rewrites or "corrects" it.
70
+
71
+ **Future keys:** `review_gate` (managed, loop-bound governance of the
72
+ plugin's Stop-hook Review Gate) is reserved for a later team-mode phase
73
+ (Phase 4). Do not add it — or any other key — ahead of its phase; the
74
+ loader rejects unknown keys today by design.
75
+
76
+ ## Role semantics — the council-verdict design constraint
77
+
78
+ Verbatim from the consuming roadmap's council verdict, binding on every
79
+ team-mode phase:
80
+
81
+ > **Council verdict on team-mode frontmatter (claude-sonnet-4-5 + gpt-4o,
82
+ > 2026-07-12, unanimous REJECT):** skills/commands get NO `team_mode` /
83
+ > role frontmatter. Role semantics belong in the `ai_team` config block +
84
+ > prompt library (reusing subagent-orchestration's implementer/judge frame
85
+ > and status envelope), not smeared across 271 skill files while the
86
+ > feature's role model does not operationally exist. Revisit-if: Phase 2
87
+ > execution turns out to be blocked SPECIFICALLY on artefact-level role
88
+ > metadata — then re-open via decision-revisit-gate, not by silently
89
+ > adding the key.
90
+
91
+ Operationally: ALL role semantics (builder/reviewer/verifier selection,
92
+ eligibility) live HERE — in this `ai_team` block — plus the prompt
93
+ library, reusing `subagent-orchestration`'s implementer/judge frame and
94
+ its `subagent-status.json` envelope. **No `team_mode`/role frontmatter key
95
+ is added to skill/command/rule schemas.**
96
+
97
+ ## Quota — one subscription, one counter
98
+
99
+ ```
100
+ TEAM CALLS COUNT INTO THE EXISTING cli_call_budget OPENAI BUCKET.
101
+ ONE SUBSCRIPTION, ONE COUNTER. NEVER A PARALLEL COUNTER.
102
+ ```
103
+
104
+ The daily CLI-call counter is already **generic per-provider** — no
105
+ team-specific counting system exists or may be built:
106
+
107
+ - **State file:** `~/.event4u/agent-config/cli-calls.json`
108
+ (`CLI_CALLS_FILENAME`, `src/scripts/ai_council/clients.ts:716`), shape
109
+ `{ date: "YYYY-MM-DD", counts: { <provider>: <int> } }`, resets on UTC
110
+ date rollover.
111
+ - **Read:** `load_cli_call_counts(path?)` —
112
+ `src/scripts/ai_council/clients.ts:738`. Returns today's per-provider
113
+ counts; empty on rollover.
114
+ - **Increment:** `record_cli_call(provider, path?)` —
115
+ `src/scripts/ai_council/clients.ts:774`. Returns the new total.
116
+ - **Gate + increment on the transport itself:** `CliClient.ask()` checks
117
+ the counter *before* spawning (`clients.ts` § quota gate, returns
118
+ `error: 'cli_quota_exhausted'` + a `block_quota` events-log line when
119
+ exhausted) and records the call *after* — even failed calls count, so a
120
+ broken CLI cannot burn the budget in a tight loop.
121
+ - **The openai bucket:** `OpenAICliClient` (`clients.ts:1275`) has
122
+ `name = 'openai'`; council CLI calls and team calls land on the **same**
123
+ `counts.openai` entry.
124
+
125
+ A `/team` invocation therefore reuses the existing seams, in preference
126
+ order:
127
+
128
+ 1. **Through the transport** — construct `OpenAICliClient` with
129
+ `max_calls_per_day: <ai_team.max_calls_per_day>`; the gate, the
130
+ exhausted-error, the events-log line, and the increment all come for
131
+ free.
132
+ 2. **Direct** (for `/team:status` rendering or a pre-flight check) —
133
+ `load_cli_call_counts()['openai'] ?? 0` to read,
134
+ `record_cli_call('openai')` to count. No new helper exists because
135
+ none is needed; adding a team-side duplicate of this counter is a
136
+ contract violation.
137
+
138
+ `ai_team.max_calls_per_day` and the council's
139
+ `cli_call_budget.max_calls_per_day.openai` are two *ceilings* over the
140
+ same *counter*: whichever path a call takes, it increments the one shared
141
+ bucket, and each surface enforces its own configured cap against that
142
+ shared count.
143
+
144
+ ## Validation rules (fail-closed)
145
+
146
+ `load_ai_team_config` / `build_ai_team_config`
147
+ (`src/scripts/ai_team/config.ts`) raise `TeamConfigError` when:
148
+
149
+ 1. `ai_team` is present but not a mapping,
150
+ 2. any **unknown key** appears under `ai_team` (a typo must never
151
+ silently disable a gate),
152
+ 3. `enabled` / `allow_delegate` / `suppress_setup_hint` is not a boolean,
153
+ 4. `model` is not a non-empty string,
154
+ 5. `max_calls_per_day` is not a non-negative integer (booleans rejected).
155
+
156
+ An **absent** `ai_team` block is not an error — it yields the defaults
157
+ (`AI_TEAM_DEFAULTS`) and the feature stays off.
158
+
159
+ ## Default-off posture
160
+
161
+ Every team-mode capability is default-off. With the block absent or
162
+ `enabled: false`, all paths are byte-identical to pre-feature behavior:
163
+ no command suggestions, no wrapper execution, no quota consumption, no
164
+ wizard nagging beyond the single suppressible setup hint.
165
+ `/team:delegate` is doubly gated (`enabled` AND `allow_delegate`).
166
+
167
+ ## No-claims constraint
168
+
169
+ No public claim about cross-model review quality ("a second model finds
170
+ errors the first never sees", "two strongest models catch each other's
171
+ errors", or any review-lift assertion) may exist anywhere in the tree
172
+ until the pre-registered three-arm defect-finding benchmark has produced
173
+ a verdict bound in CLAIMS.md. Workflow-value prose is allowed; lift
174
+ claims are not. An honest null keeps the feature documented as workflow
175
+ value only.
176
+
177
+ ## Boundary vs. the council
178
+
179
+ Team mode and the council are complements, not variants — the council's
180
+ neutrality contract is untouched by team mode:
181
+
182
+ | Axis | Council ([ai-council-config.md](ai-council-config.md)) | Team (`ai_team`) |
183
+ |---|---|---|
184
+ | Shape | N members, breadth | One strong reviewer, depth |
185
+ | Repo access | NEVER (artefact text + neutral preamble only) | Full (reviewer runs inside the working tree) |
186
+ | Config location | User-global `.ai-council.yml` (ADR-104) | Project `.agent-settings.yml` cascade |
187
+ | Default models | Mid-tier, cost-conscious | Subscription's strongest (`model: 'auto'`) |
188
+ | Quota | `cli_call_budget` per provider | Same counter — shared openai bucket |
189
+
190
+ This link is deliberately one-directional (team → council); the council
191
+ contract does not reference team mode.
@@ -45,6 +45,7 @@ column 1 of this table.
45
45
  | `council` | 3 | `default` · `pr` · `design` · `optimize` · `analysis` | `council` (legacy default lens) · `council-pr` · `council-design` · `council-optimize`; `analysis` added 2026-05-14 — wrapper for local analysis outputs with a Top-N consensus tail block consumed by `/roadmap create` |
46
46
  | `challenge-me` | — | `vision` · `with-docs` | new — Pocock-inspired one-question-at-a-time interview; `vision` is the standard 95%-confidence variant, `with-docs` adds doc/glossary awareness with a session-scoped glossary and load-bearing claim-vs-code verification |
47
47
  | `research` | 2 | `deep` · `report` | preliminary-research scaffolder ported from `Weizhena/Deep-Research-skills` (cluster head emits `outline.yaml` + `fields.yaml` against the `research-schema` contract). `:deep` populates per-item JSON in batches with native web-search + JSON-Schema self-validation (no Python runtime); `:report` renders `report.md` directly + optionally emits a `jq` template for deterministic regeneration. `add-items` / `add-fields` intentionally **not** ported — re-run `/research <topic>` to extend the field framework. |
48
+ | `team` | 2 | `review` · `adversarial` · `delegate` · `status` | new 2026-07-12 (road-to-team-mode Phase 2) — cross-model depth review: thin fail-closed delegations to the official codex plugin on Claude-Code hosts under `ai_team` governance ([`ai-team-config`](ai-team-config.md)); default-off (`ai_team.enabled: false`), `delegate` behind the second opt-in `allow_delegate`; internal visibility until the ADR promotion gate |
48
49
  | `orchestrate` | — | _(none yet — cluster head only)_ | new — runtime executor for YAML pipelines under `.agent-config/orchestrations/` per the [`orchestration-dsl-v1`](orchestration-dsl-v1.md) contract; chains personas / skills / commands / sub-agents deterministically. Single cluster head; sub-commands deferred until a second verb is needed. |
49
50
  | `sync` | 4 | `agent-settings` · `gitignore` · `gitignore-fix` | new cluster 2026-07-08 — absorbs the former single-sub `sync-gitignore` cluster (slug-neutral nests: `sync-agent-settings`, `sync-gitignore`, `sync-gitignore-fix` keep their slugs; the gitignore node keeps its own `fix` sub-dir, mirroring the `agents/user` deep-nest precedent). Bare `/sync` shows the menu. |
50
51
  | `ghostwriter` | — | `fetch` · `write` · `list` · `show` · `delete` | new cluster 2026-05-15 — third voice primitive for AI-assisted writing in the public voice of a public figure. Hybrid storage: real-person profiles live consumer-side under `agents/reference/ghostwriter/<slug>.md` (gitignored by default); package source ships only `fictional: true` fixtures. Zero network code in the package — `:fetch` delegates web-fetch / web-search to the host agent. Mandatory disclosure footer on every `:write` output (no opt-out). Schema: [`ghostwriter-schema`](ghostwriter-schema.md). |
@@ -144,6 +144,55 @@ major version bump in the package release notes. Size-cap tightening
144
144
  is breaking when it forces existing personas to lose content; size-cap
145
145
  loosening is non-breaking.
146
146
 
147
+ ## § 8 — Governance discipline (the four checks)
148
+
149
+ _Origin: migrated from `src/rules/persona-governance.md` per the P4 pattern of `road-to-kernel-and-router.md`. The rule keeps the Iron Law and the check names; the detail lives here._
150
+
151
+ Personas are review lenses, not free real estate. Every specialist persona has a maintenance cost: it must stay aligned with this schema, the cited skills must still want it, and the per-domain reasoning surface must not bloat to the point that no single persona is load-bearing.
152
+
153
+ ### 8.1 Per-domain cap — ≤ 2 specialised personas per content domain
154
+
155
+ A **content domain** is a self-contained creative or technical surface that one or two specialist personas can fully cover. Current domains:
156
+
157
+ | Domain | Specialists allowed | Examples |
158
+ |---|---|---|
159
+ | ai-video / ai-image / ai-audio | ≤ 2 | one director-shaped lens + one technical-tuning lens |
160
+ | backend engineering | ≤ 2 | architect + ORM-tamer |
161
+ | frontend engineering | ≤ 2 | component / lifecycle + design / a11y |
162
+ | security | ≤ 2 | abuse-case + secrets-and-trust |
163
+ | gtm / growth | ≤ 2 | CMO + RevOps |
164
+ | money / strategy | ≤ 2 | finance-partner + strategist |
165
+ | people / org | ≤ 2 | engineering-manager + people-strategist |
166
+ | customer / discovery | ≤ 2 | discovery-lead + customer-success-lead |
167
+
168
+ **Core personas** (`developer`, `senior-engineer`, `product-owner`, `stakeholder`, `critical-challenger`, `ai-agent`) are exempt — they are always-loaded cross-cutting lenses, not domain specialists.
169
+
170
+ A new specialist into a full domain MUST come with a deprecation candidate from the same domain. The agent surfaces both, then runs an ai-council debate (per [`ai-council`](../../src/skills/ai-council/SKILL.md)) before any rename / merge / delete.
171
+
172
+ ### 8.2 Skill citation floor — ≥ 1 cite before merge
173
+
174
+ A specialist persona without a `personas: [<id>]` citation in at least one skill's frontmatter is dead weight. The PR adding the persona MUST also add the citation, OR the PR is rejected. Citation map lives in [`docs/personas.md § Skill citations`](../personas.md#skill-citations).
175
+
176
+ ### 8.3 Deprecation path — delete immediately, record in commit
177
+
178
+ A persona being removed is **deleted in the same commit** that lands its replacement. The commit message names the successor (or "merged into X") and cites the council decision (or maintainer rationale) that authorised it. No soak window — internal personas have no external consumers; a persona file kept around as a tombstone is dead weight the linter still loads. No silent deletes either: the audit trail is the commit, not a docs table.
179
+
180
+ ### 8.4 Schema conformance — the skill linter is the gate
181
+
182
+ Every persona file is linted against this contract (§ 1–§ 5) by the skill linter: frontmatter shape, tier enum, wing enum, required sections per tier, line budget per tier (with wing override), `Unique Questions` ≥ 3, filename / id match, description ≤ 160 chars. The agent runs `./scripts-run src/scripts/skill_linter` before any persona PR is marked ready.
183
+
184
+ ### Failure modes — what counts as a violation
185
+
186
+ - Adding a third specialist to a full domain without naming the deprecation candidate.
187
+ - Landing a specialist with no `personas: [<id>]` cite in any skill.
188
+ - Renaming or deleting a persona file without naming the successor (or sunset reason) in the commit message.
189
+ - Editing core-tier personas in-place with breaking changes (rename, section removal) without bumping to a new id.
190
+ - Skipping the skill linter (`./scripts-run src/scripts/skill_linter`) on a persona PR.
191
+
192
+ ### Governance day-one state
193
+
194
+ Resolved 2026-05-17 via two-round ai-council debate (members: anthropic/claude-sonnet-4-5, openai/gpt-4o — converged on delete-and-fold): `pixar-storyboard-artist` deleted; its acting / beat-decomposition lens folded into the [`pixar-storyteller`](../../src/skills/pixar-storyteller/SKILL.md) skill body. Active per-domain count for `ai-video` is now 2 (`ai-video-technical-director`, `hollywood-director`), within cap. Total active personas in the root cluster: 24 (plus 5 advisors in `personas/advisors/`). Full inventory + ownership in [`docs/personas.md`](../personas.md).
195
+
147
196
  ## See also
148
197
 
149
198
  - [`skill-domains`](skill-domains.md) — sister taxonomy for skills
@@ -68,19 +68,44 @@ When the agent picks a provider for a `/video:*` / `/image:*` /
68
68
  1. **Read** the `provider_lifecycle` tag from the adapter's header
69
69
  comment **and** the matching `<provider id="…">` block in
70
70
  `agents/templates/.ai-video.xml.example` (or the operator's
71
- `agents/.ai-video.xml`).
71
+ `agents/.ai-video.xml`). This applies to every resolution path —
72
+ `--provider <id>`, `<default-video-provider>` /
73
+ `<default-image-provider>`, or a skill's default. A **mismatch
74
+ between the two sources is a contract violation** and MUST be
75
+ surfaced before running.
72
76
  2. **Refuse-and-surface** if the operator's resolved default is a
73
77
  non-`stable` tier — name the tier and the path to this contract
74
78
  document, then emit one clarifying question (per
75
79
  [`ask-when-uncertain`](../../.augment/rules/ask-when-uncertain.md)):
76
80
  either pick a `stable` provider, or confirm the non-stable run.
81
+ No silent default. No "I'll just try it".
77
82
  3. **Record** in the run summary which tier the chosen adapter
78
- carries — this is the audit log entry the agent-in-the-loop
79
- model rests on.
83
+ carries — the summary line after every `/video:*` / `/image:*` /
84
+ `/audio:*` run names the chosen provider AND its tier. This is the
85
+ audit log entry the agent-in-the-loop model rests on.
86
+ 4. **Never auto-promote.** Promotion is the maintainer's call. The
87
+ agent MAY draft a promotion checklist (per
88
+ [§ 2 — Promotion path](#-2--promotion-path)) for maintainer
89
+ review, but the tier-flip commit is human-authored.
80
90
 
81
91
  The agent never picks `deprecated` silently. If a successor is
82
92
  declared, the agent surfaces "X is deprecated; successor: Y" before
83
- running.
93
+ running — even with confirmation.
94
+
95
+ ### § 4a — Failure modes (agent-side violations)
96
+
97
+ _Origin: migrated from `src/rules/provider-lifecycle-discipline.md` per the P4 pattern of `road-to-kernel-and-router.md`. The rule keeps the Iron Law and the read-tier / refuse-and-surface one-liners; the detail lives here._
98
+
99
+ - Running `/video:scene` against the `<default-video-provider>` without reading the lifecycle tag first → violation.
100
+ - Picking a `community` provider because it was named in the prompt, without surfacing the tier → violation.
101
+ - Editing an adapter and leaving its header `Lifecycle:` comment out of sync with `agents/templates/.ai-video.xml.example` → violation (CI does not catch this; the agent must).
102
+ - Auto-promoting an adapter from `experimental` to `stable` because "dry-run worked" → violation. Promotion requires a maintainer-captured real-API smoke trace under `agents/reference/ai-video/smoke-traces/`.
103
+
104
+ ### § 4b — Why agent-in-the-loop, not a Python gate
105
+
106
+ A Python pre-run gate enumerating tier-by-command rules would either be too coarse (`experimental → block`, breaking day-to-day dev iteration) or too detailed (per-command tier matrix, drifting from reality on every new provider). The agent reading the tag at run time, surfacing the tier, and asking is the correct enforcement surface: the model that picked the provider is the model that surfaces the obligation, and the human is the policy decision point.
107
+
108
+ The CI guarantee is structural reachability — the linter would fail if a provider was declared in `agents/templates/.ai-video.xml.example` without a lifecycle tag (extension planned). It does not enforce the runtime obligation; the agent does.
84
109
 
85
110
  ## § 5 — Day-one assignment
86
111
 
@@ -0,0 +1,70 @@
1
+ ---
2
+ adr: 120
3
+ status: accepted
4
+ date: 2026-07-12
5
+ decision: council-chairman-mode
6
+ supersedes: —
7
+ superseded_by: —
8
+ phase: opt-council-deliberation
9
+ type: structural
10
+ ---
11
+
12
+ # ADR-120 — Council chairman mode supersedes always-host synthesis
13
+
14
+ ## Status
15
+
16
+ Accepted (2026-07-12).
17
+
18
+ ## Context
19
+
20
+ The council skill's own Iron Law argues the host agent, having framed the
21
+ artefact, cannot independently judge it — yet the shipped engine always let the
22
+ host author the synthesis ("the host runs the council and synthesises
23
+ convergence"). `road-to-opt-council-deliberation` Phase 2 applies the bias
24
+ argument to the synthesis step itself. The contested `auto`-selection detail
25
+ was resolved by a billable two-round council pass (anthropic/claude-sonnet-4-5 +
26
+ openai/gpt-4o, 2026-07-12): provider-family difference is the binding
27
+ independence property for a judge; capability (tier) is the tie-break.
28
+
29
+ ## Decision
30
+
31
+ `ai_council.chairman: { mode: host | member | auto, member? }` — **default
32
+ `host`**, preserving today's behaviour byte-for-byte (the compatibility
33
+ guarantee). When `mode != host`, a **non-deliberating member** authors the
34
+ synthesis as one billable call through the existing `consult` path (spend gate,
35
+ daily ledger, metadata stamping unchanged):
36
+
37
+ - `member` — the named member, validated fail-closed at config load (must exist
38
+ and be enabled) and rejected at selection time if it deliberated (a member
39
+ that argued cannot self-judge).
40
+ - `auto` — provider-family difference primary (non-deliberating ⇒
41
+ provider-different under the one-member-per-provider invariant), optional
42
+ `members.<name>.tier` tie-break, deterministic config order final.
43
+ - Every fallback path (member deliberated / unavailable / auto with no
44
+ candidate / call failed) degrades to the host template with a **visible
45
+ annotation** — never a silent substitution.
46
+
47
+ ## Consequences
48
+
49
+ - The synthesis slot can carry a chairman-authored body (`payload.chairman`
50
+ → `render()`); `council:estimate` shows the extra call as its own row.
51
+ - A new optional `tier` field exists on member config solely as the `auto`
52
+ tie-break.
53
+ - Host synthesis remains the default; no consumer behaviour changes without
54
+ an explicit opt-in.
55
+
56
+ ## Alternatives
57
+
58
+ - **Always-host synthesis (status quo)** — rejected: contradicts the skill's
59
+ own independence argument.
60
+ - **Tier-first auto selection** — rejected by the council pass: chairing with
61
+ the strongest model when the deliberators share its provider concentrates
62
+ the decision surface on one provider's priors.
63
+
64
+ ## References
65
+
66
+ - `docs/contracts/ai-council-config.md` § Chairman synthesis.
67
+ - `src/scripts/ai_council/chairman.ts` (selection), `council_cli.ts`
68
+ `_maybe_run_chairman` (dispatch).
69
+ - Council convergence: `road-to-opt-council-deliberation` § Council notes
70
+ (2026-07-12).
@@ -0,0 +1,90 @@
1
+ ---
2
+ adr: 121
3
+ status: accepted
4
+ date: 2026-07-12
5
+ decision: knowledge-sensitivity-classes
6
+ supersedes: —
7
+ superseded_by: —
8
+ phase: feedback-8.11
9
+ type: structural
10
+ ---
11
+
12
+ # ADR-121 — Per-card sensitivity classes for the knowledge boundary
13
+
14
+ ## Status
15
+
16
+ Accepted (2026-07-12). Successor note to ADR-119 (global knowledge sharing
17
+ default ON) — adds boundary teeth; does NOT revert the flip.
18
+
19
+ ## Context
20
+
21
+ The 8.11.0 external reviews and the maintainer both name cross-project
22
+ context transfer as the riskiest open surface of the ADR-119 flip: the only
23
+ per-entry axis was origin tier (`public|vendor|proprietary` — where knowledge
24
+ came from), the binary page flag `visibility: private`, and a write-time
25
+ regex redaction gate. There was NO sensitivity taxonomy (how far an entry may
26
+ travel), no per-card owner/expiry on shared cards, no promotion-reason
27
+ capture, and no revocation trail — deletion was silent.
28
+
29
+ A two-round council debate (anthropic/claude-sonnet-4-5 + openai/gpt-4o,
30
+ 2026-07-12) split on scope: one member argued measure-first with a 2-level
31
+ enum at most (six classes over-fit a single-maintainer install — `team` /
32
+ `organization` are phantom categories today); the other argued the full
33
+ six-class taxonomy from the reviews. Resolution: a SMALL machine-anchored
34
+ axis now (the maintainer's danger is present, not speculative), the wider
35
+ enum behind a revisit-if.
36
+
37
+ ## Decision
38
+
39
+ Three sensitivity classes, each anchored to a machine check
40
+ (`agents/settings/contexts/knowledge-sensitivity.md` carries the full table):
41
+
42
+ - `prohibited` — redaction-class content; a redaction hit FORCES this class
43
+ (declared values cannot override it); hard linter error in the global
44
+ store (check G6).
45
+ - `project` — the DEFAULT; promotion structurally refused unless a human
46
+ reclassifies; unset/invalid resolves here, never upward.
47
+ - `shareable` — global-store eligible; requires passing redaction AND full
48
+ provenance: `source_repo`, `owner`, `review_after`, `promotion_reason`
49
+ (checks G4/G5); `promotion_reason` is mandatory human input — there is no
50
+ auto-`shareable` path.
51
+
52
+ Plus an append-only revocation ledger (`.revocations.jsonl` tombstones
53
+ written by `forget`/`purge` BEFORE deletion; rendered via
54
+ `knowledge:global:list --revoked`).
55
+
56
+ ADR-119's default-ON, `allowed_tiers: [public]`, measurement window, and
57
+ demotion trigger are unchanged.
58
+
59
+ ## Consequences
60
+
61
+ - Cross-project transfer now requires a recorded human decision per card
62
+ (class + reason), machine-verified in CI (`check_knowledge_cards` G4–G6)
63
+ and at promotion time (`gate_sensitivity_for_promotion`).
64
+ - Deletion is auditable; the demotion trigger of ADR-119 gains a per-entry
65
+ trail to point at.
66
+ - Cost: one more frontmatter field + four footer fields on shared cards;
67
+ no new subsystem, no read-time machinery.
68
+
69
+ ## Alternatives considered
70
+
71
+ - Six-class enum `{local-only, project, team, organization, confidential,
72
+ prohibited}` (the reviews' proposal) — rejected now: `team`/`organization`
73
+ have no consumer today; widening is cheap later, narrowing is not.
74
+ Revisit-if: a real multi-tenant org install exists.
75
+ - Revert ADR-119 to default-OFF — rejected: re-creates the ADR-103
76
+ measure-then-decide deadlock; the danger is contained by classes + gates,
77
+ not by turning the layer off.
78
+ - Semantic PII detection / k-anonymity — out of scope per ADR-119 §6
79
+ (write-time text gate, single-install trust boundary).
80
+
81
+ ## References
82
+
83
+ - `agents/settings/contexts/knowledge-sensitivity.md` — locked design table.
84
+ - ADR-119 — the flip this hardens.
85
+ - Implementation: `knowledge_global.ts` (SENSITIVITIES, footer fields),
86
+ `knowledge_global_promote.ts` (`resolve_effective_sensitivity`,
87
+ `gate_sensitivity_for_promotion`, tombstones), `knowledge_global_cli.ts`
88
+ (promote/forget/purge/list flags), `check_knowledge_cards.ts` (G4–G6);
89
+ 118 tests across 6 files incl. 3 cross-project-contamination adversarial
90
+ cases.
@@ -123,6 +123,8 @@ _Auto-generated by `scripts/adr/regenerate_index.py`. Do not edit._
123
123
  | [ADR-117](ADR-117-subagents-auto-default-on.md) | Subagents Auto Default On | accepted | 2026-07-09 | — |
124
124
  | [ADR-118](ADR-118-loop-engineering-boundaries.md) | Loop Engineering Boundaries | accepted | 2026-07-10 | — |
125
125
  | [ADR-119](ADR-119-global-knowledge-default-on.md) | Global Knowledge Default On | accepted | 2026-07-12 | 103 |
126
+ | [ADR-120](ADR-120-council-chairman-mode.md) | Council Chairman Mode | accepted | 2026-07-12 | — |
127
+ | [ADR-121](ADR-121-knowledge-sensitivity-classes.md) | Knowledge Sensitivity Classes | accepted | 2026-07-12 | — |
126
128
  | [ADR-200](ADR-200-python-to-typescript-migration.md) | Python To Typescript Migration | accepted | 2026-06-11 | — |
127
129
 
128
130
  ## Unnumbered (legacy)
@@ -0,0 +1,92 @@
1
+ # Council-vs-solo baseline eval — design (pre-registered)
2
+
3
+ > Design artifact for `road-to-feedback-8.11` Phase 3. It fixes the
4
+ > methodology **before** the first billable call; the run itself is
5
+ > spend-gated (blocker `council-baseline-spend-authorization` — the user
6
+ > confirms the rendered estimate in-session). This document is the "design
7
+ > the baseline" step — not the run. Companion claim:
8
+ > `docs/CLAIMS.md § council-vs-solo-baseline` (status: unbacked until the run
9
+ > resolves).
10
+
11
+ ## Why this exists
12
+
13
+ The council deliberation protocol (stance tally, chairman, debate gates,
14
+ anti-conformity) is well-built and default-off — but there is **no evidence
15
+ that convening the council beats a single strong model** on any decision
16
+ class. The 2026-07-12 feedback-disposition debate (claude-sonnet-4-5 +
17
+ gpt-4o) REJECTED adding a ≥2-of-5 admission gate for exactly this reason and
18
+ ADOPTED this baseline as the precondition for ANY further
19
+ deliberation-protocol expansion: admission criteria must be derived from
20
+ empirical decision characteristics, not a-priori heuristics.
21
+
22
+ Shadow-log status at design time (2026-07-12): `agents/runtime/council/
23
+ shadow-log.jsonl` is **absent/empty** on both the main checkout and the run
24
+ worktree — the shadow-dispatch agreement mechanism has produced zero
25
+ analyzable lines. That absence is itself the first finding: the only
26
+ council-vs-solo signal the package planned to collect has no data, so a
27
+ deliberate baseline run is the only path to a verdict.
28
+
29
+ ## Arms
30
+
31
+ | Arm | What runs | Cost profile |
32
+ |---|---|---|
33
+ | A — solo | ONE strong model (the council's strongest configured member, single call, standard prompt) | 1 call/decision |
34
+ | B — council | The full configured council in `debate` mode (2 members × ≤2 rounds, current defaults; stance tally ON so dissent is recorded) | 4–5 calls/decision |
35
+
36
+ Same decision text, same context budget, both arms blind to each other.
37
+
38
+ ## Corpus — ≥30 real decisions
39
+
40
+ - Source: real decision questions from the repo's own history — the
41
+ council-labelled golden set (labels final per the 2026-07-11 amendment; no
42
+ re-labelling) plus archived council question files whose ground-truth
43
+ disposition is now KNOWN (the decision shipped and survived, was reverted,
44
+ or was killed by later evidence). Minimum n = 30; pre-register the exact
45
+ list in the run manifest BEFORE the first call.
46
+ - Class mix: at least 8 decisions per impact class {low, medium, high} so the
47
+ per-class analysis (the whole point — which characteristics correlate with
48
+ council lift) is not vacuous.
49
+
50
+ ## Metrics — fixed before data
51
+
52
+ 1. **Quality**: blind post-hoc grading of both arms' verdicts against the
53
+ known ground-truth disposition — primary judge = strongest available
54
+ model, blind second judge, report Cohen's κ (reuse `cohensKappa()` /
55
+ `judgeKappa()` from `src/scripts/check_quality_regression.ts`); verdict
56
+ admissible only at κ ≥ 0.60.
57
+ 2. **Cost**: tokens + USD (from the council cost ledger) + wall-clock per
58
+ decision, per arm.
59
+ 3. **Characteristics capture**: per decision, record the five feedback-
60
+ proposed dimensions (reversibility cost, material spend/risk,
61
+ multi-perspective conflict, evidence tension, policy/governance change) as
62
+ booleans AT PRE-REGISTRATION TIME (not after results) — so the ≥2-of-5
63
+ hypothesis is testable as a POST-HOc correlate without having gated
64
+ anything.
65
+
66
+ ## Kill criterion (falsifiable, from the 2026-07-12 debate)
67
+
68
+ - **No lift anywhere**: if council decisions show no identifiable quality
69
+ lift on ANY decision subset (overall AND per impact class AND per
70
+ dimension-count stratum), further deliberation-protocol phases STOP and
71
+ the protocol goes maintenance-only; `road-to-opt-council-deliberation`
72
+ records the honest null.
73
+ - **Lift on a subset**: derive empirical admission criteria FROM that
74
+ subset's recorded characteristics (which may or may not match the ≥2-of-5
75
+ heuristic — the data decides), and only then design an admission gate.
76
+ - **Judge floor**: κ < 0.60 → record κ, withhold the win-rate, do not claim
77
+ either direction.
78
+
79
+ ## Spend gate
80
+
81
+ Execution requires in-session user confirmation of the rendered estimate
82
+ (existing council estimate machinery; ~30 decisions × (1 + ~4.5) calls —
83
+ estimate rendered by `council estimate` at run time). Authoring the corpus
84
+ manifest and this design is unblocked and free.
85
+
86
+ ## Non-goals
87
+
88
+ - Not a cross-provider capability comparison (both arms use the configured
89
+ members; provider identity is held constant per arm definition).
90
+ - Not a re-test of the deliberation features individually (stance tally,
91
+ chairman) — arm B runs the current default debate shape; feature ablations
92
+ are follow-ups only if B beats A at all.
@@ -0,0 +1,51 @@
1
+ # Utilization-window decision criteria — pre-registered
2
+
3
+ > Design artifact for `road-to-feedback-8.11-2` Phase 0. The engagement
4
+ > observation window (telemetry.artifact_engagement, id-only,
5
+ > PII-excluded-by-construction) has been RUNNING in the agent-config repo
6
+ > since 2026-07-12. Per the repo's claims convention, the window's decision
7
+ > rules are fixed HERE, BEFORE the numbers accumulate — the reviewer's
8
+ > warning was precise: without pre-fixed criteria "the window ends with
9
+ > many events and no decidable statement." Companion claim:
10
+ > `docs/CLAIMS.md § utilization-window-decidability`.
11
+
12
+ ## Observation floor (all three, else "underpowered")
13
+
14
+ 1. **≥ 100 recorded task boundaries** in `.agent-engagement.jsonl`
15
+ (boundary_kind `task` or `phase-step`).
16
+ 2. **≥ 2 distinct hosts** contributed records (host identity read from the
17
+ session context at analysis time, not stored in the event — the event
18
+ schema stays id-only; if host cannot be attributed without widening the
19
+ schema, the floor degrades to "≥ 2 distinct recording periods ≥ 14 days
20
+ apart" and this deviation is recorded in the closing report).
21
+ 3. **≥ 45 elapsed days** since 2026-07-12.
22
+
23
+ Below the floor at day 90 → the window is **underpowered**: extend ONCE by
24
+ 30 days. Still below → STOP, record the honest null ("insufficient natural
25
+ usage volume to decide utilization"), and do NOT rebuild collection
26
+ apparatus without a new demand signal.
27
+
28
+ ## Decision rules (fixed now — no goalpost-moving)
29
+
30
+ | # | Observation at window close | Bound decision |
31
+ |---|---|---|
32
+ | D1 | Artifact kind entry (skill/rule/command/guideline/persona id) **loaded-never-consulted** across the full window (requires the U1a `loaded` denominator; if U1a has not landed, D1 degrades to consulted-set analysis and says so) | Goes on the **retirement-candidate list** feeding U1's ranked cut list — candidate, not auto-cut; kernel + safety floors exempt by construction |
33
+ | D2 | Artifact **consulted-never-applied** with ≥ 5 consultations and applied-ratio < 10% | Goes on the **trigger-review queue** (description/trigger overhaul, not deletion) |
34
+ | D3 | Window closes **above the floor** | The first U1 report MUST name ≥ 1 concrete keep/cut/review decision per artifact kind, or record per kind why the data does not support one |
35
+ | D4 | Window closes **below the floor** (after the one extension) | Honest null; lifecycle-automation and field-outcome-ledger gates STAY closed (their revisit-if remains "≥ 1 full window") |
36
+
37
+ ## Explicitly out of scope for this window
38
+
39
+ - **Outcome-quality attribution** (did artifact X improve the result) —
40
+ needs the `loaded` denominator plus far more volume; stays with U1a.
41
+ - **Cost-vs-rework economics** — owned by the orchestration telemetry
42
+ track (`road-to-subagent-value-realization-followup`).
43
+ - **Cross-repo aggregation** — the window is this repo only (council
44
+ condition from the 8.11 disposition).
45
+
46
+ ## Kill criterion
47
+
48
+ If the window closes decidable (D3) but its decisions are cited by zero
49
+ actual portfolio changes within 2 releases, the analysis layer (not the
50
+ telemetry) is the dead weight — record that honest null before building
51
+ any further reporting on top.
@@ -92,4 +92,4 @@ task lint-featured-skills
92
92
 
93
93
  CI runs this in `taskfiles/ci-fast.yml`. Stale entries (renamed / removed skill or command) fail the build. See [`scripts/lint_featured_skills.py`](../src/scripts/lint_featured_skills.py) for the matcher.
94
94
 
95
- → Browse all 271 skills: [`dist/agent-src/skills/`](../dist/agent-src/skills/) · all 178 commands: [`dist/agent-src/commands/`](../dist/agent-src/commands/)
95
+ → Browse all 271 skills: [`dist/agent-src/skills/`](../dist/agent-src/skills/) · all 183 commands: [`dist/agent-src/commands/`](../dist/agent-src/commands/)
@@ -2,7 +2,7 @@
2
2
 
3
3
  > Pick the entry that matches what you do day-to-day. Each section names the three skills you will reach for first and shows whether MCP (no terminal) or CLI (terminal) is the simpler install path for that role.
4
4
 
5
- `agent-config` ships 271 skills, 104 governed rules, and 178 commands. You do not need all of them. Each role below filters to the slice that pays back in week one; the rest stays available and shows up on demand when a task references it.
5
+ `agent-config` ships 271 skills, 104 governed rules, and 183 commands. You do not need all of them. Each role below filters to the slice that pays back in week one; the rest stays available and shows up on demand when a task references it.
6
6
 
7
7
  > **Taglines at a glance →** [`docs/role-experiences.md`](role-experiences.md) — the one-line pitch per role experience, in one table.
8
8
 
@@ -73,6 +73,8 @@ Cinematic-blueprint approach: the agent expands your script into a 12-block scen
73
73
  - [`nextjs-patterns`](../dist/agent-src/skills/nextjs-patterns/SKILL.md) — App Router, Server Components, Server Actions, caching.
74
74
  - [`quality-tools`](../dist/agent-src/skills/quality-tools/SKILL.md) — PHPStan, Rector, ECS error triage and fix loop.
75
75
 
76
+ Cross-model review of the real diff (**team mode**, default off) is documented in [Getting Started § Team mode](getting-started.md#team-mode--cross-model-review-default-off).
77
+
76
78
  **Install path:** **CLI.** Run `npx @event4u/agent-config init --tools=claude-code,cursor` in the project root. MCP works too but loses git / file-system tooling that the IDE-integrated path gives you.
77
79
 
78
80
  ---