@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
@@ -0,0 +1,173 @@
1
+ /**
2
+ * The registry of DELETED settings keys, and the once-per-run notice a leftover
3
+ * value gets. Extracted from `agent_settings.ts`, which sits at the 1500-line
4
+ * source ceiling — every retirement batch adds entries here, and here they cost
5
+ * no ratchet. `agent_settings.ts` re-exports `REMOVED_KEYS` so existing
6
+ * importers (the loader, `lint_settings_classes`) are unchanged.
7
+ */
8
+
9
+ type SettingsDict = Record<string, unknown>;
10
+
11
+ /**
12
+ * Settings keys this package has DELETED. A leftover value from an older
13
+ * install is ignored — never applied by any reader — and surfaced with ONE
14
+ * deprecation line per key per process run (stderr; the exit code never
15
+ * changes).
16
+ *
17
+ * The map carries a per-key REASON rather than one shared sentence, because
18
+ * the list now spans more than one deletion doctrine and a single blanket
19
+ * phrase would mis-attribute every future entry. A reader who hits the line
20
+ * should learn why the key went, not just that it did.
21
+ *
22
+ * `subagents.*` — the always-on-orchestration doctrine
23
+ * (road-to-always-on-orchestration Phase 1): the layer has no per-layer
24
+ * on/off setting any more. `ai_team.enabled` joined in Step 1.3 — the
25
+ * `/team` family's availability is a codex-CLI/auth FACT
26
+ * (`src/scripts/ai_team/availability.ts`), not a flag; the `ai_team` config
27
+ * loader (`src/scripts/ai_team/config.ts`) separately accepts a leftover
28
+ * `enabled` key without failing closed, so this warning is the only surfaced
29
+ * signal of that deletion.
30
+ *
31
+ * `hooks.turn_end_gate.*` — the turn-end gate is always armed (2026-08-12).
32
+ * A default-off safety gate cannot soak, so the switch protecting the soak
33
+ * made the soak impossible; whether the gate fires is now decided by each
34
+ * detector's own trigger conditions. See `turn_end_gate_hook.ts` § "Always
35
+ * armed".
36
+ *
37
+ * The five `derivable` leaves below (2026-08-12, road-to-zero-settings Phase
38
+ * 2.1) are a different case from every entry above them, and the difference is
39
+ * the whole safety argument: no code path ever *consulted* them. Each appeared
40
+ * in the template, the schema and the reference page, and several in the setup
41
+ * wizard, while the decision they looked like they governed was taken
42
+ * elsewhere. A key nothing reads cannot change a default by leaving — so this
43
+ * is the one deletion batch that needs no replacement mechanism, only the
44
+ * per-key statement of what already decides.
45
+ *
46
+ * A sixth unread key, `screenshots.data_bearing_gate`, was found in the same
47
+ * pass and deliberately NOT deleted — it is `consent`, and the open question is
48
+ * whether the repair is to build its missing reader or to delete a promise a
49
+ * Hard Floor can never honour. See `settings-classes.md` § The six unread keys.
50
+ *
51
+ * `worktrees.mode` (2026-08-13, ADR-229) is a third doctrine again: not
52
+ * always-on, not unread. It WAS read, and the reader honoured all three values —
53
+ * the deletion says the decision was never the agent's to make. `ask` bought a
54
+ * round trip per spawn, `on` let the agent start parallel work unprompted, and
55
+ * `off` described the wanted behavior, so `off` became the hardcoded rule and
56
+ * the switch went. What decides instead is the user's own sentence in the chat.
57
+ *
58
+ * The 2026-10-09 batch (road-to-settings-classes-derivable-surface-stagnation
59
+ * Phase 2) is a fourth doctrine: `derivable` keys whose shipped default is the
60
+ * only behavior the package supports. Each WAS read — by code or by rule and
61
+ * command prose — and every reader was rewritten to state the old default as
62
+ * fixed behavior in the same change, so retiring the key changes no effective
63
+ * default; what a consumer who had set a non-default value loses is named by
64
+ * the reason.
65
+ *
66
+ * Every reason string must name what decides INSTEAD, never just "removed".
67
+ * Exported so `lint_settings_classes` can check the deletion side of the
68
+ * surface: a reason that names no replacement, or an entry whose key is live in
69
+ * the template again, is a contradiction the loader itself cannot notice.
70
+ */
71
+ export const REMOVED_KEYS: ReadonlyMap<string, string> = new Map([
72
+ ['subagents.enabled', 'always-on orchestration'],
73
+ ['subagents.auto', 'always-on orchestration'],
74
+ ['subagents.host_capabilities', 'always-on orchestration'],
75
+ ['subagents.budget_routing', 'always-on orchestration'],
76
+ ['ai_team.enabled', 'always-on orchestration'],
77
+ ['hooks.turn_end_gate.enabled', 'the turn-end gate is always armed'],
78
+ ['hooks.turn_end_gate.promissory', 'the turn-end gate is always armed'],
79
+ ['hooks.turn_end_gate.language', 'the turn-end gate is always armed'],
80
+ ['hooks.turn_end_gate.verification', 'the turn-end gate is always armed'],
81
+ ['telegraph.speak_scope', 'the rule body states its own scope; compile_time_toggles decides whether the rule ships'],
82
+ ['chat_history.max_size_kb', 'the rotate command takes --max-kb from argv; session-count pruning bounds the file'],
83
+ ['chat_history.on_overflow', 'the overflow mode comes from the rotate command --mode argv'],
84
+ ['quality.wait_for_remote_ci', 'whether to poll follows from the push plus a detectable remote pipeline'],
85
+ ['legal_review_prep.consented_at', 'the provenance sidecar settings:set writes and consentVerdict reads'],
86
+ ['worktrees.mode', 'the user asking for a worktree in the chat; creation is instruction-only and hardcoded'],
87
+ // 2026-10-09 — output and tone
88
+ ['personal.minimal_output', 'direct-answers Iron Law 3 mandates terse replies; there is no verbose mode'],
89
+ ['personal.play_by_play', 'direct-answers: no narration unless the user asks for it in the turn'],
90
+ ['personal.pr_comment_bot_icon', 'no-decorative-emojis-in-git-surfaces forbids the 🤖 prefix'],
91
+ ['verbosity.intent_announcements', 'direct-answers: act and emit the result, no "Let me…" openers'],
92
+ ['verbosity.preview_artifacts', 'generated content is used directly; preview-on-error and the Iron-Law gates decide when a preview shows'],
93
+ ['verbosity.routine_confirmations', 'the no-cheap-questions Pre-Send Self-Check; Iron-Law gates always ask'],
94
+ ['verbosity.post_action_reports', 'direct-answers Iron Law 3: a one-line confirmation and one end-summary'],
95
+ ['telegraph.speak', 'the telegraph-speak predicate in compile_time_toggles.ts; the bench verdict is package-level (ADR telegraph/0002)'],
96
+ ['tokens.rich_skills', "the skill's own token_budget_class: rich plus the lint_token_budget_discipline ceiling"],
97
+ // 2026-10-09 — reasoning protocol switches
98
+ ['reasoning.auto_gate', 'the RDP gate task signal plus the host self-assessment in rdp-gate.md'],
99
+ ['reasoning.components.orchestrator', 'the RDP gate task and host signals decide per component; reasoning.enabled stays the hard off'],
100
+ ['reasoning.components.notes_first', 'the RDP gate task and host signals decide per component; reasoning.enabled stays the hard off'],
101
+ ['reasoning.components.grounding', 'the RDP gate task and host signals decide per component; reasoning.enabled stays the hard off'],
102
+ ['reasoning.components.intent', 'the RDP gate task and host signals decide per component; reasoning.enabled stays the hard off'],
103
+ ['reasoning.components.complexity_first', 'the RDP gate task and host signals decide per component; reasoning.enabled stays the hard off'],
104
+ ['reasoning.components.verifier_default', 'the RDP gate task and host signals decide per component; reasoning.enabled stays the hard off'],
105
+ ['reasoning.components.prediction_tracking', 'the RDP gate task and host signals decide per component; reasoning.enabled stays the hard off'],
106
+ ['reasoning.components.decision_ledger', 'the RDP gate task and host signals decide per component; reasoning.enabled stays the hard off'],
107
+ ['reasoning.components.uncertainty_budget', 'the RDP gate task and host signals decide per component; reasoning.enabled stays the hard off'],
108
+ // 2026-10-09 — roadmap cadence
109
+ ['roadmap.skip_pre_run_gate', 'the command name names the scope; only an ambiguous roadmap or an unresolvable conflict shows the gate'],
110
+ ['roadmap.dashboard_regen_cadence', 'a fixed cadence: every 5th closed step, every phase boundary, reply end and any file-shape touch'],
111
+ // 2026-10-09 — command suggestion and PR creation
112
+ ['commands.auto_detect', "an orchestrator's own auto_detect front-matter and the --no-auto-detect flag"],
113
+ ['commands.suggestion.enabled', 'the suggester match-score floor and cooldown; /command-suggestion-off silences one conversation'],
114
+ ['commands.suggestion.confidence_floor', "the suggester's fixed 0.6 floor; a command's own suggestion frontmatter can tighten it"],
115
+ ['commands.suggestion.cooldown_seconds', "the suggester's fixed 600-second cooldown; a command's own suggestion frontmatter can lengthen it"],
116
+ ['commands.suggestion.max_options', 'the fixed cap of 4 suggestions plus the always-present as-is option'],
117
+ ['commands.create_pr.api_examples', "/create-pr's grounding rule: an example only from a real source, otherwise a one-line pointer"],
118
+ ['commands.create_pr.ui_paths', "/create-pr's light frontend heuristic, which fails open"],
119
+ ['commands.create_pr.api_paths', "/create-pr's light API-endpoint heuristic, which fails open"],
120
+ // 2026-10-09 — memory and knowledge sharing
121
+ ['memory.cadence', 'a fixed cadence: the memory line renders whenever a memory type was asked; memory.visibility: off still silences it'],
122
+ ['memory.review_threshold', "/memory load's fixed preview threshold of 10 unreviewed intake signals"],
123
+ ['knowledge.global_sharing.redaction.enabled', 'the write-time redaction scan, which always runs before a card goes global'],
124
+ ['knowledge.global_sharing.redaction.halt_on_trigger', 'the redaction gate, which always halts on a confidential-pattern hit'],
125
+ ['knowledge.global_sharing.auto_promote_threshold', 'the fixed two-repo sighting count that triggers a promotion suggestion'],
126
+ ['knowledge.global_sharing.freshness.hypothesis_after_days', "the card's age over last_verified against the fixed 90-day lead-only window"],
127
+ ['knowledge.global_sharing.freshness.stale_after_days', "the card's age over last_verified against the fixed 180-day skip window"],
128
+ // 2026-10-09 — hooks and engine
129
+ ['hooks.concern_budget.max_per_event', "the concern-budget gate's own constant of 8 per (platform, event) cell"],
130
+ ['hooks.concern_budget.hard_fail', "the concern-budget gate's --strict argv; without it the gate warns"],
131
+ ['decision_engine.surface_traces', 'nothing: the per-phase decision trace stays off, the old default'],
132
+ ['decision_engine.on_block_fallback', 'the fail-safe: an on_block ask that times out always stops'],
133
+ ['explain.enable_last', 'the presence of a work-state trace; explain last always renders it'],
134
+ // 2026-10-09 — remaining
135
+ ['project.pr_template', '/create-pr, which reads .github/pull_request_template.md'],
136
+ ['pipelines.skill_improvement', 'the skill-improvement-trigger rule; the capture is a proposal the user confirms'],
137
+ ['consistency.cross_source', 'the cross-source-consistency rule, always on; batching and the no-cheap-questions floor bound the noise'],
138
+ ['subagents.downshift', 'the model_tier each sub-task declares; downshift is always on'],
139
+ ['ai_team.suppress_setup_hint', 'nothing: the one-line team-mode setup hint is always shown'],
140
+ ]);
141
+
142
+ /** Keys already warned about in THIS process — the "once per run" dedupe. */
143
+ const _warnedRemovedKeys = new Set<string>();
144
+
145
+ /** Read one dotted path out of a merged settings tree; `undefined` when absent. */
146
+ function _readDotted(root: SettingsDict, dotted: string): unknown {
147
+ let node: unknown = root;
148
+ for (const part of dotted.split('.')) {
149
+ if (typeof node !== 'object' || node === null || Array.isArray(node)) {
150
+ return undefined;
151
+ }
152
+ node = (node as SettingsDict)[part];
153
+ }
154
+ return node;
155
+ }
156
+
157
+ /**
158
+ * Warn once per process, on stderr, for every {@link REMOVED_KEYS} entry still
159
+ * present in a resolved settings tree. Never throws, never changes what the
160
+ * caller does with `merged` — a pure notification side effect.
161
+ */
162
+ export function warnRemovedKeys(merged: SettingsDict): void {
163
+ for (const [key, reason] of REMOVED_KEYS) {
164
+ if (_warnedRemovedKeys.has(key)) {
165
+ continue;
166
+ }
167
+ if (_readDotted(merged, key) === undefined) {
168
+ continue;
169
+ }
170
+ _warnedRemovedKeys.add(key);
171
+ process.stderr.write(`${key} was removed (${reason}); ignored.\n`);
172
+ }
173
+ }
@@ -10,6 +10,11 @@
10
10
  * This module is that emission, so the registry entry moves in the same change
