@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
@@ -0,0 +1,110 @@
1
+ /**
2
+ * The user-memory revocation ledger — Phase 4 of road-to-global-user-memory
3
+ * ("delete, revoke, audit").
4
+ *
5
+ * Reuses ADR-121's `.revocations.jsonl` tombstone-before-deletion pattern
6
+ * from `knowledge_global_promote.ts` (`append_tombstone` / `load_tombstones`)
7
+ * VERBATIM at the mechanism level: same filename, same single
8
+ * `fs.appendFileSync` per entry (never rewritten), same "the caller MUST
9
+ * call this BEFORE deleting the thing it documents" contract, same tolerant
10
+ * reader (a malformed line is skipped, never crashes the read), same
11
+ * per-domain ledger (this one lives under the `user/` root, exactly as
12
+ * ADR-121's lives under the knowledge store's own root — no line from one
13
+ * ledger is ever readable as a line of the other).
14
+ *
15
+ * The one adaptation ADR-121's shape cannot express unchanged: its
16
+ * `RevocationEntry.card_id` names a knowledge CARD, addressed by a stable,
17
+ * content-derived slug (`card_id_from`). Neither a buffered observation nor
18
+ * a `profile.md` field has an analogous natural id — the Phase 2/3 JSONL
19
+ * schema never added one, and a profile field is a YAML key, not a file
20
+ * with a stem. This module's entries therefore use `entity_id` in place of
21
+ * `card_id` — the generic name reflects that two different callers
22
+ * (`user_global_observations.ts`'s per-observation delete/purge,
23
+ * `agent_user_profile.ts`'s per-field revoke) share this ONE ledger rather
24
+ * than each inventing its own. Field order, the `{revoked_at, <id>, reason}`
25
+ * shape, and every operational guarantee are otherwise unchanged.
26
+ */
27
+ import * as fs from 'node:fs';
28
+ import * as path from 'node:path';
29
+
30
+ import * as user_global_paths from './user_global_paths.js';
31
+
32
+ /** Relative-to-root path of the ledger — lives beside the profile/buffer it audits. */
33
+ export const REVOCATIONS_RELATIVE = path.join('user', '.revocations.jsonl');
34
+
35
+ /** One append-only tombstone line: what was revoked, when, and why. */
36
+ export interface RevocationEntry {
37
+ readonly revoked_at: string;
38
+ readonly entity_id: string;
39
+ readonly reason: string;
40
+ }
41
+
42
+ function _writeTarget(env: user_global_paths.EnvMap | null): string {
43
+ return user_global_paths.write_target(REVOCATIONS_RELATIVE, { env });
44
+ }
45
+
46
+ /**
47
+ * Append one tombstone line to the revocation ledger — the caller MUST call
48
+ * this BEFORE deleting the observation/field it documents. Append-only (a
49
+ * single `fs.appendFileSync`, never rewritten): no delete or purge call
50
+ * ever removes a prior tombstone, so the ledger stays a durable audit trail
51
+ * across every deletion path — mirroring `knowledge_global_promote.ts`'s
52
+ * `append_tombstone` exactly.
53
+ */
54
+ export function appendTombstone(
55
+ entity_id: string,
56
+ reason: string,
57
+ options: { today?: string | undefined; env?: user_global_paths.EnvMap | null } = {},
58
+ ): RevocationEntry {
59
+ const entry: RevocationEntry = {
60
+ revoked_at: options.today ?? new Date().toISOString().slice(0, 10),
61
+ entity_id,
62
+ reason: reason || 'no reason given',
63
+ };
64
+ const target = _writeTarget(options.env ?? null);
65
+ fs.mkdirSync(path.dirname(target), { recursive: true });
66
+ fs.appendFileSync(target, JSON.stringify(entry) + '\n', 'utf-8');
67
+ return entry;
68
+ }
69
+
70
+ /** Read the revocation ledger. Tolerant: missing file → []; malformed lines are skipped. */
71
+ export function loadTombstones(env?: user_global_paths.EnvMap | null): RevocationEntry[] {
72
+ const resolved = user_global_paths.resolve_with_fallback(REVOCATIONS_RELATIVE, {
73
+ env: env ?? null,
74
+ });
75
+ if (resolved === null) {
76
+ return [];
77
+ }
78
+ let text: string;
79
+ try {
80
+ text = fs.readFileSync(resolved, 'utf-8');
81
+ } catch {
82
+ return [];
83
+ }
84
+ const out: RevocationEntry[] = [];
85
+ for (const raw of text.split(/\r\n|\r|\n/)) {
86
+ const line = raw.trim();
87
+ if (!line) {
88
+ continue;
89
+ }
90
+ try {
91
+ const obj: unknown = JSON.parse(line);
92
+ if (
93
+ obj !== null &&
94
+ typeof obj === 'object' &&
95
+ !Array.isArray(obj) &&
96
+ typeof (obj as Record<string, unknown>)['entity_id'] === 'string'
97
+ ) {
98
+ const rec = obj as Record<string, unknown>;
99
+ out.push({
100
+ revoked_at: String(rec['revoked_at'] ?? ''),
101
+ entity_id: rec['entity_id'] as string,
102
+ reason: String(rec['reason'] ?? ''),
103
+ });
104
+ }
105
+ } catch {
106
+ // corrupt line — skip; never let one bad line crash the ledger read
107
+ }
108
+ }
109
+ return out;
110
+ }
@@ -0,0 +1,291 @@
1
+ #!/usr/bin/env tsx
2
+ /**
3
+ * The promotion-behaviour gate counters — road-to-global-user-memory Phase 5
4
+ * ("the gate that can actually fire").
5
+ *
6
+ * ADR-119 exists because a previous gate could never fire by construction:
7
+ * reuse could only accrue while the layer was ON, and ON was withheld pending
8
+ * reuse. ADR-138's Phase 5 gate is keyed to a different signal on purpose —
9
+ * **promotion behaviour**, which moves through human `/agents:user accept`
10
+ * decisions whether or not the global profile ever loads at session start.
11
+ * See `docs/decisions/ADR-138-global-user-profile-layer.md` § Promotion-
12
+ * behaviour gate for the kill-criterion this module's counters feed.
13
+ *
14
+ * Four counts, and nothing else:
15
+ *
16
+ * 1. `projects_with_ge_10_sessions` — how many projects reached the
17
+ * sessions floor the kill-criterion denominator needs.
18
+ * 2. `projects_with_promoted_observation` — how many of those (or any)
19
+ * projects have at least one promoted global observation.
20
+ * 3. `observations_proposed` — total candidates that reached
21
+ * the global buffer (Phase 2's `appendGlobalObservation` succeeding).
22
+ * 4. `observations_accepted` — total candidates a human
23
+ * confirmed via `/agents:user accept` (Phase 2's
24
+ * `applyObservationToGlobalProfile` writing the profile).
25
+ *
26
+ * PII-exclusion-by-construction (the same shape `orchestration-telemetry.md`
27
+ * and `artifact-engagement-recording.md` already use): the counter struct has
28
+ * **no field capable of holding free-form content** — every field is a
29
+ * non-negative integer count. There is no `payload`, `notes`, or `context`
30
+ * field to widen by accident, and `readGateCounters` drops any unknown key or
31
+ * non-numeric value on read rather than passing it through. Privacy is a
32
+ * property of the shape, not of a scrubbing pass that could fail.
33
+ *
34
+ * This module never decides WHEN a project crosses the ≥10-session floor or
35
+ * WHEN a project's first observation gets promoted — those are caller-side
36
+ * facts (a session-start counter, the `/agents:user accept` flow) that the
37
+ * caller already holds in memory at the moment it happens. This module only
38
+ * durably persists the four resulting counts. Honest boundary: a
39
+ * read-then-write race between two concurrent callers can under-count by one
40
+ * increment — acceptable for a single-user local CLI with no lock primitive
41
+ * elsewhere in this package (`_lib/installed_lock.ts` tracks installed files,
42
+ * not a mutex), and irrelevant to the gate's 90-day-window granularity.
43
+ *
44
+ * Path resolution mirrors every sibling global-root artefact
45
+ * (`user_global_observations.ts`, `agent_user_profile.ts`): honours
46
+ * `$EVENT4U_CONFIG_HOME`, falls back to `~/.event4u/agent-config/`, and reads
47
+ * the legacy `~/.config/agent-config/` location for pre-migration installs.
48
+ */
49
+ import * as fs from 'node:fs';
50
+ import * as path from 'node:path';
51
+
52
+ import * as user_global_paths from './user_global_paths.js';
53
+
54
+ /** Relative-to-root path of the gate counters file. */
55
+ export const GATE_COUNTERS_RELATIVE = path.join('user', 'promotion-gate-counters.json');
56
+
57
+ /**
58
+ * The gate's counter shape. Every field is a non-negative integer count —
59
+ * this interface can never carry a string, a path, an id, or an array; there
60
+ * is no field a caller could widen into free-form content without changing
61
+ * the type itself (verified by `tests/lib/user_memory_gate_counters.test.ts`'s
62
+ * shape test).
63
+ */
64
+ /**
65
+ * The two project-level fields are **CANCELLED 2026-07-30** — kept in the struct
66
+ * so a reader finds the decision instead of the absence, never incremented. Both
67
+ * need a per-project record, and every primitive that can hold one either exposes
68
+ * the project set or, once coarsened past membership-testability, cannot resolve a
69
+ * 40% ratio at a cardinality in the tens. Reason + rejected candidates + the
70
+ * council review that forced the wording:
71
+ * agents/settings/contexts/promotion-gate-counting-primitive.md; the resulting
72
+ * narrowing of the kill criterion is recorded in ADR-138.
73
+ */
74
+ export interface PromotionGateCounters {
75
+ readonly projects_with_ge_10_sessions: number;
76
+ readonly projects_with_promoted_observation: number;
77
+ readonly observations_proposed: number;
78
+ readonly observations_accepted: number;
79
+ }
80
+
81
+ /** The closed field set — anything else read from disk is dropped, never passed through. */
82
+ export const GATE_COUNTER_FIELDS = [
83
+ 'projects_with_ge_10_sessions',
84
+ 'projects_with_promoted_observation',
85
+ 'observations_proposed',
86
+ 'observations_accepted',
87
+ ] as const satisfies readonly (keyof PromotionGateCounters)[];
88
+
89
+ /** All-zero starting state. */
90
+ export function zeroCounters(): PromotionGateCounters {
91
+ return {
92
+ projects_with_ge_10_sessions: 0,
93
+ projects_with_promoted_observation: 0,
94
+ observations_proposed: 0,
95
+ observations_accepted: 0,
96
+ };
97
+ }
98
+
99
+ /** `true` iff `value` is a non-negative integer — the only shape a counter field may hold. */
100
+ function _isNonNegativeInteger(value: unknown): value is number {
101
+ return typeof value === 'number' && Number.isInteger(value) && value >= 0;
102
+ }
103
+
104
+ /**
105
+ * Coerce an arbitrary parsed-JSON value into a valid counters struct.
106
+ * Unknown keys are dropped; a field that is missing, non-numeric, negative,
107
+ * or non-integer falls back to `0` rather than throwing or passing the raw
108
+ * value through. This is the runtime half of the shape guarantee — the
109
+ * struct that comes out of a read can never carry anything the type doesn't
110
+ * already allow, even from a hand-edited or corrupted file on disk.
111
+ */
112
+ export function coerceCounters(raw: unknown): PromotionGateCounters {
113
+ const rec =
114
+ raw !== null && typeof raw === 'object' && !Array.isArray(raw)
115
+ ? (raw as Record<string, unknown>)
116
+ : {};
117
+ const zero = zeroCounters();
118
+ const out: Record<string, number> = { ...zero };
119
+ for (const field of GATE_COUNTER_FIELDS) {
120
+ const value = rec[field];
121
+ out[field] = _isNonNegativeInteger(value) ? value : 0;
122
+ }
123
+ return out as unknown as PromotionGateCounters;
124
+ }
125
+
126
+ // ---------------------------------------------------------------------------
127
+ // Path resolution — mirrors user_global_observations.ts / agent_user_profile.ts.
128
+ // ---------------------------------------------------------------------------
129
+
130
+ /** Canonical write target for the gate counters file. */
131
+ export function gateCountersWriteTarget(env?: user_global_paths.EnvMap | null): string {
132
+ return user_global_paths.write_target(GATE_COUNTERS_RELATIVE, { env: env ?? null });
133
+ }
134
+
135
+ /** Resolve the counters file's on-disk path — new namespace first, legacy fallback, `null` if neither exists. */
136
+ export function resolveGateCountersPath(env?: user_global_paths.EnvMap | null): string | null {
137
+ return user_global_paths.resolve_with_fallback(GATE_COUNTERS_RELATIVE, { env: env ?? null });
138
+ }
139
+
140
+ // ---------------------------------------------------------------------------
141
+ // Read / write
142
+ // ---------------------------------------------------------------------------
143
+
144
+ /** Read the current counters. Missing file, missing directory, or malformed JSON all resolve to `zeroCounters()` — never throws. */
145
+ export function readGateCounters(
146
+ options: { env?: user_global_paths.EnvMap | null } = {},
147
+ ): PromotionGateCounters {
148
+ const target = resolveGateCountersPath(options.env ?? null);
149
+ if (target === null) {
150
+ return zeroCounters();
151
+ }
152
+ let raw: string;
153
+ try {
154
+ raw = fs.readFileSync(target, 'utf-8');
155
+ } catch {
156
+ return zeroCounters();
157
+ }
158
+ let parsed: unknown;
159
+ try {
160
+ parsed = JSON.parse(raw);
161
+ } catch {
162
+ return zeroCounters();
163
+ }
164
+ return coerceCounters(parsed);
165
+ }
166
+
167
+ /** Persist `counters` verbatim to the write target, creating the parent directory if needed. */
168
+ function _writeGateCounters(
169
+ counters: PromotionGateCounters,
170
+ options: { env?: user_global_paths.EnvMap | null } = {},
171
+ ): void {
172
+ const target = gateCountersWriteTarget(options.env ?? null);
173
+ fs.mkdirSync(path.dirname(target), { recursive: true });
174
+ fs.writeFileSync(target, JSON.stringify(coerceCounters(counters)) + '\n', 'utf-8');
175
+ }
176
+
177
+ // ---------------------------------------------------------------------------
178
+ // Pure increments — no disk access, easy to unit-test in isolation.
179
+ // ---------------------------------------------------------------------------
180
+
181
+ /** One project just crossed the ≥10-sessions floor. Caller dedupes per-project — this module holds no project identity. */
182
+ export function incrementProjectsWithTenSessions(
183
+ counters: PromotionGateCounters,
184
+ ): PromotionGateCounters {
185
+ return { ...counters, projects_with_ge_10_sessions: counters.projects_with_ge_10_sessions + 1 };
186
+ }
187
+
188
+ /** One project just got its FIRST promoted global observation. Caller dedupes per-project — this module holds no project identity. */
189
+ export function incrementProjectsWithPromotedObservation(
190
+ counters: PromotionGateCounters,
191
+ ): PromotionGateCounters {
192
+ return {
193
+ ...counters,
194
+ projects_with_promoted_observation: counters.projects_with_promoted_observation + 1,
195
+ };
196
+ }
197
+
198
+ /** One observation candidate reached the global buffer (a Phase 2/3 `appendGlobalObservation` success). */
199
+ export function incrementObservationsProposed(
200
+ counters: PromotionGateCounters,
201
+ ): PromotionGateCounters {
202
+ return { ...counters, observations_proposed: counters.observations_proposed + 1 };
203
+ }
204
+
205
+ /** One observation candidate was confirmed via `/agents:user accept` (a Phase 2 `applyObservationToGlobalProfile` write). */
206
+ export function incrementObservationsAccepted(
207
+ counters: PromotionGateCounters,
208
+ ): PromotionGateCounters {
209
+ return { ...counters, observations_accepted: counters.observations_accepted + 1 };
210
+ }
211
+
212
+ // ---------------------------------------------------------------------------
213
+ // Disk-touching wrappers — read, increment, write, return the new value.
214
+ // ---------------------------------------------------------------------------
215
+
216
+ /** Record one project crossing the ≥10-sessions floor. */
217
+ export function recordProjectReachedTenSessions(
218
+ options: { env?: user_global_paths.EnvMap | null } = {},
219
+ ): PromotionGateCounters {
220
+ const next = incrementProjectsWithTenSessions(readGateCounters(options));
221
+ _writeGateCounters(next, options);
222
+ return next;
223
+ }
224
+
225
+ /** Record one project's first promoted observation. */
226
+ export function recordProjectPromotedFirstObservation(
227
+ options: { env?: user_global_paths.EnvMap | null } = {},
228
+ ): PromotionGateCounters {
229
+ const next = incrementProjectsWithPromotedObservation(readGateCounters(options));
230
+ _writeGateCounters(next, options);
231
+ return next;
232
+ }
233
+
234
+ /** Record one observation reaching the global buffer. */
235
+ export function recordObservationProposed(
236
+ options: { env?: user_global_paths.EnvMap | null } = {},
237
+ ): PromotionGateCounters {
238
+ const next = incrementObservationsProposed(readGateCounters(options));
239
+ _writeGateCounters(next, options);
240
+ return next;
241
+ }
242
+
243
+ /** Record one observation confirmed via `/agents:user accept`. */
244
+ export function recordObservationAccepted(
245
+ options: { env?: user_global_paths.EnvMap | null } = {},
246
+ ): PromotionGateCounters {
247
+ const next = incrementObservationsAccepted(readGateCounters(options));
248
+ _writeGateCounters(next, options);
249
+ return next;
250
+ }
251
+
252
+ // ---------------------------------------------------------------------------
253
+ // Kill-criterion evaluation — see ADR-138 § Promotion-behaviour gate.
254
+ // ---------------------------------------------------------------------------
255
+
256
+ /** Human-confirmed floor: below this share of ≥10-session projects carrying a promotion, the teardown review is mandatory. */
257
+ export const PROJECT_PROMOTION_SHARE_FLOOR = 0.4;
258
+
259
+ /** Human-confirmed floor: below this review→accept rate, the teardown review is mandatory. */
260
+ export const REVIEW_ACCEPT_RATE_FLOOR = 0.3;
261
+
262
+ export interface KillCriterionResult {
263
+ /** `null` when `projects_with_ge_10_sessions` is `0` — the ratio is undefined, not zero, until there is a qualifying project. */
264
+ readonly project_promotion_share: number | null;
265
+ /** `null` when `observations_proposed` is `0` — same undefined-vs-zero distinction. */
266
+ readonly review_accept_rate: number | null;
267
+ /** `true` iff either floor is breached with a defined ratio — an undefined ratio never trips the gate on its own. */
268
+ readonly teardown_review_required: boolean;
269
+ }
270
+
271
+ /**
272
+ * Evaluate the two kill-criterion floors from ADR-138 § Promotion-behaviour
273
+ * gate against the current counters. A ratio with a zero denominator is
274
+ * reported as `null` (undefined), not `0` or `1` — an empty gate has not yet
275
+ * failed, it has not yet been exercised, and the ADR's window (90 days from
276
+ * release) is what turns "not yet exercised" into a real finding.
277
+ */
278
+ export function evaluateKillCriterion(counters: PromotionGateCounters): KillCriterionResult {
279
+ const project_promotion_share =
280
+ counters.projects_with_ge_10_sessions > 0
281
+ ? counters.projects_with_promoted_observation / counters.projects_with_ge_10_sessions
282
+ : null;
283
+ const review_accept_rate =
284
+ counters.observations_proposed > 0
285
+ ? counters.observations_accepted / counters.observations_proposed
286
+ : null;
287
+ const teardown_review_required =
288
+ (project_promotion_share !== null && project_promotion_share < PROJECT_PROMOTION_SHARE_FLOOR) ||
289
+ (review_accept_rate !== null && review_accept_rate < REVIEW_ACCEPT_RATE_FLOOR);
290
+ return { project_promotion_share, review_accept_rate, teardown_review_required };
291
+ }
@@ -12,9 +12,13 @@
12
12
  * same permission discipline as the API keys). The legacy
