@event4u/agent-config 9.9.0 → 9.11.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 (479) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/CHANGELOG.md +212 -194
  3. package/README.md +13 -16
  4. package/agents/templates/.ai-council.yml.example +481 -0
  5. package/agents/templates/.ai-video.xml.example +247 -0
  6. package/dist/agent-src/commands/agent-status.md +12 -11
  7. package/dist/agent-src/commands/agents/user/accept.md +115 -30
  8. package/dist/agent-src/commands/agents/user/delete.md +147 -0
  9. package/dist/agent-src/commands/agents/user/review.md +65 -28
  10. package/dist/agent-src/commands/agents/user/show.md +82 -29
  11. package/dist/agent-src/commands/agents/user/update.md +2 -2
  12. package/dist/agent-src/commands/agents/user.md +16 -3
  13. package/dist/agent-src/commands/check-current-md.md +0 -10
  14. package/dist/agent-src/commands/condense.md +28 -97
  15. package/dist/agent-src/commands/cost/report.md +7 -0
  16. package/dist/agent-src/commands/fix/portability.md +0 -8
  17. package/dist/agent-src/commands/fix/refs.md +0 -8
  18. package/dist/agent-src/commands/humanize.md +2 -2
  19. package/dist/agent-src/commands/jira-ticket.md +1 -1
  20. package/dist/agent-src/commands/memory/load.md +11 -0
  21. package/dist/agent-src/commands/optimize/skills.md +1 -1
  22. package/dist/agent-src/commands/pr/create.md +4 -4
  23. package/dist/agent-src/commands/profile/show.md +3 -3
  24. package/dist/agent-src/commands/rule-compliance-audit.md +5 -4
  25. package/dist/agent-src/commands/security-audit-config.md +1 -1
  26. package/dist/agent-src/commands/sync/gitignore/fix.md +1 -1
  27. package/dist/agent-src/commands/tdd.md +21 -0
  28. package/dist/agent-src/commands/team/delegate.md +2 -2
  29. package/dist/agent-src/commands/team-knowledge/bootstrap.md +9 -8
  30. package/dist/agent-src/commands/team-knowledge/consolidate.md +8 -7
  31. package/dist/agent-src/commands/team.md +4 -1
  32. package/dist/agent-src/commands/upstream-contribute.md +0 -1
  33. package/dist/agent-src/contexts/authority/commit-mechanics.md +7 -0
  34. package/dist/agent-src/contexts/authority/destructive-mechanics.md +16 -0
  35. package/dist/agent-src/contexts/authority/scope-mechanics.md +61 -0
  36. package/dist/agent-src/contexts/communication/rules-auto/reply-close-mechanics.md +20 -18
  37. package/dist/agent-src/contexts/communication/rules-auto/skill-quality-mechanics.md +1 -1
  38. package/dist/agent-src/contexts/communication/rules-auto/slash-command-routing-policy-mechanics.md +1 -1
  39. package/dist/agent-src/contexts/communication/rules-auto/source-of-truth-mechanics.md +9 -10
  40. package/dist/agent-src/contexts/communication/rules-auto/think-before-action-mechanics.md +1 -1
  41. package/dist/agent-src/contexts/communication/rules-auto/user-interaction-mechanics.md +11 -0
  42. package/dist/agent-src/contexts/contracts/artifact-engagement-flow.md +26 -15
  43. package/dist/agent-src/contexts/contracts/command-suggestion-flow.md +3 -0
  44. package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +67 -37
  45. package/dist/agent-src/contexts/execution/auto-orchestration-activation.md +1 -1
  46. package/dist/agent-src/contexts/execution/autonomy-examples.md +1 -1
  47. package/dist/agent-src/contexts/execution/autonomy-mechanics.md +7 -6
  48. package/dist/agent-src/contexts/execution/evidence-discipline.md +92 -77
  49. package/dist/agent-src/contexts/execution/orchestration-benchmark-gate.md +22 -21
  50. package/dist/agent-src/contexts/execution/orchestration-telemetry.md +24 -0
  51. package/dist/agent-src/contexts/execution/project-intelligence.md +122 -103
  52. package/dist/agent-src/contexts/execution/roadmap-execution-contract.md +23 -21
  53. package/dist/agent-src/contexts/execution/subagent-response-contract.md +5 -5
  54. package/dist/agent-src/contexts/execution/subagent-routing.md +11 -0
  55. package/dist/agent-src/contexts/execution/subagent-spawn-contract.md +13 -13
  56. package/dist/agent-src/contexts/execution/subagent-steering.md +36 -34
  57. package/dist/agent-src/contexts/execution/toolchain-resolver.md +1 -1
  58. package/dist/agent-src/contexts/execution/user-memory-channels.md +189 -0
  59. package/dist/agent-src/contexts/execution/verification-mechanics.md +9 -0
  60. package/dist/agent-src/contexts/model-recommendations.md +3 -2
  61. package/dist/agent-src/contexts/subagent-configuration.md +3 -3
  62. package/dist/agent-src/ghostwriter/README.md +2 -2
  63. package/dist/agent-src/packs/README.md +1 -1
  64. package/dist/agent-src/personas/README.md +5 -5
  65. package/dist/agent-src/personas/_template-specialist/persona.md +3 -3
  66. package/dist/agent-src/personas/backend-architect.md +24 -23
  67. package/dist/agent-src/personas/eloquent-tamer.md +30 -30
  68. package/dist/agent-src/personas/frontend-engineer.md +30 -30
  69. package/dist/agent-src/personas/product-owner.md +41 -38
  70. package/dist/agent-src/personas/qa.md +13 -13
  71. package/dist/agent-src/personas/security-engineer.md +22 -22
  72. package/dist/agent-src/presets/README.md +3 -3
  73. package/dist/agent-src/profiles/README.md +3 -3
  74. package/dist/agent-src/rules/active-remediation.md +2 -2
  75. package/dist/agent-src/rules/artifact-engagement-recording.md +4 -4
  76. package/dist/agent-src/rules/ask-when-uncertain.md +0 -4
  77. package/dist/agent-src/rules/augment-edit-discipline.md +1 -1
  78. package/dist/agent-src/rules/broken-access-control.md +4 -4
  79. package/dist/agent-src/rules/code-comment-discipline.md +1 -1
  80. package/dist/agent-src/rules/code-provenance.md +2 -2
  81. package/dist/agent-src/rules/commit-policy.md +4 -9
  82. package/dist/agent-src/rules/communication-through-line.md +5 -5
  83. package/dist/agent-src/rules/decision-revisit-gate.md +1 -1
  84. package/dist/agent-src/rules/design-fidelity.md +1 -1
  85. package/dist/agent-src/rules/doc-screenshot-hygiene.md +1 -1
  86. package/dist/agent-src/rules/domain-adoption-policy.md +1 -1
  87. package/dist/agent-src/rules/domain-safety-pii.md +1 -1
  88. package/dist/agent-src/rules/external-code-graph-interop.md +1 -1
  89. package/dist/agent-src/rules/fast-path-marker-visibility.md +43 -7
  90. package/dist/agent-src/rules/finance-safety-floor.md +1 -1
  91. package/dist/agent-src/rules/framework-neutrality-in-generic-skills.md +3 -3
  92. package/dist/agent-src/rules/history-discipline.md +1 -1
  93. package/dist/agent-src/rules/legal-safety-floor.md +1 -1
  94. package/dist/agent-src/rules/lethal-trifecta-guard.md +5 -5
  95. package/dist/agent-src/rules/low-impact-corpus-privacy-floor.md +10 -8
  96. package/dist/agent-src/rules/media-governance-routing.md +13 -13
  97. package/dist/agent-src/rules/media-sync-ground-truth.md +29 -11
  98. package/dist/agent-src/rules/no-cheap-questions.md +7 -7
  99. package/dist/agent-src/rules/no-decorative-emojis-in-git-surfaces.md +29 -18
  100. package/dist/agent-src/rules/non-destructive-by-default.md +5 -23
  101. package/dist/agent-src/rules/onboarding-gate.md +14 -4
  102. package/dist/agent-src/rules/persona-governance.md +2 -2
  103. package/dist/agent-src/rules/prefer-enums-over-literals.md +9 -9
  104. package/dist/agent-src/rules/preservation-guard.md +10 -2
  105. package/dist/agent-src/rules/question-not-instruction.md +1 -1
  106. package/dist/agent-src/rules/roadmap-progress-sync.md +6 -6
  107. package/dist/agent-src/rules/rule-type-governance.md +1 -1
  108. package/dist/agent-src/rules/scale-discipline.md +1 -1
  109. package/dist/agent-src/rules/scope-control.md +1 -1
  110. package/dist/agent-src/rules/secret-vcs-guard.md +1 -1
  111. package/dist/agent-src/rules/security-sensitive-stop.md +17 -11
  112. package/dist/agent-src/rules/senior-engineering-discipline.md +17 -17
  113. package/dist/agent-src/rules/session-canary.md +1 -1
  114. package/dist/agent-src/rules/skill-quality.md +1 -1
  115. package/dist/agent-src/rules/source-confidentiality.md +21 -19
  116. package/dist/agent-src/rules/source-of-truth.md +6 -5
  117. package/dist/agent-src/rules/spreadsheet-source-quality.md +2 -2
  118. package/dist/agent-src/rules/strategy-safety-floor.md +1 -1
  119. package/dist/agent-src/rules/think-before-action.md +5 -5
  120. package/dist/agent-src/rules/token-budget-discipline.md +5 -3
  121. package/dist/agent-src/rules/token-efficiency.md +2 -2
  122. package/dist/agent-src/rules/untrusted-input-defense.md +4 -4
  123. package/dist/agent-src/rules/user-interaction.md +12 -0
  124. package/dist/agent-src/rules/verify-before-complete.md +4 -24
  125. package/dist/agent-src/skills/adversarial-review/SKILL.md +2 -2
  126. package/dist/agent-src/skills/agent-security-review/SKILL.md +52 -45
  127. package/dist/agent-src/skills/agents-md-thin-root/SKILL.md +2 -2
  128. package/dist/agent-src/skills/ai-code-blindspots/SKILL.md +20 -20
  129. package/dist/agent-src/skills/ai-council/SKILL.md +185 -128
  130. package/dist/agent-src/skills/analysis-skill-router/SKILL.md +3 -3
  131. package/dist/agent-src/skills/api-endpoint/SKILL.md +2 -2
  132. package/dist/agent-src/skills/artisan-commands/SKILL.md +2 -2
  133. package/dist/agent-src/skills/async-python-patterns/SKILL.md +8 -7
  134. package/dist/agent-src/skills/authz-review/SKILL.md +16 -15
  135. package/dist/agent-src/skills/aws-infrastructure/SKILL.md +5 -5
  136. package/dist/agent-src/skills/blade-ui/SKILL.md +1 -1
  137. package/dist/agent-src/skills/bug-analyzer/SKILL.md +30 -12
  138. package/dist/agent-src/skills/code-intelligence/SKILL.md +0 -1
  139. package/dist/agent-src/skills/code-intelligence/evals/triggers.json +52 -0
  140. package/dist/agent-src/skills/code-review/SKILL.md +6 -6
  141. package/dist/agent-src/skills/command-routing/SKILL.md +5 -4
  142. package/dist/agent-src/skills/composer-packages/SKILL.md +2 -2
  143. package/dist/agent-src/skills/condense-memory/SKILL.md +43 -41
  144. package/dist/agent-src/skills/context-document/SKILL.md +23 -21
  145. package/dist/agent-src/skills/copilot-config/SKILL.md +6 -1
  146. package/dist/agent-src/skills/decision-record/SKILL.md +20 -18
  147. package/dist/agent-src/skills/design-intelligence/SKILL.md +4 -4
  148. package/dist/agent-src/skills/design-review/SKILL.md +15 -14
  149. package/dist/agent-src/skills/design-system-capture/reference/design-system-json.md +28 -25
  150. package/dist/agent-src/skills/devcontainer/SKILL.md +2 -2
  151. package/dist/agent-src/skills/docker/SKILL.md +1 -1
  152. package/dist/agent-src/skills/docx-authoring/evals/triggers.json +52 -0
  153. package/dist/agent-src/skills/emit-tickets/SKILL.md +2 -2
  154. package/dist/agent-src/skills/error-handling-patterns/SKILL.md +1 -1
  155. package/dist/agent-src/skills/estimate-ticket/SKILL.md +2 -2
  156. package/dist/agent-src/skills/evaluate-llm-feature/SKILL.md +0 -1
  157. package/dist/agent-src/skills/evaluate-llm-feature/evals/triggers.json +52 -0
  158. package/dist/agent-src/skills/existing-ui-audit/SKILL.md +21 -7
  159. package/dist/agent-src/skills/fe-design/SKILL.md +10 -0
  160. package/dist/agent-src/skills/feature-planning/SKILL.md +2 -2
  161. package/dist/agent-src/skills/finishing-a-development-branch/SKILL.md +3 -3
  162. package/dist/agent-src/skills/flux/SKILL.md +1 -1
  163. package/dist/agent-src/skills/frontend-render-security/SKILL.md +13 -13
  164. package/dist/agent-src/skills/git-workflow/SKILL.md +33 -33
  165. package/dist/agent-src/skills/grafana/SKILL.md +5 -0
  166. package/dist/agent-src/skills/humanizer/SKILL.md +83 -66
  167. package/dist/agent-src/skills/humanizer/data/patterns.md +14 -14
  168. package/dist/agent-src/skills/humanizer/references/anti-aiisms.md +4 -4
  169. package/dist/agent-src/skills/judge-artifact-completeness/SKILL.md +82 -37
  170. package/dist/agent-src/skills/judge-bug-hunter/SKILL.md +17 -5
  171. package/dist/agent-src/skills/judge-injection-defense/SKILL.md +63 -25
  172. package/dist/agent-src/skills/judge-security-auditor/SKILL.md +2 -0
  173. package/dist/agent-src/skills/judge-synthesis/SKILL.md +72 -28
  174. package/dist/agent-src/skills/laravel-horizon/SKILL.md +5 -0
  175. package/dist/agent-src/skills/laravel-mail/SKILL.md +5 -4
  176. package/dist/agent-src/skills/laravel-middleware/SKILL.md +5 -4
  177. package/dist/agent-src/skills/laravel-notifications/SKILL.md +10 -9
  178. package/dist/agent-src/skills/laravel-pennant/SKILL.md +1 -1
  179. package/dist/agent-src/skills/laravel-pulse/SKILL.md +9 -8
  180. package/dist/agent-src/skills/laravel-reverb/SKILL.md +6 -5
  181. package/dist/agent-src/skills/laravel-scheduling/SKILL.md +6 -1
  182. package/dist/agent-src/skills/laravel-validation/SKILL.md +12 -0
  183. package/dist/agent-src/skills/launch-readiness/SKILL.md +1 -1
  184. package/dist/agent-src/skills/learning-to-rule-or-skill/SKILL.md +7 -7
  185. package/dist/agent-src/skills/learning-tutor/SKILL.md +44 -43
  186. package/dist/agent-src/skills/learning-tutor/evals/triggers.json +52 -0
  187. package/dist/agent-src/skills/license-compliance-audit/SKILL.md +7 -7
  188. package/dist/agent-src/skills/license-compliance-borrow-check/SKILL.md +3 -3
  189. package/dist/agent-src/skills/license-compliance-credits/SKILL.md +4 -4
  190. package/dist/agent-src/skills/llm-provider-knowledge/SKILL.md +0 -1
  191. package/dist/agent-src/skills/memory-consolidation/SKILL.md +69 -64
  192. package/dist/agent-src/skills/motion-choreographer/SKILL.md +6 -6
  193. package/dist/agent-src/skills/pdf-tools/evals/triggers.json +52 -0
  194. package/dist/agent-src/skills/performance-analysis/SKILL.md +7 -3
  195. package/dist/agent-src/skills/persona-improvement/SKILL.md +0 -2
  196. package/dist/agent-src/skills/persona-improvement/evals/triggers.json +52 -0
  197. package/dist/agent-src/skills/php-coder/SKILL.md +10 -0
  198. package/dist/agent-src/skills/prediction-pool-optimizer/SKILL.md +129 -120
  199. package/dist/agent-src/skills/prediction-pool-optimizer/reference/ev-fixtures.md +36 -35
  200. package/dist/agent-src/skills/prediction-pool-optimizer/reference/odds-and-bonus.md +45 -41
  201. package/dist/agent-src/skills/project-analysis-core/SKILL.md +4 -4
  202. package/dist/agent-src/skills/project-analysis-hypothesis-driven/SKILL.md +3 -3
  203. package/dist/agent-src/skills/project-analysis-react/SKILL.md +1 -1
  204. package/dist/agent-src/skills/project-analysis-symfony/SKILL.md +1 -1
  205. package/dist/agent-src/skills/project-analysis-zend-laminas/SKILL.md +2 -2
  206. package/dist/agent-src/skills/prompt-engineering-patterns/SKILL.md +1 -1
  207. package/dist/agent-src/skills/prompt-validator/SKILL.md +39 -39
  208. package/dist/agent-src/skills/quality-tools/SKILL.md +15 -15
  209. package/dist/agent-src/skills/react-shadcn-ui/SKILL.md +55 -19
  210. package/dist/agent-src/skills/react-shadcn-ui/reference/registry.md +29 -27
  211. package/dist/agent-src/skills/readme-writing-package/SKILL.md +2 -2
  212. package/dist/agent-src/skills/reasoning-orchestrator/SKILL.md +25 -25
  213. package/dist/agent-src/skills/recursive-verification/SKILL.md +6 -5
  214. package/dist/agent-src/skills/refine-prompt/SKILL.md +1 -1
  215. package/dist/agent-src/skills/refine-ticket/SKILL.md +20 -2
  216. package/dist/agent-src/skills/repomix-packer/SKILL.md +1 -1
  217. package/dist/agent-src/skills/requesting-code-review/SKILL.md +2 -2
  218. package/dist/agent-src/skills/roadmap-management/SKILL.md +80 -66
  219. package/dist/agent-src/skills/roadmap-writing/SKILL.md +84 -77
  220. package/dist/agent-src/skills/rule-refactor/SKILL.md +1 -1
  221. package/dist/agent-src/skills/screenshot-hygiene/evals/triggers.json +52 -0
  222. package/dist/agent-src/skills/security-audit/SKILL.md +26 -9
  223. package/dist/agent-src/skills/security-maturity-assessment/SKILL.md +38 -16
  224. package/dist/agent-src/skills/skill-improvement-pipeline/SKILL.md +14 -11
  225. package/dist/agent-src/skills/skill-writing/SKILL.md +9 -8
  226. package/dist/agent-src/skills/song-to-script/SKILL.md +93 -85
  227. package/dist/agent-src/skills/sql-writing/SKILL.md +2 -2
  228. package/dist/agent-src/skills/stakeholder-tradeoff/SKILL.md +4 -3
  229. package/dist/agent-src/skills/standards-from-config/SKILL.md +61 -43
  230. package/dist/agent-src/skills/subagent-orchestration/SKILL.md +22 -8
  231. package/dist/agent-src/skills/subagent-orchestration/prompts/README.md +28 -2
  232. package/dist/agent-src/skills/supply-chain-intake/SKILL.md +13 -13
  233. package/dist/agent-src/skills/systematic-debugging/SKILL.md +22 -21
  234. package/dist/agent-src/skills/tailwind-engineer/SKILL.md +1 -1
  235. package/dist/agent-src/skills/technical-specification/SKILL.md +5 -0
  236. package/dist/agent-src/skills/terraform/SKILL.md +2 -2
  237. package/dist/agent-src/skills/terragrunt/SKILL.md +8 -8
  238. package/dist/agent-src/skills/testing-anti-patterns/process-anti-patterns.md +1 -1
  239. package/dist/agent-src/skills/threat-modeling/SKILL.md +19 -13
  240. package/dist/agent-src/skills/universal-project-analysis/SKILL.md +1 -1
  241. package/dist/agent-src/skills/upstream-contribute/SKILL.md +0 -1
  242. package/dist/agent-src/skills/using-git-worktrees/SKILL.md +9 -9
  243. package/dist/agent-src/skills/validate-feature-fit/SKILL.md +3 -1
  244. package/dist/agent-src/skills/verify-completion-evidence/SKILL.md +4 -6
  245. package/dist/agent-src/skills/verify-repair-loop/SKILL.md +67 -61
  246. package/dist/agent-src/skills/video-director/SKILL.md +7 -7
  247. package/dist/agent-src/skills/worktree-lifecycle/SKILL.md +3 -3
  248. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  249. package/dist/agent-src/templates/contexts/knowledge-pages.md +47 -45
  250. package/dist/agent-src/templates/contexts/lesson-card.md +2 -2
  251. package/dist/agent-src/templates/contexts/tenant-boundaries.md +2 -2
  252. package/dist/agent-src/templates/contexts.md +1 -1
  253. package/dist/agent-src/templates/features.md +1 -1
  254. package/dist/agent-src/templates/roadmaps.md +125 -116
  255. package/dist/agent-src/templates/rule.md +2 -1
  256. package/dist/agent-src/templates/scripts/pr_risk_review.ts +0 -0
  257. package/dist/agent-src/templates/scripts/telemetry/aggregator.ts +0 -0
  258. package/dist/agent-src/templates/scripts/tier_usage_report.ts +2 -2
  259. package/dist/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +30 -30
  260. package/dist/agent-src/templates/scripts/work_engine/directives/ui/design.ts +88 -33
  261. package/dist/agent-src/templates/scripts/work_engine/directives/ui/polish.ts +22 -2
  262. package/dist/agent-src/templates/scripts/work_engine/directives/ui/review.ts +21 -2
  263. package/dist/agent-src/templates/scripts/work_engine/directives/ui/stack_bundles.ts +179 -0
  264. package/dist/agent-src/templates/scripts/work_engine/stack/detect.ts +155 -4
  265. package/dist/agent-src/templates/scripts/work_engine/state.ts +21 -4
  266. package/dist/agent-src/user-types/README.md +8 -8
  267. package/dist/agent-src/user-types/galabau-field-crew.md +34 -33
  268. package/dist/agent-src/user-types/metalworking-shop.md +35 -34
  269. package/dist/agent-src/user-types/truck-driver.md +22 -20
  270. package/dist/cli/initRouting.js +74 -11
  271. package/dist/cli/initRouting.js.map +1 -1
  272. package/dist/cli/main.js +14 -3
  273. package/dist/cli/main.js.map +1 -1
  274. package/dist/cli/python/workspace_roles.js +2 -2
  275. package/dist/cli/python/workspace_roles.js.map +1 -1
  276. package/dist/cli-delegate/chunk-4SV3XGFA.js +6910 -0
  277. package/dist/cli-delegate/chunk-736JCWLM.js +1104 -0
  278. package/dist/cli-delegate/chunk-7DSAMZFU.js +356 -0
  279. package/dist/cli-delegate/chunk-7HQ52DHU.js +74 -0
  280. package/dist/cli-delegate/chunk-BJGXZNPM.js +266 -0
  281. package/dist/cli-delegate/chunk-FTAISGDQ.js +117 -0
  282. package/dist/cli-delegate/chunk-GME3Q44L.js +82 -0
  283. package/dist/cli-delegate/chunk-GRRPEPRN.js +336 -0
  284. package/dist/cli-delegate/chunk-HJ6DAJHR.js +502 -0
  285. package/dist/cli-delegate/chunk-IR7P7JWA.js +872 -0
  286. package/dist/cli-delegate/chunk-J55WI3RR.js +47 -0
  287. package/dist/cli-delegate/chunk-MCJYCQPF.js +35 -0
  288. package/dist/cli-delegate/chunk-NDJLNC6Q.js +169 -0
  289. package/dist/cli-delegate/chunk-OMIVVCG2.js +26 -0
  290. package/dist/cli-delegate/chunk-OY53J6II.js +7336 -0
  291. package/dist/cli-delegate/chunk-RDGRHAAB.js +259 -0
  292. package/dist/cli-delegate/chunk-TFG57JJM.js +1969 -0
  293. package/dist/cli-delegate/chunk-XX6TOPD7.js +715 -0
  294. package/dist/cli-delegate/chunk-YMFO6FDN.js +10603 -0
  295. package/dist/cli-delegate/cmd_analyze_session.js +294 -0
  296. package/dist/cli-delegate/cmd_conformance.js +646 -0
  297. package/dist/cli-delegate/cmd_converge.js +326 -0
  298. package/dist/cli-delegate/cmd_doctor.js +144 -0
  299. package/dist/cli-delegate/cmd_explain.js +2508 -0
  300. package/dist/cli-delegate/cmd_export.js +296 -0
  301. package/dist/cli-delegate/cmd_fleet.js +332 -0
  302. package/dist/cli-delegate/cmd_memory_get.js +3878 -0
  303. package/dist/cli-delegate/cmd_migrate.js +11 -0
  304. package/dist/cli-delegate/cmd_preflight.js +270 -0
  305. package/dist/cli-delegate/cmd_prune.js +444 -0
  306. package/dist/cli-delegate/cmd_refresh.js +28 -0
  307. package/dist/cli-delegate/cmd_settings_check.js +574 -0
  308. package/dist/cli-delegate/cmd_settings_migrate.js +223 -0
  309. package/dist/cli-delegate/cmd_sync.js +264 -0
  310. package/dist/cli-delegate/cmd_uninstall.js +656 -0
  311. package/dist/cli-delegate/cmd_update.js +425 -0
  312. package/dist/cli-delegate/cmd_upgrade.js +444 -0
  313. package/dist/cli-delegate/cmd_validate.js +305 -0
  314. package/dist/cli-delegate/cmd_versions.js +370 -0
  315. package/dist/discovery/deprecation-report.md +1 -1
  316. package/dist/discovery/discovery-manifest.json +100 -67
  317. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  318. package/dist/discovery/discovery-manifest.summary.md +4 -4
  319. package/dist/discovery/orphan-report.md +1 -1
  320. package/dist/discovery/packs.json +16 -10
  321. package/dist/discovery/trust-report.md +2 -2
  322. package/dist/discovery/workspaces.json +7 -5
  323. package/dist/hooks/dispatch.js +186 -12
  324. package/dist/install/emit_host_rules_cli.js +2 -1
  325. package/dist/install/emit_host_rules_cli.js.map +1 -1
  326. package/dist/install/install.mjs +418 -378
  327. package/dist/install/rule_scope.js +5 -1
  328. package/dist/install/rule_scope.js.map +1 -1
  329. package/dist/install/toolDetection.js +40 -12
  330. package/dist/install/toolDetection.js.map +1 -1
  331. package/dist/install/wizard-plan.js +2 -2
  332. package/dist/install/wizard-plan.js.map +1 -1
  333. package/dist/mcp/registry-manifest.json +3 -3
  334. package/dist/mcp/server.json +2 -2
  335. package/dist/mcp/server.mjs +2194 -1003
  336. package/dist/router.json +1 -1
  337. package/dist/scripts/_lib/compile_time_toggles.js +48 -0
  338. package/dist/scripts/_lib/compile_time_toggles.js.map +1 -0
  339. package/dist/scripts/condense.js +234 -217
  340. package/dist/scripts/condense.js.map +1 -1
  341. package/dist/server/schemas/settings.js +4 -0
  342. package/dist/server/schemas/settings.js.map +1 -1
  343. package/dist/shared/userMd/utils.js +30 -0
  344. package/dist/shared/userMd/utils.js.map +1 -1
  345. package/dist/ui/assets/index-BpSQt5vm.js.map +1 -1
  346. package/docs/guidelines/agent-infra/api-cost-levers.md +56 -5
  347. package/docs/guidelines/agent-infra/simplicity-and-goal-demos.md +93 -33
  348. package/package.json +4 -2
  349. package/src/agent-src/templates/scripts/pr_risk_review.ts +0 -0
  350. package/src/agent-src/templates/scripts/telemetry/aggregator.ts +0 -0
  351. package/src/agent-src/templates/scripts/tier_usage_report.ts +2 -2
  352. package/src/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +30 -30
  353. package/src/agent-src/templates/scripts/work_engine/directives/ui/design.ts +88 -33
  354. package/src/agent-src/templates/scripts/work_engine/directives/ui/polish.ts +22 -2
  355. package/src/agent-src/templates/scripts/work_engine/directives/ui/review.ts +21 -2
  356. package/src/agent-src/templates/scripts/work_engine/directives/ui/stack_bundles.ts +179 -0
  357. package/src/agent-src/templates/scripts/work_engine/stack/detect.ts +155 -4
  358. package/src/agent-src/templates/scripts/work_engine/state.ts +21 -4
  359. package/src/config/agent-settings.template.yml +32 -2
  360. package/src/config/ci-local-parity.yml +142 -0
  361. package/src/config/discovery/packs.yml +7 -0
  362. package/src/config/evaluator-budgets.json +1 -1
  363. package/src/config/gate-coverage.yml +127 -0
  364. package/src/config/pack-size-budget.json +27 -0
  365. package/src/config/preamble-payload-budget.json +44 -0
  366. package/src/install/emit_host_rules_cli.ts +2 -1
  367. package/src/install/rule_scope.ts +5 -1
  368. package/src/install/toolDetection.ts +39 -8
  369. package/src/install/wizard-plan.ts +2 -2
  370. package/src/scripts/_cli/cmd_conformance.ts +2 -1
  371. package/src/scripts/_cli/cmd_converge.ts +2 -1
  372. package/src/scripts/_cli/cmd_doctor.ts +292 -15
  373. package/src/scripts/_cli/cmd_export.ts +2 -1
  374. package/src/scripts/_cli/cmd_fleet.ts +2 -1
  375. package/src/scripts/_cli/cmd_migrate.ts +2 -1
  376. package/src/scripts/_cli/cmd_preflight.ts +2 -1
  377. package/src/scripts/_cli/cmd_refresh.ts +2 -1
  378. package/src/scripts/_cli/cmd_update.ts +2 -1
  379. package/src/scripts/_cli/cmd_upgrade.ts +2 -1
  380. package/src/scripts/_cli/cmd_versions.ts +2 -1
  381. package/src/scripts/_cli/detection_report.ts +480 -0
  382. package/src/scripts/_dispatch.bash +52 -14
  383. package/src/scripts/_lib/agent_user_profile.ts +381 -0
  384. package/src/scripts/_lib/agents_overlay.ts +9 -0
  385. package/src/scripts/_lib/anchor_eval.ts +311 -0
  386. package/src/scripts/_lib/cc_transcript.ts +316 -0
  387. package/src/scripts/_lib/changelog_eras.ts +103 -9
  388. package/src/scripts/_lib/compile_time_toggles.ts +79 -0
  389. package/src/scripts/_lib/confusables.ts +101 -0
  390. package/src/scripts/_lib/duplicate_scope_census.ts +77 -0
  391. package/src/scripts/_lib/environment_detector.ts +441 -0
  392. package/src/scripts/_lib/managed_agents_folder.ts +181 -0
  393. package/src/scripts/_lib/package_root.ts +72 -0
  394. package/src/scripts/_lib/payload_hash_drift.ts +126 -0
  395. package/src/scripts/_lib/preservation_migration.ts +291 -0
  396. package/src/scripts/_lib/retrieval_sanitize.ts +166 -2
  397. package/src/scripts/_lib/scan_scope.ts +115 -0
  398. package/src/scripts/_lib/user_global_memory_audit.ts +187 -0
  399. package/src/scripts/_lib/user_global_observations.ts +830 -0
  400. package/src/scripts/_lib/user_global_revocations.ts +110 -0
  401. package/src/scripts/_lib/user_memory_gate_counters.ts +291 -0
  402. package/src/scripts/ai_council/blind_review.ts +0 -0
  403. package/src/scripts/ai_council/budget_guard.ts +90 -11
  404. package/src/scripts/ai_council/bundler.ts +2 -2
  405. package/src/scripts/ai_council/clients.ts +59 -3
  406. package/src/scripts/ai_council/config.ts +53 -7
  407. package/src/scripts/ai_council/modes.ts +68 -2
  408. package/src/scripts/ai_council/orchestrator.ts +54 -9
  409. package/src/scripts/ai_council/transport_resolver.ts +331 -0
  410. package/src/scripts/ai_team/team_dispatch.ts +17 -6
  411. package/src/scripts/anchor_eval_falsify.ts +198 -0
  412. package/src/scripts/anchor_scoring_run.ts +239 -0
  413. package/src/scripts/annotate_discovery.ts +1 -65
  414. package/src/scripts/bench_quality_run.ts +168 -4
  415. package/src/scripts/cache_realization_report.ts +782 -0
  416. package/src/scripts/check_artefact_count_messaging.ts +5 -1
  417. package/src/scripts/check_augment_description_cap.ts +15 -4
  418. package/src/scripts/check_bundle_path_leakage.ts +10 -4
  419. package/src/scripts/check_ci_local_parity.ts +317 -0
  420. package/src/scripts/check_condensation.ts +96 -191
  421. package/src/scripts/check_context_paths.ts +38 -9
  422. package/src/scripts/check_dependency_floors.ts +153 -0
  423. package/src/scripts/check_gate_coverage.ts +299 -0
  424. package/src/scripts/check_iron_law_prominence.ts +22 -1
  425. package/src/scripts/check_kernel_prefix_stability.ts +0 -0
  426. package/src/scripts/check_no_new_legacy_path.ts +16 -6
  427. package/src/scripts/check_no_roadmap_refs.ts +22 -9
  428. package/src/scripts/check_originality_freshness.ts +167 -0
  429. package/src/scripts/check_pack_size.ts +188 -0
  430. package/src/scripts/check_preamble_payload_budget.ts +130 -0
  431. package/src/scripts/check_proposal.ts +0 -0
  432. package/src/scripts/check_references.ts +0 -1
  433. package/src/scripts/check_safety_floor_untouched.ts +171 -24
  434. package/src/scripts/check_site_links.ts +62 -3
  435. package/src/scripts/ci_status.ts +0 -0
  436. package/src/scripts/cluster_near_miss_patterns.ts +0 -0
  437. package/src/scripts/code_graph/build.ts +0 -0
  438. package/src/scripts/command_suggester/types.ts +0 -0
  439. package/src/scripts/compile_router.ts +10 -14
  440. package/src/scripts/condense.sh +3 -4
  441. package/src/scripts/condense.ts +247 -228
  442. package/src/scripts/cost/track.mjs +168 -33
  443. package/src/scripts/cost_summary.ts +33 -1
  444. package/src/scripts/council_cli.ts +51 -5
  445. package/src/scripts/discovery_graph.ts +0 -0
  446. package/src/scripts/encoding_corpus.ts +500 -0
  447. package/src/scripts/encoding_corpus_report.ts +216 -0
  448. package/src/scripts/evaluator_umbrella.sh +34 -1
  449. package/src/scripts/generate_index.ts +19 -2
  450. package/src/scripts/install-hooks.sh +2 -2
  451. package/src/scripts/learning_sidecar.ts +0 -0
  452. package/src/scripts/lint_confusables.ts +10 -72
  453. package/src/scripts/lint_eval_fixture_citations.ts +113 -0
  454. package/src/scripts/lint_featured_skills.ts +0 -0
  455. package/src/scripts/lint_hidden_unicode.ts +208 -0
  456. package/src/scripts/lint_load_context.ts +17 -5
  457. package/src/scripts/lint_new_skill_gate.ts +9 -3
  458. package/src/scripts/lint_no_python_twin_rationale.ts +17 -2
  459. package/src/scripts/lint_originality.ts +1 -1
  460. package/src/scripts/lint_skill_originality.ts +1 -1
  461. package/src/scripts/lint_ticket_buildable.ts +1 -1
  462. package/src/scripts/lint_ui_stack_bundles.ts +170 -0
  463. package/src/scripts/mcp_server/tools.ts +4 -4
  464. package/src/scripts/measure_scope_dedup.ts +224 -0
  465. package/src/scripts/memory_lookup.ts +0 -0
  466. package/src/scripts/mine_session.ts +98 -0
  467. package/src/scripts/orchestration_payload_hash_drift.ts +145 -0
  468. package/src/scripts/preamble_byte_census.ts +574 -0
  469. package/src/scripts/probe_skill_registration.ts +2 -2
  470. package/src/scripts/redact_hook_capture.ts +13 -0
  471. package/src/scripts/release.ts +65 -10
  472. package/src/scripts/router_telemetry.ts +1 -1
  473. package/src/scripts/second_brain_retrieval.ts +14 -4
  474. package/src/scripts/skill_linter.ts +5 -0
  475. package/src/scripts/surface-tiers.yml +2 -0
  476. package/src/scripts/validate_pack_yaml.ts +0 -0
  477. package/src/server/schemas/settings.ts +8 -0
  478. package/src/shared/userMd/utils.ts +31 -0
  479. package/dist/agent-src/rules/telegraph-speak.md +0 -87