11
11
  * rather than being left describing a gap that closed.
12
12
  *
13
+ * DATED 2026-10-06. The emission exists and is tested, but nothing calls it:
14
+ * this writer has no production caller, so the registry row was corrected back
15
+ * to `degraded` the same day. The caller belongs to the stub that owns it —
16
+ * whoever lands it sets the row back to `available`.
17
+ *
13
18
  * WHAT IT IS NOT. It is not a test runner, and it does not decide whether a
14
19
  * failure is a legitimate RED. The failure CLASSES belong to the TDD skill
15
20
  * (`src/skills/test-driven-development/SKILL.md`, Test-Red row) and this module
@@ -284,15 +284,95 @@ function _title(s: string): string {
284
284
  * Exported so the WRITER and every DETECTOR share one definition. A gate that
285
285
  * re-spelled this string would drift from the writer silently, and the failure
286
286
  * would be invisible in exactly the direction that matters: a stub the gate
287
- * fails to recognise reads as a complete rule body.
287
+ * fails to recognise reads as a complete rule body. Two gates had done exactly
288
+ * that until step 2.1 of `road-to-a-thinned-layer-measured-in-one-unit`; both
289
+ * import this now.
290
+ *
291
+ * SHORTENED 2026-10-06 from 47 characters to 27 (step 2.2). It is paid once per
292
+ * stub and there were 89 stubs on the measured layer, so the sentence cost
293
+ * 4,183 characters of a 97,496-character standing total; at 27 it costs 2,403,
294
+ * a saving of 1,780 = 20 x 89.
295
+ *
296
+ * WHAT THE SHORTENING WAS NOT ALLOWED TO DO: drop the instruction. This is the
297
+ * only standing text in the whole layer that says what a stub is FOR — "load
298
+ * the body" occurs in no kernel rule and in neither root instruction file — so
299
+ * a bare token like `> thin` would have saved more and left nothing that could
300
+ * be followed. The decision record (D2, K6) rejected that explicitly: nothing
301
+ * in this repository can check whether an instruction nobody states is still
302
+ * obeyed.
303
+ *
304
+ * WHY IT MUST STAY LONG ENOUGH TO BE UNIQUE: {@link is_thin_entry} is a
305
+ * substring test over the whole file, so a marker short or generic enough to
306
+ * occur inside ordinary rule prose would make that rule read as a stub — and
307
+ * nine rule files carry blockquote lines. `thin_marker_unique_in_corpus.test.ts`
308
+ * runs the constant against every rule body in `src/rules/` and against every
309
+ * entry `build_thin` emits, in both directions, which is the check that bounds
310
+ * any further shortening.
288
311
  */
289
- export const THIN_ENTRY_MARKER = '> Routed rule — load the body on trigger-match.';
312
+ export const THIN_ENTRY_MARKER = '> Load the body on a match.';
290
313
 
291
314
  /** Is this projected entry a pointer stub rather than a rule body? */
292
315
  export function is_thin_entry(text: string): boolean {
293
316
  return text.includes(THIN_ENTRY_MARKER);
294
317
  }
295
318
 
319
+ /**
320
+ * What introduces a stub's body pointer. One writer, one reader.
321
+ *
322
+ * A BARE PATH SINCE 2026-10-06 (step 2.3 of
323
+ * `road-to-a-thinned-layer-measured-in-one-unit`). The pointer used to be a
324
+ * markdown link, ``Body: [`<id>`](<prefix><id>.md)``, whose link TEXT repeated
325
+ * the rule id the target already ends in. That cost `6 + len(id)` per stub over
326
+ * the bare form — 2,359 characters across the 89 stubs of the measured layer,
327
+ * 534 of it pure syntax and the rest the id written a second time.
328
+ *
329
+ * Nothing followed the link as a link. Under `delivery` the hook loads the body
330
+ * and never reads the pointer at all; under `thin` an agent reads the path. A
331
+ * markdown link renders in neither case, so the syntax bought rendering nobody
332
+ * was doing.
333
+ */
334
+ export const THIN_BODY_POINTER_PREFIX = 'Body: ';
335
+
336
+ /**
337
+ * The pointer, as the WRITER emits it — exported so a detector cannot re-spell
338
+ * it, which is the same drift {@link THIN_ENTRY_MARKER} documents one screen up
339
+ * and which two gates had already committed there.
340
+ *
341
+ * WHAT IT CAPTURES is the whole tail of the line from `Body: ` to its end, and
342
+ * that is the intended semantic rather than an accident of greediness: the
343
+ * writer emits the pointer LAST on its line, so the tail IS the path. A review
344
+ * round proposed a lazy `(.+?\.md)` to stop at the first `.md`; measured, it
345
+ * changes nothing, because `\s*$` forces the match to reach end of line either
346
+ * way and a lazy quantifier simply backtracks forward to the same place. The
347
+ * greedy form is kept and the property is pinned by a test, so the next reader
348
+ * meets the measurement instead of repeating the proposal.
349
+ *
350
+ * ANCHORED TO END OF LINE, NOT `\S+`. The pointer is the last thing on its
351
+ * line, and a package root may contain spaces; `\S+` would silently stop at the
352
+ * first one and report a well-formed pointer as missing.
353
+ *
354
+ * COMPOSED FROM {@link THIN_BODY_POINTER_PREFIX} rather than re-spelling it.
355
+ * The constant exists so a reader cannot hold its own copy, and a pattern six
356
+ * lines below it holding a literal `Body: ` would have broken that invariant in
357
+ * the file that states it.
358
+ */
359
+ export const THIN_BODY_POINTER_RE = (() => {
360
+ const lit = THIN_BODY_POINTER_PREFIX.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
361
+ // THE LAST PREFIX ON THE LINE, NOT THE FIRST. `thin_entry` puts the rule's
362
+ // own `description` on the SAME line ahead of the pointer, so a description
363
+ // containing the literal `Body: ` used to start the match inside the
364
+ // description and capture it as part of the path — `has_body_pointer` stayed
365
+ // true while the extraction was wrong, which is a wrong assertion rather
366
+ // than a visible failure. Forbidding a second prefix inside the capture
367
+ // makes the first viable start the last occurrence, which is the pointer.
368
+ return new RegExp(`${lit}((?:(?!${lit}).)+\\.md)\\s*$`, 'm');
369
+ })();
370
+
371
+ /** Does this entry carry a body pointer the writer would recognise? */
372
+ export function has_body_pointer(text: string): boolean {
373
+ return THIN_BODY_POINTER_RE.test(text);
374
+ }
375
+
296
376
  /**
297
377
  * Where a stub tells a reader the body actually is.
298
378
  *
@@ -356,7 +436,7 @@ export function thin_entry(
356
436
  return (
357
437
  `## ${title}\n` +
358
438
  `${THIN_ENTRY_MARKER}${fires} ${desc} ` +
359
- `Body: [\`${rule_id}\`](${bodyLinkPrefix}${rule_id}.md)\n`
439
+ `${THIN_BODY_POINTER_PREFIX}${bodyLinkPrefix}${rule_id}.md\n`
360
440
  );
361
441
  }
362
442
 
@@ -89,6 +89,22 @@ export interface QualityRun {
89
89
  readonly output_head: readonly string[];
90
90
  readonly skipped: SkipReason | null;
91
91
  readonly files: readonly string[];
92
+ /**
93
+ * Matched files the tool reported it declined to look at. A run where EVERY
94
+ * matched file is listed here and the tool exited 0 is a verdict about
95
+ * nothing, so `exit_code` is `null` for it — the readings page § 5(a) found
96
+ * that row recorded `0, skipped: null`, the exact shape of a pass. A field
97
+ * rather than a fifth `SkipReason` (D2): a partly-ignored run keeps its real
98
+ * exit code, and a skip reason cannot sit beside a verdict.
99
+ */
100
+ readonly ignored_files: readonly string[];
101
+ /**
102
+ * Type-check commands the resolver emitted that produced no verdict on this
103
+ * turn — unscoped, absent or mutating. Identical on every record of the turn,
104
+ * so ANY single row says that a `0` beside it was a lint verdict and not a
105
+ * type verdict (§ 5(b): `tsc --noEmit` is unscoped on every stop).
106
+ */
107
+ readonly typecheck_not_run: readonly string[];
92
108
  readonly at: string;
93
109
  }
