@event4u/agent-config 7.5.0 → 8.0.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 (428) hide show
  1. package/.claude-plugin/marketplace.json +8 -1
  2. package/AGENTS.md +9 -9
  3. package/CHANGELOG.md +325 -0
  4. package/README.md +35 -5
  5. package/dist/agent-src/commands/analytics/prune.md +1 -1
  6. package/dist/agent-src/commands/analytics/show.md +1 -1
  7. package/dist/agent-src/commands/analyze/decision.md +2 -2
  8. package/dist/agent-src/commands/analyze/incident.md +2 -2
  9. package/dist/agent-src/commands/analyze/near-miss.md +2 -2
  10. package/dist/agent-src/commands/analyze/postmortem.md +2 -2
  11. package/dist/agent-src/commands/analyze/premortem.md +2 -2
  12. package/dist/agent-src/commands/cost-report.md +25 -0
  13. package/dist/agent-src/commands/evals/analyze.json +30 -0
  14. package/dist/agent-src/commands/evals/mission-upgrade.json +30 -0
  15. package/dist/agent-src/commands/implement-ticket.md +1 -1
  16. package/dist/agent-src/commands/knowledge/forget.md +1 -1
  17. package/dist/agent-src/commands/knowledge/ingest.md +1 -1
  18. package/dist/agent-src/commands/knowledge/list.md +1 -1
  19. package/dist/agent-src/commands/memory/load.md +12 -11
  20. package/dist/agent-src/commands/memory/promote.md +30 -0
  21. package/dist/agent-src/commands/memory/propose.md +16 -2
  22. package/dist/agent-src/commands/mission/upgrade.md +1 -1
  23. package/dist/agent-src/commands/module/explore.md +11 -7
  24. package/dist/agent-src/commands/optimize-project.md +243 -0
  25. package/dist/agent-src/commands/optimize.md +5 -0
  26. package/dist/agent-src/commands/pr/create.md +37 -8
  27. package/dist/agent-src/commands/prediction-pool.md +2 -2
  28. package/dist/agent-src/commands/profile/activate.md +3 -3
  29. package/dist/agent-src/commands/profile/deactivate.md +2 -2
  30. package/dist/agent-src/commands/profile/show.md +3 -3
  31. package/dist/agent-src/commands/research/deep.md +5 -0
  32. package/dist/agent-src/commands/research/report.md +2 -1
  33. package/dist/agent-src/commands/roadmap/create.md +88 -10
  34. package/dist/agent-src/commands/roadmap/materialize.md +1 -1
  35. package/dist/agent-src/commands/roadmap/process-full.md +15 -2
  36. package/dist/agent-src/commands/roadmap/process-phase.md +18 -6
  37. package/dist/agent-src/commands/roadmap/process-step.md +4 -0
  38. package/dist/agent-src/commands/roadmap.md +1 -1
  39. package/dist/agent-src/commands/security-audit-config.md +1 -1
  40. package/dist/agent-src/commands/sync-agent-settings.md +1 -1
  41. package/dist/agent-src/commands/sync-gitignore/fix.md +42 -6
  42. package/dist/agent-src/commands/team-knowledge/bootstrap.md +106 -0
  43. package/dist/agent-src/commands/team-knowledge/consolidate.md +105 -0
  44. package/dist/agent-src/commands/team-knowledge.md +64 -0
  45. package/dist/agent-src/contexts/authority/commit-mechanics.md +8 -0
  46. package/dist/agent-src/contexts/authority/destructive-mechanics.md +11 -0
  47. package/dist/agent-src/contexts/authority/scope-mechanics.md +25 -0
  48. package/dist/agent-src/contexts/communication/rules-auto/reply-close-mechanics.md +43 -0
  49. package/dist/agent-src/contexts/contracts/agents-md-anatomy.md +1 -1
  50. package/dist/agent-src/contexts/contracts/artifact-engagement-flow.md +2 -2
  51. package/dist/agent-src/contexts/contracts/frugality-charter.md +1 -0
  52. package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +14 -4
  53. package/dist/agent-src/contexts/execution/autonomy-mechanics.md +11 -0
  54. package/dist/agent-src/contexts/execution/orchestration-telemetry.md +32 -8
  55. package/dist/agent-src/contexts/execution/roadmap-execution-contract.md +107 -0
  56. package/dist/agent-src/contexts/execution/roadmap-process-loop.md +71 -15
  57. package/dist/agent-src/contexts/execution/subagent-steering.md +41 -1
  58. package/dist/agent-src/contexts/override-system.md +1 -1
  59. package/dist/agent-src/personas/brand-strategist.md +0 -1
  60. package/dist/agent-src/personas/data-integrity.md +66 -0
  61. package/dist/agent-src/personas/design-director.md +0 -1
  62. package/dist/agent-src/personas/performance-engineer.md +66 -0
  63. package/dist/agent-src/personas/production-validator.md +73 -0
  64. package/dist/agent-src/rules/agent-authority.md +3 -4
  65. package/dist/agent-src/rules/analysis-skill-routing.md +3 -5
  66. package/dist/agent-src/rules/architecture.md +2 -4
  67. package/dist/agent-src/rules/artifact-drafting-protocol.md +35 -6
  68. package/dist/agent-src/rules/artifact-engagement-recording.md +2 -4
  69. package/dist/agent-src/rules/ask-when-uncertain.md +10 -14
  70. package/dist/agent-src/rules/augment-edit-discipline.md +3 -5
  71. package/dist/agent-src/rules/autonomous-execution.md +3 -5
  72. package/dist/agent-src/rules/brand-consistency.md +3 -5
  73. package/dist/agent-src/rules/brand-source-of-truth.md +3 -5
  74. package/dist/agent-src/rules/cli-output-handling.md +4 -6
  75. package/dist/agent-src/rules/command-suggestion-policy.md +3 -5
  76. package/dist/agent-src/rules/commit-conventions.md +3 -5
  77. package/dist/agent-src/rules/commit-policy.md +8 -10
  78. package/dist/agent-src/rules/content-quoting-floor.md +88 -0
  79. package/dist/agent-src/rules/context-hygiene.md +3 -5
  80. package/dist/agent-src/rules/copilot-routing.md +4 -6
  81. package/dist/agent-src/rules/decision-revisit-gate.md +120 -0
  82. package/dist/agent-src/rules/delegation-policy.md +10 -6
  83. package/dist/agent-src/rules/design-fidelity.md +3 -5
  84. package/dist/agent-src/rules/devcontainer-routing.md +4 -6
  85. package/dist/agent-src/rules/direct-answers.md +13 -17
  86. package/dist/agent-src/rules/docker-commands.md +3 -5
  87. package/dist/agent-src/rules/domain-adoption-policy.md +3 -5
  88. package/dist/agent-src/rules/domain-safety-disclaimer.md +3 -5
  89. package/dist/agent-src/rules/domain-safety-pii.md +3 -5
  90. package/dist/agent-src/rules/domain-safety-retention.md +3 -5
  91. package/dist/agent-src/rules/downstream-changes.md +3 -4
  92. package/dist/agent-src/rules/engineering-safety-floor.md +3 -5
  93. package/dist/agent-src/rules/external-reference-deep-dive.md +3 -5
  94. package/dist/agent-src/rules/fast-path-marker-visibility.md +3 -5
  95. package/dist/agent-src/rules/finance-safety-floor.md +3 -6
  96. package/dist/agent-src/rules/framework-neutrality-in-generic-skills.md +3 -5
  97. package/dist/agent-src/rules/git-history-discipline.md +3 -5
  98. package/dist/agent-src/rules/guidelines.md +2 -4
  99. package/dist/agent-src/rules/icon-consistency.md +3 -5
  100. package/dist/agent-src/rules/image-likeness-and-rights.md +3 -5
  101. package/dist/agent-src/rules/improve-before-implement.md +5 -5
  102. package/dist/agent-src/rules/invite-challenge.md +3 -5
  103. package/dist/agent-src/rules/language-and-tone.md +13 -15
  104. package/dist/agent-src/rules/laravel-routing.md +3 -5
  105. package/dist/agent-src/rules/laravel-translations.md +3 -5
  106. package/dist/agent-src/rules/legal-safety-floor.md +3 -5
  107. package/dist/agent-src/rules/lethal-trifecta-guard.md +3 -5
  108. package/dist/agent-src/rules/linked-projects-onboarding-gate.md +4 -7
  109. package/dist/agent-src/rules/low-impact-corpus-privacy-floor.md +3 -5
  110. package/dist/agent-src/rules/markdown-safe-codeblocks.md +2 -4
  111. package/dist/agent-src/rules/media-governance-routing.md +3 -5
  112. package/dist/agent-src/rules/media-sync-ground-truth.md +3 -5
  113. package/dist/agent-src/rules/minimal-safe-diff.md +5 -5
  114. package/dist/agent-src/rules/missing-tool-handling.md +3 -5
  115. package/dist/agent-src/rules/model-recommendation.md +4 -6
  116. package/dist/agent-src/rules/no-attribution-footers.md +3 -5
  117. package/dist/agent-src/rules/no-cheap-questions.md +5 -8
  118. package/dist/agent-src/rules/no-decorative-emojis-in-git-surfaces.md +3 -6
  119. package/dist/agent-src/rules/no-pr-progress-comments.md +3 -6
  120. package/dist/agent-src/rules/no-roadmap-references.md +3 -5
  121. package/dist/agent-src/rules/non-destructive-by-default.md +11 -13
  122. package/dist/agent-src/rules/notes-first-reasoning.md +3 -5
  123. package/dist/agent-src/rules/onboarding-gate.md +4 -6
  124. package/dist/agent-src/rules/output-discipline.md +3 -5
  125. package/dist/agent-src/rules/package-ci-checks.md +3 -5
  126. package/dist/agent-src/rules/persona-governance.md +2 -4
  127. package/dist/agent-src/rules/php-coding.md +3 -5
  128. package/dist/agent-src/rules/preservation-guard.md +2 -4
  129. package/dist/agent-src/rules/provider-lifecycle-discipline.md +3 -5
  130. package/dist/agent-src/rules/reviewer-awareness.md +5 -6
  131. package/dist/agent-src/rules/roadmap-ci-steps-policy.md +3 -5
  132. package/dist/agent-src/rules/roadmap-progress-sync.md +5 -5
  133. package/dist/agent-src/rules/role-mode-adherence.md +2 -4
  134. package/dist/agent-src/rules/rule-type-governance.md +3 -5
  135. package/dist/agent-src/rules/runtime-safety.md +2 -4
  136. package/dist/agent-src/rules/scope-control.md +10 -11
  137. package/dist/agent-src/rules/security-sensitive-stop.md +4 -5
  138. package/dist/agent-src/rules/size-enforcement.md +2 -4
  139. package/dist/agent-src/rules/skill-improvement-trigger.md +3 -5
  140. package/dist/agent-src/rules/skill-quality.md +3 -5
  141. package/dist/agent-src/rules/slash-command-routing-policy.md +3 -5
  142. package/dist/agent-src/rules/source-confidentiality.md +3 -5
  143. package/dist/agent-src/rules/source-discovery-gate.md +3 -5
  144. package/dist/agent-src/rules/source-of-truth.md +3 -5
  145. package/dist/agent-src/rules/strategy-safety-floor.md +3 -5
  146. package/dist/agent-src/rules/symfony-routing.md +4 -6
  147. package/dist/agent-src/rules/telegraph-speak.md +4 -5
  148. package/dist/agent-src/rules/think-before-action.md +7 -4
  149. package/dist/agent-src/rules/token-budget-discipline.md +29 -5
  150. package/dist/agent-src/rules/token-efficiency.md +3 -5
  151. package/dist/agent-src/rules/token-optimizer-maintenance.md +3 -5
  152. package/dist/agent-src/rules/tool-safety.md +2 -4
  153. package/dist/agent-src/rules/ui-audit-gate.md +3 -6
  154. package/dist/agent-src/rules/untrusted-input-defense.md +3 -5
  155. package/dist/agent-src/rules/upstream-proposal.md +4 -6
  156. package/dist/agent-src/rules/user-interaction.md +7 -5
  157. package/dist/agent-src/rules/user-interrupt-priority.md +17 -8
  158. package/dist/agent-src/rules/verify-before-complete.md +12 -22
  159. package/dist/agent-src/scripts/archive_completed_roadmaps.ts +3 -3
  160. package/dist/agent-src/scripts/update_roadmap_progress.ts +197 -7
  161. package/dist/agent-src/skills/adr-create/SKILL.md +48 -42
  162. package/dist/agent-src/skills/agent-docs-writing/SKILL.md +18 -0
  163. package/dist/agent-src/skills/agent-security-review/SKILL.md +1 -1
  164. package/dist/agent-src/skills/ai-council/SKILL.md +14 -1
  165. package/dist/agent-src/skills/blameless-post-mortem/SKILL.md +0 -3
  166. package/dist/agent-src/skills/brand/SKILL.md +1 -1
  167. package/dist/agent-src/skills/brand-identity/SKILL.md +3 -3
  168. package/dist/agent-src/skills/brand-strategy/SKILL.md +1 -1
  169. package/dist/agent-src/skills/brand-to-tokens/SKILL.md +3 -3
  170. package/dist/agent-src/skills/canvas-design/SKILL.md +6 -0
  171. package/dist/agent-src/skills/check-refs/SKILL.md +7 -4
  172. package/dist/agent-src/skills/code-review/SKILL.md +1 -0
  173. package/dist/agent-src/skills/complexity-first-planning/SKILL.md +6 -5
  174. package/dist/agent-src/skills/condense-memory/SKILL.md +11 -11
  175. package/dist/agent-src/skills/context-document/SKILL.md +17 -0
  176. package/dist/agent-src/skills/corpus-grounding/SKILL.md +3 -3
  177. package/dist/agent-src/skills/decision-record/SKILL.md +6 -0
  178. package/dist/agent-src/skills/decision-review/SKILL.md +5 -3
  179. package/dist/agent-src/skills/deep-reading-analyst/SKILL.md +6 -1
  180. package/dist/agent-src/skills/design-intelligence/SKILL.md +5 -2
  181. package/dist/agent-src/skills/design-intelligence/references/design-languages.md +1 -1
  182. package/dist/agent-src/skills/design-tokens/SKILL.md +10 -4
  183. package/dist/agent-src/skills/design-variations/SKILL.md +127 -0
  184. package/dist/agent-src/skills/design-variations/evals/triggers.json +17 -0
  185. package/dist/agent-src/skills/emit-tickets/SKILL.md +4 -4
  186. package/dist/agent-src/skills/fe-design/SKILL.md +20 -0
  187. package/dist/agent-src/skills/html-deck/SKILL.md +123 -0
  188. package/dist/agent-src/skills/html-deck/evals/triggers.json +17 -0
  189. package/dist/agent-src/skills/html-deck/templates/deck-shell.html +77 -0
  190. package/dist/agent-src/skills/judge-code-quality/SKILL.md +1 -0
  191. package/dist/agent-src/skills/laravel/SKILL.md +0 -1
  192. package/dist/agent-src/skills/learning-to-rule-or-skill/SKILL.md +46 -0
  193. package/dist/agent-src/skills/lint-skills/SKILL.md +6 -6
  194. package/dist/agent-src/skills/md-language-check/SKILL.md +3 -3
  195. package/dist/agent-src/skills/memory-consolidation/SKILL.md +66 -1
  196. package/dist/agent-src/skills/migration-architect/SKILL.md +1 -0
  197. package/dist/agent-src/skills/module-detect-on-the-fly/SKILL.md +2 -2
  198. package/dist/agent-src/skills/performance-analysis/SKILL.md +2 -0
  199. package/dist/agent-src/skills/prediction-pool-optimizer/SKILL.md +4 -4
  200. package/dist/agent-src/skills/premortem/SKILL.md +0 -3
  201. package/dist/agent-src/skills/project-analysis-core/SKILL.md +16 -0
  202. package/dist/agent-src/skills/reasoning-orchestrator/SKILL.md +3 -1
  203. package/dist/agent-src/skills/release-comms/SKILL.md +46 -45
  204. package/dist/agent-src/skills/roadmap-management/SKILL.md +21 -0
  205. package/dist/agent-src/skills/roadmap-writing/SKILL.md +32 -2
  206. package/dist/agent-src/skills/root-cause-frameworks/SKILL.md +0 -3
  207. package/dist/agent-src/skills/security-audit/SKILL.md +1 -0
  208. package/dist/agent-src/skills/skill-improvement-pipeline/SKILL.md +4 -0
  209. package/dist/agent-src/skills/source-discovery/SKILL.md +22 -3
  210. package/dist/agent-src/skills/subagent-orchestration/SKILL.md +33 -14
  211. package/dist/agent-src/skills/subagent-orchestration/prompts/README.md +11 -0
  212. package/dist/agent-src/skills/subagent-orchestration/prompts/do-in-steps.md +8 -0
  213. package/dist/agent-src/skills/systematic-debugging/SKILL.md +29 -0
  214. package/dist/agent-src/skills/threat-modeling/SKILL.md +2 -2
  215. package/dist/agent-src/skills/typography-system/SKILL.md +2 -2
  216. package/dist/agent-src/skills/verify-completion-evidence/SKILL.md +2 -0
  217. package/dist/agent-src/skills/wireframe/SKILL.md +118 -0
  218. package/dist/agent-src/skills/wireframe/evals/triggers.json +17 -0
  219. package/dist/agent-src/templates/agent-settings.md +22 -1
  220. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  221. package/dist/agent-src/templates/command.md +2 -2
  222. package/dist/agent-src/templates/contexts/knowledge-pages.md +116 -0
  223. package/dist/agent-src/templates/hooks/pre-commit-frontmatter +1 -1
  224. package/dist/agent-src/templates/roadmaps.md +70 -2
  225. package/dist/agent-src/templates/rule.md +1 -1
  226. package/dist/agent-src/templates/scripts/README.md +3 -3
  227. package/dist/agent-src/templates/scripts/work_engine/_lib/agent_settings.ts +109 -0
  228. package/dist/agent-src/templates/tickets.md +8 -8
  229. package/dist/cli/commands/recordTriggerEval.test.js +1 -1
  230. package/dist/cli/commands/recordTriggerEval.test.js.map +1 -1
  231. package/dist/cli/initRouting.js +4 -2
  232. package/dist/cli/initRouting.js.map +1 -1
  233. package/dist/cli/registry.js +1 -0
  234. package/dist/cli/registry.js.map +1 -1
  235. package/dist/discovery/deprecation-report.md +1 -1
  236. package/dist/discovery/discovery-manifest.json +718 -240
  237. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  238. package/dist/discovery/discovery-manifest.summary.md +8 -8
  239. package/dist/discovery/orphan-report.md +1 -1
  240. package/dist/discovery/packs.json +43 -28
  241. package/dist/discovery/trust-report.md +12 -11
  242. package/dist/discovery/workspaces.json +29 -18
  243. package/dist/install/preflight.js +173 -0
  244. package/dist/install/preflight.js.map +1 -0
  245. package/dist/mcp/registry-manifest.json +4 -4
  246. package/dist/router.json +1 -1
  247. package/dist/server/routes/settings.js +4 -0
  248. package/dist/server/routes/settings.js.map +1 -1
  249. package/dist/server/schemas/settings.js +3 -1
  250. package/dist/server/schemas/settings.js.map +1 -1
  251. package/docs/CLAIMS.md +108 -0
  252. package/docs/MIGRATION.md +3 -3
  253. package/docs/architecture.md +5 -5
  254. package/docs/benchmark.md +133 -2
  255. package/docs/benchmark.pinned.yml +31 -0
  256. package/docs/capability-matrix.md +1 -0
  257. package/docs/catalog.md +70 -60
  258. package/docs/command-flows.md +15 -3
  259. package/docs/comparison.yaml +35 -0
  260. package/docs/contracts/agents-layout.md +148 -0
  261. package/docs/contracts/brand-token-consumption.md +5 -0
  262. package/docs/contracts/capability-boundary.md +5 -0
  263. package/docs/contracts/command-category-governance.md +5 -0
  264. package/docs/contracts/command-clusters.md +1 -0
  265. package/docs/contracts/command-surface-tiers.md +1 -1
  266. package/docs/contracts/conformance.md +84 -0
  267. package/docs/contracts/creative-pack-boundary.md +5 -0
  268. package/docs/contracts/discovery-manifest.schema.json +5 -4
  269. package/docs/contracts/file-ownership-matrix.json +4605 -985
  270. package/docs/contracts/governance-enforcement-projection.md +5 -0
  271. package/docs/contracts/gui-wizard.md +1 -1
  272. package/docs/contracts/hook-architecture-v1.md +2 -2
  273. package/docs/contracts/implement-ticket-flow.md +1 -1
  274. package/docs/contracts/kernel-membership.md +13 -0
  275. package/docs/contracts/mcp-tool-inventory.md +23 -23
  276. package/docs/contracts/no-runtime-boundary.md +6 -1
  277. package/docs/contracts/review-lens-schema.md +5 -0
  278. package/docs/contracts/rule-router.md +102 -8
  279. package/docs/contracts/skill-bundled-assets.md +1 -1
  280. package/docs/contracts/skill-dry-run.md +1 -1
  281. package/docs/contracts/subagent-boundary.md +5 -0
  282. package/docs/contracts/ticket-bundle-format.md +9 -4
  283. package/docs/contracts/tier-3-contrib-plugin.md +2 -2
  284. package/docs/contracts/write-engine.md +3 -0
  285. package/docs/customization.md +87 -15
  286. package/docs/decisions/ADR-107-legal-domain-pack-adoption.md +1 -1
  287. package/docs/decisions/ADR-109-subagent-v1-contract.md +246 -0
  288. package/docs/decisions/ADR-110-discipline-profile-resolution-locus.md +105 -0
  289. package/docs/decisions/INDEX.md +2 -0
  290. package/docs/distribution/awesome-list-submission.md +46 -0
  291. package/docs/distribution/launch-story-draft.md +58 -0
  292. package/docs/end-to-end-walkthroughs.md +2 -2
  293. package/docs/getting-started.md +2 -2
  294. package/docs/guidelines/agent-infra/asking-and-brevity-examples.md +24 -0
  295. package/docs/guidelines/agent-infra/corpus-grounding-authoring.md +1 -1
  296. package/docs/guidelines/agent-infra/linked-projects-onboarding-gate.md +2 -2
  297. package/docs/guidelines/agent-infra/missing-tool-handling.md +3 -3
  298. package/docs/guidelines/agent-infra/verify-before-complete-demos.md +2 -2
  299. package/docs/guidelines/augment-portability-patterns.md +1 -1
  300. package/docs/guidelines/code-clarity.md +19 -0
  301. package/docs/guidelines/design-antipatterns-triggers.json +2 -1
  302. package/docs/guidelines/design-antipatterns.md +10 -1
  303. package/docs/guidelines/design-modes.md +6 -0
  304. package/docs/guidelines/php/general.md +9 -1
  305. package/docs/guidelines/php/php-coding-patterns.md +7 -0
  306. package/docs/guides/cross-repo-retrieval.md +1 -1
  307. package/docs/guides/frontend-design-corpus-refresh.md +2 -2
  308. package/docs/guides/local-analytics.md +4 -4
  309. package/docs/guides/skill-discovery.md +1 -1
  310. package/docs/guides/skill-preview.md +1 -1
  311. package/docs/hook-payload-capture.md +6 -6
  312. package/docs/install-friction-report.md +66 -0
  313. package/docs/installation.md +1 -1
  314. package/docs/maintainers/optional-media-deps.md +50 -0
  315. package/docs/mcp-server.md +11 -12
  316. package/docs/media/proof-demo.cast +14 -0
  317. package/docs/media/proof-demo.gif +0 -0
  318. package/docs/migration/consumer-template-consumption-model.md +1 -1
  319. package/docs/migration/divergences/bench-stats-float-precision.md +1 -1
  320. package/docs/migration/node-floor.md +1 -1
  321. package/docs/migration/yaml-roundtrip-spike.md +1 -1
  322. package/docs/personas.md +16 -5
  323. package/docs/positioning-evidence.md +86 -0
  324. package/docs/proof.md +86 -0
  325. package/docs/skills-catalog.md +1 -1
  326. package/docs/troubleshooting.md +8 -8
  327. package/docs/wedge/production-validator/README.md +57 -0
  328. package/docs/wedge/production-validator/production-validator.md +56 -0
  329. package/docs/wizard.md +2 -2
  330. package/package.json +1 -1
  331. package/src/config/agent-settings.template.yml +59 -4
  332. package/src/config/agents-paths.yml +254 -0
  333. package/src/config/budgets.yml +16 -0
  334. package/src/config/discovery/packs.yml +1 -0
  335. package/src/config/discovery/unassigned-artefacts.yml +2 -0
  336. package/src/config/gitignore-block.txt +25 -0
  337. package/src/config/host-capabilities.yml +31 -0
  338. package/src/config/profiles/balanced.ini +4 -0
  339. package/src/config/profiles/full.ini +4 -0
  340. package/src/config/profiles/minimal.ini +4 -0
  341. package/src/scripts/_cli/cmd_conformance.ts +716 -0
  342. package/src/scripts/_cli/cmd_doctor.ts +23 -2
  343. package/src/scripts/_cli/cmd_fleet.ts +401 -0
  344. package/src/scripts/_cli/cmd_preflight.ts +159 -0
  345. package/src/scripts/_dispatch.bash +10 -0
  346. package/src/scripts/_lib/knowledge_events.ts +193 -0
  347. package/src/scripts/_lib/subagent_steering.ts +115 -3
  348. package/src/scripts/_lib/text_similarity.ts +75 -0
  349. package/src/scripts/ai-video/test-pipeline.sh +1 -1
  350. package/src/scripts/ai_council/clients.ts +19 -3
  351. package/src/scripts/append_contested.ts +112 -0
  352. package/src/scripts/audit_auto_rules.ts +11 -1
  353. package/src/scripts/audit_mcp_tools.ts +25 -11
  354. package/src/scripts/bench_ab_v2_run.ts +527 -40
  355. package/src/scripts/bench_ab_v2_stats.ts +6 -0
  356. package/src/scripts/bench_matrix.ts +266 -0
  357. package/src/scripts/bootstrap_knowledge.ts +267 -0
  358. package/src/scripts/build_discovery_manifest.ts +42 -2
  359. package/src/scripts/build_proof.ts +214 -0
  360. package/src/scripts/check_always_budget.ts +3 -0
  361. package/src/scripts/check_augment_description_cap.ts +2 -2
  362. package/src/scripts/check_claims.ts +270 -0
  363. package/src/scripts/check_comparison.ts +79 -0
  364. package/src/scripts/check_generated_artefact_headers.ts +109 -0
  365. package/src/scripts/check_generator_output_coverage.ts +142 -0
  366. package/src/scripts/check_gitignore_freshness.ts +127 -0
  367. package/src/scripts/check_knowledge_pages.ts +210 -0
  368. package/src/scripts/check_knowledge_sharing.ts +162 -0
  369. package/src/scripts/check_media_deps.ts +91 -0
  370. package/src/scripts/check_memory_contradiction.ts +280 -0
  371. package/src/scripts/check_memory_similarity.ts +134 -0
  372. package/src/scripts/check_quality_regression.ts +56 -10
  373. package/src/scripts/check_references.ts +3 -1
  374. package/src/scripts/check_release_pr_shape.ts +4 -0
  375. package/src/scripts/check_site_links.ts +135 -0
  376. package/src/scripts/check_skill_gaps.ts +99 -0
  377. package/src/scripts/check_token_quality_golden.ts +197 -11
  378. package/src/scripts/check_tracked_but_ignored.ts +67 -0
  379. package/src/scripts/cluster_near_miss_patterns.ts +0 -0
  380. package/src/scripts/compile_router.ts +30 -3
  381. package/src/scripts/condense.ts +350 -14
  382. package/src/scripts/consolidate_knowledge_events.ts +192 -0
  383. package/src/scripts/degrade_to_pointer.ts +136 -0
  384. package/src/scripts/design_slop_rules.test.ts +15 -0
  385. package/src/scripts/design_slop_rules.ts +28 -0
  386. package/src/scripts/emit_knowledge_event.ts +158 -0
  387. package/src/scripts/export_replay_corpus.ts +187 -0
  388. package/src/scripts/external_sources_denylist.json +7 -2
  389. package/src/scripts/fold_intake.ts +281 -0
  390. package/src/scripts/generate_capability_matrix.ts +9 -1
  391. package/src/scripts/generate_knowledge_index.ts +222 -0
  392. package/src/scripts/hook_manifest.yaml +26 -14
  393. package/src/scripts/hooks/dispatch_hook.ts +18 -0
  394. package/src/scripts/hot_context_hook.ts +372 -0
  395. package/src/scripts/install +47 -0
  396. package/src/scripts/install-hooks.sh +17 -0
  397. package/src/scripts/inventory_meta_layers.ts +11 -0
  398. package/src/scripts/janitor.ts +258 -0
  399. package/src/scripts/lint_agents_layout.ts +74 -15
  400. package/src/scripts/lint_bench_ab.ts +4 -1
  401. package/src/scripts/lint_featured_skills.ts +0 -0
  402. package/src/scripts/lint_framework_leakage_allowlist.json +26 -3
  403. package/src/scripts/lint_knowledge_scale.ts +250 -0
  404. package/src/scripts/lint_legal_pack.ts +67 -0
  405. package/src/scripts/lint_persona_governance.ts +8 -3
  406. package/src/scripts/lint_regression.ts +15 -0
  407. package/src/scripts/lint_roadmap_blockers.ts +202 -0
  408. package/src/scripts/lint_roadmap_complexity.ts +81 -2
  409. package/src/scripts/lint_subagent_determinism.ts +125 -0
  410. package/src/scripts/measure_augment_budget.ts +46 -6
  411. package/src/scripts/measure_patterns.ts +4 -3
  412. package/src/scripts/measure_skill_reduction.ts +6 -6
  413. package/src/scripts/migration_status.ts +6 -2
  414. package/src/scripts/mine_missing_guardrails.ts +189 -0
  415. package/src/scripts/parity/phase_gate.ts +1 -1
  416. package/src/scripts/parity/replay.ts +21 -0
  417. package/src/scripts/project_thin_rules.ts +120 -16
  418. package/src/scripts/release.ts +39 -1
  419. package/src/scripts/render_benchmark_composite.ts +378 -0
  420. package/src/scripts/roadmap_progress_hook.ts +101 -43
  421. package/src/scripts/schemas/skill.schema.json +27 -0
  422. package/src/scripts/schemas/subagent.schema.json +106 -0
  423. package/src/scripts/skill_linter.ts +1 -0
  424. package/src/scripts/smoke/kernel.sh +5 -4
  425. package/src/scripts/surface-tiers.yml +1 -0
  426. package/src/scripts/sync_gitignore.ts +4 -0
  427. package/src/scripts/update_skill_candidates.ts +172 -0
  428. package/src/scripts/validate_frontmatter.ts +1 -0