@@ -1,17 +1,18 @@
1
1
  #!/usr/bin/env tsx
2
2
  /**
3
- * Agent-config sync — condense .agent-src.uncondensed/ → dist/agent-src/
3
+ * Agent-config sync — project the artefact roots under src/ → dist/agent-src/
4
4
  * and project dist/agent-src/ → .augment/ (copies for rules by default,
5
5
  * symlinks for the rest; opt into rule symlinks via
6
6
  * augment.rules_use_symlinks in .agent-settings.yml).
7
7
  *
8
8
  * Ported from the retired Python `src/scripts/condense.py` (ADR-200 — Python→TS
9
- * migration, Phase 5). Mirrors the Python CLI surface EXACTLY — every
10
- * subcommand (`--sync`, `--list`, `--changed`, `--check`, `--check-hashes`,
11
- * `--clean-hashes`, `--mark-done <path>`, `--mark-all-done`,
12
- * `--generate-tools`, `--clean-tools`, `--project-augment`) — same flags,
13
- * exit codes, stdout/stderr split, byte-identical messages. No behaviour
14
- * changes; historical quirks preserved and flagged.
9
+ * migration, Phase 5), which mirrored the Python CLI surface exactly.
10
+ * ADR-201 then narrowed it: `.md` is copied verbatim + path-rewritten instead of
11
+ * rewritten by an agent, so the condensation-hash cache and its subcommands
12
+ * (`--check-hashes`, `--clean-hashes`, `--mark-done`, `--mark-all-done`) are gone —
13
+ * staleness is read off the projection itself. Remaining surface: `--sync`,
14
+ * `--list`, `--changed`, `--check`, `--generate-tools`, `--clean-tools`,
15
+ * `--project-augment`.
15
16
  *
16
17
  * Path handling note: the retired Python implementation uses `pathlib.Path` objects.
17
18
  * This twin uses absolute path strings (the host filesystem on the
@@ -22,12 +23,12 @@
22
23
  * multi-root helper functions (iter_all_sources, resolve_logical,
23
24
  * artefact_roots) are exposed through a mutable module-state object so the
24
25
  * pytest suite's monkeypatch pattern — reassigning `condense.PROJECT_ROOT`,
25
- * `condense.HASH_FILE`, `condense.iter_all_sources`, … — has a faithful TS
26
+ * `condense.TARGET_DIR`, `condense.iter_all_sources`, … — has a faithful TS
26
27
  * equivalent. Tests mutate `MODULE_STATE` via the exported setters.
27
28
  */