94
110
 
@@ -112,8 +128,21 @@ interface ToolSpec {
112
128
  * the resolver's by exactly the flag that makes it read-only.
113
129
  */
114
130
  readonly check_form: boolean;
131
+ /**
132
+ * A line the tool prints, exit 0, for an input its own config ignores. Per
133
+ * row because the wording is the tool's (D1); a row without one reads no
134
+ * output as an ignore, which keeps the pre-existing behaviour rather than
135
+ * guessing at a message the tool might print.
136
+ */
137
+ readonly ignored_signal?: RegExp;
115
138
  }
116
139
 
140
+ /**
141
+ * ESLint 9's stylish report for an ignored input: the absolute path on its own
142
+ * line, then this indented warning. Pinned verbatim by the ignored-file fixture.
143
+ */
144
+ const ESLINT_IGNORED = /^\s+\d+:\d+\s+warning\s+File ignored because of a matching ignore pattern\b/;
145
+
117
146
  const JS_EXTENSIONS = ['.js', '.jsx', '.mjs', '.cjs', '.ts', '.tsx', '.mts', '.cts'] as const;
118
147
 
119
148
  /**
@@ -124,7 +153,15 @@ const JS_EXTENSIONS = ['.js', '.jsx', '.mjs', '.cjs', '.ts', '.tsx', '.mts', '.c
124
153
  * and absence is what produces `skipped: unscoped`.
125
154
  */