@@ -250,6 +250,8 @@ interface ModuleState {
250
250
  PERSONAS_SOURCE: string;
251
251
  USER_TYPES_SOURCE: string;
252
252
  CLAUDE_SKILLS_DIR: string;
253
+ CLAUDE_AGENTS_DIR: string;
254
+ SUBAGENTS_SOURCE: string;
253
255
  PLUGIN_SKILLS_DIR: string;
254
256
  // Injectable multi-root helpers (monkeypatch seam).
255
257
  iter_all_sources: () => Iterable<[string, string]>;
@@ -271,6 +273,12 @@ function _deriveState(root: string): ModuleState {
271
273
  PERSONAS_SOURCE: path.join(root, 'dist/agent-src', 'personas'),
272
274
  USER_TYPES_SOURCE: path.join(root, 'dist/agent-src', 'user-types'),
273
275
  CLAUDE_SKILLS_DIR: path.join(root, '.claude', 'skills'),
276
+ // ADR-109: subagents project from src/ directly (NOT dist/) — a subagent
277
+ // is an executable system prompt Claude Code runs verbatim; telegraph
278
+ // condensation would alter its behaviour, and it is not routed through the
279
+ // pack/discovery condensation flow.
280
+ CLAUDE_AGENTS_DIR: path.join(root, '.claude', 'agents'),
281
+ SUBAGENTS_SOURCE: path.join(root, 'src', 'subagents'),
274
282
  PLUGIN_SKILLS_DIR: path.join(root, '.claude-plugin', 'skills'),
275
283
  iter_all_sources: _agent_src_iter_all_sources,
276
284
  resolve_logical: _agent_src_resolve_logical,
@@ -922,11 +930,84 @@ export function _rewrite_paths(content: string, source_relative_path: string): s
922
930
  // Expose the HRR marker for tests (mirrors condense._HRR_BANNER_MARKER access).
923
931
  export { _HRR_BANNER_MARKER };
924
932
 
925
- export function generate_rule_symlinks(): number {
926
- const rules = _iterdirSorted(MODULE_STATE.RULES_SOURCE)
933
+ // ── Consumer-scoped rule projection (road-to-request-scoped-rule-load P1) ──
934
+ //
935
+ // Opt-in via `projection.rule_workspaces: [<workspace-id>, …]` in
936
+ // `.agent-settings.yml`. Absent / empty = legacy-all (every rule projects —
937
+ // today's behaviour, non-breaking). When set, a non-kernel rule projects
938
+ // only if its `workspaces:` frontmatter intersects the configured set.
939
+ // Kernel rules (`type: always` / `alwaysApply: true`) ALWAYS project —
940
+ // the kernel is unconditional and workspace-independent by definition
941
+ // (rule-router contract § Schema v2). Untagged rules fail safe: they ship.
942
+ // ADR-040: projection-time filtering only, no runtime resolver.
943
+
944
+ function _read_projection_list(key: string): string[] | null {
945
+ const data = load_agent_settings({ project_path: MODULE_STATE.SETTINGS_FILE });
946
+ const proj = data['projection'];
947
+ const value =
948
+ typeof proj === 'object' && proj !== null && !Array.isArray(proj)
949
+ ? (proj as Record<string, unknown>)[key]
950
+ : null;
951
+ if (Array.isArray(value) && value.length > 0) {
952
+ return value.map((v) => String(v));
953
+ }
954
+ return null;
955
+ }
956
+
957
+ function _read_rule_workspaces(): string[] | null {
958
+ return _read_projection_list('rule_workspaces');
959
+ }
960
+
961
+ function _read_rule_packs(): string[] | null {
962
+ return _read_projection_list('rule_packs');
963
+ }
964
+
965
+ /**
966
+ * Whether a rule source file projects under the given workspace + pack
967
+ * scopes. Both scopes are independent constraints: when configured, the
968
+ * rule's frontmatter list must intersect (installed workspaces AND
969
+ * installed packs). Kernel always projects; untagged axes fail safe.
970
+ */
971
+ export function rule_in_scope(
972
+ source_path: string,
973
+ scope: readonly string[] | null,
974
+ pack_scope: readonly string[] | null = null,
975
+ ): boolean {
976
+ if (scope === null && pack_scope === null) {
977
+ return true;
978
+ }
979
+ const [meta] = _parse_frontmatter(_readText(source_path));
980
+ if (meta['type'] === 'always' || meta['alwaysApply'] === true) {
981
+ return true; // kernel always projects
982
+ }
983
+ const axis = (key: string, configured: readonly string[] | null): boolean => {
984
+ if (configured === null) {
985
+ return true;
986
+ }
987
+ const values = Array.isArray(meta[key])
988
+ ? (meta[key] as unknown[]).map((w) => String(w))
989
+ : [];
990
+ if (values.length === 0) {
991
+ return true; // untagged → fail safe: ship it
992
+ }
993
+ return values.some((v) => configured.includes(v));
994
+ };
995
+ return axis('workspaces', scope) && axis('packs', pack_scope);
996
+ }
997
+
998
+ /** List rule basenames under RULES_SOURCE, workspace/pack scope applied. */
999
+ function _scoped_rule_basenames(): string[] {
1000
+ const scope = _read_rule_workspaces();
1001
+ const pack_scope = _read_rule_packs();
1002
+ return _iterdirSorted(MODULE_STATE.RULES_SOURCE)
927
1003
  .filter((p) => p.endsWith('.md') && _isFile(p))
1004
+ .filter((p) => rule_in_scope(p, scope, pack_scope))
928
1005
  .map((p) => path.basename(p))
929
1006
  .sort((a, b) => (a < b ? -1 : a > b ? 1 : 0));
1007
+ }
1008
+
1009
+ export function generate_rule_symlinks(): number {
1010
+ const rules = _scoped_rule_basenames();
930
1011
  const tool_dirs = _filter_tool_dirs(TOOL_DIRS);
931
1012
 
932
1013
  let thin_files: Record<string, string> | null = null;
@@ -980,10 +1061,7 @@ export function generate_rule_symlinks(): number {
980
1061
  }
981
1062
 
982
1063
  export function generate_windsurfrules(): number {
983
- const rules = _iterdirSorted(MODULE_STATE.RULES_SOURCE)
984
- .filter((p) => p.endsWith('.md') && _isFile(p))
985
- .map((p) => path.basename(p))
986
- .sort((a, b) => (a < b ? -1 : a > b ? 1 : 0));
1064
+ const rules = _scoped_rule_basenames();
987
1065
  const parts = ['# Auto-generated from dist/agent-src/rules/ — do not edit directly\n'];
988
1066
  for (const rule of rules) {
989
1067
  const p = path.join(MODULE_STATE.RULES_SOURCE, rule);
@@ -1036,14 +1114,44 @@ function _yaml_scalar(value: string): string {
1036
1114
  return JSON.stringify(value);
1037
1115
  }
1038
1116
 
1039
- function _emit_cursor_mdc(source: string, target: string): void {
1117
+ /**
1118
+ * Derive host-native activation globs from a rule's `triggers:` frontmatter
1119
+ * (road-to-request-scoped-rule-load Phase 2). `file_pattern` triggers map
1120
+ * verbatim; `path_prefix` triggers map to `<prefix>**`. Keyword / phrase /
1121
+ * intent / command triggers produce no glob — those rules stay
1122
+ * description-activated (Cursor Agent-Requested / Windsurf model_decision).
1123
+ */
1124
+ export function derive_trigger_globs(meta: Record<string, unknown>): string[] {
1125
+ const triggers = meta['triggers'];
1126
+ if (!Array.isArray(triggers)) {
1127
+ return [];
1128
+ }
1129
+ const globs: string[] = [];
1130
+ for (const t of triggers) {
1131
+ if (t === null || typeof t !== 'object' || Array.isArray(t)) continue;
1132
+ const obj = t as Record<string, unknown>;
1133
+ if (typeof obj['file_pattern'] === 'string' && obj['file_pattern']) {
1134
+ globs.push(obj['file_pattern']);
1135
+ } else if (typeof obj['path_prefix'] === 'string' && obj['path_prefix']) {
1136
+ const prefix = obj['path_prefix'] as string;
1137
+ globs.push(prefix.endsWith('/') ? `${prefix}**` : `${prefix}**`);
1138
+ }
1139
+ }
1140
+ // De-dup, keep declaration order (deterministic output).
1141
+ return [...new Set(globs)];
1142
+ }
1143
+
1144
+ export function _emit_cursor_mdc(source: string, target: string): void {
1040
1145
  const [meta, body] = _parse_frontmatter(_readText(source));
1041
1146
  const description = _strip(String(meta['description'] ?? '').replace(/\n/g, ' '));
1042
1147
  const always_apply = Boolean(meta['alwaysApply'] || meta['type'] === 'always');
1148
+ // Path-shaped triggers become Cursor auto-attach globs; rules without
1149
+ // them keep `globs: ` empty and stay Agent-Requested via description.
1150
+ const globs = always_apply ? [] : derive_trigger_globs(meta);
1043
1151
  const lines = [
1044
1152
  '---',
1045
1153
  `description: ${_yaml_scalar(description)}`,
1046
- 'globs: ',
1154
+ `globs: ${globs.join(',')}`,
1047
1155
  `alwaysApply: ${always_apply ? 'true' : 'false'}`,
1048
1156
  '---',
1049
1157
  '',
@@ -1053,16 +1161,19 @@ function _emit_cursor_mdc(source: string, target: string): void {
1053
1161
  _writeText(target, lines.join('\n'));
1054
1162
  }
1055
1163
 
1056
- function _emit_windsurf_rule(source: string, target: string): void {
1164
+ export function _emit_windsurf_rule(source: string, target: string): void {
1057
1165
  const [meta, body] = _parse_frontmatter(_readText(source));
1058
1166
  const description = _strip(String(meta['description'] ?? '').replace(/\n/g, ' '));
1059
1167
  const always_apply = Boolean(meta['alwaysApply'] || meta['type'] === 'always');
1060
- const trigger = always_apply ? 'always_on' : 'model_decision';
1168
+ // Path-shaped triggers activate host-natively via Windsurf's `glob`
1169
+ // trigger; keyword/intent-only rules keep `model_decision`.
1170
+ const globs = always_apply ? [] : derive_trigger_globs(meta);
1171
+ const trigger = always_apply ? 'always_on' : globs.length > 0 ? 'glob' : 'model_decision';
1061
1172
  const lines = [
1062
1173
  '---',
1063
1174
  `trigger: ${trigger}`,
1064
1175
  `description: ${_yaml_scalar(description)}`,
1065
- 'globs: ',
1176
+ `globs: ${globs.join(',')}`,
1066
1177
  '---',
1067
1178
  '',
1068
1179
  _pyRstrip(body) + '\n',
@@ -1096,7 +1207,11 @@ function _clean_modern_dir(target_dir: string, valid_names: ReadonlySet<string>)
1096
1207
  }
1097
1208
 
1098
1209
  export function generate_cursor_mdc_rules(): number {
1099
- const rules = _rglobSorted(MODULE_STATE.RULES_SOURCE, '*.md').filter((p) => _isFile(p));
1210
+ const scope = _read_rule_workspaces();
1211
+ const pack_scope = _read_rule_packs();
1212
+ const rules = _rglobSorted(MODULE_STATE.RULES_SOURCE, '*.md')
1213
+ .filter((p) => _isFile(p))
1214
+ .filter((p) => rule_in_scope(p, scope, pack_scope));
1100
1215
  const stems = rules.map((r) => path.basename(r, '.md'));
1101
1216
  const valid = new Set([
1102
1217
  ...stems.map((s) => `${s}.mdc`),
@@ -1111,7 +1226,11 @@ export function generate_cursor_mdc_rules(): number {
1111
1226
  }
1112
1227
 
1113
1228
  export function generate_windsurf_modern_rules(): number {
1114
- const rules = _rglobSorted(MODULE_STATE.RULES_SOURCE, '*.md').filter((p) => _isFile(p));
1229
+ const scope = _read_rule_workspaces();
1230
+ const pack_scope = _read_rule_packs();
1231
+ const rules = _rglobSorted(MODULE_STATE.RULES_SOURCE, '*.md')
1232
+ .filter((p) => _isFile(p))
1233
+ .filter((p) => rule_in_scope(p, scope, pack_scope));
1115
1234
  const valid = new Set(rules.map((r) => path.basename(r)));
1116
1235
  _clean_modern_dir(_WINDSURF_RULES_DIR(), valid);
1117
1236
  for (const rule of rules) {
@@ -1475,6 +1594,221 @@ export function generate_claude_commands(active_command_slugs: ReadonlySet<strin
1475
1594
  return count;
1476
1595
  }
1477
1596
 
1597
+ /**
1598
+ * Project `src/subagents/*.md` (subagent-v1, ADR-109) → `.claude/agents/*.md`
1599
+ * in Claude Code's native subagent format.
1600
+ *
1601
+ * The source frontmatter carries governance metadata (schema_version, trust,
1602
+ * lifecycle, discovery, source) that Claude Code does not understand; the native
1603
+ * `.claude/agents/` format wants only `{name, description, tools, model}` + the
1604
+ * system-prompt body. This is a **frontmatter transform**, not a symlink:
1605
+ *
1606
+ * - `model_tier` → native `model:` via `_TIER_TO_CLAUDE_MODEL` (ADR-034/035);
1607
+ * the `inherit` sentinel passes through to `model: inherit`.
1608
+ * - `tools` (a YAML list) → the comma-joined form Claude Code accepts.
1609
+ * - the body (everything after the closing `---`) is copied verbatim.
1610
+ *
1611
+ * Static projection only — Claude Code (or the user via `@<name>`) decides
1612
+ * dispatch; nothing here runs an agent. Reads from `src/` directly (subagent
1613
+ * prompts are not telegraph-condensed). Reaps stale generated `.claude/agents/`
1614
+ * files whose source no longer exists.
1615
+ */
1616
+ export function generate_claude_subagents(): number {
1617
+ if (!_isDir(MODULE_STATE.SUBAGENTS_SOURCE)) {
1618
+ return 0;
1619
+ }
1620
+ _mkdirp(MODULE_STATE.CLAUDE_AGENTS_DIR);
1621
+
1622
+ const sources = _rglobSorted(MODULE_STATE.SUBAGENTS_SOURCE, '*.md').filter((p) => _isFile(p));
1623
+ const current = new Set<string>();
1624
+ let count = 0;
1625
+
1626
+ for (const src of sources) {
1627
+ const stem = path.basename(src, '.md');
1628
+ const text = _readText(src);
1629
+ if (!text.startsWith('---\n')) {
1630
+ continue;
1631
+ }
1632
+ const end = text.indexOf('\n---\n', 4);
1633
+ if (end === -1) {
1634
+ continue;
1635
+ }
1636
+ const fmBlock = text.slice(4, end);
1637
+ const body = text.slice(end + 5);
1638
+ const fm = _yamlParse(fmBlock) as Record<string, unknown> | null;
1639
+ if (fm === null) {
1640
+ continue;
1641
+ }
1642
+ const name = typeof fm['name'] === 'string' ? (fm['name'] as string) : stem;
1643
+ const description = typeof fm['description'] === 'string' ? (fm['description'] as string) : '';
1644
+ const toolsRaw = fm['tools'];
1645
+ const tools = Array.isArray(toolsRaw) ? toolsRaw.map((t) => String(t)).join(', ') : String(toolsRaw ?? '');
1646
+ const tier = typeof fm['model_tier'] === 'string' ? (fm['model_tier'] as string) : 'inherit';
1647
+ const model = tier === 'inherit' ? 'inherit' : (_TIER_TO_CLAUDE_MODEL[tier] ?? 'inherit');
1648
+
1649
+ const out =
1650
+ '---\n' +
1651
+ `name: ${name}\n` +
1652
+ `description: ${description}\n` +
1653
+ `tools: ${tools}\n` +
1654
+ `model: ${model}\n` +
1655
+ '---\n' +
1656
+ body;
1657
+
1658
+ const target = path.join(MODULE_STATE.CLAUDE_AGENTS_DIR, `${name}.md`);
1659
+ _writeText(target, out);
1660
+ current.add(`${name}.md`);
1661
+ count += 1;
1662
+ }
1663
+
1664
+ // Reap stale generated agent files (source removed). Only touch plain .md
1665
+ // files we would have generated; never follow into unrelated content.
1666
+ for (const item of _iterdirSorted(MODULE_STATE.CLAUDE_AGENTS_DIR)) {
1667
+ const base = path.basename(item);
1668
+ if (base === 'README.md' || current.has(base)) {
1669
+ continue;
1670
+ }
1671
+ if (_isFile(item) && base.endsWith('.md') && !_isSymlink(item)) {
1672
+ fs.unlinkSync(item);
1673
+ }
1674
+ }
1675
+
1676
+ info(` ✅ Created ${count} subagent entries in .claude/agents/`);
1677
+ return count;
1678
+ }
1679
+
1680
+ /**
1681
+ * Cross-host degradation for subagent-v1 (ADR-109 §4).
1682
+ *
1683
+ * Only Claude Code has native subagents (`generate_claude_subagents`). On the
1684
+ * other rules-surface hosts a subagent projects to a **loadable context file** —
1685
+ * a *passive reference*, honestly labelled: there is NO host-native `@`-dispatch
1686
+ * (faking it would need a runtime the package refuses to add). Council
1687
+ * (claude-sonnet-4-5 + gpt-4o, 2026-07-05) converged here over honest-null: the
1688
+ * body is 95% reusable review discipline, 5% dispatch syntax, so an advanced user
1689
+ * on Cursor / Windsurf / Cline loads it on intent and applies the discipline
1690
+ * manually. This is **governance parity, not feature parity** — trust / lifecycle
1691
+ * / model_tier stay legible; automation does not.
1692
+ *
1693
+ * Placement is reaper-safe by construction:
1694
+ * - Cursor / Windsurf → a dedicated `subagents/` subdir with its own reaper,
1695
+ * so it never collides with the aggressive `_clean_modern_dir` rule reapers.
1696
+ * - Cline → a flat real `<name>.subagent.md` in `.clinerules/` (whose reaper
1697
+ * only unlinks *symlinks*, so a real file survives).
1698
+ *
1699
+ * Copilot / Gemini are skipped (no per-file context surface), per ADR-109 §4.
1700
+ * Reads from `src/` directly (subagent prompts are not telegraph-condensed).
1701
+ */
1702
+ export function generate_subagent_host_contexts(): number {
1703
+ if (!_isDir(MODULE_STATE.SUBAGENTS_SOURCE)) {
1704
+ return 0;
1705
+ }
1706
+ const sources = _rglobSorted(MODULE_STATE.SUBAGENTS_SOURCE, '*.md').filter((p) => _isFile(p));
1707
+
1708
+ // Build the passive-reference body once per subagent, keyed by projected name.
1709
+ const rendered: Array<{ name: string; text: string }> = [];
1710
+ for (const src of sources) {
1711
+ const stem = path.basename(src, '.md');
1712
+ const text = _readText(src);
1713
+ if (!text.startsWith('---\n')) {
1714
+ continue;
1715
+ }
1716
+ const end = text.indexOf('\n---\n', 4);
1717
+ if (end === -1) {
1718
+ continue;
1719
+ }
1720
+ const fm = _yamlParse(text.slice(4, end)) as Record<string, unknown> | null;
1721
+ if (fm === null) {
1722
+ continue;
1723
+ }
1724
+ const body = text.slice(end + 5);
1725
+ const name = typeof fm['name'] === 'string' ? (fm['name'] as string) : stem;
1726
+ const description = typeof fm['description'] === 'string' ? (fm['description'] as string) : '';
1727
+ // `trust` is either a flat string or the subagent-v1 nested object
1728
+ // {level, confidence, human_review_required}; surface the level either way.
1729
+ const trustRaw = fm['trust'];
1730
+ const trust =
1731
+ typeof trustRaw === 'string'
1732
+ ? trustRaw
1733
+ : typeof trustRaw === 'object' && trustRaw !== null && typeof (trustRaw as Record<string, unknown>)['level'] === 'string'
1734
+ ? ((trustRaw as Record<string, unknown>)['level'] as string)
1735
+ : 'unknown';
1736
+ const lifecycle = typeof fm['lifecycle'] === 'string' ? (fm['lifecycle'] as string) : 'unknown';
1737
+ const tier = typeof fm['model_tier'] === 'string' ? (fm['model_tier'] as string) : 'inherit';
1738
+ const toolsRaw = fm['tools'];
1739
+ const tools = Array.isArray(toolsRaw)
1740
+ ? toolsRaw.map((t) => String(t)).join(', ')
1741
+ : String(toolsRaw ?? '');
1742
+ const out =
1743
+ '---\n' +
1744
+ `description: ${description}\n` +
1745
+ '---\n\n' +
1746
+ `# Subagent (passive reference): ${name}\n\n` +
1747
+ '> Passive subagent reference. This host has **no native subagent dispatch** —\n' +
1748
+ `> there is no \`@${name}\` here. Load this discipline manually and apply it.\n` +
1749
+ '> Governance parity (trust / lifecycle / model tier) is preserved below;\n' +
1750
+ '> feature parity is not (ADR-109 §4).\n\n' +
1751
+ `- trust: ${trust}\n` +
1752
+ `- lifecycle: ${lifecycle}\n` +
1753
+ `- model tier: ${tier}\n` +
1754
+ (tools ? `- tools: ${tools}\n` : '') +
1755
+ '\n' +
1756
+ _pyRstrip(body) +
1757
+ '\n';
1758
+ rendered.push({ name, text: out });
1759
+ }
1760
+
1761
+ // Host targets: [dir, filename(name)->basename, reaper-predicate].
1762
+ const targets: Array<{ active: boolean; dir: string; file: (n: string) => string; owns: (b: string) => boolean }> = [
1763
+ {
1764
+ active: _tool_active('cursor'),
1765
+ dir: path.join(MODULE_STATE.PROJECT_ROOT, '.cursor', 'subagents'),
1766
+ file: (n) => `${n}.md`,
1767
+ owns: (b) => b.endsWith('.md'),
1768
+ },
1769
+ {
1770
+ active: _tool_active('windsurf'),
1771
+ dir: path.join(MODULE_STATE.PROJECT_ROOT, '.windsurf', 'subagents'),
1772
+ file: (n) => `${n}.md`,
1773
+ owns: (b) => b.endsWith('.md'),
1774
+ },
1775
+ {
1776
+ active: _tool_active('cline'),
1777
+ dir: path.join(MODULE_STATE.PROJECT_ROOT, '.clinerules'),
1778
+ file: (n) => `${n}.subagent.md`,
1779
+ owns: (b) => b.endsWith('.subagent.md'),
1780
+ },
1781
+ ];
1782
+
1783
+ let count = 0;
1784
+ for (const t of targets) {
1785
+ if (!t.active) {
1786
+ continue;
1787
+ }
1788
+ const current = new Set(rendered.map((r) => t.file(r.name)));
1789
+ _mkdirp(t.dir);
1790
+ for (const r of rendered) {
1791
+ _writeText(path.join(t.dir, t.file(r.name)), r.text);
1792
+ count += 1;
1793
+ }
1794
+ // Reap stale generated files we own whose source is gone. Never touch
1795
+ // symlinks (cline's rule symlinks) or a README.
1796
+ if (_exists(t.dir)) {
1797
+ for (const item of _iterdirSorted(t.dir)) {
1798
+ const base = path.basename(item);
1799
+ if (base === 'README.md' || current.has(base)) {
1800
+ continue;
1801
+ }
1802
+ if (_isFile(item) && !_isSymlink(item) && t.owns(base)) {
1803
+ fs.unlinkSync(item);
1804
+ }
1805
+ }
1806
+ }
1807
+ }
1808
+ info(` ✅ Projected ${count} passive subagent context file(s) to non-Claude-Code hosts`);
1809
+ return count;
1810
+ }
1811
+
1478
1812
  export function generate_plugin_command_skills(): number {
1479
1813
  if (!_isDir(path.join(MODULE_STATE.PROJECT_ROOT, 'src', 'domains'))) {
1480
1814
  return 0;
@@ -1713,6 +2047,8 @@ function _generate_tools_inner(
1713
2047
  }
1714
2048
  const skills = _tool_active('claude-code') ? generate_claude_skills(skill_names) : 0;
1715
2049
  const commands = _tool_active('claude-code') ? generate_claude_commands(cmd_slugs) : 0;
2050
+ const subagents = _tool_active('claude-code') ? generate_claude_subagents() : 0;
2051
+ const subagent_contexts = generate_subagent_host_contexts();
1716
2052
  const plugin_cmd_skills = _tool_active('claude-code') ? generate_plugin_command_skills() : 0;
1717
2053
  const plugin_hooks = _tool_active('claude-code') ? generate_plugin_hooks() : 0;
1718
2054
  const personas = generate_persona_symlinks();
@@ -1723,7 +2059,7 @@ function _generate_tools_inner(
1723
2059
  const windsurf_wf = _tool_active('windsurf') ? generate_windsurf_workflows(cmd_slugs) : 0;
1724
2060
  const summary =
1725
2061
  `✅ generate-tools — rules=${rules} skills=${skills} ` +
1726
- `commands=${commands} plugin_cmd_skills=${plugin_cmd_skills} ` +
2062
+ `commands=${commands} subagents=${subagents} subagent_contexts=${subagent_contexts} plugin_cmd_skills=${plugin_cmd_skills} ` +
1727
2063
  `plugin_hooks=${plugin_hooks} ` +
1728
2064
  `personas=${personas} user_types=${user_types} ` +
1729
2065
  `cursor_mdc=${cursor_mdc} windsurf_rules=${windsurf_modern} ` +
@@ -0,0 +1,192 @@
1
+ #!/usr/bin/env tsx
2
+ /**
3
+ * Consolidation report generator for `/team-knowledge consolidate` —
4
+ * road-to-knowledge-system Phase 5. Reads the pending typed-observation
5
+ * intake, aggregates by topic, and finds the nearest existing knowledge
6
+ * page for each aggregate (mechanical similarity only). It NEVER decides
7
+ * NEW/EXTEND/CONFIRM/CONFLICT and NEVER writes a page — per the council
8
+ * verdict, that triage is always a human-reviewed judgment call the
9
+ * command prose makes from this report.
10
+ *
11
+ * Default mode prints the report and exits — intake is untouched.
12
+ * `--commit` additionally clears the consumed intake AFTER printing,
13
+ * for use once the agent has written the reviewed batch (mirrors
14
+ * memory-consolidation's --preview / --commit-intake split).
15
+ *
16
+ * Usage:
17
+ * consolidate_knowledge_events.ts [--intake-dir <dir>] [--knowledge-dir <dir>] [--format text|json] [--commit]
18
+ *
19
+ * Exit codes: 0 = report printed (regardless of pending-event count), 1 = usage error.
20
+ */
21
+ import * as fs from 'node:fs';
22
+ import * as path from 'node:path';
23
+ import process from 'node:process';
24
+ import { fileURLToPath } from 'node:url';
25
+
26
+ import { findMostSimilar, type Candidate } from './_lib/text_similarity.js';
27
+ import { clearAllEvents, readAllEvents, type KnowledgeEvent } from './_lib/knowledge_events.js';
28
+
29
+ const PROG = 'consolidate_knowledge_events.ts';
30
+ const DEFAULT_INTAKE_DIR = path.join('agents', 'knowledge', 'intake');
31
+ const DEFAULT_KNOWLEDGE_DIR = path.join('agents', 'knowledge');
32
+ const PAGE_DIRS = ['concepts', 'procedures'] as const;
33
+
34
+ /** Stable aggregation key per event type — events with the same key describe the same emerging topic. */
35
+ export function aggregationKey(event: KnowledgeEvent): string {
36
+ switch (event.type) {
37
+ case 'convention_detected':
38
+ return `convention:${event.pattern}`;
39
+ case 'mistake_made':
40
+ return `mistake:${event.recurrenceKey}`;
41
+ case 'api_shape_learned':
42
+ return `api:${event.method} ${event.endpoint}`;
43
+ case 'context_stale':
44
+ return `stale:${event.pagePath}#${event.field}`;
45
+ }
46
+ }
47
+
48
+ /** Short human-readable text representing the aggregate, used for the similarity scan against existing pages. */
49
+ function aggregateText(event: KnowledgeEvent): string {
50
+ switch (event.type) {
51
+ case 'convention_detected':
52
+ return event.pattern;
53
+ case 'mistake_made':
54
+ return `${event.errorCategory} ${event.correction}`;
55
+ case 'api_shape_learned':
56
+ return `${event.method} ${event.endpoint}`;
57
+ case 'context_stale':
58
+ return `${event.field} ${String(event.expected)} ${String(event.actual)}`;
59
+ }
60
+ }
61
+
62
+ export interface AggregateGroup {
63
+ key: string;
64
+ events: KnowledgeEvent[];
65
+ nearestPage: { path: string; score: number } | null;
66
+ }
67
+
68
+ function listMarkdownFiles(dirPath: string): string[] {
69
+ let entries: fs.Dirent[];
70
+ try {
71
+ entries = fs.readdirSync(dirPath, { withFileTypes: true });
72
+ } catch {
73
+ return [];
74
+ }
75
+ return entries.filter((e) => e.isFile() && e.name.endsWith('.md')).map((e) => e.name);
76
+ }
77
+
78
+ function loadPageCandidates(knowledgeDir: string): Candidate[] {
79
+ const out: Candidate[] = [];
80
+ for (const dir of PAGE_DIRS) {
81
+ const scanDir = path.join(knowledgeDir, dir);
82
+ for (const file of listMarkdownFiles(scanDir)) {
83
+ let text = '';
84
+ try {
85
+ text = fs.readFileSync(path.join(scanDir, file), 'utf8');
86
+ } catch {
87
+ continue;
88
+ }
89
+ out.push({ id: `${dir}/${file}`, text });
90
+ }
91
+ }
92
+ return out;
93
+ }
94
+
95
+ /** Pure aggregation + similarity-scan step. Never touches disk beyond the passed-in candidates. */
96
+ export function buildReport(events: KnowledgeEvent[], pageCandidates: Candidate[]): AggregateGroup[] {
97
+ const groups = new Map<string, KnowledgeEvent[]>();
98
+ for (const event of events) {
99
+ const key = aggregationKey(event);
100
+ const bucket = groups.get(key) ?? [];
101
+ bucket.push(event);
102
+ groups.set(key, bucket);
103
+ }
104
+
105
+ const out: AggregateGroup[] = [];
106
+ for (const [key, groupEvents] of groups) {
107
+ const first = groupEvents[0];
108
+ if (first === undefined) continue;
109
+ const representative = aggregateText(first);
110
+ const match = findMostSimilar(representative, pageCandidates);
111
+ out.push({
112
+ key,
113
+ events: groupEvents,
114
+ nearestPage: match && match.classification !== 'create' ? { path: match.id, score: match.score } : null,
115
+ });
116
+ }
117
+ return out.sort((a, b) => (a.key < b.key ? -1 : a.key > b.key ? 1 : 0));
118
+ }
119
+
120
+ function renderText(report: AggregateGroup[]): string {
121
+ if (report.length === 0) return `${PROG}: no pending knowledge events.\n`;
122
+ const lines: string[] = [`${PROG}: ${report.length} topic(s) pending review.`, ''];
123
+ for (const group of report) {
124
+ lines.push(`## ${group.key} (${group.events.length} event(s))`);
125
+ if (group.nearestPage) {
126
+ lines.push(
127
+ ` Nearest existing page: ${group.nearestPage.path} (${(group.nearestPage.score * 100).toFixed(0)}% similar) — triage EXTEND/CONFIRM/CONFLICT`,
128
+ );
129
+ } else {
130
+ lines.push(' No similar existing page found — triage NEW');
131
+ }
132
+ lines.push('');
133
+ }
134
+ return lines.join('\n');
135
+ }
136
+
137
+ function printUsage(): void {
138
+ process.stdout.write(`usage: ${PROG} [--intake-dir DIR] [--knowledge-dir DIR] [--format text|json] [--commit]\n`);
139
+ }
140
+
141
+ export function main(argv: string[]): number {
142
+ let intakeDir = DEFAULT_INTAKE_DIR;
143
+ let knowledgeDir = DEFAULT_KNOWLEDGE_DIR;
144
+ let format: 'text' | 'json' = 'text';
145
+ let commit = false;
146
+
147
+ for (let i = 0; i < argv.length; i++) {
148
+ const arg = argv[i];
149
+ if (arg === '-h' || arg === '--help') {
150
+ printUsage();
151
+ return 0;
152
+ } else if (arg === '--intake-dir') {
153
+ intakeDir = argv[++i] ?? intakeDir;
154
+ } else if (arg === '--knowledge-dir') {
155
+ knowledgeDir = argv[++i] ?? knowledgeDir;
156
+ } else if (arg === '--format') {
157
+ const value = argv[++i];
158
+ if (value !== 'text' && value !== 'json') {
159
+ process.stderr.write(`${PROG}: error: --format must be text or json\n`);
160
+ return 1;
161
+ }
162
+ format = value;
163
+ } else if (arg === '--commit') {
164
+ commit = true;
165
+ } else {
166
+ process.stderr.write(`${PROG}: error: unrecognized argument: ${arg}\n`);
167
+ printUsage();
168
+ return 1;
169
+ }
170
+ }
171
+
172
+ const events = readAllEvents(intakeDir);
173
+ const candidates = loadPageCandidates(knowledgeDir);
174
+ const report = buildReport(events, candidates);
175
+
176
+ if (format === 'json') {
177
+ process.stdout.write(JSON.stringify(report, null, 2) + '\n');
178
+ } else {
179
+ process.stdout.write(renderText(report));
180
+ }
181
+
182
+ if (commit) {
183
+ clearAllEvents(intakeDir);
184
+ process.stdout.write(`${PROG}: intake cleared.\n`);
185
+ }
186
+
187
+ return 0;
188
+ }
189
+
190
+ if (fileURLToPath(import.meta.url) === path.resolve(process.argv[1] ?? '')) {
191
+ process.exit(main(process.argv.slice(2)));
192
+ }