@event4u/agent-config 16.2.0 → 16.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (651) hide show
  1. package/.augment-plugin/marketplace.json +3 -3
  2. package/.augment-plugin/plugin.json +1 -1
  3. package/.claude-plugin/marketplace.json +1 -1
  4. package/CHANGELOG.md +337 -234
  5. package/README.md +15 -13
  6. package/agents/templates/.ai-council.yml.example +26 -8
  7. package/dist/agent-src/commands/analyze/inbox.md +11 -8
  8. package/dist/agent-src/commands/analyze/roadmap-repos.md +1 -1
  9. package/dist/agent-src/commands/bug/fix.md +17 -2
  10. package/dist/agent-src/commands/bug/investigate.md +1 -1
  11. package/dist/agent-src/commands/commit/in-chunks.md +40 -31
  12. package/dist/agent-src/commands/commit.md +72 -33
  13. package/dist/agent-src/commands/condense.md +2 -8
  14. package/dist/agent-src/commands/council/debate.md +11 -7
  15. package/dist/agent-src/commands/council/default.md +10 -9
  16. package/dist/agent-src/commands/council.md +1 -1
  17. package/dist/agent-src/commands/estimate-ticket.md +1 -1
  18. package/dist/agent-src/commands/feature/explore.md +3 -3
  19. package/dist/agent-src/commands/feature/plan.md +2 -2
  20. package/dist/agent-src/commands/feature/roadmap.md +1 -1
  21. package/dist/agent-src/commands/fix/ci.md +18 -4
  22. package/dist/agent-src/commands/fix/commit-messages.md +48 -23
  23. package/dist/agent-src/commands/fix/pr-comments.md +3 -6
  24. package/dist/agent-src/commands/implement-ticket.md +4 -4
  25. package/dist/agent-src/commands/jira-ticket.md +1 -1
  26. package/dist/agent-src/commands/memory/add.md +4 -16
  27. package/dist/agent-src/commands/memory/load.md +5 -6
  28. package/dist/agent-src/commands/memory/promote.md +3 -16
  29. package/dist/agent-src/commands/mission/upgrade.md +3 -2
  30. package/dist/agent-src/commands/optimize/agents-dir.md +2 -2
  31. package/dist/agent-src/commands/optimize/deep.md +4 -2
  32. package/dist/agent-src/commands/optimize/rtk.md +4 -26
  33. package/dist/agent-src/commands/pr/create/description-only.md +18 -15
  34. package/dist/agent-src/commands/pr/create.md +42 -34
  35. package/dist/agent-src/commands/pr/merge.md +136 -9
  36. package/dist/agent-src/commands/prepare-for-review.md +13 -11
  37. package/dist/agent-src/commands/project/analyze.md +7 -35
  38. package/dist/agent-src/commands/refine-ticket.md +1 -1
  39. package/dist/agent-src/commands/review/changes.md +14 -19
  40. package/dist/agent-src/commands/roadmap/create.md +1 -1
  41. package/dist/agent-src/commands/roadmap/materialize.md +1 -1
  42. package/dist/agent-src/commands/roadmap/next.md +10 -1
  43. package/dist/agent-src/commands/roadmap/process-full.md +56 -42
  44. package/dist/agent-src/commands/roadmap/resolve-blockers.md +411 -0
  45. package/dist/agent-src/commands/roadmap/triage-parked.md +325 -0
  46. package/dist/agent-src/commands/roadmap.md +18 -4
  47. package/dist/agent-src/commands/tests/create.md +17 -3
  48. package/dist/agent-src/commands/tests/execute.md +22 -5
  49. package/dist/agent-src/commands/worktree/create.md +7 -3
  50. package/dist/agent-src/commands/worktree/verify.md +2 -1
  51. package/dist/agent-src/contexts/authority/decision-revisit-gate-enforcement.md +43 -0
  52. package/dist/agent-src/contexts/communication/rules-auto/design-fidelity-enforcement.md +24 -0
  53. package/dist/agent-src/contexts/communication/rules-auto/think-before-action-mechanics.md +5 -3
  54. package/dist/agent-src/contexts/communication/rules-auto/token-efficiency-mechanics.md +7 -9
  55. package/dist/agent-src/contexts/contracts/command-suggestion-flow.md +8 -6
  56. package/dist/agent-src/contexts/contracts/frugality-charter.md +8 -5
  57. package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +7 -7
  58. package/dist/agent-src/contexts/execution/auto-orchestration-activation.md +0 -1
  59. package/dist/agent-src/contexts/execution/evidence-discipline.md +2 -2
  60. package/dist/agent-src/contexts/execution/non-interactive-contract.md +5 -8
  61. package/dist/agent-src/contexts/execution/rdp-gate.md +4 -4
  62. package/dist/agent-src/contexts/execution/roadmap-execution-contract.md +9 -8
  63. package/dist/agent-src/contexts/execution/roadmap-process-loop.md +99 -54
  64. package/dist/agent-src/contexts/execution/session-canary-enforcement-history.md +67 -0
  65. package/dist/agent-src/contexts/execution/subagent-routing.md +8 -8
  66. package/dist/agent-src/contexts/execution/subagent-steering.md +6 -4
  67. package/dist/agent-src/contexts/execution/terminal-states.md +2 -2
  68. package/dist/agent-src/contexts/execution/toolchain-resolver.md +95 -7
  69. package/dist/agent-src/contexts/subagent-configuration.md +1 -1
  70. package/dist/agent-src/guidelines/agent-infra/active-remediation-mechanics.md +39 -0
  71. package/dist/agent-src/guidelines/agent-infra/context-hygiene-mechanics.md +1 -1
  72. package/dist/agent-src/guidelines/agent-infra/cross-source-consistency-mechanics.md +8 -10
  73. package/dist/agent-src/guidelines/agent-infra/frontier-reasoning-operating-profile.md +3 -2
  74. package/dist/agent-src/guidelines/agent-infra/layered-settings.md +13 -1
  75. package/dist/agent-src/guidelines/agent-infra/roadmap-progress-mechanics.md +1 -1
  76. package/dist/agent-src/guidelines/agent-infra/self-improvement-pipeline.md +10 -3
  77. package/dist/agent-src/guidelines/agent-infra/size-and-scope.md +36 -0
  78. package/dist/agent-src/guidelines/php/git.md +15 -2
  79. package/dist/agent-src/rules/active-remediation.md +1 -2
  80. package/dist/agent-src/rules/analysis-skill-routing.md +0 -1
  81. package/dist/agent-src/rules/architecture.md +0 -1
  82. package/dist/agent-src/rules/artifact-drafting-protocol.md +0 -1
  83. package/dist/agent-src/rules/artifact-engagement-recording.md +0 -1
  84. package/dist/agent-src/rules/augment-edit-discipline.md +0 -1
  85. package/dist/agent-src/rules/autonomous-execution.md +1 -1
  86. package/dist/agent-src/rules/brand-consistency.md +0 -1
  87. package/dist/agent-src/rules/brand-source-of-truth.md +0 -1
  88. package/dist/agent-src/rules/broken-access-control.md +1 -1
  89. package/dist/agent-src/rules/cli-output-handling.md +0 -1
  90. package/dist/agent-src/rules/code-comment-discipline.md +0 -1
  91. package/dist/agent-src/rules/code-provenance.md +0 -1
  92. package/dist/agent-src/rules/command-suggestion-policy.md +1 -1
  93. package/dist/agent-src/rules/commit-conventions.md +1 -2
  94. package/dist/agent-src/rules/communication-through-line.md +1 -2
  95. package/dist/agent-src/rules/content-quoting-floor.md +1 -2
  96. package/dist/agent-src/rules/context-hygiene.md +6 -6
  97. package/dist/agent-src/rules/copilot-routing.md +1 -2
  98. package/dist/agent-src/rules/council-availability.md +4 -4
  99. package/dist/agent-src/rules/cross-source-consistency.md +4 -6
  100. package/dist/agent-src/rules/decision-revisit-gate.md +17 -35
  101. package/dist/agent-src/rules/delegation-policy.md +2 -3
  102. package/dist/agent-src/rules/design-fidelity.md +12 -16
  103. package/dist/agent-src/rules/design-review-after-ui-write.md +3 -3
  104. package/dist/agent-src/rules/devcontainer-routing.md +1 -2
  105. package/dist/agent-src/rules/doc-screenshot-hygiene.md +1 -1
  106. package/dist/agent-src/rules/docker-commands.md +0 -1
  107. package/dist/agent-src/rules/domain-adoption-policy.md +0 -1
  108. package/dist/agent-src/rules/domain-safety-disclaimer.md +1 -1
  109. package/dist/agent-src/rules/domain-safety-pii.md +1 -1
  110. package/dist/agent-src/rules/domain-safety-retention.md +1 -1
  111. package/dist/agent-src/rules/downstream-changes.md +0 -1
  112. package/dist/agent-src/rules/engineering-safety-floor.md +1 -1
  113. package/dist/agent-src/rules/evaluator-independence.md +3 -2
  114. package/dist/agent-src/rules/external-code-graph-interop.md +0 -1
  115. package/dist/agent-src/rules/external-reference-deep-dive.md +0 -1
  116. package/dist/agent-src/rules/fast-path-marker-visibility.md +2 -2
  117. package/dist/agent-src/rules/finance-safety-floor.md +1 -1
  118. package/dist/agent-src/rules/fix-what-you-see.md +6 -32
  119. package/dist/agent-src/rules/framework-neutrality-in-generic-skills.md +0 -1
  120. package/dist/agent-src/rules/git-history-discipline.md +2 -2
  121. package/dist/agent-src/rules/guidelines.md +0 -1
  122. package/dist/agent-src/rules/history-discipline.md +0 -1
  123. package/dist/agent-src/rules/icon-consistency.md +0 -1
  124. package/dist/agent-src/rules/image-likeness-and-rights.md +1 -1
  125. package/dist/agent-src/rules/improve-before-implement.md +0 -1
  126. package/dist/agent-src/rules/invite-challenge.md +0 -1
  127. package/dist/agent-src/rules/laravel-routing.md +1 -2
  128. package/dist/agent-src/rules/laravel-translations.md +0 -1
  129. package/dist/agent-src/rules/legal-safety-floor.md +3 -3
  130. package/dist/agent-src/rules/lethal-trifecta-guard.md +1 -1
  131. package/dist/agent-src/rules/linked-projects-onboarding-gate.md +0 -1
  132. package/dist/agent-src/rules/low-impact-corpus-privacy-floor.md +1 -1
  133. package/dist/agent-src/rules/markdown-safe-codeblocks.md +0 -1
  134. package/dist/agent-src/rules/media-governance-routing.md +13 -17
  135. package/dist/agent-src/rules/media-sync-ground-truth.md +0 -1
  136. package/dist/agent-src/rules/minimal-safe-diff.md +0 -1
  137. package/dist/agent-src/rules/missing-skill-recovery.md +0 -1
  138. package/dist/agent-src/rules/missing-tool-handling.md +0 -1
  139. package/dist/agent-src/rules/model-recommendation.md +0 -1
  140. package/dist/agent-src/rules/neighbour-precedence.md +64 -0
  141. package/dist/agent-src/rules/no-attribution-footers.md +0 -1
  142. package/dist/agent-src/rules/no-decorative-emojis-in-git-surfaces.md +0 -1
  143. package/dist/agent-src/rules/no-pr-progress-comments.md +0 -1
  144. package/dist/agent-src/rules/no-roadmap-references.md +0 -1
  145. package/dist/agent-src/rules/notes-first-reasoning.md +0 -1
  146. package/dist/agent-src/rules/onboarding-gate.md +0 -1
  147. package/dist/agent-src/rules/output-discipline.md +0 -1
  148. package/dist/agent-src/rules/package-ci-checks.md +0 -1
  149. package/dist/agent-src/rules/persona-governance.md +4 -5
  150. package/dist/agent-src/rules/php-coding.md +0 -1
  151. package/dist/agent-src/rules/prefer-enums-over-literals.md +0 -1
  152. package/dist/agent-src/rules/preservation-guard.md +0 -1
  153. package/dist/agent-src/rules/provider-lifecycle-discipline.md +3 -4
  154. package/dist/agent-src/rules/question-not-instruction.md +1 -1
  155. package/dist/agent-src/rules/reviewer-awareness.md +0 -1
  156. package/dist/agent-src/rules/roadmap-ci-steps-policy.md +0 -1
  157. package/dist/agent-src/rules/roadmap-progress-sync.md +4 -7
  158. package/dist/agent-src/rules/role-mode-adherence.md +0 -1
  159. package/dist/agent-src/rules/rule-type-governance.md +0 -1
  160. package/dist/agent-src/rules/runtime-safety.md +1 -1
  161. package/dist/agent-src/rules/scale-discipline.md +0 -1
  162. package/dist/agent-src/rules/secret-vcs-guard.md +1 -1
  163. package/dist/agent-src/rules/security-sensitive-stop.md +3 -3
  164. package/dist/agent-src/rules/self-repair-loop.md +0 -1
  165. package/dist/agent-src/rules/senior-engineering-discipline.md +0 -1
  166. package/dist/agent-src/rules/session-canary.md +7 -62
  167. package/dist/agent-src/rules/settings-ask-protocol.md +6 -6
  168. package/dist/agent-src/rules/size-enforcement.md +0 -1
  169. package/dist/agent-src/rules/skill-improvement-trigger.md +2 -3
  170. package/dist/agent-src/rules/skill-quality.md +0 -1
  171. package/dist/agent-src/rules/slash-command-routing-policy.md +0 -1
  172. package/dist/agent-src/rules/source-confidentiality.md +1 -1
  173. package/dist/agent-src/rules/source-discovery-gate.md +0 -1
  174. package/dist/agent-src/rules/source-of-truth.md +0 -1
  175. package/dist/agent-src/rules/spreadsheet-source-quality.md +1 -2
  176. package/dist/agent-src/rules/strategy-safety-floor.md +1 -1
  177. package/dist/agent-src/rules/symfony-routing.md +1 -2
  178. package/dist/agent-src/rules/think-before-action.md +0 -1
  179. package/dist/agent-src/rules/token-budget-discipline.md +12 -46
  180. package/dist/agent-src/rules/token-efficiency.md +0 -1
  181. package/dist/agent-src/rules/token-optimizer-maintenance.md +0 -1
  182. package/dist/agent-src/rules/tool-safety.md +1 -1
  183. package/dist/agent-src/rules/ui-audit-gate.md +1 -2
  184. package/dist/agent-src/rules/untrusted-input-defense.md +1 -1
  185. package/dist/agent-src/rules/upstream-proposal.md +0 -1
  186. package/dist/agent-src/rules/user-interaction.md +0 -1
  187. package/dist/agent-src/rules/user-interrupt-priority.md +1 -1
  188. package/dist/agent-src/scripts/archive_completed_roadmaps.ts +115 -20
  189. package/dist/agent-src/scripts/deferral_carry.ts +339 -0
  190. package/dist/agent-src/scripts/gate_budget.ts +47 -23
  191. package/dist/agent-src/scripts/gate_execute.ts +12 -4
  192. package/dist/agent-src/scripts/update_roadmap_progress.ts +4 -1
  193. package/dist/agent-src/skills/ai-council/SKILL.md +7 -4
  194. package/dist/agent-src/skills/ai-council/references/cost-and-redaction.md +21 -11
  195. package/dist/agent-src/skills/ai-council/references/procedure.md +12 -6
  196. package/dist/agent-src/skills/analysis-autonomous-mode/SKILL.md +1 -1
  197. package/dist/agent-src/skills/api-design/data/manifest.json +2 -2
  198. package/dist/agent-src/skills/api-testing/SKILL.md +17 -0
  199. package/dist/agent-src/skills/bug-analyzer/SKILL.md +1 -1
  200. package/dist/agent-src/skills/code-intelligence/SKILL.md +14 -2
  201. package/dist/agent-src/skills/command-routing/SKILL.md +3 -4
  202. package/dist/agent-src/skills/conventional-commits-writing/SKILL.md +127 -139
  203. package/dist/agent-src/skills/corpus-grounding/ATTRIBUTION.md +39 -0
  204. package/dist/agent-src/skills/corpus-grounding/SKILL.md +8 -2
  205. package/dist/agent-src/skills/database/data/manifest.json +2 -2
  206. package/dist/agent-src/skills/database/data/query-tuning.csv +13 -13
  207. package/dist/agent-src/skills/design-system-capture/SKILL.md +0 -3
  208. package/dist/agent-src/skills/design-system-capture/references/import-procedure.md +1 -1
  209. package/dist/agent-src/skills/estimate-ticket/SKILL.md +1 -1
  210. package/dist/agent-src/skills/existing-ui-audit/SKILL.md +2 -2
  211. package/dist/agent-src/skills/fe-design/SKILL.md +1 -1
  212. package/dist/agent-src/skills/feature-planning/SKILL.md +1 -1
  213. package/dist/agent-src/skills/git-workflow/SKILL.md +44 -44
  214. package/dist/agent-src/skills/git-workflow/references/branch-update.md +312 -0
  215. package/dist/agent-src/skills/git-workflow/references/commit-subject.md +205 -0
  216. package/dist/agent-src/skills/iconography/SKILL.md +1 -1
  217. package/dist/agent-src/skills/jira-integration/SKILL.md +3 -3
  218. package/dist/agent-src/skills/js-library-packaging/SKILL.md +2 -2
  219. package/dist/agent-src/skills/merge-conflicts/SKILL.md +10 -4
  220. package/dist/agent-src/skills/monorepo-workspace/SKILL.md +1 -1
  221. package/dist/agent-src/skills/po-discovery/SKILL.md +1 -1
  222. package/dist/agent-src/skills/quality-tools/SKILL.md +11 -1
  223. package/dist/agent-src/skills/quality-tools/references/go-tools.md +76 -0
  224. package/dist/agent-src/skills/quality-tools/references/python-tools.md +104 -0
  225. package/dist/agent-src/skills/refine-ticket/SKILL.md +4 -4
  226. package/dist/agent-src/skills/review-routing/SKILL.md +2 -2
  227. package/dist/agent-src/skills/roadmap-writing/SKILL.md +2 -2
  228. package/dist/agent-src/skills/skill-improvement-pipeline/SKILL.md +5 -3
  229. package/dist/agent-src/skills/source-discovery/SKILL.md +1 -1
  230. package/dist/agent-src/skills/storybook-workshop/SKILL.md +3 -3
  231. package/dist/agent-src/skills/tailwind-engineer/SKILL.md +4 -2
  232. package/dist/agent-src/skills/test-case-discovery/SKILL.md +7 -0
  233. package/dist/agent-src/skills/test-driven-development/SKILL.md +17 -0
  234. package/dist/agent-src/skills/test-performance/SKILL.md +19 -1
  235. package/dist/agent-src/skills/testing-anti-patterns/SKILL.md +1 -1
  236. package/dist/agent-src/skills/ui-component-architect/SKILL.md +2 -2
  237. package/dist/agent-src/skills/using-git-worktrees/SKILL.md +1 -1
  238. package/dist/agent-src/skills/verify-repair-loop/SKILL.md +2 -2
  239. package/dist/agent-src/templates/AGENTS.md +1 -1
  240. package/dist/agent-src/templates/agent-settings.md +46 -129
  241. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +3 -3
  242. package/dist/agent-src/templates/command.md +2 -2
  243. package/dist/agent-src/templates/roadmaps.md +6 -1
  244. package/dist/agent-src/templates/scripts/work_engine/_lib/agent_settings.ts +0 -6
  245. package/dist/agent-src/templates/scripts/work_engine/directives/backend/_self_fix.ts +11 -7
  246. package/dist/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +48 -6
  247. package/dist/agent-src/templates/scripts/work_engine/hooks/builtin/decision_trace.ts +3 -2
  248. package/dist/agent-src/templates/scripts/work_engine/hooks/builtin/memory_visibility.ts +2 -1
  249. package/dist/agent-src/templates/scripts/work_engine/hooks/settings.ts +0 -6
  250. package/dist/agent-src/templates/scripts/work_engine/scoring/decision_engine.ts +9 -12
  251. package/dist/agent-src/templates/scripts/work_engine/scoring/memory_visibility.ts +2 -1
  252. package/dist/agent-src/templates/scripts/work_engine/stack/runner.ts +774 -109
  253. package/dist/agent-src/templates/skill.md +1 -1
  254. package/dist/cli/registry.js +2 -1
  255. package/dist/cli-delegate/archive_completed_roadmaps.js +92 -12
  256. package/dist/cli-delegate/check_update_banner.js +207 -120
  257. package/dist/cli-delegate/chunk-523HCFYO.js +90 -0
  258. package/dist/cli-delegate/{chunk-FP36SWJD.js → chunk-5GPULQBE.js} +2797 -338
  259. package/dist/cli-delegate/{chunk-IGD6ERX6.js → chunk-6SRJTYJS.js} +42 -176
  260. package/dist/cli-delegate/chunk-6V5FMA3P.js +186 -0
  261. package/dist/cli-delegate/{chunk-M2DPGFZ4.js → chunk-6V6TA25H.js} +22 -152
  262. package/dist/cli-delegate/chunk-6YQC2HLF.js +415 -0
  263. package/dist/cli-delegate/{chunk-E4XIZDIB.js → chunk-7HKRE54K.js} +1 -64
  264. package/dist/cli-delegate/chunk-7IQE3D5S.js +191 -0
  265. package/dist/cli-delegate/{chunk-YJ72UIAK.js → chunk-AED2VQGM.js} +1245 -249
  266. package/dist/cli-delegate/{chunk-7HQ52DHU.js → chunk-AL3RZ22D.js} +1 -1
  267. package/dist/cli-delegate/chunk-DEIV7XP7.js +108 -0
  268. package/dist/cli-delegate/{chunk-DBH4AHDK.js → chunk-ED7KCMLB.js} +9 -11
  269. package/dist/cli-delegate/chunk-F3QDG2GT.js +2569 -0
  270. package/dist/cli-delegate/{chunk-6KFEC3G7.js → chunk-G5VVIZRC.js} +3 -3
  271. package/dist/cli-delegate/{chunk-FC75PGJE.js → chunk-H76PHZBI.js} +149 -61
  272. package/dist/cli-delegate/chunk-IAYTIIQW.js +67 -0
  273. package/dist/cli-delegate/chunk-JQOM7TTM.js +1201 -0
  274. package/dist/cli-delegate/chunk-KB5FZ655.js +208 -0
  275. package/dist/cli-delegate/{chunk-7RQP4UDH.js → chunk-KR6EM23A.js} +235 -1455
  276. package/dist/cli-delegate/{chunk-LTYVIY76.js → chunk-KXXWJTDO.js} +6 -11
  277. package/dist/cli-delegate/{chunk-T7L2QK3K.js → chunk-LQOCRFWT.js} +1 -1
  278. package/dist/cli-delegate/{chunk-6KM6ORRY.js → chunk-MDPPKQCQ.js} +58 -9
  279. package/dist/cli-delegate/{chunk-4XFP2Y3E.js → chunk-MSUL5NYP.js} +5 -5
  280. package/dist/cli-delegate/chunk-OAFSJBHH.js +272 -0
  281. package/dist/cli-delegate/{chunk-4E2W63DA.js → chunk-OKJUIAPS.js} +62 -1
  282. package/dist/cli-delegate/{chunk-QAJS5YWY.js → chunk-PHD7OOLE.js} +2 -1
  283. package/dist/cli-delegate/{chunk-P6ZHP5W2.js → chunk-PWX7CKMD.js} +4 -4
  284. package/dist/cli-delegate/{chunk-NDJLNC6Q.js → chunk-T6BP34WI.js} +1 -0
  285. package/dist/cli-delegate/{chunk-7XGBX6ZH.js → chunk-T7XSJSUQ.js} +1144 -589
  286. package/dist/cli-delegate/chunk-ULQRUR23.js +208 -0
  287. package/dist/cli-delegate/chunk-WQWXGIWB.js +1779 -0
  288. package/dist/cli-delegate/{chunk-RGNIWTEA.js → chunk-XQTPXKFA.js} +1 -1
  289. package/dist/cli-delegate/{chunk-NUHLI2RX.js → chunk-YCU3TIXH.js} +2 -0
  290. package/dist/cli-delegate/chunk-ZBZV2G5R.js +210 -0
  291. package/dist/cli-delegate/{chunk-WGXTVKCQ.js → chunk-ZUZKZYCN.js} +5 -3
  292. package/dist/cli-delegate/cmd_analyze_session.js +223 -43
  293. package/dist/cli-delegate/cmd_brand_status.js +3 -2
  294. package/dist/cli-delegate/cmd_conformance.js +1252 -249
  295. package/dist/cli-delegate/cmd_converge.js +3 -3
  296. package/dist/cli-delegate/cmd_doctor.js +19 -9
  297. package/dist/cli-delegate/cmd_doctor_neighbours.js +30 -0
  298. package/dist/cli-delegate/cmd_explain.js +45 -21
  299. package/dist/cli-delegate/cmd_export.js +13 -10
  300. package/dist/cli-delegate/cmd_fleet.js +3 -3
  301. package/dist/cli-delegate/cmd_git_convention.js +1851 -0
  302. package/dist/cli-delegate/cmd_handoff.js +44 -22
  303. package/dist/cli-delegate/cmd_mcp_available.js +3 -2
  304. package/dist/cli-delegate/cmd_memory_get.js +3 -1
  305. package/dist/cli-delegate/cmd_migrate.js +3 -3
  306. package/dist/cli-delegate/cmd_packs_active.js +5 -4
  307. package/dist/cli-delegate/cmd_preflight.js +6 -6
  308. package/dist/cli-delegate/cmd_prune.js +14 -11
  309. package/dist/cli-delegate/cmd_refresh.js +2 -1
  310. package/dist/cli-delegate/cmd_route_audit.js +10 -8
  311. package/dist/cli-delegate/cmd_route_explain.js +4 -4
  312. package/dist/cli-delegate/cmd_session_recycle.js +10 -7
  313. package/dist/cli-delegate/cmd_settings_check.js +54 -7
  314. package/dist/cli-delegate/cmd_settings_get.js +18 -8
  315. package/dist/cli-delegate/cmd_settings_migrate.js +13 -10
  316. package/dist/cli-delegate/cmd_settings_set.js +4 -4
  317. package/dist/cli-delegate/cmd_sync.js +14 -11
  318. package/dist/cli-delegate/cmd_uninstall.js +15 -12
  319. package/dist/cli-delegate/cmd_update.js +7 -7
  320. package/dist/cli-delegate/cmd_upgrade.js +9 -8
  321. package/dist/cli-delegate/cmd_validate.js +15 -12
  322. package/dist/cli-delegate/cmd_versions.js +5 -5
  323. package/dist/cli-delegate/deferral_carry.js +16 -0
  324. package/dist/cli-delegate/gate_budget.js +1 -1
  325. package/dist/cli-delegate/gate_execute.js +3 -3
  326. package/dist/cli-delegate/roadmap_gates.js +6 -6
  327. package/dist/cli-delegate/update_roadmap_progress.js +1 -1
  328. package/dist/discovery/deprecation-report.md +1 -1
  329. package/dist/discovery/discovery-manifest.json +232 -141
  330. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  331. package/dist/discovery/discovery-manifest.summary.md +3 -3
  332. package/dist/discovery/dormancy-report.md +1 -1
  333. package/dist/discovery/orphan-report.md +1 -1
  334. package/dist/discovery/packs.json +26 -9
  335. package/dist/discovery/trust-report.md +3 -3
  336. package/dist/discovery/workspaces.json +7 -4
  337. package/dist/hooks/dispatch.js +5655 -6623
  338. package/dist/hooks/dispatch.sha256 +1 -1
  339. package/dist/install/claudePathsPlan.js +47 -6
  340. package/dist/install/claudeRuleRewrite.js +7 -0
  341. package/dist/install/emit_host_rules_cli.js +39 -36
  342. package/dist/install/globalRuleScope.js +87 -0
  343. package/dist/install/host_rule_ownership.js +160 -0
  344. package/dist/install/install.mjs +2336 -1249
  345. package/dist/install/installThinLayer.js +289 -0
  346. package/dist/install/installedRuleLinks.js +262 -0
  347. package/dist/install/wizard-plan.js +24 -0
  348. package/dist/mcp/awesome-mcp-servers.row.md +1 -1
  349. package/dist/mcp/mcp-cloudflare-catalogue.json +2 -2
  350. package/dist/mcp/registry-manifest.json +5 -5
  351. package/dist/mcp/server.json +2 -2
  352. package/dist/mcp/server.mjs +36504 -30986
  353. package/dist/router.json +1 -1
  354. package/dist/scripts/_lib/agent_settings.js +26 -120
  355. package/dist/scripts/_lib/claude_settings_hooks.js +10 -8
  356. package/dist/scripts/_lib/compile_time_toggles.js +12 -21
  357. package/dist/scripts/_lib/git_convention.js +232 -0
  358. package/dist/scripts/_lib/global_deploy_inventory.js +730 -0
  359. package/dist/scripts/_lib/installed_layer.js +704 -0
  360. package/dist/scripts/_lib/lean_projection_mode.js +218 -15
  361. package/dist/scripts/_lib/package_root.js +68 -0
  362. package/dist/scripts/_lib/rule_consequence_class.js +45 -0
  363. package/dist/scripts/_lib/rule_injection.js +67 -10
  364. package/dist/scripts/_lib/rule_law_section.js +122 -0
  365. package/dist/scripts/_lib/settings_removed_keys.js +168 -0
  366. package/dist/scripts/_lib/thin_rules.js +535 -0
  367. package/dist/scripts/_lib/windsurf_render.js +60 -0
  368. package/dist/scripts/condense.js +14 -26
  369. package/dist/scripts/project_thin_rules.js +14 -294
  370. package/dist/server/app.js +2 -1
  371. package/dist/server/gitKeysGate.js +105 -0
  372. package/dist/server/routes/settings.js +67 -8
  373. package/dist/server/routes/wizard.js +4 -0
  374. package/dist/server/schemas/settings.js +29 -81
  375. package/dist/shared/skillRanking.js +103 -16
  376. package/dist/ui/assets/{index-Cwq4d0hX.js → index-C3djEJah.js} +2 -2
  377. package/dist/ui/index.html +1 -1
  378. package/docs/MIGRATION.md +72 -1
  379. package/docs/contracts/settings-classes.md +39 -67
  380. package/docs/guidelines/agent-infra/active-remediation-mechanics.md +39 -0
  381. package/docs/guidelines/agent-infra/context-hygiene-mechanics.md +1 -1
  382. package/docs/guidelines/agent-infra/cross-source-consistency-mechanics.md +8 -10
  383. package/docs/guidelines/agent-infra/frontier-reasoning-operating-profile.md +3 -2
  384. package/docs/guidelines/agent-infra/layered-settings.md +13 -1
  385. package/docs/guidelines/agent-infra/roadmap-progress-mechanics.md +1 -1
  386. package/docs/guidelines/agent-infra/self-improvement-pipeline.md +10 -3
  387. package/docs/guidelines/agent-infra/size-and-scope.md +36 -0
  388. package/docs/guidelines/php/git.md +15 -2
  389. package/package.json +1 -1
  390. package/src/agent-src/scripts/archive_completed_roadmaps.ts +115 -20
  391. package/src/agent-src/scripts/deferral_carry.ts +339 -0
  392. package/src/agent-src/scripts/gate_budget.ts +47 -23
  393. package/src/agent-src/scripts/gate_execute.ts +12 -4
  394. package/src/agent-src/scripts/update_roadmap_progress.ts +4 -1
  395. package/src/agent-src/templates/AGENTS.md +1 -1
  396. package/src/agent-src/templates/scripts/work_engine/_lib/agent_settings.ts +0 -6
  397. package/src/agent-src/templates/scripts/work_engine/directives/backend/_self_fix.ts +11 -7
  398. package/src/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +48 -6
  399. package/src/agent-src/templates/scripts/work_engine/hooks/builtin/decision_trace.ts +3 -2
  400. package/src/agent-src/templates/scripts/work_engine/hooks/builtin/memory_visibility.ts +2 -1
  401. package/src/agent-src/templates/scripts/work_engine/hooks/settings.ts +0 -6
  402. package/src/agent-src/templates/scripts/work_engine/scoring/decision_engine.ts +9 -12
  403. package/src/agent-src/templates/scripts/work_engine/scoring/memory_visibility.ts +2 -1
  404. package/src/agent-src/templates/scripts/work_engine/stack/runner.ts +774 -109
  405. package/src/config/agent-settings.template.yml +141 -334
  406. package/src/config/agents-paths.yml +16 -0
  407. package/src/config/assurance-capability-registry.json +7 -3
  408. package/src/config/ci-local-parity.yml +3 -0
  409. package/src/config/continuity-surface.json +10 -3
  410. package/src/config/discovery/packs.yml +17 -1
  411. package/src/config/evaluator-budgets.json +23 -10
  412. package/src/config/gate-coverage.yml +138 -3
  413. package/src/config/gate-violation-baselines.json +64 -16
  414. package/src/config/gitignore-block.txt +19 -0
  415. package/src/config/hook-bundle-budget.json +25 -0
  416. package/src/config/hook-token-budget.json +6 -1
  417. package/src/config/host-instruction-limits.json +33 -0
  418. package/src/config/release-gate-locality.yml +2 -1
  419. package/src/config/routing-coverage-seed.json +67 -4
  420. package/src/config/rule-activation-census.json +7 -3
  421. package/src/config/rule-consequence-class.json +161 -0
  422. package/src/config/rule-law-ceilings.json +105 -0
  423. package/src/config/rule-obligations.json +833 -0
  424. package/src/install/claudePathsPlan.ts +46 -4
  425. package/src/install/claudeRuleRewrite.ts +10 -1
  426. package/src/install/emit_host_rules_cli.ts +43 -34
  427. package/src/install/globalRuleScope.ts +109 -0
  428. package/src/install/host_rule_ownership.ts +170 -0
  429. package/src/install/installThinLayer.ts +378 -0
  430. package/src/install/installedRuleLinks.ts +308 -0
  431. package/src/install/wizard-plan.ts +24 -0
  432. package/src/scripts/_cli/cmd_analyze_session.ts +9 -15
  433. package/src/scripts/_cli/cmd_conformance.ts +13 -2
  434. package/src/scripts/_cli/cmd_doctor.ts +33 -81
  435. package/src/scripts/_cli/cmd_doctor_neighbours.ts +426 -0
  436. package/src/scripts/_cli/cmd_explain.ts +72 -14
  437. package/src/scripts/_cli/cmd_git_convention.ts +637 -0
  438. package/src/scripts/_cli/cmd_settings_check.ts +66 -8
  439. package/src/scripts/_cli/cmd_settings_get.ts +18 -3
  440. package/src/scripts/_cli/doctor_execution.ts +72 -1
  441. package/src/scripts/_dispatch.bash +53 -4
  442. package/src/scripts/_lib/agent_settings.ts +26 -124
  443. package/src/scripts/_lib/blocked_by_marker.ts +1 -1
  444. package/src/scripts/_lib/claude_settings_hooks.ts +10 -8
  445. package/src/scripts/_lib/compile_time_toggles.ts +12 -21
  446. package/src/scripts/_lib/dispatch_import_closure.ts +163 -0
  447. package/src/scripts/_lib/estate_offsets.ts +241 -0
  448. package/src/scripts/_lib/exemption_shape.ts +143 -0
  449. package/src/scripts/_lib/fnv.ts +23 -0
  450. package/src/scripts/_lib/foreign_scan.ts +106 -0
  451. package/src/scripts/_lib/git_base_ref.ts +92 -0
  452. package/src/scripts/_lib/git_convention.ts +291 -0
  453. package/src/scripts/_lib/git_convention_carrier.ts +389 -0
  454. package/src/scripts/_lib/git_convention_grammar.ts +246 -0
  455. package/src/scripts/_lib/git_convention_measure.ts +344 -0
  456. package/src/scripts/_lib/gitignore_block.ts +314 -0
  457. package/src/scripts/_lib/global_deploy_inventory.ts +106 -0
  458. package/src/scripts/_lib/graph_feeder_record.ts +437 -0
  459. package/src/scripts/_lib/hook_settings.ts +73 -0
  460. package/src/scripts/_lib/host_capability.ts +40 -19
  461. package/src/scripts/_lib/host_hook_merge.ts +165 -0
  462. package/src/scripts/_lib/installed_layer.ts +963 -0
  463. package/src/scripts/_lib/json_merge.ts +82 -0
  464. package/src/scripts/_lib/json_pointers.ts +93 -11
  465. package/src/scripts/_lib/knowledge_global.ts +14 -1
  466. package/src/scripts/_lib/lean_projection_mode.ts +275 -15
  467. package/src/scripts/_lib/machine_wake.ts +16 -3
  468. package/src/scripts/_lib/module_reach.ts +456 -0
  469. package/src/scripts/_lib/neighbour_census.ts +760 -0
  470. package/src/scripts/_lib/neighbour_contradictions.ts +236 -0
  471. package/src/scripts/_lib/neighbour_scan.ts +122 -0
  472. package/src/scripts/_lib/neighbour_tool_use.ts +187 -0
  473. package/src/scripts/_lib/prompt_shape.ts +46 -0
  474. package/src/scripts/_lib/ratification_artifact.ts +220 -1
  475. package/src/scripts/_lib/ratification_subject.ts +92 -0
  476. package/src/scripts/_lib/release_findings_ingest.ts +15 -7
  477. package/src/scripts/_lib/release_highlights.ts +5 -0
  478. package/src/scripts/_lib/release_migration_gate.ts +19 -3
  479. package/src/scripts/_lib/reserved_name_sweep.ts +73 -0
  480. package/src/scripts/_lib/review_coverage.ts +134 -0
  481. package/src/scripts/_lib/rule_consequence_class.ts +71 -0
  482. package/src/scripts/_lib/rule_injection.ts +130 -10
  483. package/src/scripts/_lib/rule_law_section.ts +147 -0
  484. package/src/scripts/_lib/rule_layer_overlap.ts +58 -0
  485. package/src/scripts/_lib/rule_obligations.ts +205 -0
  486. package/src/scripts/_lib/self_repair.ts +1 -1
  487. package/src/scripts/_lib/settings_removed_keys.ts +173 -0
  488. package/src/scripts/_lib/skill_origin.ts +254 -0
  489. package/src/scripts/_lib/structured_ask.ts +64 -21
  490. package/src/scripts/_lib/test_red_state.ts +5 -0
  491. package/src/scripts/_lib/thin_rules.ts +620 -0
  492. package/src/scripts/_lib/touched_file_quality.ts +570 -0
  493. package/src/scripts/_lib/turn_end_refusals.ts +77 -2
  494. package/src/scripts/_lib/windsurf_render.ts +63 -0
  495. package/src/scripts/_lib/worker_budget.ts +1 -1
  496. package/src/scripts/adr/regenerate_index.ts +16 -1
  497. package/src/scripts/ai_council/cli_call_budget.ts +13 -5
  498. package/src/scripts/ai_council/clients.ts +26 -57
  499. package/src/scripts/ai_council/config.ts +8 -8
  500. package/src/scripts/ai_council/modification_review.ts +100 -0
  501. package/src/scripts/ai_council/modification_review_questions.ts +90 -0
  502. package/src/scripts/ai_council/orchestrator.ts +5 -5
  503. package/src/scripts/ai_council/spend_gate.ts +18 -7
  504. package/src/scripts/ai_council/vendor_defaults.ts +45 -0
  505. package/src/scripts/ai_team/config.ts +11 -16
  506. package/src/scripts/audit_skill_overlap.ts +261 -0
  507. package/src/scripts/audit_user_type_axis.ts +20 -8
  508. package/src/scripts/before_complete_hook.ts +243 -12
  509. package/src/scripts/bench_ab_clone.ts +1 -2
  510. package/src/scripts/bench_concern_spawn_path.ts +129 -0
  511. package/src/scripts/bench_graph_feeder_latency.ts +584 -0
  512. package/src/scripts/bench_touched_file_quality.ts +238 -0
  513. package/src/scripts/check_agent_artifact_location.ts +36 -0
  514. package/src/scripts/check_branch_freshness.ts +147 -24
  515. package/src/scripts/check_enforcement_coverage.ts +130 -0
  516. package/src/scripts/check_enforcement_matrix.ts +377 -20
  517. package/src/scripts/check_estate_count.ts +130 -153
  518. package/src/scripts/check_evaluator_budgets.ts +4 -0
  519. package/src/scripts/check_finding_dispositions.ts +196 -21
  520. package/src/scripts/check_gate_coverage.ts +4 -3
  521. package/src/scripts/check_gate_reachability.ts +48 -1
  522. package/src/scripts/check_generator_sync.ts +48 -0
  523. package/src/scripts/check_hook_bundle_composition.ts +477 -0
  524. package/src/scripts/check_kernel_edit_ratified.ts +132 -14
  525. package/src/scripts/check_memory.ts +7 -1
  526. package/src/scripts/check_pack_size.ts +1 -1
  527. package/src/scripts/check_release_highlights.ts +10 -0
  528. package/src/scripts/check_release_manifest_content.ts +189 -0
  529. package/src/scripts/check_release_pr_shape.ts +38 -15
  530. package/src/scripts/check_standing_rule_delivery.ts +129 -13
  531. package/src/scripts/check_suppression_hygiene.ts +2 -5
  532. package/src/scripts/check_verify_expectation_delta.ts +521 -0
  533. package/src/scripts/ci_settle.ts +42 -5
  534. package/src/scripts/classify_merge_risk.ts +320 -0
  535. package/src/scripts/closure_scan.ts +91 -1
  536. package/src/scripts/code_graph/detect.ts +127 -7
  537. package/src/scripts/code_graph/foreign.ts +194 -0
  538. package/src/scripts/code_graph/query.ts +217 -4
  539. package/src/scripts/code_graph/types.ts +26 -2
  540. package/src/scripts/code_graph/validate.ts +3 -1
  541. package/src/scripts/code_graph/verbs.ts +103 -0
  542. package/src/scripts/command_suggester/settings.ts +8 -108
  543. package/src/scripts/command_suggester/types.ts +4 -5
  544. package/src/scripts/compile_hook_manifest.ts +33 -1
  545. package/src/scripts/condense.ts +14 -27
  546. package/src/scripts/consumer_matrix.ts +102 -0
  547. package/src/scripts/context_hygiene_hook.ts +13 -23
  548. package/src/scripts/cost/preflight.mjs +12 -1
  549. package/src/scripts/council_cli.ts +7 -7
  550. package/src/scripts/dispatch_r2_reviewer.ts +24 -11
  551. package/src/scripts/estate_exemption_shape.ts +202 -0
  552. package/src/scripts/explain_run.ts +8 -13
  553. package/src/scripts/generate_git_convention_grammar.ts +127 -0
  554. package/src/scripts/generate_host_cost_table.ts +21 -4
  555. package/src/scripts/handoff_context_hook.ts +86 -37
  556. package/src/scripts/hook_manifest.json +1 -1
  557. package/src/scripts/hook_manifest.yaml +175 -15
  558. package/src/scripts/hooks/block_config_weakening.ts +115 -7
  559. package/src/scripts/hooks/block_plumbing_writes.ts +37 -5
  560. package/src/scripts/hooks/code_graph_context_hook.ts +252 -23
  561. package/src/scripts/hooks/concern_failure_policy.ts +280 -0
  562. package/src/scripts/hooks/concern_registry.ts +2 -0
  563. package/src/scripts/hooks/delegation_nudge_hook.ts +2 -3
  564. package/src/scripts/hooks/dispatch_hook.ts +52 -52
  565. package/src/scripts/hooks/evidence_independence.ts +12 -4
  566. package/src/scripts/hooks/exit_codes.ts +2 -1
  567. package/src/scripts/hooks/host_lowering.json +1 -1
  568. package/src/scripts/hooks/host_lowering.ts +19 -1
  569. package/src/scripts/hooks/mcp_usage_observation_hook.ts +121 -0
  570. package/src/scripts/hooks/one_question_per_ask_hook.ts +41 -25
  571. package/src/scripts/hooks/payload_stub.ts +10 -1
  572. package/src/scripts/hooks/push_settle_hook.ts +4 -3
  573. package/src/scripts/hooks/rule_inject_hook.ts +795 -60
  574. package/src/scripts/hooks/state_io.ts +8 -4
  575. package/src/scripts/hooks/table_fingerprint.ts +21 -0
  576. package/src/scripts/hooks/telemetry_usage_hook.ts +24 -7
  577. package/src/scripts/hooks/turn_end_gate_hook.ts +85 -0
  578. package/src/scripts/hooks_status.ts +112 -0
  579. package/src/scripts/injection_scan_hook.ts +7 -0
  580. package/src/scripts/install-hooks.sh +42 -14
  581. package/src/scripts/install.ts +78 -215
  582. package/src/scripts/installed_layer_report.ts +103 -0
  583. package/src/scripts/language_mirror_hook.ts +15 -6
  584. package/src/scripts/learning_sidecar.ts +119 -8
  585. package/src/scripts/lint_blocker_citations.ts +198 -0
  586. package/src/scripts/lint_evidence_artifacts.ts +9 -0
  587. package/src/scripts/lint_hook_concern_budget.ts +10 -21
  588. package/src/scripts/lint_hook_manifest.ts +53 -0
  589. package/src/scripts/lint_major_migration_sections.ts +156 -26
  590. package/src/scripts/lint_pack_boundaries.ts +465 -29
  591. package/src/scripts/lint_roadmap_blockers.ts +282 -29
  592. package/src/scripts/lint_roadmap_complexity.ts +4 -2
  593. package/src/scripts/lint_rule_law_section.ts +647 -0
  594. package/src/scripts/lint_rule_skill_pack_reach.ts +17 -0
  595. package/src/scripts/lint_settings_classes.ts +1 -1
  596. package/src/scripts/lint_ticked_unmet_criteria.ts +165 -0
  597. package/src/scripts/lint_workflow_security.ts +173 -6
  598. package/src/scripts/mcp_server/consumer_tool_catalog.json +53 -0
  599. package/src/scripts/mcp_server/graph_tools.ts +72 -3
  600. package/src/scripts/measure_routing_signal.ts +54 -16
  601. package/src/scripts/measure_skill_ranker_baseline.ts +221 -8
  602. package/src/scripts/memory_learn_hook.ts +91 -6
  603. package/src/scripts/model_rule_injection.ts +55 -8
  604. package/src/scripts/onboarding_gate_hook.ts +7 -6
  605. package/src/scripts/print_required_checks.ts +15 -3
  606. package/src/scripts/probe_host_compliance.ts +33 -5
  607. package/src/scripts/probe_turnaround.ts +183 -3
  608. package/src/scripts/project_thin_rules.ts +34 -327
  609. package/src/scripts/ratification_header.ts +77 -0
  610. package/src/scripts/refusal_envelope.ts +138 -0
  611. package/src/scripts/release_publication.ts +29 -3
  612. package/src/scripts/report_dispatch_import_closure.ts +76 -0
  613. package/src/scripts/report_evidence_temperature.ts +657 -0
  614. package/src/scripts/report_installed_rule_links.ts +274 -0
  615. package/src/scripts/report_label_agreement.ts +233 -0
  616. package/src/scripts/report_module_reach.ts +212 -0
  617. package/src/scripts/report_obligation_mechanism.ts +228 -0
  618. package/src/scripts/report_parked_blockers.ts +222 -0
  619. package/src/scripts/report_required_checks_drift.ts +196 -0
  620. package/src/scripts/report_single_token_triggers.ts +277 -0
  621. package/src/scripts/report_skill_ranker_confusion.ts +543 -0
  622. package/src/scripts/report_standing_payload_by_host.ts +188 -15
  623. package/src/scripts/report_verification_record_coverage.ts +306 -0
  624. package/src/scripts/routing_doctor.ts +2 -2
  625. package/src/scripts/rule_activation_census.ts +5 -2
  626. package/src/scripts/rule_trigger_eval.ts +9 -9
  627. package/src/scripts/schemas/agent-settings.schema.json +17 -31
  628. package/src/scripts/schemas/command.schema.json +1 -1
  629. package/src/scripts/schemas/review-findings.schema.json +3 -2
  630. package/src/scripts/schemas/rule.schema.json +5 -0
  631. package/src/scripts/schemas/skill.schema.json +1 -1
  632. package/src/scripts/self_review_gate.ts +101 -9
  633. package/src/scripts/skill_tools/score_skill_relevance.ts +314 -40
  634. package/src/scripts/sweep_skill_ranker_signals.ts +129 -0
  635. package/src/scripts/sync_gitignore.ts +29 -235
  636. package/src/scripts/sync_pr_branch.ts +403 -132
  637. package/src/scripts/trigger_eval_grandfather.json +0 -21
  638. package/src/server/schemas/settings.ts +42 -176
  639. package/src/shared/skillRanking.ts +169 -14
  640. package/dist/cli-delegate/chunk-5R7HOLAF.js +0 -99
  641. package/dist/cli-delegate/chunk-JNMVLWLR.js +0 -4457
  642. package/dist/cli-delegate/chunk-YDPILCOL.js +0 -152
  643. package/src/scripts/_lib/config_chain.ts +0 -477
  644. package/src/scripts/_lib/conformance_report.ts +0 -403
  645. package/src/scripts/_lib/eval_discrimination.ts +0 -95
  646. package/src/scripts/_lib/evaluator_promotion.ts +0 -225
  647. package/src/scripts/_lib/file_slicer.ts +0 -117
  648. package/src/scripts/_lib/legacy_boundary_map.ts +0 -228
  649. package/src/scripts/_lib/minimality_tiebreak.ts +0 -168
  650. package/src/scripts/_lib/overbuild_lens_contract.ts +0 -196
  651. package/src/scripts/_lib/role_split.ts +0 -338