126
155
  const SCOPED_FORMS: ReadonlyMap<string, ToolSpec> = new Map<string, ToolSpec>([
127
- ['npx eslint .', { argv: ['npx', 'eslint'], extensions: JS_EXTENSIONS, check_form: false }],
156
+ [
157
+ 'npx eslint .',
158
+ {
159
+ argv: ['npx', 'eslint'],
160
+ extensions: JS_EXTENSIONS,
161
+ check_form: false,
162
+ ignored_signal: ESLINT_IGNORED,
163
+ },
164
+ ],
128
165
  [
129
166
  'vendor/bin/phpstan analyse',
130
167
  { argv: ['vendor/bin/phpstan', 'analyse'], extensions: ['.php'], check_form: false },
@@ -153,6 +190,38 @@ const SCOPED_FORMS: ReadonlyMap<string, ToolSpec> = new Map<string, ToolSpec>([
153
190
  */
154
191
  const MUTATING_WITHOUT_CHECK_FORM: ReadonlySet<string> = new Set<string>([]);
155
192
 
193
+ /**
194
+ * Resolver commands with no file-scoped form, unscoped ON PURPOSE (rule 3).
195
+ *
196
+ * Named so the parity test can tell a deliberate absence from `SCOPED_FORMS`
197
+ * apart from a resolver command nobody classified: every command the resolver
198
+ * emits is a scoped key, a mutating key, or on this list — or a test is red.
199
+ */
200
+ export const UNSCOPED_ON_PURPOSE: readonly string[] = [
201
+ 'npx tsc --noEmit',
202
+ 'go vet ./...',
203
+ 'cargo clippy',
204
+ ];
205
+
206
+ /** The keys of `SCOPED_FORMS`, for the parity test. */
207
+ export const SCOPED_FORM_COMMANDS: readonly string[] = [...SCOPED_FORMS.keys()];
208
+
209
+ /** The keys of `MUTATING_WITHOUT_CHECK_FORM`, for the parity test. */
210
+ export const MUTATING_COMMANDS: readonly string[] = [...MUTATING_WITHOUT_CHECK_FORM];
211
+
212
+ /**
213
+ * Resolver commands whose verdict is a type verdict. `go vet` and `cargo clippy`
214
+ * both compile the package, so a type error stops them; ESLint, ruff and pint do
215
+ * not type-check, which is the whole of § 5(b).
216
+ */
217
+ export const TYPE_CHECK_COMMANDS: ReadonlySet<string> = new Set<string>([
218
+ 'npx tsc --noEmit',
219
+ 'vendor/bin/phpstan analyse',
220
+ 'mypy .',
221
+ 'go vet ./...',
222
+ 'cargo clippy',
223
+ ]);
224
+
156
225
  function extensionOf(file: string): string {
157
226
  const base = path.basename(file);
158
227
  const dot = base.lastIndexOf('.');
@@ -253,7 +322,7 @@ function defaultSpawn(
253
322
  export function runTouchedFileQuality(opts: RunOptions): QualityRun[] {
254
323
  const timeout_ms = opts.timeout_ms ?? DEFAULT_TIMEOUT_MS;
255
324
  const spawn = opts.spawn ?? defaultSpawn;
256
- const out: QualityRun[] = [];
325
+ const out: Omit<QualityRun, 'typecheck_not_run'>[] = [];
257
326
  for (const plan of planQualityRuns(opts.commands, opts.files)) {
258
327
  if (plan.argv === null) {
259
328
  out.push({
@@ -263,6 +332,7 @@ export function runTouchedFileQuality(opts: RunOptions): QualityRun[] {
263
332
  output_head: [],
264
333
  skipped: plan.skipped,
265
334
  files: [],
335
+ ignored_files: [],
266
336
  at: now(),
267
337
  });
268
338
  continue;
@@ -282,17 +352,69 @@ export function runTouchedFileQuality(opts: RunOptions): QualityRun[] {
282
352
  // tool is a wrapper script whose own dependency is missing. Same meaning
283
353
  // as ENOENT for this module's purposes, and the same bucket in 2.1.
284
354
  const absent = enoent || status === 127;
355
+ const signal = SCOPED_FORMS.get(plan.source_command)?.ignored_signal;
356
+ const ignored =
357
+ absent || signal === undefined ? [] : ignoredFiles(output, signal, plan.files);
358
+ // Every matched file ignored AND exit 0: the tool looked at nothing, so
359
+ // there is no verdict to record. A non-zero exit over the same set stays,
360
+ // because a red the tool raised (a config crash, say) is real.
361
+ const nothingLooked = ignored.length === plan.files.length && status === 0;
285
362
  out.push({
286
363
  command: renderCommand(plan.argv),
287
364
  source_command: plan.source_command,
288
- exit_code: absent ? null : status,
365
+ exit_code: absent || nothingLooked ? null : status,
289
366
  output_head: absent ? [] : headLines(output, OUTPUT_HEAD_LINES),
290
367
  skipped: absent ? 'absent' : null,
291
368
  files: plan.files,
369
+ ignored_files: ignored,
292
370
  at: now(),
293
371
  });
294
372
  }
295
- return out;
373
+ // `no_files` is excluded: no file the type checker reads was touched, so
374
+ // there was nothing on this turn for it to have caught.
375
+ const typecheck_not_run = out
376
+ .filter(
377
+ (r) =>
378
+ TYPE_CHECK_COMMANDS.has(r.source_command) &&
379
+ r.exit_code === null &&
380
+ r.skipped !== 'no_files' &&
381
+ r.skipped !== null,
382
+ )
383
+ .map((r) => r.source_command);
384
+ return out.map((r) => ({ ...r, typecheck_not_run: [...typecheck_not_run] }));
385
+ }
386
+
387
+ /**
388
+ * The matched files the tool's output reports as ignored.
389
+ *
390
+ * The stylish report names the file on an unindented line and the warning on
391
+ * the indented lines under it, so a signal line is attributed to the last path
392
+ * line above it. A signal that cannot be attributed is attributed to the one
393
+ * matched file only when there is exactly one; otherwise it is dropped, so an
394
+ * unreadable report keeps today's behaviour instead of inventing an ignore.
395
+ */
396
+ export function ignoredFiles(
397
+ output: string,
398
+ signal: RegExp,
399
+ files: readonly string[],
400
+ ): string[] {
401
+ const reported: string[] = [];
402
+ let unattributed = false;
403
+ let current: string | null = null;
404
+ for (const line of output.split(/\r\n|\r|\n/)) {
405
+ if (signal.test(line)) {
406
+ if (current === null) unattributed = true;
407
+ else reported.push(normalizePath(current));
408
+ continue;
409
+ }
410
+ if (line !== '' && !/^\s/.test(line)) current = line.trim();
411
+ }
412
+ const hit = files.filter((f) => {
413
+ const want = normalizePath(f);
414
+ return reported.some((r) => r === want || r.endsWith(`/${want}`));
415
+ });
416
+ if (hit.length === 0 && unattributed && files.length === 1) return [...files];
417
+ return hit;
296
418
  }
297
419
 
298
420
  /**
@@ -306,11 +428,25 @@ export function runTouchedFileQuality(opts: RunOptions): QualityRun[] {
306
428
  export const WARN_LINE_MAX_BYTES = 200;
307
429
 
308
430
  export function advisoryLine(runs: readonly QualityRun[]): string | null {
431
+ const ignored = [...new Set(runs.flatMap((r) => r.ignored_files))];
432
+ const ignoredPart =
433
+ ignored.length === 0
434
+ ? ''
435
+ : `ignored ${ignored[0] ?? ''}${ignored.length > 1 ? ` (+${String(ignored.length - 1)} more)` : ''}`;
309
436
  const failed = runs.find((r) => r.skipped === null && r.exit_code !== null && r.exit_code !== 0);
310
- if (failed === undefined) return null;
437
+ if (failed === undefined) {
438
+ // Nothing failed. Silence is right when every file was looked at; when a
439
+ // file was ignored, silence would read as clean, so say what was not seen.
440
+ if (ignored.length === 0) return null;
441
+ return truncateToBytes(
442
+ `touched-file quality: no verdict, ${ignoredPart}`,
443
+ WARN_LINE_MAX_BYTES,
444
+ );
445
+ }
311
446
  const file = failed.files[0] ?? '(no file)';
312
447
  const more = failed.files.length > 1 ? ` (+${String(failed.files.length - 1)} more)` : '';
313
- const line = `touched-file quality: ${failed.source_command} exited ${String(failed.exit_code)} on ${file}${more}`;
448
+ const tail = ignoredPart === '' ? '' : `; ${ignoredPart}`;
449
+ const line = `touched-file quality: ${failed.source_command} exited ${String(failed.exit_code)} on ${file}${more}${tail}`;
314
450
  return truncateToBytes(line, WARN_LINE_MAX_BYTES);
315
451
  }
316
452
 
@@ -9,7 +9,7 @@
9
9
  * error on the wrong rung, not diligence.
10
10
  *
11
11
  * Composes with — replaces nothing:
12
- * - the N=3 validation-loop budget (`autonomous-execution`),
12
+ * - the `execution.fix_loop_max` validation-loop budget (`autonomous-execution`),
13
13
  * - the ADR-109 / `subagent-response-contract` body + 4-status envelope
14
14
  * (`subagent-steering`): the partial result rides as the body of a
15
15
  * `BLOCKED` envelope with `budget_hit: true` as the escalation flag.
@@ -187,11 +187,26 @@ export function scan(d: string): [Row[], Row[], string[]] {
187
187
  * A scope with no refs renders as `—`: a qualifier on nothing is not a
188
188
  * supersession, and printing the prose alone would read as one.
189
189
  */
190
+ /**
191
+ * Escape a `|` for safety inside a Markdown table cell. The free-text scope
192
+ * fields this feeds (`supersedes_scope` / `superseded_scope`) routinely quote
193
+ * a table row from the record they describe — and a quoted row has its own
194
+ * `|` column separators, verbatim, in the frontmatter prose. Unescaped, that
195
+ * splits the generated row into extra columns rather than rendering the quote
196
+ * (found live in ADR-230's and ADR-279's own rows, both quoting the same
197
+ * table cell from ADR-230 § Decision). `refs` itself is never escaped: it is
198
+ * always an `ADR-NNN` token list this generator produces or validates, never
199
+ * free text.
200
+ */
201
+ function escapeCell(text: string): string {
202
+ return text.replaceAll('|', '\\|');
203
+ }
204
+
190
205
  export function supersessionCell(refs: string | undefined, scope: string | undefined): string {
191
206
  const r = (refs ?? '').trim();
192
207
  if (r === '' || r === '—') return '—';
193
208
  const s = (scope ?? '').trim();
194
- return s === '' || s === '—' ? r : `${r} (${s})`;
209
+ return s === '' || s === '—' ? r : `${r} (${escapeCell(s)})`;
195
210
  }
196
211
 
197
212
  /** Mirror `row(r)`. */
@@ -291,8 +291,8 @@ export interface CostBudgetConfig {
291
291
  readonly max_output_tokens: number;
292
292
  readonly max_calls: number;
293
293
  readonly max_total_usd: number;
294
- /** Rolling 24h cap. 0 disables it — and disabling it also disables the spend
295
- * ledger, since the orchestrator only appends an entry while a cap is live. */
294
+ /** Rolling 24h cap. 0 disables it. The spend ledger is written either way
295
+ * (ADR-279); this value decides only whether the total is compared. */
296
296
  readonly daily_limit_usd: number;
297
297
  }
298
298
 
@@ -1020,7 +1020,7 @@ function _build_debate(d: Dict): DebateConfig {
1020
1020
  if (!_isDict(d)) {
1021
1021
  throw new CouncilConfigError('`debate` must be a mapping.');
1022
1022
  }
1023
- const cap = _pyFloat(_get(d, 'max_cost_usd', 5.0));
1023
+ const cap = _pyFloat(_get(d, 'max_cost_usd', 0.0)); // 0 = no refusal cap (ADR-279)
1024
1024
  if (cap < 0) {
1025
1025
  throw new CouncilConfigError(
1026
1026
  `debate.max_cost_usd must be >= 0 (got ${_pyRepr(_f(cap))}; ` +
@@ -1671,10 +1671,10 @@ function _build_cost_budget(d: Dict): CostBudgetConfig {
1671
1671
  throw new CouncilConfigError('`cost_budget` must be a mapping.');
1672
1672
  }
1673
1673
  const cb: CostBudgetConfig = {
1674
- max_input_tokens: _pyInt(_get(d, 'max_input_tokens', 500_000)),
1675
- max_output_tokens: _pyInt(_get(d, 'max_output_tokens', 200_000)),
1676
- max_calls: _pyInt(_get(d, 'max_calls', 50)),
1677
- max_total_usd: _pyFloat(_get(d, 'max_total_usd', 20.0)),
1674
+ max_input_tokens: _pyInt(_get(d, 'max_input_tokens', 0)), // 0 = unbounded (ADR-279)
1675
+ max_output_tokens: _pyInt(_get(d, 'max_output_tokens', 0)), // 0 = unbounded (ADR-279)
1676
+ max_calls: _pyInt(_get(d, 'max_calls', 50)), // fan-out, not money — kept
1677
+ max_total_usd: _pyFloat(_get(d, 'max_total_usd', 0.0)), // 0 = unbounded (ADR-279)
1678
1678
  daily_limit_usd: _pyFloat(_get(d, 'daily_limit_usd', 0.0)),
1679
1679
  };
1680
1680
  const fields: Array<[keyof CostBudgetConfig, boolean]> = [