13
13
  * `~/.config/agent-config/council-spend.jsonl` is read as a fallback.
14
14
  *
15
- * Contract (verbatim from the Python module):
15
+ * Contract (verbatim from the Python module, plus the additive TS-only
16
+ * cache extension below):
16
17
  * - The ledger is **append-only**. Each line is `{"ts": ISO-8601 UTC,
17
- * "usd": float, "provider": str, "model": str}`.
18
+ * "usd": float, "provider": str, "model": str}`, optionally followed by
19
+ * `"cache_read_input_tokens": int, "cache_creation_input_tokens": int,
20
+ * "cache_ttl": "5m"|"1h"` when the caller reports cache activity — absent
21
+ * on every entry recorded before this extension shipped.
18
22
  * - `today_spend_usd()` sums entries within the last 24h from "now".
19
23
  * - `would_exceed(limit_usd, next_call_usd)` returns true iff the next call
20
24
  * would push the rolling window past the limit.
@@ -75,6 +79,12 @@ export interface SpendEntry {
75
79
  usd: number;
76
80
  provider: string;
77
81
  model: string;
82
+ // Prompt-cache accounting (additive — absent on entries recorded before
83
+ // this field existed, and on calls with no cache activity to report).
84
+ cache_read_input_tokens?: number;
85
+ cache_creation_input_tokens?: number;
86
+ /** Write-multiplier TTL tier in effect when this entry was recorded. */
87
+ cache_ttl?: '5m' | '1h';
78
88
  }
79
89
 
80
90
  function _nowUtcMs(): number {
@@ -259,14 +269,37 @@ function _pyJsonString(s: string): string {
259
269
  * `json.dumps({"ts": ts, "usd": round(usd, 6), "provider": provider,
260
270
  * "model": model})` does: default separators (`", "`, `": "`), insertion
261
271
  * order (NOT sorted). `usd` is a float (`pyFloatRepr`); the rest are strings.
272
+ *
273
+ * The three cache params are appended only when the CALLER passed them
274
+ * (`!== undefined`) — a call with none of the three reproduces the original
275
+ * 4-key line byte-for-byte, which is what keeps every pre-existing caller
276
+ * (and the python3 byte-parity test, which has no Python-side cache
277
+ * counterpart) unaffected by this additive extension.
262
278
  */
263
- function _dumpEntry(ts: string, usd: number, provider: string, model: string): string {
264
- return (
265
- `{${_pyJsonString('ts')}: ${_pyJsonString(ts)}, ` +
279
+ function _dumpEntry(
280
+ ts: string,
281
+ usd: number,
282
+ provider: string,
283
+ model: string,
284
+ cacheRead?: number,
285
+ cacheWrite?: number,
286
+ cacheTtl?: '5m' | '1h',
287
+ ): string {
288
+ let body =
289
+ `${_pyJsonString('ts')}: ${_pyJsonString(ts)}, ` +
266
290
  `${_pyJsonString('usd')}: ${pyFloatRepr(usd)}, ` +
267
291
  `${_pyJsonString('provider')}: ${_pyJsonString(provider)}, ` +
268
- `${_pyJsonString('model')}: ${_pyJsonString(model)}}`
269
- );
292
+ `${_pyJsonString('model')}: ${_pyJsonString(model)}`;
293
+ if (cacheRead !== undefined) {
294
+ body += `, ${_pyJsonString('cache_read_input_tokens')}: ${Math.trunc(cacheRead)}`;
295
+ }
296
+ if (cacheWrite !== undefined) {
297
+ body += `, ${_pyJsonString('cache_creation_input_tokens')}: ${Math.trunc(cacheWrite)}`;
298
+ }
299
+ if (cacheTtl !== undefined) {
300
+ body += `, ${_pyJsonString('cache_ttl')}: ${_pyJsonString(cacheTtl)}`;
301
+ }
302
+ return `{${body}}`;
270
303
  }
271
304
 
272
305
  /** Coerce a parsed JSON value to a float like Python's `float(obj.get(...))`. */
@@ -366,16 +399,46 @@ export function read_entries(p: string | null = null): SpendEntry[] {
366
399
  if (usd === null) {
367
400
  continue;
368
401
  }
369
- out.push({
402
+ const entry: SpendEntry = {
370
403
  ts,
371
404
  usd,
372
405
  provider: _toStr(record.provider, ''),
373
406
  model: _toStr(record.model, ''),
374
- });
407
+ };
408
+ // exactOptionalPropertyTypes forbids `key: undefined` on an object
409
+ // literal — assign conditionally so a legacy (or cache-less) line
410
+ // leaves these keys absent rather than present-but-undefined.
411
+ const cacheRead = _toOptionalNonNegInt(record.cache_read_input_tokens);
412
+ if (cacheRead !== undefined) {
413
+ entry.cache_read_input_tokens = cacheRead;
414
+ }
415
+ const cacheWrite = _toOptionalNonNegInt(record.cache_creation_input_tokens);
416
+ if (cacheWrite !== undefined) {
417
+ entry.cache_creation_input_tokens = cacheWrite;
418
+ }
419
+ const cacheTtl = _toOptionalTtl(record.cache_ttl);
420
+ if (cacheTtl !== undefined) {
421
+ entry.cache_ttl = cacheTtl;
422
+ }
423
+ out.push(entry);
375
424
  }
376
425
  return out;
377
426
  }
378
427
 
428
+ /** A non-negative finite number, or `undefined` when absent/malformed. */
429
+ function _toOptionalNonNegInt(v: unknown): number | undefined {
430
+ if (v === undefined || v === null) {
431
+ return undefined;
432
+ }
433
+ const n = _toFloat(v);
434
+ return n === null || n < 0 ? undefined : n;
435
+ }
436
+
437
+ /** `'5m' | '1h'`, or `undefined` for anything else (including absent). */
438
+ function _toOptionalTtl(v: unknown): '5m' | '1h' | undefined {
439
+ return v === '5m' || v === '1h' ? v : undefined;
440
+ }
441
+
379
442
  /** `str(obj.get("ts", ""))` — the timestamp is read as a string before parsing. */
380
443
  function _rawStr(v: unknown): string {
381
444
  if (v === undefined) {
@@ -424,7 +487,15 @@ export function record_spend(
424
487
  usd: number,
425
488
  provider: string,
426
489
  model: string,
427
- options: { path?: string | null; now?: number | null } = {},
490
+ options: {
491
+ path?: string | null;
492
+ now?: number | null;
493
+ // Additive prompt-cache accounting (Step B). Omitting all three
494
+ // reproduces the original 4-field ledger line exactly.
495
+ cache_read_input_tokens?: number;
496
+ cache_creation_input_tokens?: number;
497
+ cache_ttl?: '5m' | '1h';
498
+ } = {},
428
499
  ): boolean {
429
500
  if (usd <= 0) {
430
501
  return true; // zero-cost calls (manual mode) skip the ledger
@@ -435,7 +506,15 @@ export function record_spend(
435
506
  }
436
507
  const nowMs = options.now ?? _nowUtcMs();
437
508
  const ts = nowUtcIso(nowMs);
438
- const entry = `${_dumpEntry(ts, _pyRound6(usd), provider, model)}\n`;
509
+ const entry = `${_dumpEntry(
510
+ ts,
511
+ _pyRound6(usd),
512
+ provider,
513
+ model,
514
+ options.cache_read_input_tokens,
515
+ options.cache_creation_input_tokens,
516
+ options.cache_ttl,
517
+ )}\n`;
439
518
  try {
440
519
  fs.appendFileSync(p, entry, { encoding: 'utf-8' });
441
520
  } catch (exc) {
@@ -263,7 +263,7 @@ export function bundle_diff_with_context(
263
263
  }
264
264
 
265
265
  const root = cwd ? cwd : '.';
266
- const seen = new Set<string>(); // `${file}${signature_line}`
266
+ const seen = new Set<string>(); // `${file}\0${signature_line}`
267
267
  // Preserve insertion order of first-seen files (Python dict order).
268
268
  const byFile = new Map<string, Array<[number, string]>>();
269
269
 
@@ -279,7 +279,7 @@ export function bundle_diff_with_context(
279
279
  if (sig === null) {
280
280
  continue;
281
281
  }
282
- const key = `${filePath}${sig[0]}`;
282
+ const key = `${filePath}\0${sig[0]}`;
283
283
  if (seen.has(key)) {
284
284
  continue;
285
285
  }