@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
@@ -3,7 +3,7 @@
3
3
  * reader in the neighbour census.
4
4
  *
5
5
  * WHY A MODULE OF ITS OWN, AND NOT A CONSTANT IN EITHER SIDE. The writer lives
6
- * in `hooks/telemetry_usage_hook.ts`, which is inlined into the shared hook
6
+ * in `hooks/mcp_usage_observation_hook.ts`, which is inlined into the shared hook
7
7
  * bundle `check_hook_bundle_composition` caps; the reader lives in
8
8
  * `_lib/neighbour_census.ts`, which is not. Putting the pair here lets esbuild
9
9
  * tree-shake {@link toolsUsedByServer} out of the hook bundle while both sides
@@ -113,16 +113,14 @@ export function toolBelongsTo(tool: string, segment: string): boolean {
113
113
  /**
114
114
  * The directory the store lives under, from any directory inside the project.
115
115
  *
116
- * The WRITER roots the store at the directory holding `.agent-settings.yml`
117
- * (`telemetry_usage_hook.readSettingsFor`), because a session started in a
118
- * subdirectory would otherwise scatter one store per directory it happened to
119
- * start in. The reader has to resolve the same way or it looks in the wrong
120
- * place: a monorepo with settings at the repo root and `.mcp.json` under
121
- * `packages/web` would report `0` for a server in daily use. The two walks are
122
- * pinned equal by a fixture rather than by assertion.
116
+ * Both the writer and the reader call this one function, so the store is
117
+ * rooted at the directory holding `.agent-settings.yml` on both sides: a
118
+ * session started in a subdirectory would otherwise scatter one store per
119
+ * directory, and a monorepo with settings at the repo root and `.mcp.json`
120
+ * under `packages/web` would read `0` for a server in daily use. A fixture
121
+ * still pins the two sides equal end to end.
123
122
  *
124
- * No settings file on any ancestor → `start`, matching the writer's own
125
- * fallback.
123
+ * No settings file on any ancestor → `start`.
126
124
  */
127
125
  export function resolveStoreRoot(start: string): string {
128
126
  let dir = path.resolve(start);
@@ -96,10 +96,227 @@ export interface RatificationProblem {
96
96
  | 'no-providers'
97
97
  | 'diversity-required'
98
98
  | 'diversity-unverifiable'
99
- | 'bad-effective-after';
99
+ | 'bad-effective-after'
100
+ | 'no-seats'
101
+ | 'malformed-seats'
102
+ | 'bad-seat-provider'
103
+ | 'unknown-seat-verdict'
104
+ | 'seat-dissent'
105
+ | 'providers-exceed-seats'
106
+ | 'header-not-derived';
100
107
  message: string;
101
108
  }
102
109
 
110
+ /** A seat that closed, timed out or was absent at the last round gave no final verdict. */
111
+ export const SEAT_NO_FINAL_VERDICT = 'no-final-verdict';
112
+ export type SeatVerdict = RatificationVerdict | typeof SEAT_NO_FINAL_VERDICT;
113
+ /** Every value a seat's final verdict may take — shared by the writer and the reader. */
114
+ export const SEAT_VERDICTS: readonly string[] = [...RATIFICATION_VERDICTS, SEAT_NO_FINAL_VERDICT];
115
+
116
+ /**
117
+ * A provider id as a seat key: lower-case, no whitespace and no YAML
118
+ * metacharacter, so a rendered header cannot be split or extended by a name
119
+ * and two spellings of one provider cannot collide after normalisation.
120
+ */
121
+ export const SEAT_PROVIDER_RE = /^[a-z0-9][a-z0-9._-]*$/u;
122
+
123
+ export type SeatsReading =
124
+ | { kind: 'absent' }
125
+ | { kind: 'invalid'; problems: RatificationProblem[] }
126
+ | { kind: 'present'; seats: Map<string, SeatVerdict> };
127
+
128
+ /**
129
+ * The `seats:` map — provider id to that seat's FINAL verdict — in source
130
+ * order, which is the order `providers` is derived in.
131
+ *
132
+ * Absent and present-but-unusable are reported apart: a missing key and a
133
+ * `seats:` key that is empty, a scalar, a list, or carries a bad id or verdict
134
+ * are both refusals, with different codes.
135
+ */
136
+ export function readSeats(fm: AdrFrontmatter, text = ''): SeatsReading {
137
+ const duplicates = duplicateSeatKeys(text);
138
+ if (duplicates.length > 0) {
139
+ return {
140
+ kind: 'invalid',
141
+ problems: [
142
+ {
143
+ code: 'bad-seat-provider',
144
+ message: `seat \`${duplicates.join('`, `')}\` is recorded more than once — the parser keeps only the last`,
145
+ },
146
+ ],
147
+ };
148
+ }
149
+ const hasScalar = Object.prototype.hasOwnProperty.call(fm.scalars, 'seats');
150
+ const node = fm.nested['seats'];
151
+ if (node === undefined && !hasScalar) {
152
+ return { kind: 'absent' };
153
+ }
154
+ if (node === undefined || typeof node === 'string' || Array.isArray(node)) {
155
+ return {
156
+ kind: 'invalid',
157
+ problems: [{ code: 'malformed-seats', message: '`seats:` is present but is not a provider-to-verdict map' }],
158
+ };
159
+ }
160
+ const problems: RatificationProblem[] = [];
161
+ const seats = new Map<string, SeatVerdict>();
162
+ for (const [provider, verdict] of Object.entries(node)) {
163
+ if (!SEAT_PROVIDER_RE.test(provider)) {
164
+ problems.push({
165
+ code: 'bad-seat-provider',
166
+ message: `seat key \`${provider}\` is not a provider id (${String(SEAT_PROVIDER_RE)})`,
167
+ });
168
+ continue;
169
+ }
170
+ if (typeof verdict !== 'string' || !SEAT_VERDICTS.includes(verdict.trim())) {
171
+ problems.push({
172
+ code: 'unknown-seat-verdict',
173
+ message: `seat \`${provider}\` records \`${String(verdict)}\`, not one of ${SEAT_VERDICTS.join(', ')}`,
174
+ });
175
+ continue;
176
+ }
177
+ seats.set(provider, verdict.trim() as SeatVerdict);
178
+ }
179
+ if (problems.length === 0 && seats.size === 0) {
180
+ problems.push({ code: 'malformed-seats', message: '`seats:` is present and empty' });
181
+ }
182
+ return problems.length > 0 ? { kind: 'invalid', problems } : { kind: 'present', seats };
183
+ }
184
+
185
+ /** Keys repeated inside the frontmatter `seats:` block, read from the raw text. */
186
+ function duplicateSeatKeys(text: string): string[] {
187
+ if (!text.startsWith('---\n')) return [];
188
+ const end = text.indexOf('\n---\n', 4);
189
+ const lines = text.slice(4, end === -1 ? undefined : end).split('\n');
190
+ const start = lines.findIndex((l) => /^seats:\s*$/u.test(l));
191
+ if (start === -1) return [];
192
+ const seen = new Set<string>();
193
+ const dup = new Set<string>();
194
+ for (const line of lines.slice(start + 1)) {
195
+ if (!/^\s/u.test(line)) break;
196
+ // Compared by the identity a YAML parser would give the key, so a quoted
197
+ // spelling cannot hide a second entry for the same seat.
198
+ const key = line
199
+ .slice(0, line.indexOf(':') === -1 ? undefined : line.indexOf(':'))
200
+ .trim()
201
+ .replace(/^(["'])(.*)\1$/u, '$2')
202
+ .trim();
203
+ if (key === '' || key.startsWith('#')) continue;
204
+ if (seen.has(key)) dup.add(key);
205
+ seen.add(key);
206
+ }
207
+ return [...dup];
208
+ }
209
+
210
+ /**
211
+ * The header a set of seat verdicts supports, and no more.
212
+ *
213
+ * `providers` is every seat that gave a final verdict — a closed seat is not a
214
+ * provider the verdict came from. Any refusing seat makes the verdict `refused`,
215
+ * any non-convergent one `non-convergent`; only when every final seat passed is
216
+ * the verdict passing, and then `ratified` if any seat said so. No final seat at
217
+ * all is `non-convergent`: a review that ended without a verdict did not pass.
218
+ */
219
+ export function deriveRatificationHeader(
220
+ seats: ReadonlyMap<string, SeatVerdict> | Readonly<Record<string, SeatVerdict>>,
221
+ ): { providers: string[]; verdict: RatificationVerdict } {
222
+ const entries = seats instanceof Map ? [...seats.entries()] : Object.entries(seats);
223
+ const final = entries.filter(([, v]) => v !== SEAT_NO_FINAL_VERDICT) as [string, RatificationVerdict][];
224
+ const verdicts = final.map(([, v]) => v);
225
+ let verdict: RatificationVerdict;
226
+ if (verdicts.includes('refused')) {
227
+ verdict = 'refused';
228
+ } else if (final.length === 0 || verdicts.includes('non-convergent')) {
229
+ verdict = 'non-convergent';
230
+ } else {
231
+ verdict = verdicts.includes('ratified') ? 'ratified' : 'confirmed-non-expanding';
232
+ }
233
+ return { providers: final.map(([p]) => p), verdict };
234
+ }
235
+
236
+ /**
237
+ * The `providers:`, `verdict:` and `seats:` frontmatter lines, derived — never
238
+ * typed. Throws on a provider id outside {@link SEAT_PROVIDER_RE}: a name that
239
+ * could carry YAML syntax is refused rather than escaped.
240
+ */
241
+ export function renderRatificationHeader(
242
+ seats: ReadonlyMap<string, SeatVerdict> | Readonly<Record<string, SeatVerdict>>,
243
+ ): string {
244
+ const entries = seats instanceof Map ? [...seats.entries()] : Object.entries(seats);
245
+ for (const [p, v] of entries) {
246
+ if (!SEAT_PROVIDER_RE.test(p)) throw new Error(`not a provider id: ${JSON.stringify(p)}`);
247
+ if (!SEAT_VERDICTS.includes(v)) throw new Error(`not a seat verdict: ${JSON.stringify(v)}`);
248
+ }
249
+ const { providers, verdict } = deriveRatificationHeader(seats);
250
+ return [
251
+ `providers: [${providers.join(', ')}]`,
252
+ `verdict: ${verdict}`,
253
+ 'seats:',
254
+ ...entries.map(([p, v]) => ` ${p}: ${v}`),
255
+ ].join('\n');
256
+ }
257
+
258
+ /**
259
+ * The header claims the seats do not support.
260
+ *
261
+ * `seats:` is required. Optional, it left `providers` and `verdict` free-written
262
+ * for every author who omitted it, which is the defect it exists to close; the
263
+ * round-2 ratification review refused that shape. The gate reads only the
264
+ * artifacts in the diff under review, so an artifact merged before the field
265
+ * existed is never re-read and needs no migration to stay valid.
266
+ *
267
+ * The recorded header must EQUAL the derived one; the two named overclaims get
268
+ * their own codes so a reader sees which one it was.
269
+ */
270
+ function seatProblems(reading: SeatsReading, providers: readonly string[], verdict: string | null): RatificationProblem[] {
271
+ if (reading.kind === 'absent') {
272
+ return [
273
+ {
274
+ code: 'no-seats',
275
+ message:
276
+ 'missing `seats:` — `providers` and `verdict` are derived from the per-seat final ' +
277
+ 'verdicts, never typed (print all three with `ratification_header`)',
278
+ },
279
+ ];
280
+ }
281
+ if (reading.kind === 'invalid') return reading.problems;
282
+ const seats = reading.seats;
283
+ const problems: RatificationProblem[] = [];
284
+ if (verdict !== null && PASSING_VERDICTS.has(verdict)) {
285
+ const dissent = [...seats].filter(([, v]) => v === 'refused' || v === 'non-convergent');
286
+ if (dissent.length > 0) {
287
+ problems.push({
288
+ code: 'seat-dissent',
289
+ message:
290
+ `verdict \`${verdict}\` while ${dissent.map(([p, v]) => `${p} was \`${v}\``).join(', ')} ` +
291
+ 'at the final round — a header cannot say more than its seats said',
292
+ });
293
+ }
294
+ }
295
+ const derived = deriveRatificationHeader(seats);
296
+ const extra = providers.filter((p) => !derived.providers.includes(p));
297
+ if (extra.length > 0) {
298
+ problems.push({
299
+ code: 'providers-exceed-seats',
300
+ message:
301
+ `providers names ${extra.join(', ')}, which gave no final verdict ` +
302
+ `(${String(derived.providers.length)} seat(s) did) — diversity is counted over seats that answered`,
303
+ });
304
+ }
305
+ if (
306
+ problems.length === 0 &&
307
+ (verdict !== derived.verdict || providers.join('\u0000') !== derived.providers.join('\u0000'))
308
+ ) {
309
+ problems.push({
310
+ code: 'header-not-derived',
311
+ message:
312
+ `recorded providers [${providers.join(', ')}] / verdict \`${String(verdict)}\` differ from the ` +
313
+ `header the seats derive: [${derived.providers.join(', ')}] / \`${derived.verdict}\` ` +
314
+ '(print it with `ratification_header`)',
315
+ });
316
+ }
317
+ return problems;
318
+ }
319
+
103
320
  export interface RatificationReading {
104
321
  artifact: RatificationArtifact | null;
105
322
  problems: RatificationProblem[];
@@ -208,6 +425,8 @@ export function readRatification(
208
425
  }
209
426
  }
210
427
 
428
+ problems.push(...seatProblems(readSeats(fm, text), providers, verdict));
429
+
211
430
  // Diversity, against the REQUIRED count.
212
431
  //
213
432
  // Round 1 refused the previous shape: the count came from the user-global
@@ -0,0 +1,92 @@
1
+ /**
2
+ * ratification_subject — the digest a ratification record carries over the
3
+ * gated content it reviewed.
4
+ *
5
+ * `road-to-self-modification-that-a-council-must-pass` step 2.1, the half that
6
+ * does not touch the gate. The record says WHO reviewed; without a digest it
7
+ * does not say WHAT, so a gated file edited after its review still ships under
8
+ * a record that approved something else.
9
+ *
10
+ * WHY IT RE-ASSEMBLES THE LIST RATHER THAN RE-DECIDING IT. The gate's
11
+ * `classifyPaths` returns the kernel rules, hooks and plumbing by name but
12
+ * reports the self surface as a BOOLEAN, so the gated list cannot be read back
13
+ * out of it. This module therefore imports the gate's own path constants and
14
+ * re-assembles — it never restates the membership rule, because a second
15
+ * definition of "gated" is a second thing to keep in step, and the first time
16
+ * the two diverged a file would be reviewed by one and digested by the other.
17
+ *
18
+ * NO BASE DIFF. The digest is over the tree as it stands, so it is the same on
19
+ * a branch and on the merged checkout CI judges — unless the base changed a
20
+ * gated file the change also touches, and then the content that would land is
21
+ * not the content that was reviewed, which is precisely what should move it.
22
+ */
23
+
24
+ import { createHash } from 'node:crypto';
25
+ import * as fs from 'node:fs';
26
+ import * as path from 'node:path';
27
+
28
+ import {
29
+ ANCHOR_PATHS,
30
+ CLOSURE_READER_PATH,
31
+ POLICY_PATH,
32
+ READER_PATH,
33
+ SELF_PATH,
34
+ WORKFLOW_PATH,
35
+ classifyPaths,
36
+ } from '../check_kernel_edit_ratified.js';
37
+
38
+ /**
39
+ * Stands in for the content of a gated file the change deletes. A deleted file
40
+ * is ENTERED, never skipped: skipping would make "this file was removed"
41
+ * digest-identical to "this file was never gated", and removing a governance
42
+ * hook is exactly the change the record most needs to be bound to.
43
+ */
44
+ export const DELETED_MARKER = '\u0000deleted\u0000';
45
+
46
+ /** The self surface, by the gate's own constants rather than a copy of them. */
47
+ const SELF_SET: ReadonlySet<string> = new Set<string>([
48
+ SELF_PATH,
49
+ READER_PATH,
50
+ CLOSURE_READER_PATH,
51
+ POLICY_PATH,
52
+ WORKFLOW_PATH,
53
+ ...ANCHOR_PATHS,
54
+ ]);
55
+
56
+ /**
57
+ * The gated subset of a changed-file list: sorted, deduplicated, and stable
58
+ * against the order the caller happened to collect the paths in.
59
+ */
60
+ export function gatedFilesOf(
61
+ files: readonly string[],
62
+ derived?: readonly string[],
63
+ ): readonly string[] {
64
+ const normalized = files.map((f) => f.replace(/\\/g, '/').trim()).filter((f) => f !== '');
65
+ const g = derived === undefined ? classifyPaths(normalized) : classifyPaths(normalized, derived);
66
+ const out = new Set<string>([...g.kernelRules, ...g.governanceHooks, ...g.plumbing]);
67
+ for (const f of normalized) {
68
+ if (SELF_SET.has(f)) out.add(f);
69
+ }
70
+ return [...out].sort();
71
+ }
72
+
73
+ /**
74
+ * One digest over the sorted paths AND contents of the gated files, read from
75
+ * `root`.
76
+ *
77
+ * The path is hashed alongside its content, so two files with identical bytes
78
+ * do not collide and a rename moves the digest — a gated file moved to another
79
+ * gated path is a different change, not the same one.
80
+ */
81
+ export function subjectDigest(root: string, files: readonly string[]): string {
82
+ const h = createHash('sha256');
83
+ for (const rel of gatedFilesOf(files)) {
84
+ const abs = path.join(root, rel);
85
+ const content = fs.existsSync(abs) ? fs.readFileSync(abs) : Buffer.from(DELETED_MARKER);
86
+ h.update(rel);
87
+ h.update('\u0000');
88
+ h.update(createHash('sha256').update(content).digest('hex'));
89
+ h.update('\n');
90
+ }
91
+ return h.digest('hex');
92
+ }
@@ -160,7 +160,9 @@ export function dispositionStopMessage(
160
160
  resumeCmd: string,
161
161
  ): string {
162
162
  const count =
163
- blocking > 0 ? ` ${blocking} of them are blocking findings with no status yet.\n` : '';
163
+ blocking > 0
164
+ ? ` ${blocking} of them are blocking findings with no disposition yet (no status, or still_open).\n`
165
+ : '';
164
166
  return (
165
167
  `the disposition gate refuses ${version}. Its own report:\n` +
166
168
  `${gateOutput.trim() || ' (the gate printed nothing — run it directly to see why)'}\n` +
@@ -296,7 +298,7 @@ export function settleFindingsLedger(
296
298
  // the operator `scanned: N` and discarded the entire reason the
297
299
  // release stopped.
298
300
  [verdict.stdout, verdict.stderr].map((s) => s.trim()).filter(Boolean).join('\n'),
299
- blockingWithoutDisposition(path.join(deps.repoRoot, rel)),
301
+ blockingWithoutDisposition(path.join(deps.repoRoot, rel), version),
300
302
  'task release -- --resume --yes',
301
303
  ),
302
304
  );
@@ -304,20 +306,26 @@ export function settleFindingsLedger(
304
306
  }
305
307
 
306
308
  /**
307
- * How many blocking findings carry no status — a figure for the stop message,
308
- * never the reason for it.
309
+ * How many blocking findings carry no disposition — no status, or `still_open`,
310
+ * which a blocking row may not rest on — a figure for the stop message, never
311
+ * the reason for it.
309
312
  *
310
313
  * The gate refuses for more shapes than this counts (an unknown status, an
311
314
  * empty rationale or verifier, a `fixed` with no commit, a malformed ledger),
312
- * which is why the gate's own output is what the operator is shown.
315
+ * which is why the gate's own output is what the operator is shown. It
316
+ * classifies against the version being released, the same input the gate
317
+ * reads from `--release`, not the ledger file's own `release` field.
313
318
  */
314
- function blockingWithoutDisposition(ledgerAbs: string): number {
319
+ export function blockingWithoutDisposition(ledgerAbs: string, version: string): number {
315
320
  if (!fs.existsSync(ledgerAbs)) {
316
321
  return 0;
317
322
  }
318
323
  try {
319
324
  const ledger = parse_ledger(fs.readFileSync(ledgerAbs, 'utf-8'), ledgerAbs);
320
- return ledger.findings.filter((f) => isBlocking(f) && !f.status).length;
325
+ return ledger.findings.filter((f) => {
326
+ const status = (f.status ?? '').trim();
327
+ return isBlocking(f, version) && (status === '' || status === 'still_open');
328
+ }).length;
321
329
  } catch {
322
330
  return 0;
323
331
  }
@@ -610,6 +610,11 @@ const TEST_FOOTER_RE = /^Tests: \d+/mu;
610
610
  */
611
611
  export interface MixObligation {
612
612
  level: string;
613
+ /** The resolved ends the counts were read on; the rendered level names both. */
614
+ from_sha?: string;
615
+ to_sha?: string;
616
+ governance_only?: number;
617
+ consumer_only?: number;
613
618
  }
614
619
 
615
620
  /** Labels whose curated value is still the generator's unedited draft. */
@@ -25,7 +25,7 @@
25
25
  * law in bold prose or a bare fence under no heading at all — several of the 35
26
26
  * routed rules without a heading match do exactly that. A heading match is a
27
27
  * STRUCTURAL property, checkable; "this sentence is the obligation" is not, and
28
- * `report_obligation_carriers` plus the `# obligation: line N` marker is where
28
+ * `report_obligation_carriers` plus the ids in `src/config/rule-obligations.json` is where
29
29
  * that question already lives.
30
30
  */
31
31
  import * as fs from 'node:fs';
@@ -0,0 +1,205 @@
1
+ /**
2
+ * Stable obligation ids per rule, and which `enforced_by` entry refuses which.
3
+ *
4
+ * A rule holds several obligations, and `enforced_by` used to credit all of
5
+ * them for whatever one gate refuses: `git-history-discipline` counted as gated
6
+ * because a hook refuses `--no-verify`, while its laws against unsolicited
7
+ * rebase and dropped commits are refused by nothing. The inventory names each
8
+ * obligation `<rule>.<obligation>` so a gate is credited with the ids it
9
+ * actually refuses and nothing else.
10
+ *
11
+ * WHY A SIDECAR AND NOT RULE FRONTMATTER. `check_preamble_payload_budget`
12
+ * measures every byte of every projected rule file, frontmatter included, as
13
+ * per-spawn payload, and holds it at zero net growth. Some 290 ids in
14
+ * frontmatter would have been payload no model needs. The ids are routing and
15
+ * accounting data, so they live with the rest of that data in `src/config/`.
16
+ *
17
+ * WHY THE ID IS NOT DERIVED FROM THE LAW TEXT. A hash or an excerpt changes
18
+ * when the law is reworded, and an id that moves on every reword is not stable.
19
+ * The slug names the clause; the law text is free to change under it. That is
20
+ * also why the `# obligation: line N` frontmatter marker is retired: a line
21
+ * number drifts on every edit above it, and at retirement 34 of the 68 markers
22
+ * on rules with a law section no longer pointed inside that section.
23
+ *
24
+ * BINDINGS. `bindings` maps an `enforced_by` entry, spelled exactly as in the
25
+ * rule's frontmatter, to the ids it refuses. An entry with no key here is
26
+ * UNBOUND: it keeps the rule-level credit it always had and is counted
27
+ * separately, never as obligation-level coverage. An entry bound to `[]` is a
28
+ * recorded finding that it refuses none of this rule's obligations.
29
+ *
30
+ * The nine kernel rules are absent by construction: agents cannot write them,
31
+ * and they stay at rule granularity.
32
+ */
33
+ import * as fs from 'node:fs';
34
+ import * as path from 'node:path';
35
+
36
+ import { parse as parseYaml } from 'yaml';
37
+
38
+ import { KERNEL_RULE_ID_SET } from './kernel_rules.js';
39
+ import { lawSections, ruleBody, splitFrontmatter } from './rule_law_section.js';
40
+
41
+ export const RULE_OBLIGATIONS_PATH = 'src/config/rule-obligations.json';
42
+
43
+ const SLUG = '[a-z0-9]+(?:-[a-z0-9]+)*';
44
+
45
+ /** `<rule>.<obligation>`, both halves kebab-case. */
46
+ export const OBLIGATION_ID_RE = new RegExp(`^(${SLUG})\\.(${SLUG})$`);
47
+
48
+ /** The retired per-rule pointer. Kept only so the lint can refuse its return. */
49
+ export const OBLIGATION_MARKER_RE = /^#\s*obligation:\s*line\s+\d+\s*$/m;
50
+
51
+ export interface RuleObligationEntry {
52
+ obligations: string[];
53
+ bindings?: Record<string, string[]>;
54
+ }
55
+
56
+ export interface RuleObligationInventory {
57
+ rules: Record<string, RuleObligationEntry>;
58
+ }
59
+
60
+ export function loadRuleObligations(root: string): RuleObligationInventory {
61
+ const file = path.join(root, RULE_OBLIGATIONS_PATH);
62
+ const raw = JSON.parse(fs.readFileSync(file, 'utf-8')) as Partial<RuleObligationInventory>;
63
+ return { rules: raw.rules ?? {} };
64
+ }
65
+
66
+ /** What the lint needs to know about one rule file. */
67
+ export interface RuleFacts {
68
+ id: string;
69
+ kernel: boolean;
70
+ hasLawSection: boolean;
71
+ enforcedBy: string[];
72
+ hasMarker: boolean;
73
+ }
74
+
75
+ export function readRuleFacts(id: string, text: string): RuleFacts {
76
+ const [fmBlock] = splitFrontmatter(text);
77
+ let enforcedBy: string[] = [];
78
+ if (fmBlock !== '') {
79
+ const inner = fmBlock.replace(/^---\n/, '').replace(/\n---\n$/, '');
80
+ const fm = (parseYaml(inner) ?? {}) as Record<string, unknown>;
81
+ const raw = fm['enforced_by'];
82
+ if (Array.isArray(raw)) enforcedBy = raw.map(String);
83
+ else if (typeof raw === 'string' && raw !== '') enforcedBy = [raw];
84
+ }
85
+ return {
86
+ id,
87
+ kernel: KERNEL_RULE_ID_SET.has(id),
88
+ hasLawSection: lawSections(ruleBody(text)).length > 0,
89
+ enforcedBy,
90
+ hasMarker: OBLIGATION_MARKER_RE.test(fmBlock),
91
+ };
92
+ }
93
+
94
+ export function collectRuleFacts(rulesDir: string): RuleFacts[] {
95
+ return fs
96
+ .readdirSync(rulesDir)
97
+ .filter((n) => n.endsWith('.md'))
98
+ .sort()
99
+ .map((n) => readRuleFacts(n.slice(0, -3), fs.readFileSync(path.join(rulesDir, n), 'utf-8')));
100
+ }
101
+
102
+ export interface ObligationFinding {
103
+ rule: string;
104
+ code:
105
+ | 'unknown-rule'
106
+ | 'kernel-declared'
107
+ | 'missing'
108
+ | 'empty'
109
+ | 'bad-id'
110
+ | 'wrong-prefix'
111
+ | 'duplicate'
112
+ | 'binding-entry-not-declared'
113
+ | 'binding-id-unknown'
114
+ | 'marker-present';
115
+ message: string;
116
+ }
117
+
118
+ /**
119
+ * Every finding the inventory and the rule tree produce together.
120
+ *
121
+ * Required: every non-kernel rule with a law section has an entry. A rule
122
+ * without one MAY have an entry, and if it does the same checks apply.
123
+ */
124
+ export function lintRuleObligations(
125
+ inventory: RuleObligationInventory,
126
+ facts: readonly RuleFacts[],
127
+ ): ObligationFinding[] {
128
+ const out: ObligationFinding[] = [];
129
+ const byId = new Map(facts.map((f) => [f.id, f]));
130
+ const seen = new Map<string, string>();
131
+
132
+ for (const f of facts) {
133
+ if (f.hasMarker) {
134
+ out.push({
135
+ rule: f.id,
136
+ code: 'marker-present',
137
+ message:
138
+ 'carries a `# obligation: line N` marker; it is retired — the ids in ' +
139
+ `${RULE_OBLIGATIONS_PATH} name the obligation`,
140
+ });
141
+ }
142
+ if (!f.kernel && f.hasLawSection && inventory.rules[f.id] === undefined) {
143
+ out.push({
144
+ rule: f.id,
145
+ code: 'missing',
146
+ message: `has a law section and no entry in ${RULE_OBLIGATIONS_PATH}`,
147
+ });
148
+ }
149
+ }
150
+
151
+ for (const [rule, entry] of Object.entries(inventory.rules)) {
152
+ const fact = byId.get(rule);
153
+ if (fact === undefined) {
154
+ out.push({ rule, code: 'unknown-rule', message: 'no such rule under src/rules/' });
155
+ continue;
156
+ }
157
+ if (fact.kernel) {
158
+ out.push({
159
+ rule,
160
+ code: 'kernel-declared',
161
+ message: 'kernel rules stay at rule granularity and carry no obligation ids',
162
+ });
163
+ }
164
+ const ids = Array.isArray(entry.obligations) ? entry.obligations : [];
165
+ if (ids.length === 0) {
166
+ out.push({ rule, code: 'empty', message: 'declares no obligations' });
167
+ }
168
+ const own = new Set<string>();
169
+ for (const id of ids) {
170
+ const m = OBLIGATION_ID_RE.exec(id);
171
+ if (m === null) {
172
+ out.push({ rule, code: 'bad-id', message: `\`${id}\` is not \`<rule>.<obligation>\` kebab-case` });
173
+ continue;
174
+ }
175
+ if (m[1] !== rule) {
176
+ out.push({ rule, code: 'wrong-prefix', message: `\`${id}\` is not prefixed with \`${rule}.\`` });
177
+ }
178
+ const prior = seen.get(id);
179
+ if (prior !== undefined) {
180
+ out.push({ rule, code: 'duplicate', message: `\`${id}\` is declared twice (also under ${prior})` });
181
+ }
182
+ seen.set(id, rule);
183
+ own.add(id);
184
+ }
185
+ for (const [entryName, bound] of Object.entries(entry.bindings ?? {})) {
186
+ if (!fact.enforcedBy.includes(entryName)) {
187
+ out.push({
188
+ rule,
189
+ code: 'binding-entry-not-declared',
190
+ message: `binds \`${entryName}\`, which is not in the rule's enforced_by`,
191
+ });
192
+ }
193
+ for (const id of bound) {
194
+ if (!own.has(id)) {
195
+ out.push({
196
+ rule,
197
+ code: 'binding-id-unknown',
198
+ message: `\`${entryName}\` binds \`${id}\`, which this rule does not declare`,
199
+ });
200
+ }
201
+ }
202
+ }
203
+ }
204
+ return out;
205
+ }
@@ -322,7 +322,7 @@ function stemOf(token: string): string {
322
322
  return base.replace(/\.md$/, '');
323
323
  }
324
324
 
325
- /** Dotted settings-key shape — `personal.autonomy`, `tokens.rich_skills`, … */
325
+ /** Dotted settings-key shape — `personal.autonomy`, `memory.redact_patterns`, … */
326
326
  const DOTTED_KEY_RE = /^[a-z0-9_]+(\.[a-z0-9_]+)+$/;
327
327
 
328
328
  /**