@event4u/agent-config 16.3.0 → 16.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (486) 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 +251 -0
  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/estimate-ticket.md +1 -1
  16. package/dist/agent-src/commands/feature/explore.md +3 -3
  17. package/dist/agent-src/commands/feature/plan.md +1 -1
  18. package/dist/agent-src/commands/fix/ci.md +17 -3
  19. package/dist/agent-src/commands/fix/commit-messages.md +48 -23
  20. package/dist/agent-src/commands/fix/pr-comments.md +3 -6
  21. package/dist/agent-src/commands/implement-ticket.md +3 -3
  22. package/dist/agent-src/commands/memory/add.md +4 -16
  23. package/dist/agent-src/commands/memory/load.md +5 -6
  24. package/dist/agent-src/commands/memory/promote.md +3 -16
  25. package/dist/agent-src/commands/mission/upgrade.md +3 -2
  26. package/dist/agent-src/commands/optimize/agents-dir.md +2 -2
  27. package/dist/agent-src/commands/optimize/deep.md +4 -2
  28. package/dist/agent-src/commands/optimize/rtk.md +4 -26
  29. package/dist/agent-src/commands/pr/create/description-only.md +18 -15
  30. package/dist/agent-src/commands/pr/create.md +42 -34
  31. package/dist/agent-src/commands/pr/merge.md +136 -9
  32. package/dist/agent-src/commands/prepare-for-review.md +13 -11
  33. package/dist/agent-src/commands/project/analyze.md +7 -35
  34. package/dist/agent-src/commands/refine-ticket.md +1 -1
  35. package/dist/agent-src/commands/review/changes.md +14 -19
  36. package/dist/agent-src/commands/roadmap/next.md +10 -1
  37. package/dist/agent-src/commands/roadmap/process-full.md +52 -38
  38. package/dist/agent-src/commands/roadmap/resolve-blockers.md +64 -14
  39. package/dist/agent-src/commands/worktree/create.md +7 -3
  40. package/dist/agent-src/commands/worktree/verify.md +2 -1
  41. package/dist/agent-src/contexts/communication/rules-auto/think-before-action-mechanics.md +5 -3
  42. package/dist/agent-src/contexts/communication/rules-auto/token-efficiency-mechanics.md +7 -9
  43. package/dist/agent-src/contexts/contracts/command-suggestion-flow.md +8 -6
  44. package/dist/agent-src/contexts/contracts/frugality-charter.md +8 -5
  45. package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +1 -1
  46. package/dist/agent-src/contexts/execution/auto-orchestration-activation.md +0 -1
  47. package/dist/agent-src/contexts/execution/evidence-discipline.md +2 -2
  48. package/dist/agent-src/contexts/execution/non-interactive-contract.md +5 -8
  49. package/dist/agent-src/contexts/execution/rdp-gate.md +4 -4
  50. package/dist/agent-src/contexts/execution/roadmap-execution-contract.md +9 -8
  51. package/dist/agent-src/contexts/execution/roadmap-process-loop.md +67 -52
  52. package/dist/agent-src/contexts/execution/subagent-routing.md +8 -8
  53. package/dist/agent-src/contexts/execution/subagent-steering.md +6 -4
  54. package/dist/agent-src/contexts/execution/terminal-states.md +2 -2
  55. package/dist/agent-src/contexts/execution/toolchain-resolver.md +4 -10
  56. package/dist/agent-src/contexts/subagent-configuration.md +1 -1
  57. package/dist/agent-src/guidelines/agent-infra/active-remediation-mechanics.md +39 -0
  58. package/dist/agent-src/guidelines/agent-infra/context-hygiene-mechanics.md +1 -1
  59. package/dist/agent-src/guidelines/agent-infra/cross-source-consistency-mechanics.md +8 -10
  60. package/dist/agent-src/guidelines/agent-infra/frontier-reasoning-operating-profile.md +3 -2
  61. package/dist/agent-src/guidelines/agent-infra/layered-settings.md +13 -1
  62. package/dist/agent-src/guidelines/agent-infra/roadmap-progress-mechanics.md +1 -1
  63. package/dist/agent-src/guidelines/agent-infra/self-improvement-pipeline.md +10 -3
  64. package/dist/agent-src/guidelines/agent-infra/size-and-scope.md +36 -0
  65. package/dist/agent-src/guidelines/php/git.md +15 -2
  66. package/dist/agent-src/rules/active-remediation.md +0 -1
  67. package/dist/agent-src/rules/analysis-skill-routing.md +0 -1
  68. package/dist/agent-src/rules/architecture.md +0 -1
  69. package/dist/agent-src/rules/artifact-drafting-protocol.md +0 -1
  70. package/dist/agent-src/rules/artifact-engagement-recording.md +0 -1
  71. package/dist/agent-src/rules/augment-edit-discipline.md +0 -1
  72. package/dist/agent-src/rules/autonomous-execution.md +0 -1
  73. package/dist/agent-src/rules/brand-consistency.md +0 -1
  74. package/dist/agent-src/rules/brand-source-of-truth.md +0 -1
  75. package/dist/agent-src/rules/broken-access-control.md +0 -1
  76. package/dist/agent-src/rules/cli-output-handling.md +0 -1
  77. package/dist/agent-src/rules/code-comment-discipline.md +0 -1
  78. package/dist/agent-src/rules/code-provenance.md +0 -1
  79. package/dist/agent-src/rules/command-suggestion-policy.md +0 -1
  80. package/dist/agent-src/rules/commit-conventions.md +1 -2
  81. package/dist/agent-src/rules/communication-through-line.md +1 -2
  82. package/dist/agent-src/rules/content-quoting-floor.md +1 -2
  83. package/dist/agent-src/rules/context-hygiene.md +5 -5
  84. package/dist/agent-src/rules/copilot-routing.md +1 -2
  85. package/dist/agent-src/rules/council-availability.md +4 -4
  86. package/dist/agent-src/rules/cross-source-consistency.md +4 -6
  87. package/dist/agent-src/rules/decision-revisit-gate.md +2 -3
  88. package/dist/agent-src/rules/delegation-policy.md +2 -3
  89. package/dist/agent-src/rules/design-fidelity.md +0 -1
  90. package/dist/agent-src/rules/design-review-after-ui-write.md +3 -3
  91. package/dist/agent-src/rules/devcontainer-routing.md +1 -2
  92. package/dist/agent-src/rules/doc-screenshot-hygiene.md +0 -1
  93. package/dist/agent-src/rules/docker-commands.md +0 -1
  94. package/dist/agent-src/rules/domain-adoption-policy.md +0 -1
  95. package/dist/agent-src/rules/domain-safety-disclaimer.md +0 -1
  96. package/dist/agent-src/rules/domain-safety-pii.md +0 -1
  97. package/dist/agent-src/rules/domain-safety-retention.md +0 -1
  98. package/dist/agent-src/rules/downstream-changes.md +0 -1
  99. package/dist/agent-src/rules/engineering-safety-floor.md +0 -1
  100. package/dist/agent-src/rules/external-code-graph-interop.md +0 -1
  101. package/dist/agent-src/rules/external-reference-deep-dive.md +0 -1
  102. package/dist/agent-src/rules/fast-path-marker-visibility.md +1 -2
  103. package/dist/agent-src/rules/finance-safety-floor.md +0 -1
  104. package/dist/agent-src/rules/fix-what-you-see.md +6 -32
  105. package/dist/agent-src/rules/framework-neutrality-in-generic-skills.md +0 -1
  106. package/dist/agent-src/rules/git-history-discipline.md +1 -2
  107. package/dist/agent-src/rules/guidelines.md +0 -1
  108. package/dist/agent-src/rules/history-discipline.md +0 -1
  109. package/dist/agent-src/rules/icon-consistency.md +0 -1
  110. package/dist/agent-src/rules/image-likeness-and-rights.md +0 -1
  111. package/dist/agent-src/rules/improve-before-implement.md +0 -1
  112. package/dist/agent-src/rules/invite-challenge.md +0 -1
  113. package/dist/agent-src/rules/laravel-routing.md +1 -2
  114. package/dist/agent-src/rules/laravel-translations.md +0 -1
  115. package/dist/agent-src/rules/legal-safety-floor.md +0 -1
  116. package/dist/agent-src/rules/lethal-trifecta-guard.md +0 -1
  117. package/dist/agent-src/rules/linked-projects-onboarding-gate.md +0 -1
  118. package/dist/agent-src/rules/low-impact-corpus-privacy-floor.md +0 -1
  119. package/dist/agent-src/rules/markdown-safe-codeblocks.md +0 -1
  120. package/dist/agent-src/rules/media-governance-routing.md +1 -2
  121. package/dist/agent-src/rules/media-sync-ground-truth.md +0 -1
  122. package/dist/agent-src/rules/minimal-safe-diff.md +0 -1
  123. package/dist/agent-src/rules/missing-skill-recovery.md +0 -1
  124. package/dist/agent-src/rules/missing-tool-handling.md +0 -1
  125. package/dist/agent-src/rules/model-recommendation.md +0 -1
  126. package/dist/agent-src/rules/neighbour-precedence.md +64 -0
  127. package/dist/agent-src/rules/no-attribution-footers.md +0 -1
  128. package/dist/agent-src/rules/no-decorative-emojis-in-git-surfaces.md +0 -1
  129. package/dist/agent-src/rules/no-pr-progress-comments.md +0 -1
  130. package/dist/agent-src/rules/no-roadmap-references.md +0 -1
  131. package/dist/agent-src/rules/notes-first-reasoning.md +0 -1
  132. package/dist/agent-src/rules/onboarding-gate.md +0 -1
  133. package/dist/agent-src/rules/output-discipline.md +0 -1
  134. package/dist/agent-src/rules/package-ci-checks.md +0 -1
  135. package/dist/agent-src/rules/persona-governance.md +2 -3
  136. package/dist/agent-src/rules/php-coding.md +0 -1
  137. package/dist/agent-src/rules/prefer-enums-over-literals.md +0 -1
  138. package/dist/agent-src/rules/preservation-guard.md +0 -1
  139. package/dist/agent-src/rules/provider-lifecycle-discipline.md +2 -3
  140. package/dist/agent-src/rules/question-not-instruction.md +0 -1
  141. package/dist/agent-src/rules/reviewer-awareness.md +0 -1
  142. package/dist/agent-src/rules/roadmap-ci-steps-policy.md +0 -1
  143. package/dist/agent-src/rules/roadmap-progress-sync.md +3 -6
  144. package/dist/agent-src/rules/role-mode-adherence.md +0 -1
  145. package/dist/agent-src/rules/rule-type-governance.md +0 -1
  146. package/dist/agent-src/rules/runtime-safety.md +0 -1
  147. package/dist/agent-src/rules/scale-discipline.md +0 -1
  148. package/dist/agent-src/rules/secret-vcs-guard.md +0 -1
  149. package/dist/agent-src/rules/security-sensitive-stop.md +0 -1
  150. package/dist/agent-src/rules/self-repair-loop.md +0 -1
  151. package/dist/agent-src/rules/senior-engineering-discipline.md +0 -1
  152. package/dist/agent-src/rules/session-canary.md +0 -1
  153. package/dist/agent-src/rules/settings-ask-protocol.md +5 -6
  154. package/dist/agent-src/rules/size-enforcement.md +0 -1
  155. package/dist/agent-src/rules/skill-improvement-trigger.md +2 -3
  156. package/dist/agent-src/rules/skill-quality.md +0 -1
  157. package/dist/agent-src/rules/slash-command-routing-policy.md +0 -1
  158. package/dist/agent-src/rules/source-confidentiality.md +0 -1
  159. package/dist/agent-src/rules/source-discovery-gate.md +0 -1
  160. package/dist/agent-src/rules/source-of-truth.md +0 -1
  161. package/dist/agent-src/rules/spreadsheet-source-quality.md +1 -2
  162. package/dist/agent-src/rules/strategy-safety-floor.md +0 -1
  163. package/dist/agent-src/rules/symfony-routing.md +1 -2
  164. package/dist/agent-src/rules/think-before-action.md +0 -1
  165. package/dist/agent-src/rules/token-budget-discipline.md +12 -46
  166. package/dist/agent-src/rules/token-efficiency.md +0 -1
  167. package/dist/agent-src/rules/token-optimizer-maintenance.md +0 -1
  168. package/dist/agent-src/rules/tool-safety.md +0 -1
  169. package/dist/agent-src/rules/ui-audit-gate.md +1 -2
  170. package/dist/agent-src/rules/untrusted-input-defense.md +0 -1
  171. package/dist/agent-src/rules/upstream-proposal.md +0 -1
  172. package/dist/agent-src/rules/user-interaction.md +0 -1
  173. package/dist/agent-src/rules/user-interrupt-priority.md +0 -1
  174. package/dist/agent-src/scripts/gate_budget.ts +47 -23
  175. package/dist/agent-src/scripts/gate_execute.ts +12 -4
  176. package/dist/agent-src/skills/ai-council/SKILL.md +7 -4
  177. package/dist/agent-src/skills/ai-council/references/cost-and-redaction.md +21 -11
  178. package/dist/agent-src/skills/ai-council/references/procedure.md +12 -6
  179. package/dist/agent-src/skills/analysis-autonomous-mode/SKILL.md +1 -1
  180. package/dist/agent-src/skills/bug-analyzer/SKILL.md +1 -1
  181. package/dist/agent-src/skills/command-routing/SKILL.md +3 -4
  182. package/dist/agent-src/skills/conventional-commits-writing/SKILL.md +127 -139
  183. package/dist/agent-src/skills/corpus-grounding/ATTRIBUTION.md +39 -0
  184. package/dist/agent-src/skills/corpus-grounding/SKILL.md +8 -2
  185. package/dist/agent-src/skills/database/data/manifest.json +2 -2
  186. package/dist/agent-src/skills/database/data/query-tuning.csv +13 -13
  187. package/dist/agent-src/skills/design-system-capture/SKILL.md +0 -3
  188. package/dist/agent-src/skills/estimate-ticket/SKILL.md +1 -1
  189. package/dist/agent-src/skills/feature-planning/SKILL.md +1 -1
  190. package/dist/agent-src/skills/git-workflow/SKILL.md +44 -44
  191. package/dist/agent-src/skills/git-workflow/references/branch-update.md +312 -0
  192. package/dist/agent-src/skills/git-workflow/references/commit-subject.md +205 -0
  193. package/dist/agent-src/skills/jira-integration/SKILL.md +3 -3
  194. package/dist/agent-src/skills/merge-conflicts/SKILL.md +10 -4
  195. package/dist/agent-src/skills/po-discovery/SKILL.md +1 -1
  196. package/dist/agent-src/skills/refine-ticket/SKILL.md +4 -4
  197. package/dist/agent-src/skills/roadmap-writing/SKILL.md +2 -2
  198. package/dist/agent-src/skills/skill-improvement-pipeline/SKILL.md +4 -2
  199. package/dist/agent-src/skills/source-discovery/SKILL.md +1 -1
  200. package/dist/agent-src/skills/tailwind-engineer/SKILL.md +3 -1
  201. package/dist/agent-src/skills/testing-anti-patterns/SKILL.md +1 -1
  202. package/dist/agent-src/skills/using-git-worktrees/SKILL.md +1 -1
  203. package/dist/agent-src/skills/verify-repair-loop/SKILL.md +2 -2
  204. package/dist/agent-src/templates/AGENTS.md +1 -1
  205. package/dist/agent-src/templates/agent-settings.md +46 -129
  206. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +3 -3
  207. package/dist/agent-src/templates/command.md +2 -2
  208. package/dist/agent-src/templates/roadmaps.md +6 -1
  209. package/dist/agent-src/templates/scripts/work_engine/_lib/agent_settings.ts +0 -6
  210. package/dist/agent-src/templates/scripts/work_engine/directives/backend/_self_fix.ts +11 -7
  211. package/dist/agent-src/templates/scripts/work_engine/hooks/builtin/decision_trace.ts +3 -2
  212. package/dist/agent-src/templates/scripts/work_engine/hooks/builtin/memory_visibility.ts +2 -1
  213. package/dist/agent-src/templates/scripts/work_engine/hooks/settings.ts +0 -6
  214. package/dist/agent-src/templates/scripts/work_engine/scoring/decision_engine.ts +9 -12
  215. package/dist/agent-src/templates/scripts/work_engine/scoring/memory_visibility.ts +2 -1
  216. package/dist/agent-src/templates/skill.md +1 -1
  217. package/dist/cli/registry.js +1 -0
  218. package/dist/cli-delegate/check_update_banner.js +195 -119
  219. package/dist/cli-delegate/{chunk-TRI6DQZ6.js → chunk-5GPULQBE.js} +60 -42
  220. package/dist/cli-delegate/{chunk-JQVYKIZA.js → chunk-6SRJTYJS.js} +33 -177
  221. package/dist/cli-delegate/chunk-6V5FMA3P.js +186 -0
  222. package/dist/cli-delegate/chunk-6YQC2HLF.js +415 -0
  223. package/dist/cli-delegate/{chunk-E4XIZDIB.js → chunk-7HKRE54K.js} +1 -64
  224. package/dist/cli-delegate/{chunk-NQ7WT43P.js → chunk-AED2VQGM.js} +65 -11
  225. package/dist/cli-delegate/{chunk-7HQ52DHU.js → chunk-AL3RZ22D.js} +1 -1
  226. package/dist/cli-delegate/{chunk-DBH4AHDK.js → chunk-ED7KCMLB.js} +9 -11
  227. package/dist/cli-delegate/{chunk-NXEILF2K.js → chunk-F3QDG2GT.js} +481 -72
  228. package/dist/cli-delegate/{chunk-CQWX336L.js → chunk-G5VVIZRC.js} +3 -3
  229. package/dist/cli-delegate/{chunk-JY2I2DXV.js → chunk-H76PHZBI.js} +137 -60
  230. package/dist/cli-delegate/chunk-IAYTIIQW.js +67 -0
  231. package/dist/cli-delegate/{chunk-LIYTLH6O.js → chunk-KXXWJTDO.js} +5 -10
  232. package/dist/cli-delegate/{chunk-T7L2QK3K.js → chunk-LQOCRFWT.js} +1 -1
  233. package/dist/cli-delegate/{chunk-S4YWNRKO.js → chunk-MDPPKQCQ.js} +34 -1
  234. package/dist/cli-delegate/{chunk-S4UMZNES.js → chunk-MSUL5NYP.js} +5 -5
  235. package/dist/cli-delegate/chunk-OAFSJBHH.js +272 -0
  236. package/dist/cli-delegate/{chunk-GKE7ZVFA.js → chunk-PWX7CKMD.js} +1 -1
  237. package/dist/cli-delegate/{chunk-NDJLNC6Q.js → chunk-T6BP34WI.js} +1 -0
  238. package/dist/cli-delegate/{chunk-RQNNW7IF.js → chunk-T7XSJSUQ.js} +433 -632
  239. package/dist/cli-delegate/{chunk-EEHDXSYD.js → chunk-WQWXGIWB.js} +12 -273
  240. package/dist/cli-delegate/{chunk-QLDHIPWR.js → chunk-XQTPXKFA.js} +1 -1
  241. package/dist/cli-delegate/cmd_analyze_session.js +223 -43
  242. package/dist/cli-delegate/cmd_brand_status.js +3 -2
  243. package/dist/cli-delegate/cmd_conformance.js +105 -35
  244. package/dist/cli-delegate/cmd_converge.js +3 -3
  245. package/dist/cli-delegate/cmd_doctor.js +15 -12
  246. package/dist/cli-delegate/cmd_doctor_neighbours.js +11 -4
  247. package/dist/cli-delegate/cmd_explain.js +43 -19
  248. package/dist/cli-delegate/cmd_export.js +10 -10
  249. package/dist/cli-delegate/cmd_git_convention.js +1851 -0
  250. package/dist/cli-delegate/cmd_handoff.js +40 -21
  251. package/dist/cli-delegate/cmd_mcp_available.js +3 -2
  252. package/dist/cli-delegate/cmd_migrate.js +3 -3
  253. package/dist/cli-delegate/cmd_packs_active.js +4 -3
  254. package/dist/cli-delegate/cmd_prune.js +10 -10
  255. package/dist/cli-delegate/cmd_route_audit.js +7 -7
  256. package/dist/cli-delegate/cmd_route_explain.js +5 -5
  257. package/dist/cli-delegate/cmd_session_recycle.js +9 -7
  258. package/dist/cli-delegate/cmd_settings_check.js +54 -7
  259. package/dist/cli-delegate/cmd_settings_get.js +18 -8
  260. package/dist/cli-delegate/cmd_settings_migrate.js +10 -10
  261. package/dist/cli-delegate/cmd_settings_set.js +1 -1
  262. package/dist/cli-delegate/cmd_sync.js +10 -10
  263. package/dist/cli-delegate/cmd_uninstall.js +10 -10
  264. package/dist/cli-delegate/cmd_update.js +7 -7
  265. package/dist/cli-delegate/cmd_upgrade.js +7 -7
  266. package/dist/cli-delegate/cmd_validate.js +10 -10
  267. package/dist/cli-delegate/cmd_versions.js +5 -5
  268. package/dist/cli-delegate/gate_budget.js +1 -1
  269. package/dist/cli-delegate/gate_execute.js +2 -2
  270. package/dist/cli-delegate/roadmap_gates.js +2 -2
  271. package/dist/discovery/deprecation-report.md +1 -1
  272. package/dist/discovery/discovery-manifest.json +129 -90
  273. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  274. package/dist/discovery/discovery-manifest.summary.md +3 -3
  275. package/dist/discovery/dormancy-report.md +1 -1
  276. package/dist/discovery/orphan-report.md +1 -1
  277. package/dist/discovery/packs.json +24 -9
  278. package/dist/discovery/trust-report.md +3 -3
  279. package/dist/discovery/workspaces.json +5 -4
  280. package/dist/hooks/dispatch.js +2151 -1820
  281. package/dist/hooks/dispatch.sha256 +1 -1
  282. package/dist/install/install.mjs +462 -431
  283. package/dist/install/installThinLayer.js +40 -12
  284. package/dist/install/installedRuleLinks.js +105 -19
  285. package/dist/mcp/awesome-mcp-servers.row.md +1 -1
  286. package/dist/mcp/mcp-cloudflare-catalogue.json +2 -2
  287. package/dist/mcp/registry-manifest.json +5 -5
  288. package/dist/mcp/server.json +2 -2
  289. package/dist/mcp/server.mjs +2702 -1995
  290. package/dist/router.json +1 -1
  291. package/dist/scripts/_lib/agent_settings.js +15 -120
  292. package/dist/scripts/_lib/compile_time_toggles.js +12 -21
  293. package/dist/scripts/_lib/git_convention.js +232 -0
  294. package/dist/scripts/_lib/global_deploy_inventory.js +730 -0
  295. package/dist/scripts/_lib/installed_layer.js +344 -18
  296. package/dist/scripts/_lib/package_root.js +68 -0
  297. package/dist/scripts/_lib/rule_law_section.js +1 -1
  298. package/dist/scripts/_lib/settings_removed_keys.js +168 -0
  299. package/dist/scripts/_lib/thin_rules.js +80 -3
  300. package/dist/server/app.js +2 -1
  301. package/dist/server/gitKeysGate.js +105 -0
  302. package/dist/server/routes/settings.js +67 -8
  303. package/dist/server/routes/wizard.js +4 -0
  304. package/dist/server/schemas/settings.js +23 -81
  305. package/dist/shared/skillRanking.js +30 -4
  306. package/dist/ui/assets/{index-Cwq4d0hX.js → index-C3djEJah.js} +2 -2
  307. package/dist/ui/index.html +1 -1
  308. package/docs/MIGRATION.md +72 -1
  309. package/docs/contracts/settings-classes.md +35 -65
  310. package/docs/guidelines/agent-infra/active-remediation-mechanics.md +39 -0
  311. package/docs/guidelines/agent-infra/context-hygiene-mechanics.md +1 -1
  312. package/docs/guidelines/agent-infra/cross-source-consistency-mechanics.md +8 -10
  313. package/docs/guidelines/agent-infra/frontier-reasoning-operating-profile.md +3 -2
  314. package/docs/guidelines/agent-infra/layered-settings.md +13 -1
  315. package/docs/guidelines/agent-infra/roadmap-progress-mechanics.md +1 -1
  316. package/docs/guidelines/agent-infra/self-improvement-pipeline.md +10 -3
  317. package/docs/guidelines/agent-infra/size-and-scope.md +36 -0
  318. package/docs/guidelines/php/git.md +15 -2
  319. package/package.json +1 -1
  320. package/src/agent-src/scripts/gate_budget.ts +47 -23
  321. package/src/agent-src/scripts/gate_execute.ts +12 -4
  322. package/src/agent-src/templates/AGENTS.md +1 -1
  323. package/src/agent-src/templates/scripts/work_engine/_lib/agent_settings.ts +0 -6
  324. package/src/agent-src/templates/scripts/work_engine/directives/backend/_self_fix.ts +11 -7
  325. package/src/agent-src/templates/scripts/work_engine/hooks/builtin/decision_trace.ts +3 -2
  326. package/src/agent-src/templates/scripts/work_engine/hooks/builtin/memory_visibility.ts +2 -1
  327. package/src/agent-src/templates/scripts/work_engine/hooks/settings.ts +0 -6
  328. package/src/agent-src/templates/scripts/work_engine/scoring/decision_engine.ts +9 -12
  329. package/src/agent-src/templates/scripts/work_engine/scoring/memory_visibility.ts +2 -1
  330. package/src/config/agent-settings.template.yml +79 -312
  331. package/src/config/agents-paths.yml +16 -0
  332. package/src/config/assurance-capability-registry.json +7 -3
  333. package/src/config/ci-local-parity.yml +3 -0
  334. package/src/config/continuity-surface.json +3 -3
  335. package/src/config/discovery/packs.yml +17 -1
  336. package/src/config/evaluator-budgets.json +19 -6
  337. package/src/config/gate-coverage.yml +65 -23
  338. package/src/config/gate-violation-baselines.json +53 -13
  339. package/src/config/gitignore-block.txt +19 -0
  340. package/src/config/hook-bundle-budget.json +1 -1
  341. package/src/config/release-gate-locality.yml +2 -1
  342. package/src/config/routing-coverage-seed.json +48 -6
  343. package/src/config/rule-law-ceilings.json +12 -6
  344. package/src/config/rule-obligations.json +833 -0
  345. package/src/install/installThinLayer.ts +76 -10
  346. package/src/install/installedRuleLinks.ts +105 -17
  347. package/src/scripts/_cli/cmd_analyze_session.ts +9 -15
  348. package/src/scripts/_cli/cmd_conformance.ts +13 -2
  349. package/src/scripts/_cli/cmd_doctor.ts +10 -10
  350. package/src/scripts/_cli/cmd_doctor_neighbours.ts +133 -0
  351. package/src/scripts/_cli/cmd_explain.ts +72 -14
  352. package/src/scripts/_cli/cmd_git_convention.ts +637 -0
  353. package/src/scripts/_cli/cmd_settings_check.ts +66 -8
  354. package/src/scripts/_cli/cmd_settings_get.ts +18 -3
  355. package/src/scripts/_cli/doctor_execution.ts +72 -1
  356. package/src/scripts/_dispatch.bash +37 -2
  357. package/src/scripts/_lib/agent_settings.ts +15 -124
  358. package/src/scripts/_lib/blocked_by_marker.ts +1 -1
  359. package/src/scripts/_lib/compile_time_toggles.ts +12 -21
  360. package/src/scripts/_lib/dispatch_import_closure.ts +163 -0
  361. package/src/scripts/_lib/git_base_ref.ts +92 -0
  362. package/src/scripts/_lib/git_convention.ts +291 -0
  363. package/src/scripts/_lib/git_convention_carrier.ts +389 -0
  364. package/src/scripts/_lib/git_convention_grammar.ts +246 -0
  365. package/src/scripts/_lib/git_convention_measure.ts +344 -0
  366. package/src/scripts/_lib/global_deploy_inventory.ts +74 -0
  367. package/src/scripts/_lib/graph_feeder_record.ts +236 -13
  368. package/src/scripts/_lib/installed_layer.ts +448 -23
  369. package/src/scripts/_lib/knowledge_global.ts +14 -1
  370. package/src/scripts/_lib/module_reach.ts +456 -0
  371. package/src/scripts/_lib/neighbour_contradictions.ts +236 -0
  372. package/src/scripts/_lib/neighbour_tool_use.ts +8 -10
  373. package/src/scripts/_lib/ratification_artifact.ts +220 -1
  374. package/src/scripts/_lib/ratification_subject.ts +92 -0
  375. package/src/scripts/_lib/release_findings_ingest.ts +15 -7
  376. package/src/scripts/_lib/release_highlights.ts +5 -0
  377. package/src/scripts/_lib/rule_law_section.ts +1 -1
  378. package/src/scripts/_lib/rule_obligations.ts +205 -0
  379. package/src/scripts/_lib/self_repair.ts +1 -1
  380. package/src/scripts/_lib/settings_removed_keys.ts +173 -0
  381. package/src/scripts/_lib/test_red_state.ts +5 -0
  382. package/src/scripts/_lib/thin_rules.ts +83 -3
  383. package/src/scripts/_lib/touched_file_quality.ts +142 -6
  384. package/src/scripts/_lib/worker_budget.ts +1 -1
  385. package/src/scripts/adr/regenerate_index.ts +16 -1
  386. package/src/scripts/ai_council/config.ts +7 -7
  387. package/src/scripts/ai_council/modification_review.ts +100 -0
  388. package/src/scripts/ai_council/modification_review_questions.ts +90 -0
  389. package/src/scripts/ai_council/orchestrator.ts +5 -5
  390. package/src/scripts/ai_council/spend_gate.ts +18 -7
  391. package/src/scripts/ai_team/config.ts +11 -16
  392. package/src/scripts/audit_user_type_axis.ts +20 -8
  393. package/src/scripts/bench_ab_clone.ts +1 -2
  394. package/src/scripts/bench_concern_spawn_path.ts +129 -0
  395. package/src/scripts/bench_graph_feeder_latency.ts +584 -0
  396. package/src/scripts/check_agent_artifact_location.ts +36 -0
  397. package/src/scripts/check_branch_freshness.ts +147 -24
  398. package/src/scripts/check_enforcement_coverage.ts +130 -0
  399. package/src/scripts/check_evaluator_budgets.ts +4 -0
  400. package/src/scripts/check_finding_dispositions.ts +88 -25
  401. package/src/scripts/check_gate_coverage.ts +4 -3
  402. package/src/scripts/check_gate_reachability.ts +48 -1
  403. package/src/scripts/check_generator_sync.ts +48 -0
  404. package/src/scripts/check_hook_bundle_composition.ts +107 -0
  405. package/src/scripts/check_kernel_edit_ratified.ts +86 -6
  406. package/src/scripts/check_pack_size.ts +1 -1
  407. package/src/scripts/check_release_manifest_content.ts +189 -0
  408. package/src/scripts/check_standing_rule_delivery.ts +96 -0
  409. package/src/scripts/check_suppression_hygiene.ts +2 -5
  410. package/src/scripts/ci_settle.ts +42 -5
  411. package/src/scripts/classify_merge_risk.ts +320 -0
  412. package/src/scripts/closure_scan.ts +91 -1
  413. package/src/scripts/command_suggester/settings.ts +8 -108
  414. package/src/scripts/command_suggester/types.ts +4 -5
  415. package/src/scripts/consumer_matrix.ts +102 -0
  416. package/src/scripts/context_hygiene_hook.ts +13 -23
  417. package/src/scripts/cost/preflight.mjs +12 -1
  418. package/src/scripts/council_cli.ts +7 -7
  419. package/src/scripts/dispatch_r2_reviewer.ts +24 -11
  420. package/src/scripts/explain_run.ts +8 -13
  421. package/src/scripts/generate_git_convention_grammar.ts +127 -0
  422. package/src/scripts/generate_host_cost_table.ts +20 -3
  423. package/src/scripts/handoff_context_hook.ts +86 -37
  424. package/src/scripts/hook_manifest.json +1 -1
  425. package/src/scripts/hook_manifest.yaml +25 -6
  426. package/src/scripts/hooks/block_config_weakening.ts +48 -5
  427. package/src/scripts/hooks/block_plumbing_writes.ts +8 -4
  428. package/src/scripts/hooks/concern_registry.ts +2 -0
  429. package/src/scripts/hooks/delegation_nudge_hook.ts +2 -3
  430. package/src/scripts/hooks/evidence_independence.ts +12 -4
  431. package/src/scripts/hooks/mcp_usage_observation_hook.ts +121 -0
  432. package/src/scripts/hooks/push_settle_hook.ts +4 -3
  433. package/src/scripts/hooks/rule_inject_hook.ts +44 -3
  434. package/src/scripts/hooks/state_io.ts +8 -4
  435. package/src/scripts/hooks/telemetry_usage_hook.ts +7 -46
  436. package/src/scripts/hooks/turn_end_gate_hook.ts +1 -0
  437. package/src/scripts/install-hooks.sh +42 -14
  438. package/src/scripts/install.ts +7 -31
  439. package/src/scripts/lint_blocker_citations.ts +198 -0
  440. package/src/scripts/lint_evidence_artifacts.ts +9 -0
  441. package/src/scripts/lint_hook_concern_budget.ts +10 -21
  442. package/src/scripts/lint_pack_boundaries.ts +406 -28
  443. package/src/scripts/lint_roadmap_blockers.ts +282 -29
  444. package/src/scripts/lint_roadmap_complexity.ts +4 -2
  445. package/src/scripts/lint_rule_law_section.ts +151 -21
  446. package/src/scripts/lint_rule_skill_pack_reach.ts +17 -0
  447. package/src/scripts/lint_settings_classes.ts +1 -1
  448. package/src/scripts/lint_ticked_unmet_criteria.ts +165 -0
  449. package/src/scripts/lint_workflow_security.ts +12 -1
  450. package/src/scripts/measure_skill_ranker_baseline.ts +5 -0
  451. package/src/scripts/model_rule_injection.ts +3 -3
  452. package/src/scripts/onboarding_gate_hook.ts +7 -6
  453. package/src/scripts/print_required_checks.ts +15 -3
  454. package/src/scripts/probe_host_compliance.ts +33 -5
  455. package/src/scripts/probe_turnaround.ts +183 -3
  456. package/src/scripts/ratification_header.ts +77 -0
  457. package/src/scripts/refusal_envelope.ts +138 -0
  458. package/src/scripts/release_publication.ts +29 -3
  459. package/src/scripts/report_dispatch_import_closure.ts +76 -0
  460. package/src/scripts/report_installed_rule_links.ts +118 -1
  461. package/src/scripts/report_module_reach.ts +212 -0
  462. package/src/scripts/report_obligation_mechanism.ts +16 -18
  463. package/src/scripts/report_parked_blockers.ts +222 -0
  464. package/src/scripts/report_required_checks_drift.ts +196 -0
  465. package/src/scripts/report_skill_ranker_confusion.ts +103 -2
  466. package/src/scripts/report_standing_payload_by_host.ts +1 -1
  467. package/src/scripts/routing_doctor.ts +2 -2
  468. package/src/scripts/schemas/agent-settings.schema.json +17 -31
  469. package/src/scripts/schemas/command.schema.json +1 -1
  470. package/src/scripts/schemas/skill.schema.json +1 -1
  471. package/src/scripts/self_review_gate.ts +39 -2
  472. package/src/scripts/skill_tools/score_skill_relevance.ts +28 -19
  473. package/src/scripts/sync_pr_branch.ts +403 -132
  474. package/src/scripts/trigger_eval_grandfather.json +0 -16
  475. package/src/server/schemas/settings.ts +33 -177
  476. package/src/shared/skillRanking.ts +53 -4
  477. package/dist/cli-delegate/chunk-NYX3L2PZ.js +0 -99
  478. package/src/scripts/_lib/config_chain.ts +0 -477
  479. package/src/scripts/_lib/conformance_report.ts +0 -403
  480. package/src/scripts/_lib/eval_discrimination.ts +0 -95
  481. package/src/scripts/_lib/evaluator_promotion.ts +0 -225
  482. package/src/scripts/_lib/file_slicer.ts +0 -117
  483. package/src/scripts/_lib/legacy_boundary_map.ts +0 -228
  484. package/src/scripts/_lib/minimality_tiebreak.ts +0 -168
  485. package/src/scripts/_lib/overbuild_lens_contract.ts +0 -196
  486. package/src/scripts/_lib/role_split.ts +0 -338
