@event4u/agent-config 10.1.0 → 10.3.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 (158) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/CHANGELOG.md +110 -167
  3. package/README.md +1 -1
  4. package/dist/agent-src/commands/analyze/reference-repo.md +62 -0
  5. package/dist/agent-src/commands/roadmap/create.md +4 -1
  6. package/dist/agent-src/commands/roadmap/next.md +38 -0
  7. package/dist/agent-src/contexts/communication/rules-auto/token-efficiency-mechanics.md +22 -1
  8. package/dist/agent-src/contexts/contracts/frugality-charter.md +1 -1
  9. package/dist/agent-src/personas/advisors/first-principles.md +6 -0
  10. package/dist/agent-src/rules/active-remediation.md +53 -2
  11. package/dist/agent-src/rules/code-provenance.md +66 -4
  12. package/dist/agent-src/rules/content-quoting-floor.md +6 -0
  13. package/dist/agent-src/rules/context-hygiene.md +39 -0
  14. package/dist/agent-src/rules/design-fidelity.md +49 -3
  15. package/dist/agent-src/rules/token-budget-discipline.md +3 -2
  16. package/dist/agent-src/rules/token-efficiency.md +22 -0
  17. package/dist/agent-src/skills/ai-council/SKILL.md +28 -6
  18. package/dist/agent-src/skills/condense-memory/SKILL.md +1 -1
  19. package/dist/agent-src/skills/design-review/references/verification-automation.md +23 -1
  20. package/dist/agent-src/skills/fe-design/SKILL.md +27 -3
  21. package/dist/agent-src/skills/judge-synthesis/SKILL.md +30 -0
  22. package/dist/agent-src/skills/learning-to-rule-or-skill/SKILL.md +11 -0
  23. package/dist/agent-src/skills/roadmap-writing/SKILL.md +9 -9
  24. package/dist/agent-src/skills/skill-writing/SKILL.md +4 -0
  25. package/dist/agent-src/skills/token-optimizer/SKILL.md +5 -1
  26. package/dist/agent-src/templates/agent-settings.md +12 -28
  27. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +2 -2
  28. package/dist/agent-src/templates/persona.md +26 -0
  29. package/dist/agent-src/templates/roadmaps.md +27 -7
  30. package/dist/agent-src/templates/scripts/work_engine/_lib/agent_settings.ts +0 -1
  31. package/dist/agent-src/templates/skill.md +35 -1
  32. package/dist/cli/commands/commands.candidates.test.js +257 -0
  33. package/dist/cli/commands/commands.candidates.test.js.map +1 -0
  34. package/dist/cli/commands/commands.js +199 -0
  35. package/dist/cli/commands/commands.js.map +1 -1
  36. package/dist/cli/main.js +1 -0
  37. package/dist/cli/main.js.map +1 -1
  38. package/dist/cli/registry.js +2 -2
  39. package/dist/cli/registry.js.map +1 -1
  40. package/dist/cli-delegate/{chunk-3JUTT26I.js → chunk-6ENSXSBW.js} +1 -1
  41. package/dist/cli-delegate/{chunk-TVGXH7VA.js → chunk-6LOPHJLD.js} +1 -1
  42. package/dist/cli-delegate/{chunk-XT2YTJCZ.js → chunk-AYKQGIBG.js} +4 -0
  43. package/dist/cli-delegate/{chunk-HJSKTMIF.js → chunk-BV3WR67D.js} +3 -19
  44. package/dist/cli-delegate/{chunk-HTIU3W56.js → chunk-BWMXLD4B.js} +6 -2
  45. package/dist/cli-delegate/{chunk-2H5SE7DU.js → chunk-FV34EGEX.js} +166 -39
  46. package/dist/cli-delegate/{chunk-XTC5ARB6.js → chunk-IR3IVRVC.js} +7 -2
  47. package/dist/cli-delegate/{chunk-LRXJK6GN.js → chunk-JMQZ7MM5.js} +1 -1
  48. package/dist/cli-delegate/{chunk-NX5AXSLD.js → chunk-X3VOARZD.js} +3 -3
  49. package/dist/cli-delegate/cmd_analyze_session.js +1 -1
  50. package/dist/cli-delegate/cmd_brand_status.js +1 -1
  51. package/dist/cli-delegate/cmd_conformance.js +881 -204
  52. package/dist/cli-delegate/cmd_doctor.js +3 -3
  53. package/dist/cli-delegate/cmd_explain.js +2 -2
  54. package/dist/cli-delegate/cmd_export.js +4 -4
  55. package/dist/cli-delegate/cmd_handoff.js +6 -5
  56. package/dist/cli-delegate/cmd_mcp_available.js +1 -1
  57. package/dist/cli-delegate/cmd_migrate.js +2 -2
  58. package/dist/cli-delegate/cmd_packs_active.js +2 -2
  59. package/dist/cli-delegate/cmd_prune.js +4 -4
  60. package/dist/cli-delegate/cmd_route_audit.js +2 -2
  61. package/dist/cli-delegate/cmd_route_explain.js +1 -1
  62. package/dist/cli-delegate/cmd_session_recycle.js +44 -9
  63. package/dist/cli-delegate/cmd_settings_get.js +2 -2
  64. package/dist/cli-delegate/cmd_settings_migrate.js +4 -4
  65. package/dist/cli-delegate/cmd_settings_set.js +2 -2
  66. package/dist/cli-delegate/cmd_sync.js +4 -4
  67. package/dist/cli-delegate/cmd_uninstall.js +4 -4
  68. package/dist/cli-delegate/cmd_update.js +1 -1
  69. package/dist/cli-delegate/cmd_upgrade.js +1 -1
  70. package/dist/cli-delegate/cmd_validate.js +4 -4
  71. package/dist/cli-delegate/cmd_versions.js +1 -1
  72. package/dist/discovery/deprecation-report.md +1 -1
  73. package/dist/discovery/discovery-manifest.json +21 -21
  74. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  75. package/dist/discovery/discovery-manifest.summary.md +1 -1
  76. package/dist/discovery/dormancy-report.md +1 -1
  77. package/dist/discovery/orphan-report.md +1 -1
  78. package/dist/discovery/packs.json +2 -2
  79. package/dist/discovery/trust-report.md +1 -1
  80. package/dist/discovery/workspaces.json +2 -2
  81. package/dist/hooks/dispatch.js +204 -44
  82. package/dist/install/install.mjs +9 -21
  83. package/dist/mcp/registry-manifest.json +2 -2
  84. package/dist/mcp/server.json +2 -2
  85. package/dist/mcp/server.mjs +1337 -490
  86. package/dist/router.json +1 -1
  87. package/dist/scripts/_lib/agent_settings.js +25 -2
  88. package/dist/scripts/_lib/agent_settings.js.map +1 -1
  89. package/dist/scripts/_lib/compile_time_toggles.js +4 -3
  90. package/dist/scripts/_lib/compile_time_toggles.js.map +1 -1
  91. package/dist/server/io/yamlIO.js +0 -2
  92. package/dist/server/io/yamlIO.js.map +1 -1
  93. package/dist/server/schemas/settings.js +3 -9
  94. package/dist/server/schemas/settings.js.map +1 -1
  95. package/dist/shared/settingsClasses.js +64 -2
  96. package/dist/shared/settingsClasses.js.map +1 -1
  97. package/dist/ui/assets/{index-B5qGYOJo.js → index-5fXOHoVh.js} +2 -2
  98. package/dist/ui/assets/index-5fXOHoVh.js.map +1 -0
  99. package/dist/ui/index.html +1 -1
  100. package/docs/contracts/settings-classes.md +307 -145
  101. package/docs/guidelines/agent-infra/active-remediation-mechanics.md +54 -0
  102. package/docs/guidelines/agent-infra/layered-settings.md +1 -2
  103. package/docs/guidelines/agent-infra/symptom-driven-harvest-loop.md +104 -0
  104. package/docs/guidelines/design-antipatterns.md +79 -10
  105. package/docs/guidelines/design-fidelity-mechanics.md +120 -2
  106. package/package.json +1 -1
  107. package/src/agent-src/templates/scripts/work_engine/_lib/agent_settings.ts +0 -1
  108. package/src/config/agent-settings.template.yml +12 -30
  109. package/src/config/gate-coverage.yml +42 -8
  110. package/src/config/gate-violation-baselines.json +15 -3
  111. package/src/config/profiles/balanced.ini +0 -2
  112. package/src/config/profiles/full.ini +1 -3
  113. package/src/config/profiles/minimal.ini +0 -2
  114. package/src/config/review-prompt-binding-baseline.json +19 -0
  115. package/src/config/rule-enforcement-baseline.json +0 -1
  116. package/src/scripts/_cli/cmd_session_recycle.ts +66 -9
  117. package/src/scripts/_cli/handoff_sessions.ts +3 -2
  118. package/src/scripts/_dispatch.bash +1 -0
  119. package/src/scripts/_lib/agent_settings.ts +25 -2
  120. package/src/scripts/_lib/bench_telegraph.ts +1 -1
  121. package/src/scripts/_lib/cc_transcript.ts +25 -0
  122. package/src/scripts/_lib/compile_time_toggles.ts +4 -3
  123. package/src/scripts/ai_council/clients.ts +243 -34
  124. package/src/scripts/cache_realization_report.ts +3 -2
  125. package/src/scripts/check_ci_local_parity.ts +60 -6
  126. package/src/scripts/check_review_prompt_binding.ts +553 -0
  127. package/src/scripts/check_rule_projection_integrity.ts +3 -1
  128. package/src/scripts/check_suppression_hygiene.ts +19 -3
  129. package/src/scripts/conformance_scan.ts +282 -9
  130. package/src/scripts/cost/track.mjs +10 -4
  131. package/src/scripts/council_cli.ts +33 -3
  132. package/src/scripts/design_slop_rules.test.ts +37 -6
  133. package/src/scripts/design_slop_rules.ts +150 -22
  134. package/src/scripts/dispatch_r2_reviewer.ts +15 -1
  135. package/src/scripts/external_sources_denylist.json +3 -1
  136. package/src/scripts/hook_manifest.yaml +17 -6
  137. package/src/scripts/hooks/block_unauthorized_git.ts +54 -8
  138. package/src/scripts/hooks/delegation_nudge_hook.ts +33 -8
  139. package/src/scripts/hooks/evidence_independence.ts +61 -9
  140. package/src/scripts/hooks/session_eol_hook.ts +123 -3
  141. package/src/scripts/hooks/turn_end_gate_hook.ts +31 -0
  142. package/src/scripts/hooks/ui_route_nudge_hook.ts +55 -2
  143. package/src/scripts/lint_design_antipattern_parity.ts +201 -0
  144. package/src/scripts/lint_harvest_provenance.ts +483 -0
  145. package/src/scripts/lint_settings_classes.ts +273 -11
  146. package/src/scripts/lint_skill_router_head.ts +254 -0
  147. package/src/scripts/lint_symptom_intake.ts +241 -0
  148. package/src/scripts/report_consultation_rate.ts +128 -2
  149. package/src/scripts/report_skill_activation.ts +6 -4
  150. package/src/scripts/report_skill_obligation_violations.ts +2 -1
  151. package/src/scripts/run_skill_evals.ts +10 -5
  152. package/src/scripts/schemas/persona.schema.json +8 -0
  153. package/src/scripts/schemas/provenance-harvest.schema.json +39 -0
  154. package/src/scripts/sweep_dead_scan_roots.ts +51 -0
  155. package/src/server/io/yamlIO.ts +0 -2
  156. package/src/server/schemas/settings.ts +3 -19
  157. package/src/shared/settingsClasses.ts +93 -2
  158. package/dist/ui/assets/index-B5qGYOJo.js.map +0 -1
