@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,637 @@
1
+ /**
2
+ * `agent-config git:convention <subcommand>` — the git convention as code an
3
+ * installed command can reach.
4
+ *
5
+ * A consumer project has neither `scripts-run` nor `node_modules`, so a command
6
+ * that needs the strategy, the commit format or the branch pattern can only ask
7
+ * the `agent-config` binary. `settings:get` answers "not set" for a file that
8
+ * does not parse, which is the reading that turns an unreadable `rebase` into a
9
+ * merge; this verb reports the six states of `_lib/git_convention.ts` instead.
10
+ *
11
+ * Subcommands live in one table so a new one is a row, not a new verb.
12
+ *
13
+ * Every key is read through `_lib/git_convention_carrier.ts`: the committed
14
+ * `.git-convention.yml` over the developer layers, `update_strategy` at the
15
+ * commit the branch is judged against. Where this checkout's own value differs,
16
+ * it is printed as a candidate beside the value in force.
17
+ *
18
+ * `show` exit codes: `0` every requested key in force is readable · `1` a
19
+ * requested key in force is in a state `isRefusal` names (the set `sync`
20
+ * refuses) · `2` usage error. `--key` (repeatable) narrows the keys read and
21
+ * judged; without it all three are. A candidate in a refusal state is printed
22
+ * as a warning: `sync` never reads it.
23
+ *
24
+ * `--base` names the commit `update_strategy` is read at. Without it that is
25
+ * the default branch, which is the answer only for a branch that targets it: a
26
+ * caller acting on a pull request passes `--base origin/<its base>`. A blank
27
+ * `--base` is a usage error (exit `2`) in `show` and in `sync`, never read as
28
+ * no `--base`.
29
+ *
30
+ * `subject` reads subjects on stdin and exits `0` all valid · `1` a subject
31
+ * fails, or the format cannot be read · `2` usage. It checks only the
32
+ * convention in force; a `commit-msg` hook or a commitlint config is named in a
33
+ * note as also running at commit, and never changes the exit, because what such
34
+ * a validator accepts cannot be told without running it. `ticket` exits `0`; `branch`
35
+ * prints the name and exits `0`, or `1` on a value it would have to rewrite.
36
+ *
37
+ * `init --yes` creates `.git-convention.yml` once (ADR-283 § Creation) and exits
38
+ * `0` created · `1` a carrier exists, no `--yes`, an invalid value or nothing to
39
+ * write · `2` usage.
40
+ *
41
+ * `sync` is `sync_pr_branch` run in-process, its arguments and exit codes
42
+ * unchanged: `0` current or merged · `1` conflict or no base · `2` internal
43
+ * error or a blank `--base` · `3` behind under a strategy other than `merge` · `4` the strategy
44
+ * cannot be read.
45
+ */
46
+ import { spawnSync } from 'node:child_process';
47
+ import * as fs from 'node:fs';
48
+ import * as path from 'node:path';
49
+ import process from 'node:process';
50
+ import { fileURLToPath, pathToFileURL } from 'node:url';
51
+
52
+ import { baseValueError } from '../_lib/git_base_ref.js';
53
+ import {
54
+ GIT_CONVENTION_KEYS,
55
+ conventionDefault,
56
+ describeRefusal,
57
+ invalidReason,
58
+ isRefusal,
59
+ type GitConventionKey,
60
+ type GitConventionReading,
61
+ } from '../_lib/git_convention.js';
62
+ import { CARRIER_PATH, IGNORED_CARRIER_PATH, conventionRoot, ignoredCarrierWarning, readCommittedConvention, type TargetDeps } from '../_lib/git_convention_carrier.js';
63
+ import {
64
+ FAMILY_ERE,
65
+ checkSubject,
66
+ commitlintIssuePrefixes,
67
+ parseTicketKeys,
68
+ renderBranch,
69
+ ruleName,
70
+ ticketCandidates,
71
+ type CommitFormat,
72
+ type SubjectFamily,
73
+ type SubjectRule,
74
+ } from '../_lib/git_convention_grammar.js';
75
+ import {
76
+ CLASSIFIER_VERSION,
77
+ MEASURE_LIMIT,
78
+ MEASURE_SINCE,
79
+ MIN_N,
80
+ formatForFamily,
81
+ measureBranches,
82
+ measureSubjects,
83
+ measureUpdateStyle,
84
+ pct,
85
+ readHistory,
86
+ teamFile,
87
+ } from '../_lib/git_convention_measure.js';
88
+ import { main as syncPrBranch } from '../sync_pr_branch.js';
89
+
90
+ export interface GitConventionResult {
91
+ code: 0 | 1 | 2 | 3 | 4;
92
+ out: string[];
93
+ err: string[];
94
+ }
95
+
96
+ export interface CommitMessageValidator {
97
+ kind: 'commit-msg hook' | 'commitlint config';
98
+ path: string;
99
+ }
100
+
101
+ /** Every file name in commitlint's documented config search places; `package.json` is checked separately. */
102
+ const COMMITLINT_FILES = [
103
+ '.commitlintrc',
104
+ '.commitlintrc.json',
105
+ '.commitlintrc.yaml',
106
+ '.commitlintrc.yml',
107
+ '.commitlintrc.js',
108
+ '.commitlintrc.cjs',
109
+ '.commitlintrc.mjs',
110
+ '.commitlintrc.ts',
111
+ '.commitlintrc.cts',
112
+ '.commitlintrc.mts',
113
+ 'commitlint.config.js',
114
+ 'commitlint.config.cjs',
115
+ 'commitlint.config.mjs',
116
+ 'commitlint.config.ts',
117
+ 'commitlint.config.cts',
118
+ 'commitlint.config.mts',
119
+ ] as const;
120
+
121
+ function _git(cwd: string, ...args: string[]): string | null {
122
+ const r = spawnSync('git', args, { cwd, encoding: 'utf8' });
123
+ return r.status === 0 ? r.stdout.trim() : null;
124
+ }
125
+
126
+ function _isExecutableFile(p: string): boolean {
127
+ try {
128
+ const st = fs.statSync(p);
129
+ return st.isFile() && (st.mode & 0o111) !== 0;
130
+ } catch {
131
+ return false;
132
+ }
133
+ }
134
+
135
+ /**
136
+ * Every repository-level commit-message validator: the `commit-msg` hook git
137
+ * will run, then the commitlint config. Either may reject a commit the
138
+ * convention accepts, so each is named beside the verdict, never inferred.
139
+ *
140
+ * A hook counts only where git will run it: the path comes from git, so
141
+ * `core.hooksPath` and worktrees resolve, and a `.husky/commit-msg` this clone
142
+ * never pointed `core.hooksPath` at is a file in the tree, not a hook.
143
+ */
144
+ export function commitMessageValidators(cwd: string): CommitMessageValidator[] {
145
+ const found: CommitMessageValidator[] = [];
146
+ const top = _git(cwd, 'rev-parse', '--show-toplevel') ?? cwd;
147
+ const hook = _git(cwd, 'rev-parse', '--path-format=absolute', '--git-path', 'hooks/commit-msg');
148
+ if (hook !== null && _isExecutableFile(hook)) found.push({ kind: 'commit-msg hook', path: hook });
149
+ const config = COMMITLINT_FILES.map((name) => path.join(top, name)).find((p) => fs.existsSync(p));
150
+ if (config !== undefined) found.push({ kind: 'commitlint config', path: config });
151
+ else {
152
+ try {
153
+ const pkg = JSON.parse(fs.readFileSync(path.join(top, 'package.json'), 'utf-8')) as Record<string, unknown>;
154
+ if (pkg.commitlint !== undefined) found.push({ kind: 'commitlint config', path: path.join(top, 'package.json') });
155
+ } catch {
156
+ // No package.json, or one that does not parse: neither declares a validator.
157
+ }
158
+ }
159
+ return found;
160
+ }
161
+
162
+ /** The first of `commitMessageValidators`, or null. */
163
+ export function commitMessageValidator(cwd: string): CommitMessageValidator | null {
164
+ return commitMessageValidators(cwd)[0] ?? null;
165
+ }
166
+
167
+ function _validatorNote(v: CommitMessageValidator): string {
168
+ return `note: the ${v.kind} at ${v.path} also runs at commit time and may be stricter`;
169
+ }
170
+
171
+
172
+ function _short(sha: string | null | undefined): string {
173
+ return sha === null || sha === undefined ? '?' : sha.slice(0, 12);
174
+ }
175
+
176
+ /** `show` with the target lookups injectable; the verb passes none. */
177
+ export function showConvention(args: readonly string[], cwd: string, deps?: TargetDeps): GitConventionResult {
178
+ let json = false;
179
+ let base: string | null = null;
180
+ const asked: GitConventionKey[] = [];
181
+ for (let i = 0; i < args.length; i++) {
182
+ const a = args[i] as string;
183
+ const next = args[i + 1];
184
+ if (a === '--json') json = true;
185
+ else if (a === '--base' && next !== undefined && !next.startsWith('--')) {
186
+ const blank = baseValueError(next);
187
+ if (blank !== null) return { code: 2, out: [], err: [blank, USAGE] };
188
+ base = args[++i] as string;
189
+ } else if (a === '--key' && next !== undefined && (GIT_CONVENTION_KEYS as readonly string[]).includes(next)) {
190
+ if (!asked.includes(next as GitConventionKey)) asked.push(next as GitConventionKey);
191
+ i++;
192
+ } else return { code: 2, out: [], err: [a === '--key' ? `unknown key: ${next ?? '(none)'}` : `unknown argument: ${a}`, USAGE] };
193
+ }
194
+ const keys = asked.length === 0 ? GIT_CONVENTION_KEYS : GIT_CONVENTION_KEYS.filter((k) => asked.includes(k));
195
+ const read = readCommittedConvention(cwd, { override: base, keys, ...(deps ? { deps } : {}) });
196
+ const readings = read.readings as Record<GitConventionKey, GitConventionReading>;
197
+ const validators = commitMessageValidators(cwd);
198
+ const ok = !keys.some((k) => isRefusal(readings[k].state));
199
+ const code: 0 | 1 = ok ? 0 : 1;
200
+ const established = keys.includes('commit_format') ? _established(readings.commit_format, read.root) : null;
201
+ const ignored = ignoredCarrierWarning(read.root);
202
+ const warnings = ignored === null ? [] : [ignored];
203
+
204
+ if (json) {
205
+ const entries: Record<string, unknown> = {};
206
+ for (const k of keys) {
207
+ const { key: _key, ...rest } = readings[k];
208
+ const cand = read.candidates[k];
209
+ entries[k] = {
210
+ ...rest,
211
+ read_at: read.readAt[k] ?? null,
212
+ candidate: cand === undefined ? null : { value: cand.value, source: cand.source, state: cand.state, reason: cand.reason },
213
+ };
214
+ }
215
+ return {
216
+ code,
217
+ out: [JSON.stringify({ ok, keys: entries, target: read.target, warnings, convention_established: established, commit_message_validator: validators[0] ?? null, commit_message_validators: validators }, null, 2)],
218
+ err: [],
219
+ };
220
+ }
221
+
222
+ const out: string[] = [];
223
+ for (const k of keys) {
224
+ const r = readings[k];
225
+ out.push(r.value === null ? `git.${k} — unknown` : `git.${k} = ${r.value}`);
226
+ out.push(` state ${r.state}`);
227
+ out.push(` source ${r.source ?? '(template default)'}`);
228
+ const at = read.readAt[k];
229
+ if (k === 'update_strategy' && read.target !== null) {
230
+ out.push(` read at ${_short(read.target.sha)} — ${read.target.ref}, the commit this branch is judged against`);
231
+ } else if (at !== null && at !== undefined) {
232
+ out.push(` read at ${_short(at)} — HEAD`);
233
+ }
234
+ if (r.reason !== null) out.push(` ⚠️ ${describeRefusal(r)}`);
235
+ const cand = read.candidates[k];
236
+ if (cand !== undefined) {
237
+ out.push(
238
+ ` candidate ${cand.value ?? 'unknown'} (${cand.state}) from ${cand.source ?? '(template default)'} — this checkout's value; the value above is in force`,
239
+ );
240
+ if (cand.reason !== null) out.push(` ⚠️ candidate only, not in force: ${describeRefusal(cand)}`);
241
+ }
242
+ }
243
+ out.push(`team declaration: ${CARRIER_PATH} at the repository root (ADR-283)`);
244
+ if (established === false) out.push(NO_CONVENTION);
245
+ for (const w of warnings) out.push(`⚠️ ${w}`);
246
+ if (validators.length === 0) out.push('commit-message validator: none in this repository');
247
+ for (const v of validators) out.push(`commit-message validator: ${v.kind} at ${v.path} — also runs at commit time and may be stricter than git.commit_format`);
248
+ return { code, out, err: [] };
249
+ }
250
+
251
+ /** Where the skill's tier 2 persists an approved measurement. */
252
+ export const APPROVED_CARD = 'agents/memory/curated/conventions/approved/commit-subject.md';
253
+
254
+ function _flags(args: readonly string[], names: readonly string[]): { values: Record<string, string>; json: boolean; positional: string[]; bad: string | null } {
255
+ const values: Record<string, string> = {};
256
+ const positional: string[] = [];
257
+ let json = false;
258
+ for (let i = 0; i < args.length; i++) {
259
+ const a = args[i] as string;
260
+ if (a === '--json') json = true;
261
+ else if (a.startsWith('--')) {
262
+ const v = args[i + 1];
263
+ if (!names.includes(a.slice(2)) || v === undefined || v.startsWith('--')) return { values, json, positional, bad: a };
264
+ values[a.slice(2)] = v;
265
+ i++;
266
+ } else positional.push(a);
267
+ }
268
+ return { values, json, positional, bad: null };
269
+ }
270
+
271
+ function _cardFamily(root: string): string | null {
272
+ let text: string;
273
+ try {
274
+ text = fs.readFileSync(path.join(root, APPROVED_CARD), 'utf-8');
275
+ } catch {
276
+ return null;
277
+ }
278
+ return /^[ \t]*dominant_family:\s*["']?([a-z-]+)/m.exec(text)?.[1] ?? null;
279
+ }
280
+
281
+ /**
282
+ * A `git.commit_format` the user chose: any valid committed value, or a
283
+ * developer value other than the template default — `settings:sync` inserts the
284
+ * default into every project file, so the default there proves no choice.
285
+ */
286
+ function _declares(reading: GitConventionReading): boolean {
287
+ if (reading.state !== 'valid') return false;
288
+ return (reading.source ?? '').startsWith(CARRIER_PATH) || reading.value !== conventionDefault('commit_format');
289
+ }
290
+
291
+ /** The commitlint config, which establishes the convention as the repository's own subject validator. */
292
+ function _commitlint(cwd: string): CommitMessageValidator | null {
293
+ return commitMessageValidators(cwd).find((v) => v.kind === 'commitlint config') ?? null;
294
+ }
295
+
296
+ /** True with a declaration, an approved card or a commitlint config, false with none, null when the format cannot be read. */
297
+ function _established(reading: GitConventionReading, root: string): boolean | null {
298
+ if (isRefusal(reading.state)) return null;
299
+ return _declares(reading) || _cardFamily(root) !== null || _commitlint(root) !== null;
300
+ }
301
+
302
+ /** Printed when no declaration, approved card or commitlint config exists. */
303
+ export const NO_CONVENTION = 'no convention established — run git:convention measure';
304
+
305
+ type SubjectPlan =
306
+ | { kind: 'rule'; rule: SubjectRule; tier: string; notes: string[]; established?: false }
307
+ | { kind: 'stop'; code: 1; lines: string[] };
308
+
309
+ function _planSubject(values: Record<string, string>, cwd: string): SubjectPlan {
310
+ if (values.format !== undefined) {
311
+ if (!['ticket-scope', 'ticket-conventional'].includes(values.format)) return { kind: 'stop', code: 1, lines: [`unknown format: ${values.format}`] };
312
+ return { kind: 'rule', rule: { format: values.format as CommitFormat }, tier: 'passed by the caller', notes: [] };
313
+ }
314
+ if (values.family !== undefined) {
315
+ if (!FAMILY_ERE.some(([f]) => f === values.family)) return { kind: 'stop', code: 1, lines: [`no grammar for family: ${values.family}`] };
316
+ return { kind: 'rule', rule: { family: values.family as SubjectFamily }, tier: 'passed by the caller', notes: [] };
317
+ }
318
+ const read = readCommittedConvention(cwd, { keys: ['commit_format'] });
319
+ const reading = read.readings.commit_format as GitConventionReading;
320
+ if (isRefusal(reading.state)) return { kind: 'stop', code: 1, lines: [describeRefusal(reading)] };
321
+ const ignored = ignoredCarrierWarning(read.root);
322
+ const notes = [...(ignored === null ? [] : [`⚠️ ${ignored}`]), ...commitMessageValidators(cwd).map(_validatorNote)];
323
+ if (_declares(reading)) return { kind: 'rule', rule: { format: reading.value as CommitFormat }, tier: `declared in ${reading.source}`, notes };
324
+ const family = _cardFamily(read.root);
325
+ if (family !== null) {
326
+ if (!FAMILY_ERE.some(([f]) => f === family)) return { kind: 'stop', code: 1, lines: [`the approved family ${family} in ${APPROVED_CARD} has no grammar to validate against`] };
327
+ return { kind: 'rule', rule: { family: family as SubjectFamily }, tier: `approved in ${APPROVED_CARD}`, notes };
328
+ }
329
+ const lint = _commitlint(cwd);
330
+ if (lint !== null) return { kind: 'rule', rule: { format: (reading.value ?? 'ticket-scope') as CommitFormat }, tier: `default (Conventional Commits); the commitlint config at ${lint.path} governs`, notes };
331
+ return { kind: 'rule', rule: { format: (reading.value ?? 'ticket-scope') as CommitFormat }, tier: 'default (Conventional Commits)', notes, established: false };
332
+ }
333
+
334
+ /** Under `--json` every exit prints one object carrying `ok`, `code` and the human `lines`. */
335
+ function _subjectResult(json: boolean, code: GitConventionResult['code'], lines: string[], err: string[] = [], extra: Record<string, unknown> = {}): GitConventionResult {
336
+ if (!json) return { code, out: lines, err };
337
+ return { code, out: [JSON.stringify({ ok: code === 0, code, lines, ...extra }, null, 2)], err };
338
+ }
339
+
340
+ /** Exit `2` here means the verb ran and received nothing — not that it cannot run. */
341
+ export const NO_SUBJECTS = 'no subjects on stdin — the verb ran; pipe the subjects into it, one per line';
342
+
343
+ export function subjectCommand(args: readonly string[], cwd: string, stdin = ''): GitConventionResult {
344
+ const f = _flags(args, ['format', 'family']);
345
+ if (f.bad !== null || f.positional.length > 0) {
346
+ const why = `unknown argument: ${f.bad ?? f.positional[0]}`;
347
+ return _subjectResult(f.json, 2, f.json ? [why] : [], [why, USAGE]);
348
+ }
349
+ const subjects = stdin.split('\n').map((l) => l.trimEnd()).filter((l) => l !== '');
350
+ if (subjects.length === 0) return _subjectResult(f.json, 2, f.json ? [NO_SUBJECTS] : [], [NO_SUBJECTS, USAGE]);
351
+ const plan = _planSubject(f.values, cwd);
352
+ if (plan.kind === 'stop') return _subjectResult(f.json, plan.code, plan.lines);
353
+ const failures = subjects.map((s) => ({ s, v: checkSubject(s, plan.rule) })).filter((x) => !x.v.ok);
354
+ const lines = failures.length === 0
355
+ ? [`${subjects.length} subject(s) valid under ${ruleName(plan.rule)} (${plan.tier})`, ...plan.notes]
356
+ : [...failures.map((x) => `✗ ${x.s}\n ${x.v.ok ? '' : x.v.rule}`), ...plan.notes];
357
+ if (plan.established === false) lines.push(NO_CONVENTION);
358
+ return _subjectResult(f.json, failures.length === 0 ? 0 : 1, lines, [], {
359
+ rule: ruleName(plan.rule),
360
+ tier: plan.tier,
361
+ notes: plan.notes,
362
+ convention_established: plan.established === false ? false : plan.tier === 'passed by the caller' ? null : true,
363
+ failures: failures.map((x) => ({ subject: x.s, rule: x.v.ok ? null : x.v.rule })),
364
+ });
365
+ }
366
+
367
+ function _commitlintProposal(cwd: string): { keys: string[]; from: string } | null {
368
+ // A husky setup lists its commit-msg hook first, ahead of the config.
369
+ const v = commitMessageValidators(cwd).find((c) => c.kind === 'commitlint config');
370
+ if (v === undefined) return null;
371
+ try {
372
+ const keys = commitlintIssuePrefixes(fs.readFileSync(v.path, 'utf-8'));
373
+ return keys.length === 0 ? null : { keys, from: v.path };
374
+ } catch {
375
+ return null;
376
+ }
377
+ }
378
+
379
+ export function ticketCommand(args: readonly string[], cwd: string): GitConventionResult {
380
+ const f = _flags(args, ['keys']);
381
+ if (f.bad !== null || f.positional.length > 1) return { code: 2, out: [], err: [`unknown argument: ${f.bad ?? f.positional[1]}`, USAGE] };
382
+ const name = f.positional[0] ?? _git(cwd, 'rev-parse', '--abbrev-ref', 'HEAD') ?? '';
383
+ const keys = f.values.keys === undefined ? null : parseTicketKeys(f.values.keys);
384
+ const all = ticketCandidates(name, keys);
385
+ const ticket = all.find((c) => c.status === 'ticket')?.token ?? null;
386
+ const proposal = keys === null ? _commitlintProposal(cwd) : null;
387
+ if (f.json) return { code: 0, out: [JSON.stringify({ branch: name, ticket, candidates: all, proposal }, null, 2)], err: [] };
388
+ const out = [`ticket ${ticket ?? 'none'}`, ...all.map((c) => ` ${c.token.padEnd(14)} ${c.status}`)];
389
+ if (proposal !== null) {
390
+ out.push(`proposal ticket_keys: ${proposal.keys.join(', ')} (issuePrefixes in ${proposal.from}) — offer it for the convention card; this verb writes nothing`);
391
+ }
392
+ return { code: 0, out, err: [] };
393
+ }
394
+
395
+ /** `absent` with no template default: nothing to render from, and not a refusal either. */
396
+ export const NO_BRANCH_PATTERN = 'no branch_pattern declared — pass --pattern or declare one';
397
+
398
+ export function branchCommand(args: readonly string[], cwd: string): GitConventionResult {
399
+ const f = _flags(args, ['type', 'ticket', 'slug', 'pattern']);
400
+ if (f.bad !== null || f.positional.length > 0 || f.values.slug === undefined) {
401
+ return { code: 2, out: [], err: [f.bad === null && f.positional.length === 0 ? '--slug is required' : `unknown argument: ${f.bad ?? f.positional[0]}`, USAGE] };
402
+ }
403
+ let pattern = f.values.pattern;
404
+ if (pattern === undefined) {
405
+ const reading = readCommittedConvention(cwd, { keys: ['branch_pattern'] }).readings.branch_pattern as GitConventionReading;
406
+ if (isRefusal(reading.state)) return { code: 1, out: [], err: [describeRefusal(reading)] };
407
+ if (reading.value === null) return { code: 1, out: [], err: [NO_BRANCH_PATTERN] };
408
+ pattern = reading.value;
409
+ } else {
410
+ const why = invalidReason('branch_pattern', pattern);
411
+ if (why !== null) return { code: 1, out: [], err: [`invalid pattern: ${why}`] };
412
+ }
413
+ const r = renderBranch(pattern, { type: f.values.type ?? null, ticket: f.values.ticket ?? null, slug: f.values.slug });
414
+ if (!r.ok) return { code: 1, out: [], err: [r.reason] };
415
+ const check = spawnSync('git', ['check-ref-format', '--branch', r.name], { encoding: 'utf8' });
416
+ if (check.error === undefined && check.status !== 0) return { code: 1, out: [], err: [`\`${r.name}\` fails git check-ref-format --branch`] };
417
+ return { code: 0, out: f.json ? [JSON.stringify({ branch: r.name, pattern })] : [r.name], err: [] };
418
+ }
419
+
420
+ /** The convention card `/commit` writes under `approved/` once the user has answered. */
421
+ export function cardText(m: { family: SubjectFamily; observedN: number; share: number; authors: number; trunk: string; windowExtended?: boolean }): string {
422
+ return [
423
+ '---',
424
+ `dominant_family: ${m.family}`,
425
+ `observed_n: ${m.observedN}`,
426
+ `dominant_share: ${m.share.toFixed(2)}`,
427
+ `author_count: ${m.authors}`,
428
+ m.windowExtended === true
429
+ ? `sample_window: "any age (fewer than ${MIN_N} since ${MEASURE_SINCE}), newest ${MEASURE_LIMIT} non-merge commits"`
430
+ : `sample_window: "${MEASURE_SINCE}, newest ${MEASURE_LIMIT} non-merge commits"`,
431
+ `classifier_version: ${CLASSIFIER_VERSION}`,
432
+ `confirm_against: ${m.trunk}`,
433
+ 'ticket_keys: []',
434
+ '---',
435
+ '',
436
+ `Approved by the user from \`agent-config git:convention measure\`. Re-measure when a tier-1 source appears or the newer half's family changes.`,
437
+ '',
438
+ ].join('\n');
439
+ }
440
+
441
+ export function measureCommand(args: readonly string[], cwd: string): GitConventionResult {
442
+ const f = _flags(args, ['limit', 'family']);
443
+ const limit = f.values.limit === undefined ? MEASURE_LIMIT : Number(f.values.limit);
444
+ if (f.bad !== null || f.positional.length > 0 || !Number.isInteger(limit) || limit < 1) {
445
+ return { code: 2, out: [], err: [f.bad === null && f.positional.length === 0 ? `--limit must be a positive integer: ${f.values.limit}` : `unknown argument: ${f.bad ?? f.positional[0]}`, USAGE] };
446
+ }
447
+ const chosen = f.values.family;
448
+ if (chosen !== undefined && !FAMILY_ERE.some(([fam]) => fam === chosen)) return { code: 2, out: [], err: [`no grammar for family: ${chosen}`, USAGE] };
449
+ const history = readHistory(cwd, limit);
450
+ if (history === null) return { code: 1, out: [], err: ['not a git repository'] };
451
+ if ('unresolved' in history) {
452
+ const line = `sample none — ${history.unresolved}; nothing was sampled and nothing is proposed. Set it with: git remote set-head origin --auto`;
453
+ return f.json
454
+ ? { code: 1, out: [JSON.stringify({ classifier_version: CLASSIFIER_VERSION, sample: { trunk: null, limit, since: MEASURE_SINCE, read: 0 }, trunk_unresolved: history.unresolved }, null, 2)], err: [] }
455
+ : { code: 1, out: [line], err: [] };
456
+ }
457
+ const m = measureSubjects(history.commits);
458
+ const b = measureBranches(history.branches);
459
+ const u = measureUpdateStyle(history.mergeSubjects, history.defaultBranch);
460
+ const read = readCommittedConvention(cwd, { keys: ['commit_format'] });
461
+ const established = _established(read.readings.commit_format as GitConventionReading, read.root);
462
+ const lint = _commitlint(cwd);
463
+ const ignored = ignoredCarrierWarning(read.root);
464
+ const family = (chosen as SubjectFamily | undefined) ?? m.established;
465
+ const share = family === null ? 0 : (m.families.find((x) => x.family === family)?.share ?? 0);
466
+ const team = teamFile(family, b.pattern);
467
+ const card = family === null ? null : cardText({ family, observedN: m.eligible, share, authors: m.authors, trunk: history.trunk, windowExtended: history.windowExtended });
468
+
469
+ if (f.json) {
470
+ return {
471
+ code: 0,
472
+ out: [JSON.stringify({
473
+ convention_established: established,
474
+ commitlint_config: lint?.path ?? null,
475
+ classifier_version: CLASSIFIER_VERSION,
476
+ sample: { trunk: history.trunk, limit, since: MEASURE_SINCE, window_extended: history.windowExtended, read: history.commits.length, eligible: m.eligible, excluded: m.excluded, authors: m.authors, capped: m.capped, capped_total: m.cappedTotal },
477
+ bar: { min_n: MIN_N, share: m.bar },
478
+ families: m.families,
479
+ halves: { newer: m.newer, older: m.older, agree: m.halvesAgree },
480
+ recent: m.recent,
481
+ verdict: { established: m.established, migrating: m.migrating, migrated_by: m.migratedBy, reasons: m.reasons, strongest: m.strongest },
482
+ branches: { sampled: b.sampled, pattern: b.pattern, share: b.share, shapes: b.shapes },
483
+ update_style: { observed: u.observed, base_merges: u.baseMerges, merges: u.merges, adopted: false },
484
+ chosen: family,
485
+ team_file: team,
486
+ card,
487
+ }, null, 2)],
488
+ err: [],
489
+ };
490
+ }
491
+
492
+ const out = [
493
+ ...(ignored === null ? [] : [`⚠️ ${ignored}`]),
494
+ ...(lint === null ? [] : [`commitlint: the repository has a commitlint config — the commitlint config at ${lint.path} governs the subject format; this measurement is advisory`]),
495
+ established === true ? 'convention: already established — a declaration or an approved card is in force; this measurement is advisory'
496
+ : established === null ? 'convention: git.commit_format cannot be read — see git:convention show' : 'convention: none established — /commit offers the result below once',
497
+ history.windowExtended
498
+ ? `sample fewer than ${MIN_N} since ${MEASURE_SINCE} — sampled the newest ${history.commits.length} regardless of age on ${history.trunk} · classifier ${CLASSIFIER_VERSION}`
499
+ : `sample ${history.commits.length} commit(s) on ${history.trunk} since ${MEASURE_SINCE} · classifier ${CLASSIFIER_VERSION}`,
500
+ ` eligible ${m.eligible} (excluded: bots ${m.excluded.bots}, automation ${m.excluded.automation}, bulk ${m.excluded.bulk}) · authors ${m.authors}`
501
+ + (m.capped ? ` · capped per author per half → ${m.cappedTotal}` : ' · uncapped (fewer than three authors)'),
502
+ ...m.families.map((x) => ` ${x.family.padEnd(20)} ${String(x.count).padStart(4)} ${pct(x.share)}`),
503
+ `halves newer ${m.newer.family ?? '—'} ${pct(m.newer.share)} · older ${m.older.family ?? '—'} ${pct(m.older.share)} — ${m.halvesAgree ? 'agree' : 'disagree'}`,
504
+ m.established !== null
505
+ ? `verdict established: ${m.established}${m.migrating ? ` (migrating to ${m.established} — ${m.migratedBy === 'recent-window' ? `the newest ${m.recent.n} commits` : 'the newer half'} alone clear the bar)` : ''} — bar n ≥ ${MIN_N}, share ≥ ${pct(m.bar)}`
506
+ : `verdict below the bar (${m.reasons.join('; ')}) — strongest: ${m.strongest.join(', ') || 'none with a grammar'}`,
507
+ b.pattern !== null
508
+ ? `branches ${b.sampled} sampled — proposed branch_pattern "${b.pattern}" (${pct(b.share)})`
509
+ : `branches ${b.sampled} sampled — no clear pattern`,
510
+ `update observed ${u.observed} (${u.baseMerges} of ${u.merges} merge(s) bring the default branch into a topic branch) — shown, never adopted`,
511
+ ];
512
+ if (team !== null) {
513
+ out.push(`team file ${chosen === undefined ? 'for the measured result' : `for --family ${chosen}`} — a human creates and commits ${CARRIER_PATH}, or init --yes creates it on the user's yes; this verb writes nothing:`);
514
+ out.push(...team.trimEnd().split('\n').map((l) => ` ${l}`));
515
+ }
516
+ if (chosen !== undefined && card !== null) {
517
+ // Unindented: the card is saved as printed, and its frontmatter must open the file.
518
+ out.push(`card for ${APPROVED_CARD}, save the lines below as they are:`);
519
+ out.push(...card.trimEnd().split('\n'));
520
+ }
521
+ return { code: 0, out, err: [] };
522
+ }
523
+
524
+ /**
525
+ * Create `.git-convention.yml` once, after the user's yes this turn (owner
526
+ * decision 2026-10-07). It never overwrites or edits a carrier under either
527
+ * name, never writes `update_strategy`, and never stages or commits.
528
+ */
529
+ export function initCommand(args: readonly string[], cwd: string): GitConventionResult {
530
+ let yes = false;
531
+ const rest: string[] = [];
532
+ for (const a of args) {
533
+ if (a === '--yes') yes = true;
534
+ else rest.push(a);
535
+ }
536
+ const f = _flags(rest, ['commit-format', 'branch-pattern']);
537
+ if (f.bad !== null || f.positional.length > 0) return { code: 2, out: [], err: [`unknown argument: ${f.bad ?? f.positional[0]}`, USAGE] };
538
+ const { root, git } = conventionRoot(cwd);
539
+ if (!git) return { code: 1, out: [], err: ['not a git repository — the carrier lives at a repository root'] };
540
+ const existing = [CARRIER_PATH, IGNORED_CARRIER_PATH].find((name) => fs.existsSync(path.join(root, name)));
541
+ if (existing !== undefined) return { code: 1, out: [], err: [`${existing} already exists at ${root} — init creates the file once and never changes it; nothing was written`] };
542
+ if (!yes) return { code: 1, out: [], err: ['init writes only on the user\'s explicit yes this turn — pass --yes; nothing was written'] };
543
+
544
+ let format = f.values['commit-format'] ?? null;
545
+ let pattern = f.values['branch-pattern'] ?? null;
546
+ if (format === null || pattern === null) {
547
+ const history = readHistory(cwd);
548
+ if (history !== null && !('unresolved' in history)) {
549
+ const family = measureSubjects(history.commits).established;
550
+ if (format === null && family !== null) format = formatForFamily(family);
551
+ if (pattern === null) pattern = measureBranches(history.branches).pattern;
552
+ }
553
+ }
554
+ for (const [key, value] of [['commit_format', format], ['branch_pattern', pattern]] as const) {
555
+ const why = value === null ? null : invalidReason(key, value);
556
+ if (why !== null) return { code: 1, out: [], err: [`git.${key}: ${why}; nothing was written`] };
557
+ }
558
+ if (format === null && pattern === null) {
559
+ return { code: 1, out: [], err: ['nothing to write — measure proposes neither a commit_format nor a branch_pattern; pass --commit-format or --branch-pattern'] };
560
+ }
561
+ const content = ['git:', ...(format === null ? [] : [` commit_format: ${format}`]), ...(pattern === null ? [] : [` branch_pattern: "${pattern}"`]), ''].join('\n');
562
+ try {
563
+ fs.writeFileSync(path.join(root, CARRIER_PATH), content, { flag: 'wx' });
564
+ } catch {
565
+ return { code: 1, out: [], err: [`${CARRIER_PATH} could not be created at ${root} (it may have appeared meanwhile); nothing was written`] };
566
+ }
567
+ return {
568
+ code: 0,
569
+ out: [`created ${CARRIER_PATH} at ${root} — NOT committed; review and commit it:`, ...content.trimEnd().split('\n')],
570
+ err: [],
571
+ };
572
+ }
573
+
574
+ export const SUBCOMMANDS: Readonly<Record<string, (args: readonly string[], cwd: string, stdin?: string) => GitConventionResult>> = {
575
+ show: (args, cwd) => showConvention(args, cwd),
576
+ subject: (args, cwd, stdin) => subjectCommand(args, cwd, stdin),
577
+ ticket: (args, cwd) => ticketCommand(args, cwd),
578
+ branch: (args, cwd) => branchCommand(args, cwd),
579
+ measure: (args, cwd) => measureCommand(args, cwd),
580
+ init: (args, cwd) => initCommand(args, cwd),
581
+ // Prints as it runs; a later `--repo` in `args` overrides the directory.
582
+ sync: (args, cwd) => ({ code: syncPrBranch(['--repo', cwd, ...args]) as GitConventionResult['code'], out: [], err: [] }),
583
+ };
584
+
585
+ const USAGE = [
586
+ 'usage: agent-config git:convention show [--json] [--base REF] [--key KEY]... (a pull request passes --base origin/<its base>)',
587
+ ' agent-config git:convention subject [--format F | --family F] [--json] (subjects on stdin)',
588
+ ' agent-config git:convention ticket [BRANCH] [--keys "DEV, OPS"] [--json]',
589
+ ' agent-config git:convention branch --slug S [--type T] [--ticket K] [--pattern P] [--json]',
590
+ ' agent-config git:convention measure [--limit N] [--family F] [--json] (proposes a convention from the history; writes nothing)',
591
+ ' agent-config git:convention init --yes [--commit-format F] [--branch-pattern P] (creates .git-convention.yml once, on the user\'s yes; never overwrites, never commits)',
592
+ ' agent-config git:convention sync [--base REF] [--dry-run] [--auto-resolve-generated] [--quiet] (without --base: the default branch)',
593
+ ].join('\n');
594
+
595
+ export function runGitConvention(argv: readonly string[], cwd: string, stdin?: string): GitConventionResult {
596
+ const [sub, ...rest] = argv;
597
+ if (sub === '-h' || sub === '--help') return { code: 0, out: [USAGE], err: [] };
598
+ const handler = sub === undefined ? undefined : SUBCOMMANDS[sub];
599
+ if (handler === undefined) {
600
+ return { code: 2, out: [], err: [sub === undefined ? USAGE : `unknown subcommand: ${sub}`, ...(sub === undefined ? [] : [USAGE])] };
601
+ }
602
+ return handler(rest, cwd, stdin);
603
+ }
604
+
605
+ /**
606
+ * Every chunk to EOF, awaited. A synchronous read of fd 0 returns early on a
607
+ * pipe with no data yet, so a late writer or a batch past one pipe buffer read
608
+ * as no subjects at all. A terminal is not read: nothing was piped, and waiting
609
+ * on it would look like a hang.
610
+ */
611
+ async function _stdin(): Promise<string> {
612
+ if (process.stdin.isTTY) return '';
613
+ const chunks: Buffer[] = [];
614
+ for await (const chunk of process.stdin) chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk)));
615
+ return Buffer.concat(chunks).toString('utf-8');
616
+ }
617
+
618
+ export async function main(argv: readonly string[] = process.argv.slice(2)): Promise<number> {
619
+ const result = runGitConvention(argv, process.cwd(), argv[0] === 'subject' ? await _stdin() : undefined);
620
+ for (const line of result.out) process.stdout.write(`${line}\n`);
621
+ for (const line of result.err) process.stderr.write(`${line}\n`);
622
+ return result.code;
623
+ }
624
+
625
+ function _isCliEntry(): boolean {
626
+ if (process.argv[1] === undefined) return false;
627
+ if (import.meta.url === pathToFileURL(path.resolve(process.argv[1])).href) return true;
628
+ try {
629
+ return fs.realpathSync(fileURLToPath(import.meta.url)) === fs.realpathSync(path.resolve(process.argv[1]));
630
+ } catch {
631
+ return false;
632
+ }
633
+ }
634
+
635
+ if (_isCliEntry()) {
636
+ process.exitCode = await main();
637
+ }