@@ -33,6 +33,20 @@
33
33
  * priced in the same unit the installed-layer report uses. Today's larger
34
34
  * rules are named in `body_exceptions`, shrink-only on the same terms.
35
35
  *
36
+ * 4. TRIGGER PRESENCE (`--axis trigger`). Added by step 3.4 of
37
+ * `road-to-an-installed-layer-that-is-thinned`: a stub is a pointer a prompt
38
+ * must be able to pull in, so a routed rule with ZERO triggers in
39
+ * `dist/router.json` cannot be discovered once it ships as a stub — the
40
+ * pointer sits in the installed layer forever and the law behind it never
41
+ * arrives. Four rules read zero today (measured 2026-10-06) and are named in
42
+ * `no_trigger`, SHRINK-ONLY on the same terms as `missing`: each is delivered
43
+ * by a mechanism other than a keyword match — a path collision
44
+ * (`collision_ok`) or an unconditional load with no scoping at all — which is
45
+ * a deliberate routing choice recorded in the rule's own frontmatter, not an
46
+ * oversight this gate should paper over. A NEW routed rule therefore cannot
47
+ * be born with no trigger a prompt can fire, same as it cannot be born
48
+ * lawless.
49
+ *
36
50
  * WHY THE TARGET IS REPORTED AND NOT ENFORCED. A rule shortened to fit a number