@@ -56,6 +56,10 @@ INTENT
56
56
  │ → cite markitdown (upstream: https://github.com/microsoft/markitdown)
57
57
  │ Convert FIRST, then read the markdown — never paste raw binary.
58
58
  │
59
+ ├── Large file read (source / data / log already in the tree, > 800 lines)
60
+ │ → cite [token-efficiency § Size-gated reads](../../rules/token-efficiency.md)
61
+ │ (size → structural grep → bounded slice; never a full read on spec)
62
+ │
59
63
  ├── Repeated tool-call across N targets
60
64
  │ → cite [token-efficiency](../../rules/token-efficiency.md)
61
65
  │ (batch, parallelize, prune; one tool call > many)
@@ -81,7 +85,7 @@ INTENT
81
85
  |---|---|---|---|
82
86
  | `cli-output-handling` | `src/rules/cli-output-handling.md` | `verbose`, `tail`, `grep`, `CLI` | Wrap-tail-grep contract for any verbose command |
83
87
  | `rtk-output-filtering` | `src/skills/rtk-output-filtering/SKILL.md` | `rtk`, `verbose`, `filter`, `wrap` | Project-local rtk filters; wrapper command |
84
- | `token-efficiency` | `src/rules/token-efficiency.md` | `redirect`, `verbose`, `concise`, `tool` | Batch + parallelize tool calls; brevity floor |
88
+ | `token-efficiency` | `src/rules/token-efficiency.md` | `redirect`, `verbose`, `concise`, `tool`, `large file` | Batch + parallelize tool calls; brevity floor; size-gated reads (probe → grep → slice above 800 lines) |
85
89
  | `agent-handoff` | `src/domains/meta/agent-handoff/command.md` | `handoff`, `fresh`, `chat`, `context`, `resume`, `session` | Session picker + generated handoff auto-seeding the next session |
86
90
  | `direct-answers` | `src/rules/direct-answers.md` | `brevity`, `flattery`, `severity`, `tiered` | Iron-Law brevity floor (kernel) |
87
91
  | `markitdown` | upstream: github.com/microsoft/markitdown | `PDF`, `DOCX`, `HTML`, `convert` | Document → markdown converter (authoritative-link only) |
@@ -176,12 +176,6 @@ chat_history:
176
176
  # Logging granularity: per_turn | per_phase | per_tool
177
177
  frequency: per_phase
178
178
 
179
- # Max file size in KB before overflow handling kicks in
180
- max_size_kb: 256
181
-
182
- # Overflow behavior: rotate (drop oldest) | condense (summarize)
183
- on_overflow: rotate
184
-
185
179
  # --- Work-engine hooks ---
186
180
  #
187
181
  # Lifecycle hook surface of the `work_engine` Python engine
@@ -288,12 +282,6 @@ quality:
288
282
  # never claimed as passing.
289
283
  local_auto_run: false
290
284
 
291
- # Wait for remote CI to finish on the PR / pipeline (true, false)
292
- # true = poll GitHub check-runs / pipeline after push and report
293
- # green / red before handing back
294
- # false = push and hand back immediately (default)
295
- wait_for_remote_ci: false
296
-
297
285
  # --- Subagent orchestration ---
298
286
  subagents:
299
287
  # Model for implementer subagents (empty = same tier as the session model)
@@ -485,19 +473,18 @@ verbosity:
485
473
  # safe task per Phase 10.3.
486
474
  taskfile_command_echo: false
487
475
 
488
- # --- Telegraph speak (authoring-only) ---
476
+ # --- Telegraph condensation (output-side) ---
489
477
  #
490
- # Telegraph-style condensation scope for newly authored prose. The
491
- # compile-time toggle (`telegraph.speak`) is added in Phase 8.
492
- # `speak_scope` lands now so the charter and consumers can pin it.
478
+ # One lever, deliberately: whether the telegraph-speak rule ships at all.
479
+ # The rule body states its own grammar scope — which carve-outs (numbered
480
+ # options, Iron-Law literals, code, paths) stay full prose — so there is no
481
+ # separate scope key to pin.
493
482
  telegraph:
494
- # speak_scope = how widely telegraph-speak grammar applies in chat
495
- # off = no telegraph grammar in output (compile-time still
496
- # governed by telegraph.speak)
497
- # prose_only = telegraph in body prose; numbered options +
498
- # Iron-Law-literal blocks stay full prose
499
- # aggressive = telegraph everywhere except Iron-Law literals
500
- speak_scope: prose_only
483
+ # speak: false = DORMANT (the shipped default). The rule is omitted from
484
+ # dist/router.json entirely, so its body never reaches a host. That
485
+ # omission is what stops the cost. Set true only after an output-side
486
+ # bench clears the kill-criterion bar.
487
+ speak: false
501
488
 
502
489
  telemetry:
503
490
  artifact_engagement:
@@ -552,7 +539,7 @@ Personal and project-level settings (initial file written by
552
539
  **Key paths use dot-notation** to denote nesting: `personal.user_name`
553
540
  lives under `personal:` in YAML.
554
541
 
555
- The `verbosity.*` and `telegraph.speak_scope` rows are summarized below;
542
+ The `verbosity.*` rows are summarized below;
556
543
  the canonical narrative lives in
557
544
  [`docs/customization.md` § Verbosity](../../docs/customization.md#verbosity).
558
545
 
@@ -575,8 +562,6 @@ the canonical narrative lives in
575
562
  | `code_style.docblocks` | `minimal`, `full` | `minimal` | Consumed by the `code-comment-discipline` rule. `minimal`: no signature-mirroring docblocks; docblocks only for machine-relevant precision (generics, array shapes) or genuine why-context. `full`: exported public library surface may carry one-line summary docblocks; the redundancy ban still holds. |
576
563
  | `chat_history.enabled` | `true`, `false` | `true` | Persist chat events to `agents/runtime/.agent-chat-history` (JSONL) for crash recovery. |
577
564
  | `chat_history.frequency` | `per_turn`, `per_phase`, `per_tool` | per profile | Logging granularity. Defaults: `minimal`→`per_turn`, `balanced`→`per_phase`, `full`→`per_tool`. |
578
- | `chat_history.max_size_kb` | integer | per profile | Max file size before overflow handling. Defaults: `minimal`→`128`, `balanced`→`256`, `full`→`512`. |
579
- | `chat_history.on_overflow` | `rotate`, `condense` | per profile | On overflow: `rotate` drops oldest entries; `condense` marks the file for summarization on the next turn. Defaults: `minimal`/`balanced`→`rotate`, `full`→`condense`. |
580
565
  | `chat_history.text_limits.{user,agent,tool,phase}` | integer (chars) | `user=0`, `agent=5000`, `tool=200`, `phase=200` | Per-entry-type text-length cap. `0` = verbatim, no slice. `N > 0` = collapse whitespace, slice to N chars, append `" … [+K chars]"` so the log self-reports truncation. Defaults match `DEFAULT_TEXT_LIMITS` in `scripts/chat_history.ts`. |
581
566
  | `hooks.concern_budget.{max_per_event,tier1_concerns,hard_fail}` | integer / list / `true`,`false` | `8` / `[]` / `false` | Concern budget gate for the hook dispatcher (`lint_hook_concern_budget`): caps concerns per (platform, event) cell, restricts `fail_closed: true` to the `tier1_concerns` allowlist, and `hard_fail: false` keeps the gate warn-only. |
582
567
  | `hooks.injection_scan.enabled` | `true`, `false` | `false` | PostToolUse prompt-injection scanner: scans tool output for injection signatures and warns in context (exit 2) — never blocks. |
@@ -587,7 +572,6 @@ the canonical narrative lives in
587
572
  | `roadmap.skip_pre_run_gate` | `true`, `false` | `true` | When `true` (default): `/roadmap:process-step\|phase\|full` skips the interactive pre-run summary and starts the loop immediately — the resolved roadmap, cadence, and council are surfaced inline so an unwanted pick can still be aborted. When `false`: the loop shows the pre-run summary with numbered options (Go / Different roadmap / Different scope / Toggle council / Abort) and waits. The gate is always shown — regardless of this flag — when the roadmap is ambiguous (multiple active, none named) or a scope / cadence conflict has no sensible default. |
588
573
  | `roadmap.quality_cadence` | `end_of_roadmap`, `per_phase`, `per_step` | `end_of_roadmap` | When `/roadmap:process-step|phase|full` runs the project's quality pipeline — only relevant when `quality.local_auto_run` is `true`; when it is `false` (the default) local pipeline runs are suppressed at every cadence and remote CI is the gate. Default skips per-step / per-phase runs and gates only the final archival. `per_phase` runs once after every phase; `per_step` is the legacy verbose mode. Step checkboxes and the dashboard are always updated regardless. |
589
574
  | `quality.local_auto_run` | `true`, `false` | `false` | When `false` (default): agent NEVER runs the project's quality pipeline (`task ci`, `make test`, `npm run check`, PHPStan, ECS, Rector, test suites) proactively — and does not ask. The user runs quality tools manually; remote CI is the authoritative gate. The agent runs one only on (1) an explicit ask this turn, (2) a concrete CI failure (run exactly that failing check), or (3) the new-gate carve-out. When `true`: opt-in legacy — agent runs the pipeline autonomously when work is ready for verification. **Carve-out**: NEW CI gates / smoke tests / test files MUST run locally regardless of this flag — without execution the new gate is unverified evidence. Iron Law `verify-before-complete` still applies; suppressed runs are surfaced ("quality gates delegated to remote CI"), never claimed as passing. |
590
- | `quality.wait_for_remote_ci` | `true`, `false` | `false` | When `true`: after `git push`, the agent polls GitHub check-runs / pipeline status on the PR and reports green / red before handing back. When `false`: agent pushes and hands back immediately; the user inspects CI themselves (default — saves agent runtime and tokens). |
591
575
  | `subagents.implementer_model` | model alias or empty | _(empty)_ | Model for implementer subagents. Empty = same tier as session model. See [subagent-configuration](../contexts/subagent-configuration.md). |
592
576
  | `subagents.judge_model` | model alias or empty | _(empty)_ | Model for judge subagents. Empty = one tier above implementer (opus if sonnet, sonnet if haiku). |
593
577
  | `subagents.max_parallel` | integer | `3` | Maximum parallel subagent invocations. `1` serializes. |
@@ -613,7 +597,7 @@ the canonical narrative lives in
613
597
  | `verbosity.offer_council_in_delivery` | `true`, `false` | `false` | Offer "run AI Council on this?" inside delivery commands (`/feature-plan`, `/review-changes`, `/roadmap-create`). Council commands themselves are unaffected. |
614
598
  | `verbosity.post_action_reports` | `off`, `minimal`, `full` | `minimal` | Multi-line status / summary blocks after a successful action. `off` = no report; `minimal` = one-line confirmation; `full` = bullet list. |
615
599
  | `verbosity.intent_announcements` | `true`, `false` | `false` | Intent announcements ("Let me check…", "Now I will…", "Found it") in skill bodies. `false` = act and emit the result. |
616
- | `telegraph.speak_scope` | `off`, `prose_only`, `aggressive` | `off` | How widely telegraph-speak grammar applies in chat. `off` = no telegraph grammar; `prose_only` = telegraph in body prose, numbered options + Iron-Law-literal blocks stay full prose; `aggressive` = telegraph everywhere except Iron-Law literals. The compile-time toggle `telegraph.speak` ships as `false` (dormant) — the projector gates the rule on `speak`, never on `speak_scope`. |
600
+ | `telegraph.speak` | `true`, `false` | `false` | Whether the telegraph-speak rule ships at all. `false` (default) = dormant: the projector omits the rule from `dist/router.json`, so its body never reaches a host. The rule body states its own grammar scope and carve-outs (numbered options, Iron-Law literals, code, paths), so this is the only lever. |
617
601
  | `telemetry.artifact_engagement.enabled` | `true`, `false` | `false` | Master switch for the artefact engagement log. Not in the shipped template — a missing `telemetry:` section means disabled (the recording rule no-ops). Default-off; zero file IO and zero token cost when `false`. Maintainer-targeted; consumers leave it off. |
618
602
  | `telemetry.artifact_engagement.granularity` | `task`, `phase-step`, `tool-call` | `task` | Boundary at which events are recorded. `tool-call` is expensive — opt-in only. |
619
603
  | `telemetry.artifact_engagement.record.consulted` | `true`, `false` | `true` | When `true`: record artefacts loaded into context. |
@@ -8,7 +8,7 @@
8
8
  # 1. Package defaults (shipped by event4u/agent-config)
9
9
  # 2. ~/.event4u/agent-config/agent-settings.yml — user-global DX-comfort
10
10
  # defaults (whitelist: name, ide, rule_loading_tier, personal.bot_icon,
11
- # personal.autonomy, telegraph.speak_scope). Created on opt-in via
11
+ # personal.autonomy, memory.cadence). Created on opt-in via
12
12
  # /onboard; project-local files always win. Legacy
13
13
  # ~/.config/agent-config/agent-settings.yml is read as a fallback.
14
14
  # 3. This file (.agent-project-settings.yml) — team defaults
@@ -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.ts (road-to-
41
41
  # portable-runtime-and-update-check P3.3).
42
- agent_config_version: "10.1.0"
42
+ agent_config_version: "10.3.0"
43
43
 
44
44
  # --- Project identity ---
45
45
  project:
@@ -38,6 +38,32 @@ source: package
38
38
  - mode optional — advisory link to a role-contracts workflow mode
39
39
  - version required — semantic version; bump on breaking changes
40
40
  - source required — "package" for personas shipped in dist/agent-src/
41
+ - sources optional — harvest_id list this persona may cite as external
42
+ doctrine (provenance/harvests.jsonl). OMIT IT unless you mean
43
+ one of the two scoped states; absent is the normal case and
44
+ the one every existing persona is in.
45
+ -->
46
+
47
+ <!-- SOURCES — an epistemic scope, not a bibliography.
48
+
49
+ A persona declares a voice. `sources:` optionally declares what that voice is
50
+ allowed to assert as *external doctrine* — as opposed to its own reasoning,
51
+ which needs no declaration and is never restricted.
52
+
53
+ | State | Meaning |
54
+ |---|---|
55
+ | field absent | Unscoped. Today's behaviour for every persona; nothing changes. |
56
+ | `sources: []` | Explicitly asserts nothing harvested — its positions are its own. |
57
+ | `sources: [id, …]` | May cite those harvest ids as doctrine. |
58
+
59
+ Every declared id must resolve to a row in `provenance/harvests.jsonl`;
60
+ `lint_harvest_provenance` fails an id that does not. Do NOT invent a row to
61
+ populate the field — an empty ledger and an absent field is the correct
62
+ resting state, and `[]` is for a persona where the distinction is worth
63
+ stating out loud.
64
+
65
+ This does not touch the Unique-Questions heuristic. A scoped persona still
66
+ earns its place by asking what nobody else asks.
41
67
  -->
42
68
 
43
69
  # {Role name}
@@ -197,9 +197,22 @@ Templates for roadmap files stored in `agents/roadmaps/` or `{module_root}/{Modu
197
197
  "user approves", "looks good", or "sign-off".
198
198
  - A **human gate** is allowed only when only a human can **decide or
199
199
  authorize**: a Hard-Floor action (deploy, prod data/infra),
200
- billable spend, or a contested product / architecture decision.
201
- Record it as a structured `## Blockers` entry (rule 20) — never as
202
- an inline checkbox step scattered through phases.
200
+ billable spend, or a decision bound to the user's own preference,
201
+ risk appetite, or product intent.
202
+ - A **contested technical decision is not a human gate while a
203
+ council is configured.** Which design is sound, whether a contract
204
+ still holds, which of N implementations to pick — these have
205
+ technical answers, and `decision_resolution` already classes a
206
+ contract or architecture change as `medium_impact → council`
207
+ (`docs/contracts/ai-council-config.md`). Authoring them as human
208
+ gates contradicts that classification and spends the user's
209
+ attention on a question the council answers. Run it, record the
210
+ verdict in the phase, and the gate becomes a step.
211
+ `agent-config council:status` says whether one is configured —
212
+ never infer it from the project tree (`council-availability`).
213
+ Record a genuine gate as a structured `## Blockers` entry
214
+ (rule 20) — never as an inline checkbox step scattered through
215
+ phases.
203
216
  - An **external dependency is a blocker, not a human gate**, whenever
204
217
  the agent can probe its status (CI run finished, package version
205
218
  published, upstream PR merged, API reachable, DNS propagated):
@@ -216,10 +229,17 @@ Templates for roadmap files stored in `agents/roadmaps/` or `{module_root}/{Modu
216
229
  `security-sensitive-stop`, and `commit-policy` fire at run time on
217
230
  their own; an authored "STOP: confirm with user before X" duplicates
218
231
  them and only adds interruptions.
219
- Gate-test before writing any checkpoint: *"Could the agent clear this
220
- with a tool or command during the run?"* Yes → it is a step, not a
221
- gate. No → structured blocker with a decidable `Resolved when:`,
222
- owned by a human only when the blocker is a genuine human gate.
232
+ Gate-test before writing any checkpoint, asked in this order:
233
+ 1. *"Could the agent clear this with a tool or command during the
234
+ run?"* Yes → it is a step, not a gate.
235
+ 2. *"Does it have a technical answer a council could reach?"* Yes →
236
+ it is a step whose first action runs the council.
237
+ 3. Only what survives both — preference, risk appetite, product
238
+ intent, authorization, spend — becomes a structured blocker with
239
+ a decidable `Resolved when:`, owned by a human.
240
+ Stopping at question 1 is the authoring bug this ordering exists to
241
+ prevent: it sends every decision the agent cannot compute straight to
242
+ the user, including the ones the council exists to answer.
223
243
  `task lint-roadmap-complexity` warns on human-gate step patterns,
224
244
  human-gate phase headings, and human-approval exit criteria.
225
245
 
@@ -210,7 +210,6 @@ export const MERGEABLE_KEYS: readonly string[] = [
210
210
  'memory.cadence',
211
211
  'personal.bot_icon',
212
212
  'personal.autonomy',
213
- 'telegraph.speak_scope',
214
213
  // Knowledge-card global cross-project sharing is a USER-GLOBAL setting
215
214
  // (ADR-100 / road-to-structure-grounding-v2). Whitelisted so the
216
215
  // ~/.event4u/agent-config/agent-settings.yml values are honoured.
@@ -207,8 +207,42 @@ Before considering a skill complete, verify it passes all 5 checks:
207
207
  - [ ] **K3: No obvious content** — doesn't teach the model what it already knows; only project-specific conventions and non-obvious patterns
208
208
  - [ ] **K4: Has Gotcha section** — documents real failure patterns, not theoretical advice; seeded with 2-3 entries
209
209
  - [ ] **K5: Has Output format** — numbered list with 2-4 deliverables describing what the skill produces
210
- - [ ] **K6: Under 400 lines** — if larger, extract reference tables or templates into separate files in the skill folder
210
+ - [ ] **K6: Under 400 lines** — if larger, restructure as a router head per the contract below (gate: `lint_skill_router_head`)
211
211
  - [ ] **English only** — all content in English
212
212
  - [ ] **No duplication** — doesn't repeat rules or guidelines that are already enforced elsewhere
213
213
  - [ ] **No "Related skills" section for mid-tier / untiered skills** — the agent discovers them via `<available_skills>` descriptions; cross-links waste tokens. Senior-tier skills (`tier: senior`) MUST include the block per `skill-quality.md` § Senior-Tier Required Structure (linter-enforced).
214
214
 
215
+ ## The router-head contract (K6, over the cap)
216
+
217
+ A `SKILL.md` over the 400-line cap restructures instead of growing. The shape:
218
+
219
+ | Part | Holds | Budget |
220
+ |---|---|---|
221
+ | **Entry head** — `SKILL.md` | When-to-use · a mode table · the routing that picks a mode · anything true across *all* modes | the cap |
222
+ | **Mode bodies** — `tasks/*.md` or `references/*.md` in the skill folder | One file per mode: the procedure, its examples, its tables | unbudgeted |
223
+
224
+ One binding constraint on the head: **it never inlines the procedure body for
225
+ more than one mode.** A head that carries mode A in full and points at modes
226
+ B and C has not been restructured — it has been relabelled, and the next edit
227
+ will grow it back.
228
+
229
+ ### What this contract does NOT claim
230
+
231
+ It does not claim a token win. The host loads `SKILL.md` whole on trigger, and
232
+ whether it then follows a pointer into `tasks/` is host behaviour **nothing in
233
+ this tree observes**. Anyone proposing a retrofit of an existing oversized skill
234
+ on activation grounds is asserting something currently unmeasurable, and
235
+ ADR-202's lesson binds: an activation claim goes behind a measured instrument or
236
+ it is not made.
237
+
238
+ What the contract does is narrower and real: the 400-line cap was already this
239
+ repo's published position, sitting in a checklist nothing enforced. The gate
240
+ makes an existing contract true for **new** skills. Restructuring the current
241
+ offenders is a separate decision with its own evidence bar.
242
+
243
+ ### Grandfathering
244
+
245
+ `lint_skill_router_head` carries a shrink-only allowlist seeded with the skills
246
+ that already exceed the cap. Entries may be removed, never added — a new
247
+ oversized monolith fails the gate rather than joining the list.
248
+
@@ -0,0 +1,257 @@
1
+ /**
2
+ * `commands ls --candidates` — the surface-reduction report of roadmap step 3.4
3
+ * (`road-to-inbox-harvest-2026-08-b-release-integrity`).
4
+ *
5
+ * Every assertion derives its expectation from the synthetic input rather than
6
+ * pinning a literal the implementation happens to emit, so the suite cannot go
7
+ * green for the wrong reason. The report is deliberately built from the
8
+ * discovery manifest ALONE — no census file, no `utilization_report` import —
9
+ * and the tests pin exactly that: the honesty band must survive, and the
10
+ * ownership pointers must not be dropped by a later edit.
11
+ */
12
+ import { describe, expect, it } from 'vitest';
13
+ import { buildCandidatesReport, renderCandidates, runCommandsLs, CANDIDATES_INCOMPATIBLE, REDUCTION_OWNERS, REPORT_ONLY_NOTICE, TEXT_LIST_CAP, } from './commands.js';
14
+ function cmd(slug, pack, extra = {}) {
15
+ return {
16
+ path: `src/domains/${pack}/${slug}/command.md`,
17
+ category: 'command',
18
+ name: slug,
19
+ slug,
20
+ pack,
21
+ tier: 2,
22
+ workspaces: [],
23
+ packs: [pack],
24
+ lifecycle: 'stable',
25
+ trust: { level: 'core', confidence: 'high', human_review_required: false },
26
+ install: { default: true, removable: false },
27
+ intent: `do ${slug}`,
28
+ ...extra,
29
+ };
30
+ }
31
+ /** An artefact with NO `intent` key at all — distinct from `intent: ''`, and the
32
+ * shape `exactOptionalPropertyTypes` forces us to build by omission. */
33
+ function cmdWithoutIntent(slug, pack, visibility) {
34
+ const { intent: _omitted, ...rest } = cmd(slug, pack, { visibility });
35
+ return rest;
36
+ }
37
+ /** Mixed fixture: two absorbed-name commands, two undocumented, three packs of
38
+ * unequal weight. */
39
+ const FIXTURE = [
40
+ cmd('alpha', 'engineering-base', { visibility: 'visible' }),
41
+ cmd('bravo', 'engineering-base', { visibility: 'advanced' }),
42
+ cmd('charlie', 'engineering-base', { visibility: 'internal', intent: '' }),
43
+ cmd('delta', 'frontend-design', { visibility: 'visible', replaces: ['old-delta'] }),
44
+ cmd('echo', 'frontend-design', { visibility: 'internal', replaces: ['old-echo', 'older-echo'] }),
45
+ cmdWithoutIntent('foxtrot', 'finance-basic', 'advanced'),
46
+ ];
47
+ describe('buildCandidatesReport', () => {
48
+ const report = buildCandidatesReport(FIXTURE);
49
+ it('counts the whole estate it was given', () => {
50
+ expect(report.total).toBe(FIXTURE.length);
51
+ });
52
+ it('partitions visibility exhaustively — the buckets sum to the total', () => {
53
+ const summed = Object.values(report.byVisibility).reduce((a, b) => a + b, 0);
54
+ expect(summed).toBe(FIXTURE.length);
55
+ });
56
+ it('collects the commands that ABSORBED prior names, named explicitly', () => {
57
+ // Named rather than recomputed from the implementation predicate: the
58
+ // first version of this bucket inverted the field's meaning, and a test
59
+ // that re-derives `(replaces ?? []).length > 0` certifies whatever the
60
+ // code does — including the inversion.
61
+ expect(report.absorbedNames.map((r) => r.slug)).toEqual(['delta', 'echo']);
62
+ expect(report.absorbedNames.map((r) => r.slug)).not.toContain('alpha');
63
+ });
64
+ it('carries each absorbed-name list through unchanged', () => {
65
+ for (const row of report.absorbedNames) {
66
+ const source = FIXTURE.find((c) => c.slug === row.slug);
67
+ expect(row.replaces).toEqual(source?.replaces ?? []);
68
+ }
69
+ });
70
+ it('treats an empty-string intent as undocumented, not as documented', () => {
71
+ const expected = FIXTURE
72
+ .filter((c) => (c.intent ?? '').trim() === '')
73
+ .map((c) => c.slug)
74
+ .sort();
75
+ expect(report.noIntent.map((r) => r.slug)).toEqual(expected);
76
+ // Guard the boundary the implementation could get wrong in either
77
+ // direction: '' and undefined both count, a real string never does.
78
+ expect(expected).toContain('charlie');
79
+ expect(expected).toContain('foxtrot');
80
+ expect(expected).not.toContain('alpha');
81
+ });
82
+ it('orders packs by weight descending', () => {
83
+ const counts = report.byPack.map(([, n]) => n);
84
+ expect([...counts]).toEqual([...counts].sort((a, b) => b - a));
85
+ const summed = counts.reduce((a, b) => a + b, 0);
86
+ expect(summed).toBe(FIXTURE.length);
87
+ });
88
+ it('breaks a pack tie by name — exercised on an actual tie', () => {
89
+ // The mixed fixture has counts 3/2/1 and never hits the tie-break, so
90
+ // the previous version of this test asserted a branch it never reached.
91
+ const tied = buildCandidatesReport([
92
+ cmd('one', 'zulu'),
93
+ cmd('two', 'alpha'),
94
+ ]);
95
+ expect(tied.byPack.map(([p]) => p)).toEqual(['alpha', 'zulu']);
96
+ });
97
+ it('is byte-stable across input permutations — the report is a set view', () => {
98
+ const shuffled = [...FIXTURE].reverse();
99
+ expect(renderCandidates(buildCandidatesReport(shuffled)))
100
+ .toBe(renderCandidates(buildCandidatesReport(FIXTURE)));
101
+ });
102
+ });
103
+ describe('buildCandidatesReport — empty estate', () => {
104
+ it('reports a measured zero rather than throwing or omitting sections', () => {
105
+ const empty = buildCandidatesReport([]);
106
+ expect(empty.total).toBe(0);
107
+ expect(empty.absorbedNames).toEqual([]);
108
+ expect(empty.noIntent).toEqual([]);
109
+ expect(empty.byPack).toEqual([]);
110
+ const text = renderCandidates(empty);
111
+ // An absent section would let a real zero read as a missing check.
112
+ expect(text).toContain('measured zero');
113
+ });
114
+ });
115
+ describe('renderCandidates — the honesty band', () => {
116
+ const text = renderCandidates(buildCandidatesReport(FIXTURE));
117
+ it('states up front that it decides nothing', () => {
118
+ expect(text.split('\n')[0]).toMatch(/report-only/i);
119
+ });
120
+ it('names the usage-evidence owner it deliberately does not import', () => {
121
+ expect(text).toContain('utilization_report');
122
+ });
123
+ it('warns that both census snapshots are dated, not current', () => {
124
+ expect(text).toContain('docs/SKILL_CENSUS.md');
125
+ expect(text).toContain('docs/artefact-census.md');
126
+ expect(text).toMatch(/point-in-time|do not\s+read their numbers as current/i);
127
+ });
128
+ it('hands the reduction targets to their owning roadmaps, all of them', () => {
129
+ for (const owner of REDUCTION_OWNERS)
130
+ expect(text).toContain(owner);
131
+ expect(REDUCTION_OWNERS.length).toBeGreaterThan(0);
132
+ });
133
+ it('never presents itself as a prune instruction', () => {
134
+ // Assert the exported contract, not a hand-copied sentence — a reworded
135
+ // disclaimer stays covered, a DELETED one fails.
136
+ expect(text).toContain(REPORT_ONLY_NOTICE);
137
+ });
138
+ it('states that the absorbed-name bucket is NOT a retirement class', () => {
139
+ // The defect this pins: the bucket was first labelled "deprecation
140
+ // shims", i.e. the exact inverse of what `replaces` means.
141
+ expect(text).not.toMatch(/deprecation shims +\d/);
142
+ expect(text).toMatch(/NOT a retirement class/);
143
+ expect(text).toContain('absorbed prior names');
144
+ });
145
+ it('reports the real shim class as not computable, with its canonical figure', () => {
146
+ expect(text).toMatch(/deprecation shims\s+not computable/);
147
+ expect(text).toContain('superseded_by');
148
+ expect(text).toContain('0 shims of 196');
149
+ });
150
+ it('renders every absorbed-name row it counted, with its absorbed ids', () => {
151
+ const report = buildCandidatesReport(FIXTURE);
152
+ for (const row of report.absorbedNames) {
153
+ expect(text).toContain(row.slug);
154
+ for (const prior of row.replaces)
155
+ expect(text).toContain(prior);
156
+ }
157
+ });
158
+ });
159
+ describe('runCommandsLs — --candidates refuses the narrowing flags', () => {
160
+ // Regression: each of these silently produced a whole-estate report, and a
161
+ // typo'd --profile exited 0 where plain `ls` exits 1.
162
+ for (const flag of CANDIDATES_INCOMPATIBLE) {
163
+ it(`exits 1 when combined with ${flag}`, () => {
164
+ const opts = { candidates: true };
165
+ if (flag === '--pack')
166
+ opts['pack'] = 'git';
167
+ if (flag === '--visible')
168
+ opts['visible'] = true;
169
+ if (flag === '--profile')
170
+ opts['profile'] = 'bogus';
171
+ if (flag === '--expanded')
172
+ opts['expanded'] = true;
173
+ expect(runCommandsLs(opts)).toBe(1);
174
+ });
175
+ }
176
+ });
177
+ describe('renderCandidates — an unrecognised visibility value cannot vanish', () => {
178
+ // `visibility` is a free string in the manifest (ADR-092 named the field,
179
+ // nothing pins its domain). Rendering only the three known labels made the
180
+ // printed breakdown silently disagree with the total — the exact false-green
181
+ // shape a report must not have.
182
+ const withUnknown = [
183
+ cmd('known', 'engineering-base', { visibility: 'visible' }),
184
+ cmd('odd-one', 'engineering-base', { visibility: 'experimental' }),
185
+ cmd('odd-two', 'engineering-base', { visibility: 'experimental' }),
186
+ ];
187
+ const report = buildCandidatesReport(withUnknown);
188
+ const text = renderCandidates(report);
189
+ it('counts the unrecognised value rather than dropping it', () => {
190
+ expect(report.byVisibility['experimental']).toBe(2);
191
+ const summed = Object.values(report.byVisibility).reduce((a, b) => a + b, 0);
192
+ expect(summed).toBe(withUnknown.length);
193
+ });
194
+ it('renders it, so the printed breakdown sums to the printed total', () => {
195
+ expect(text).toContain('experimental');
196
+ // Sum only the visibility block: the run of bucket lines directly
197
+ // following the `surface` line. (A wider filter also matched the
198
+ // owning-packs block, which is why the earlier version of this test
199
+ // carried a variable that did not hold what its name claimed.)
200
+ const rows = text.split('\n');
201
+ const start = rows.findIndex((l) => l.startsWith('surface '));
202
+ const block = [];
203
+ for (const line of rows.slice(start + 1)) {
204
+ const m = line.match(/^ {2}(\S+) +(\d+)$/);
205
+ if (!m)
206
+ break;
207
+ block.push(Number(m[2]));
208
+ }
209
+ expect(block).toHaveLength(4);
210
+ expect(block.reduce((a, b) => a + b, 0)).toBe(report.total);
211
+ });
212
+ it('keeps the JSON record key order deterministic too, not just the render', () => {
213
+ // The fix first sorted unknowns in the renderer only, leaving the record
214
+ // a --json consumer reads in first-seen order.
215
+ const forward = buildCandidatesReport([
216
+ cmd('a', 'p', { visibility: 'zeta' }),
217
+ cmd('b', 'p', { visibility: 'alpha' }),
218
+ ]);
219
+ const reversed = buildCandidatesReport([
220
+ cmd('b', 'p', { visibility: 'alpha' }),
221
+ cmd('a', 'p', { visibility: 'zeta' }),
222
+ ]);
223
+ expect(Object.keys(forward.byVisibility)).toEqual(Object.keys(reversed.byVisibility));
224
+ expect(Object.keys(forward.byVisibility).slice(-2)).toEqual(['alpha', 'zeta']);
225
+ });
226
+ it('keeps the known labels ahead of the unrecognised one, for byte stability', () => {
227
+ const order = [...text.matchAll(/^ {2}(visible|advanced|internal|experimental) +\d+$/gm)]
228
+ .map((m) => m[1]);
229
+ expect(order[order.length - 1]).toBe('experimental');
230
+ });
231
+ });
232
+ describe('renderCandidates — the text-mode cap is named, never silent', () => {
233
+ /** One more undocumented command than the cap allows, so truncation bites. */
234
+ const over = Array.from({ length: TEXT_LIST_CAP + 3 }, (_unused, i) => cmd(`undoc-${String(i).padStart(3, '0')}`, 'engineering-base', { intent: '' }));
235
+ const report = buildCandidatesReport(over);
236
+ const text = renderCandidates(report);
237
+ it('keeps the COUNT honest even though the list is truncated', () => {
238
+ expect(report.noIntent.length).toBe(over.length);
239
+ expect(text).toContain(`no stated intent ${over.length}`);
240
+ });
241
+ it('states how many rows it withheld, derived from the input', () => {
242
+ expect(text).toContain(`… and ${over.length - TEXT_LIST_CAP} more`);
243
+ });
244
+ it('caps the enumeration at exactly TEXT_LIST_CAP rows', () => {
245
+ const listed = over.filter((c) => text.includes(` ${c.slug} (`)).length;
246
+ expect(listed).toBe(TEXT_LIST_CAP);
247
+ });
248
+ it('never caps the structured payload', () => {
249
+ // --json consumers get the whole set; the cap is a text-mode concern.
250
+ expect(report.noIntent).toHaveLength(over.length);
251
+ });
252
+ it('adds no truncation notice when the set fits', () => {
253
+ const fits = renderCandidates(buildCandidatesReport(over.slice(0, TEXT_LIST_CAP)));
254
+ expect(fits).not.toContain('more — the full set is in --json');
255
+ });
256
+ });
257
+ //# sourceMappingURL=commands.candidates.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commands.candidates.test.js","sourceRoot":"","sources":["../../../src/cli/commands/commands.candidates.test.ts"],"names":[],"mappings":"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"}