@event4u/agent-config 16.2.0 → 16.4.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 (651) hide show
  1. package/.augment-plugin/marketplace.json +3 -3
  2. package/.augment-plugin/plugin.json +1 -1
  3. package/.claude-plugin/marketplace.json +1 -1
  4. package/CHANGELOG.md +337 -234
  5. package/README.md +15 -13
  6. package/agents/templates/.ai-council.yml.example +26 -8
  7. package/dist/agent-src/commands/analyze/inbox.md +11 -8
  8. package/dist/agent-src/commands/analyze/roadmap-repos.md +1 -1
  9. package/dist/agent-src/commands/bug/fix.md +17 -2
  10. package/dist/agent-src/commands/bug/investigate.md +1 -1
  11. package/dist/agent-src/commands/commit/in-chunks.md +40 -31
  12. package/dist/agent-src/commands/commit.md +72 -33
  13. package/dist/agent-src/commands/condense.md +2 -8
  14. package/dist/agent-src/commands/council/debate.md +11 -7
  15. package/dist/agent-src/commands/council/default.md +10 -9
  16. package/dist/agent-src/commands/council.md +1 -1
  17. package/dist/agent-src/commands/estimate-ticket.md +1 -1
  18. package/dist/agent-src/commands/feature/explore.md +3 -3
  19. package/dist/agent-src/commands/feature/plan.md +2 -2
  20. package/dist/agent-src/commands/feature/roadmap.md +1 -1
  21. package/dist/agent-src/commands/fix/ci.md +18 -4
  22. package/dist/agent-src/commands/fix/commit-messages.md +48 -23
  23. package/dist/agent-src/commands/fix/pr-comments.md +3 -6
  24. package/dist/agent-src/commands/implement-ticket.md +4 -4
  25. package/dist/agent-src/commands/jira-ticket.md +1 -1
  26. package/dist/agent-src/commands/memory/add.md +4 -16
  27. package/dist/agent-src/commands/memory/load.md +5 -6
  28. package/dist/agent-src/commands/memory/promote.md +3 -16
  29. package/dist/agent-src/commands/mission/upgrade.md +3 -2
  30. package/dist/agent-src/commands/optimize/agents-dir.md +2 -2
  31. package/dist/agent-src/commands/optimize/deep.md +4 -2
  32. package/dist/agent-src/commands/optimize/rtk.md +4 -26
  33. package/dist/agent-src/commands/pr/create/description-only.md +18 -15
  34. package/dist/agent-src/commands/pr/create.md +42 -34
  35. package/dist/agent-src/commands/pr/merge.md +136 -9
  36. package/dist/agent-src/commands/prepare-for-review.md +13 -11
  37. package/dist/agent-src/commands/project/analyze.md +7 -35
  38. package/dist/agent-src/commands/refine-ticket.md +1 -1
  39. package/dist/agent-src/commands/review/changes.md +14 -19
  40. package/dist/agent-src/commands/roadmap/create.md +1 -1
  41. package/dist/agent-src/commands/roadmap/materialize.md +1 -1
  42. package/dist/agent-src/commands/roadmap/next.md +10 -1
  43. package/dist/agent-src/commands/roadmap/process-full.md +56 -42
  44. package/dist/agent-src/commands/roadmap/resolve-blockers.md +411 -0
  45. package/dist/agent-src/commands/roadmap/triage-parked.md +325 -0
  46. package/dist/agent-src/commands/roadmap.md +18 -4
  47. package/dist/agent-src/commands/tests/create.md +17 -3
  48. package/dist/agent-src/commands/tests/execute.md +22 -5
  49. package/dist/agent-src/commands/worktree/create.md +7 -3
  50. package/dist/agent-src/commands/worktree/verify.md +2 -1
  51. package/dist/agent-src/contexts/authority/decision-revisit-gate-enforcement.md +43 -0
  52. package/dist/agent-src/contexts/communication/rules-auto/design-fidelity-enforcement.md +24 -0
  53. package/dist/agent-src/contexts/communication/rules-auto/think-before-action-mechanics.md +5 -3
  54. package/dist/agent-src/contexts/communication/rules-auto/token-efficiency-mechanics.md +7 -9
  55. package/dist/agent-src/contexts/contracts/command-suggestion-flow.md +8 -6
  56. package/dist/agent-src/contexts/contracts/frugality-charter.md +8 -5
  57. package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +7 -7
  58. package/dist/agent-src/contexts/execution/auto-orchestration-activation.md +0 -1
  59. package/dist/agent-src/contexts/execution/evidence-discipline.md +2 -2
  60. package/dist/agent-src/contexts/execution/non-interactive-contract.md +5 -8
  61. package/dist/agent-src/contexts/execution/rdp-gate.md +4 -4
  62. package/dist/agent-src/contexts/execution/roadmap-execution-contract.md +9 -8
  63. package/dist/agent-src/contexts/execution/roadmap-process-loop.md +99 -54
  64. package/dist/agent-src/contexts/execution/session-canary-enforcement-history.md +67 -0
  65. package/dist/agent-src/contexts/execution/subagent-routing.md +8 -8
  66. package/dist/agent-src/contexts/execution/subagent-steering.md +6 -4
  67. package/dist/agent-src/contexts/execution/terminal-states.md +2 -2
  68. package/dist/agent-src/contexts/execution/toolchain-resolver.md +95 -7
  69. package/dist/agent-src/contexts/subagent-configuration.md +1 -1
  70. package/dist/agent-src/guidelines/agent-infra/active-remediation-mechanics.md +39 -0
  71. package/dist/agent-src/guidelines/agent-infra/context-hygiene-mechanics.md +1 -1
  72. package/dist/agent-src/guidelines/agent-infra/cross-source-consistency-mechanics.md +8 -10
  73. package/dist/agent-src/guidelines/agent-infra/frontier-reasoning-operating-profile.md +3 -2
  74. package/dist/agent-src/guidelines/agent-infra/layered-settings.md +13 -1
  75. package/dist/agent-src/guidelines/agent-infra/roadmap-progress-mechanics.md +1 -1
  76. package/dist/agent-src/guidelines/agent-infra/self-improvement-pipeline.md +10 -3
  77. package/dist/agent-src/guidelines/agent-infra/size-and-scope.md +36 -0
  78. package/dist/agent-src/guidelines/php/git.md +15 -2
  79. package/dist/agent-src/rules/active-remediation.md +1 -2
  80. package/dist/agent-src/rules/analysis-skill-routing.md +0 -1
  81. package/dist/agent-src/rules/architecture.md +0 -1
  82. package/dist/agent-src/rules/artifact-drafting-protocol.md +0 -1
  83. package/dist/agent-src/rules/artifact-engagement-recording.md +0 -1
  84. package/dist/agent-src/rules/augment-edit-discipline.md +0 -1
  85. package/dist/agent-src/rules/autonomous-execution.md +1 -1
  86. package/dist/agent-src/rules/brand-consistency.md +0 -1
  87. package/dist/agent-src/rules/brand-source-of-truth.md +0 -1
  88. package/dist/agent-src/rules/broken-access-control.md +1 -1
  89. package/dist/agent-src/rules/cli-output-handling.md +0 -1
  90. package/dist/agent-src/rules/code-comment-discipline.md +0 -1
  91. package/dist/agent-src/rules/code-provenance.md +0 -1
  92. package/dist/agent-src/rules/command-suggestion-policy.md +1 -1
  93. package/dist/agent-src/rules/commit-conventions.md +1 -2
  94. package/dist/agent-src/rules/communication-through-line.md +1 -2
  95. package/dist/agent-src/rules/content-quoting-floor.md +1 -2
  96. package/dist/agent-src/rules/context-hygiene.md +6 -6
  97. package/dist/agent-src/rules/copilot-routing.md +1 -2
  98. package/dist/agent-src/rules/council-availability.md +4 -4
  99. package/dist/agent-src/rules/cross-source-consistency.md +4 -6
  100. package/dist/agent-src/rules/decision-revisit-gate.md +17 -35
  101. package/dist/agent-src/rules/delegation-policy.md +2 -3
  102. package/dist/agent-src/rules/design-fidelity.md +12 -16
  103. package/dist/agent-src/rules/design-review-after-ui-write.md +3 -3
  104. package/dist/agent-src/rules/devcontainer-routing.md +1 -2
  105. package/dist/agent-src/rules/doc-screenshot-hygiene.md +1 -1
  106. package/dist/agent-src/rules/docker-commands.md +0 -1
  107. package/dist/agent-src/rules/domain-adoption-policy.md +0 -1
  108. package/dist/agent-src/rules/domain-safety-disclaimer.md +1 -1
  109. package/dist/agent-src/rules/domain-safety-pii.md +1 -1
  110. package/dist/agent-src/rules/domain-safety-retention.md +1 -1
  111. package/dist/agent-src/rules/downstream-changes.md +0 -1
  112. package/dist/agent-src/rules/engineering-safety-floor.md +1 -1
  113. package/dist/agent-src/rules/evaluator-independence.md +3 -2
  114. package/dist/agent-src/rules/external-code-graph-interop.md +0 -1
  115. package/dist/agent-src/rules/external-reference-deep-dive.md +0 -1
  116. package/dist/agent-src/rules/fast-path-marker-visibility.md +2 -2
  117. package/dist/agent-src/rules/finance-safety-floor.md +1 -1
  118. package/dist/agent-src/rules/fix-what-you-see.md +6 -32
  119. package/dist/agent-src/rules/framework-neutrality-in-generic-skills.md +0 -1
  120. package/dist/agent-src/rules/git-history-discipline.md +2 -2
  121. package/dist/agent-src/rules/guidelines.md +0 -1
  122. package/dist/agent-src/rules/history-discipline.md +0 -1
  123. package/dist/agent-src/rules/icon-consistency.md +0 -1
  124. package/dist/agent-src/rules/image-likeness-and-rights.md +1 -1
  125. package/dist/agent-src/rules/improve-before-implement.md +0 -1
  126. package/dist/agent-src/rules/invite-challenge.md +0 -1
  127. package/dist/agent-src/rules/laravel-routing.md +1 -2
  128. package/dist/agent-src/rules/laravel-translations.md +0 -1
  129. package/dist/agent-src/rules/legal-safety-floor.md +3 -3
  130. package/dist/agent-src/rules/lethal-trifecta-guard.md +1 -1
  131. package/dist/agent-src/rules/linked-projects-onboarding-gate.md +0 -1
  132. package/dist/agent-src/rules/low-impact-corpus-privacy-floor.md +1 -1
  133. package/dist/agent-src/rules/markdown-safe-codeblocks.md +0 -1
  134. package/dist/agent-src/rules/media-governance-routing.md +13 -17
  135. package/dist/agent-src/rules/media-sync-ground-truth.md +0 -1
  136. package/dist/agent-src/rules/minimal-safe-diff.md +0 -1
  137. package/dist/agent-src/rules/missing-skill-recovery.md +0 -1
  138. package/dist/agent-src/rules/missing-tool-handling.md +0 -1
  139. package/dist/agent-src/rules/model-recommendation.md +0 -1
  140. package/dist/agent-src/rules/neighbour-precedence.md +64 -0
  141. package/dist/agent-src/rules/no-attribution-footers.md +0 -1
  142. package/dist/agent-src/rules/no-decorative-emojis-in-git-surfaces.md +0 -1
  143. package/dist/agent-src/rules/no-pr-progress-comments.md +0 -1
  144. package/dist/agent-src/rules/no-roadmap-references.md +0 -1
  145. package/dist/agent-src/rules/notes-first-reasoning.md +0 -1
  146. package/dist/agent-src/rules/onboarding-gate.md +0 -1
  147. package/dist/agent-src/rules/output-discipline.md +0 -1
  148. package/dist/agent-src/rules/package-ci-checks.md +0 -1
  149. package/dist/agent-src/rules/persona-governance.md +4 -5
  150. package/dist/agent-src/rules/php-coding.md +0 -1
  151. package/dist/agent-src/rules/prefer-enums-over-literals.md +0 -1
  152. package/dist/agent-src/rules/preservation-guard.md +0 -1
  153. package/dist/agent-src/rules/provider-lifecycle-discipline.md +3 -4
  154. package/dist/agent-src/rules/question-not-instruction.md +1 -1
  155. package/dist/agent-src/rules/reviewer-awareness.md +0 -1
  156. package/dist/agent-src/rules/roadmap-ci-steps-policy.md +0 -1
  157. package/dist/agent-src/rules/roadmap-progress-sync.md +4 -7
  158. package/dist/agent-src/rules/role-mode-adherence.md +0 -1
  159. package/dist/agent-src/rules/rule-type-governance.md +0 -1
  160. package/dist/agent-src/rules/runtime-safety.md +1 -1
  161. package/dist/agent-src/rules/scale-discipline.md +0 -1
  162. package/dist/agent-src/rules/secret-vcs-guard.md +1 -1
  163. package/dist/agent-src/rules/security-sensitive-stop.md +3 -3
  164. package/dist/agent-src/rules/self-repair-loop.md +0 -1
  165. package/dist/agent-src/rules/senior-engineering-discipline.md +0 -1
  166. package/dist/agent-src/rules/session-canary.md +7 -62
  167. package/dist/agent-src/rules/settings-ask-protocol.md +6 -6
  168. package/dist/agent-src/rules/size-enforcement.md +0 -1
  169. package/dist/agent-src/rules/skill-improvement-trigger.md +2 -3
  170. package/dist/agent-src/rules/skill-quality.md +0 -1
  171. package/dist/agent-src/rules/slash-command-routing-policy.md +0 -1
  172. package/dist/agent-src/rules/source-confidentiality.md +1 -1
  173. package/dist/agent-src/rules/source-discovery-gate.md +0 -1
  174. package/dist/agent-src/rules/source-of-truth.md +0 -1
  175. package/dist/agent-src/rules/spreadsheet-source-quality.md +1 -2
  176. package/dist/agent-src/rules/strategy-safety-floor.md +1 -1
  177. package/dist/agent-src/rules/symfony-routing.md +1 -2
  178. package/dist/agent-src/rules/think-before-action.md +0 -1
  179. package/dist/agent-src/rules/token-budget-discipline.md +12 -46
  180. package/dist/agent-src/rules/token-efficiency.md +0 -1
  181. package/dist/agent-src/rules/token-optimizer-maintenance.md +0 -1
  182. package/dist/agent-src/rules/tool-safety.md +1 -1
  183. package/dist/agent-src/rules/ui-audit-gate.md +1 -2
  184. package/dist/agent-src/rules/untrusted-input-defense.md +1 -1
  185. package/dist/agent-src/rules/upstream-proposal.md +0 -1
  186. package/dist/agent-src/rules/user-interaction.md +0 -1
  187. package/dist/agent-src/rules/user-interrupt-priority.md +1 -1
  188. package/dist/agent-src/scripts/archive_completed_roadmaps.ts +115 -20
  189. package/dist/agent-src/scripts/deferral_carry.ts +339 -0
  190. package/dist/agent-src/scripts/gate_budget.ts +47 -23
  191. package/dist/agent-src/scripts/gate_execute.ts +12 -4
  192. package/dist/agent-src/scripts/update_roadmap_progress.ts +4 -1
  193. package/dist/agent-src/skills/ai-council/SKILL.md +7 -4
  194. package/dist/agent-src/skills/ai-council/references/cost-and-redaction.md +21 -11
  195. package/dist/agent-src/skills/ai-council/references/procedure.md +12 -6
  196. package/dist/agent-src/skills/analysis-autonomous-mode/SKILL.md +1 -1
  197. package/dist/agent-src/skills/api-design/data/manifest.json +2 -2
  198. package/dist/agent-src/skills/api-testing/SKILL.md +17 -0
  199. package/dist/agent-src/skills/bug-analyzer/SKILL.md +1 -1
  200. package/dist/agent-src/skills/code-intelligence/SKILL.md +14 -2
  201. package/dist/agent-src/skills/command-routing/SKILL.md +3 -4
  202. package/dist/agent-src/skills/conventional-commits-writing/SKILL.md +127 -139
  203. package/dist/agent-src/skills/corpus-grounding/ATTRIBUTION.md +39 -0
  204. package/dist/agent-src/skills/corpus-grounding/SKILL.md +8 -2
  205. package/dist/agent-src/skills/database/data/manifest.json +2 -2
  206. package/dist/agent-src/skills/database/data/query-tuning.csv +13 -13
  207. package/dist/agent-src/skills/design-system-capture/SKILL.md +0 -3
  208. package/dist/agent-src/skills/design-system-capture/references/import-procedure.md +1 -1
  209. package/dist/agent-src/skills/estimate-ticket/SKILL.md +1 -1
  210. package/dist/agent-src/skills/existing-ui-audit/SKILL.md +2 -2
  211. package/dist/agent-src/skills/fe-design/SKILL.md +1 -1
  212. package/dist/agent-src/skills/feature-planning/SKILL.md +1 -1
  213. package/dist/agent-src/skills/git-workflow/SKILL.md +44 -44
  214. package/dist/agent-src/skills/git-workflow/references/branch-update.md +312 -0
  215. package/dist/agent-src/skills/git-workflow/references/commit-subject.md +205 -0
  216. package/dist/agent-src/skills/iconography/SKILL.md +1 -1
  217. package/dist/agent-src/skills/jira-integration/SKILL.md +3 -3
  218. package/dist/agent-src/skills/js-library-packaging/SKILL.md +2 -2
  219. package/dist/agent-src/skills/merge-conflicts/SKILL.md +10 -4
  220. package/dist/agent-src/skills/monorepo-workspace/SKILL.md +1 -1
  221. package/dist/agent-src/skills/po-discovery/SKILL.md +1 -1
  222. package/dist/agent-src/skills/quality-tools/SKILL.md +11 -1
  223. package/dist/agent-src/skills/quality-tools/references/go-tools.md +76 -0
  224. package/dist/agent-src/skills/quality-tools/references/python-tools.md +104 -0
  225. package/dist/agent-src/skills/refine-ticket/SKILL.md +4 -4
  226. package/dist/agent-src/skills/review-routing/SKILL.md +2 -2
  227. package/dist/agent-src/skills/roadmap-writing/SKILL.md +2 -2
  228. package/dist/agent-src/skills/skill-improvement-pipeline/SKILL.md +5 -3
  229. package/dist/agent-src/skills/source-discovery/SKILL.md +1 -1
  230. package/dist/agent-src/skills/storybook-workshop/SKILL.md +3 -3
  231. package/dist/agent-src/skills/tailwind-engineer/SKILL.md +4 -2
  232. package/dist/agent-src/skills/test-case-discovery/SKILL.md +7 -0
  233. package/dist/agent-src/skills/test-driven-development/SKILL.md +17 -0
  234. package/dist/agent-src/skills/test-performance/SKILL.md +19 -1
  235. package/dist/agent-src/skills/testing-anti-patterns/SKILL.md +1 -1
  236. package/dist/agent-src/skills/ui-component-architect/SKILL.md +2 -2
  237. package/dist/agent-src/skills/using-git-worktrees/SKILL.md +1 -1
  238. package/dist/agent-src/skills/verify-repair-loop/SKILL.md +2 -2
  239. package/dist/agent-src/templates/AGENTS.md +1 -1
  240. package/dist/agent-src/templates/agent-settings.md +46 -129
  241. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +3 -3
  242. package/dist/agent-src/templates/command.md +2 -2
  243. package/dist/agent-src/templates/roadmaps.md +6 -1
  244. package/dist/agent-src/templates/scripts/work_engine/_lib/agent_settings.ts +0 -6
  245. package/dist/agent-src/templates/scripts/work_engine/directives/backend/_self_fix.ts +11 -7
  246. package/dist/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +48 -6
  247. package/dist/agent-src/templates/scripts/work_engine/hooks/builtin/decision_trace.ts +3 -2
  248. package/dist/agent-src/templates/scripts/work_engine/hooks/builtin/memory_visibility.ts +2 -1
  249. package/dist/agent-src/templates/scripts/work_engine/hooks/settings.ts +0 -6
  250. package/dist/agent-src/templates/scripts/work_engine/scoring/decision_engine.ts +9 -12
  251. package/dist/agent-src/templates/scripts/work_engine/scoring/memory_visibility.ts +2 -1
  252. package/dist/agent-src/templates/scripts/work_engine/stack/runner.ts +774 -109
  253. package/dist/agent-src/templates/skill.md +1 -1
  254. package/dist/cli/registry.js +2 -1
  255. package/dist/cli-delegate/archive_completed_roadmaps.js +92 -12
  256. package/dist/cli-delegate/check_update_banner.js +207 -120
  257. package/dist/cli-delegate/chunk-523HCFYO.js +90 -0
  258. package/dist/cli-delegate/{chunk-FP36SWJD.js → chunk-5GPULQBE.js} +2797 -338
  259. package/dist/cli-delegate/{chunk-IGD6ERX6.js → chunk-6SRJTYJS.js} +42 -176
  260. package/dist/cli-delegate/chunk-6V5FMA3P.js +186 -0
  261. package/dist/cli-delegate/{chunk-M2DPGFZ4.js → chunk-6V6TA25H.js} +22 -152
  262. package/dist/cli-delegate/chunk-6YQC2HLF.js +415 -0
  263. package/dist/cli-delegate/{chunk-E4XIZDIB.js → chunk-7HKRE54K.js} +1 -64
  264. package/dist/cli-delegate/chunk-7IQE3D5S.js +191 -0
  265. package/dist/cli-delegate/{chunk-YJ72UIAK.js → chunk-AED2VQGM.js} +1245 -249
  266. package/dist/cli-delegate/{chunk-7HQ52DHU.js → chunk-AL3RZ22D.js} +1 -1
  267. package/dist/cli-delegate/chunk-DEIV7XP7.js +108 -0
  268. package/dist/cli-delegate/{chunk-DBH4AHDK.js → chunk-ED7KCMLB.js} +9 -11
  269. package/dist/cli-delegate/chunk-F3QDG2GT.js +2569 -0
  270. package/dist/cli-delegate/{chunk-6KFEC3G7.js → chunk-G5VVIZRC.js} +3 -3
  271. package/dist/cli-delegate/{chunk-FC75PGJE.js → chunk-H76PHZBI.js} +149 -61
  272. package/dist/cli-delegate/chunk-IAYTIIQW.js +67 -0
  273. package/dist/cli-delegate/chunk-JQOM7TTM.js +1201 -0
  274. package/dist/cli-delegate/chunk-KB5FZ655.js +208 -0
  275. package/dist/cli-delegate/{chunk-7RQP4UDH.js → chunk-KR6EM23A.js} +235 -1455
  276. package/dist/cli-delegate/{chunk-LTYVIY76.js → chunk-KXXWJTDO.js} +6 -11
  277. package/dist/cli-delegate/{chunk-T7L2QK3K.js → chunk-LQOCRFWT.js} +1 -1
  278. package/dist/cli-delegate/{chunk-6KM6ORRY.js → chunk-MDPPKQCQ.js} +58 -9
  279. package/dist/cli-delegate/{chunk-4XFP2Y3E.js → chunk-MSUL5NYP.js} +5 -5
  280. package/dist/cli-delegate/chunk-OAFSJBHH.js +272 -0
  281. package/dist/cli-delegate/{chunk-4E2W63DA.js → chunk-OKJUIAPS.js} +62 -1
  282. package/dist/cli-delegate/{chunk-QAJS5YWY.js → chunk-PHD7OOLE.js} +2 -1
  283. package/dist/cli-delegate/{chunk-P6ZHP5W2.js → chunk-PWX7CKMD.js} +4 -4
  284. package/dist/cli-delegate/{chunk-NDJLNC6Q.js → chunk-T6BP34WI.js} +1 -0
  285. package/dist/cli-delegate/{chunk-7XGBX6ZH.js → chunk-T7XSJSUQ.js} +1144 -589
  286. package/dist/cli-delegate/chunk-ULQRUR23.js +208 -0
  287. package/dist/cli-delegate/chunk-WQWXGIWB.js +1779 -0
  288. package/dist/cli-delegate/{chunk-RGNIWTEA.js → chunk-XQTPXKFA.js} +1 -1
  289. package/dist/cli-delegate/{chunk-NUHLI2RX.js → chunk-YCU3TIXH.js} +2 -0
  290. package/dist/cli-delegate/chunk-ZBZV2G5R.js +210 -0
  291. package/dist/cli-delegate/{chunk-WGXTVKCQ.js → chunk-ZUZKZYCN.js} +5 -3
  292. package/dist/cli-delegate/cmd_analyze_session.js +223 -43
  293. package/dist/cli-delegate/cmd_brand_status.js +3 -2
  294. package/dist/cli-delegate/cmd_conformance.js +1252 -249
  295. package/dist/cli-delegate/cmd_converge.js +3 -3
  296. package/dist/cli-delegate/cmd_doctor.js +19 -9
  297. package/dist/cli-delegate/cmd_doctor_neighbours.js +30 -0
  298. package/dist/cli-delegate/cmd_explain.js +45 -21
  299. package/dist/cli-delegate/cmd_export.js +13 -10
  300. package/dist/cli-delegate/cmd_fleet.js +3 -3
  301. package/dist/cli-delegate/cmd_git_convention.js +1851 -0
  302. package/dist/cli-delegate/cmd_handoff.js +44 -22
  303. package/dist/cli-delegate/cmd_mcp_available.js +3 -2
  304. package/dist/cli-delegate/cmd_memory_get.js +3 -1
  305. package/dist/cli-delegate/cmd_migrate.js +3 -3
  306. package/dist/cli-delegate/cmd_packs_active.js +5 -4
  307. package/dist/cli-delegate/cmd_preflight.js +6 -6
  308. package/dist/cli-delegate/cmd_prune.js +14 -11
  309. package/dist/cli-delegate/cmd_refresh.js +2 -1
  310. package/dist/cli-delegate/cmd_route_audit.js +10 -8
  311. package/dist/cli-delegate/cmd_route_explain.js +4 -4
  312. package/dist/cli-delegate/cmd_session_recycle.js +10 -7
  313. package/dist/cli-delegate/cmd_settings_check.js +54 -7
  314. package/dist/cli-delegate/cmd_settings_get.js +18 -8
  315. package/dist/cli-delegate/cmd_settings_migrate.js +13 -10
  316. package/dist/cli-delegate/cmd_settings_set.js +4 -4
  317. package/dist/cli-delegate/cmd_sync.js +14 -11
  318. package/dist/cli-delegate/cmd_uninstall.js +15 -12
  319. package/dist/cli-delegate/cmd_update.js +7 -7
  320. package/dist/cli-delegate/cmd_upgrade.js +9 -8
  321. package/dist/cli-delegate/cmd_validate.js +15 -12
  322. package/dist/cli-delegate/cmd_versions.js +5 -5
  323. package/dist/cli-delegate/deferral_carry.js +16 -0
  324. package/dist/cli-delegate/gate_budget.js +1 -1
  325. package/dist/cli-delegate/gate_execute.js +3 -3
  326. package/dist/cli-delegate/roadmap_gates.js +6 -6
  327. package/dist/cli-delegate/update_roadmap_progress.js +1 -1
  328. package/dist/discovery/deprecation-report.md +1 -1
  329. package/dist/discovery/discovery-manifest.json +232 -141
  330. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  331. package/dist/discovery/discovery-manifest.summary.md +3 -3
  332. package/dist/discovery/dormancy-report.md +1 -1
  333. package/dist/discovery/orphan-report.md +1 -1
  334. package/dist/discovery/packs.json +26 -9
  335. package/dist/discovery/trust-report.md +3 -3
  336. package/dist/discovery/workspaces.json +7 -4
  337. package/dist/hooks/dispatch.js +5655 -6623
  338. package/dist/hooks/dispatch.sha256 +1 -1
  339. package/dist/install/claudePathsPlan.js +47 -6
  340. package/dist/install/claudeRuleRewrite.js +7 -0
  341. package/dist/install/emit_host_rules_cli.js +39 -36
  342. package/dist/install/globalRuleScope.js +87 -0
  343. package/dist/install/host_rule_ownership.js +160 -0
  344. package/dist/install/install.mjs +2336 -1249
  345. package/dist/install/installThinLayer.js +289 -0
  346. package/dist/install/installedRuleLinks.js +262 -0
  347. package/dist/install/wizard-plan.js +24 -0
  348. package/dist/mcp/awesome-mcp-servers.row.md +1 -1
  349. package/dist/mcp/mcp-cloudflare-catalogue.json +2 -2
  350. package/dist/mcp/registry-manifest.json +5 -5
  351. package/dist/mcp/server.json +2 -2
  352. package/dist/mcp/server.mjs +36504 -30986
  353. package/dist/router.json +1 -1
  354. package/dist/scripts/_lib/agent_settings.js +26 -120
  355. package/dist/scripts/_lib/claude_settings_hooks.js +10 -8
  356. package/dist/scripts/_lib/compile_time_toggles.js +12 -21
  357. package/dist/scripts/_lib/git_convention.js +232 -0
  358. package/dist/scripts/_lib/global_deploy_inventory.js +730 -0
  359. package/dist/scripts/_lib/installed_layer.js +704 -0
  360. package/dist/scripts/_lib/lean_projection_mode.js +218 -15
  361. package/dist/scripts/_lib/package_root.js +68 -0
  362. package/dist/scripts/_lib/rule_consequence_class.js +45 -0
  363. package/dist/scripts/_lib/rule_injection.js +67 -10
  364. package/dist/scripts/_lib/rule_law_section.js +122 -0
  365. package/dist/scripts/_lib/settings_removed_keys.js +168 -0
  366. package/dist/scripts/_lib/thin_rules.js +535 -0
  367. package/dist/scripts/_lib/windsurf_render.js +60 -0
  368. package/dist/scripts/condense.js +14 -26
  369. package/dist/scripts/project_thin_rules.js +14 -294
  370. package/dist/server/app.js +2 -1
  371. package/dist/server/gitKeysGate.js +105 -0
  372. package/dist/server/routes/settings.js +67 -8
  373. package/dist/server/routes/wizard.js +4 -0
  374. package/dist/server/schemas/settings.js +29 -81
  375. package/dist/shared/skillRanking.js +103 -16
  376. package/dist/ui/assets/{index-Cwq4d0hX.js → index-C3djEJah.js} +2 -2
  377. package/dist/ui/index.html +1 -1
  378. package/docs/MIGRATION.md +72 -1
  379. package/docs/contracts/settings-classes.md +39 -67
  380. package/docs/guidelines/agent-infra/active-remediation-mechanics.md +39 -0
  381. package/docs/guidelines/agent-infra/context-hygiene-mechanics.md +1 -1
  382. package/docs/guidelines/agent-infra/cross-source-consistency-mechanics.md +8 -10
  383. package/docs/guidelines/agent-infra/frontier-reasoning-operating-profile.md +3 -2
  384. package/docs/guidelines/agent-infra/layered-settings.md +13 -1
  385. package/docs/guidelines/agent-infra/roadmap-progress-mechanics.md +1 -1
  386. package/docs/guidelines/agent-infra/self-improvement-pipeline.md +10 -3
  387. package/docs/guidelines/agent-infra/size-and-scope.md +36 -0
  388. package/docs/guidelines/php/git.md +15 -2
  389. package/package.json +1 -1
  390. package/src/agent-src/scripts/archive_completed_roadmaps.ts +115 -20
  391. package/src/agent-src/scripts/deferral_carry.ts +339 -0
  392. package/src/agent-src/scripts/gate_budget.ts +47 -23
  393. package/src/agent-src/scripts/gate_execute.ts +12 -4
  394. package/src/agent-src/scripts/update_roadmap_progress.ts +4 -1
  395. package/src/agent-src/templates/AGENTS.md +1 -1
  396. package/src/agent-src/templates/scripts/work_engine/_lib/agent_settings.ts +0 -6
  397. package/src/agent-src/templates/scripts/work_engine/directives/backend/_self_fix.ts +11 -7
  398. package/src/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +48 -6
  399. package/src/agent-src/templates/scripts/work_engine/hooks/builtin/decision_trace.ts +3 -2
  400. package/src/agent-src/templates/scripts/work_engine/hooks/builtin/memory_visibility.ts +2 -1
  401. package/src/agent-src/templates/scripts/work_engine/hooks/settings.ts +0 -6
  402. package/src/agent-src/templates/scripts/work_engine/scoring/decision_engine.ts +9 -12
  403. package/src/agent-src/templates/scripts/work_engine/scoring/memory_visibility.ts +2 -1
  404. package/src/agent-src/templates/scripts/work_engine/stack/runner.ts +774 -109
  405. package/src/config/agent-settings.template.yml +141 -334
  406. package/src/config/agents-paths.yml +16 -0
  407. package/src/config/assurance-capability-registry.json +7 -3
  408. package/src/config/ci-local-parity.yml +3 -0
  409. package/src/config/continuity-surface.json +10 -3
  410. package/src/config/discovery/packs.yml +17 -1
  411. package/src/config/evaluator-budgets.json +23 -10
  412. package/src/config/gate-coverage.yml +138 -3
  413. package/src/config/gate-violation-baselines.json +64 -16
  414. package/src/config/gitignore-block.txt +19 -0
  415. package/src/config/hook-bundle-budget.json +25 -0
  416. package/src/config/hook-token-budget.json +6 -1
  417. package/src/config/host-instruction-limits.json +33 -0
  418. package/src/config/release-gate-locality.yml +2 -1
  419. package/src/config/routing-coverage-seed.json +67 -4
  420. package/src/config/rule-activation-census.json +7 -3
  421. package/src/config/rule-consequence-class.json +161 -0
  422. package/src/config/rule-law-ceilings.json +105 -0
  423. package/src/config/rule-obligations.json +833 -0
  424. package/src/install/claudePathsPlan.ts +46 -4
  425. package/src/install/claudeRuleRewrite.ts +10 -1
  426. package/src/install/emit_host_rules_cli.ts +43 -34
  427. package/src/install/globalRuleScope.ts +109 -0
  428. package/src/install/host_rule_ownership.ts +170 -0
  429. package/src/install/installThinLayer.ts +378 -0
  430. package/src/install/installedRuleLinks.ts +308 -0
  431. package/src/install/wizard-plan.ts +24 -0
  432. package/src/scripts/_cli/cmd_analyze_session.ts +9 -15
  433. package/src/scripts/_cli/cmd_conformance.ts +13 -2
  434. package/src/scripts/_cli/cmd_doctor.ts +33 -81
  435. package/src/scripts/_cli/cmd_doctor_neighbours.ts +426 -0
  436. package/src/scripts/_cli/cmd_explain.ts +72 -14
  437. package/src/scripts/_cli/cmd_git_convention.ts +637 -0
  438. package/src/scripts/_cli/cmd_settings_check.ts +66 -8
  439. package/src/scripts/_cli/cmd_settings_get.ts +18 -3
  440. package/src/scripts/_cli/doctor_execution.ts +72 -1
  441. package/src/scripts/_dispatch.bash +53 -4
  442. package/src/scripts/_lib/agent_settings.ts +26 -124
  443. package/src/scripts/_lib/blocked_by_marker.ts +1 -1
  444. package/src/scripts/_lib/claude_settings_hooks.ts +10 -8
  445. package/src/scripts/_lib/compile_time_toggles.ts +12 -21
  446. package/src/scripts/_lib/dispatch_import_closure.ts +163 -0
  447. package/src/scripts/_lib/estate_offsets.ts +241 -0
  448. package/src/scripts/_lib/exemption_shape.ts +143 -0
  449. package/src/scripts/_lib/fnv.ts +23 -0
  450. package/src/scripts/_lib/foreign_scan.ts +106 -0
  451. package/src/scripts/_lib/git_base_ref.ts +92 -0
  452. package/src/scripts/_lib/git_convention.ts +291 -0
  453. package/src/scripts/_lib/git_convention_carrier.ts +389 -0
  454. package/src/scripts/_lib/git_convention_grammar.ts +246 -0
  455. package/src/scripts/_lib/git_convention_measure.ts +344 -0
  456. package/src/scripts/_lib/gitignore_block.ts +314 -0
  457. package/src/scripts/_lib/global_deploy_inventory.ts +106 -0
  458. package/src/scripts/_lib/graph_feeder_record.ts +437 -0
  459. package/src/scripts/_lib/hook_settings.ts +73 -0
  460. package/src/scripts/_lib/host_capability.ts +40 -19
  461. package/src/scripts/_lib/host_hook_merge.ts +165 -0
  462. package/src/scripts/_lib/installed_layer.ts +963 -0
  463. package/src/scripts/_lib/json_merge.ts +82 -0
  464. package/src/scripts/_lib/json_pointers.ts +93 -11
  465. package/src/scripts/_lib/knowledge_global.ts +14 -1
  466. package/src/scripts/_lib/lean_projection_mode.ts +275 -15
  467. package/src/scripts/_lib/machine_wake.ts +16 -3
  468. package/src/scripts/_lib/module_reach.ts +456 -0
  469. package/src/scripts/_lib/neighbour_census.ts +760 -0
  470. package/src/scripts/_lib/neighbour_contradictions.ts +236 -0
  471. package/src/scripts/_lib/neighbour_scan.ts +122 -0
  472. package/src/scripts/_lib/neighbour_tool_use.ts +187 -0
  473. package/src/scripts/_lib/prompt_shape.ts +46 -0
  474. package/src/scripts/_lib/ratification_artifact.ts +220 -1
  475. package/src/scripts/_lib/ratification_subject.ts +92 -0
  476. package/src/scripts/_lib/release_findings_ingest.ts +15 -7
  477. package/src/scripts/_lib/release_highlights.ts +5 -0
  478. package/src/scripts/_lib/release_migration_gate.ts +19 -3
  479. package/src/scripts/_lib/reserved_name_sweep.ts +73 -0
  480. package/src/scripts/_lib/review_coverage.ts +134 -0
  481. package/src/scripts/_lib/rule_consequence_class.ts +71 -0
  482. package/src/scripts/_lib/rule_injection.ts +130 -10
  483. package/src/scripts/_lib/rule_law_section.ts +147 -0
  484. package/src/scripts/_lib/rule_layer_overlap.ts +58 -0
  485. package/src/scripts/_lib/rule_obligations.ts +205 -0
  486. package/src/scripts/_lib/self_repair.ts +1 -1
  487. package/src/scripts/_lib/settings_removed_keys.ts +173 -0
  488. package/src/scripts/_lib/skill_origin.ts +254 -0
  489. package/src/scripts/_lib/structured_ask.ts +64 -21
  490. package/src/scripts/_lib/test_red_state.ts +5 -0
  491. package/src/scripts/_lib/thin_rules.ts +620 -0
  492. package/src/scripts/_lib/touched_file_quality.ts +570 -0
  493. package/src/scripts/_lib/turn_end_refusals.ts +77 -2
  494. package/src/scripts/_lib/windsurf_render.ts +63 -0
  495. package/src/scripts/_lib/worker_budget.ts +1 -1
  496. package/src/scripts/adr/regenerate_index.ts +16 -1
  497. package/src/scripts/ai_council/cli_call_budget.ts +13 -5
  498. package/src/scripts/ai_council/clients.ts +26 -57
  499. package/src/scripts/ai_council/config.ts +8 -8
  500. package/src/scripts/ai_council/modification_review.ts +100 -0
  501. package/src/scripts/ai_council/modification_review_questions.ts +90 -0
  502. package/src/scripts/ai_council/orchestrator.ts +5 -5
  503. package/src/scripts/ai_council/spend_gate.ts +18 -7
  504. package/src/scripts/ai_council/vendor_defaults.ts +45 -0
  505. package/src/scripts/ai_team/config.ts +11 -16
  506. package/src/scripts/audit_skill_overlap.ts +261 -0
  507. package/src/scripts/audit_user_type_axis.ts +20 -8
  508. package/src/scripts/before_complete_hook.ts +243 -12
  509. package/src/scripts/bench_ab_clone.ts +1 -2
  510. package/src/scripts/bench_concern_spawn_path.ts +129 -0
  511. package/src/scripts/bench_graph_feeder_latency.ts +584 -0
  512. package/src/scripts/bench_touched_file_quality.ts +238 -0
  513. package/src/scripts/check_agent_artifact_location.ts +36 -0
  514. package/src/scripts/check_branch_freshness.ts +147 -24
  515. package/src/scripts/check_enforcement_coverage.ts +130 -0
  516. package/src/scripts/check_enforcement_matrix.ts +377 -20
  517. package/src/scripts/check_estate_count.ts +130 -153
  518. package/src/scripts/check_evaluator_budgets.ts +4 -0
  519. package/src/scripts/check_finding_dispositions.ts +196 -21
  520. package/src/scripts/check_gate_coverage.ts +4 -3
  521. package/src/scripts/check_gate_reachability.ts +48 -1
  522. package/src/scripts/check_generator_sync.ts +48 -0
  523. package/src/scripts/check_hook_bundle_composition.ts +477 -0
  524. package/src/scripts/check_kernel_edit_ratified.ts +132 -14
  525. package/src/scripts/check_memory.ts +7 -1
  526. package/src/scripts/check_pack_size.ts +1 -1
  527. package/src/scripts/check_release_highlights.ts +10 -0
  528. package/src/scripts/check_release_manifest_content.ts +189 -0
  529. package/src/scripts/check_release_pr_shape.ts +38 -15
  530. package/src/scripts/check_standing_rule_delivery.ts +129 -13
  531. package/src/scripts/check_suppression_hygiene.ts +2 -5
  532. package/src/scripts/check_verify_expectation_delta.ts +521 -0
  533. package/src/scripts/ci_settle.ts +42 -5
  534. package/src/scripts/classify_merge_risk.ts +320 -0
  535. package/src/scripts/closure_scan.ts +91 -1
  536. package/src/scripts/code_graph/detect.ts +127 -7
  537. package/src/scripts/code_graph/foreign.ts +194 -0
  538. package/src/scripts/code_graph/query.ts +217 -4
  539. package/src/scripts/code_graph/types.ts +26 -2
  540. package/src/scripts/code_graph/validate.ts +3 -1
  541. package/src/scripts/code_graph/verbs.ts +103 -0
  542. package/src/scripts/command_suggester/settings.ts +8 -108
  543. package/src/scripts/command_suggester/types.ts +4 -5
  544. package/src/scripts/compile_hook_manifest.ts +33 -1
  545. package/src/scripts/condense.ts +14 -27
  546. package/src/scripts/consumer_matrix.ts +102 -0
  547. package/src/scripts/context_hygiene_hook.ts +13 -23
  548. package/src/scripts/cost/preflight.mjs +12 -1
  549. package/src/scripts/council_cli.ts +7 -7
  550. package/src/scripts/dispatch_r2_reviewer.ts +24 -11
  551. package/src/scripts/estate_exemption_shape.ts +202 -0
  552. package/src/scripts/explain_run.ts +8 -13
  553. package/src/scripts/generate_git_convention_grammar.ts +127 -0
  554. package/src/scripts/generate_host_cost_table.ts +21 -4
  555. package/src/scripts/handoff_context_hook.ts +86 -37
  556. package/src/scripts/hook_manifest.json +1 -1
  557. package/src/scripts/hook_manifest.yaml +175 -15
  558. package/src/scripts/hooks/block_config_weakening.ts +115 -7
  559. package/src/scripts/hooks/block_plumbing_writes.ts +37 -5
  560. package/src/scripts/hooks/code_graph_context_hook.ts +252 -23
  561. package/src/scripts/hooks/concern_failure_policy.ts +280 -0
  562. package/src/scripts/hooks/concern_registry.ts +2 -0
  563. package/src/scripts/hooks/delegation_nudge_hook.ts +2 -3
  564. package/src/scripts/hooks/dispatch_hook.ts +52 -52
  565. package/src/scripts/hooks/evidence_independence.ts +12 -4
  566. package/src/scripts/hooks/exit_codes.ts +2 -1
  567. package/src/scripts/hooks/host_lowering.json +1 -1
  568. package/src/scripts/hooks/host_lowering.ts +19 -1
  569. package/src/scripts/hooks/mcp_usage_observation_hook.ts +121 -0
  570. package/src/scripts/hooks/one_question_per_ask_hook.ts +41 -25
  571. package/src/scripts/hooks/payload_stub.ts +10 -1
  572. package/src/scripts/hooks/push_settle_hook.ts +4 -3
  573. package/src/scripts/hooks/rule_inject_hook.ts +795 -60
  574. package/src/scripts/hooks/state_io.ts +8 -4
  575. package/src/scripts/hooks/table_fingerprint.ts +21 -0
  576. package/src/scripts/hooks/telemetry_usage_hook.ts +24 -7
  577. package/src/scripts/hooks/turn_end_gate_hook.ts +85 -0
  578. package/src/scripts/hooks_status.ts +112 -0
  579. package/src/scripts/injection_scan_hook.ts +7 -0
  580. package/src/scripts/install-hooks.sh +42 -14
  581. package/src/scripts/install.ts +78 -215
  582. package/src/scripts/installed_layer_report.ts +103 -0
  583. package/src/scripts/language_mirror_hook.ts +15 -6
  584. package/src/scripts/learning_sidecar.ts +119 -8
  585. package/src/scripts/lint_blocker_citations.ts +198 -0
  586. package/src/scripts/lint_evidence_artifacts.ts +9 -0
  587. package/src/scripts/lint_hook_concern_budget.ts +10 -21
  588. package/src/scripts/lint_hook_manifest.ts +53 -0
  589. package/src/scripts/lint_major_migration_sections.ts +156 -26
  590. package/src/scripts/lint_pack_boundaries.ts +465 -29
  591. package/src/scripts/lint_roadmap_blockers.ts +282 -29
  592. package/src/scripts/lint_roadmap_complexity.ts +4 -2
  593. package/src/scripts/lint_rule_law_section.ts +647 -0
  594. package/src/scripts/lint_rule_skill_pack_reach.ts +17 -0
  595. package/src/scripts/lint_settings_classes.ts +1 -1
  596. package/src/scripts/lint_ticked_unmet_criteria.ts +165 -0
  597. package/src/scripts/lint_workflow_security.ts +173 -6
  598. package/src/scripts/mcp_server/consumer_tool_catalog.json +53 -0
  599. package/src/scripts/mcp_server/graph_tools.ts +72 -3
  600. package/src/scripts/measure_routing_signal.ts +54 -16
  601. package/src/scripts/measure_skill_ranker_baseline.ts +221 -8
  602. package/src/scripts/memory_learn_hook.ts +91 -6
  603. package/src/scripts/model_rule_injection.ts +55 -8
  604. package/src/scripts/onboarding_gate_hook.ts +7 -6
  605. package/src/scripts/print_required_checks.ts +15 -3
  606. package/src/scripts/probe_host_compliance.ts +33 -5
  607. package/src/scripts/probe_turnaround.ts +183 -3
  608. package/src/scripts/project_thin_rules.ts +34 -327
  609. package/src/scripts/ratification_header.ts +77 -0
  610. package/src/scripts/refusal_envelope.ts +138 -0
  611. package/src/scripts/release_publication.ts +29 -3
  612. package/src/scripts/report_dispatch_import_closure.ts +76 -0
  613. package/src/scripts/report_evidence_temperature.ts +657 -0
  614. package/src/scripts/report_installed_rule_links.ts +274 -0
  615. package/src/scripts/report_label_agreement.ts +233 -0
  616. package/src/scripts/report_module_reach.ts +212 -0
  617. package/src/scripts/report_obligation_mechanism.ts +228 -0
  618. package/src/scripts/report_parked_blockers.ts +222 -0
  619. package/src/scripts/report_required_checks_drift.ts +196 -0
  620. package/src/scripts/report_single_token_triggers.ts +277 -0
  621. package/src/scripts/report_skill_ranker_confusion.ts +543 -0
  622. package/src/scripts/report_standing_payload_by_host.ts +188 -15
  623. package/src/scripts/report_verification_record_coverage.ts +306 -0
  624. package/src/scripts/routing_doctor.ts +2 -2
  625. package/src/scripts/rule_activation_census.ts +5 -2
  626. package/src/scripts/rule_trigger_eval.ts +9 -9
  627. package/src/scripts/schemas/agent-settings.schema.json +17 -31
  628. package/src/scripts/schemas/command.schema.json +1 -1
  629. package/src/scripts/schemas/review-findings.schema.json +3 -2
  630. package/src/scripts/schemas/rule.schema.json +5 -0
  631. package/src/scripts/schemas/skill.schema.json +1 -1
  632. package/src/scripts/self_review_gate.ts +101 -9
  633. package/src/scripts/skill_tools/score_skill_relevance.ts +314 -40
  634. package/src/scripts/sweep_skill_ranker_signals.ts +129 -0
  635. package/src/scripts/sync_gitignore.ts +29 -235
  636. package/src/scripts/sync_pr_branch.ts +403 -132
  637. package/src/scripts/trigger_eval_grandfather.json +0 -21
  638. package/src/server/schemas/settings.ts +42 -176
  639. package/src/shared/skillRanking.ts +169 -14
  640. package/dist/cli-delegate/chunk-5R7HOLAF.js +0 -99
  641. package/dist/cli-delegate/chunk-JNMVLWLR.js +0 -4457
  642. package/dist/cli-delegate/chunk-YDPILCOL.js +0 -152
  643. package/src/scripts/_lib/config_chain.ts +0 -477
  644. package/src/scripts/_lib/conformance_report.ts +0 -403
  645. package/src/scripts/_lib/eval_discrimination.ts +0 -95
  646. package/src/scripts/_lib/evaluator_promotion.ts +0 -225
  647. package/src/scripts/_lib/file_slicer.ts +0 -117
  648. package/src/scripts/_lib/legacy_boundary_map.ts +0 -228
  649. package/src/scripts/_lib/minimality_tiebreak.ts +0 -168
  650. package/src/scripts/_lib/overbuild_lens_contract.ts +0 -196
  651. package/src/scripts/_lib/role_split.ts +0 -338
