@event4u/agent-config 16.3.0 → 16.5.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 (532) 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 +178 -78
  5. package/README.md +2 -2
  6. package/agents/templates/.ai-council.yml.example +26 -8
  7. package/dist/agent-src/commands/analyze/inbox.md +10 -7
  8. package/dist/agent-src/commands/bug/investigate.md +1 -1
  9. package/dist/agent-src/commands/commit/in-chunks.md +40 -31
  10. package/dist/agent-src/commands/commit.md +72 -33
  11. package/dist/agent-src/commands/condense.md +2 -8
  12. package/dist/agent-src/commands/council/debate.md +11 -7
  13. package/dist/agent-src/commands/council/default.md +10 -9
  14. package/dist/agent-src/commands/council.md +1 -1
  15. package/dist/agent-src/commands/design.md +1 -1
  16. package/dist/agent-src/commands/estimate-ticket.md +1 -1
  17. package/dist/agent-src/commands/feature/explore.md +3 -3
  18. package/dist/agent-src/commands/feature/plan.md +1 -1
  19. package/dist/agent-src/commands/fix/ci.md +17 -3
  20. package/dist/agent-src/commands/fix/commit-messages.md +48 -23
  21. package/dist/agent-src/commands/fix/pr-comments.md +3 -6
  22. package/dist/agent-src/commands/implement-ticket.md +3 -3
  23. package/dist/agent-src/commands/memory/add.md +4 -16
  24. package/dist/agent-src/commands/memory/load.md +5 -6
  25. package/dist/agent-src/commands/memory/promote.md +3 -16
  26. package/dist/agent-src/commands/mission/upgrade.md +3 -2
  27. package/dist/agent-src/commands/optimize/agents-dir.md +2 -2
  28. package/dist/agent-src/commands/optimize/deep.md +4 -2
  29. package/dist/agent-src/commands/optimize/rtk.md +4 -26
  30. package/dist/agent-src/commands/pr/create/description-only.md +18 -15
  31. package/dist/agent-src/commands/pr/create.md +42 -34
  32. package/dist/agent-src/commands/pr/merge.md +136 -9
  33. package/dist/agent-src/commands/prepare-for-review.md +13 -11
  34. package/dist/agent-src/commands/project/analyze.md +7 -35
  35. package/dist/agent-src/commands/refine-ticket.md +1 -1
  36. package/dist/agent-src/commands/review/changes.md +14 -19
  37. package/dist/agent-src/commands/roadmap/next.md +10 -1
  38. package/dist/agent-src/commands/roadmap/process-full.md +52 -38
  39. package/dist/agent-src/commands/roadmap/resolve-blockers.md +64 -14
  40. package/dist/agent-src/commands/worktree/create.md +7 -3
  41. package/dist/agent-src/commands/worktree/verify.md +2 -1
  42. package/dist/agent-src/contexts/communication/rules-auto/think-before-action-mechanics.md +5 -3
  43. package/dist/agent-src/contexts/communication/rules-auto/token-efficiency-mechanics.md +7 -9
  44. package/dist/agent-src/contexts/contracts/command-suggestion-flow.md +8 -6
  45. package/dist/agent-src/contexts/contracts/frugality-charter.md +8 -5
  46. package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +1 -1
  47. package/dist/agent-src/contexts/execution/auto-orchestration-activation.md +0 -1
  48. package/dist/agent-src/contexts/execution/evidence-discipline.md +2 -2
  49. package/dist/agent-src/contexts/execution/non-interactive-contract.md +5 -8
  50. package/dist/agent-src/contexts/execution/rdp-gate.md +4 -4
  51. package/dist/agent-src/contexts/execution/roadmap-execution-contract.md +9 -8
  52. package/dist/agent-src/contexts/execution/roadmap-process-loop.md +67 -52
  53. package/dist/agent-src/contexts/execution/subagent-routing.md +8 -8
  54. package/dist/agent-src/contexts/execution/subagent-steering.md +6 -4
  55. package/dist/agent-src/contexts/execution/terminal-states.md +2 -2
  56. package/dist/agent-src/contexts/execution/toolchain-resolver.md +4 -10
  57. package/dist/agent-src/contexts/subagent-configuration.md +1 -1
  58. package/dist/agent-src/guidelines/agent-infra/active-remediation-mechanics.md +39 -0
  59. package/dist/agent-src/guidelines/agent-infra/context-hygiene-mechanics.md +1 -1
  60. package/dist/agent-src/guidelines/agent-infra/cross-source-consistency-mechanics.md +8 -10
  61. package/dist/agent-src/guidelines/agent-infra/frontier-reasoning-operating-profile.md +3 -2
  62. package/dist/agent-src/guidelines/agent-infra/layered-settings.md +13 -1
  63. package/dist/agent-src/guidelines/agent-infra/roadmap-progress-mechanics.md +1 -1
  64. package/dist/agent-src/guidelines/agent-infra/self-improvement-pipeline.md +10 -3
  65. package/dist/agent-src/guidelines/agent-infra/size-and-scope.md +36 -0
  66. package/dist/agent-src/guidelines/design-antipatterns.md +1 -1
  67. package/dist/agent-src/guidelines/php/git.md +15 -2
  68. package/dist/agent-src/rules/active-remediation.md +0 -1
  69. package/dist/agent-src/rules/analysis-skill-routing.md +0 -1
  70. package/dist/agent-src/rules/architecture.md +0 -1
  71. package/dist/agent-src/rules/artifact-drafting-protocol.md +0 -1
  72. package/dist/agent-src/rules/artifact-engagement-recording.md +0 -1
  73. package/dist/agent-src/rules/augment-edit-discipline.md +0 -1
  74. package/dist/agent-src/rules/autonomous-execution.md +0 -1
  75. package/dist/agent-src/rules/brand-consistency.md +0 -1
  76. package/dist/agent-src/rules/brand-source-of-truth.md +0 -1
  77. package/dist/agent-src/rules/broken-access-control.md +0 -1
  78. package/dist/agent-src/rules/cli-output-handling.md +0 -1
  79. package/dist/agent-src/rules/code-comment-discipline.md +0 -1
  80. package/dist/agent-src/rules/code-provenance.md +0 -1
  81. package/dist/agent-src/rules/command-suggestion-policy.md +0 -1
  82. package/dist/agent-src/rules/commit-conventions.md +1 -2
  83. package/dist/agent-src/rules/communication-through-line.md +1 -2
  84. package/dist/agent-src/rules/content-quoting-floor.md +1 -2
  85. package/dist/agent-src/rules/context-hygiene.md +5 -5
  86. package/dist/agent-src/rules/copilot-routing.md +1 -2
  87. package/dist/agent-src/rules/council-availability.md +4 -4
  88. package/dist/agent-src/rules/cross-source-consistency.md +4 -6
  89. package/dist/agent-src/rules/decision-revisit-gate.md +2 -3
  90. package/dist/agent-src/rules/delegation-policy.md +2 -3
  91. package/dist/agent-src/rules/design-fidelity.md +0 -1
  92. package/dist/agent-src/rules/design-review-after-ui-write.md +3 -3
  93. package/dist/agent-src/rules/devcontainer-routing.md +1 -2
  94. package/dist/agent-src/rules/doc-screenshot-hygiene.md +0 -1
  95. package/dist/agent-src/rules/docker-commands.md +0 -1
  96. package/dist/agent-src/rules/domain-adoption-policy.md +0 -1
  97. package/dist/agent-src/rules/domain-safety-disclaimer.md +0 -1
  98. package/dist/agent-src/rules/domain-safety-pii.md +0 -1
  99. package/dist/agent-src/rules/domain-safety-retention.md +0 -1
  100. package/dist/agent-src/rules/downstream-changes.md +0 -1
  101. package/dist/agent-src/rules/engineering-safety-floor.md +0 -1
  102. package/dist/agent-src/rules/external-code-graph-interop.md +0 -1
  103. package/dist/agent-src/rules/external-reference-deep-dive.md +0 -1
  104. package/dist/agent-src/rules/fast-path-marker-visibility.md +1 -2
  105. package/dist/agent-src/rules/finance-safety-floor.md +0 -1
  106. package/dist/agent-src/rules/fix-what-you-see.md +6 -32
  107. package/dist/agent-src/rules/framework-neutrality-in-generic-skills.md +0 -1
  108. package/dist/agent-src/rules/git-history-discipline.md +1 -2
  109. package/dist/agent-src/rules/guidelines.md +0 -1
  110. package/dist/agent-src/rules/history-discipline.md +0 -1
  111. package/dist/agent-src/rules/icon-consistency.md +0 -1
  112. package/dist/agent-src/rules/image-likeness-and-rights.md +0 -1
  113. package/dist/agent-src/rules/improve-before-implement.md +0 -1
  114. package/dist/agent-src/rules/invite-challenge.md +0 -1
  115. package/dist/agent-src/rules/laravel-routing.md +1 -2
  116. package/dist/agent-src/rules/laravel-translations.md +0 -1
  117. package/dist/agent-src/rules/legal-safety-floor.md +0 -1
  118. package/dist/agent-src/rules/lethal-trifecta-guard.md +0 -1
  119. package/dist/agent-src/rules/linked-projects-onboarding-gate.md +0 -1
  120. package/dist/agent-src/rules/low-impact-corpus-privacy-floor.md +0 -1
  121. package/dist/agent-src/rules/markdown-safe-codeblocks.md +0 -1
  122. package/dist/agent-src/rules/media-governance-routing.md +1 -2
  123. package/dist/agent-src/rules/media-sync-ground-truth.md +0 -1
  124. package/dist/agent-src/rules/minimal-safe-diff.md +0 -1
  125. package/dist/agent-src/rules/missing-skill-recovery.md +0 -1
  126. package/dist/agent-src/rules/missing-tool-handling.md +0 -1
  127. package/dist/agent-src/rules/model-recommendation.md +0 -1
  128. package/dist/agent-src/rules/neighbour-precedence.md +64 -0
  129. package/dist/agent-src/rules/no-attribution-footers.md +0 -1
  130. package/dist/agent-src/rules/no-decorative-emojis-in-git-surfaces.md +0 -1
  131. package/dist/agent-src/rules/no-pr-progress-comments.md +0 -1
  132. package/dist/agent-src/rules/no-roadmap-references.md +0 -1
  133. package/dist/agent-src/rules/notes-first-reasoning.md +0 -1
  134. package/dist/agent-src/rules/onboarding-gate.md +0 -1
  135. package/dist/agent-src/rules/output-discipline.md +0 -1
  136. package/dist/agent-src/rules/package-ci-checks.md +0 -1
  137. package/dist/agent-src/rules/persona-governance.md +2 -3
  138. package/dist/agent-src/rules/php-coding.md +0 -1
  139. package/dist/agent-src/rules/prefer-enums-over-literals.md +0 -1
  140. package/dist/agent-src/rules/preservation-guard.md +0 -1
  141. package/dist/agent-src/rules/provider-lifecycle-discipline.md +2 -3
  142. package/dist/agent-src/rules/question-not-instruction.md +0 -1
  143. package/dist/agent-src/rules/reviewer-awareness.md +0 -1
  144. package/dist/agent-src/rules/roadmap-ci-steps-policy.md +0 -1
  145. package/dist/agent-src/rules/roadmap-progress-sync.md +3 -6
  146. package/dist/agent-src/rules/role-mode-adherence.md +0 -1
  147. package/dist/agent-src/rules/rule-type-governance.md +0 -1
  148. package/dist/agent-src/rules/runtime-safety.md +0 -1
  149. package/dist/agent-src/rules/scale-discipline.md +0 -1
  150. package/dist/agent-src/rules/secret-vcs-guard.md +0 -1
  151. package/dist/agent-src/rules/security-sensitive-stop.md +0 -1
  152. package/dist/agent-src/rules/self-repair-loop.md +0 -1
  153. package/dist/agent-src/rules/senior-engineering-discipline.md +0 -1
  154. package/dist/agent-src/rules/session-canary.md +0 -1
  155. package/dist/agent-src/rules/settings-ask-protocol.md +5 -6
  156. package/dist/agent-src/rules/size-enforcement.md +0 -1
  157. package/dist/agent-src/rules/skill-improvement-trigger.md +2 -3
  158. package/dist/agent-src/rules/skill-quality.md +0 -1
  159. package/dist/agent-src/rules/slash-command-routing-policy.md +0 -1
  160. package/dist/agent-src/rules/source-confidentiality.md +0 -1
  161. package/dist/agent-src/rules/source-discovery-gate.md +0 -1
  162. package/dist/agent-src/rules/source-of-truth.md +0 -1
  163. package/dist/agent-src/rules/spreadsheet-source-quality.md +1 -2
  164. package/dist/agent-src/rules/strategy-safety-floor.md +0 -1
  165. package/dist/agent-src/rules/symfony-routing.md +1 -2
  166. package/dist/agent-src/rules/think-before-action.md +0 -1
  167. package/dist/agent-src/rules/token-budget-discipline.md +14 -48
  168. package/dist/agent-src/rules/token-efficiency.md +0 -1
  169. package/dist/agent-src/rules/token-optimizer-maintenance.md +0 -1
  170. package/dist/agent-src/rules/tool-safety.md +0 -1
  171. package/dist/agent-src/rules/ui-audit-gate.md +1 -2
  172. package/dist/agent-src/rules/untrusted-input-defense.md +0 -1
  173. package/dist/agent-src/rules/upstream-proposal.md +0 -1
  174. package/dist/agent-src/rules/user-interaction.md +0 -1
  175. package/dist/agent-src/rules/user-interrupt-priority.md +0 -1
  176. package/dist/agent-src/scripts/gate_budget.ts +47 -23
  177. package/dist/agent-src/scripts/gate_execute.ts +12 -4
  178. package/dist/agent-src/skills/accessibility-auditor/data/aria-patterns.csv +2 -0
  179. package/dist/agent-src/skills/accessibility-auditor/data/manifest.json +3 -3
  180. package/dist/agent-src/skills/ai-council/SKILL.md +7 -4
  181. package/dist/agent-src/skills/ai-council/references/cost-and-redaction.md +21 -11
  182. package/dist/agent-src/skills/ai-council/references/procedure.md +12 -6
  183. package/dist/agent-src/skills/analysis-autonomous-mode/SKILL.md +1 -1
  184. package/dist/agent-src/skills/bug-analyzer/SKILL.md +1 -1
  185. package/dist/agent-src/skills/canvas-design/SKILL.md +4 -2
  186. package/dist/agent-src/skills/command-routing/SKILL.md +3 -4
  187. package/dist/agent-src/skills/conventional-commits-writing/SKILL.md +127 -139
  188. package/dist/agent-src/skills/corpus-grounding/ATTRIBUTION.md +39 -0
  189. package/dist/agent-src/skills/corpus-grounding/SKILL.md +8 -2
  190. package/dist/agent-src/skills/database/data/manifest.json +2 -2
  191. package/dist/agent-src/skills/database/data/query-tuning.csv +13 -13
  192. package/dist/agent-src/skills/design-intelligence/references/integration-mapping.md +13 -10
  193. package/dist/agent-src/skills/design-system-capture/SKILL.md +0 -3
  194. package/dist/agent-src/skills/estimate-ticket/SKILL.md +1 -1
  195. package/dist/agent-src/skills/fe-design/references/design-patterns.md +49 -2
  196. package/dist/agent-src/skills/feature-planning/SKILL.md +1 -1
  197. package/dist/agent-src/skills/frontend-render-security/SKILL.md +9 -0
  198. package/dist/agent-src/skills/git-workflow/SKILL.md +44 -44
  199. package/dist/agent-src/skills/git-workflow/references/branch-update.md +312 -0
  200. package/dist/agent-src/skills/git-workflow/references/commit-subject.md +205 -0
  201. package/dist/agent-src/skills/iconography/SKILL.md +4 -2
  202. package/dist/agent-src/skills/image-provider-routing/SKILL.md +16 -5
  203. package/dist/agent-src/skills/jira-integration/SKILL.md +3 -3
  204. package/dist/agent-src/skills/logo-generation/SKILL.md +12 -8
  205. package/dist/agent-src/skills/merge-conflicts/SKILL.md +10 -4
  206. package/dist/agent-src/skills/po-discovery/SKILL.md +1 -1
  207. package/dist/agent-src/skills/refine-ticket/SKILL.md +4 -4
  208. package/dist/agent-src/skills/roadmap-writing/SKILL.md +2 -2
  209. package/dist/agent-src/skills/skill-improvement-pipeline/SKILL.md +4 -2
  210. package/dist/agent-src/skills/source-discovery/SKILL.md +1 -1
  211. package/dist/agent-src/skills/svg-authoring/SKILL.md +318 -0
  212. package/dist/agent-src/skills/tailwind-engineer/SKILL.md +3 -1
  213. package/dist/agent-src/skills/testing-anti-patterns/SKILL.md +1 -1
  214. package/dist/agent-src/skills/using-git-worktrees/SKILL.md +1 -1
  215. package/dist/agent-src/skills/verify-repair-loop/SKILL.md +2 -2
  216. package/dist/agent-src/skills/wireframe/SKILL.md +5 -2
  217. package/dist/agent-src/templates/AGENTS.md +1 -1
  218. package/dist/agent-src/templates/agent-settings.md +46 -129
  219. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +3 -3
  220. package/dist/agent-src/templates/command.md +2 -2
  221. package/dist/agent-src/templates/roadmaps.md +6 -1
  222. package/dist/agent-src/templates/scripts/work_engine/_lib/agent_settings.ts +0 -6
  223. package/dist/agent-src/templates/scripts/work_engine/directives/backend/_self_fix.ts +11 -7
  224. package/dist/agent-src/templates/scripts/work_engine/hooks/builtin/decision_trace.ts +3 -2
  225. package/dist/agent-src/templates/scripts/work_engine/hooks/builtin/memory_visibility.ts +2 -1
  226. package/dist/agent-src/templates/scripts/work_engine/hooks/settings.ts +0 -6
  227. package/dist/agent-src/templates/scripts/work_engine/scoring/decision_engine.ts +9 -12
  228. package/dist/agent-src/templates/scripts/work_engine/scoring/memory_visibility.ts +2 -1
  229. package/dist/agent-src/templates/skill.md +1 -1
  230. package/dist/cli/commands/uiRender.js +201 -4
  231. package/dist/cli/commands/uiRenderAsset.js +1308 -0
  232. package/dist/cli/commands/uiRenderAssetCompare.js +752 -0
  233. package/dist/cli/commands/uiRenderAssetGrid.js +265 -0
  234. package/dist/cli/commands/uiRenderAssetGrounds.js +323 -0
  235. package/dist/cli/commands/uiRenderAssetIsolation.js +85 -0
  236. package/dist/cli/commands/uiRenderAssetTypes.js +145 -0
  237. package/dist/cli/main.js +47 -1
  238. package/dist/cli/registry.js +2 -1
  239. package/dist/cli-delegate/check_update_banner.js +195 -119
  240. package/dist/cli-delegate/{chunk-S4UMZNES.js → chunk-4DBG5K7M.js} +5 -5
  241. package/dist/cli-delegate/{chunk-TRI6DQZ6.js → chunk-5GPULQBE.js} +60 -42
  242. package/dist/cli-delegate/{chunk-JQVYKIZA.js → chunk-6SRJTYJS.js} +33 -177
  243. package/dist/cli-delegate/chunk-6V5FMA3P.js +186 -0
  244. package/dist/cli-delegate/chunk-6YQC2HLF.js +415 -0
  245. package/dist/cli-delegate/{chunk-E4XIZDIB.js → chunk-7HKRE54K.js} +1 -64
  246. package/dist/cli-delegate/{chunk-7HQ52DHU.js → chunk-AL3RZ22D.js} +1 -1
  247. package/dist/cli-delegate/{chunk-DBH4AHDK.js → chunk-ED7KCMLB.js} +9 -11
  248. package/dist/cli-delegate/{chunk-NXEILF2K.js → chunk-F3QDG2GT.js} +481 -72
  249. package/dist/cli-delegate/{chunk-CQWX336L.js → chunk-G5VVIZRC.js} +3 -3
  250. package/dist/cli-delegate/{chunk-JY2I2DXV.js → chunk-H76PHZBI.js} +137 -60
  251. package/dist/cli-delegate/chunk-IAYTIIQW.js +67 -0
  252. package/dist/cli-delegate/{chunk-LIYTLH6O.js → chunk-KXXWJTDO.js} +5 -10
  253. package/dist/cli-delegate/{chunk-T7L2QK3K.js → chunk-LQOCRFWT.js} +1 -1
  254. package/dist/cli-delegate/{chunk-S4YWNRKO.js → chunk-MDPPKQCQ.js} +34 -1
  255. package/dist/cli-delegate/chunk-OAFSJBHH.js +272 -0
  256. package/dist/cli-delegate/{chunk-GKE7ZVFA.js → chunk-PWX7CKMD.js} +1 -1
  257. package/dist/cli-delegate/{chunk-NDJLNC6Q.js → chunk-T6BP34WI.js} +1 -0
  258. package/dist/cli-delegate/{chunk-RQNNW7IF.js → chunk-T7XSJSUQ.js} +433 -632
  259. package/dist/cli-delegate/{chunk-NQ7WT43P.js → chunk-TMWYUOK4.js} +75 -12
  260. package/dist/cli-delegate/{chunk-EEHDXSYD.js → chunk-WQWXGIWB.js} +12 -273
  261. package/dist/cli-delegate/{chunk-QLDHIPWR.js → chunk-XQTPXKFA.js} +1 -1
  262. package/dist/cli-delegate/cmd_analyze_session.js +223 -43
  263. package/dist/cli-delegate/cmd_brand_status.js +3 -2
  264. package/dist/cli-delegate/cmd_conformance.js +489 -238
  265. package/dist/cli-delegate/cmd_converge.js +3 -3
  266. package/dist/cli-delegate/cmd_doctor.js +15 -12
  267. package/dist/cli-delegate/cmd_doctor_neighbours.js +11 -4
  268. package/dist/cli-delegate/cmd_explain.js +43 -19
  269. package/dist/cli-delegate/cmd_export.js +10 -10
  270. package/dist/cli-delegate/cmd_git_convention.js +1851 -0
  271. package/dist/cli-delegate/cmd_handoff.js +40 -21
  272. package/dist/cli-delegate/cmd_mcp_available.js +3 -2
  273. package/dist/cli-delegate/cmd_migrate.js +3 -3
  274. package/dist/cli-delegate/cmd_packs_active.js +4 -3
  275. package/dist/cli-delegate/cmd_prune.js +10 -10
  276. package/dist/cli-delegate/cmd_route_audit.js +7 -7
  277. package/dist/cli-delegate/cmd_route_explain.js +5 -5
  278. package/dist/cli-delegate/cmd_session_recycle.js +9 -7
  279. package/dist/cli-delegate/cmd_settings_check.js +54 -7
  280. package/dist/cli-delegate/cmd_settings_get.js +18 -8
  281. package/dist/cli-delegate/cmd_settings_migrate.js +10 -10
  282. package/dist/cli-delegate/cmd_settings_set.js +1 -1
  283. package/dist/cli-delegate/cmd_sync.js +10 -10
  284. package/dist/cli-delegate/cmd_uninstall.js +10 -10
  285. package/dist/cli-delegate/cmd_update.js +7 -7
  286. package/dist/cli-delegate/cmd_upgrade.js +7 -7
  287. package/dist/cli-delegate/cmd_validate.js +10 -10
  288. package/dist/cli-delegate/cmd_versions.js +5 -5
  289. package/dist/cli-delegate/gate_budget.js +1 -1
  290. package/dist/cli-delegate/gate_execute.js +2 -2
  291. package/dist/cli-delegate/roadmap_gates.js +2 -2
  292. package/dist/discovery/deprecation-report.md +1 -1
  293. package/dist/discovery/discovery-manifest.json +171 -107
  294. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  295. package/dist/discovery/discovery-manifest.summary.md +7 -7
  296. package/dist/discovery/dormancy-report.md +1 -1
  297. package/dist/discovery/orphan-report.md +1 -1
  298. package/dist/discovery/packs.json +41 -22
  299. package/dist/discovery/trust-report.md +3 -3
  300. package/dist/discovery/workspaces.json +16 -11
  301. package/dist/hooks/dispatch.js +2520 -1924
  302. package/dist/hooks/dispatch.sha256 +1 -1
  303. package/dist/hooks/svg_rules.chunk.cjs +1626 -0
  304. package/dist/hooks/svg_rules.chunk.cjs.sha256 +1 -0
  305. package/dist/install/install.mjs +462 -431
  306. package/dist/install/installThinLayer.js +40 -12
  307. package/dist/install/installedRuleLinks.js +105 -19
  308. package/dist/mcp/awesome-mcp-servers.row.md +1 -1
  309. package/dist/mcp/mcp-cloudflare-catalogue.json +2 -2
  310. package/dist/mcp/registry-manifest.json +5 -5
  311. package/dist/mcp/server.json +2 -2
  312. package/dist/mcp/server.mjs +3063 -2160
  313. package/dist/router.json +1 -1
  314. package/dist/scripts/_lib/agent_settings.js +15 -120
  315. package/dist/scripts/_lib/compile_time_toggles.js +12 -21
  316. package/dist/scripts/_lib/git_convention.js +232 -0
  317. package/dist/scripts/_lib/global_deploy_inventory.js +730 -0
  318. package/dist/scripts/_lib/installed_layer.js +344 -18
  319. package/dist/scripts/_lib/package_root.js +68 -0
  320. package/dist/scripts/_lib/rule_law_section.js +1 -1
  321. package/dist/scripts/_lib/scan_scope.js +105 -0
  322. package/dist/scripts/_lib/settings_removed_keys.js +168 -0
  323. package/dist/scripts/_lib/svg_dom.js +284 -0
  324. package/dist/scripts/_lib/svg_geometry.js +477 -0
  325. package/dist/scripts/_lib/svg_motion.js +179 -0
  326. package/dist/scripts/_lib/svg_rules.js +1337 -0
  327. package/dist/scripts/_lib/svg_urls.js +67 -0
  328. package/dist/scripts/_lib/thin_rules.js +80 -3
  329. package/dist/scripts/lint_svg_asset.js +324 -0
  330. package/dist/server/app.js +2 -1
  331. package/dist/server/gitKeysGate.js +105 -0
  332. package/dist/server/routes/settings.js +67 -8
  333. package/dist/server/routes/wizard.js +4 -0
  334. package/dist/server/schemas/settings.js +23 -81
  335. package/dist/shared/skillRanking.js +30 -4
  336. package/dist/ui/assets/{index-Cwq4d0hX.js → index-C3djEJah.js} +2 -2
  337. package/dist/ui/index.html +1 -1
  338. package/docs/MIGRATION.md +72 -1
  339. package/docs/contracts/settings-classes.md +35 -65
  340. package/docs/guidelines/agent-infra/active-remediation-mechanics.md +39 -0
  341. package/docs/guidelines/agent-infra/context-hygiene-mechanics.md +1 -1
  342. package/docs/guidelines/agent-infra/cross-source-consistency-mechanics.md +8 -10
  343. package/docs/guidelines/agent-infra/frontier-reasoning-operating-profile.md +3 -2
  344. package/docs/guidelines/agent-infra/layered-settings.md +13 -1
  345. package/docs/guidelines/agent-infra/roadmap-progress-mechanics.md +1 -1
  346. package/docs/guidelines/agent-infra/self-improvement-pipeline.md +10 -3
  347. package/docs/guidelines/agent-infra/size-and-scope.md +36 -0
  348. package/docs/guidelines/design-antipatterns.md +1 -1
  349. package/docs/guidelines/php/git.md +15 -2
  350. package/package.json +4 -3
  351. package/src/agent-src/scripts/gate_budget.ts +47 -23
  352. package/src/agent-src/scripts/gate_execute.ts +12 -4
  353. package/src/agent-src/templates/AGENTS.md +1 -1
  354. package/src/agent-src/templates/scripts/work_engine/_lib/agent_settings.ts +0 -6
  355. package/src/agent-src/templates/scripts/work_engine/directives/backend/_self_fix.ts +11 -7
  356. package/src/agent-src/templates/scripts/work_engine/hooks/builtin/decision_trace.ts +3 -2
  357. package/src/agent-src/templates/scripts/work_engine/hooks/builtin/memory_visibility.ts +2 -1
  358. package/src/agent-src/templates/scripts/work_engine/hooks/settings.ts +0 -6
  359. package/src/agent-src/templates/scripts/work_engine/scoring/decision_engine.ts +9 -12
  360. package/src/agent-src/templates/scripts/work_engine/scoring/memory_visibility.ts +2 -1
  361. package/src/config/agent-settings.template.yml +79 -312
  362. package/src/config/agents-paths.yml +16 -0
  363. package/src/config/assurance-capability-registry.json +7 -3
  364. package/src/config/ci-local-parity.yml +3 -0
  365. package/src/config/continuity-surface.json +3 -3
  366. package/src/config/discovery/packs.yml +17 -1
  367. package/src/config/evaluator-budgets.json +19 -6
  368. package/src/config/gate-coverage.yml +65 -23
  369. package/src/config/gate-violation-baselines.json +56 -16
  370. package/src/config/gitignore-block.txt +19 -0
  371. package/src/config/hook-bundle-budget.json +1 -1
  372. package/src/config/release-gate-locality.yml +2 -1
  373. package/src/config/routing-coverage-seed.json +55 -6
  374. package/src/config/rule-law-ceilings.json +12 -6
  375. package/src/config/rule-obligations.json +833 -0
  376. package/src/install/installThinLayer.ts +76 -10
  377. package/src/install/installedRuleLinks.ts +105 -17
  378. package/src/scripts/_cli/cmd_analyze_session.ts +9 -15
  379. package/src/scripts/_cli/cmd_conformance.ts +13 -2
  380. package/src/scripts/_cli/cmd_doctor.ts +10 -10
  381. package/src/scripts/_cli/cmd_doctor_neighbours.ts +133 -0
  382. package/src/scripts/_cli/cmd_explain.ts +72 -14
  383. package/src/scripts/_cli/cmd_git_convention.ts +637 -0
  384. package/src/scripts/_cli/cmd_settings_check.ts +66 -8
  385. package/src/scripts/_cli/cmd_settings_get.ts +18 -3
  386. package/src/scripts/_cli/doctor_execution.ts +72 -1
  387. package/src/scripts/_dispatch.bash +37 -2
  388. package/src/scripts/_lib/agent_settings.ts +15 -124
  389. package/src/scripts/_lib/blocked_by_marker.ts +1 -1
  390. package/src/scripts/_lib/compile_time_toggles.ts +12 -21
  391. package/src/scripts/_lib/dispatch_import_closure.ts +163 -0
  392. package/src/scripts/_lib/git_base_ref.ts +92 -0
  393. package/src/scripts/_lib/git_convention.ts +291 -0
  394. package/src/scripts/_lib/git_convention_carrier.ts +389 -0
  395. package/src/scripts/_lib/git_convention_grammar.ts +246 -0
  396. package/src/scripts/_lib/git_convention_measure.ts +344 -0
  397. package/src/scripts/_lib/global_deploy_inventory.ts +74 -0
  398. package/src/scripts/_lib/graph_feeder_record.ts +236 -13
  399. package/src/scripts/_lib/installed_layer.ts +448 -23
  400. package/src/scripts/_lib/knowledge_global.ts +14 -1
  401. package/src/scripts/_lib/module_reach.ts +456 -0
  402. package/src/scripts/_lib/neighbour_contradictions.ts +236 -0
  403. package/src/scripts/_lib/neighbour_tool_use.ts +8 -10
  404. package/src/scripts/_lib/ratification_artifact.ts +220 -1
  405. package/src/scripts/_lib/ratification_subject.ts +92 -0
  406. package/src/scripts/_lib/release_findings_ingest.ts +15 -7
  407. package/src/scripts/_lib/release_highlights.ts +5 -0
  408. package/src/scripts/_lib/rule_law_section.ts +1 -1
  409. package/src/scripts/_lib/rule_obligations.ts +205 -0
  410. package/src/scripts/_lib/self_repair.ts +1 -1
  411. package/src/scripts/_lib/settings_removed_keys.ts +173 -0
  412. package/src/scripts/_lib/svg_dom.ts +318 -0
  413. package/src/scripts/_lib/svg_geometry.ts +480 -0
  414. package/src/scripts/_lib/svg_motion.ts +208 -0
  415. package/src/scripts/_lib/svg_rules.ts +1453 -0
  416. package/src/scripts/_lib/svg_urls.ts +72 -0
  417. package/src/scripts/_lib/test_red_state.ts +5 -0
  418. package/src/scripts/_lib/thin_rules.ts +83 -3
  419. package/src/scripts/_lib/touched_file_quality.ts +142 -6
  420. package/src/scripts/_lib/verification_command.ts +59 -0
  421. package/src/scripts/_lib/verify_clause.ts +27 -17
  422. package/src/scripts/_lib/worker_budget.ts +1 -1
  423. package/src/scripts/adr/regenerate_index.ts +16 -1
  424. package/src/scripts/ai_council/config.ts +7 -7
  425. package/src/scripts/ai_council/modification_review.ts +100 -0
  426. package/src/scripts/ai_council/modification_review_questions.ts +90 -0
  427. package/src/scripts/ai_council/orchestrator.ts +5 -5
  428. package/src/scripts/ai_council/spend_gate.ts +18 -7
  429. package/src/scripts/ai_team/config.ts +11 -16
  430. package/src/scripts/audit_user_type_axis.ts +20 -8
  431. package/src/scripts/bench_ab_clone.ts +1 -2
  432. package/src/scripts/bench_concern_spawn_path.ts +129 -0
  433. package/src/scripts/bench_graph_feeder_latency.ts +584 -0
  434. package/src/scripts/check_agent_artifact_location.ts +36 -0
  435. package/src/scripts/check_branch_freshness.ts +147 -24
  436. package/src/scripts/check_enforcement_coverage.ts +130 -0
  437. package/src/scripts/check_evaluator_budgets.ts +4 -0
  438. package/src/scripts/check_finding_dispositions.ts +88 -25
  439. package/src/scripts/check_gate_coverage.ts +4 -3
  440. package/src/scripts/check_gate_reachability.ts +48 -1
  441. package/src/scripts/check_generator_sync.ts +48 -0
  442. package/src/scripts/check_hook_bundle_composition.ts +107 -0
  443. package/src/scripts/check_kernel_edit_ratified.ts +86 -6
  444. package/src/scripts/check_pack_size.ts +1 -1
  445. package/src/scripts/check_release_manifest_content.ts +189 -0
  446. package/src/scripts/check_standing_rule_delivery.ts +96 -0
  447. package/src/scripts/check_suppression_hygiene.ts +2 -5
  448. package/src/scripts/ci_settle.ts +42 -5
  449. package/src/scripts/classify_merge_risk.ts +320 -0
  450. package/src/scripts/closure_scan.ts +91 -1
  451. package/src/scripts/command_suggester/settings.ts +8 -108
  452. package/src/scripts/command_suggester/types.ts +4 -5
  453. package/src/scripts/consumer_matrix.ts +102 -0
  454. package/src/scripts/context_hygiene_hook.ts +13 -23
  455. package/src/scripts/cost/preflight.mjs +12 -1
  456. package/src/scripts/council_cli.ts +7 -7
  457. package/src/scripts/dispatch_r2_reviewer.ts +24 -11
  458. package/src/scripts/explain_run.ts +8 -13
  459. package/src/scripts/generate_git_convention_grammar.ts +127 -0
  460. package/src/scripts/generate_host_cost_table.ts +20 -3
  461. package/src/scripts/handoff_context_hook.ts +86 -37
  462. package/src/scripts/hook_manifest.json +1 -1
  463. package/src/scripts/hook_manifest.yaml +25 -6
  464. package/src/scripts/hooks/block_config_weakening.ts +48 -5
  465. package/src/scripts/hooks/block_plumbing_writes.ts +8 -4
  466. package/src/scripts/hooks/block_speaking_inbox_dir.ts +16 -1
  467. package/src/scripts/hooks/concern_registry.ts +2 -0
  468. package/src/scripts/hooks/delegation_nudge_hook.ts +2 -3
  469. package/src/scripts/hooks/design_pass_hook.ts +157 -3
  470. package/src/scripts/hooks/evidence_independence.ts +12 -4
  471. package/src/scripts/hooks/mcp_usage_observation_hook.ts +121 -0
  472. package/src/scripts/hooks/push_settle_hook.ts +4 -3
  473. package/src/scripts/hooks/rule_inject_hook.ts +44 -3
  474. package/src/scripts/hooks/state_io.ts +8 -4
  475. package/src/scripts/hooks/svg_obligation.ts +497 -0
  476. package/src/scripts/hooks/svg_rules_loader.ts +133 -0
  477. package/src/scripts/hooks/telemetry_usage_hook.ts +7 -46
  478. package/src/scripts/hooks/turn_end_gate_hook.ts +6 -3
  479. package/src/scripts/install-hooks.sh +42 -14
  480. package/src/scripts/install.ts +7 -31
  481. package/src/scripts/lint_blocker_citations.ts +198 -0
  482. package/src/scripts/lint_consolidation_lineage.ts +6 -3
  483. package/src/scripts/lint_design_quality.ts +60 -12
  484. package/src/scripts/lint_evidence_artifacts.ts +9 -0
  485. package/src/scripts/lint_hook_concern_budget.ts +10 -21
  486. package/src/scripts/lint_motion_authority_drift.ts +27 -0
  487. package/src/scripts/lint_pack_boundaries.ts +406 -28
  488. package/src/scripts/lint_roadmap_blockers.ts +282 -29
  489. package/src/scripts/lint_roadmap_complexity.ts +4 -2
  490. package/src/scripts/lint_rule_law_section.ts +151 -21
  491. package/src/scripts/lint_rule_skill_pack_reach.ts +17 -0
  492. package/src/scripts/lint_settings_classes.ts +1 -1
  493. package/src/scripts/lint_svg_asset.ts +365 -0
  494. package/src/scripts/lint_ticked_unmet_criteria.ts +165 -0
  495. package/src/scripts/lint_workflow_security.ts +12 -1
  496. package/src/scripts/measure_skill_ranker_baseline.ts +5 -0
  497. package/src/scripts/model_rule_injection.ts +3 -3
  498. package/src/scripts/onboarding_gate_hook.ts +7 -6
  499. package/src/scripts/print_required_checks.ts +15 -3
  500. package/src/scripts/probe_host_compliance.ts +33 -5
  501. package/src/scripts/probe_turnaround.ts +183 -3
  502. package/src/scripts/ratification_header.ts +77 -0
  503. package/src/scripts/refusal_envelope.ts +138 -0
  504. package/src/scripts/release_publication.ts +29 -3
  505. package/src/scripts/report_dispatch_import_closure.ts +76 -0
  506. package/src/scripts/report_installed_rule_links.ts +118 -1
  507. package/src/scripts/report_module_reach.ts +212 -0
  508. package/src/scripts/report_obligation_mechanism.ts +16 -18
  509. package/src/scripts/report_parked_blockers.ts +222 -0
  510. package/src/scripts/report_required_checks_drift.ts +196 -0
  511. package/src/scripts/report_skill_ranker_confusion.ts +103 -2
  512. package/src/scripts/report_standing_payload_by_host.ts +1 -1
  513. package/src/scripts/routing_doctor.ts +2 -2
  514. package/src/scripts/schemas/agent-settings.schema.json +17 -31
  515. package/src/scripts/schemas/command.schema.json +1 -1
  516. package/src/scripts/schemas/skill.schema.json +1 -1
  517. package/src/scripts/self_review_gate.ts +39 -2
  518. package/src/scripts/skill_tools/score_skill_relevance.ts +28 -19
  519. package/src/scripts/sync_pr_branch.ts +403 -132
  520. package/src/scripts/trigger_eval_grandfather.json +0 -16
  521. package/src/server/schemas/settings.ts +33 -177
  522. package/src/shared/skillRanking.ts +53 -4
  523. package/dist/cli-delegate/chunk-NYX3L2PZ.js +0 -99
  524. package/src/scripts/_lib/config_chain.ts +0 -477
  525. package/src/scripts/_lib/conformance_report.ts +0 -403
  526. package/src/scripts/_lib/eval_discrimination.ts +0 -95
  527. package/src/scripts/_lib/evaluator_promotion.ts +0 -225
  528. package/src/scripts/_lib/file_slicer.ts +0 -117
  529. package/src/scripts/_lib/legacy_boundary_map.ts +0 -228
  530. package/src/scripts/_lib/minimality_tiebreak.ts +0 -168
  531. package/src/scripts/_lib/overbuild_lens_contract.ts +0 -196
  532. package/src/scripts/_lib/role_split.ts +0 -338