@@ -0,0 +1,280 @@
1
+ /**
2
+ * What a concern's DECLARED SEVERITY means when the concern produced no verdict.
3
+ *
4
+ * Extracted from `dispatch_hook.ts` on 2026-10-03, and not for tidiness.
5
+ * `check_source_size_budget` measured that file at exactly 1,500 lines on
6
+ * `main` — sitting precisely on the cap — and step 3.3's additions put it 203
7
+ * lines over. The ratchet turns one way, and the doctrine every entry in
8
+ * `gate-violation-baselines.json` records is that a MOVE gives the budget back
9
+ * where raising the baseline spends it. The same move
10
+ * `_lib/concern_sla_window.ts` made out of `bench_hook_latency.ts`.
11
+ *
12
+ * It is also the better boundary on its own terms. Everything here answers one
13
+ * question — what a concern's declaration permits and requires when the
14
+ * concern itself said nothing — and none of it is about RUNNING a concern,
15
+ * which is what the dispatcher does. `stdin_failure_policy.ts` is its sibling:
16
+ * the same question for a payload the dispatcher could not read.
17
+ *
18
+ * The dispatcher re-exports every symbol here, so callers and tests that
19
+ * imported them from `dispatch_hook.js` are unaffected.
20
+ */
21
+ import { EXIT_ALLOW, EXIT_BLOCK, EXIT_ERROR } from './exit_codes.js';
22
+
23
+ type JsonObject = Record<string, unknown>;
24
+
25
+ /**
26
+ * P0.2 (road-to-rule-coherence) — is this concern declared advisory?
27
+ *
28
+ * An advisory concern MUST never produce a BLOCK verdict on any host. Four
29
+ * PreToolUse concerns document themselves as advisory in prose
30
+ * (`design_slop_hook`: "FLAGS, NEVER A BLOCK") while the transport happily
31
+ * turned their WARN into a host-level deny. Prose is not enforcement: the
32
+ * manifest now declares severity and the dispatcher enforces the ceiling.
33
+ */
34
+ export function _is_advisory(concern: JsonObject): boolean {
35
+ return String(concern["severity"] ?? "").trim().toLowerCase() === "advisory";
36
+ }
37
+
38
+ /**
39
+ * Is this concern declared `severity: blocking`?
40
+ *
41
+ * The positive twin of `_is_advisory`, and NOT its negation. A concern whose
42
+ * `severity` is absent, misspelt or any third value is neither — and step 3.3
43
+ * below promotes a crash to a refusal only on an EXPLICIT `blocking`, so an
44
+ * undeclared concern keeps the historical fail-open rather than inheriting a
45
+ * refusal from a typo. `lint_hook_manifest` requires the key, so the middle
46
+ * case should not exist; this reads it as the safe direction anyway, because
47
+ * the cost of the two mistakes is not symmetric.
48
+ */
49
+ export function _is_blocking(concern: JsonObject): boolean {
50
+ return String(concern["severity"] ?? "").trim().toLowerCase() === "blocking";
51
+ }
52
+
53
+ /**
54
+ * What an `rc >= 3` (crash / could-not-decide) becomes — step 3.3 of
55
+ * `road-to-a-kernel-that-guards-its-plumbing`.
56
+ *
57
+ * WHAT CHANGED, AND WHAT AUTHORISES IT.
58
+ * Until this step the resolution read the `fail_closed:` FLAG: a crash blocked
59
+ * when the concern opted in and allowed otherwise. Three of nine
60
+ * `severity: blocking` concerns carried the flag, so six guards declared
61
+ * blocking in the manifest — the declaration that AUTHORISES a refusal, and the
62
+ * one `_is_advisory` already enforces as a ceiling — and then allowed the call
63
+ * through whenever they crashed. A guard that refuses when it works and permits
64
+ * when it breaks is not a guard: a crash is exactly the moment the check did
65
+ * not happen, so it is the moment the answer matters most.
66
+ *
67
+ * So `severity` now decides both directions. It is the ceiling (an advisory
68
+ * concern may never block) AND the floor (a blocking concern that could not
69
+ * decide refuses). `fail_closed:` is no longer consulted on this branch — all
70
+ * three concerns carrying it are `severity: blocking`, so no verdict moves
71
+ * because it stopped being read here.
72
+ *
73
+ * WHAT A SLOW CONCERN IS NOT, ON EITHER PATH.
74
+ * This branch resolves a concern that produced NO VERDICT. It is not a latency
75
+ * gate and no reading of `concern_sla_ms` reaches it. On the default in-process
76
+ * route a kill-timeout cannot preempt synchronous code, so an overrun there is
77
+ * a POST-HOC observation about a concern that did in fact answer — refusing it
78
+ * afterwards would deny a call whose guard passed, buying no enforcement while
79
+ * spending exactly the availability risk Risk 1 of the owning roadmap holds
80
+ * down. On the spawn route the timeout stays the historical 30 s, because the
81
+ * registered SLA measures in-process concern work and is three to fifteen times
82
+ * smaller than interpreter startup alone; `SPAWN_TIMEOUT_MS` carries that
83
+ * measurement and the probe that refused the substitution.
84
+ *
85
+ * So `sla_ms x 3` remains what the warn-only window made it: a number the bench
86
+ * prints beside each measured p95, gating nothing. Its readings are recorded
87
+ * with the owning plan and no count is repeated here — a review of an earlier
88
+ * revision found two different tallies in one diff, because a number had been
89
+ * pasted into an implementation comment while the record kept accumulating.
90
+ * The readings validate the bound as an OBSERVATION, which is the only thing
91
+ * this step asks of them.
92
+ *
93
+ * The discriminator for this branch is whether a VERDICT EXISTS. A crash and a
94
+ * killed spawn leave none, so they fail closed. A slow success leaves one, so
95
+ * it is honoured, however slow it was.
96
+ *
97
+ * THE ONE-RETRY ESCAPE, AND WHY THE STOP SLOT NEEDS IT.
98
+ * `turn-end-gate` and `run-continuation` are `severity: blocking` on `stop`,
99
+ * and `tests/hooks/concern_severity.test.ts` records the hazard in as many
100
+ * words: a turn-end gate that fails closed "does not degrade, it wedges the
101
+ * session". Neither carries `skip_on_refusal_retry`, so without this clause a
102
+ * DETERMINISTIC crash in either would refuse every Stop, indefinitely, with no
103
+ * escape the user can reach.
104
+ *
105
+ * So the promotion is spent ONCE. On the retry the host itself marks
106
+ * (`stop_hook_active`, read by `_is_refusal_retry`) a crash falls back to
107
+ * fail-open and the turn ends. The legitimate refusal path is untouched: a
108
+ * concern that DECIDED to refuse returns `EXIT_BLOCK` and never reaches this
109
+ * branch. What a broken concern loses is only the power to refuse forever on
110
+ * the strength of being broken.
111
+ *
112
+ * `pre_tool_use` is untouched by the clause — `_is_refusal_retry` is false on
113
+ * every event but `stop` — and that asymmetry is deliberate. A crashing
114
+ * tool-call guard refuses every attempt, which is the right answer there: the
115
+ * user can run a different command and nothing is wedged, whereas a turn that
116
+ * cannot end leaves no move at all.
117
+ */
118
+ export function _resolve_execution_failure(
119
+ concern: JsonObject,
120
+ refusal_retry: boolean,
121
+ ): number {
122
+ if (!_is_blocking(concern)) return EXIT_ALLOW;
123
+ if (refusal_retry) return EXIT_ALLOW;
124
+ return EXIT_BLOCK;
125
+ }
126
+
127
+ /**
128
+ * The spawn kill-timeout, and why `concern_sla_ms` is NOT what sets it.
129
+ *
130
+ * Step 3.3 of `road-to-a-kernel-that-guards-its-plumbing` reads "timeout for a
131
+ * blocking concern becomes `sla_ms x 3`". That clause is NOT landed, and the
132
+ * reason is a unit mismatch that is measurable rather than arguable.
133
+ *
134
+ * `concern_sla_ms` is derived from the per-concern `duration_ms` this file
135
+ * reports into the timings sink, which on the in-process route brackets
136
+ * `main_fn(argsList)` and nothing else — the concern's OWN work. The registered
137
+ * rows are 0.564 to 1.587 ms, so `sla_ms x 3` is 1.7 to 4.8 ms.
138
+ *
139
+ * A `spawnSync` timeout bounds something else entirely: fork, interpreter
140
+ * start, module graph load, and only then the same work. The bench's own
141
+ * control row measures the interpreter term alone at p95 17 ms on the 1 vCPU
142
+ * reference class and 26 ms on the GitHub runner — three to fifteen times the
143
+ * whole proposed bound, before the concern has run a line.
144
+ *
145
+ * Wiring it was tried on this branch and probed against the real dispatcher.
146
+ * With `AGENT_CONFIG_HOOKS_ISOLATED=1` on `claude/pre_tool_use`, all six
147
+ * blocking concerns returned `ETIMEDOUT`, left no verdict, and — resolved by
148
+ * `_resolve_execution_failure` — turned the dispatch into a deny: exit 2 on an
149
+ * ordinary `Read`. That is Risk 1 of the owning roadmap ("fail-closed wedges
150
+ * slow hosts") firing on every host rather than a slow one, reached through a
151
+ * documented escape hatch. The two changes are individually defensible and
152
+ * lethal together, which is exactly the shape a measured bound is supposed to
153
+ * prevent.
154
+ *
155
+ * So the bound stays where the window put it: an observation
156
+ * `src/scripts/_lib/concern_sla_window.ts` prints on every bench run, gating
157
+ * nothing. The spawn path keeps the historical 30 s. Re-wiring it needs a
158
+ * SPAWN-path measurement — which this tree does not have, because the sink it
159
+ * would come from records the in-process number — and not a second reading of
160
+ * the one registered here.
161
+ *
162
+ * `spawn_path_keeps_the_historical_timeout` in `dispatch_hook.test.ts` pins
163
+ * this: it dispatches a blocking concern whose NAME carries a registered SLA
164
+ * row down the spawn path and asserts the call is allowed. Under the bound it
165
+ * reds.
166
+ */
167
+ export const SPAWN_TIMEOUT_MS = 30000;
168
+
169
+ /**
170
+ * The signal name a killed child reports, or the honest placeholder.
171
+ *
172
+ * A SIGNALLED child has `status === null` and `signal` set, and reaches the
173
+ * dispatcher's spawn branch with no `proc.error` whenever the signal came from
174
+ * outside this process — an OOM kill, a SIGTERM from a supervisor, a crash in
175
+ * the child's own runtime. `proc.status ?? 0` read that as exit 0, i.e. ALLOW,
176
+ * which is a fail-OPEN at the one moment the error band exists to fail closed:
177
+ * the concern was killed, so it decided nothing. The coalescing default was
178
+ * harmless while the band meant fail-open for six of nine blocking concerns;
179
+ * with the severity resolution it is the difference between a guard that
180
+ * refuses when it is killed and one that waves the call through. Found by an
181
+ * independent review, 2026-10-03, latent since the spawn path was written.
182
+ *
183
+ * `null` for both fields is possible and is reported as an unknown signal
184
+ * rather than guessed at — a refusal whose cause reads "unknown" is still
185
+ * actionable, and one whose cause is invented is not.
186
+ */
187
+ export function signalLabel(signal: NodeJS.Signals | null): string {
188
+ return signal === null ? 'unknown signal' : signal;
189
+ }
190
+
191
+ /**
192
+ * What an operator is told when a blocking concern refuses without deciding.
193
+ *
194
+ * Printed where the refusal is produced rather than left in a source comment.
195
+ * Both review seats of 2026-10-03 named the same gap: on `pre_tool_use` a
196
+ * deterministically crashing blocking concern refuses every tool call, and the
197
+ * operator cannot discover the escape hatch from inside a wedged session.
198
+ * `stop` is bounded by the one-retry clause and needs no such line, so the
199
+ * caller prints this only where the denial can repeat.
200
+ */
201
+ export function noVerdictRefusalNotice(name: string): string {
202
+ return (
203
+ `dispatch_hook: '${name}' is severity: blocking and produced no ` +
204
+ `verdict, so this call is refused. If it keeps failing, ` +
205
+ `AGENT_CONFIG_HOOKS_ISOLATED=1 runs concerns out of process and ` +
206
+ `agents/runtime/state/dispatch-issues.jsonl names the cause.\n`
207
+ );
208
+ }
209
+
210
+ /**
211
+ * What a finished `spawnSync` actually said, in the vocabulary of verdicts.
212
+ *
213
+ * Three ways a spawned concern produces NO VERDICT, and until 2026-10-03 only
214
+ * two of them were recognised as such:
215
+ *
216
+ * - **`proc.error`** — an OSError, or the kill-timeout expiring. Always a
217
+ * no-verdict and always was.
218
+ * - **`status === null` with a signal** — the child was killed from outside
219
+ * this process: an OOM kill, a supervisor SIGTERM, an abort in the child's
220
+ * own runtime. `proc.status ?? 0` read this as exit 0, i.e. ALLOW, which is
221
+ * a fail-OPEN at the one moment the error band exists to fail closed. The
222
+ * coalescing default was harmless while the band meant fail-open for six of
223
+ * nine blocking concerns; with the severity resolution it is the difference
224
+ * between a guard that refuses when it is killed and one that waves the call
225
+ * through. Found by an independent review, latent since the spawn path was
226
+ * written.
227
+ * - **an exit code in the error band** — a child that simply exited 3. This
228
+ * logged nothing until step 3.3: `proc.error` covers the first case, the
229
+ * in-process route logs its own throw, and this fell between the two. That
230
+ * was survivable while the band meant fail-open; now it can produce a
231
+ * refusal, and a refusal whose cause is in no record is one nobody can act
232
+ * on.
233
+ *
234
+ * Returning a classification rather than writing the log here keeps this module
235
+ * free of I/O — the caller owns `log_dispatch_issue` and the workspace it needs,
236
+ * and this owns what the three cases MEAN.
237
+ */
238
+ export interface SpawnClassification {
239
+ /** The exit code the dispatcher should carry forward. */
240
+ readonly rc: number;
241
+ /** `execution_failed` detail to record, or `null` when there is nothing to record. */
242
+ readonly issueDetail: string | null;
243
+ /** True when the concern produced no verdict and its own stdout must be discarded. */
244
+ readonly noVerdict: boolean;
245
+ /** Prefix for the stderr line, or `null` to pass the child's stderr through unchanged. */
246
+ readonly stderrNote: string | null;
247
+ }
248
+
249
+ export function classifySpawnResult(
250
+ error: Error | undefined,
251
+ status: number | null,
252
+ signal: NodeJS.Signals | null,
253
+ ): SpawnClassification {
254
+ if (error !== undefined) {
255
+ const err = error as NodeJS.ErrnoException;
256
+ const typeName = err.code === 'ETIMEDOUT' ? 'TimeoutExpired' : err.name || 'OSError';
257
+ return {
258
+ rc: EXIT_ERROR,
259
+ issueDetail: `${typeName}: ${err.message}`,
260
+ noVerdict: true,
261
+ stderrNote: err.message,
262
+ };
263
+ }
264
+ if (status === null) {
265
+ const sig = signalLabel(signal);
266
+ return {
267
+ rc: EXIT_ERROR,
268
+ issueDetail: `concern was terminated by ${sig} without a verdict`,
269
+ noVerdict: true,
270
+ stderrNote: `terminated by ${sig}`,
271
+ };
272
+ }
273
+ return {
274
+ rc: status,
275
+ issueDetail:
276
+ status >= EXIT_ERROR ? `concern exited ${String(status)} without a verdict` : null,
277
+ noVerdict: false,
278
+ stderrNote: null,
279
+ };
280
+ }
@@ -65,6 +65,7 @@ import { main as suggestionCaptureMain } from './suggestion_capture_hook.js';
65
65
  import { main as uiRouteNudgeMain } from './ui_route_nudge_hook.js';