@@ -0,0 +1,236 @@
1
+ /**
2
+ * Contradiction review between a project's instructions and its neighbours'
3
+ * (road-to-neighbours-that-pull-their-weight step 2.2).
4
+ *
5
+ * REPORT-ONLY. Nothing here edits, gates or suppresses an instruction — the
6
+ * output is a table a human reads. `neighbour-precedence` (step 2.1) is the
7
+ * rubric: the "which wins" column is its source order applied to the two
8
+ * sources, computed here, and the verdict column is one council seat's reading
9
+ * of whether the pair actually disagrees.
10
+ *
11
+ * NO STATIC DETECTOR DECIDES ANYTHING. A static contradiction detector was
12
+ * measured at 67 % false positives (`docs/contracts/rule-interactions.md`), so
13
+ * this module only FORMS candidate pairs, and only from strong signals: a
14
+ * shared subject word with opposite modality, or a skill name collision the
15
+ * census already found. Whether a candidate is a contradiction is the seat's
16
+ * call, never this file's.
17
+ *
18
+ * A neighbour body the shape scan refused (step 1.3) is never read here: the
19
+ * caller passes only scanned sources, and a refused body contributes no line.
20
+ */
21
+ import * as fs from 'node:fs';
22
+
23
+ /** Rank in `neighbour-precedence`'s source order — lower wins. */
24
+ export const RANK_PROJECT = 3;
25
+ export const RANK_SUITE = 4;
26
+ export const RANK_NEIGHBOUR_ALWAYS_ON = 6;
27
+ export const RANK_NEIGHBOUR_SKILL = 7;
28
+
29
+ const RANK_LABEL: Record<number, string> = {
30
+ [RANK_PROJECT]: 'project instruction file',
31
+ [RANK_SUITE]: "this suite's routed guidance",
32
+ [RANK_NEIGHBOUR_ALWAYS_ON]: "neighbour's always-on text",
33
+ [RANK_NEIGHBOUR_SKILL]: 'neighbour skill body (discoverable)',
34
+ };
35
+
36
+ export interface InstructionSource {
37
+ /** Where the text came from, as printed. */
38
+ label: string;
39
+ file: string;
40
+ rank: number;
41
+ }
42
+
43
+ export interface InstructionLine {
44
+ source: InstructionSource;
45
+ line: number;
46
+ text: string;
47
+ negative: boolean;
48
+ stems: Set<string>;
49
+ }
50
+
51
+ export interface CandidatePair {
52
+ kind: 'opposite-modality' | 'name-collision';
53
+ a: { label: string; rank: number; text: string };
54
+ b: { label: string; rank: number; text: string };
55
+ /** The shared subject word, or the colliding name. */
56
+ subject: string;
57
+ }
58
+
59
+ export type Verdict = 'contradiction' | 'compatible' | 'unclear';
60
+
61
+ const NEGATION = /\b(never|don't|do not|must not|mustn't|should not|shouldn't|avoid|stop)\b/iu;
62
+ const DIRECTIVE_WORD = /\b(always|must|should|never|don't|do not|avoid)\b/iu;
63
+ const NON_IMPERATIVE_START = new Set([
64
+ 'the', 'a', 'an', 'this', 'that', 'these', 'those', 'it', 'its', 'we', 'you', 'i', 'our',
65
+ 'they', 'there', 'when', 'if', 'see', 'for', 'in', 'on', 'as', 'by', 'with', 'from',
66
+ ]);
67
+ const STOP = new Set([
68
+ 'always', 'never', 'must', 'should', 'avoid', 'stop', 'don', 'with', 'without', 'that', 'this',
69
+ 'they', 'them', 'then', 'than', 'into', 'from', 'your', 'when', 'what', 'will', 'each', 'every',
70
+ 'only', 'also', 'here', 'there', 'have', 'been', 'more', 'some', 'such', 'like', 'just',
71
+ ]);
72
+
73
+ /** A crude stem — enough to meet `wait` and `waiting`, never a lemmatiser. */
74
+ export function stem(word: string): string {
75
+ let w = word.toLowerCase().replace(/[^a-z]/gu, '');
76
+ for (const suffix of ['ing', 'ed', 'es', 's']) {
77
+ if (w.length > suffix.length + 3 && w.endsWith(suffix)) {
78
+ w = w.slice(0, -suffix.length);
79
+ break;
80
+ }
81
+ }
82
+ return w;
83
+ }
84
+
85
+ /** Is this line phrased as an instruction at all? */
86
+ export function isDirective(text: string): boolean {
87
+ if (DIRECTIVE_WORD.test(text)) return true;
88
+ const first = (text.split(/\s+/u)[0] ?? '').toLowerCase().replace(/[^a-z']/gu, '');
89
+ return first.length > 0 && !NON_IMPERATIVE_START.has(first);
90
+ }
91
+
92
+ /** Directive lines of one markdown source, outside fences and frontmatter. */
93
+ export function extractInstructions(source: InstructionSource, body?: string): InstructionLine[] {
94
+ let text: string;
95
+ try {
96
+ text = body ?? fs.readFileSync(source.file, 'utf-8');
97
+ } catch {
98
+ return [];
99
+ }
100
+ const out: InstructionLine[] = [];
101
+ let fenced = false;
102
+ let frontmatter = false;
103
+ text.split('\n').forEach((raw, i) => {
104
+ const line = raw.trim();
105
+ if (i === 0 && line === '---') {
106
+ frontmatter = true;
107
+ return;
108
+ }
109
+ if (frontmatter) {
110
+ if (line === '---') frontmatter = false;
111
+ return;
112
+ }
113
+ if (line.startsWith('```') || line.startsWith('~~~')) {
114
+ fenced = !fenced;
115
+ return;
116
+ }
117
+ if (fenced || line === '' || line.startsWith('#') || line.startsWith('|') || line.startsWith('>')) return;
118
+ const clean = line.replace(/^([-*+]|\d+\.)\s+/u, '').replace(/[*_`]/gu, '');
119
+ if (clean.split(/\s+/u).length < 3 || !isDirective(clean)) return;
120
+ const stems = new Set(
121
+ clean
122
+ .split(/\s+/u)
123
+ .map(stem)
124
+ .filter((s) => s.length >= 4 && !STOP.has(s)),
125
+ );
126
+ out.push({ source, line: i + 1, text: clean, negative: NEGATION.test(clean), stems });
127
+ });
128
+ return out;
129
+ }
130
+
131
+ function where(l: InstructionLine): string {
132
+ return `${l.source.label}:${l.line}`;
133
+ }
134
+
135
+ /**
136
+ * Candidate pairs from opposite modality over a shared subject word.
137
+ *
138
+ * Only ACROSS ranks — two lines of one source rank are one author's
139
+ * contradiction, which is not what this review is for — and only where one
140
+ * side is negative and the other is not. One pair per line pair, naming the
141
+ * first shared stem in sorted order so the output is stable.
142
+ */
143
+ export function modalityPairs(lines: readonly InstructionLine[], cap = 20): CandidatePair[] {
144
+ const out: CandidatePair[] = [];
145
+ for (let i = 0; i < lines.length && out.length < cap; i += 1) {
146
+ for (let j = i + 1; j < lines.length && out.length < cap; j += 1) {
147
+ const x = lines[i] as InstructionLine;
148
+ const y = lines[j] as InstructionLine;
149
+ if (x.source.rank === y.source.rank || x.negative === y.negative) continue;
150
+ const shared = [...x.stems].filter((s) => y.stems.has(s)).sort();
151
+ if (shared.length === 0) continue;
152
+ const [hi, lo] = x.source.rank <= y.source.rank ? [x, y] : [y, x];
153
+ out.push({
154
+ kind: 'opposite-modality',
155
+ a: { label: where(hi), rank: hi.source.rank, text: hi.text },
156
+ b: { label: where(lo), rank: lo.source.rank, text: lo.text },
157
+ subject: shared[0] as string,
158
+ });
159
+ }
160
+ }
161
+ return out;
162
+ }
163
+
164
+ /** A neighbour skill that shares a name with one of ours — the census's `shadowed`. */
165
+ export function collisionPair(neighbourQualified: string, ourName: string): CandidatePair {
166
+ return {
167
+ kind: 'name-collision',
168
+ a: { label: `suite:${ourName}`, rank: RANK_SUITE, text: `this suite's skill \`${ourName}\`` },
169
+ b: {
170
+ label: neighbourQualified,
171
+ rank: RANK_NEIGHBOUR_SKILL,
172
+ text: `neighbour skill \`${neighbourQualified}\``,
173
+ },
174
+ subject: ourName,
175
+ };
176
+ }
177
+
178
+ /** "Which wins by 2.1" — the lower rank, named. */
179
+ export function winnerBy21(p: CandidatePair): string {
180
+ const w = p.a.rank <= p.b.rank ? p.a : p.b;
181
+ return `${w.label} (rank ${w.rank}, ${RANK_LABEL[w.rank] ?? 'unranked'})`;
182
+ }
183
+
184
+ /** The single-seat prompt. States no expected verdict (evaluator-independence). */
185
+ export function seatPrompt(pairs: readonly CandidatePair[], rubric: string): string {
186
+ const rows = pairs.map(
187
+ (p, i) => `PAIR ${i + 1} (${p.kind}, subject "${p.subject}")\n A [${p.a.label}]: ${p.a.text}\n B [${p.b.label}]: ${p.b.text}`,
188
+ );
189
+ return [
190
+ '# Neighbour contradiction review',
191
+ '',
192
+ 'For each pair, decide whether A and B give an agent instructions that cannot both be followed.',
193
+ 'Answer one line per pair, exactly `PAIR <n>: contradiction`, `PAIR <n>: compatible` or `PAIR <n>: unclear`,',
194
+ 'then at most one sentence of reason on the same line. The rubric for which source wins is below; you do not',
195
+ 'need to restate it.',
196
+ '',
197
+ '## Rubric — neighbour-precedence',
198
+ '',
199
+ rubric.trim(),
200
+ '',
201
+ '## Pairs',
202
+ '',
203
+ ...rows,
204
+ '',
205
+ ].join('\n');
206
+ }
207
+
208
+ /** Read `PAIR <n>: <verdict>` lines; a pair the seat did not answer is `unclear`. */
209
+ export function parseVerdicts(text: string, count: number): Verdict[] {
210
+ const out: Verdict[] = Array.from({ length: count }, () => 'unclear');
211
+ for (const m of text.matchAll(/PAIR\s+(\d+)\s*:\s*(contradiction|compatible|unclear)/giu)) {
212
+ const n = Number(m[1]) - 1;
213
+ if (n >= 0 && n < count) out[n] = (m[2] ?? 'unclear').toLowerCase() as Verdict;
214
+ }
215
+ return out;
216
+ }
217
+
218
+ export interface ReviewRow {
219
+ pair: string;
220
+ verdict: Verdict;
221
+ wins: string;
222
+ }
223
+
224
+ /** The table, from pairs and a seat's verdicts. */
225
+ export function reviewRows(pairs: readonly CandidatePair[], verdicts: readonly Verdict[]): ReviewRow[] {
226
+ return pairs.map((p, i) => ({
227
+ pair: `${p.a.label} "${p.a.text}" × ${p.b.label} "${p.b.text}"`,
228
+ verdict: verdicts[i] ?? 'unclear',
229
+ wins: winnerBy21(p),
230
+ }));
231
+ }
232
+
233
+ export function renderReview(rows: readonly ReviewRow[]): string[] {
234
+ if (rows.length === 0) return [' no candidate pairs — nothing to review'];
235
+ return [' pair | verdict | which wins by 2.1', ...rows.map((r) => ` ${r.pair} | ${r.verdict} | ${r.wins}`)];
236
+ }
@@ -0,0 +1,122 @@
1
+ /**
2
+ * The shape scan a neighbour skill body passes before any of it may be indexed.
3
+ *
4
+ * SCAN BEFORE INJECT. A foreign `SKILL.md` is a file another package put on
5
+ * disk, and the ranker reaches it through the catalogue union. Nothing about
6
+ * being in `~/.claude/skills` makes its prose safe to fold into a term index
7
+ * whose output names skills to a model — the body is untrusted content in the
8
+ * sense `untrusted-input-defense` means it, and the floor here is the same one
9
+ * that rule states: it is data until something has looked at it.
10
+ *
11
+ * THE SHAPES ARE THE ONES THIS SUITE ALREADY SCANS ITS OWN CORPUS WITH. Four
12
+ * `security_lint` checks, reused as functions rather than re-implemented
13
+ * (decision D3 of the lane): instruction smuggling, hidden Unicode, mixed-script
14
+ * confusables and dangerous frontmatter. Re-declaring their patterns here would
15
+ * create a second copy to drift against the first, and the first is the one CI
16
+ * keeps honest.
17
+ *
18
+ * ANY FINDING REFUSES THE BODY — severity is NOT the discriminator. In the
19
+ * corpus linters, `HIGH` fails a build and `MED` warns, because the corpus is
20
+ * this package's own prose and a warning there is a maintainer's to weigh. A
21
+ * neighbour body is nobody's to weigh at rank time, and the cost of refusing is
22
+ * known and small: the skill still RANKS, by its name, with the finding kind
23
+ * printed. Risk-register row 4 is exactly this trade and resolves the same way —
24
+ * a shell snippet can be an installer skill's whole point, so the skill is never
25
+ * hidden, only un-indexed.
26
+ *
27
+ * WHY THIS IS NOT IMPORTED BY THE RANKER. It pulls four linter modules and,
28
+ * through one of them, `node:child_process`. The ranker runs inside the shared
29
+ * hook bundle on `user_prompt_submit`, where every byte is paid by every concern
30
+ * on every dispatch and `check_hook_bundle_composition` holds the ceiling. So
31
+ * the scan runs in the census CLI and its verdict reaches the ranker as a cached
32
+ * record — see `neighbour_census.scanVerdict`, where a missing record is a
33
+ * refusal rather than a pass.
34
+ */
35
+ import * as fs from 'node:fs';
36
+ import * as path from 'node:path';
37
+
38
+ import * as sl from './security_lint.js';
39
+ import { fileDigest, type ScanCache, type ScanRecord } from './skill_origin.js';
40
+ import { _scan as scanSmuggling } from '../lint_instruction_smuggling.js';
41
+ import { _scan as scanHiddenUnicode } from '../lint_hidden_unicode.js';
42
+ import { _scan as scanConfusables } from '../lint_confusables.js';
43
+ import { _scan as scanFrontmatter } from '../lint_skill_frontmatter_safety.js';
44
+
45
+ /** The shape checks, in the order their findings are reported. */
46
+ const SHAPES: ReadonlyArray<readonly [string, (sf: sl.ScannedFile) => sl.Finding[]]> = [
47
+ ['instruction-smuggling', scanSmuggling],
48
+ ['dangerous-frontmatter', scanFrontmatter],
49
+ ['hidden-unicode', scanHiddenUnicode],
50
+ ['mixed-script-confusable', scanConfusables],
51
+ ];
52
+
53
+ export interface ScanResult {
54
+ /** `null` when every shape passed; otherwise the first finding's check id. */
55
+ kind: string | null;
56
+ /** Every finding, for a report that wants more than the first kind. */
57
+ findings: sl.Finding[];
58
+ }
59
+
60
+ /**
61
+ * Scan one `SKILL.md`.
62
+ *
63
+ * An unreadable file is a refusal, not a pass (`unreadable`): a body nobody
64
+ * could open is in exactly the state this gate exists to keep out of the index,
65
+ * and returning `kind: null` for it would make an IO error look like a clean
66
+ * scan. A THROWING check is reported under its own id rather than swallowed, for
67
+ * the same reason.
68
+ */
69
+ export function scanNeighbourBody(skillMdPath: string): ScanResult {
70
+ let sf: sl.ScannedFile;
71
+ try {
72
+ sf = sl.scan_file(skillMdPath);
73
+ } catch {
74
+ return { kind: 'unreadable', findings: [] };
75
+ }
76
+ const findings: sl.Finding[] = [];
77
+ for (const [id, scan] of SHAPES) {
78
+ try {
79
+ findings.push(...scan(sf));
80
+ } catch {
81
+ findings.push(
82
+ new sl.Finding(sf.rel, 0, id, 'HIGH', 'shape check threw on this body', 1.0),
83
+ );
84
+ }
85
+ }
86
+ return { kind: findings.length === 0 ? null : (findings[0] as sl.Finding).check, findings };
87
+ }
88
+
89
+ /**
90
+ * Record what the scan found, for the ranker to read on the hook path.
91
+ *
92
+ * The digest is the FILE's, not the finding's: the ranker re-digests the body it
93
+ * is about to index and compares, so a body edited after its scan reads as
94
+ * `digest-changed` and goes back to name-only ranking until the census runs
95
+ * again. That compare is the whole mechanism behind "a changed digest rescans
96
+ * first" — without it a one-time pass would keep clearing a file forever.
97
+ *
98
+ * A write failure is reported to the caller rather than thrown: the scan is
99
+ * correct either way, and a read-only report directory must not fail a census.
100
+ */
101
+ export function writeScanCache(file: string, entries: readonly ScanRecord[]): boolean {
102
+ const payload: ScanCache = {
103
+ schema_version: 1,
104
+ entries: [...entries].sort((a, b) => (a.qualified < b.qualified ? -1 : 1)),
105
+ };
106
+ try {
107
+ fs.mkdirSync(path.dirname(file), { recursive: true });
108
+ fs.writeFileSync(file, `${JSON.stringify(payload, null, 2)}\n`, 'utf-8');
109
+ return true;
110
+ } catch {
111
+ return false;
112
+ }
113
+ }
114
+
115
+ /** A `ScanRecord` for one file, digest included. */
116
+ export function scanRecordFor(qualified: string, skillMdPath: string): ScanRecord {
117
+ return {
118
+ qualified,
119
+ digest: fileDigest(skillMdPath) ?? '',
120
+ unscanned: scanNeighbourBody(skillMdPath).kind,
121
+ };
122
+ }
@@ -0,0 +1,187 @@
1
+ /**
2
+ * The foreign-MCP-tool-name store: one writer on the post-tool hook path, one
3
+ * reader in the neighbour census.
4
+ *
5
+ * WHY A MODULE OF ITS OWN, AND NOT A CONSTANT IN EITHER SIDE. The writer lives
6
+ * in `hooks/mcp_usage_observation_hook.ts`, which is inlined into the shared hook
7
+ * bundle `check_hook_bundle_composition` caps; the reader lives in
8
+ * `_lib/neighbour_census.ts`, which is not. Putting the pair here lets esbuild
9
+ * tree-shake {@link toolsUsedByServer} out of the hook bundle while both sides
10
+ * still name one path — a constant copied into two files is a store that
11
+ * silently splits in two the first time one copy is edited.
12
+ *
13
+ * WHAT IS RECORDED, AND WHAT IS NOT. One map of `mcp__<server>__<tool>` to the
14
+ * ISO date it was last seen. No arguments, no responses, no session id, no
15
+ * project path beyond the file's own location. The names recorded are names the
16
+ * consumer's own `.mcp.json` already lists, and the file is written under
17
+ * `agents/runtime/`, which is gitignored and local-only — nothing here is sent
18
+ * anywhere, and no transport reads it.
19
+ *
20
+ * NOT GATED ON THE TELEMETRY OPT-IN, DELIBERATELY. `telemetry_usage_hook`'s
21
+ * Class-A capture is default-off because it feeds an outbound spool. This store
22
+ * feeds `doctor neighbours`, a local report the consumer runs on their own tree.
23
+ * Gating it on an org telemetry switch would make the census print `0` on every
24
+ * install that never enabled one — a number that looks like a measurement and is
25
+ * an instrumentation artifact, which is the exact failure the usage hook's own
26
+ * header records from the collector it replaced.
27
+ *
28
+ * GROWTH, DECLARED (scale-discipline R-A7). The store is a map keyed by tool
29
+ * NAME, not an append log: one entry per distinct `mcp__…` name the consumer
30
+ * has ever called, each rewritten in place at most once per day. The bound is
31
+ * therefore the size of the neighbour's tool surface — tens of entries, not a
32
+ * series — so it needs no TTL job. The reader applies the window; entries older
33
+ * than it stay on disk and stop counting, which is why a stale entry is inert
34
+ * rather than wrong.
35
+ */
36
+ import * as fs from 'node:fs';
37
+ import * as path from 'node:path';
38
+
39
+ /** Host-side prefix of every MCP tool name: `mcp__<server>__<tool>`. */
40
+ export const MCP_TOOL_PREFIX = 'mcp__';
41
+
42
+ /**
43
+ * The store, relative to the project root. Gitignored; see the header.
44
+ *
45
+ * A literal with forward slashes rather than `path.join`, and the reason is
46
+ * measured rather than stylistic: `path.join` here is a top-level call, so the
47
+ * `node:path` namespace import survives into the hook bundle even though every
48
+ * function in this module that needs it is tree-shaken out of that bundle.
49
+ * `path.join(root, REL)` at each call site normalises the separator on Windows,
50
+ * so the only thing lost is the authoring convention.
51
+ */
52
+ export const FOREIGN_TOOL_USE_REL = 'agents/runtime/neighbour-tool-use.json';
53
+
54
+ /** The census window. 30 days, matching the step that asked for the number. */
55
+ export const TOOL_USE_WINDOW_DAYS = 30;
56
+
57
+ /** The filename the writer's root is the directory of. */
58
+ const SETTINGS_FILENAME = '.agent-settings.yml';
59
+
60
+ /** `YYYY-MM-DD` in UTC — the granularity the store keys on. */
61
+ export function usageDay(now: Date): string {
62
+ return now.toISOString().slice(0, 10);
63
+ }
64
+
65
+ const DAY_RE = /^\d{4}-\d{2}-\d{2}$/u;
66
+
67
+ /**
68
+ * Is this store value a day the window comparison can be trusted on?
69
+ *
70
+ * The comparison is lexicographic, which is exactly right for `YYYY-MM-DD` and
71
+ * quietly wrong for anything else: `'TODO'`, `'unknown'` and `'hand edited'`
72
+ * all sort ABOVE a real cutoff, so without this check a hand-edited or
73
+ * half-written store inflates the count instead of being ignored. The reader's
74
+ * promise is that a malformed store yields nothing, and a malformed VALUE is
75
+ * the likelier half of that.
76
+ */
77
+ export function isUsageDay(value: unknown): value is string {
78
+ return typeof value === 'string' && DAY_RE.test(value);
79
+ }
80
+
81
+ /**
82
+ * The `.mcp.json` key as it appears inside a tool name.
83
+ *
84
+ * Hosts sanitise the key before embedding it — a server registered as
85
+ * `claude.ai Claude Docs` arrives as `mcp__claude_ai_Claude_Docs__…`. Normalising
86
+ * BOTH sides the same way is what keeps a matched count from quietly being a
87
+ * zero: an exact-key match would report `0` for every server whose name carries
88
+ * a dot or a space, which reads as "never used" rather than as "never matched".
89
+ */
90
+ export function serverSegment(key: string): string {
91
+ return key.replace(/[^A-Za-z0-9_-]/gu, '_');
92
+ }
93
+
94
+ /**
95
+ * Does `tool` belong to the server whose sanitised key is `segment`?
96
+ *
97
+ * Driven by the KNOWN segment rather than by parsing the tool name, and that
98
+ * direction is the whole correctness argument. Parsing — split at the first
99
+ * `__` after the prefix — is ambiguous exactly where {@link serverSegment} is
100
+ * lossy: `Acme Inc. Tools` sanitises to `Acme_Inc__Tools`, whose own name
101
+ * contains the separator, so a parser reads the server as `Acme_Inc` and the
102
+ * census reports `0` for a server in daily use. That is the same never-matched
103
+ * zero `serverSegment` exists to prevent, reintroduced one layer down. Matching
104
+ * against the keys `.mcp.json` actually lists cannot be ambiguous, because the
105
+ * candidate set is finite and known.
106
+ */
107
+ export function toolBelongsTo(tool: string, segment: string): boolean {
108
+ if (!tool.startsWith(MCP_TOOL_PREFIX)) return false;
109
+ const rest = tool.slice(MCP_TOOL_PREFIX.length);
110
+ return rest === segment || rest.startsWith(`${segment}__`);
111
+ }
112
+
113
+ /**
114
+ * The directory the store lives under, from any directory inside the project.
115
+ *
116
+ * Both the writer and the reader call this one function, so the store is
117
+ * rooted at the directory holding `.agent-settings.yml` on both sides: a
118
+ * session started in a subdirectory would otherwise scatter one store per
119
+ * directory, and a monorepo with settings at the repo root and `.mcp.json`
120
+ * under `packages/web` would read `0` for a server in daily use. A fixture
121
+ * still pins the two sides equal end to end.
122
+ *
123
+ * No settings file on any ancestor → `start`.
124
+ */
125
+ export function resolveStoreRoot(start: string): string {
126
+ let dir = path.resolve(start);
127
+ for (;;) {
128
+ try {
129
+ if (fs.statSync(path.join(dir, SETTINGS_FILENAME)).isFile()) return dir;
130
+ } catch {
131
+ // Not here — keep walking.
132
+ }
133
+ const parent = path.dirname(dir);
134
+ if (parent === dir) return path.resolve(start);
135
+ dir = parent;
136
+ }
137
+ }
138
+
139
+ /**
140
+ * Distinct tools seen per server inside the window, keyed by server segment.
141
+ *
142
+ * `segments` is the closed candidate set — the sanitised `.mcp.json` keys. Every
143
+ * one of them appears in the result, so a server with no sightings reads `0`
144
+ * rather than being absent. Longest segment wins where one is a prefix of
145
+ * another, so a tool is counted once.
146
+ *
147
+ * A missing, unreadable or malformed store yields all-zero — true of what was
148
+ * observed. It does not mean the server was unused, and the census says so next
149
+ * to the number.
150
+ */
151
+ export function toolsUsedByServer(
152
+ projectRoot: string,
153
+ now: Date,
154
+ segments: Iterable<string>,
155
+ ): Map<string, number> {
156
+ const known = [...new Set(segments)].sort((a, b) => b.length - a.length);
157
+ const counts = new Map<string, number>(known.map((s) => [s, 0]));
158
+ if (known.length === 0) return counts;
159
+
160
+ let decoded: unknown;
161
+ try {
162
+ const root = resolveStoreRoot(projectRoot);
163
+ decoded = JSON.parse(fs.readFileSync(path.join(root, FOREIGN_TOOL_USE_REL), 'utf-8'));
164
+ } catch {
165
+ return counts;
166
+ }
167
+ if (typeof decoded !== 'object' || decoded === null || Array.isArray(decoded)) return counts;
168
+
169
+ const today = usageDay(now);
170
+ // Inclusive of both ends, so the span is WINDOW days and not WINDOW+1: a
171
+ // floor computed at `now - 30d` would count 31 distinct days under a field
172
+ // named `tools_used_30d`.
173
+ const floor = usageDay(new Date(now.getTime() - (TOOL_USE_WINDOW_DAYS - 1) * 86_400_000));
174
+
175
+ for (const [tool, seen] of Object.entries(decoded as Record<string, unknown>)) {
176
+ // A future date is as much a sign of a bad write as a malformed one,
177
+ // and without the upper bound a single `9999-01-01` counts forever.
178
+ if (!isUsageDay(seen) || seen < floor || seen > today) continue;
179
+ for (const segment of known) {
180
+ if (toolBelongsTo(tool, segment)) {
181
+ counts.set(segment, (counts.get(segment) ?? 0) + 1);
182
+ break;
183
+ }
184
+ }
185
+ }
186
+ return counts;
187
+ }
@@ -41,6 +41,50 @@
41
41
  * over-filtering would silently stop pinning real prompts, which is worse.
42
42
  * Measured across 1 540 user-role entries: 509 open at character zero with a
43
43
  * marker, and in 0 of them does human text survive wrapper removal.
44
+ *
45
+ * `<agent-message` added 2026-10-03, by the same under-filtering it warns
46
+ * about: a subagent hand-back reaches this slot as `<agent-message from="…">`,
47
+ * and 12 of the 153 hook-sourced user records in this project's capture open
48
+ * with it. It pinned a German session to `en`, after which the turn-end gate
49
+ * refused each German reply — a reply language derived from a frame nobody
50
+ * typed. Its literal stops before the `>` because the element carries an
51
+ * attribute; the anchor at character zero is unchanged.
52
+ *
53
+ * **The fourth shape has NO envelope tag, and it is the exception this file's
54
+ * own "structural, not linguistic" rule has to name rather than quietly break.**
55
+ * The host resumes a rate-limited session with a plain sentence —
56
+ * `Your claude.ai usage limit has reset. Continue the task you were working
57
+ * on…` — carrying no element, no bracket and no stamp. 5 of the 153
58
+ * hook-sourced user records in this project's capture open with it. Measured
59
+ * 2026-10-03: it pinned a German session to `en` with `prompt_chars: 148`,
60
+ * which is that sentence's exact length, and every German reply for the rest
61
+ * of the run was then refused by the turn-end gate as wrong-language.
62
+ *
63
+ * Matching prose is what the paragraph above warns against, so what makes this
64
+ * one admissible is stated rather than assumed: it is a FIXED host string, not
65
+ * a linguistic pattern, and the character-zero anchor does the same work a tag
66
+ * would — a human asking *why did I get "Your claude.ai usage limit has
67
+ * reset"* does not open with it. A test pins that direction. If the host ever
68
+ * reworded the sentence this guard would silently stop matching, which is the
69
+ * honest failure mode: it under-filters back to today's behaviour rather than
70
+ * misfiring on a real turn.
71
+ *
72
+ * It is deliberately NOT added to `machine_wake.ts`. There the same
73
+ * misclassification retains an authorization instead of mis-pinning a reply,
74
+ * and a prose match is too weak a warrant for that consequence — see the
75
+ * asymmetry note below, which this is the first real test of.
76
+ *
77
+ * **A SECOND VOCABULARY ANSWERS THIS SAME QUESTION AND THE TWO HAVE DRIFTED.**
78
+ * `_lib/machine_wake.ts`'s `humanTypedThisTurn` guards per-turn STATE on this
79
+ * slot (the git-authorization ledger, the suggestion latch) while this one
80
+ * guards the language pin. As of this change both know `<task-notification>`,
81
+ * `<system-reminder>` and `<agent-message`; only this one knows
82
+ * `[SYSTEM NOTIFICATION` and `<local-command-caveat>`. That asymmetry is NOT
83
+ * obviously a defect and was deliberately left: mistaking a real turn for a
84
+ * machine one costs a mis-pinned reply here and a RETAINED AUTHORIZATION
85
+ * there, so the two sides do not want the same error budget — and
86
+ * `<local-command-caveat>` in particular precedes a real typed prompt. Unify
87
+ * them only with that asymmetry answered, never as tidying.
44
88
  */
45
89
  export function isSyntheticPrompt(prompt: string): boolean {
46
90
  const head = prompt.trimStart().slice(0, 400);
@@ -49,6 +93,8 @@ export function isSyntheticPrompt(prompt: string): boolean {
49
93
  head.startsWith("<task-notification>") ||
50
94
  head.startsWith("<system-reminder>") ||
51
95
  head.startsWith("<local-command-caveat>") ||
96
+ head.startsWith("<agent-message") ||
97
+ head.startsWith("Your claude.ai usage limit has reset") ||
52
98
  /^\[SYSTEM NOTIFICATION\b/.test(head)
53
99
  );
54
100
  }