@event4u/agent-config 2.12.0 → 2.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 (64) hide show
  1. package/.agent-src/commands/council/analysis.md +142 -0
  2. package/.agent-src/commands/council/debate.md +129 -0
  3. package/.agent-src/commands/council/default.md +8 -0
  4. package/.agent-src/commands/council/design.md +16 -12
  5. package/.agent-src/commands/council/optimize.md +16 -15
  6. package/.agent-src/commands/council/pr.md +12 -12
  7. package/.agent-src/commands/council.md +48 -2
  8. package/.agent-src/personas/advisors/contrarian.md +95 -0
  9. package/.agent-src/personas/advisors/executor.md +99 -0
  10. package/.agent-src/personas/advisors/expansionist.md +98 -0
  11. package/.agent-src/personas/advisors/first-principles.md +98 -0
  12. package/.agent-src/personas/advisors/outsider.md +102 -0
  13. package/.agent-src/rules/copilot-routing.md +19 -0
  14. package/.agent-src/rules/devcontainer-routing.md +20 -0
  15. package/.agent-src/rules/laravel-routing.md +20 -0
  16. package/.agent-src/rules/symfony-routing.md +20 -0
  17. package/.agent-src/skills/ai-council/SKILL.md +180 -2
  18. package/.agent-src/skills/copilot-config/SKILL.md +1 -1
  19. package/.agent-src/skills/devcontainer/SKILL.md +1 -1
  20. package/.agent-src/skills/laravel/SKILL.md +1 -1
  21. package/.agent-src/skills/project-analysis-core/SKILL.md +1 -1
  22. package/.agent-src/skills/project-analyzer/SKILL.md +1 -1
  23. package/.agent-src/skills/symfony-workflow/SKILL.md +1 -1
  24. package/.agent-src/skills/universal-project-analysis/SKILL.md +1 -1
  25. package/.agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  26. package/.claude-plugin/marketplace.json +3 -1
  27. package/AGENTS.md +1 -1
  28. package/CHANGELOG.md +47 -0
  29. package/CONTRIBUTING.md +5 -0
  30. package/README.md +3 -3
  31. package/config/agent-settings.template.yml +5 -93
  32. package/docs/architecture/multi-tool-projection.md +53 -0
  33. package/docs/architecture/{compression.md → source-projection.md} +21 -3
  34. package/docs/architecture.md +5 -5
  35. package/docs/catalog.md +21 -11
  36. package/docs/contracts/adr-architectural-consensus-mechanism.md +67 -0
  37. package/docs/contracts/ai-council-config.md +186 -0
  38. package/docs/contracts/command-clusters.md +57 -1
  39. package/docs/contracts/multi-tool-projection-fidelity.md +109 -0
  40. package/docs/getting-started.md +2 -2
  41. package/package.json +1 -1
  42. package/scripts/_archive/README.md +59 -0
  43. package/scripts/ai_council/_default_prices.py +10 -1
  44. package/scripts/ai_council/advisors.py +148 -0
  45. package/scripts/ai_council/clients.py +172 -0
  46. package/scripts/ai_council/config.py +368 -0
  47. package/scripts/ai_council/consensus.py +290 -0
  48. package/scripts/ai_council/orchestrator.py +628 -14
  49. package/scripts/ai_council/prompts.py +335 -0
  50. package/scripts/check_compressed_paths.py +6 -1
  51. package/scripts/ci_time_ratio.py +168 -0
  52. package/scripts/council_cli.py +973 -29
  53. package/scripts/measure_projection_bytes.py +159 -0
  54. package/scripts/measure_roadmap_trajectory.py +112 -0
  55. package/scripts/probe_projection_fidelity.py +202 -0
  56. package/scripts/score_skill_selection.py +198 -0
  57. package/scripts/skill_collision_clusters.py +162 -0
  58. /package/scripts/{_backfill_skill_domains.py → _archive/_backfill_skill_domains.py} +0 -0
  59. /package/scripts/{_bootstrap_tier_frontmatter.py → _archive/_bootstrap_tier_frontmatter.py} +0 -0
  60. /package/scripts/{_p43_bodies.py → _archive/_p43_bodies.py} +0 -0
  61. /package/scripts/{_p43_compress.py → _archive/_p43_compress.py} +0 -0
  62. /package/scripts/{_p4_migrate.py → _archive/_p4_migrate.py} +0 -0
  63. /package/scripts/{_phase2_shim_helper.py → _archive/_phase2_shim_helper.py} +0 -0
  64. /package/scripts/{_pilot_council_question.py → _archive/_pilot_council_question.py} +0 -0
@@ -292,6 +292,65 @@ NEVER ships the host verdict as council output. Provider attribution
292
292
  stays visible in the per-member sections; host verdicts stay
293
293
  attributed to the host.
294
294
 