37
51
  * is the failure this roadmap says it will not cause. 1,200 is where the
38
52
  * distribution sits (median 511, p90 1,787) and a rule between target and hard
@@ -51,7 +65,7 @@
51
65
  *
52
66
  * WHAT IT DOES NOT ASSERT. Not that the extracted section is the rule's real
53
67
  * obligation — a heading match is structural and checkable, "this sentence is
54
- * the obligation" is not; the `# obligation: line N` marker and
68
+ * the obligation" is not; the ids in `src/config/rule-obligations.json` and
55
69
  * `report_obligation_carriers` own that. Not that a rule at its recorded
56
70
  * exception is correct, only that it is not worse. And not a cross-commit
57
71
  * ratchet: this gate reads one tree, so "shrink-only" means the tree sits at or
@@ -100,13 +114,15 @@ export interface LawConfig {
100
114
  measured_at_commit?: string;
101
115
  /** Routed rules with no law section. Shrink-only: ids may leave, never join. */
102
116
  missing: string[];
117
+ /** Routed rules with no trigger a prompt can fire. Shrink-only, same terms as `missing`. */
118
+ no_trigger: string[];
103
119
  /** Rules whose law exceeds {@link LAW_HARD_CHARS}. */
104
120
  law_exceptions: Record<string, SizeException>;
105
121
  /** Rules whose body exceeds {@link BODY_HARD_CHARS}. */
106
122
  body_exceptions: Record<string, SizeException>;
107
123
  }
