@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
@@ -96,10 +96,227 @@ export interface RatificationProblem {
96
96
  | 'no-providers'
97
97
  | 'diversity-required'
98
98
  | 'diversity-unverifiable'
99
- | 'bad-effective-after';
99
+ | 'bad-effective-after'
100
+ | 'no-seats'
101
+ | 'malformed-seats'
102
+ | 'bad-seat-provider'
103
+ | 'unknown-seat-verdict'
104
+ | 'seat-dissent'
105
+ | 'providers-exceed-seats'
106
+ | 'header-not-derived';
100
107
  message: string;
101
108
  }
102
109
 
110
+ /** A seat that closed, timed out or was absent at the last round gave no final verdict. */
111
+ export const SEAT_NO_FINAL_VERDICT = 'no-final-verdict';
112
+ export type SeatVerdict = RatificationVerdict | typeof SEAT_NO_FINAL_VERDICT;
113
+ /** Every value a seat's final verdict may take — shared by the writer and the reader. */
114
+ export const SEAT_VERDICTS: readonly string[] = [...RATIFICATION_VERDICTS, SEAT_NO_FINAL_VERDICT];
115
+
116
+ /**
117
+ * A provider id as a seat key: lower-case, no whitespace and no YAML
118
+ * metacharacter, so a rendered header cannot be split or extended by a name
119
+ * and two spellings of one provider cannot collide after normalisation.
120
+ */
121
+ export const SEAT_PROVIDER_RE = /^[a-z0-9][a-z0-9._-]*$/u;
122
+
123
+ export type SeatsReading =
124
+ | { kind: 'absent' }
125
+ | { kind: 'invalid'; problems: RatificationProblem[] }
126
+ | { kind: 'present'; seats: Map<string, SeatVerdict> };
127
+
128
+ /**
129
+ * The `seats:` map — provider id to that seat's FINAL verdict — in source
130
+ * order, which is the order `providers` is derived in.
131
+ *
132
+ * Absent and present-but-unusable are reported apart: a missing key and a
133
+ * `seats:` key that is empty, a scalar, a list, or carries a bad id or verdict
134
+ * are both refusals, with different codes.
135
+ */
136
+ export function readSeats(fm: AdrFrontmatter, text = ''): SeatsReading {
137
+ const duplicates = duplicateSeatKeys(text);
138
+ if (duplicates.length > 0) {
139
+ return {
140
+ kind: 'invalid',
141
+ problems: [
142
+ {
143
+ code: 'bad-seat-provider',
144
+ message: `seat \`${duplicates.join('`, `')}\` is recorded more than once — the parser keeps only the last`,
145
+ },
146
+ ],
147
+ };
148
+ }
149
+ const hasScalar = Object.prototype.hasOwnProperty.call(fm.scalars, 'seats');
150
+ const node = fm.nested['seats'];
151
+ if (node === undefined && !hasScalar) {
152
+ return { kind: 'absent' };
153
+ }
154
+ if (node === undefined || typeof node === 'string' || Array.isArray(node)) {
155
+ return {
156
+ kind: 'invalid',
157
+ problems: [{ code: 'malformed-seats', message: '`seats:` is present but is not a provider-to-verdict map' }],
158
+ };
159
+ }
160
+ const problems: RatificationProblem[] = [];
161
+ const seats = new Map<string, SeatVerdict>();
162
+ for (const [provider, verdict] of Object.entries(node)) {
163
+ if (!SEAT_PROVIDER_RE.test(provider)) {
164
+ problems.push({
165
+ code: 'bad-seat-provider',
166
+ message: `seat key \`${provider}\` is not a provider id (${String(SEAT_PROVIDER_RE)})`,
167
+ });
168
+ continue;
169
+ }
170
+ if (typeof verdict !== 'string' || !SEAT_VERDICTS.includes(verdict.trim())) {
171
+ problems.push({
172
+ code: 'unknown-seat-verdict',
173
+ message: `seat \`${provider}\` records \`${String(verdict)}\`, not one of ${SEAT_VERDICTS.join(', ')}`,
174
+ });
175
+ continue;
176
+ }
177
+ seats.set(provider, verdict.trim() as SeatVerdict);
178
+ }
179
+ if (problems.length === 0 && seats.size === 0) {
180
+ problems.push({ code: 'malformed-seats', message: '`seats:` is present and empty' });
181
+ }
182
+ return problems.length > 0 ? { kind: 'invalid', problems } : { kind: 'present', seats };
183
+ }
184
+
185
+ /** Keys repeated inside the frontmatter `seats:` block, read from the raw text. */
186
+ function duplicateSeatKeys(text: string): string[] {
187
+ if (!text.startsWith('---\n')) return [];
188
+ const end = text.indexOf('\n---\n', 4);
189
+ const lines = text.slice(4, end === -1 ? undefined : end).split('\n');
190
+ const start = lines.findIndex((l) => /^seats:\s*$/u.test(l));
191
+ if (start === -1) return [];
192
+ const seen = new Set<string>();
193
+ const dup = new Set<string>();
194
+ for (const line of lines.slice(start + 1)) {
195
+ if (!/^\s/u.test(line)) break;
196
+ // Compared by the identity a YAML parser would give the key, so a quoted
197
+ // spelling cannot hide a second entry for the same seat.
198
+ const key = line
199
+ .slice(0, line.indexOf(':') === -1 ? undefined : line.indexOf(':'))
200
+ .trim()
201
+ .replace(/^(["'])(.*)\1$/u, '$2')
202
+ .trim();
203
+ if (key === '' || key.startsWith('#')) continue;
204
+ if (seen.has(key)) dup.add(key);
205
+ seen.add(key);
206
+ }
207
+ return [...dup];
208
+ }
209
+
210
+ /**
211
+ * The header a set of seat verdicts supports, and no more.
212
+ *
213
+ * `providers` is every seat that gave a final verdict — a closed seat is not a
214
+ * provider the verdict came from. Any refusing seat makes the verdict `refused`,
215
+ * any non-convergent one `non-convergent`; only when every final seat passed is
216
+ * the verdict passing, and then `ratified` if any seat said so. No final seat at
217
+ * all is `non-convergent`: a review that ended without a verdict did not pass.
218
+ */
219
+ export function deriveRatificationHeader(
220
+ seats: ReadonlyMap<string, SeatVerdict> | Readonly<Record<string, SeatVerdict>>,
221
+ ): { providers: string[]; verdict: RatificationVerdict } {
222
+ const entries = seats instanceof Map ? [...seats.entries()] : Object.entries(seats);
223
+ const final = entries.filter(([, v]) => v !== SEAT_NO_FINAL_VERDICT) as [string, RatificationVerdict][];
224
+ const verdicts = final.map(([, v]) => v);
225
+ let verdict: RatificationVerdict;
226
+ if (verdicts.includes('refused')) {
227
+ verdict = 'refused';
228
+ } else if (final.length === 0 || verdicts.includes('non-convergent')) {
229
+ verdict = 'non-convergent';
230
+ } else {
231
+ verdict = verdicts.includes('ratified') ? 'ratified' : 'confirmed-non-expanding';
232
+ }
233
+ return { providers: final.map(([p]) => p), verdict };
234
+ }
235
+
236
+ /**
237
+ * The `providers:`, `verdict:` and `seats:` frontmatter lines, derived — never
238
+ * typed. Throws on a provider id outside {@link SEAT_PROVIDER_RE}: a name that
239
+ * could carry YAML syntax is refused rather than escaped.
240
+ */
241
+ export function renderRatificationHeader(
242
+ seats: ReadonlyMap<string, SeatVerdict> | Readonly<Record<string, SeatVerdict>>,
243
+ ): string {
244
+ const entries = seats instanceof Map ? [...seats.entries()] : Object.entries(seats);
245
+ for (const [p, v] of entries) {
246
+ if (!SEAT_PROVIDER_RE.test(p)) throw new Error(`not a provider id: ${JSON.stringify(p)}`);
247
+ if (!SEAT_VERDICTS.includes(v)) throw new Error(`not a seat verdict: ${JSON.stringify(v)}`);
248
+ }
249
+ const { providers, verdict } = deriveRatificationHeader(seats);
250
+ return [
251
+ `providers: [${providers.join(', ')}]`,
252
+ `verdict: ${verdict}`,
253
+ 'seats:',
254
+ ...entries.map(([p, v]) => ` ${p}: ${v}`),
255
+ ].join('\n');
256
+ }
257
+
258
+ /**
259
+ * The header claims the seats do not support.
260
+ *
261
+ * `seats:` is required. Optional, it left `providers` and `verdict` free-written
262
+ * for every author who omitted it, which is the defect it exists to close; the
263
+ * round-2 ratification review refused that shape. The gate reads only the
264
+ * artifacts in the diff under review, so an artifact merged before the field
265
+ * existed is never re-read and needs no migration to stay valid.
266
+ *
267
+ * The recorded header must EQUAL the derived one; the two named overclaims get
268
+ * their own codes so a reader sees which one it was.
269
+ */
270
+ function seatProblems(reading: SeatsReading, providers: readonly string[], verdict: string | null): RatificationProblem[] {
271
+ if (reading.kind === 'absent') {
272
+ return [
273
+ {
274
+ code: 'no-seats',
275
+ message:
276
+ 'missing `seats:` — `providers` and `verdict` are derived from the per-seat final ' +
277
+ 'verdicts, never typed (print all three with `ratification_header`)',
278
+ },
279
+ ];
280
+ }
281
+ if (reading.kind === 'invalid') return reading.problems;
282
+ const seats = reading.seats;
283
+ const problems: RatificationProblem[] = [];
284
+ if (verdict !== null && PASSING_VERDICTS.has(verdict)) {
285
+ const dissent = [...seats].filter(([, v]) => v === 'refused' || v === 'non-convergent');
286
+ if (dissent.length > 0) {
287
+ problems.push({
288
+ code: 'seat-dissent',
289
+ message:
290
+ `verdict \`${verdict}\` while ${dissent.map(([p, v]) => `${p} was \`${v}\``).join(', ')} ` +
291
+ 'at the final round — a header cannot say more than its seats said',
292
+ });
293
+ }
294
+ }
295
+ const derived = deriveRatificationHeader(seats);
296
+ const extra = providers.filter((p) => !derived.providers.includes(p));
297
+ if (extra.length > 0) {
298
+ problems.push({
299
+ code: 'providers-exceed-seats',
300
+ message:
301
+ `providers names ${extra.join(', ')}, which gave no final verdict ` +
302
+ `(${String(derived.providers.length)} seat(s) did) — diversity is counted over seats that answered`,
303
+ });
304
+ }
305
+ if (
306
+ problems.length === 0 &&
307
+ (verdict !== derived.verdict || providers.join('\u0000') !== derived.providers.join('\u0000'))
308
+ ) {
309
+ problems.push({
310
+ code: 'header-not-derived',
311
+ message:
312
+ `recorded providers [${providers.join(', ')}] / verdict \`${String(verdict)}\` differ from the ` +
313
+ `header the seats derive: [${derived.providers.join(', ')}] / \`${derived.verdict}\` ` +
314
+ '(print it with `ratification_header`)',
315
+ });
316
+ }
317
+ return problems;
318
+ }
319
+
103
320
  export interface RatificationReading {
104
321
  artifact: RatificationArtifact | null;
105
322
  problems: RatificationProblem[];
@@ -208,6 +425,8 @@ export function readRatification(
208
425
  }
209
426
  }
210
427
 
428
+ problems.push(...seatProblems(readSeats(fm, text), providers, verdict));
429
+
211
430
  // Diversity, against the REQUIRED count.
212
431
  //
213
432
  // Round 1 refused the previous shape: the count came from the user-global
@@ -0,0 +1,92 @@
1
+ /**
2
+ * ratification_subject — the digest a ratification record carries over the
3
+ * gated content it reviewed.
4
+ *
5
+ * `road-to-self-modification-that-a-council-must-pass` step 2.1, the half that
6
+ * does not touch the gate. The record says WHO reviewed; without a digest it
7
+ * does not say WHAT, so a gated file edited after its review still ships under
8
+ * a record that approved something else.
9
+ *
10
+ * WHY IT RE-ASSEMBLES THE LIST RATHER THAN RE-DECIDING IT. The gate's
11
+ * `classifyPaths` returns the kernel rules, hooks and plumbing by name but
12
+ * reports the self surface as a BOOLEAN, so the gated list cannot be read back
13
+ * out of it. This module therefore imports the gate's own path constants and
14
+ * re-assembles — it never restates the membership rule, because a second
15
+ * definition of "gated" is a second thing to keep in step, and the first time
16
+ * the two diverged a file would be reviewed by one and digested by the other.
17
+ *
18
+ * NO BASE DIFF. The digest is over the tree as it stands, so it is the same on
19
+ * a branch and on the merged checkout CI judges — unless the base changed a
20
+ * gated file the change also touches, and then the content that would land is
21
+ * not the content that was reviewed, which is precisely what should move it.
22
+ */
23
+
24
+ import { createHash } from 'node:crypto';
25
+ import * as fs from 'node:fs';
26
+ import * as path from 'node:path';
27
+
28
+ import {
29
+ ANCHOR_PATHS,
30
+ CLOSURE_READER_PATH,
31
+ POLICY_PATH,
32
+ READER_PATH,
33
+ SELF_PATH,
34
+ WORKFLOW_PATH,
35
+ classifyPaths,
36
+ } from '../check_kernel_edit_ratified.js';
37
+
38
+ /**
39
+ * Stands in for the content of a gated file the change deletes. A deleted file
40
+ * is ENTERED, never skipped: skipping would make "this file was removed"
41
+ * digest-identical to "this file was never gated", and removing a governance
42
+ * hook is exactly the change the record most needs to be bound to.
43
+ */
44
+ export const DELETED_MARKER = '\u0000deleted\u0000';
45
+
46
+ /** The self surface, by the gate's own constants rather than a copy of them. */
47
+ const SELF_SET: ReadonlySet<string> = new Set<string>([
48
+ SELF_PATH,
49
+ READER_PATH,
50
+ CLOSURE_READER_PATH,
51
+ POLICY_PATH,
52
+ WORKFLOW_PATH,
53
+ ...ANCHOR_PATHS,
54
+ ]);
55
+
56
+ /**
57
+ * The gated subset of a changed-file list: sorted, deduplicated, and stable
58
+ * against the order the caller happened to collect the paths in.
59
+ */
60
+ export function gatedFilesOf(
61
+ files: readonly string[],
62
+ derived?: readonly string[],
63
+ ): readonly string[] {
64
+ const normalized = files.map((f) => f.replace(/\\/g, '/').trim()).filter((f) => f !== '');
65
+ const g = derived === undefined ? classifyPaths(normalized) : classifyPaths(normalized, derived);
66
+ const out = new Set<string>([...g.kernelRules, ...g.governanceHooks, ...g.plumbing]);
67
+ for (const f of normalized) {
68
+ if (SELF_SET.has(f)) out.add(f);
69
+ }
70
+ return [...out].sort();
71
+ }
72
+
73
+ /**
74
+ * One digest over the sorted paths AND contents of the gated files, read from
75
+ * `root`.
76
+ *
77
+ * The path is hashed alongside its content, so two files with identical bytes
78
+ * do not collide and a rename moves the digest — a gated file moved to another
79
+ * gated path is a different change, not the same one.
80
+ */
81
+ export function subjectDigest(root: string, files: readonly string[]): string {
82
+ const h = createHash('sha256');
83
+ for (const rel of gatedFilesOf(files)) {
84
+ const abs = path.join(root, rel);
85
+ const content = fs.existsSync(abs) ? fs.readFileSync(abs) : Buffer.from(DELETED_MARKER);
86
+ h.update(rel);
87
+ h.update('\u0000');
88
+ h.update(createHash('sha256').update(content).digest('hex'));
89
+ h.update('\n');
90
+ }
91
+ return h.digest('hex');
92
+ }
@@ -160,7 +160,9 @@ export function dispositionStopMessage(
160
160
  resumeCmd: string,
161
161
  ): string {
162
162
  const count =
163
- blocking > 0 ? ` ${blocking} of them are blocking findings with no status yet.\n` : '';
163
+ blocking > 0
164
+ ? ` ${blocking} of them are blocking findings with no disposition yet (no status, or still_open).\n`
165
+ : '';
164
166
  return (
165
167
  `the disposition gate refuses ${version}. Its own report:\n` +
166
168
  `${gateOutput.trim() || ' (the gate printed nothing — run it directly to see why)'}\n` +
@@ -296,7 +298,7 @@ export function settleFindingsLedger(
296
298
  // the operator `scanned: N` and discarded the entire reason the
297
299
  // release stopped.
298
300
  [verdict.stdout, verdict.stderr].map((s) => s.trim()).filter(Boolean).join('\n'),
299
- blockingWithoutDisposition(path.join(deps.repoRoot, rel)),
301
+ blockingWithoutDisposition(path.join(deps.repoRoot, rel), version),
300
302
  'task release -- --resume --yes',
301
303
  ),
302
304
  );
@@ -304,20 +306,26 @@ export function settleFindingsLedger(
304
306
  }
305
307
 
306
308
  /**
307
- * How many blocking findings carry no status — a figure for the stop message,
308
- * never the reason for it.
309
+ * How many blocking findings carry no disposition — no status, or `still_open`,
310
+ * which a blocking row may not rest on — a figure for the stop message, never
311
+ * the reason for it.
309
312
  *
310
313
  * The gate refuses for more shapes than this counts (an unknown status, an
311
314
  * empty rationale or verifier, a `fixed` with no commit, a malformed ledger),
312
- * which is why the gate's own output is what the operator is shown.
315
+ * which is why the gate's own output is what the operator is shown. It
316
+ * classifies against the version being released, the same input the gate
317
+ * reads from `--release`, not the ledger file's own `release` field.
313
318
  */
314
- function blockingWithoutDisposition(ledgerAbs: string): number {
319
+ export function blockingWithoutDisposition(ledgerAbs: string, version: string): number {
315
320
  if (!fs.existsSync(ledgerAbs)) {
316
321
  return 0;
317
322
  }
318
323
  try {
319
324
  const ledger = parse_ledger(fs.readFileSync(ledgerAbs, 'utf-8'), ledgerAbs);
320
- return ledger.findings.filter((f) => isBlocking(f) && !f.status).length;
325
+ return ledger.findings.filter((f) => {
326
+ const status = (f.status ?? '').trim();
327
+ return isBlocking(f, version) && (status === '' || status === 'still_open');
328
+ }).length;
321
329
  } catch {
322
330
  return 0;
323
331
  }
@@ -610,6 +610,11 @@ const TEST_FOOTER_RE = /^Tests: \d+/mu;
610
610
  */
611
611
  export interface MixObligation {
612
612
  level: string;
613
+ /** The resolved ends the counts were read on; the rendered level names both. */
614
+ from_sha?: string;
615
+ to_sha?: string;
616
+ governance_only?: number;
617
+ consumer_only?: number;
613
618
  }
614
619
 
615
620
  /** Labels whose curated value is still the generator's unedited draft. */
@@ -24,6 +24,7 @@ import * as path from 'node:path';
24
24
  import { REPO_ROOT } from '../release_env.js';
25
25
  import { die, run, type RunResult } from '../release_publication.js';
26
26
  import {
27
+ BREAKING_INDEX_PATH,
27
28
  MIGRATION_PATH as MAJOR_MIGRATION_PATH,
28
29
  pendingMajorFinding,
29
30
  } from '../lint_major_migration_sections.js';
@@ -148,8 +149,15 @@ export function assert_scheduled_deprecations_clear(
148
149
  * real run will refuse and returns, because `--dry-run exits 0` is a contract
149
150
  * this file's own tests assert.
150
151
  *
152
+ * A major owes TWO records and this seam reads both: the migration section and
153
+ * the by-major row in `BREAKING_CHANGES.md`. Checking only the first at cut
154
+ * time while the lint checks both would let a cut create the exact state the
155
+ * lint then reds `main` over — the gate arriving one merge too late, which is
156
+ * the shape `pendingMajorFinding` exists to avoid in the first place.
157
+ *
151
158
  * @param migrationReader Seam for the file read, so a test can drive the
152
159
  * refusal without mutating a tracked file.
160
+ * @param indexReader The same seam for the breaking-changes index.
153
161
  */
154
162
  export function assert_major_migration_section(
155
163
  target: string,
@@ -157,18 +165,23 @@ export function assert_major_migration_section(
157
165
  opts: { previewOnly?: boolean } = {},
158
166
  migrationReader: () => string = () =>
159
167
  fs.readFileSync(path.join(REPO_ROOT, MAJOR_MIGRATION_PATH), 'utf-8'),
168
+ indexReader: () => string = () =>
169
+ fs.readFileSync(path.join(REPO_ROOT, BREAKING_INDEX_PATH), 'utf-8'),
160
170
  ): void {
161
171
  let migration: string;
172
+ let index: string;
162
173
  try {
163
174
  migration = migrationReader();
175
+ index = indexReader();
164
176
  } catch (exc) {
165
177
  die(
166
- `refusing the ${target} cut: cannot read ${MAJOR_MIGRATION_PATH} ` +
178
+ `refusing the ${target} cut: cannot read ${MAJOR_MIGRATION_PATH} or ` +
179
+ `${BREAKING_INDEX_PATH} ` +
167
180
  `(${exc instanceof Error ? exc.message : String(exc)}). That is an environment ` +
168
181
  'failure, not a finding — fix the checkout, then re-run.',
169
182
  );
170
183
  }
171
- const finding = pendingMajorFinding(target, changelog_entry, migration);
184
+ const finding = pendingMajorFinding(target, changelog_entry, migration, index);
172
185
  if (finding === null) {
173
186
  return;
174
187
  }
@@ -180,5 +193,8 @@ export function assert_major_migration_section(
180
193
  );
181
194
  return;
182
195
  }
183
- die(`refusing the ${target} cut: ${MAJOR_MIGRATION_PATH} has no section for ${target}.`);
196
+ die(
197
+ `refusing the ${target} cut: ${MAJOR_MIGRATION_PATH} or ${BREAKING_INDEX_PATH} ` +
198
+ `does not name ${target}.`,
199
+ );
184
200
  }
@@ -0,0 +1,73 @@
1
+ /**
2
+ * The reserved-name sweep over flat Claude Code command files.
3
+ *
4
+ * A flat command whose slug shadows a Claude Code built-in never ships on the
5
+ * claude-code anchor — the suite complements the host, it does not overlay its
6
+ * built-ins. The sweep that enforces this used to delete EVERY builtin-named
7
+ * `.md` in the anchor's `commands/` directory, including one another agent
8
+ * package or the consumer had put there. The consumer's own `/review` command
9
+ * disappeared at install time with no message, because the sweep's only
10
+ * question was the filename.
11
+ *
12
+ * The question it asks now is ownership: a file is removed when this package
13
+ * wrote it — the current deploy's own written set, or a path a previous
14
+ * install recorded in the installed-tools manifest. Anything else is FOREIGN:
15
+ * it stays on disk and is reported, so the consumer learns that a built-in
16
+ * name is shadowed by someone and can decide, rather than finding their file
17
+ * gone.
18
+ *
19
+ * Both halves of the sweep's original purpose survive: ours never ships under
20
+ * a reserved name, and the suite still never overlays a built-in with its own
21
+ * file. What it no longer does is enforce that on a file that is not its own.
22
+ */
23
+
24
+ import * as fs from 'node:fs';
25
+ import * as path from 'node:path';
26
+
27
+ export interface ReservedSweepResult {
28
+ /** Slugs of OUR files removed because the name is a host built-in. */
29
+ reserved: string[];
30
+ /** Slugs left in place because nothing proves this package wrote them. */
31
+ foreign: string[];
32
+ }
33
+
34
+ /**
35
+ * Remove our builtin-named flat commands from `commandsDir`; keep foreign ones.
36
+ *
37
+ * Both ownership sets are anchor-relative, exactly as the deploy inventory
38
+ * records them. `currentFiles` is this deploy's written set — the live half,
39
+ * and the only one that exists on a first install. `recordedFiles` is what a
40
+ * previous deploy recorded under the same anchor, so a builtin-named file of
41
+ * ours left behind by an older version is still reaped rather than becoming
42
+ * permanently unprovable. A removed entry is dropped from `currentFiles` so
43
+ * the inventory record stays consistent with the tree, exactly as before.
44
+ */
45
+ export function sweepReservedNames(
46
+ commandsDir: string,
47
+ currentFiles: Set<string>,
48
+ isBuiltinName: (slug: string) => boolean,
49
+ recordedFiles: ReadonlySet<string>,
50
+ ): ReservedSweepResult {
51
+ const reserved: string[] = [];
52
+ const foreign: string[] = [];
53
+ let entries: string[] = [];
54
+ try {
55
+ entries = fs.readdirSync(commandsDir).filter((f) => f.endsWith('.md'));
56
+ } catch {
57
+ return { reserved, foreign };
58
+ }
59
+ for (const fname of entries.sort()) {
60
+ const slug = fname.slice(0, -'.md'.length);
61
+ if (!isBuiltinName(slug)) continue;
62
+ const rel = `commands/${fname}`;
63
+ const ours = currentFiles.has(rel) || recordedFiles.has(rel);
64
+ if (!ours) {
65
+ foreign.push(slug);
66
+ continue;
67
+ }
68
+ fs.rmSync(path.join(commandsDir, fname), { force: true });
69
+ currentFiles.delete(rel);
70
+ reserved.push(slug);
71
+ }
72
+ return { reserved, foreign };
73
+ }
@@ -0,0 +1,134 @@
1
+ /**
2
+ * How much of a release the self-review actually read, stated where the record
3
+ * is read.
4
+ *
5
+ * `self_review_gate` writes a `coverage` block — `{chunks, filesReviewed,
6
+ * filesTotal, unreviewed[]}` — into the findings artifact, `--ingest` carries it
7
+ * into the per-release ledger named by {@link LEDGER_DIR}, and from there NOBODY
8
+ * reads `filesReviewed` back. The 16.2.0 ledger records `filesReviewed: 65,
9
+ * filesTotal: 678`: the review saw under a tenth of the change. Every consumer
10
+ * of that record — the disposition gate's success line, the release-highlights
11
+ * gate, a human opening the file — saw output that said nothing about it.
12
+ *
13
+ * A finding count over 9.6 % of a diff and the same count over all of it are
14
+ * different claims, and the record spelled them identically.
15
+ *
16
+ * A LABEL, NEVER A FLOOR, and the distinction is the decision.
17
+ *
18
+ * Nothing here refuses. `coverageLabel` returns a string or `null`; no caller
19
+ * turns it into an exit code, and none may. Raising what a review reads costs
20
+ * one more paid model request per chunk per cut, which is a spend decision
21
+ * belonging to the owner. A gate that failed a cut on partial coverage would
22
+ * force that decision through the back door — the operator would either pay or
23
+ * be unable to release — which is exactly the move the roadmap's decision D1
24
+ * records as rejected.
25
+ *
26
+ * The honest cost of that choice, stated rather than left to be discovered: a
27
+ * release can ship with 9.6 % coverage and this module will only have said so.
28
+ * Saying so is the whole claim.
29
+ *
30
+ * It lives in its own module because two consumers read it — `check_finding_dispositions` on the ledger and
31
+ * `check_release_highlights` beside the Known-limitations field — and a label
32
+ * the two spell differently is a label a reader cannot compare across the two
33
+ * places they meet it. One definition is also the seam the unit tests use, so
34
+ * the arithmetic is checked without either CLI in the loop.
35
+ */
36
+ import * as fs from 'node:fs';
37
+ import * as path from 'node:path';
38
+
39
+ /** Where the per-release ledgers live, relative to the repository root. */
40
+ export const LEDGER_DIR = path.join('agents', 'evidence', 'release-findings');
41
+
42
+ /**
43
+ * The coverage block as the gate writes it. Every field optional: this type
44
+ * describes an artifact read back off disk, which may be from an older writer
45
+ * or hand-edited, so the reader's job is to decide whether it can answer rather
46
+ * than to assume it can.
47
+ */
48
+ export interface ReviewCoverage {
49
+ readonly chunks?: unknown;
50
+ readonly filesReviewed?: unknown;
51
+ readonly filesTotal?: unknown;
52
+ readonly unreviewed?: unknown;
53
+ }
54
+
55
+ function _finite(v: unknown): number | null {
56
+ return typeof v === 'number' && Number.isFinite(v) ? v : null;
57
+ }
58
+
59
+ /**
60
+ * The one sentence both gates print, or `null` when there is nothing to say.
61
+ *
62
+ * `null` covers three cases deliberately collapsed into one, because they lead
63
+ * to the same output: full coverage (nothing to warn about), an absent block (an
64
+ * older ledger, written before the gate recorded coverage), and a malformed one
65
+ * (a string where a number belongs, a zero total). A reader who sees no label
66
+ * learns "this record makes no partial-coverage claim" — which is true of all
67
+ * three — and never a fabricated percentage derived from a field that was not
68
+ * a number.
69
+ *
70
+ * `filesTotal === 0` is `null` rather than `0 of 0 (partial)`: a change set with
71
+ * no files was fully read by any definition, and dividing by it says nothing.
72
+ */
73
+ export function coverageLabel(coverage: unknown): string | null {
74
+ if (coverage === null || typeof coverage !== 'object') {
75
+ return null;
76
+ }
77
+ const c = coverage as ReviewCoverage;
78
+ const reviewed = _finite(c.filesReviewed);
79
+ const total = _finite(c.filesTotal);
80
+ if (reviewed === null || total === null || total <= 0 || reviewed >= total) {
81
+ return null;
82
+ }
83
+ return `self-review read ${String(reviewed)} of ${String(total)} changed files (partial)`;
84
+ }
85
+
86
+ /**
87
+ * The `coverage` block of a committed ledger, or `undefined`.
88
+ *
89
+ * Never throws. A missing ledger is the normal state of an in-flight release and
90
+ * a corrupt one is already the business of the gate that parses it properly —
91
+ * a label is not the place to discover either, and a reader that threw here
92
+ * would turn an informational line into a crash on a release branch.
93
+ */
94
+ export function readLedgerCoverage(root: string, release: string): unknown {
95
+ const file = path.join(root, LEDGER_DIR, `${release}.json`);
96
+ try {
97
+ const parsed: unknown = JSON.parse(fs.readFileSync(file, 'utf-8'));
98
+ if (parsed === null || typeof parsed !== 'object') {
99
+ return undefined;
100
+ }
101
+ return (parsed as Record<string, unknown>)['coverage'];
102
+ } catch {
103
+ return undefined;
104
+ }
105
+ }
106
+
107
+ /** `coverageLabel` over the committed ledger for `release`. */
108
+ export function ledgerCoverageLabel(root: string, release: string): string | null {
109
+ return coverageLabel(readLedgerCoverage(root, release));
110
+ }
111
+
112
+ /**
113
+ * The same label as a Known-limitations line, for the release-highlights gate.
114
+ *
115
+ * It carries the label plus the sentence that keeps a reader from mistaking it
116
+ * for a refusal, because the field it prints beside is one the gate CAN refuse
117
+ * on. Without that sentence the next person to read the output reasonably
118
+ * concludes the gate is about to start failing cuts on coverage, and the cheapest
119
+ * way to make the message go away becomes raising the ceiling — which is the
120
+ * owner's spend decision, taken by whoever happened to read the line.
121
+ *
122
+ * Returns `null` when there is nothing to say, so the caller prints nothing
123
+ * rather than a reassuring sentence about a number it does not have.
124
+ */
125
+ export function coverageLimitationNote(label: string | null): string | null {
126
+ if (label === null) {
127
+ return null;
128
+ }
129
+ return (
130
+ `ℹ️ ${label} — a limitation of the RECORD, not a verdict on the release. ` +
131
+ 'Stated, never enforced:\n what the review reads is a spend decision and this ' +
132
+ 'gate does not take it.'
133
+ );
134
+ }