@@ -0,0 +1,344 @@
1
+ /**
2
+ * Measures the convention an existing history already follows, so a project
3
+ * with no declaration is offered its own format instead of the shipped default.
4
+ *
5
+ * The core is pure — commits, branch names and merge subjects in, a verdict
6
+ * out — and the thresholds live here as constants: the reference page renders
7
+ * them from this module, so the bar a reader sees is the bar the code applies.
8
+ * `readHistory` is the one function that runs git.
9
+ *
10
+ * Every figure is a policy heuristic (council 2026-09-04), not a statistically
11
+ * derived threshold.
12
+ */
13
+ import { spawnSync } from 'node:child_process';
14
+
15
+ import { invalidReason } from './git_convention.js';
16
+ import { makeTargetDeps } from './git_convention_carrier.js';
17
+ import { classifySubject, COMMIT_TYPES, TICKET_GRAMMAR, type CommitFormat, type SubjectFamily } from './git_convention_grammar.js';
18
+
19
+ export const MEASURE_LIMIT = 200;
20
+ export const MEASURE_SINCE = '24 months ago';
21
+ export const MIN_N = 30;
22
+ /** The newest eligible commits read on their own for a recent switch the halves still average away. */
23
+ export const RECENT_WINDOW = MIN_N;
24
+ /** With three or more human authors, over the per-author-capped sample. */
25
+ export const SHARE_BAR = 0.8;
26
+ /** With one or two authors, uncapped: a cap of 20 would put `MIN_N` out of reach. */
27
+ export const SMALL_TEAM_SHARE_BAR = 0.9;
28
+ export const MIN_CAPPED_AUTHORS = 3;
29
+ export const AUTHOR_CAP_PER_HALF = 20;
30
+ export const BULK_IMPORT_FILES = 500;
31
+ /** Merged branches are usually deleted, so far fewer names survive than commits. */
32
+ export const MIN_BRANCHES = 10;
33
+ /** The revision of the families and exclusions; a card measured under another one is re-measured. */
34
+ export const CLASSIFIER_VERSION = '2026-10-06';
35
+
36
+ export const BOT_AUTHOR = /\[bot\]|dependabot|renovate|github-actions|semantic-release|release-please/i;
37
+ export const AUTOMATION_SUBJECT = /^Revert |^Merge |^chore\(release\)|^Bump |^v?\d+\.\d+\.\d+$/;
38
+
39
+ export interface HistoryCommit {
40
+ author: string;
41
+ email: string;
42
+ subject: string;
43
+ /** Files the commit touched, or null when unknown. */
44
+ files: number | null;
45
+ }
46
+
47
+ export interface FamilyShare {
48
+ family: SubjectFamily | 'other';
49
+ count: number;
50
+ share: number;
51
+ }
52
+
53
+ export interface HalfReading {
54
+ n: number;
55
+ family: SubjectFamily | 'other' | null;
56
+ share: number;
57
+ }
58
+
59
+ export interface SubjectMeasurement {
60
+ eligible: number;
61
+ excluded: { bots: number; automation: number; bulk: number };
62
+ authors: number;
63
+ capped: boolean;
64
+ cappedTotal: number;
65
+ bar: number;
66
+ families: FamilyShare[];
67
+ newer: HalfReading;
68
+ older: HalfReading;
69
+ halvesAgree: boolean;
70
+ /** The newest `RECENT_WINDOW` eligible commits, capped per author like the halves. */
71
+ recent: HalfReading;
72
+ /** Which reading showed the switch when `migrating`. */
73
+ migratedBy: 'newer-half' | 'recent-window' | null;
74
+ /** The family to propose, or null below the bar. */
75
+ established: SubjectFamily | null;
76
+ /** True when the newer half, or the newest window, clears the bar on a family other than the history's dominant one. */
77
+ migrating: boolean;
78
+ /** Why the history is below the bar; empty when a family is established. */
79
+ reasons: string[];
80
+ /** The two strongest families with a grammar, strongest first. */
81
+ strongest: SubjectFamily[];
82
+ }
83
+
84
+ function _key(c: HistoryCommit): string {
85
+ return (c.email || c.author).toLowerCase();
86
+ }
87
+
88
+ function _cap(commits: readonly HistoryCommit[]): HistoryCommit[] {
89
+ const seen = new Map<string, number>();
90
+ return commits.filter((c) => {
91
+ const k = _key(c);
92
+ const n = (seen.get(k) ?? 0) + 1;
93
+ seen.set(k, n);
94
+ return n <= AUTHOR_CAP_PER_HALF;
95
+ });
96
+ }
97
+
98
+ function _shares(commits: readonly HistoryCommit[]): FamilyShare[] {
99
+ const counts = new Map<SubjectFamily | 'other', number>();
100
+ for (const c of commits) {
101
+ const f = classifySubject(c.subject);
102
+ counts.set(f, (counts.get(f) ?? 0) + 1);
103
+ }
104
+ const total = commits.length;
105
+ return [...counts.entries()]
106
+ .map(([family, count]) => ({ family, count, share: total === 0 ? 0 : count / total }))
107
+ .sort((a, b) => b.count - a.count || a.family.localeCompare(b.family));
108
+ }
109
+
110
+ function _half(commits: readonly HistoryCommit[]): HalfReading {
111
+ const top = _shares(commits)[0];
112
+ return { n: commits.length, family: top?.family ?? null, share: top?.share ?? 0 };
113
+ }
114
+
115
+ function _clears(n: number, top: FamilyShare | HalfReading | undefined, bar: number): top is FamilyShare | HalfReading {
116
+ return n >= MIN_N && top !== undefined && top.family !== null && top.family !== 'other' && top.share >= bar;
117
+ }
118
+
119
+ /** `commits` newest first, as `git log` prints them. */
120
+ export function measureSubjects(commits: readonly HistoryCommit[]): SubjectMeasurement {
121
+ const excluded = { bots: 0, automation: 0, bulk: 0 };
122
+ const eligible = commits.filter((c) => {
123
+ if (BOT_AUTHOR.test(c.author) || BOT_AUTHOR.test(c.email)) excluded.bots++;
124
+ else if (AUTOMATION_SUBJECT.test(c.subject)) excluded.automation++;
125
+ else if (c.files !== null && c.files > BULK_IMPORT_FILES) excluded.bulk++;
126
+ else return true;
127
+ return false;
128
+ });
129
+ const authors = new Set(eligible.map(_key)).size;
130
+ const capped = authors >= MIN_CAPPED_AUTHORS;
131
+ const bar = capped ? SHARE_BAR : SMALL_TEAM_SHARE_BAR;
132
+ // Split before capping: a cap over the whole sample lets one author's
133
+ // newest commits fill the quota and empty the older half.
134
+ const cut = Math.ceil(eligible.length / 2);
135
+ const newerRaw = eligible.slice(0, cut);
136
+ const olderRaw = eligible.slice(cut);
137
+ const newerSample = capped ? _cap(newerRaw) : newerRaw;
138
+ const olderSample = capped ? _cap(olderRaw) : olderRaw;
139
+ const sample = [...newerSample, ...olderSample];
140
+ const families = _shares(sample);
141
+ const newer = _half(newerSample);
142
+ const older = _half(olderSample);
143
+ const halvesAgree = newer.family !== null && newer.family === older.family;
144
+ const recent = _half((capped ? _cap(eligible) : eligible).slice(0, RECENT_WINDOW));
145
+ const top = families[0];
146
+
147
+ let established: SubjectFamily | null = null;
148
+ let migrating = false;
149
+ let migratedBy: SubjectMeasurement['migratedBy'] = null;
150
+ const reasons: string[] = [];
151
+ if (eligible.length < MIN_N) reasons.push(`n ${eligible.length} < ${MIN_N}`);
152
+ if (top === undefined || top.family === 'other') reasons.push('no family with a grammar leads');
153
+ else if (top.share < bar) reasons.push(`${top.family} at ${pct(top.share)} < ${pct(bar)}`);
154
+ if (!halvesAgree && eligible.length > 0) reasons.push(`the halves disagree (newer ${newer.family ?? '—'}, older ${older.family ?? '—'})`);
155
+ if (reasons.length === 0 && top !== undefined) established = top.family as SubjectFamily;
156
+ else if (!halvesAgree && _clears(newer.n, newer, bar)) {
157
+ established = newer.family as SubjectFamily;
158
+ migrating = true;
159
+ migratedBy = 'newer-half';
160
+ }
161
+ // A switch younger than half the sample: both halves still read the old
162
+ // family, so only the newest window shows the history has moved on.
163
+ if (!migrating && recent.n >= RECENT_WINDOW && recent.family !== top?.family && _clears(recent.n, recent, bar)) {
164
+ established = recent.family as SubjectFamily;
165
+ migrating = true;
166
+ migratedBy = 'recent-window';
167
+ reasons.push(`the newest ${recent.n} read ${recent.family} at ${pct(recent.share)}, not ${top?.family ?? '—'}`);
168
+ }
169
+ return {
170
+ eligible: eligible.length,
171
+ excluded,
172
+ authors,
173
+ capped,
174
+ cappedTotal: sample.length,
175
+ bar,
176
+ families,
177
+ newer,
178
+ older,
179
+ halvesAgree,
180
+ recent,
181
+ migratedBy,
182
+ established,
183
+ migrating,
184
+ reasons: established === null || migrating ? reasons : [],
185
+ strongest: families.filter((f) => f.family !== 'other').slice(0, 2).map((f) => f.family as SubjectFamily),
186
+ };
187
+ }
188
+
189
+ export type BranchShape = '{type}/{ticket}-{slug}' | '{type}/{ticket}/{slug}' | '{ticket}-{slug}' | '{ticket}/{slug}' | '{type}/{slug}';
190
+
191
+ const BRANCH_TYPES = [...COMMIT_TYPES, 'feature', 'bugfix', 'hotfix'].join('|');
192
+ const BRANCH_SHAPES: ReadonlyArray<readonly [BranchShape, RegExp]> = [
193
+ ['{type}/{ticket}-{slug}', new RegExp(`^(${BRANCH_TYPES})/${TICKET_GRAMMAR}-[^/]+$`)],
194
+ ['{type}/{ticket}/{slug}', new RegExp(`^(${BRANCH_TYPES})/${TICKET_GRAMMAR}/[^/]+$`)],
195
+ ['{ticket}-{slug}', new RegExp(`^${TICKET_GRAMMAR}-[^/]+$`)],
196
+ ['{ticket}/{slug}', new RegExp(`^${TICKET_GRAMMAR}/[^/]+$`)],
197
+ ['{type}/{slug}', new RegExp(`^(${BRANCH_TYPES})/[^/]+$`)],
198
+ ];
199
+ const BOT_BRANCH = /^(dependabot|renovate|release-please)[/-]/;
200
+
201
+ export interface BranchMeasurement {
202
+ sampled: number;
203
+ shapes: { shape: BranchShape | 'other'; count: number; share: number }[];
204
+ /** A pattern the reader accepts, or null when no shape clears the bar. */
205
+ pattern: BranchShape | null;
206
+ share: number;
207
+ }
208
+
209
+ export function classifyBranch(name: string): BranchShape | 'other' {
210
+ return BRANCH_SHAPES.find(([, re]) => re.test(name))?.[0] ?? 'other';
211
+ }
212
+
213
+ /** Branch names without their remote prefix; the default branch and bots already excluded by the caller or here. */
214
+ export function measureBranches(names: readonly string[]): BranchMeasurement {
215
+ const sample = names.filter((n) => !BOT_BRANCH.test(n));
216
+ const counts = new Map<BranchShape | 'other', number>();
217
+ for (const n of sample) {
218
+ const s = classifyBranch(n);
219
+ counts.set(s, (counts.get(s) ?? 0) + 1);
220
+ }
221
+ const shapes = [...counts.entries()]
222
+ .map(([shape, count]) => ({ shape, count, share: count / sample.length }))
223
+ .sort((a, b) => b.count - a.count || a.shape.localeCompare(b.shape));
224
+ const top = shapes[0];
225
+ const clear = top !== undefined && top.shape !== 'other' && sample.length >= MIN_BRANCHES && top.share >= SHARE_BAR
226
+ && invalidReason('branch_pattern', top.shape) === null;
227
+ return { sampled: sample.length, shapes, pattern: clear ? (top.shape as BranchShape) : null, share: top?.share ?? 0 };
228
+ }
229
+
230
+ export interface UpdateStyle {
231
+ merges: number;
232
+ baseMerges: number;
233
+ observed: 'merge' | 'linear';
234
+ }
235
+
236
+ /** Merges of the default branch into a topic branch, read from their default subjects. */
237
+ export function measureUpdateStyle(mergeSubjects: readonly string[], defaultBranch: string): UpdateStyle {
238
+ const name = defaultBranch.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
239
+ const base = new RegExp(`^Merge (remote-tracking )?branch '(origin/)?${name}'`);
240
+ const baseMerges = mergeSubjects.filter((s) => base.test(s)).length;
241
+ return { merges: mergeSubjects.length, baseMerges, observed: baseMerges > 0 ? 'merge' : 'linear' };
242
+ }
243
+
244
+ /** The `git.commit_format` value a family maps to, or null when it maps to none. */
245
+ export function formatForFamily(family: SubjectFamily): CommitFormat | null {
246
+ if (family === 'conventional') return 'ticket-scope';
247
+ if (family === 'ticket-conventional') return 'ticket-conventional';
248
+ return null;
249
+ }
250
+
251
+ /** The `.git-convention.yml` content for a choice, or null when neither key has a value. `update_strategy` is never written. */
252
+ export function teamFile(family: SubjectFamily | null, pattern: BranchShape | null): string | null {
253
+ const format = family === null ? null : formatForFamily(family);
254
+ if (format === null && pattern === null) return null;
255
+ return ['git:', ...(format === null ? [] : [` commit_format: ${format}`]), ...(pattern === null ? [] : [` branch_pattern: "${pattern}"`]), ''].join('\n');
256
+ }
257
+
258
+ export function pct(x: number): string {
259
+ return `${Math.round(x * 100)} %`;
260
+ }
261
+
262
+ function _git(cwd: string, args: readonly string[]): string | null {
263
+ const r = spawnSync('git', args, { cwd, encoding: 'utf8', maxBuffer: 64 * 1024 * 1024 });
264
+ return r.status === 0 ? r.stdout : null;
265
+ }
266
+
267
+ export interface History {
268
+ trunk: string;
269
+ defaultBranch: string;
270
+ commits: HistoryCommit[];
271
+ branches: string[];
272
+ mergeSubjects: string[];
273
+ /** True when `MEASURE_SINCE` yielded fewer than `MIN_N` commits and the newest ones were read regardless of age. */
274
+ windowExtended: boolean;
275
+ }
276
+
277
+ /** No default branch could be resolved, so nothing was sampled; `reason` says why. */
278
+ export interface TrunkUnresolved {
279
+ unresolved: string;
280
+ }
281
+
282
+ /**
283
+ * The default branch as the carrier resolves it, or why there is none. A
284
+ * branch name guessed in its place (`main`, `master`, the current `HEAD`)
285
+ * samples another history and proposes a convention from it.
286
+ */
287
+ function _trunk(cwd: string): { trunk: string; remote: string; name: string } | TrunkUnresolved {
288
+ const ref = makeTargetDeps(cwd).defaultBranch();
289
+ if (ref === null) {
290
+ return { unresolved: 'no default branch could be resolved — origin names none and refs/remotes/origin/HEAD is not set' };
291
+ }
292
+ if (_git(cwd, ['rev-parse', '-q', '--verify', `${ref}^{commit}`]) === null) {
293
+ return { unresolved: `the default branch ${ref} is not in this checkout — fetch it first` };
294
+ }
295
+ const slash = ref.indexOf('/');
296
+ return { trunk: ref, remote: ref.slice(0, slash), name: ref.slice(slash + 1) };
297
+ }
298
+
299
+ /**
300
+ * The sample `measureSubjects`, `measureBranches` and `measureUpdateStyle` read,
301
+ * `TrunkUnresolved` without a default branch, or null outside a git repository.
302
+ */
303
+ export function readHistory(cwd: string, limit = MEASURE_LIMIT): History | TrunkUnresolved | null {
304
+ if (_git(cwd, ['rev-parse', '--git-dir']) === null) return null;
305
+ const t = _trunk(cwd);
306
+ if ('unresolved' in t) return t;
307
+ const read = (since: readonly string[]): HistoryCommit[] =>
308
+ (_git(cwd, ['log', t.trunk, '--no-merges', '-n', String(limit), ...since, '--pretty=format:%x1e%aN%x09%aE%x09%s', '--shortstat']) ?? '')
309
+ .split('\x1e')
310
+ .filter((r) => r.trim() !== '')
311
+ .map((r) => {
312
+ const [head = '', ...rest] = r.split('\n');
313
+ const [author = '', email = '', ...subject] = head.split('\t');
314
+ const stat = /(\d+) files? changed/.exec(rest.join('\n'));
315
+ return { author, email, subject: subject.join('\t'), files: stat === null ? null : Number(stat[1]) };
316
+ });
317
+ // A quiet or archived project has its convention in older commits; a
318
+ // window that samples nothing would report "below the bar" for a history
319
+ // that states its format plainly.
320
+ let commits = read([`--since=${MEASURE_SINCE}`]);
321
+ let windowExtended = false;
322
+ if (commits.length < MIN_N) {
323
+ const all = read([]);
324
+ windowExtended = all.length > commits.length;
325
+ if (windowExtended) commits = all;
326
+ }
327
+ const refs = _git(cwd, ['for-each-ref', '--format=%(refname:short)', 'refs/remotes']) ?? '';
328
+ const branches = refs
329
+ .split('\n')
330
+ .map((r) => r.trim())
331
+ .filter((r) => r !== '' && r.includes('/'))
332
+ .map((r) => ({ remote: r.slice(0, r.indexOf('/')), name: r.slice(r.indexOf('/') + 1) }))
333
+ .filter((b) => b.name !== 'HEAD' && !(b.name === t.name && b.remote === t.remote))
334
+ .map((b) => b.name);
335
+ const merges = _git(cwd, ['log', '--all', '--merges', '-n', String(limit), `--since=${MEASURE_SINCE}`, '--pretty=format:%s']) ?? '';
336
+ return {
337
+ trunk: t.trunk,
338
+ defaultBranch: t.name,
339
+ commits,
340
+ branches,
341
+ mergeSubjects: merges.split('\n').filter((s) => s !== ''),
342
+ windowExtended,
343
+ };
344
+ }
@@ -71,6 +71,21 @@ function expanduser(p: string): string {
71
71
  return p;
72
72
  }