295
+ ## Synthesis templates (lens-aware)
296
+
297
+ The **Convergence / Divergence** slot in `council:render` output is
298
+ populated with a lens-specific synthesis prompt. The host agent reads
299
+ this prompt and writes the summary in the shape it dictates. The five
300
+ templates live in `scripts/ai_council/prompts.py::_SYNTHESIS_TABLE`
301
+ and are exposed via `synthesis_template(mode)`.
302
+
303
+ **R4 Q4 split** — decision lenses get a structured Karpathy-style
304
+ template; creative lenses stay open-ended prose (bare slot):
305
+
306
+ | Lens | Class | Synthesis sections |
307
+ |---|---|---|
308
+ | `default` | decision | Agreement · Clashes · Blind spots · Recommendation · Next step |
309
+ | `pr` | decision | Consensus · Conflicts · Must-fix before merge · Recommendation |
310
+ | `analysis` | decision | Top-10 by consensus · Supporting · Outliers |
311
+ | `design` | creative | *(no template — open prose passthrough)* |
312
+ | `optimize` | creative | *(no template — open prose passthrough)* |
313
+
314
+ Input modes (`prompt` / `roadmap` / `diff` / `files`) inherit the
315
+ `default` decision template — they are bundling shapes, not lenses.
316
+
317
+ **Source citations:**
318
+ * Template shape — Round 2 council verdict
319
+ (`agents/council-sessions/2026-05-14-ai-council-redesign/round-1.md`,
320
+ Opus's lens-adaptive synthesis proposal).
321
+ * Decision/creative split — Round 4 Q4 verdict
322
+ (`agents/council-sessions/2026-05-14-ai-council-redesign/round-3-responses.json`).
323
+ R4 reframed `optimize` as creative because perf trade-offs resist
324
+ pre-templated shape — Performance-wins / Trade-offs /
325
+ Implementation-order is too rigid for the variety of optimize-lens
326
+ artefacts. R4 reframed `design` for the same reason — design
327
+ critiques are inherently narrative.
328
+
329
+ ### `--prose-synthesis` escape hatch (R4 Q4)
330
+
331
+ Both `council:run` and `council:render` accept symmetric escape-hatch
332
+ flags on top of the lens table:
333
+
334
+ * `--prose-synthesis` — force creative-lens passthrough (bare slot)
335
+ regardless of lens. Use when the user on `default`/`pr`/`analysis`
336
+ prefers a narrative recommendation over the structured template.
337
+ * `--no-prose-synthesis` — force the `default` structured template
338
+ even on a creative lens. Use when a `design` or `optimize` artefact
339
+ has a one-shot need for Karpathy-style structure.
340
+
341
+ The flag is mutually exclusive — picking one disables the other on
342
+ the same invocation. When `council:run` records either flag in the
343
+ output JSON, `council:render` honours it unless the renderer is
344
+ called with an explicit flag of its own.
345
+
346
+ ### Renderer lens resolution
347
+
348
+ `council:render <responses.json>` resolves the active lens in this
349
+ order: explicit `--prompt-mode` flag > `prompt_mode` field in the
350
+ payload > `mode` field in the payload > `None` (default decision
351
+ template). The `--prose-synthesis` / `--no-prose-synthesis` flag
352
+ overrides the table regardless of how the lens resolved.
353
+
295
354
  ## Do NOT
296
355
 
297
356
  - Do NOT paraphrase council output into the host agent's voice — strip
@@ -435,8 +494,8 @@ prompt as `<original artefact> + <prior round, anonymised>` so each
435
494
  member can refine, agree, or push back on the previous critique
436
495
  without seeing which provider produced which point.
437
496
 
438
- The default round count comes from `ai_council.min_rounds` in
439
- `.agent-settings.yml` (default `2` so members critique each other
497
+ The default round count comes from `defaults.min_rounds` in
498
+ `agents/.ai-council.yml` (default `2` so members critique each other
440
499
  at least once before convergence). The host agent does **not** ask
441
500
  "how many rounds?" when the requested count is `<= min_rounds` —
442
501
  the settings owner already made that decision. Ask only when a
@@ -516,6 +575,121 @@ internal "more feedback" follow-up loop (1 / 2 / 3 menu) is
516
575
  **inside** a single member's chat thread and is orthogonal to the
517
576
  orchestrator-level rounds.
518
577
 
578
+ ### `/council debate` sub-command (progressive disclosure)
579
+
580
+ `/council debate <artefact> [--rounds N] [--continue-as-debate <session>]`
581
+ runs an **interactive** multi-round critique with a confirmation gate
582
+ between every round so the user can stop the spend at any point.
583
+
584
+ | Property | Behaviour |
585
+ |---|---|
586
+ | 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. |
587
+ | 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. |
588
+ | 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. |
589
+ | `--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. |
590
+ | Session files | One file per round under `agents/council-sessions/<slug>/debate-round-NN.md`. |
591
+ | Anonymisation | Identical to `rounds:N`. The continue-as-debate path also anonymises the seeded round-1 responses when building the round-2 prompt. |
592
+
593
+ Use this when the artefact is genuinely contentious and the user
594
+ wants to control depth interactively. For a fire-and-forget
595
+ multi-round run, prefer `consult(..., rounds=N)` or `--rounds N` on
596
+ `/council default`.
597
+
598
+
599
+ ## Karpathy peer-review (opt-in)
600
+
601
+ After the final deliberation round, an optional **anonymous peer-review
602
+ pass** lets each member critique the *other* members' responses for
603
+ blind spots before synthesis. Inspired by Andrej Karpathy's "ask the
604
+ strongest models to review each other anonymously" pattern; see his
605
+ [talks / threads on inter-model critique](https://karpathy.ai/) and the
606
+ internal verdict in
607
+ `agents/council-sessions/2026-05-14-ai-council-redesign/round-2.md`
608
+ (R2 split: one approve-as-flag, one reject-as-default → opt-in only).
609
+
610
+ Pipeline order when every feature is active:
611
+
612
+ ```
613
+ deliberation rounds → peer-review → consensus-scoring → synthesis
614
+ ```
615
+
616
+ Activation — two equivalent paths:
617
+
618
+ * CLI: `--peer-review` on `council:estimate` or `council:run`.
619
+ * Config: `ai_council.peer_review.enabled: true` in
620
+ `agents/.ai-council.yml`. Default is `false`.
621
+
622
+ Mechanics:
623
+
624
+ 1. The final deliberation round's outputs are anonymised into
625
+ `Response-A`, `Response-B`, … in stable input order. Provider /
626
+ model identity is stripped (Iron-Law neutrality holds); empty or
627
+ errored deliberation responses are skipped.
628
+ 2. Each member receives an N−1 view (its own response filtered out)
629
+ plus the Karpathy prompt: *strongest response*, *weakest blind
630
+ spot*, *what did everyone miss*, *refinement*.
631
+ 3. The N critiques flow back into synthesis through a
632
+ "Peer-Review-Surfaced Blind Spots" addendum on the lens template.
633
+ 4. **Advisor preserve-persona (R4 Q3, hard-coded):** when the
634
+ deliberation was an advisor-mode run (Phase 6), anonymisation
635
+ strips provider identity but **preserves the advisor persona
636
+ label**. Peer-review renders as `Response A (Contrarian)`, never
637
+ `Response A (Anthropic Opus)`. Plain-member runs strip identity
638
+ entirely.
639
+
640
+ Cost — adds exactly N billable calls (one per member) at the same
641
+ per-call cost as a deliberation call. The `council:estimate` table
642
+ surfaces the delta as a `+peer-review: +N calls (~+$X)` row.
643
+
644
+ Needs ≥ 2 distinct deliberation outputs; below that the round is a
645
+ no-op and nothing extra is billed. Self-review is structurally
646
+ impossible — a member never sees its own response.
647
+
648
+ ## Thinking-style advisors (replace-mode)
649
+
650
+ Phase 6 introduces five **advisor personas** the council adopts in
651
+ *replace-mode*: an enabled advisor substitutes its bound member's
652
+ plain call with the same provider running the advisor's persona
653
+ prompt. Total call count stays the same — only the system prompt
654
+ swaps.
655
+
656
+ | Advisor | Default bound member | Focus |
657
+ |---|---|---|
658
+ | **Contrarian** | `anthropic` | strongest counterargument, hidden assumptions |
659
+ | **First-Principles** | `anthropic` | strip metaphor, derive from physics / math / cost |
660
+ | **Expansionist** | `openai` | adjacent opportunities, second-order effects |
661
+ | **Outsider** | `openai` | naive-but-sharp questions, beginner's-mind probes |
662
+ | **Executor** | `anthropic` | what ships this quarter, what blocks delivery |
663
+
664
+ Activation — edit `agents/.ai-council.yml` and flip the advisor's
665
+ `enabled: true`. Optional `model: <name>` overrides the bound
666
+ member's default model. An advisor referencing a disabled member
667
+ fails closed at config load — never silently skipped.
668
+
669
+ ```yaml
670
+ advisors:
671
+ contrarian:
672
+ enabled: true # ← swap anthropic's plain call for contrarian
673
+ member: anthropic
674
+ # model: claude-opus-4 # optional pin
675
+ ```
676
+
677
+ `council:estimate` surfaces every active swap on a dedicated line
678
+ above the cost table:
679
+
680
+ ```
681
+ council:estimate · mode=prompt · members=2 (billable=2)
682
+ advisor: Contrarian on anthropic via claude-sonnet-4-5
683
+ anthropic/claude-sonnet-4-5: ~991 in + 256 out = $0.0068
684
+ openai/gpt-4o: ~208 in + 256 out = $0.0031
685
+ ```
686
+
687
+ Cost-bounded — replace-mode never adds calls. The persona prompt is
688
+ larger than plain (~1k extra input tokens per swap); output tokens
689
+ and call count are unaffected. Peer-review preserves the advisor
690
+ label while stripping provider identity (`Response A (Contrarian)`).
691
+ Two enabled advisors on the same member is a config error.
692
+
519
693
  ## See also
520
694
 
521
695
  - `/council` command — the user-facing entry point.
@@ -523,6 +697,10 @@ orchestrator-level rounds.
523
697
  network, no spend, but no diversity of weights either).
524
698
  - `scripts/ai_council/prompts.py` — neutrality preamble + per-mode
525
699
  system prompts.
700
+ - `scripts/ai_council/advisors.py` — replace-mode planning + persona
701
+ resolution.
526
702
  - `scripts/ai_council/bundler.py` — redaction pattern set + size
527
703
  guard.
528
704
  - `docs/customization.md` § `ai_council.*` — settings reference.
705
+ - `docs/contracts/ai-council-config.md` § advisors — schema + precedence
706
+ contract.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: copilot-config
3
- description: "Use when configuring GitHub Copilot — copilot-instructions.md, PR review patterns, output optimization even when the user just says 'tune Copilot' or 'why is Copilot commenting on X'."
3
+ description: "Tune the GitHub Copilot AI `copilot-instructions.md`, PR-review patterns, suggestion behavior, output verbosity. NOT for dev-environment setup (use `devcontainer`)."
4
4
  source: package
5
5
  domain: process
6
6
  ---
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: devcontainer
3
- description: "Use when configuring DevContainers or GitHub Codespaces — devcontainer.json, custom images, secrets, VS Code features even when the user just says 'why does my Codespace not start'."
3
+ description: "Wire up DevContainers / GitHub Codespaces — `devcontainer.json`, container images, secrets, VS Code features, port forwarding. NOT for tuning Copilot itself (use `copilot-config`)."
4
4
  source: package
5
5
  domain: devops
6
6
  ---
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: laravel
3
- description: "Writes Laravel code following framework conventions, project architecture, and modern best practices for controllers, requests, services, jobs, events, policies, and application structure."
3
+ description: "Writes Laravel PHP Eloquent, Artisan controllers, FormRequests, jobs, events, policies, providers. For Symfony / Doctrine use `symfony-workflow`. For framework-free PHP use `php-coder`."
4
4
  source: package
5
5
  domain: engineering
6
6
  ---
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: project-analysis-core
3
- description: "Use for the universal deep-analysis workflow: project discovery, version resolution, docs loading, architecture mapping, execution flow, and package research."
3
+ description: "Raw discovery primitives project discovery, version resolution, docs loading, architecture mapping, execution flow. Called by `universal-project-analysis`. Single-pass scan → `project-analyzer`."
4
4
  source: package
5
5
  domain: discovery
6
6
  ---
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: project-analyzer
3
- description: "ONLY when user explicitly requests: full project analysis, tech stack detection, or structured analysis documents for agents/analysis/. NOT for regular feature work."
3
+ description: "ONLY when user asks for single-pass tech-stack detection or `agents/analysis/` write-up. Deep multi-pass audit → `universal-project-analysis`. Raw primitives `project-analysis-core`."
4
4
  source: package
5
5
  domain: discovery
6
6
  ---
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: symfony-workflow
3
- description: "Writes Symfony code following framework conventions, container wiring, and modern best practices for controllers, services, bundles, Messenger, Doctrine, security, and console commands."
3
+ description: "Writes Symfony PHP DI container, bundles, Doctrine, Messenger, Security voters, console commands. For Laravel / Eloquent / Artisan use `laravel`. For framework-free PHP use `php-coder`."
4
4
  source: package
5
5
  domain: engineering
6
6
  ---
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: universal-project-analysis
3
- description: "ONLY when user explicitly requests: full project analysis, deep codebase audit, or comprehensive architecture review. Routes to core and framework-specific analysis skills."
3
+ description: "ONLY when user asks for deep multi-pass codebase audit orchestrator routing to `project-analysis-core` + framework-specific `project-analysis-*`. Single-pass scan → `project-analyzer`."
4
4
  source: package
5
5
  domain: discovery
6
6
  ---
@@ -39,7 +39,7 @@ schema_version: 1
39
39
  # CI guard: a release bump of `package.json` must update this value
40
40
  # in lockstep — see scripts/check_template_pin_drift.py (road-to-
41
41
  # portable-runtime-and-update-check P3.3).
42
- agent_config_version: "2.8.0"
42
+ agent_config_version: "2.12.0"
43
43
 
44
44
  # --- Project identity ---
45
45
  project:
@@ -6,7 +6,7 @@
6
6
  },
7
7
  "metadata": {
8
8
  "description": "Shared agent configuration \u2014 skills for AI coding tools (Claude Code, Augment, Cursor, Cline, Windsurf, Gemini CLI).",
9
- "version": "2.12.0",
9
+ "version": "2.13.0",
10
10
  "keywords": [
11
11
  "agent-config",
12
12
  "skills",
@@ -105,6 +105,8 @@
105
105
  "./.claude/skills/copilot-config",
106
106
  "./.claude/skills/cost-report",
107
107
  "./.claude/skills/council",
108
+ "./.claude/skills/council-analysis",
109
+ "./.claude/skills/council-debate",
108
110
  "./.claude/skills/council-default",
109
111
  "./.claude/skills/council-design",
110
112
  "./.claude/skills/council-optimize",
package/AGENTS.md CHANGED
@@ -18,7 +18,7 @@ task ci # full pipeline — green before PR
18
18
 
19
19
  - **Package self-orientation** (beta) — identity, four-wing cognition map, repo layout, tech stack, key-rules table, telemetry, command-suggester: [`docs/contracts/package-self-orientation.md`](docs/contracts/package-self-orientation.md).
20
20
  - **Kernel + Router** (beta) — 9 always-loaded Iron-Law rules, tier-1 / tier-2 routing, cost profiles, per-rule char caps enforced by `task lint-rule-budget`: [`kernel-membership`](docs/contracts/kernel-membership.md) + [`rule-router`](docs/contracts/rule-router.md).
21
- - **Content pipelines** — A [compression](docs/architecture/compression.md), B [Augment projection](docs/architecture/augment-projection.md), C [multi-tool projection](docs/architecture/multi-tool-projection.md), D [Claude.ai bundle](docs/architecture/claude-bundle.md). Index: [`docs/architecture.md`](docs/architecture.md).
21
+ - **Content pipelines** — A [source projection](docs/architecture/source-projection.md), B [Augment projection](docs/architecture/augment-projection.md), C [multi-tool projection](docs/architecture/multi-tool-projection.md), D [Claude.ai bundle](docs/architecture/claude-bundle.md). Index: [`docs/architecture.md`](docs/architecture.md).
22
22
  - **Editing this repo** — Iron-Law rules (portability, source-of-truth, skill-quality) + Thin-Root contract: [`augment-portability`](.agent-src/rules/augment-portability.md), [`augment-source-of-truth`](.agent-src/rules/augment-source-of-truth.md), [`skill-quality`](.agent-src/rules/skill-quality.md), [`agents-md-thin-root`](.agent-src/skills/agents-md-thin-root/SKILL.md).
23
23
  - **Consumer story** — `npx` + `scripts/install.sh` + `.agent-settings.yml` opt-in flags, sandbox/offline install paths, verified-offline manifest: [`README.md`](README.md).
24
24
  - **Personas** — 11 review-lens cast (6 core · 5 specialist), `personas:` vs `/mode` axes, citation map, override pattern: [`docs/personas.md`](docs/personas.md), schema [`docs/contracts/persona-schema.md`](docs/contracts/persona-schema.md) (beta).
package/CHANGELOG.md CHANGED
@@ -429,6 +429,53 @@ our recommendation order, not its support status.
429
429
  > that forces a new era split (`# Era: 2.8.x`, etc.) — see
430
430
  > [`docs/contracts/CHANGELOG-conventions.md § Era splits`](docs/contracts/CHANGELOG-conventions.md).
431
431
 
432
+ ## [2.13.0](https://github.com/event4u-app/agent-config/compare/2.12.0...2.13.0) (2026-05-14)
433
+
434
+ ### Features
435
+
436
+ * **council:** Phase 7 — debate orchestration + CLI wiring ([647a3f0](https://github.com/event4u-app/agent-config/commit/647a3f07698792f41beb7413600d54b2321f4a96))
437
+ * **council:** Phase 7 — /council debate sub-command files ([abbd436](https://github.com/event4u-app/agent-config/commit/abbd43666b7e2c704ab3c46f2901f01eae446139))
438
+ * **council:** Phase 6 — thinking-style advisor personas ([21c8b88](https://github.com/event4u-app/agent-config/commit/21c8b88310a2a65d7ea9082da085d023f813d114))
439
+ * **council:** Phase 5 — Karpathy peer-review opt-in flag ([bce381a](https://github.com/event4u-app/agent-config/commit/bce381ae9c412abf501473fa4154f91d9c0befbf))
440
+ * **council:** analysis lens + lens-adaptive synthesis + consensus scoring ([6d7136a](https://github.com/event4u-app/agent-config/commit/6d7136ad6be31b7627a332600a7623f2cd929e76))
441
+ * **council:** add config loader, overlay, and 3 new provider clients ([0cb5591](https://github.com/event4u-app/agent-config/commit/0cb55914457a62b6f57744d8c8dac16bf777921d))
442
+ * **council:** introduce agents/.ai-council.yml as single source of truth ([043c2d2](https://github.com/event4u-app/agent-config/commit/043c2d23445f2ef7ad8aee880dc83d97c347635f))
443
+ * **governance:** Phase 5 — roadmap trajectory metric + architectural-consensus ADR ([926a632](https://github.com/event4u-app/agent-config/commit/926a63237c3dbe1fcfd7df05c9230809382d8790))
444
+ * **projection:** Phase 4 + 1.4 — multi-tool projection fidelity contract + ci-strict gate ([e18e4ad](https://github.com/event4u-app/agent-config/commit/e18e4ad73595e17889009b0123ebd000254c165b))
445
+ * **routing:** Phase 3 — tighten skill descriptions + 4 tier-3 routing rules for failing clusters ([2a11c70](https://github.com/event4u-app/agent-config/commit/2a11c70b274741e7d98fd814ac39c1d05a1a38c9))
446
+ * **governance:** Phase 1 — credibility (CONTRIBUTING preface, source-projection rename, archive 7 migration scripts) ([2e5cfe0](https://github.com/event4u-app/agent-config/commit/2e5cfe02e1b5f4218d1283108796b0ce43fd9165))
447
+
448
+ ### Bug Fixes
449
+
450
+ * **docs:** drop transient council-sessions citation from multi-tool-projection ([55dbbb1](https://github.com/event4u-app/agent-config/commit/55dbbb1e599aae2d913dc56a05c9dab0014e2739))
451
+ * **linter:** treat ../docs/contracts/ links as out-of-scope like guidelines ([a2249b0](https://github.com/event4u-app/agent-config/commit/a2249b02b70233e2b13ccf3efeda4188686b6181))
452
+ * **routing:** strip transient roadmap citation from tier-3 routing rules ([2cf745c](https://github.com/event4u-app/agent-config/commit/2cf745cad9beb40c4e6e9eb7f97abbc58a94d9de))
453
+
454
+ ### Documentation
455
+
456
+ * **roadmap:** rename "rule" to "invariant" for deep_min_rounds reference ([758ea46](https://github.com/event4u-app/agent-config/commit/758ea46568c23ef5518ff61d80700f7559bc54a1))
457
+ * **ai-council:** sync compressed SKILL.md with Phase 6 advisors section ([6d57034](https://github.com/event4u-app/agent-config/commit/6d57034c7b342abdd5d38ff300fa67c51deb3471))
458
+ * **council:** document master/wrapper contract for the council cluster ([7346f34](https://github.com/event4u-app/agent-config/commit/7346f34376b48c02ced3ae939dfff6ea215025ba))
459
+
460
+ ### Tests
461
+
462
+ * **ai-council:** Phase 8 — negative-test backfill for config loader ([cc3a08c](https://github.com/event4u-app/agent-config/commit/cc3a08c360c94685f9a1efaaa57f84001f78788c))
463
+
464
+ ### Chores
465
+
466
+ * **roadmaps:** archive step-2-ai-council-consolidation — all phases + ACs done ([c7f0c9c](https://github.com/event4u-app/agent-config/commit/c7f0c9ca7ac300023c5da0b939e0c63554dbcfed))
467
+ * **docs:** bump getting-started command count 106 -> 108 after council debate sub-command ([5e256d7](https://github.com/event4u-app/agent-config/commit/5e256d79d3eea3046900e8afa5be64526b4fc61d))
468
+ * **roadmaps:** retag complexity from "medium" to lint-valid values ([4c5457e](https://github.com/event4u-app/agent-config/commit/4c5457e271f8dcdc03943bac7adff84455388615))
469
+ * regenerate index + catalog for council-debate skill ([3c365a3](https://github.com/event4u-app/agent-config/commit/3c365a375da22f16f97829677c875500e40d436a))
470
+ * **roadmap:** mark Phases 6-7 of step-2-ai-council-consolidation complete ([7e8e557](https://github.com/event4u-app/agent-config/commit/7e8e557505bbf88b486605980a7f5ee2f97bcbb4))
471
+ * **roadmap:** mark Phases 1-4 of step-2-ai-council-consolidation complete ([101a5cf](https://github.com/event4u-app/agent-config/commit/101a5cf70d4fc694f85a270b2bebfb8fe545833a))
472
+ * **roadmap:** mark Phase 0 of step-2-ai-council-consolidation complete ([4fa2734](https://github.com/event4u-app/agent-config/commit/4fa27346c8faad54de582757ce5cfe7216041bda))
473
+ * **template:** bump agent_config_version pin to 2.12.0 ([e5c41fd](https://github.com/event4u-app/agent-config/commit/e5c41fd433105359d6e36b03b0de62415be212f0))
474
+ * regenerate agents/index.md + docs/catalog.md after rule additions ([b7fa4b6](https://github.com/event4u-app/agent-config/commit/b7fa4b6e25cbc55d8b3197f815c00530bd1eee79))
475
+ * **roadmap:** archive completed step-1-v2-feedback-followup (20/20 done) ([88a07ea](https://github.com/event4u-app/agent-config/commit/88a07ea9a983f0b63710e5461c8fddee36b2d378))
476
+
477
+ Tests: 3868 (+150 since 2.12.0)
478
+
432
479
  ## [2.12.0](https://github.com/event4u-app/agent-config/compare/2.11.0...2.12.0) (2026-05-14)
433
480
 
434
481
  ### Features
package/CONTRIBUTING.md CHANGED
@@ -3,6 +3,11 @@
3
3
  Thanks for considering a contribution to `event4u/agent-config`. This file
4
4
  describes how to propose changes and what the package's conventions are.
5
5
 
6
+ > **This project is currently single-maintainer (`matze4u`).** Contributions
7
+ > are welcome; expect direct review and potentially slower response than
8
+ > multi-maintainer projects. The process below describes the target workflow
9
+ > as the contributor base grows.
10
+
6
11
  ## Status and scope
7
12
 
8
13
  The package is maintained by a small team at event4u:
package/README.md CHANGED
@@ -7,7 +7,7 @@ Give your AI agents an audit-disciplined orchestration contract — testing, Git
7
7
  > Your agent picks up the project's stack, runs tests, prepares PRs, fixes CI — and follows your team's coding standards while doing it. Stack-aware skill sets ship for PHP (Laravel · Symfony · Zend/Laminas), JavaScript (Next.js · React · Node), and cross-stack concerns (API · testing · security · observability).
8
8
 
9
9
  <p align="center">
10
- <strong>210 Skills</strong> · <strong>61 Rules</strong> · <strong>106 Commands</strong> · <strong>72 Guidelines</strong> · <strong>8 AI Tools</strong>
10
+ <strong>210 Skills</strong> · <strong>65 Rules</strong> · <strong>108 Commands</strong> · <strong>72 Guidelines</strong> · <strong>8 AI Tools</strong>
11
11
  </p>
12
12
 
13
13
  ---
@@ -524,7 +524,7 @@ kernel set: [`docs/contracts/kernel-membership.md`](docs/contracts/kernel-member
524
524
  | [`/jira-ticket`](.agent-src/commands/jira-ticket.md) | Read ticket from branch, implement feature |
525
525
  | [`/compress`](.agent-src/commands/compress.md) | Compress skills for token efficiency |
526
526
 
527
- → [Browse all 106 active commands](.agent-src/commands/)
527
+ → [Browse all 108 active commands](.agent-src/commands/)
528
528
 
529
529
  ---
530
530
 
@@ -556,7 +556,7 @@ slash-commands) &nbsp; 📌 = informational marker only (no auto-discovery
556
556
  or manual wiring required)
557
557
 
558
558
  > **What this means in practice:** Claude Code gets the full project-scoped
559
- > package (rules + 210 skills + 106 native commands); Augment Code gets the
559
+ > package (rules + 210 skills + 108 native commands); Augment Code gets the
560
560
  > same content but only from a single global install at `~/.augment/`.
561
561
  > Cursor, Cline, Windsurf, Gemini CLI, GitHub Copilot, Roo Code, Codex CLI,
562
562
  > and Continue.dev only get the **rules** natively; skills and commands are
@@ -232,100 +232,12 @@ worktrees:
232
232
 
233
233
  # --- AI Council (external second-opinion network) ---
234
234
  #
235
- # When enabled, the /council command lets the agent poll independent
236
- # external models (OpenAI, Anthropic) for a neutral critique of a
237
- # roadmap, diff, prompt, or file set. Council members never see the
238
- # host agent's reasoning only the artefact + a neutral system prompt.
235
+ # Configuration moved to `agents/.ai-council.yml` as of the Step-2
236
+ # consolidation roadmap. Consumer projects opt in by copying the
237
+ # reference file from the package (`agents/.ai-council.yml`) into their
238
+ # own `agents/` tree and flipping `enabled: true` per provider.
239
239
  #
240
- # Tokens are NEVER stored here. They live in ~/.event4u/agent-config/
241
- # <provider>.key (mode 0600; legacy ~/.config/agent-config/<provider>.key
242
- # is read as a fallback), installed via:
243
- # bash scripts/install_anthropic_key.sh
244
- # bash scripts/install_openai_key.sh
245
- #
246
- # Cost note: every consultation makes real, paid API calls. The
247
- # autonomy directive does NOT silently spend tokens — the /council
248
- # command always asks before invoking, even under autonomy: on.
249
- ai_council:
250
- # Master switch (true, false). Default false — installing a key is
251
- # not the same as wanting the agent to spend money on it.
252
- enabled: false
253
-
254
- # Default transport mode for every member (overridable per-member
255
- # below, and per-invocation via `/council mode:<x>`).
256
- #
257
- # api = direct SDK call against the provider's API (billable).
258
- # manual = copy-paste loop, user is the transport (free).
259
- #
260
- # Precedence: invocation flag > per-member mode > global mode > "manual".
261
- mode: "manual"
262
-
263
- # Per-member configuration. Set enabled=true on the providers you want
264
- # to consult. The model field selects which model receives the query.
265
- # Optional `mode:` overrides the global setting for that member only.
266
- members:
267
- anthropic:
268
- enabled: false
269
- model: "claude-sonnet-4-5"
270
- # mode: "api" # uncomment to override ai_council.mode
271
- openai:
272
- enabled: false
273
- model: "gpt-4o"
274
- # mode: "manual" # uncomment to override ai_council.mode
275
-
276
- # Default number of debate rounds per /council invocation.
277
- #
278
- # Round 1 sees the artefact alone. Round 2+ sees the artefact plus
279
- # anonymised critiques from the previous round (provider/model
280
- # identity stripped per the neutrality Iron Law). Applies identically
281
- # to api and manual transports — manual mode runs round 1 across all
282
- # members, the host agent consolidates, then round 2 starts with the
283
- # anonymised round-1 critiques folded in.
284
- #
285
- # Default is 2 so council members critique each other at least once
286
- # before convergence. The agent does NOT ask "how many rounds?" when
287
- # the requested rounds <= min_rounds; pass `rounds:N` on the
288
- # invocation (or `--rounds N` to the CLI) to override.
289
- min_rounds: 2
290
-
291
- # Higher floor for deep-reasoning artefacts (architecture review,
292
- # refactoring proposals, bug-diagnosis runs). Activated when the
293
- # consuming rule, skill, or command declares `council_depth: deep`
294
- # in its frontmatter, or the user passes `--depth deep` to the CLI.
295
- # Effective rounds = max(deep_min_rounds, min_rounds), so this floor
296
- # is monotonic — lowering it below `min_rounds` has no effect.
297
- # Standard tasks keep `min_rounds`; cost rises only when an artefact
298
- # opts in. Set to `min_rounds` to disable the deep tier.
299
- deep_min_rounds: 3
300
-
301
- # Per-member output-token budget passed to every API call. The CLI
302
- # `--max-tokens` flag overrides this on a single invocation; the
303
- # cost estimator uses the same value as its worst-case ceiling.
304
- # `0` means "unlimited" — internally widened to the safe provider
305
- # ceiling (16384) because Anthropic rejects max_tokens=0. Raise
306
- # explicitly past 16384 only when a model genuinely supports more
307
- # and you want longer answers.
308
- max_output_tokens: 2048
309
-
310
- # Hard cost ceiling per /council invocation. The orchestrator pauses
311
- # before any member whose projected spend would breach a cap and asks
312
- # the user to continue. `max_total_usd: 0` disables the USD ceiling
313
- # (token caps still apply). Total spend = rounds * single-round cost.
314
- #
315
- # Prices come from `agents/.agent-prices.md` (gitignored, refreshed weekly
316
- # by `python3 scripts/update_prices.py`; bootstrapped from
317
- # scripts/ai_council/_default_prices.py on first run).
318
- cost_budget:
319
- max_input_tokens: 50000
320
- max_output_tokens: 20000
321
- max_calls: 10
322
- max_total_usd: 0.50
323
-
324
- # Retention for council artefacts. Files older than this in
325
- # `agents/council-{questions,responses,sessions}/` are pruned
326
- # automatically on the next `save()` and on `task council-prune`.
327
- # `0` disables pruning (keep forever — disk grows unbounded).
328
- session_retention_days: 7
240
+ # See `docs/contracts/ai-council-config.md` for the schema.
329
241
 
330
242
  # --- Onboarding ---
331
243
  #
@@ -61,6 +61,56 @@ removes `.cursor/` on next `task generate-tools`.
61
61
  | Stale `.windsurfrules` after rule rename | concatenation cache | `task clean-tools && task generate-tools` |
62
62
  | Gemini CLI reads outdated content | `AGENTS.md` changed without re-symlink | `task generate-tools` |
63
63
 
64
+ ## Per-tool projection size
65
+
66
+ The previous "0.45 % reduction" headline was a wrong-boundary
67
+ measurement: that figure compares `.agent-src.uncompressed/` to
68
+ `.agent-src/`, but the pipeline's claimed function is *projection*, not
69
+ byte compression. The table below is produced by
70
+ [`scripts/measure_projection_bytes.py --regenerate`](../../scripts/measure_projection_bytes.py)
71
+ with every tool ID temporarily enabled in `.agent-tools.yml`.
72
+
73
+ | Surface | Files | Symlinks | Bytes materialized | Method |
74
+ |---|---:|---:|---:|---|
75
+ | `.agent-src.uncompressed/` | 596 | 0 | 3,253,997 | verbose source (input) |
76
+ | `.agent-src/` | 596 | 0 | 3,242,579 | source projection (path-rewrite + `.npmignore`) |
77
+ | `.augment/` | 61 | 7 | 136,146 | Augment Code — copies (rules) + symlinks (skills/cmds) |
78
+ | `.claude/` | 0 | 395 | 0 | Claude Code — pure symlinks |
79
+ | `.cursor/` | 61 | 189 | 124,741 | Cursor — per-rule `.mdc` materialized + symlinks |
80
+ | `.clinerules/` | 0 | 61 | 0 | Cline — pure symlinks |
81
+ | `.windsurf/` | 61 | 106 | 125,010 | Windsurf — per-rule wave-8 `.md` + symlinks |
82
+ | `.windsurfrules` | 1 | 0 | 114,263 | Windsurf legacy — concatenated single file |
83
+ | `GEMINI.md` | 0 | 1 | 0 | Gemini CLI — symlink → `AGENTS.md` |
84
+
85
+ **What the pipeline optimises**
86
+
87
+ - **Format fidelity** — each tool receives content in the format its host
88
+ reads natively (Cursor `.mdc` frontmatter, Windsurf Wave-8 frontmatter,
89
+ Claude / Cline symlinked into the source tree, Gemini single-file).
90
+ - **Path stability** — surface paths match the host vendor's
91
+ documentation so users opt in by enabling the tool, not by remapping.
92
+ - **Materialization minimization** — pure-symlink tools (`.claude/`,
93
+ `.clinerules/`, `GEMINI.md`) contribute zero bytes; tools that need a
94
+ format transform materialize only the transformed rule files.
95
+
96
+ **What the pipeline does not optimise**
97
+
98
+ - **Raw byte count** — `.cursor/` and `.windsurf/` *grow* the on-disk
99
+ footprint by ~125 KB each because their host formats require
100
+ per-rule frontmatter that cannot be supplied via symlink alone.
101
+ `.windsurfrules` materializes the rule set a second time as a
102
+ concatenated single file for users who prefer that surface.
103
+ - **Source dedup** — the same rule body appears in `.agent-src/rules/`
104
+ *and* in every tool's materialized projection. This is intentional:
105
+ removing the duplication would push format conversion into runtime.
106
+
107
+ Re-run the measurement after every change to the projection logic:
108
+
109
+ ```bash
110
+ python3 scripts/measure_projection_bytes.py --regenerate
111
+ python3 scripts/measure_projection_bytes.py --json # CI-friendly
112
+ ```
113
+
64
114
  ## Proving the pipeline
65
115
 
66
116
  - [`tests/test_modern_editor_formats.py`](../../tests/test_modern_editor_formats.py)
@@ -68,5 +118,8 @@ removes `.cursor/` on next `task generate-tools`.
68
118
  frontmatter; runs only when `task generate-tools` has been executed.
69
119
  - [`tests/test_compress.py`](../../tests/test_compress.py) — covers
70
120
  the shared compress / generate-tools entrypoint and `_filter_tool_dirs`.
121
+ - [`scripts/measure_projection_bytes.py`](../../scripts/measure_projection_bytes.py)
122
+ — per-tool byte / file / symlink count; the per-tool-size table above
123
+ is its output.
71
124
 
72
125
  ← [Architecture overview](../architecture.md)
@@ -1,7 +1,25 @@
1
- # Pipeline A — Compression
1
+ # Pipeline A — Source projection
2
2
 
3
- > **Scope:** transform verbose authoring source into the token-efficient
4
- > distribution payload that ships in the npm package.
3
+ > **Scope:** transform verbose authoring source into the deterministic
4
+ > distribution payload that ships in the npm package. The pipeline does
5
+ > path-rewriting, `.npmignore`-style filtering, hash-tracking, and (on
6
+ > selected files) caveman-style prose compression. The *primary* function
7
+ > is the source-to-dist projection itself; raw byte reduction is small
8
+ > (~0.35 % on the source/dist boundary: 3,253,997 B → 3,242,579 B across
9
+ > 596 files) because most files are 1:1-projected with only frontmatter
10
+ > and link rewrites. Per-tool size at the downstream projection
11
+ > boundaries (`.augment/`, `.claude/`, `.cursor/`, `.windsurf/`,
12
+ > `.clinerules/`, `.windsurfrules`, `GEMINI.md`) is measured separately
13
+ > — see [`multi-tool-projection.md § Per-tool projection size`](multi-tool-projection.md#per-tool-projection-size)
14
+ > for the table produced by [`scripts/measure_projection_bytes.py`](../../scripts/measure_projection_bytes.py).
15
+
16
+ > **Historical note.** This pipeline was previously labelled
17
+ > "Compression". Renamed in the v2.10.0 feedback follow-up after the
18
+ > council pointed out that the dominant function is projection, not
19
+ > byte compression. The script names (`scripts/compress.py`,
20
+ > `scripts/compress.sh`) are kept for now to avoid a large blast-radius
21
+ > refactor; the prose-compression sub-step (and the `/compress` slash
22
+ > command for caveman text compression) still earn the legacy name.
5
23
 
6
24
  ## Input → Transform → Output
7
25