108
124
 
109
- export type Axis = 'presence' | 'ceiling' | 'body-ceiling' | 'all';
125
+ export type Axis = 'presence' | 'ceiling' | 'body-ceiling' | 'trigger' | 'all';
110
126
 
111
127
  export interface Finding {
112
128
  id: string;
@@ -153,6 +169,7 @@ export function readConfig(root = REPO_ROOT): LawConfig {
153
169
  const raw = JSON.parse(fs.readFileSync(p, 'utf-8')) as Partial<LawConfig>;
154
170
  return {
155
171
  missing: Array.isArray(raw.missing) ? raw.missing : [],
172
+ no_trigger: Array.isArray(raw.no_trigger) ? raw.no_trigger : [],
156
173
  law_exceptions: raw.law_exceptions ?? {},
157
174
  body_exceptions: raw.body_exceptions ?? {},
158
175
  measured_at_commit: raw.measured_at_commit ?? '',
@@ -170,15 +187,47 @@ export function measureRouted(root = REPO_ROOT): RuleLawMeasure[] {
170
187
  return out;
171
188
  }
172
189
 
190
+ /** Trigger count per routed tier rule id, straight off `dist/router.json`. */
191
+ export function routedRuleTriggerCounts(root = REPO_ROOT): Map<string, number> {
192
+ const data = JSON.parse(fs.readFileSync(path.join(root, ROUTER_REL), 'utf-8')) as Record<
193
+ string,
194
+ unknown
195
+ >;
196
+ const counts = new Map<string, number>();
197
+ for (const tier of ['tier_1', 'tier_2']) {
198
+ const entries = data[tier];
199
+ if (!Array.isArray(entries)) continue;
200
+ for (const e of entries) {
201
+ const rec = e as Record<string, unknown>;
202
+ const triggers = rec['triggers'];
203
+ counts.set(String(rec['id']), Array.isArray(triggers) ? triggers.length : 0);
204
+ }
205
+ }
206
+ return counts;
207
+ }
208
+
173
209
  export function lint(root = REPO_ROOT, axis: Axis = 'all'): LintResult {
174
210
  const cfg = readConfig(root);
175
211
  const measures = measureRouted(root);
212
+ const triggerCounts = routedRuleTriggerCounts(root);
176
213
  const findings: Finding[] = [];
177
214
  const overTarget: Array<{ id: string; chars: number }> = [];
178
215
  const baselined = new Set(cfg.missing);
216
+ const noTriggerBaselined = new Set(cfg.no_trigger);
179
217
  const want = (a: Exclude<Axis, 'all'>): boolean => axis === 'all' || axis === a;
180
218
 
181
219
  for (const m of measures) {
220
+ if (want('trigger') && (triggerCounts.get(m.id) ?? 0) === 0 && !noTriggerBaselined.has(m.id)) {
221
+ findings.push({
222
+ id: m.id,
223
+ axis: 'trigger',
224
+ kind: 'no-trigger',
225
+ detail:
226
+ 'routed rule has no trigger in `dist/router.json` — a prompt can never pull it in, ' +
227
+ `so it cannot ship as a stub; add a trigger, or add the id to \`no_trigger\` in ` +
228
+ `${CONFIG_REL} (that list is shrink-only, so a new routed rule may not join it)`,
229
+ });
230
+ }
182
231
  if (want('presence') && m.law === null && !baselined.has(m.id)) {
183
232
  findings.push({
184
233
  id: m.id,
@@ -270,6 +319,30 @@ export function lint(root = REPO_ROOT, axis: Axis = 'all'): LintResult {
270
319
  }
271
320
  }
272
321
 
322
+ // Same stale-debt check for the trigger baseline: an id that gained a
323
+ // trigger, or left the routed set, is debt that was paid and never
324
+ // collected.
325
+ if (want('trigger')) {
326
+ const routed = new Set(measures.map((m) => m.id));
327
+ for (const id of cfg.no_trigger) {
328
+ if (!routed.has(id)) {
329
+ findings.push({
330
+ id,
331
+ axis: 'trigger',
332
+ kind: 'stale-baseline-entry',
333
+ detail: `is not a routed rule any more — remove it from \`no_trigger\` in ${CONFIG_REL}`,
334
+ });
335
+ } else if ((triggerCounts.get(id) ?? 0) > 0) {
336
+ findings.push({
337
+ id,
338
+ axis: 'trigger',
339
+ kind: 'stale-baseline-entry',
340
+ detail: `now has a trigger — remove it from \`no_trigger\` in ${CONFIG_REL}`,
341
+ });
342
+ }
343
+ }
344
+ }
345
+
273
346
  const kernelReported = kernelRuleIds(root).map((id) => {
274
347
  const p = path.join(root, RULES_REL, `${id}.md`);
275
348
  return { id, sections: fs.existsSync(p) ? measureRuleFile(id, p).sections : 0 };
@@ -284,9 +357,14 @@ export function lint(root = REPO_ROOT, axis: Axis = 'all'): LintResult {
284
357
  export function writeBaseline(root = REPO_ROOT, today: string): string {
285
358
  const prev = fs.existsSync(path.join(root, CONFIG_REL))
286
359
  ? readConfig(root)
287
- : { missing: [], law_exceptions: {}, body_exceptions: {} };
360
+ : { missing: [], no_trigger: [], law_exceptions: {}, body_exceptions: {} };
288
361
  const measures = measureRouted(root);
362
+ const triggerCounts = routedRuleTriggerCounts(root);
289
363
  const missing = measures.filter((m) => m.law === null).map((m) => m.id).sort();
364
+ const no_trigger = measures
365
+ .filter((m) => (triggerCounts.get(m.id) ?? 0) === 0)
366
+ .map((m) => m.id)
367
+ .sort();
290
368
  const law_exceptions: Record<string, SizeException> = {};
291
369
  const body_exceptions: Record<string, SizeException> = {};
292
370
  for (const m of measures) {
@@ -311,16 +389,22 @@ export function writeBaseline(root = REPO_ROOT, today: string): string {
311
389
  }
312
390
  const cfg = {
313
391
  _comment:
314
- 'Per-rule law-section and body ceilings (road-to-rule-laws-that-can-stand Phase 1). ' +
315
- 'SHRINK-ONLY on every axis: an id may LEAVE `missing`, never join it; a recorded ' +
316
- 'exception is a ceiling the rule may fall below and never rise above. Raising one to ' +
317
- 'clear a red is the config-weakening move this repo blocks by construction — ' +
318
- '`--write-baseline` refuses to raise, it only re-records the smaller of old and ' +
319
- 'current. A rule at its exception is not thereby correct, only not worse. Regenerate ' +
320
- 'with `lint_rule_law_section --write-baseline`; never hand-edit the counts, but DO ' +
321
- 'hand-edit `owner`, `review` and `reason` — those are the review contract and the ' +
322
- 'generator only seeds them.',
392
+ 'Per-rule law-section and body ceilings (road-to-rule-laws-that-can-stand Phase 1) plus ' +
393
+ 'the trigger-presence baseline (road-to-an-installed-layer-that-is-thinned step 3.4). Two ' +
394
+ 'different guarantees, not one: `law_exceptions` and `body_exceptions` are numeric ' +
395
+ 'ceilings `--write-baseline` structurally refuses to raise (it re-records the SMALLER of ' +
396
+ 'old and current, never the current alone) — a rule at its exception is not thereby ' +
397
+ 'correct, only not worse. `missing` and `no_trigger` are LIST membership: an id SHOULD ' +
398
+ 'only leave, never join, but that is a review convention the generator does not enforce ' +
399
+ 'by construction — `--write-baseline` re-records every id that currently fails ' +
400
+ 'presence/trigger, full stop, so a newly-broken rule is swept in exactly like a ' +
401
+ 'genuinely-fixed one is swept out. The `stale-baseline-entry` finding makes a fixed id ' +
402
+ 'visible for removal; nothing makes a newly-broken id visible for refusal except a human ' +
403
+ 'reading the diff. Regenerate with `lint_rule_law_section --write-baseline`; never ' +
404
+ 'hand-edit the counts, but DO hand-edit `owner`, `review` and `reason` — those are the ' +
405
+ 'review contract and the generator only seeds them.',
323
406
  measured_at_commit: prev.measured_at_commit ?? '',
407
+ no_trigger,
324
408
  missing,
325
409
  law_exceptions,
326
410
  body_exceptions,
@@ -339,7 +423,7 @@ interface Args {
339
423
  }
340
424
 
341
425
  const USAGE =
342
- 'usage: lint_rule_law_section [--axis presence|ceiling|body-ceiling|all] [--quiet] ' +
426
+ 'usage: lint_rule_law_section [--axis presence|ceiling|body-ceiling|trigger|all] [--quiet] ' +
343
427
  '[--write-baseline] [--root DIR] [--self-test]\n';
344
428
 
345
429
  function parseArgs(argv: string[]): Args {
@@ -381,7 +465,7 @@ function parseArgs(argv: string[]): Args {
381
465
  process.exit(2);
382
466
  }
383
467
  }
384
- if (!['presence', 'ceiling', 'body-ceiling', 'all'].includes(out.axis)) {
468
+ if (!['presence', 'ceiling', 'body-ceiling', 'trigger', 'all'].includes(out.axis)) {
385
469
  process.stderr.write(USAGE);
386
470
  process.stderr.write(`lint_rule_law_section: error: unknown axis: ${out.axis}\n`);
387
471
  process.exit(2);
@@ -402,23 +486,45 @@ export function selfTest(write: (s: string) => void = (s) => process.stdout.writ
402
486
  fs.mkdirSync(path.join(tmp, 'dist'), { recursive: true });
403
487
  fs.writeFileSync(
404
488
  path.join(tmp, ROUTER_REL),
405
- JSON.stringify({ kernel: [], tier_1: [{ id: 'lawless' }, { id: 'lawful' }], tier_2: [] }),
489
+ JSON.stringify({
490
+ kernel: [],
491
+ tier_1: [
492
+ { id: 'lawless', triggers: [{ keyword: 'lawless-word' }] },
493
+ { id: 'lawful', triggers: [{ keyword: 'lawful-word' }] },
494
+ { id: 'mute', triggers: [] },
495
+ { id: 'vocal', triggers: [{ keyword: 'vocal-word' }] },
496
+ ],
497
+ tier_2: [],
498
+ }),
406
499
  );
407
500
  fs.writeFileSync(
408
501
  path.join(tmp, CONFIG_REL),
409
- JSON.stringify({ missing: [], law_exceptions: {}, body_exceptions: {} }),
502
+ JSON.stringify({ missing: [], no_trigger: [], law_exceptions: {}, body_exceptions: {} }),
410
503
  );
411
504
  fs.writeFileSync(path.join(tmp, 'src/rules/lawless.md'), '---\nx: 1\n---\n\n# Lawless\n\nProse.\n');
412
505
  fs.writeFileSync(
413
506
  path.join(tmp, 'src/rules/lawful.md'),
414
507
  '---\nx: 1\n---\n\n# Lawful\n\n## The Iron Law\n\nNEVER DO THE THING.\n',
415
508
  );
509
+ fs.writeFileSync(
510
+ path.join(tmp, 'src/rules/mute.md'),
511
+ '---\nx: 1\n---\n\n# Mute\n\n## The Iron Law\n\nNEVER DO THE THING.\n',
512
+ );
513
+ fs.writeFileSync(
514
+ path.join(tmp, 'src/rules/vocal.md'),
515
+ '---\nx: 1\n---\n\n# Vocal\n\n## The Iron Law\n\nNEVER DO THE THING.\n',
516
+ );
416
517
 
417
518
  const rejecting = lint(tmp, 'presence');
418
519
  const accepting = (() => {
419
520
  fs.writeFileSync(
420
521
  path.join(tmp, CONFIG_REL),
421
- JSON.stringify({ missing: ['lawless'], law_exceptions: {}, body_exceptions: {} }),
522
+ JSON.stringify({
523
+ missing: ['lawless'],
524
+ no_trigger: [],
525
+ law_exceptions: {},
526
+ body_exceptions: {},
527
+ }),
422
528
  );
423
529
  return lint(tmp, 'presence');
424
530
  })();
@@ -426,12 +532,36 @@ export function selfTest(write: (s: string) => void = (s) => process.stdout.writ
426
532
  rejecting.findings.length === 1 &&
427
533
  rejecting.findings[0]?.kind === 'no-law-section' &&
428
534
  accepting.findings.length === 0;
535
+
536
+ // Same rejecting/accepting shape for the trigger axis (step 3.4):
537
+ // `mute` has a law but no trigger and is unbaselined, `vocal` has both.
538
+ const triggerRejecting = lint(tmp, 'trigger');
539
+ const triggerAccepting = (() => {
540
+ fs.writeFileSync(
541
+ path.join(tmp, CONFIG_REL),
542
+ JSON.stringify({
543
+ missing: ['lawless'],
544
+ no_trigger: ['mute'],
545
+ law_exceptions: {},
546
+ body_exceptions: {},
547
+ }),
548
+ );
549
+ return lint(tmp, 'trigger');
550
+ })();
551
+ const triggerOk =
552
+ triggerRejecting.findings.map((f) => f.id).sort().join(',') === 'mute' &&
553
+ triggerRejecting.findings.every((f) => f.kind === 'no-trigger') &&
554
+ triggerAccepting.findings.length === 0;
555
+
556
+ const allOk = ok && triggerOk;
429
557
  write(
430
- ok
431
- ? '✅ self-test: 1 rejecting case, 1 accepting case — the reading decides the verdict\n'
432
- : `❌ self-test FAILED: rejecting=${rejecting.findings.length} accepting=${accepting.findings.length}\n`,
558
+ allOk
559
+ ? '✅ self-test: presence + trigger axes each have a rejecting and an accepting case\n'
560
+ : `❌ self-test FAILED: presence rejecting=${rejecting.findings.length} ` +
561
+ `accepting=${accepting.findings.length}; trigger rejecting=` +
562
+ `${triggerRejecting.findings.length} accepting=${triggerAccepting.findings.length}\n`,
433
563
  );
434
- return ok ? 0 : 1;
564
+ return allOk ? 0 : 1;
435
565
  } finally {
436
566
  fs.rmSync(tmp, { recursive: true, force: true });
437
567
  }
@@ -35,6 +35,23 @@
35
35
  * the wizard may offer it and the user may decline, so an invariant that
36
36
  * counted it would pass on installs that do not exist.
37
37
  *
38
+ * SIBLING GATE, OPPOSITE READING, SAME REASONING (2026-10-09). Since D5 of
39
+ * `road-to-gates-a-pull-request-can-hear`, `lint_pack_boundaries` DOES read
40
+ * `suggests` — as permitting a cross-pack link. That is not a contradiction of
41
+ * the paragraph above, and the discriminator is the direction of the claim
42
+ * each gate makes:
43
+ *
44
+ * - THIS gate asserts a route WILL RESOLVE on the installs it covers.
45
+ * Counting an advisory edge would assert resolution on installs that may
46
+ * not exist — a false negative in the dangerous direction.
47
+ * - The boundary gate reports a link that MAY DANGLE. An advisory edge is
48
+ * the author stating they accept the dangle for a declining consumer, so
49
+ * reading it there downgrades a finding the author has already answered.
50
+ *
51
+ * Practical consequence, stated because it is the mistake the asymmetry
52
+ * invites: adding a `suggests` edge does NOT clear an `unreachable-route`
53
+ * finding here. It never will. Fix the route or accept the finding.
54
+ *
38
55
  * ADVISORY UNTIL ITS FINDING SET IS EMPTY, AND THE FIRST RUN SAYS WHY.
39
56
  * Measured on introduction: 12 `unreachable-route` and 14 `unrouted-skill`
40
57
  * findings across 116 rules. The UI pair is one instance of an estate-wide
@@ -604,7 +604,7 @@ function main(): number {
604
604
  for (const [removedKey, reason] of REMOVED_KEYS) {
605
605
  if (reason.trim() === '') {
606
606
  findings.push(
607
- `src/scripts/_lib/agent_settings.ts \`${removedKey}\` is in REMOVED_KEYS with an empty ` +
607
+ `src/scripts/_lib/settings_removed_keys.ts \`${removedKey}\` is in REMOVED_KEYS with an empty ` +
608
608
  'reason — name what decides instead, not that it is gone.',
609
609
  );
610
610
  }
@@ -0,0 +1,165 @@
1
+ #!/usr/bin/env tsx
2
+ /**
3
+ * Reports an acceptance criterion ticked over its own "NOT met".
4
+ *
5
+ * A `- [x] AC-<n>` item whose own text says a half of it `is NOT met` is a
6
+ * contradiction a reader of the checkbox never sees: the glyph says done, the
7
+ * prose says not. The honest glyph is `[~]`, which carries the unmet half as a
8
+ * deferral rather than hiding it under a tick.
9
+ *
10
+ * The criterion's text is the bullet line plus its indented continuation lines,
11
+ * up to a blank line, a less-indented line or the next checkbox. Fenced code is
12
+ * skipped, so a quoted example is not a finding. The match is the literal
13
+ * `NOT met` — upper-case on purpose, because that is how an author marks the
14
+ * unmet half, and a lower-case "not met" inside an explanation is prose.
15
+ *
16
+ * Usage:
17
+ * ./scripts-run src/scripts/lint_ticked_unmet_criteria
18
+ * ./scripts-run src/scripts/lint_ticked_unmet_criteria --root <repo>
19
+ *
20
+ * Scans every `*.md` under the roadmap tree, archive included: an archived
21
+ * roadmap is exactly where a contradictory tick outlives the session that
22
+ * made it.
23
+ *
24
+ * Exit codes: 0 no hit · 1 at least one hit · 2 usage error.
25
+ */
26
+ import * as fs from 'node:fs';
27
+ import * as path from 'node:path';
28
+ import { fileURLToPath, pathToFileURL } from 'node:url';
29
+
30
+ import { reportScanned } from './_lib/scan_scope.js';
31
+
32
+ interface Hit {
33
+ file: string;
34
+ line: number;
35
+ criterion: string;
36
+ }
37
+
38
+ const TICKED_AC_RE = /^([ \t]*)[-*][ \t]+\[[xX]\][ \t]+(AC-[\w.-]+)/;
39
+ const CHECKBOX_RE = /^[ \t]*[-*][ \t]+\[[ xX~-]\]/;
40
+ const FENCE_RE = /^[ \t]*(```|~~~)/;
41
+ const UNMET = 'NOT met';
42
+
43
+ function _indent(line: string): number {
44
+ return (/^[ \t]*/.exec(line)?.[0] ?? '').length;
45
+ }
46
+
47
+ function scanText(text: string, file: string): Hit[] {
48
+ const lines = text.split('\n');
49
+ const hits: Hit[] = [];
50
+ let inFence = false;
51
+ for (let i = 0; i < lines.length; i += 1) {
52
+ const line = lines[i] as string;
53
+ if (FENCE_RE.test(line)) {
54
+ inFence = !inFence;
55
+ continue;
56
+ }
57
+ if (inFence) {
58
+ continue;
59
+ }
60
+ const m = TICKED_AC_RE.exec(line);
61
+ if (!m) {
62
+ continue;
63
+ }
64
+ const base = (m[1] as string).length;
65
+ const block = [line];
66
+ for (let j = i + 1; j < lines.length; j += 1) {
67
+ const next = lines[j] as string;
68
+ if (next.trim() === '' || CHECKBOX_RE.test(next) || FENCE_RE.test(next) || _indent(next) <= base) {
69
+ break;
70
+ }
71
+ block.push(next);
72
+ }
73
+ if (block.join('\n').includes(UNMET)) {
74
+ hits.push({ file, line: i + 1, criterion: m[2] as string });
75
+ }
76
+ }
77
+ return hits;
78
+ }
79
+
80
+ function _walk(dir: string): string[] {
81
+ let entries: fs.Dirent[];
82
+ try {
83
+ entries = fs.readdirSync(dir, { withFileTypes: true });
84
+ } catch {
85
+ return [];
86
+ }
87
+ const out: string[] = [];
88
+ for (const e of entries.sort((a, b) => a.name.localeCompare(b.name))) {
89
+ const full = path.join(dir, e.name);
90
+ if (e.isDirectory()) {
91
+ out.push(..._walk(full));
92
+ } else if (e.isFile() && e.name.endsWith('.md')) {
93
+ out.push(full);
94
+ }
95
+ }
96
+ return out;
97
+ }
98
+
99
+ function scanTree(root: string): { hits: Hit[]; scanned: number } {
100
+ const files = _walk(path.join(root, 'agents', 'roadmaps'));
101
+ const hits: Hit[] = [];
102
+ for (const abs of files) {
103
+ const rel = path.relative(root, abs).split(path.sep).join('/');
104
+ hits.push(...scanText(fs.readFileSync(abs, 'utf8'), rel));
105
+ }
106
+ return { hits, scanned: files.length };
107
+ }
108
+
109
+ const _DEFAULT_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', '..');
110
+
111
+ function main(argv: string[] = process.argv.slice(2)): number {
112
+ let root = _DEFAULT_ROOT;
113
+ for (let i = 0; i < argv.length; i += 1) {
114
+ const arg = argv[i];
115
+ if (arg === '--root') {
116
+ const v = argv[i + 1];
117
+ if (v === undefined) {
118
+ process.stderr.write('lint_ticked_unmet_criteria: --root requires a value\n');
119
+ return 2;
120
+ }
121
+ root = path.resolve(v);
122
+ i += 1;
123
+ } else {
124
+ process.stderr.write(`lint_ticked_unmet_criteria: unknown argument: ${String(arg)}\n`);
125
+ return 2;
126
+ }
127
+ }
128
+ const { hits, scanned } = scanTree(root);
129
+ reportScanned({
130
+ gate: 'lint_ticked_unmet_criteria',
131
+ scanned,
132
+ units: 'roadmap file(s)',
133
+ roots: ['agents/roadmaps'],
134
+ allowEmpty: 'EMPTY_VALID: a checkout with no roadmap has no criterion to tick',
135
+ });
136
+ if (hits.length === 0) {
137
+ process.stdout.write(`✅ lint_ticked_unmet_criteria: ${String(scanned)} roadmap file(s), no criterion ticked over "${UNMET}".\n`);
138
+ return 0;
139
+ }
140
+ process.stderr.write(
141
+ `❌ lint_ticked_unmet_criteria: ${String(hits.length)} criterion/criteria ticked [x] over their own "${UNMET}":\n`,
142
+ );
143
+ for (const h of hits) {
144
+ process.stderr.write(` ${h.file}:${String(h.line)} · ${h.criterion}\n`);
145
+ }
146
+ process.stderr.write('\n The unmet half is a deferral: use `[~]` and carry it, or meet it.\n');
147
+ return 1;
148
+ }
149
+
150
+ if (process.argv[1] !== undefined) {
151
+ try {
152
+ const here = fs.realpathSync(fileURLToPath(import.meta.url));
153
+ const argv1 = fs.realpathSync(path.resolve(process.argv[1]));
154
+ if (here === argv1) {
155
+ process.exit(main());
156
+ }
157
+ } catch {
158
+ if (import.meta.url === pathToFileURL(path.resolve(process.argv[1])).href) {
159
+ process.exit(main());
160
+ }
161
+ }
162
+ }
163
+
164
+ export { scanText, scanTree, main };
165
+ export type { Hit };
@@ -28,6 +28,9 @@
28
28
  * TIERS are untouched; only the description of what MEDIUM covers now matches
29
29
  * the code. Re-tiering the locked model is a separate decision, recorded as
30
30
  * unresolved in agents/evidence/analysis/workflow-security-net-degraded-decision.md.
31
+ * The CI INVOCATION is decided there too: since 2026-10-07 consistency.yml runs
32
+ * this gate under `--strict` (AI council, 2/2), so a HIGH fails a pull request;
33
+ * the tiers are unchanged.
31
34
  *
32
35
  * Script-injection detection (regex-based) is intentionally deferred — it
33
36
  * requires an AST-aware pass to avoid false positives on quoted / escaped
@@ -805,7 +808,9 @@ export function main(argv?: string[]): number {
805
808
  );
806
809
  if (high.length || medium.length) {
807
810
  process.stdout.write(
808
- ' (warn-only — run with --strict to make HIGH findings block CI)\n',
811
+ args.strict
812
+ ? ' (--strict — HIGH findings fail this run; MEDIUM stays advisory)\n'
813
+ : ' (warn-only — run with --strict to make HIGH findings block CI)\n',
809
814
  );
810
815
  } else {
811
816
  process.stdout.write(' no non-allowlisted findings\n');
@@ -813,6 +818,12 @@ export function main(argv?: string[]): number {
813
818
  }
814
819
 
815
820
  if (args.strict && high.length) {
821
+ if (args.quiet) {
822
+ // --quiet suppresses the report; a failing run still names its cause.
823
+ process.stderr.write(
824
+ `workflow-security: ${high.length} HIGH under --strict — rerun without --quiet for the findings\n`,
825
+ );
826
+ }
816
827
  return 1;
817
828
  }
818
829
  return 0;
@@ -495,6 +495,11 @@ export const RANKER_LABELS: Readonly<Record<string, RankOptions>> = {
495
495
  headings: { includeHeadings: true },
496
496
  idf: { idfWeighting: true },
497
497
  'idf+when-to-use': { idfWeighting: true, includeWhenToUse: true },
498
+ // `road-to-a-ranker-whose-ties-break-on-signal` Phase 3: the order inside a
499
+ // block of equal integer scores, alone and over the one weighting that
500
+ // makes the unrounded score vary.
501
+ ties: { tieBreakUnrounded: true },
502
+ 'idf+ties': { idfWeighting: true, tieBreakUnrounded: true },
498
503
  };
499
504
 
500
505
  /**
@@ -617,7 +617,7 @@ export function runEndpoints(corpusDir: string): EndpointResult[] {
617
617
  let deliveries = 0;
618
618
  let unequal = 0;
619
619
  for (const c of positives) {
620
- const injection = buildInjection(REPO_ROOT, c.prompt, c.openFiles, null, new Set());
620
+ const injection = buildInjection(REPO_ROOT, c.prompt, c.openFiles, null, new Set(), false);
621
621
  if (injection === null) continue;
622
622
  for (const id of injection.rules) {
623
623
  const projected = loadRuleBody(REPO_ROOT, id);
@@ -803,12 +803,12 @@ export function runSelftest(corpusDir: string): SelftestCase[] {
803
803
  const probe = cases.find(
804
804
  (c) =>
805
805
  c.label === 'positive' &&
806
- buildInjection(REPO_ROOT, c.prompt, c.openFiles, null, new Set()) !== null,
806
+ buildInjection(REPO_ROOT, c.prompt, c.openFiles, null, new Set(), false) !== null,
807
807
  );
808
808
  const injection =
809
809
  probe === undefined
810
810
  ? null
811
- : buildInjection(REPO_ROOT, probe.prompt, probe.openFiles, null, new Set());
811
+ : buildInjection(REPO_ROOT, probe.prompt, probe.openFiles, null, new Set(), false);
812
812
  if (injection === null || injection.rules.length === 0) {
813
813
  out.push({
814
814
  endpoint: 'a-delivery',
@@ -10,7 +10,7 @@
10
10
  * deterministic state file the rule body can cite as the source of
11
11
  * truth for "do I need to prompt the user about /onboard?".
12
12
  *
13
- * Output is written to `agents/runtime/state/onboarding-gate.json` with:
13
+ * Output is written to `agents/state/onboarding-gate.json` with:
14
14
  * {
15
15
  * "required": <bool>, // true → rule fires on first turn
16
16
  * "reason": "<string>", // why this state was set
@@ -33,8 +33,9 @@ import path from "node:path";
33
33
  import { fileURLToPath, pathToFileURL } from "node:url";
34
34
 
35
35
  // Re-use the shared atomic-write helper so concerns honour the single
36
- // `agents/runtime/state/.dispatcher.lock` discipline (hook-architecture-v1.md
37
- // § Concurrency, Phase 7.4).
36
+ // `agents/state/.dispatcher.lock` discipline (hook-architecture-v1.md,
37
+ // Concurrency, Phase 7.4) — the lock sits beside THIS hook's own target, not
38
+ // the fixed `agents/runtime/state/` path the discipline cites generally.
38
39
  import { atomic_write_json } from "./hooks/state_io.js";
39
40
  import { readHookStdin } from "./hooks/hook_stdin.js";
40
41
 
@@ -153,11 +154,11 @@ function _now_iso(): string {
153
154
  }
154
155
 
155
156
  /**
156
- * Write `agents/runtime/state/onboarding-gate.json` atomically.
157
+ * Write `agents/state/onboarding-gate.json` atomically.
157
158
  *
158
- * Uses the shared `agents/runtime/state/.dispatcher.lock` so concurrent
159
+ * Uses the shared `agents/state/.dispatcher.lock` so concurrent
159
160
  * dispatcher invocations across platforms cannot tear the file
160
- * (hook-architecture-v1.md § Concurrency, Phase 7.4).
161
+ * (hook-architecture-v1.md, Concurrency, Phase 7.4).
161
162
  */
162
163
  function _write_state(
163
164
  consumer_root: string,
@@ -63,6 +63,8 @@ const DOCS_ONLY_ALLOWED_TOP: ReadonlySet<string> = new Set([
63
63
 
64
64
  // Check names below are the strings GitHub actually REPORTS, verified against
65
65
  // `gh pr checks 1108` on 2026-08-02 (road-to-renewal-foundation Phase 1).
66
+ // `Standing payload delta + budget gate` was added to all three shapes on
67
+ // 2026-10-07, when it was found required by the ruleset and absent here.
66
68
  //
67
69
  // They previously named a matrix that had drifted into fiction — `Consistency`,
68
70
  // `Skill Lint`, `Tests / install-tests`, `Tests / node-tests`,
@@ -79,6 +81,7 @@ const DOCS_ONLY_ALLOWED_TOP: ReadonlySet<string> = new Set([
79
81
  // change — the exact failure this reconciliation removed.
80
82
  const FEATURE_CHECKS = [
81
83
  'Sync + Generate Tools Consistency',
84
+ 'Standing payload delta + budget gate',
82
85
  'Smoke — kernel',
83
86
  'Smoke — router',
84
87
  'Smoke — schema',
@@ -98,6 +101,7 @@ const FEATURE_CHECKS = [
98
101
 
99
102
  const RELEASE_CHECKS = [
100
103
  'Sync + Generate Tools Consistency',
104
+ 'Standing payload delta + budget gate',
101
105
  'Smoke — kernel',
102
106
  'Smoke — router',
103
107
  'Smoke — schema',
@@ -112,6 +116,7 @@ const RELEASE_CHECKS = [
112
116
 
113
117
  const DOCS_ONLY_CHECKS = [
114
118
  'Sync + Generate Tools Consistency',
119
+ 'Standing payload delta + budget gate',
115
120
  'Smoke — kernel',
116
121
  'Smoke — router',
117
122
  'Smoke — schema',
@@ -120,8 +125,11 @@ const DOCS_ONLY_CHECKS = [
120
125
 
121
126
  /**
122
127
  * The checks that mechanically BLOCK a merge, per the repository ruleset
123
- * `main protection` (id 17749383). Everything else above runs and is visible
124
- * on the PR but does not gate the merge button.
128
+ * `main protection` (id 17749383), read on 2026-10-07: two required status
129
+ * contexts, the second added on 2026-09-11 (ADR-276, recorded by #2169).
130
+ * Everything else above runs and is visible on the PR but does not gate the
131
+ * merge button. `standing-payload-delta.yml` runs on every `pull_request`, so
132
+ * the second context appears in all three shapes.
125
133
  *
126
134
  * Deliberately a constant, not an API read: this script is contractually
127
135
  * offline ("never invokes `gh`, never touches the network"). Re-verify with
@@ -129,7 +137,10 @@ const DOCS_ONLY_CHECKS = [
129
137
  * changes — `docs/contracts/branch-protection-policy.md` § Change discipline
130
138
  * owns that procedure.
131
139
  */
132
- const ENFORCED_CHECKS = ['Sync + Generate Tools Consistency'] as const;
140
+ const ENFORCED_CHECKS = [
141
+ 'Sync + Generate Tools Consistency',
142
+ 'Standing payload delta + budget gate',
143
+ ] as const;
133
144
 
134
145
  /** `git rev-parse --abbrev-ref HEAD`, mirroring `_git(check=True)`. */
135
146
  function current_branch(): string {
@@ -314,6 +325,7 @@ export {
314
325
  FEATURE_CHECKS,
315
326
  RELEASE_CHECKS,
316
327
  DOCS_ONLY_CHECKS,
328
+ ENFORCED_CHECKS,
317
329
  current_branch,
318
330
  diff_files,
319
331
  is_docs_only,