28
29
 
29
- import * as crypto from 'node:crypto';
30
30
  import * as fs from 'node:fs';
31
+ import * as os from 'node:os';
31
32
  import * as path from 'node:path';
32
33
  import { fileURLToPath, pathToFileURL } from 'node:url';
33
34
 
@@ -42,6 +43,7 @@ import {
42
43
  import { build_claude_hook_matrix } from './_lib/claude_settings_hooks.js';
43
44
  import { is_claude_builtin_name } from './_lib/claude_builtin_names.js';
44
45
  import { project_settings_path, load_agent_settings } from './_lib/agent_settings.js';
46
+ import { rule_is_compile_enabled } from './_lib/compile_time_toggles.js';
45
47
  import { info, success, flush_summary, resolve_level } from './_lib/script_output.js';
46
48
  import {
47
49
  TIER_TO_CLAUDE_MODEL as _TIER_TO_CLAUDE_MODEL,
@@ -223,7 +225,7 @@ function _stripChars(s: string, chars: string): string {
223
225
  // =============================================================================
224
226
  // Module state — mutable mirror of the Python module-level constants & hooks.
225
227
  //
226
- // The pytest suite reassigns `condense.PROJECT_ROOT`, `condense.HASH_FILE`,
228
+ // The pytest suite reassigns `condense.PROJECT_ROOT`, `condense.TARGET_DIR`,
227
229
  // `condense.TARGET_DIR`, `condense.SOURCE_DIR`, `condense.RULES_SOURCE`,
228
230
  // `condense.SKILLS_SOURCE`, `condense.COMMANDS_SOURCE`,
229
231
  // `condense.CLAUDE_SKILLS_DIR`, `condense.AUGMENT_DIR`, `condense.SETTINGS_FILE`,
@@ -244,7 +246,6 @@ interface ModuleState {
244
246
  SOURCE_DIR: string;
245
247
  TARGET_DIR: string;
246
248
  AUGMENT_DIR: string;
247
- HASH_FILE: string;
248
249
  SETTINGS_FILE: string;
249
250
  RULES_SOURCE: string;
250
251
  SKILLS_SOURCE: string;
@@ -267,7 +268,6 @@ function _deriveState(root: string): ModuleState {
267
268
  SOURCE_DIR: path.join(root, '.agent-src.uncondensed'),
268
269
  TARGET_DIR: path.join(root, 'dist/agent-src'),
269
270
  AUGMENT_DIR: path.join(root, '.augment'),
270
- HASH_FILE: path.join(root, 'internal', '.condensation-hashes.json'),
271
271
  SETTINGS_FILE: project_settings_path(root),
272
272
  RULES_SOURCE: path.join(root, 'dist/agent-src', 'rules'),
273
273
  SKILLS_SOURCE: path.join(root, 'dist/agent-src', 'skills'),
@@ -396,130 +396,105 @@ function _read_augment_rules_use_symlinks(): boolean {
396
396
  return false;
397
397
  }
398
398
 
399
- function _lean_projection_mode(): string {
399
+ /**
400
+ * Per-tool user-scope rule directory, for the scope-dedup below. Only tools
401
+ * whose host reads a user-scope rules directory can have a redundant twin;
402
+ * everything else has nothing to de-duplicate against.
403
+ */
404
+ const USER_SCOPE_RULE_DIRS: Readonly<Record<string, string>> = {
405
+ '.claude/rules': path.join('.claude', 'rules'),
406
+ };
407
+
408
+ function _read_projection_scope_dedup(): boolean {
400
409
  const data = load_agent_settings({ project_path: MODULE_STATE.SETTINGS_FILE });
401
- const lean = data['lean_projection'];
402
- if (
403
- typeof lean === 'object' &&
404
- lean !== null &&
405
- !Array.isArray(lean) &&
406
- String((lean as Record<string, unknown>)['mode'] ?? '')
407
- .trim()
408
- .toLowerCase() === 'thin'
409
- ) {
410
- return 'thin';
410
+ const projection = data['projection'];
411
+ if (typeof projection !== 'object' || projection === null || Array.isArray(projection)) {
412
+ return false;
411
413
  }
412
- return 'eager-all';
413
- }
414
-
415
- // --- hashing -----------------------------------------------------------------
416
-
417
- export function file_hash(filepath: string): string {
418
- const h = crypto.createHash('sha256');
419
- h.update(fs.readFileSync(filepath));
420
- return h.digest('hex');
421
- }
422
-
423
- const _DEP_FRONTMATTER_KEYS = ['skills', 'rules'] as const;
424
-
425
- function _slug_to_logical(slug: string): string | null {
426
- for (const cand of [`skills/${slug}/SKILL.md`, `rules/${slug}.md`]) {
427
- if (_resolve_source(cand) !== null) {
428
- return cand;
429
- }
414
+ const value = (projection as Record<string, unknown>)['scope_dedup'];
415
+ if (typeof value === 'boolean') {
416
+ return value;
430
417
  }
431
- return null;
418
+ if (typeof value === 'string') {
419
+ return ['true', 'yes', 'on', '1'].includes(value.trim().toLowerCase());
420
+ }
421
+ return false;
432
422
  }
433
423
 
434
- function _direct_includes(relative: string): string[] {
435
- const source = _resolve_source(relative);
436
- if (source === null) {
437
- return [];
438
- }
439
- let meta: Record<string, unknown>;
424
+ /**
425
+ * Rules whose user-scope twin is BYTE-IDENTICAL to the source, i.e. safe to
426
+ * skip at project scope: the host still loads the same text, once instead of
427
+ * twice, so nothing the model sees changes.
428
+ *
429
+ * Byte-identity is the whole safety argument and is not negotiable. Keying on
430
+ * the filename alone would silently let a stale globally-installed copy win
431
+ * whenever the two scopes hold different versions — which is the NORMAL state
432
+ * while developing the package (measured: 110/110 shared filenames differing in
433
+ * bytes). This is deliberately not the thin-projection mechanism: no rule
434
+ * becomes trigger-gated, so the quality floor that disabled thin projection
435
+ * does not apply here.
436
+ */
437
+ function _dedupable_rules(tool_dir: string, rules: readonly string[], userHome: string): Set<string> {
438
+ const relative = USER_SCOPE_RULE_DIRS[tool_dir];
439
+ if (relative === undefined) {
440
+ return new Set();
441
+ }
442
+ // A hostile or simply absent $HOME must make the dedup inert, not
443
+ // adventurous. In a container `$HOME` is often unset (so `homedir()` can
444
+ // resolve to `/`) or world-writable, and this function decides which rules
445
+ // to STOP emitting — reading an unexpected tree there is how a projection
446
+ // silently loses a rule. Council review of PR #1055 raised exactly this.
447
+ let userDirStat: fs.Stats;
448
+ const userDir = path.join(userHome, relative);
440
449
  try {
441
- [meta] = _parse_frontmatter(_readText(source));
450
+ userDirStat = fs.statSync(userDir);
442
451
  } catch {
443
- return [];
452
+ return new Set();
444
453
  }
445
- const deps: string[] = [];
446
- for (const key of _DEP_FRONTMATTER_KEYS) {
447
- const value = meta[key];
448
- if (!Array.isArray(value)) {
449
- continue;
450
- }
451
- for (const item of value) {
452
- if (typeof item !== 'string') {
453
- continue;
454
- }
455
- const logical = _slug_to_logical(item.trim());
456
- if (logical !== null && logical !== relative) {
457
- deps.push(logical);
458
- }
459
- }
454
+ if (!userDirStat.isDirectory()) {
455
+ return new Set();
460
456
  }
461
- return deps;
462
- }
463
-
464
- export function effective_hash(relative: string, _seen: ReadonlySet<string> | null = null): string {
465
- const source = _resolve_source(relative);
466
- if (source === null) {
467
- return '';
468
- }
469
- const own = file_hash(source);
470
- if (_seen !== null && _seen.has(relative)) {
471
- return own; // cycle — fold own content only
457
+ // World-writable user scope: anyone on the box could plant a byte-identical
458
+ // twin and thereby delete a rule from the project projection. Refuse.
459
+ if ((userDirStat.mode & 0o002) !== 0) {
460
+ _print(` ⚠️ ${tool_dir}: user-scope rules dir is world-writable — scope-dedup skipped`);
461
+ return new Set();
472
462
  }
473
- const deps = [...new Set(_direct_includes(relative))].sort((a, b) =>
474
- a < b ? -1 : a > b ? 1 : 0,
475
- );
476
- if (deps.length === 0) {
477
- return own; // leaf — identical to plain file_hash
478
- }
479
- const seenNext = new Set(_seen ?? []);
480
- seenNext.add(relative);
481
- const parts = [own, ...deps.map((dep) => effective_hash(dep, seenNext))];
482
- return crypto.createHash('sha256').update(parts.join('\n'), 'utf-8').digest('hex');
483
- }
484
-
485
- export function load_hashes(): Record<string, string> {
486
- if (_exists(MODULE_STATE.HASH_FILE)) {
463
+ const skip = new Set<string>();
464
+ for (const rule of rules) {
465
+ const twin = path.join(userDir, rule);
466
+ const source = path.join(MODULE_STATE.RULES_SOURCE, rule);
487
467
  try {
488
- return JSON.parse(_readText(MODULE_STATE.HASH_FILE)) as Record<string, string>;
468
+ if (!_isFile(twin) || !_isFile(source)) continue;
469
+ if (fs.readFileSync(twin).equals(fs.readFileSync(source))) {
470
+ skip.add(rule);
471
+ }
489
472
  } catch {
490
- return {};
473
+ // An unreadable twin is simply not de-duplicable — emit the project copy.
491
474
  }
492
475
  }
493
- return {};
476
+ return skip;
494
477
  }
495
478
 
496
- export function save_hashes(hashes: Record<string, string>): void {
497
- _mkdirp(path.dirname(MODULE_STATE.HASH_FILE));
498
- _writeText(MODULE_STATE.HASH_FILE, _jsonDumpsSorted(hashes) + '\n');
499
- }
500
-
501
- /** Mirror json.dumps(obj, indent=2, sort_keys=True) for a flat string map. */
502
- function _jsonDumpsSorted(obj: Record<string, string>): string {
503
- const keys = Object.keys(obj).sort((a, b) => (a < b ? -1 : a > b ? 1 : 0));
504
- if (keys.length === 0) {
505
- return '{}';
479
+ function _lean_projection_mode(): string {
480
+ const data = load_agent_settings({ project_path: MODULE_STATE.SETTINGS_FILE });
481
+ const lean = data['lean_projection'];
482
+ if (
483
+ typeof lean === 'object' &&
484
+ lean !== null &&
485
+ !Array.isArray(lean) &&
486
+ String((lean as Record<string, unknown>)['mode'] ?? '')
487
+ .trim()
488
+ .toLowerCase() === 'thin'
489
+ ) {
490
+ return 'thin';
506
491
  }
507
- const lines = keys.map((k) => ` ${JSON.stringify(k)}: ${JSON.stringify(obj[k])}`);
508
- return `{\n${lines.join(',\n')}\n}`;
492
+ return 'eager-all';
509
493
  }
510
494
 
511
- export function mark_done(relative_path: string): void {
512
- const source_file = _resolve_source(relative_path);
513
- if (source_file === null || !_exists(source_file)) {
514
- _print(`❌ Source file not found: ${relative_path}`);
515
- process.exit(1);
516
- }
517
- apply_path_rewriter(relative_path);
518
- const hashes = load_hashes();
519
- hashes[relative_path] = effective_hash(relative_path);
520
- save_hashes(hashes);
521
- _print(`✅ Marked as condensed: ${relative_path}`);
522
- }
495
+ // --- hashing -----------------------------------------------------------------
496
+
497
+
523
498
 
524
499
  export function apply_path_rewriter(relative_path: string): boolean {
525
500
  const target = path.join(MODULE_STATE.TARGET_DIR, relative_path);
@@ -535,60 +510,66 @@ export function apply_path_rewriter(relative_path: string): boolean {
535
510
  return true;
536
511
  }
537
512
 
538
- export function mark_all_done(): void {
539
- const hashes = load_hashes();
540
- let count = 0;
541
- for (const [source_file, relative] of _iter_sources()) {
542
- if (!should_condense(source_file)) {
543
- continue;
544
- }
545
- hashes[relative] = effective_hash(relative);
546
- count += 1;
513
+
514
+ /**
515
+ * Whether the projection of `relative` is out of date.
516
+ *
517
+ * Post-ADR-201 the projection IS `rewrite(source)` — a pure function of the
518
+ * source's own bytes and its own relative path. So staleness is *observable in
519
+ * the output* rather than inferred from a stored source hash, which is both
520
+ * simpler and strictly stronger: the old hash cache could only tell you the
521
+ * source had moved since someone last claimed to have condensed it. It never
522
+ * looked at dist, so a hand-edited or half-written projection read as current.
523
+ *
524
+ * The dropped dependency-folding (`effective_hash` mixed in the hashes of
525
+ * `skills:` / `rules:` frontmatter deps) has no counterpart here, and needs
526
+ * none: an LLM rewrite could be influenced by a dependency's content, a pure
527
+ * rewrite cannot. Probed rather than assumed — the whole rewriter chain
528
+ * (`_depth_prefix`, `_split_frontmatter`, `_rewrite_body_links`,
529
+ * `_rewrite_frontmatter_lines`, `_parse_trust_and_owner`,
530
+ * `_inject_hrr_banner`) touches no file but its own input.
531
+ */
532
+ export function is_projection_stale(relative: string): boolean {
533
+ const source = _resolve_source(relative);
534
+ if (source === null) {
535
+ // No source at all — a leftover in dist. `check_sync` owns that verdict.
536
+ return false;
547
537
  }
548
- save_hashes(hashes);
549
- _print(`✅ Marked ${count} files as condensed`);
538
+ if (skip_compile_disabled_rule(relative)) {
539
+ // Deliberately absent from the projection, not out of date.
540
+ return false;
541
+ }
542
+ const target = path.join(MODULE_STATE.TARGET_DIR, relative);
543
+ if (!_exists(target)) {
544
+ return true; // never projected
545
+ }
546
+ return _readText(target) !== _rewrite_paths(_readText(source), relative);
550
547
  }
551
548
 
552
549
  export function list_changed_md(_source_dir?: string): string[] {
553
550
  // _source_dir retained for signature compatibility but ignored (multi-root).
554
- const hashes = load_hashes();
555
551
  const changed: string[] = [];
556
- for (const [source_file, relative] of _iter_sources()) {
557
- if (!should_condense(source_file)) {
552
+ const seen = new Set<string>();
553
+ for (const [, relative] of _iter_sources()) {
554
+ if (seen.has(relative)) {
555
+ continue;
556
+ }
557
+ seen.add(relative);
558
+ // Resolve through `_resolve_source` rather than trusting the iterator's
559
+ // physical hit: `src/` and `src/agent-src/` are both artefact roots, so
560
+ // one relative path can name two unrelated files and only the resolver
561
+ // knows which one wins.
562
+ const source = _resolve_source(relative);
563
+ if (source === null || !should_condense(source)) {
558
564
  continue;
559
565
  }
560
- const current_hash = effective_hash(relative);
561
- const stored_hash = hashes[relative];
562
- if (stored_hash !== current_hash) {
566
+ if (is_projection_stale(relative)) {
563
567
  changed.push(relative);
564
568
  }
565
569
  }
566
570
  return changed;
567
571
  }
568
572
 
569
- export function find_stale_hashes(_source_dir?: string): string[] {
570
- const hashes = load_hashes();
571
- const stale: string[] = [];
572
- for (const relative of Object.keys(hashes).sort((a, b) => (a < b ? -1 : a > b ? 1 : 0))) {
573
- if (_resolve_source(relative) === null) {
574
- stale.push(relative);
575
- }
576
- }
577
- return stale;
578
- }
579
-
580
- export function clean_stale_hashes(_source_dir?: string): number {
581
- const stale = find_stale_hashes(_source_dir);
582
- if (stale.length === 0) {
583
- return 0;
584
- }
585
- const hashes = load_hashes();
586
- for (const relative of stale) {
587
- delete hashes[relative];
588
- }
589
- save_hashes(hashes);
590
- return stale.length;
591
- }
592
573
 
593
574
  export function should_condense(filepath: string): boolean {
594
575
  if (path.extname(filepath) !== '.md') {
@@ -660,19 +641,66 @@ export function cleanup_stale(_source_dir: string, target_dir: string): number {
660
641
  return deleted;
661
642
  }
662
643
 
644
+ /** ADR-201 (accepted 2026-07-29): `.md` is COPIED + path-rewritten, never rewritten
645
+ * by an LLM. Set false to restore the pre-ADR-201 behaviour, where `.md` was skipped
646
+ * here and an agent wrote the condensed body into `dist/` by hand.
647
+ *
648
+ * Measured basis for the removal: 0/429 artifacts saved ≥500 tok, aggregate 0.86%,
649
+ * 267/429 byte-identical, and −36 tok on the always-loaded kernel (condensation made
650
+ * the per-request surface *worse*). Determinism failed by construction: the hash
651
+ * covered the source, never the output, so drift was undetectable — observed live.
652
+ *
653
+ * Council verdict A: `dist/agent-src/` STAYS as a deterministically-produced,
654
+ * git-diffable artifact. Only the *manner* of derivation changes. */
655
+ export const COPY_MD_VERBATIM = true;
656
+
657
+ /** True when `relative` is a rule whose compile-time toggle is off, so the projector
658
+ * must not emit it. Exported for the coupling test — without a pinned test the
659
+ * second half of "dormancy" would be asserted rather than enforced, which is the
660
+ * exact failure ADR telegraph/0002 § part 1 records. */
661
+ export function skip_compile_disabled_rule(relative: string): boolean {
662
+ const posix = relative.split(path.sep).join('/');
663
+ if (!posix.startsWith('rules/') || !posix.endsWith('.md')) {
664
+ return false;
665
+ }
666
+ const rule_id = path.basename(posix, '.md');
667
+ const settings = load_agent_settings({ project_path: MODULE_STATE.SETTINGS_FILE }) as Record<
668
+ string,
669
+ unknown
670
+ >;
671
+ return !rule_is_compile_enabled(rule_id, settings);
672
+ }
673
+
663
674
  export function sync_non_md(_source_dir: string, target_dir: string): number {
664
675
  let copied = 0;
665
676
  const seen = new Set<string>();
666
677
  for (const [source_file, relative] of _iter_sources()) {
667
- if (should_condense(source_file)) {
668
- continue; // .md files are condensed by the agent, not copied here
678
+ if (!COPY_MD_VERBATIM && should_condense(source_file)) {
679
+ continue; // pre-ADR-201: .md was condensed by the agent, not copied here
669
680
  }
670
681
  if (seen.has(relative)) {
671
682
  continue;
672
683
  }
684
+ // ADR telegraph/0002 § part 1: a compile-time-disabled RULE must not be
685
+ // emitted at all. Router membership alone was never zero-cost — the host
686
+ // reads the projected FILE, so a rule dropped from router.json while its
687
+ // body still shipped kept costing its full token price. One switch, both
688
+ // surfaces. Unknown ids are always emitted (the map gates, it does not
689
+ // allowlist), so this is a no-op for every rule but the gated ones.
690
+ if (skip_compile_disabled_rule(relative)) {
691
+ continue;
692
+ }
673
693
  seen.add(relative);
674
694
  const target_file = path.join(target_dir, relative);
675
695
  copy_file(source_file, target_file);
696
+ // ADR-201: a copied `.md` still needs the ONE deterministic transform the
697
+ // removal deliberately preserves — `apply_path_rewriter` fixes relative
698
+ // links so they resolve from the DELIVERED location (`../../docs/…` →
699
+ // `../docs/…`, ~38 artifacts). Without this the projection's links break.
700
+ // Idempotent: it returns false when nothing changed.
701
+ if (COPY_MD_VERBATIM && relative.endsWith('.md')) {
702
+ apply_path_rewriter(relative);
703
+ }
676
704
  _print(` Copied: ${relative}`);
677
705
  copied += 1;
678
706
  }
@@ -704,6 +732,12 @@ export function check_sync(_source_dir: string, target_dir: string): [string[],
704
732
  continue;
705
733
  }
706
734
  seen.add(relative);
735
+ // A compile-disabled rule is deliberately absent from the projection,
736
+ // so demanding a counterpart would report the intended state as a defect.
737
+ // Same predicate the projector and the router compiler use.
738
+ if (skip_compile_disabled_rule(relative)) {
739
+ continue;
740
+ }
707
741
  if (!_exists(path.join(target_dir, relative))) {
708
742
  missing.push(relative);
709
743
  }
@@ -714,7 +748,10 @@ export function check_sync(_source_dir: string, target_dir: string): [string[],
714
748
  continue;
715
749
  }
716
750
  const relative = _relativeToPosix(target_file, target_dir);
717
- if (_resolve_source(relative) === null) {
751
+ // Two ways a projected file is stale: no source at all, or a source
752
+ // that is compile-disabled — the second is how a re-enabled-then-
753
+ // disabled rule leaves weight behind.
754
+ if (_resolve_source(relative) === null || skip_compile_disabled_rule(relative)) {
718
755
  stale.push(relative);
719
756
  }
720
757
  }
@@ -1012,6 +1049,12 @@ function _scoped_rule_basenames(): string[] {
1012
1049
  return _iterdirSorted(MODULE_STATE.RULES_SOURCE)
1013
1050
  .filter((p) => p.endsWith('.md') && _isFile(p))
1014
1051
  .filter((p) => rule_in_scope(p, scope, pack_scope))
1052
+ // A compile-disabled rule has no dist/agent-src/ counterpart, so a per-tool
1053
+ // symlink to it would dangle. The source file still exists, which is why the
1054
+ // scope filters alone let it through — the toggle is a separate axis and this
1055
+ // is its fourth consumer, after the router compiler, the dist writer, and
1056
+ // check_sync. Same predicate in all four; that is the point.
1057
+ .filter((p) => !skip_compile_disabled_rule(`rules/${path.basename(p)}`))
1015
1058
  .map((p) => path.basename(p))
1016
1059
  .sort((a, b) => (a < b ? -1 : a > b ? 1 : 0));
1017
1060
  }
@@ -1030,18 +1073,28 @@ export function generate_rule_symlinks(): number {
1030
1073
  );
1031
1074
  }
1032
1075
 
1076
+ const dedup_on = _read_projection_scope_dedup();
1077
+ const user_home = process.env['HOME'] ?? os.homedir();
1078
+ const skipped_per_tool: Record<string, Set<string>> = {};
1079
+
1033
1080
  let total = 0;
1034
1081
  for (const [tool_dir, rel_prefix] of Object.entries(tool_dirs)) {
1035
1082
  const target_dir = path.join(MODULE_STATE.PROJECT_ROOT, tool_dir);
1083
+ const skip = dedup_on ? _dedupable_rules(tool_dir, rules, user_home) : new Set<string>();
1084
+ skipped_per_tool[tool_dir] = skip;
1036
1085
  _mkdirp(target_dir);
1037
- // Clean stale symlinks
1086
+ // Clean stale symlinks — a rule that became de-duplicable this run is
1087
+ // stale at project scope too, so it has to go with the rest.
1038
1088
  for (const item of _iterdirSorted(target_dir)) {
1039
1089
  const name = path.basename(item);
1040
- if (_isSymlink(item) && !rules.includes(name) && name !== 'README.md') {
1090
+ if (_isSymlink(item) && (!rules.includes(name) || skip.has(name)) && name !== 'README.md') {
1041
1091
  fs.unlinkSync(item);
1042
1092
  }
1043
1093
  }
1044
1094
  for (const rule of rules) {
1095
+ if (skip.has(rule)) {
1096
+ continue;
1097
+ }
1045
1098
  const link = path.join(target_dir, rule);
1046
1099
  if (_existsOrSymlink(link)) {
1047
1100
  fs.unlinkSync(link);
@@ -1058,9 +1111,25 @@ export function generate_rule_symlinks(): number {
1058
1111
  const source_count = rules.length;
1059
1112
  for (const tool_dir of Object.keys(tool_dirs)) {
1060
1113
  const target_dir = path.join(MODULE_STATE.PROJECT_ROOT, tool_dir);
1061
- const tool_count = _iterdirSorted(target_dir).filter((f) => f.endsWith('.md')).length;
1062
- if (tool_count !== source_count) {
1063
- _print(` ⚠️ ${tool_dir}: ${tool_count} rules (expected ${source_count})`);
1114
+ // Count only the RULES this run emitted, not every `.md` in the tree.
1115
+ // Some tool trees legitimately receive other artefact classes — the cline
1116
+ // tree also carries `*.subagent.md` — and counting those produced a
1117
+ // permanent "111 rules (expected 110)" warning that was pure noise. A
1118
+ // warning that is always on is a warning nobody reads.
1119
+ const emitted = new Set(rules);
1120
+ const tool_count = _iterdirSorted(target_dir).filter((f) => emitted.has(path.basename(f))).length;
1121
+ // Expect the de-duplicated count, not the source count: a skipped rule is
1122
+ // an intended absence, so warning on it would train the reader to ignore
1123
+ // this line — which is how a real drift gets missed.
1124
+ const skipped = (skipped_per_tool[tool_dir] ?? new Set()).size;
1125
+ const expected = source_count - skipped;
1126
+ if (tool_count !== expected) {
1127
+ _print(` ⚠️ ${tool_dir}: ${tool_count} rules (expected ${expected})`);
1128
+ }
1129
+ if (skipped > 0) {
1130
+ _print(
1131
+ ` ℹ️ ${tool_dir}: ${skipped} rule(s) skipped — byte-identical twin already installed at user scope`,
1132
+ );
1064
1133
  }
1065
1134
  }
1066
1135
 
@@ -2284,7 +2353,7 @@ function _print(line: string): void {
2284
2353
  export function main(argv: readonly string[] = process.argv.slice(2)): number {
2285
2354
  if (!_exists(MODULE_STATE.SOURCE_DIR) && !_any_source_root_exists()) {
2286
2355
  _print(
2287
- `❌ No source directory found (looked at ${MODULE_STATE.SOURCE_DIR} and packages/*/.agent-src.uncondensed)`,
2356
+ `❌ No source directory found (looked at the artefact roots under src/ and ${MODULE_STATE.SOURCE_DIR})`,
2288
2357
  );
2289
2358
  return 1;
2290
2359
  }
@@ -2300,25 +2369,17 @@ export function main(argv: readonly string[] = process.argv.slice(2)): number {
2300
2369
  } else if (arg === '--changed') {
2301
2370
  const changed = list_changed_md(MODULE_STATE.SOURCE_DIR);
2302
2371
  if (changed.length === 0) {
2303
- _print('✅ No .md files changed since last condensation');
2372
+ _print('✅ Every .md projection matches its source');
2304
2373
  return 0;
2305
2374
  }
2306
- _print(`📝 ${changed.length} .md files changed since last condensation:\n`);
2375
+ _print(`📝 ${changed.length} .md projection(s) out of date — run 'task sync':\n`);
2307
2376
  for (const f of changed) {
2308
2377
  _print(` ${f}`);
2309
2378
  }
2310
- } else if (arg === '--mark-done') {
2311
- if (argv.length < 2) {
2312
- _print('Usage: python scripts/condense.py --mark-done <relative-path>');
2313
- return 1;
2314
- }
2315
- mark_done(argv[1] as string);
2316
- } else if (arg === '--mark-all-done') {
2317
- mark_all_done();
2318
2379
  } else if (arg === '--check') {
2319
2380
  const [missing, stale] = check_sync(MODULE_STATE.SOURCE_DIR, MODULE_STATE.TARGET_DIR);
2320
2381
  if (missing.length === 0 && stale.length === 0) {
2321
- _print('✅ dist/agent-src/ is in sync with .agent-src.uncondensed/');
2382
+ _print('✅ dist/agent-src/ is in sync with the artefact roots under src/');
2322
2383
  return 0;
2323
2384
  }
2324
2385
  if (missing.length > 0) {
@@ -2333,70 +2394,28 @@ export function main(argv: readonly string[] = process.argv.slice(2)): number {
2333
2394
  _print(` ${f}`);
2334
2395
  }
2335
2396
  }
2336
- _print(`\nRun 'task sync' to fix non-.md files, then ask the agent to condense .md files.`);
2397
+ _print(`\nRun 'task sync' — the projection is a deterministic copy, so it needs no agent step.`);
2337
2398
  return 1;
2338
2399
  } else if (arg === '--sync') {
2339
- _print(`Source: ${MODULE_STATE.SOURCE_DIR}`);
2400
+ // SOURCE_DIR is the pre-ADR-051 single root, kept only as a fallback probe;
2401
+ // the real inputs are the artefact roots the multi-root iterator walks.
2402
+ _print(`Source: the artefact roots under src/`);
2340
2403
  _print(`Target: ${MODULE_STATE.TARGET_DIR}\n`);
2341
2404
  _print('--- Syncing non-.md files ---');
2342
2405
  const copied = sync_non_md(MODULE_STATE.SOURCE_DIR, MODULE_STATE.TARGET_DIR);
2343
2406
  _print(`\n--- Cleanup stale files ---`);
2344
2407
  const deleted = cleanup_stale(MODULE_STATE.SOURCE_DIR, MODULE_STATE.TARGET_DIR);
2345
- const hashes = load_hashes();
2346
- const stale_keys = Object.keys(hashes).filter((k) => _resolve_source(k) === null);
2347
- for (const k of stale_keys) {
2348
- delete hashes[k];
2349
- }
2350
- if (stale_keys.length > 0) {
2351
- save_hashes(hashes);
2352
- _print(` Cleaned ${stale_keys.length} stale hash entries`);
2353
- }
2354
2408
  const changed = list_changed_md(MODULE_STATE.SOURCE_DIR);
2355
2409
  _print(`\n✅ Done: ${copied} copied, ${deleted} stale deleted`);
2356
2410
  if (changed.length > 0) {
2357
- _print(`📝 ${changed.length} .md files need condensation (run --changed to see them)`);
2411
+ // --sync writes .md itself, so anything still stale here is a bug in
2412
+ // the projector, not work left for a follow-up step.
2413
+ _print(`❌ ${changed.length} .md projection(s) still out of date after sync (run --changed)`);
2358
2414
  } else {
2359
- _print(`✅ All .md files are up to date`);
2415
+ _print(`✅ Every .md projection matches its source`);
2360
2416
  }
2361
2417
  _print(`\n--- Projecting dist/agent-src/ → .augment/ ---`);
2362
2418
  project_to_augment();
2363
- } else if (arg === '--check-hashes') {
2364
- let has_issues = false;
2365
- const changed = list_changed_md(MODULE_STATE.SOURCE_DIR);
2366
- const stale = find_stale_hashes(MODULE_STATE.SOURCE_DIR);
2367
-
2368
- if (stale.length > 0) {
2369
- has_issues = true;
2370
- _print(`⚠️ ${stale.length} stale hash(es) for deleted source files:\n`);
2371
- for (const f of stale) {
2372
- _print(` ${f}`);
2373
- }
2374
- _print(`\nRun 'task sync-clean-hashes' to remove them.\n`);
2375
- }
2376
-
2377
- if (changed.length > 0) {
2378
- has_issues = true;
2379
- _print(`❌ ${changed.length} .md file(s) need recondensation:\n`);
2380
- for (const f of changed) {
2381
- const stored = load_hashes()[f];
2382
- const reason = stored === undefined ? 'no hash stored' : 'hash mismatch';
2383
- _print(` ${f} (${reason})`);
2384
- }
2385
- _print(`\nRun '/condense' command to recondense these files.`);
2386
- }
2387
-
2388
- if (!has_issues) {
2389
- _print('✅ All condensation hashes are clean (no stale, no mismatches)');
2390
- return 0;
2391
- }
2392
- return 1;
2393
- } else if (arg === '--clean-hashes') {
2394
- const count = clean_stale_hashes(MODULE_STATE.SOURCE_DIR);
2395
- if (count) {
2396
- _print(`✅ Removed ${count} stale hash(es)`);
2397
- } else {
2398
- _print('✅ No stale hashes found');
2399
- }
2400
2419
  } else if (arg === '--generate-tools') {
2401
2420
  generate_tools();
2402
2421
  } else if (arg === '--clean-tools') {
@@ -2405,7 +2424,7 @@ export function main(argv: readonly string[] = process.argv.slice(2)): number {
2405
2424
  project_to_augment();
2406
2425
  } else {
2407
2426
  _print(
2408
- 'Usage: python scripts/condense.py [--sync|--list|--changed|--check|--check-hashes|--clean-hashes|--mark-done <path>|--mark-all-done|--generate-tools|--clean-tools|--project-augment]',
2427
+ 'Usage: condense [--sync|--list|--changed|--check|--generate-tools|--clean-tools|--project-augment]',
2409
2428
  );
2410
2429
  return 1;
2411
2430
  }