66
66
  import { main as orchestrationRecordMain } from './orchestration_record_hook.js';
67
67
  import { main as telemetryUsageMain } from './telemetry_usage_hook.js';
68
+ import { main as mcpUsageObservationMain } from './mcp_usage_observation_hook.js';
68
69
  import { main as telemetryFlushMain } from './telemetry_flush_hook.js';
69
70
  import { main as delegationNudgeMain } from './delegation_nudge_hook.js';
70
71
  import { main as skillRouteMain } from './skill_route_hook.js';
@@ -132,6 +133,7 @@ export const CONCERN_REGISTRY: Readonly<Record<string, ConcernMain>> = {
132
133
  'src/scripts/hooks/ui_route_nudge_hook.ts': uiRouteNudgeMain as ConcernMain,
133
134
  'src/scripts/hooks/orchestration_record_hook.ts': orchestrationRecordMain as ConcernMain,
134
135
  'src/scripts/hooks/telemetry_usage_hook.ts': telemetryUsageMain as ConcernMain,
136
+ 'src/scripts/hooks/mcp_usage_observation_hook.ts': mcpUsageObservationMain as ConcernMain,
135
137
  'src/scripts/hooks/telemetry_flush_hook.ts': telemetryFlushMain as ConcernMain,
136
138
  'src/scripts/hooks/delegation_nudge_hook.ts': delegationNudgeMain as ConcernMain,
137
139
  'src/scripts/hooks/skill_route_hook.ts': skillRouteMain as ConcernMain,
@@ -320,11 +320,10 @@ export function resolveActivation(
320
320
  const emergency = (settings["emergency"] ?? {}) as Record<string, unknown>;
321
321
  const halted = emergency["orchestration_halt"] === true;
322
322
  const host_manifest = probeHostCapabilities(hostId);
323
- const sub = (settings["subagents"] ?? {}) as Record<string, unknown>;
324
- const downshift = sub["downshift"] !== false;
325
323
  return {
326
324
  activation: { halted, subagent_spawn: host_manifest.subagent_spawn },
327
- downshift,
325
+ // Fixed on: the `subagents.downshift` key was retired with this default.
326
+ downshift: true,
328
327
  separate_quota_pool: host_manifest.separate_quota_pool,
329
328
  agentTeams: host_manifest.agent_teams,
330
329
  };
@@ -12,7 +12,7 @@
12
12
  * Per `docs/contracts/hook-architecture-v1.md`. Reads `src/scripts/hook_manifest.yaml`,
13
13
  * resolves which concerns fire on the given (platform, event) tuple, and runs each
14
14
  * sequentially with the stdin envelope contract. Reduces concern exit codes per the
15
- * spec (0=allow, 1=block, 2=warn, ≥3=error → fail-open unless concern is fail_closed).
15
+ * spec (0=allow, 1=block, 2=warn, ≥3=error → resolved by declared `severity`).
16
16
  *
17
17
  * Invocation:
18
18
  *
@@ -59,6 +59,13 @@ import { _concern_body_classes, planPayloadShapes } from "./payload_stub.js";
59
59
  import { resolveSessionRole, type SessionRole } from "../_lib/session_role.js";
60
60
  import { stdinReadFailure, denyOnStdinFailure } from './stdin_failure_policy.js';
61
61
  export { stdinReadFailure, denyOnStdinFailure, _is_fail_closed_blocking } from './stdin_failure_policy.js';
62
+ // Severity policy — what a declaration means when the concern said nothing.
63
+ // Re-exported so the move out of this file left every importer unaffected.
64
+ import {
65
+ _is_advisory, _is_blocking, _resolve_execution_failure,
66
+ classifySpawnResult, noVerdictRefusalNotice, SPAWN_TIMEOUT_MS,
67
+ } from './concern_failure_policy.js';
68
+ export { _is_advisory, _is_blocking, _resolve_execution_failure };
62
69
  import { _py_json_dumps } from './py_json_dumps.js';
63
70
  import { _fallback_yaml } from './fallback_yaml.js';
64
71
  import { detectSurface } from '../_lib/surface.js';
@@ -128,18 +135,6 @@ export function _severity_for(rc: number): string {
128
135
  return _SEVERITY_BY_EXIT[rc] ?? "error";
129
136
  }
130
137
 
131
- /**
132
- * P0.2 (road-to-rule-coherence) — is this concern declared advisory?
133
- *
134
- * An advisory concern MUST never produce a BLOCK verdict on any host. Four
135
- * PreToolUse concerns document themselves as advisory in prose
136
- * (`design_slop_hook`: "FLAGS, NEVER A BLOCK") while the transport happily
137
- * turned their WARN into a host-level deny. Prose is not enforcement: the
138
- * manifest now declares severity and the dispatcher enforces the ceiling.
139
- */
140
- export function _is_advisory(concern: JsonObject): boolean {
141
- return String(concern["severity"] ?? "").trim().toLowerCase() === "advisory";
142
- }
143
138
 
144
139
  function _now_iso(): string {
145
140
  // Python: datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ").
@@ -198,32 +193,25 @@ export function _parse_concern_stdout(stdout_text: string): JsonObject {
198
193
  * path (`yaml.safe_load(text) or {}`); version 1.1 matches PyYAML.safe_load.
199
194
  */
200
195
  /**
201
- * Cheap content fingerprint of a manifest source — FNV-1a 32-bit plus the byte
202
- * length, hex.
196
+ * Content fingerprint of a manifest source — delegated to `tableFingerprint`,
197
+ * which owns the algorithm and the measurement.
203
198
  *
204
- * Deliberately NOT a crypto hash: `require('node:crypto')` costs 8 ms of
205
- * process start, which is most of what the precompiled manifest exists to
206
- * save. This runs in about 0.2 ms over 61 kB and only has to detect an edited
207
- * source, not resist an adversary — a wrong answer costs the slow path, never
208
- * correctness.
199
+ * road-to-blocking-severities 3.1: this comment used to argue against a crypto
200
+ * hash for a function that already used one. The retired argument and the
201
+ * numbers that retired it live there now.
209
202
  */
210
203
  export function _manifest_fingerprint(text: string): string {
211
204
  return tableFingerprint(text);
212
205
  }
213
206
 
214
207
  export function _load_yaml(p: string): JsonObject {
215
- // Precompiled fast path. The manifest is ~61 kB of YAML and is parsed on
216
- // EVERY dispatch, which measured 12 ms of a ~103 ms dispatch (plus 8 ms to
217
- // load the `yaml` module itself). The sibling `.json` is the same data with
218
- // comments stripped — 14.7 kB — and JSON.parse of it is sub-millisecond.
208
+ // Precompiled fast path. The manifest is ~61 kB of YAML parsed on EVERY
209
+ // dispatch — 12 ms of a ~103 ms dispatch, plus 8 ms to load the `yaml` module
210
+ // itself. The sibling `.json` is the same data with comments stripped,
211
+ // 14.7 kB, and JSON.parse of it is sub-millisecond.
219
212
  //
220
- // Freshness is decided by the SOURCE CONTENT, not by mtime. The first version
221
- // of this compared mtimes and that was a measured defect, not a theoretical
222
- // one: on a fresh `actions/checkout` both files get the checkout timestamp in
223
- // whatever order git wrote them, so whether the optimisation applied at all
224
- // was a coin flip. It won on the PR (p95 129 ms) and lost on the trunk
225
- // (p95 186 ms) for the same commit. A fingerprint is deterministic wherever
226
- // the tree came from.
213
+ // Freshness is SOURCE CONTENT, never mtime — the measured defect behind that
214
+ // is in `table_fingerprint.ts`, told once rather than in all three readers.
227
215
  //
228
216
  // Reading the YAML unconditionally costs ~0 ms (it is the PARSE that is
229
217
  // expensive), so the fast path still skips ~20 ms.
@@ -235,7 +223,14 @@ export function _load_yaml(p: string): JsonObject {
235
223
  if (
236
224
  _isObject(raw) &&
237
225
  raw["fingerprint"] === _manifest_fingerprint(text) &&
238
- _isObject(raw["manifest"])
226
+ _isObject(raw["manifest"]) &&
227
+ // road-to-blocking-severities 2.3, the manifest twin of the check in
228
+ // `host_lowering.resolveTable`, which carries the full reasoning. In
229
+ // one line: the label above binds this file to the YAML SOURCE and says
230
+ // nothing about the body underneath, so an edited `manifest` body with
231
+ // an untouched label was served — on the table that decides which
232
+ // concern runs on which slot at all. Absent field → fall through.
233
+ raw["body_fingerprint"] === _manifest_fingerprint(JSON.stringify(raw["manifest"]))
239
234
  ) {
240
235
  return raw["manifest"];
241
236
  }
@@ -565,10 +560,10 @@ function _resolve_tsx_invocation(
565
560
  * Escape hatch: AGENT_CONFIG_HOOKS_ISOLATED=1 forces the historical
566
561
  * spawn-per-concern path (also used by the bench harness for A/B numbers).
567
562
  *
568
- * Known trade-off vs the spawn path: the 30 s kill-timeout cannot preempt
569
- * in-process synchronous code. Concerns are repo-owned, budget-capped and
570
- * fail-open; the latency budget gate (hook-latency-budget.json) is the
571
- * standing regression net.
563
+ * Known trade-off vs the spawn path: a kill-timeout cannot preempt in-process
564
+ * synchronous code, so a slow concern is bounded on neither route — see
565
+ * `SPAWN_TIMEOUT_MS`. A CRASH is caught here, surfaces as rc 3, and the caller
566
+ * resolves it by declared severity.
572
567
  */
573
568
  /**
574
569
  * ## Why this still re-serialises the envelope per concern (step 1.1, MEASURED NULL)
@@ -678,6 +673,7 @@ function _run_concern_inproc(
678
673
  return { rc, stderr: err, stdout: out, duration_ms: performance.now() - started };
679
674
  }
680
675
 
676
+
681
677
  function _run_concern(concern: ConcernDef, envelope: JsonObject): RunResult {
682
678
  // In-process fast path — the default whenever the concern is in the
683
679
  // static registry (all manifest concerns; parity is CI-enforced).
@@ -728,31 +724,31 @@ function _run_concern(concern: ConcernDef, envelope: JsonObject): RunResult {
728
724
  encoding: "utf-8",
729
725
  cwd: workspace,
730
726
  env: concern_env,
731
- timeout: 30000,
727
+ timeout: SPAWN_TIMEOUT_MS, // historical bound; `SPAWN_TIMEOUT_MS` says why
732
728
  });
733
729
  const elapsed = performance.now() - started;
734
- if (proc.error) {
735
- // OSError / timeout equivalent — log execution-failed so the
736
- // never-block contract keeps a trace.
737
- const err = proc.error as NodeJS.ErrnoException;
738
- const typeName =
739
- err.code === "ETIMEDOUT" ? "TimeoutExpired" : err.name || "OSError";
730
+ // Three ways a spawn produces no verdict; `classifySpawnResult` owns the
731
+ // reading, this writes the record and carries the code.
732
+ const outcome = classifySpawnResult(proc.error, proc.status, proc.signal);
733
+ if (outcome.issueDetail !== null) {
740
734
  log_dispatch_issue(
741
735
  workspace,
742
736
  String(concern["name"] || "unknown"),
743
737
  "execution_failed",
744
- `${typeName}: ${err.message}`,
738
+ outcome.issueDetail,
745
739
  fix_hint(),
746
740
  );
741
+ }
742
+ if (outcome.noVerdict) {
747
743
  return {
748
- rc: 3,
749
- stderr: `${String(concern["name"])}: ${err.message}`,
744
+ rc: outcome.rc,
745
+ stderr: `${String(concern["name"])}: ${String(outcome.stderrNote)}\n${proc.stderr || ""}`,
750
746
  stdout: "",
751
747
  duration_ms: elapsed,
752
748
  };
753
749
  }
754
750
  return {
755
- rc: proc.status ?? 0,
751
+ rc: outcome.rc,
756
752
  stderr: proc.stderr || "",
757
753
  stdout: proc.stdout || "",
758
754
  duration_ms: elapsed,
@@ -1317,14 +1313,18 @@ export function main(argv?: string[]): number {
1317
1313
  let rc = rawRcResult;
1318
1314
  const raw_rc = rc;
1319
1315
  if (rc >= 3) {
1320
- if (!concern["fail_closed"]) {
1321
- rc = EXIT_ALLOW; // fail-open
1322
- } else {
1323
- rc = EXIT_BLOCK;
1324
- }
1316
+ // Resolved by DECLARED SEVERITY, no longer by `fail_closed:`. Every
1317
+ // crash path has already written an `execution_failed` row, so a refusal
1318
+ // here is traceable to a named failure. See `_resolve_execution_failure`.
1319
+ rc = _resolve_execution_failure(concern, refusal_retry);
1325
1320
  if (stderr_text) {
1326
1321
  process.stderr.write(stderr_text);
1327
1322
  }
1323
+ // The escape, printed only where a denial can repeat — `stop` is bounded
1324
+ // by the one-retry clause above. Reasoning: `noVerdictRefusalNotice`.
1325
+ if (rc === EXIT_BLOCK && !refusal_retry) {
1326
+ process.stderr.write(noVerdictRefusalNotice(String(concern["name"])));
1327
+ }
1328
1328
  }
1329
1329
  // P0.2 severity ceiling: an advisory concern can never block, on any host.
1330
1330
  // This covers BOTH the concern emitting EXIT_BLOCK directly and the
@@ -53,6 +53,7 @@ import { atomic_write_json } from "./state_io.js";
53
53
  import { readHookStdin } from "./hook_stdin.js";
54
54
  import { isCodePath, isTestPath } from "../_lib/test_delta.js";
55
55
  import { EXIT_ALLOW, EXIT_BLOCK } from './exit_codes.js';
56
+ import { ledgerFileFor } from "../git_authorization_hook.js";
56
57
 
57
58
  // MUST equal dispatch_hook.EXIT_BLOCK. The dispatcher's internal ladder is
58
59
  // 0 allow / 1 block / 2 warn — NOT the 2-means-block shape a PreToolUse guard
@@ -198,11 +199,18 @@ interface DispatchState extends JsonObject {
198
199
  evaluations: JsonValue[];
199
200
  }
200
201
 
201
- /** The current user turn's stamp, or "" when no ledger exists yet. */
202
- function _ledgerStamp(consumer_root: string): string {
202
+ /**
203
+ * The current user turn's stamp, or "" when no ledger exists yet.
204
+ *
205
+ * Reads the ledger through the writer's own `ledgerFileFor(session_id)`
206
+ * rather than the legacy session-less path: with a session id the writer
207
+ * never touches that path, so reading it unconditionally found an empty or
208
+ * stale file and the stamp never changed per turn.
209
+ */
210
+ function _ledgerStamp(consumer_root: string, session_id: string): string {
203
211
  try {
204
212
  const raw = fs.readFileSync(
205
- path.join(consumer_root, "agents", "state", "git-authorization.json"),
213
+ path.join(consumer_root, ledgerFileFor(session_id)),
206
214
  "utf8",
207
215
  );
208
216
  const d = JSON.parse(raw) as Record<string, unknown>;
@@ -421,7 +429,7 @@ export function run(stdin_text: string, options: { consumer_root: string }): num
421
429
  // in a session blocked every later one. The only per-user-turn stamp that
422
430
  // actually exists is `detected_at` in the authorization ledger, which
423
431
  // `git_authorization_hook` rewrites on every `user_prompt_submit`.
424
- const turnMarker = `${session_id}:${_ledgerStamp(options.consumer_root)}`;
432
+ const turnMarker = `${session_id}:${_ledgerStamp(options.consumer_root, session_id)}`;
425
433
  if (state.session_id !== turnMarker) {
426
434
  state.session_id = turnMarker;
427
435
  state.turn_started_at = new Date().toISOString();
@@ -114,7 +114,8 @@ export const EXIT_CODES: readonly ExitCodeRow[] = Object.freeze([
114
114
  'resolves it by the concern`s declared severity, never by the number itself',
115
115
  owner: 'no concern emits this on purpose; the runtime does',
116
116
  authorizedBy:
117
- 'hook_manifest.yaml `fail_closed` and `severity` together — see ' +
117
+ 'hook_manifest.yaml `severity` alone — blocking refuses, anything else fails ' +
118
+ 'open; `fail_closed` is no longer read on this branch. See ' +
118
119
  'docs/contracts/hook-architecture-v1.md § Exit-code semantics',
119
120
  }),
120
121
  ] as const);
@@ -1 +1 @@
1
- {"fingerprint":"08575a71d81fd8a5ef9e4b400f4a38cb66c26e1dd701d98f3cdc0bdc9e4758b4:22235","table":{"schema_version":1,"hosts":{"claude":{"surfaces":{"any":{"entry_shape":"claude-settings-hooks","json_shape":"hook-specific-output","fail_policy":"propagate","timeout_unit":"seconds","timeout_default":null,"verified":{"docs_at":"2026-09-29","docs_url":"https://code.claude.com/docs/en/hooks.md","docs_digest":"9dd68316c1111c118e3ddb82861ac6271a8cd164cee0d371b26165efff35fe88","probe_at":"2026-09-06","host_version":"2.1.263","expires":"2027-09-06"},"slots":{"session_start":{"native":"SessionStart","block_exit":null,"answered_at":"2026-09-29"},"session_end":{"native":"SessionEnd","block_exit":null,"answered_at":"2026-09-29"},"stop":{"native":"Stop","block_exit":2,"answered_at":"2026-09-29"},"user_prompt_submit":{"native":"UserPromptSubmit","block_exit":2,"answered_at":"2026-09-29"},"pre_tool_use":{"native":"PreToolUse","block_exit":2,"answered_at":"2026-09-29"},"post_tool_use":{"native":"PostToolUse","block_exit":null,"answered_at":"2026-09-29"},"pre_compact":{"native":"PreCompact","block_exit":null,"answered_at":"2026-09-29"},"subagent_start":{"native":"SubagentStart","block_exit":null,"answered_at":"2026-09-29"},"subagent_stop":{"native":"SubagentStop","block_exit":null,"answered_at":"2026-09-29"}}}}},"augment":{"surfaces":{"any":{"entry_shape":"augment-settings-hooks","json_shape":"none","fail_policy":"discard","timeout_unit":"unknown","timeout_default":null,"verified":{"docs_at":"2026-09-29","docs_url":"https://docs.augmentcode.com/cli/hooks.md","docs_digest":"e500823be8303717020c1823f670e06d100108f6e3ac4b8d12a46d91fd1898fa","probe_at":null,"host_version":null,"expires":"2027-09-29"},"slots":{"session_start":{"native":"SessionStart","block_exit":null,"answered_at":"2026-09-29"},"session_end":{"native":"SessionEnd","block_exit":null,"answered_at":"2026-09-29"},"stop":{"native":"Stop","block_exit":null,"answered_at":"2026-09-29"},"pre_tool_use":{"native":"PreToolUse","block_exit":null,"answered_at":"2026-09-29"},"post_tool_use":{"native":"PostToolUse","block_exit":null,"answered_at":"2026-09-29"}}}}},"cursor":{"surfaces":{"any":{"entry_shape":"cursor-hooks-json","json_shape":"none","fail_policy":"propagate","timeout_unit":"unknown","timeout_default":null,"verified":{"docs_at":"2026-09-29","docs_url":"https://cursor.com/docs/hooks.md","docs_digest":"7294a2d63b19d79a5283c948afe174cba8b06a7585563d34a2c41b90f5df0d39","probe_at":null,"host_version":null,"expires":"2027-09-29"},"slots":{"session_start":{"native":"sessionStart","block_exit":null,"answered_at":"2026-09-29"},"session_end":{"native":"sessionEnd","block_exit":null,"answered_at":"2026-09-29"},"stop":{"native":"stop","block_exit":null,"answered_at":"2026-09-29"},"user_prompt_submit":{"native":"beforeSubmitPrompt","block_exit":null,"answered_at":"2026-09-29"},"post_tool_use":{"native":"postToolUse","block_exit":null,"answered_at":"2026-09-29"}}}}},"cline":{"surfaces":{"any":{"entry_shape":"cline-per-event-script","json_shape":"none","fail_policy":"discard","timeout_unit":"unknown","timeout_default":null,"verified":{"docs_at":"2026-09-29","docs_url":"https://docs.cline.bot/customization/hooks.md","docs_digest":"ef87561721f4cb80fe6d682b6866d638a4952dd416d36cd5ab398426ce64084b","probe_at":null,"host_version":null,"expires":"2027-09-29"},"slots":{"session_start":{"native":["TaskStart","TaskResume"],"block_exit":null,"answered_at":"2026-09-29"},"session_end":{"native":"TaskComplete","block_exit":null,"answered_at":"2026-09-29"},"stop":{"native":"TaskCancel","block_exit":null,"answered_at":"2026-09-29"},"user_prompt_submit":{"native":"UserPromptSubmit","block_exit":null,"answered_at":"2026-09-29"},"post_tool_use":{"native":"PostToolUse","block_exit":null,"answered_at":"2026-09-29"}}}}},"windsurf":{"surfaces":{"any":{"entry_shape":"windsurf-hooks-json","json_shape":"none","fail_policy":"propagate","timeout_unit":"unknown","timeout_default":null,"verified":{"docs_at":"2026-09-29","docs_url":"https://docs.devin.ai/desktop/cascade/hooks.md","docs_digest":"460ffe7aa91998804920f6722c0153b9948eadd5edafa19582298475a19835a2","probe_at":null,"host_version":null,"expires":"2027-09-29"},"slots":{"session_start":{"native":"post_setup_worktree","block_exit":null,"answered_at":"2026-09-29"},"user_prompt_submit":{"native":"pre_user_prompt","block_exit":null,"answered_at":"2026-09-29"},"stop":{"native":"post_cascade_response","block_exit":null,"answered_at":"2026-09-29"}}}}},"gemini":{"surfaces":{"any":{"entry_shape":"gemini-settings-hooks","json_shape":"none","fail_policy":"propagate","timeout_unit":"unknown","timeout_default":null,"verified":{"docs_at":"2026-09-29","docs_url":"https://geminicli.com/docs/hooks/reference.md","docs_digest":"06d37f2f66812ee78bb46c37a112203376f0bae4d3b8b44ac79d0bda4b86a118","probe_at":null,"host_version":null,"expires":"2027-09-29"},"slots":{"session_start":{"native":"SessionStart","block_exit":null,"answered_at":"2026-09-29","matcher":""},"session_end":{"native":"SessionEnd","block_exit":null,"answered_at":"2026-09-29","matcher":""},"stop":{"native":"AfterAgent","block_exit":null,"answered_at":"2026-09-29","matcher":""},"user_prompt_submit":{"native":"BeforeAgent","block_exit":null,"answered_at":"2026-09-29","matcher":""},"post_tool_use":{"native":"AfterTool","block_exit":null,"answered_at":"2026-09-29","matcher":".*"}}}}},"cowork":{"surfaces":{"any":{"entry_shape":"none","json_shape":"none","fail_policy":"discard","timeout_unit":"unknown","timeout_default":null,"verified":{"docs_at":"2026-09-29","docs_url":null,"docs_digest":null,"probe_at":null,"host_version":null,"expires":"2027-09-29"},"slots":{}}}},"copilot":{"surfaces":{"any":{"entry_shape":"none","json_shape":"none","fail_policy":"discard","timeout_unit":"unknown","timeout_default":null,"verified":{"docs_at":"2026-09-29","docs_url":"https://docs.github.com/en/copilot/concepts/agents/hooks.md","docs_digest":"bfd40aa93ad62133efc17a50f189034f01594dc89a5d31a13a0c541d691acede","probe_at":null,"host_version":null,"expires":"2027-09-29"},"slots":{}}}},"codex":{"surfaces":{"any":{"entry_shape":"none","json_shape":"none","fail_policy":"discard","timeout_unit":"unknown","timeout_default":null,"verified":{"docs_at":"2026-09-29","docs_url":"https://developers.openai.com/codex/hooks.md","docs_digest":"724881d81f1a9fdb35ea42d4851a11b1f6606bbc6e9d2d05c1e8c466fc25c630","probe_at":"2026-10-01","host_version":"0.148.0","expires":"2027-09-29"},"slots":{}}}}}}}
1
+ {"fingerprint":"08575a71d81fd8a5ef9e4b400f4a38cb66c26e1dd701d98f3cdc0bdc9e4758b4:22235","body_fingerprint":"26a02a8e0fb2b6be6eb1def6ae8792c021425598bd672c850e6582726d96a6a5:6376","table":{"schema_version":1,"hosts":{"claude":{"surfaces":{"any":{"entry_shape":"claude-settings-hooks","json_shape":"hook-specific-output","fail_policy":"propagate","timeout_unit":"seconds","timeout_default":null,"verified":{"docs_at":"2026-09-29","docs_url":"https://code.claude.com/docs/en/hooks.md","docs_digest":"9dd68316c1111c118e3ddb82861ac6271a8cd164cee0d371b26165efff35fe88","probe_at":"2026-09-06","host_version":"2.1.263","expires":"2027-09-06"},"slots":{"session_start":{"native":"SessionStart","block_exit":null,"answered_at":"2026-09-29"},"session_end":{"native":"SessionEnd","block_exit":null,"answered_at":"2026-09-29"},"stop":{"native":"Stop","block_exit":2,"answered_at":"2026-09-29"},"user_prompt_submit":{"native":"UserPromptSubmit","block_exit":2,"answered_at":"2026-09-29"},"pre_tool_use":{"native":"PreToolUse","block_exit":2,"answered_at":"2026-09-29"},"post_tool_use":{"native":"PostToolUse","block_exit":null,"answered_at":"2026-09-29"},"pre_compact":{"native":"PreCompact","block_exit":null,"answered_at":"2026-09-29"},"subagent_start":{"native":"SubagentStart","block_exit":null,"answered_at":"2026-09-29"},"subagent_stop":{"native":"SubagentStop","block_exit":null,"answered_at":"2026-09-29"}}}}},"augment":{"surfaces":{"any":{"entry_shape":"augment-settings-hooks","json_shape":"none","fail_policy":"discard","timeout_unit":"unknown","timeout_default":null,"verified":{"docs_at":"2026-09-29","docs_url":"https://docs.augmentcode.com/cli/hooks.md","docs_digest":"e500823be8303717020c1823f670e06d100108f6e3ac4b8d12a46d91fd1898fa","probe_at":null,"host_version":null,"expires":"2027-09-29"},"slots":{"session_start":{"native":"SessionStart","block_exit":null,"answered_at":"2026-09-29"},"session_end":{"native":"SessionEnd","block_exit":null,"answered_at":"2026-09-29"},"stop":{"native":"Stop","block_exit":null,"answered_at":"2026-09-29"},"pre_tool_use":{"native":"PreToolUse","block_exit":null,"answered_at":"2026-09-29"},"post_tool_use":{"native":"PostToolUse","block_exit":null,"answered_at":"2026-09-29"}}}}},"cursor":{"surfaces":{"any":{"entry_shape":"cursor-hooks-json","json_shape":"none","fail_policy":"propagate","timeout_unit":"unknown","timeout_default":null,"verified":{"docs_at":"2026-09-29","docs_url":"https://cursor.com/docs/hooks.md","docs_digest":"7294a2d63b19d79a5283c948afe174cba8b06a7585563d34a2c41b90f5df0d39","probe_at":null,"host_version":null,"expires":"2027-09-29"},"slots":{"session_start":{"native":"sessionStart","block_exit":null,"answered_at":"2026-09-29"},"session_end":{"native":"sessionEnd","block_exit":null,"answered_at":"2026-09-29"},"stop":{"native":"stop","block_exit":null,"answered_at":"2026-09-29"},"user_prompt_submit":{"native":"beforeSubmitPrompt","block_exit":null,"answered_at":"2026-09-29"},"post_tool_use":{"native":"postToolUse","block_exit":null,"answered_at":"2026-09-29"}}}}},"cline":{"surfaces":{"any":{"entry_shape":"cline-per-event-script","json_shape":"none","fail_policy":"discard","timeout_unit":"unknown","timeout_default":null,"verified":{"docs_at":"2026-09-29","docs_url":"https://docs.cline.bot/customization/hooks.md","docs_digest":"ef87561721f4cb80fe6d682b6866d638a4952dd416d36cd5ab398426ce64084b","probe_at":null,"host_version":null,"expires":"2027-09-29"},"slots":{"session_start":{"native":["TaskStart","TaskResume"],"block_exit":null,"answered_at":"2026-09-29"},"session_end":{"native":"TaskComplete","block_exit":null,"answered_at":"2026-09-29"},"stop":{"native":"TaskCancel","block_exit":null,"answered_at":"2026-09-29"},"user_prompt_submit":{"native":"UserPromptSubmit","block_exit":null,"answered_at":"2026-09-29"},"post_tool_use":{"native":"PostToolUse","block_exit":null,"answered_at":"2026-09-29"}}}}},"windsurf":{"surfaces":{"any":{"entry_shape":"windsurf-hooks-json","json_shape":"none","fail_policy":"propagate","timeout_unit":"unknown","timeout_default":null,"verified":{"docs_at":"2026-09-29","docs_url":"https://docs.devin.ai/desktop/cascade/hooks.md","docs_digest":"460ffe7aa91998804920f6722c0153b9948eadd5edafa19582298475a19835a2","probe_at":null,"host_version":null,"expires":"2027-09-29"},"slots":{"session_start":{"native":"post_setup_worktree","block_exit":null,"answered_at":"2026-09-29"},"user_prompt_submit":{"native":"pre_user_prompt","block_exit":null,"answered_at":"2026-09-29"},"stop":{"native":"post_cascade_response","block_exit":null,"answered_at":"2026-09-29"}}}}},"gemini":{"surfaces":{"any":{"entry_shape":"gemini-settings-hooks","json_shape":"none","fail_policy":"propagate","timeout_unit":"unknown","timeout_default":null,"verified":{"docs_at":"2026-09-29","docs_url":"https://geminicli.com/docs/hooks/reference.md","docs_digest":"06d37f2f66812ee78bb46c37a112203376f0bae4d3b8b44ac79d0bda4b86a118","probe_at":null,"host_version":null,"expires":"2027-09-29"},"slots":{"session_start":{"native":"SessionStart","block_exit":null,"answered_at":"2026-09-29","matcher":""},"session_end":{"native":"SessionEnd","block_exit":null,"answered_at":"2026-09-29","matcher":""},"stop":{"native":"AfterAgent","block_exit":null,"answered_at":"2026-09-29","matcher":""},"user_prompt_submit":{"native":"BeforeAgent","block_exit":null,"answered_at":"2026-09-29","matcher":""},"post_tool_use":{"native":"AfterTool","block_exit":null,"answered_at":"2026-09-29","matcher":".*"}}}}},"cowork":{"surfaces":{"any":{"entry_shape":"none","json_shape":"none","fail_policy":"discard","timeout_unit":"unknown","timeout_default":null,"verified":{"docs_at":"2026-09-29","docs_url":null,"docs_digest":null,"probe_at":null,"host_version":null,"expires":"2027-09-29"},"slots":{}}}},"copilot":{"surfaces":{"any":{"entry_shape":"none","json_shape":"none","fail_policy":"discard","timeout_unit":"unknown","timeout_default":null,"verified":{"docs_at":"2026-09-29","docs_url":"https://docs.github.com/en/copilot/concepts/agents/hooks.md","docs_digest":"bfd40aa93ad62133efc17a50f189034f01594dc89a5d31a13a0c541d691acede","probe_at":null,"host_version":null,"expires":"2027-09-29"},"slots":{}}}},"codex":{"surfaces":{"any":{"entry_shape":"none","json_shape":"none","fail_policy":"discard","timeout_unit":"unknown","timeout_default":null,"verified":{"docs_at":"2026-09-29","docs_url":"https://developers.openai.com/codex/hooks.md","docs_digest":"724881d81f1a9fdb35ea42d4851a11b1f6606bbc6e9d2d05c1e8c466fc25c630","probe_at":"2026-10-01","host_version":"0.148.0","expires":"2027-09-29"},"slots":{}}}}}}}
@@ -251,7 +251,25 @@ export function resolveTable(yamlText: string, compiledText: string | null): Hos
251
251
  if (
252
252
  raw['fingerprint'] === tableFingerprint(yamlText) &&
253
253
  typeof table === 'object' &&
254
- table !== null
254
+ table !== null &&
255
+ // road-to-blocking-severities 2.3 — the BODY, not only its
256
+ // label. `fingerprint` above says the file was compiled from
257
+ // the YAML as it stands; it says nothing about whether the
258
+ // body underneath was edited afterwards, and an edited body
259
+ // with an untouched label was served. `body_fingerprint` is
260
+ // the fingerprint of the exact bytes the compiler emitted, so
261
+ // re-stringifying what we just parsed recovers them.
262
+ //
263
+ // A compiled file WITHOUT the field — one written before 2.3 —
264
+ // falls through here, which is slow and correct: accepting it
265
+ // would make the check optional and therefore absent.
266
+ //
267
+ // What it covers is a partial edit, never an author: anyone
268
+ // who edits the body can recompute this as easily as the
269
+ // compiler. The deny in `block_plumbing_writes` and the
270
+ // ratification record are the mechanisms aimed at an author;
271
+ // this one is aimed at a mistake.
272
+ raw['body_fingerprint'] === tableFingerprint(JSON.stringify(table))
255
273
  ) {
256
274
  return _structure(table as Record<string, unknown>);
257
275
  }