73
73
 
74
+ /**
75
+ * `expanduser`, against a STATED home rather than the process's own.
76
+ *
77
+ * `home` omitted or empty falls back to {@link expanduser}, so every existing
78
+ * caller is unchanged.
79
+ */
80
+ function expanduser_at(p: string, home?: string | null): string {
81
+ if (home === undefined || home === null || home === "") return expanduser(p);
82
+ if (p === "~") return home;
83
+ if (p.startsWith("~/") || (process.platform === "win32" && p.startsWith("~\\"))) {
84
+ return path.join(home, p.slice(2));
85
+ }
86
+ return p;
87
+ }
88
+
74
89
  /**
75
90
  * Resolve a path the way `Path.resolve()` does: expand-free `realpath`-style
76
91
  * resolution that follows existing symlinks and normalises `..`, but does not
@@ -690,6 +705,65 @@ export function recorded_rel_files(
690
705
  return new Set(files.filter((f): f is string => typeof f === "string"));
691
706
  }
692
707
 
708
+ /**
709
+ * Every file a previous deploy recorded, as ABSOLUTE paths, across all tools.
710
+ *
711
+ * `recorded_rel_files` answers "did this package write that file" for one tool
712
+ * whose anchor the caller already knows. This answers the ownership question a
713
+ * READER has — the installed-layer report and the install receipt both walk
714
+ * host rule directories and hold absolute paths, with no tool id and no anchor
715
+ * in hand — so asking the inventory per tool would mean the reader guessing
716
+ * anchors it never recorded.
717
+ *
718
+ * `home` IS A PARAMETER, AND NOT A CONVENIENCE. The installer records the
719
+ * anchor TILDE-RELATIVE — the real inventory reads `"anchor": "~/.claude/"` —
720
+ * so the recorded path is only meaningful against a stated home. Expanding it
721
+ * against `os.homedir()` makes the answer depend on which process is asking,
722
+ * which is exactly how a reader measuring a staged install under a temporary
723
+ * HOME gets back a set naming the maintainer's own machine and claims nothing.
724
+ * Omitted, it falls back to `os.homedir()`, which is right for a caller asking
725
+ * about the install it is itself running under.
726
+ *
727
+ * BOTH SPELLINGS OF EVERY PATH ARE EMITTED — the symlink-resolved one and the
728
+ * merely-normalised one. Callers compare by set membership against a path they
729
+ * built with `path.join(dir, name)` while walking a directory, which is
730
+ * lexical; the inventory's anchor is resolved with `realpath` the way
731
+ * `recorded_rel_files` resolves its anchor comparison. On macOS those two
732
+ * differ for anything under `/var`, which realpaths to `/private/var`, and a
733
+ * one-spelling set silently claimed nothing there — the reader asked about
734
+ * `/var/...`, the set held `/private/var/...`, and every file read foreign.
735
+ * Emitting both is the cheap direction: a set is a membership test, so a second
736
+ * spelling can only make a true answer reachable, never a false one.
737
+ *
738
+ * A malformed tool entry contributes nothing rather than throwing: a corrupt
739
+ * inventory is "no evidence", never a finding, which is the same discipline
740
+ * `reap_stale` applies before it deletes anything.
741
+ */
742
+ export function recorded_absolute_files(
743
+ inventory?: Inventory | null,
744
+ home?: string | null,
745
+ ): ReadonlySet<string> {
746
+ const inv = inventory ?? load_inventory();
747
+ const tools = (inv["tools"] as Record<string, unknown> | undefined) ?? {};
748
+ const out = new Set<string>();
749
+ if (typeof tools !== "object" || tools === null || Array.isArray(tools)) return out;
750
+ for (const entry of Object.values(tools)) {
751
+ if (typeof entry !== "object" || entry === null || Array.isArray(entry)) continue;
752
+ const e = entry as Record<string, unknown>;
753
+ const anchor = e["anchor"];
754
+ const files = e["files"];
755
+ if (typeof anchor !== "string" || !Array.isArray(files)) continue;
756
+ const expanded = expanduser_at(anchor, home);
757
+ for (const rel of files) {
758
+ if (typeof rel !== "string") continue;
759
+ const lexical = path.resolve(expanded, rel);
760
+ out.add(lexical);
761
+ out.add(resolve_path(lexical));
762
+ }
763
+ }
764
+ return out;
765
+ }
766
+
693
767
  /** Sort string members ascending by codepoint (non-strings filtered out). */
694
768
  function sorted_strings(items: unknown[]): string[] {
695
769
  return items