@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,165 @@
1
+ #!/usr/bin/env tsx
2
+ /**
3
+ * Reports an acceptance criterion ticked over its own "NOT met".
4
+ *
5
+ * A `- [x] AC-<n>` item whose own text says a half of it `is NOT met` is a
6
+ * contradiction a reader of the checkbox never sees: the glyph says done, the
7
+ * prose says not. The honest glyph is `[~]`, which carries the unmet half as a
8
+ * deferral rather than hiding it under a tick.
9
+ *
10
+ * The criterion's text is the bullet line plus its indented continuation lines,
11
+ * up to a blank line, a less-indented line or the next checkbox. Fenced code is
12
+ * skipped, so a quoted example is not a finding. The match is the literal
13
+ * `NOT met` — upper-case on purpose, because that is how an author marks the
14
+ * unmet half, and a lower-case "not met" inside an explanation is prose.
15
+ *
16
+ * Usage:
17
+ * ./scripts-run src/scripts/lint_ticked_unmet_criteria
18
+ * ./scripts-run src/scripts/lint_ticked_unmet_criteria --root <repo>
19
+ *
20
+ * Scans every `*.md` under the roadmap tree, archive included: an archived
21
+ * roadmap is exactly where a contradictory tick outlives the session that
22
+ * made it.
23
+ *
24
+ * Exit codes: 0 no hit · 1 at least one hit · 2 usage error.
25
+ */
26
+ import * as fs from 'node:fs';
27
+ import * as path from 'node:path';
28
+ import { fileURLToPath, pathToFileURL } from 'node:url';
29
+
30
+ import { reportScanned } from './_lib/scan_scope.js';
31
+
32
+ interface Hit {
33
+ file: string;
34
+ line: number;
35
+ criterion: string;
36
+ }
37
+
38
+ const TICKED_AC_RE = /^([ \t]*)[-*][ \t]+\[[xX]\][ \t]+(AC-[\w.-]+)/;
39
+ const CHECKBOX_RE = /^[ \t]*[-*][ \t]+\[[ xX~-]\]/;
40
+ const FENCE_RE = /^[ \t]*(```|~~~)/;
41
+ const UNMET = 'NOT met';
42
+
43
+ function _indent(line: string): number {
44
+ return (/^[ \t]*/.exec(line)?.[0] ?? '').length;
45
+ }
46
+
47
+ function scanText(text: string, file: string): Hit[] {
48
+ const lines = text.split('\n');
49
+ const hits: Hit[] = [];
50
+ let inFence = false;
51
+ for (let i = 0; i < lines.length; i += 1) {
52
+ const line = lines[i] as string;
53
+ if (FENCE_RE.test(line)) {
54
+ inFence = !inFence;
55
+ continue;
56
+ }
57
+ if (inFence) {
58
+ continue;
59
+ }
60
+ const m = TICKED_AC_RE.exec(line);
61
+ if (!m) {
62
+ continue;
63
+ }
64
+ const base = (m[1] as string).length;
65
+ const block = [line];
66
+ for (let j = i + 1; j < lines.length; j += 1) {
67
+ const next = lines[j] as string;
68
+ if (next.trim() === '' || CHECKBOX_RE.test(next) || FENCE_RE.test(next) || _indent(next) <= base) {
69
+ break;
70
+ }
71
+ block.push(next);
72
+ }
73
+ if (block.join('\n').includes(UNMET)) {
74
+ hits.push({ file, line: i + 1, criterion: m[2] as string });
75
+ }
76
+ }
77
+ return hits;
78
+ }
79
+
80
+ function _walk(dir: string): string[] {
81
+ let entries: fs.Dirent[];
82
+ try {
83
+ entries = fs.readdirSync(dir, { withFileTypes: true });
84
+ } catch {
85
+ return [];
86
+ }
87
+ const out: string[] = [];
88
+ for (const e of entries.sort((a, b) => a.name.localeCompare(b.name))) {
89
+ const full = path.join(dir, e.name);
90
+ if (e.isDirectory()) {
91
+ out.push(..._walk(full));
92
+ } else if (e.isFile() && e.name.endsWith('.md')) {
93
+ out.push(full);
94
+ }
95
+ }
96
+ return out;
97
+ }
98
+
99
+ function scanTree(root: string): { hits: Hit[]; scanned: number } {
100
+ const files = _walk(path.join(root, 'agents', 'roadmaps'));
101
+ const hits: Hit[] = [];
102
+ for (const abs of files) {
103
+ const rel = path.relative(root, abs).split(path.sep).join('/');
104
+ hits.push(...scanText(fs.readFileSync(abs, 'utf8'), rel));
105
+ }
106
+ return { hits, scanned: files.length };
107
+ }
108
+
109
+ const _DEFAULT_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', '..');
110
+
111
+ function main(argv: string[] = process.argv.slice(2)): number {
112
+ let root = _DEFAULT_ROOT;
113
+ for (let i = 0; i < argv.length; i += 1) {
114
+ const arg = argv[i];
115
+ if (arg === '--root') {
116
+ const v = argv[i + 1];
117
+ if (v === undefined) {
118
+ process.stderr.write('lint_ticked_unmet_criteria: --root requires a value\n');
119
+ return 2;
120
+ }
121
+ root = path.resolve(v);
122
+ i += 1;
123
+ } else {
124
+ process.stderr.write(`lint_ticked_unmet_criteria: unknown argument: ${String(arg)}\n`);
125
+ return 2;
126
+ }
127
+ }
128
+ const { hits, scanned } = scanTree(root);
129
+ reportScanned({
130
+ gate: 'lint_ticked_unmet_criteria',
131
+ scanned,
132
+ units: 'roadmap file(s)',
133
+ roots: ['agents/roadmaps'],
134
+ allowEmpty: 'EMPTY_VALID: a checkout with no roadmap has no criterion to tick',
135
+ });
136
+ if (hits.length === 0) {
137
+ process.stdout.write(`✅ lint_ticked_unmet_criteria: ${String(scanned)} roadmap file(s), no criterion ticked over "${UNMET}".\n`);
138
+ return 0;
139
+ }
140
+ process.stderr.write(
141
+ `❌ lint_ticked_unmet_criteria: ${String(hits.length)} criterion/criteria ticked [x] over their own "${UNMET}":\n`,
142
+ );
143
+ for (const h of hits) {
144
+ process.stderr.write(` ${h.file}:${String(h.line)} · ${h.criterion}\n`);
145
+ }
146
+ process.stderr.write('\n The unmet half is a deferral: use `[~]` and carry it, or meet it.\n');
147
+ return 1;
148
+ }
149
+
150
+ if (process.argv[1] !== undefined) {
151
+ try {
152
+ const here = fs.realpathSync(fileURLToPath(import.meta.url));
153
+ const argv1 = fs.realpathSync(path.resolve(process.argv[1]));
154
+ if (here === argv1) {
155
+ process.exit(main());
156
+ }
157
+ } catch {
158
+ if (import.meta.url === pathToFileURL(path.resolve(process.argv[1])).href) {
159
+ process.exit(main());
160
+ }
161
+ }
162
+ }
163
+
164
+ export { scanText, scanTree, main };
165
+ export type { Hit };
@@ -28,6 +28,9 @@
28
28
  * TIERS are untouched; only the description of what MEDIUM covers now matches
29
29
  * the code. Re-tiering the locked model is a separate decision, recorded as
30
30
  * unresolved in agents/evidence/analysis/workflow-security-net-degraded-decision.md.
31
+ * The CI INVOCATION is decided there too: since 2026-10-07 consistency.yml runs
32
+ * this gate under `--strict` (AI council, 2/2), so a HIGH fails a pull request;
33
+ * the tiers are unchanged.
31
34
  *
32
35
  * Script-injection detection (regex-based) is intentionally deferred — it
33
36
  * requires an AST-aware pass to avoid false positives on quoted / escaped
@@ -35,12 +38,14 @@
35
38
  */
36
39
 
37
40
  import * as fs from 'node:fs';
41
+ import * as os from 'node:os';
38
42
  import * as path from 'node:path';
39
43
  import { fileURLToPath, pathToFileURL } from 'node:url';
40
44
 
41
45
  import YAML from 'yaml';
42
46
 
43
- import { assertScanned, DeadScopeError } from './_lib/scan_scope.js';
47
+ import { runGateCli, runSelfTest } from './_lib/gate_self_test.js';
48
+ import { DeadScopeError, reportScanned } from './_lib/scan_scope.js';
44
49
  import { py_json_dumps_indent2 } from './_lib/security_lint.js';
45
50
 
46
51
  const _HERE = fileURLToPath(import.meta.url);
@@ -48,8 +53,16 @@ const _HERE = fileURLToPath(import.meta.url);
48
53
  const REPO_ROOT = path.resolve(path.dirname(_HERE), '..', '..');
49
54
  // Mutable bindings so tests can sandbox the scan target (mirrors the pytest
50
55
  // monkeypatch.setattr seam used by sibling lint twins).
51
- let WORKFLOWS_DIR = path.join(REPO_ROOT, '.github', 'workflows');
52
- let ALLOWLIST_PATH = path.join(path.dirname(_HERE), 'lint_workflow_security_allowlist.json');
56
+ //
57
+ // `--self-test` needs the same sandbox from a CHILD process, which cannot reach
58
+ // the in-process seam, so the two paths are also readable from the environment.
59
+ // Deliberately env and not argv: the CLI surface is pinned (argparse flags,
60
+ // byte-identical usage lines, unknown arg → exit 2), and a scan root is not
61
+ // something a caller should be able to redirect by typing a flag.
62
+ let WORKFLOWS_DIR = process.env['LINT_WORKFLOW_SECURITY_DIR'] ?? path.join(REPO_ROOT, '.github', 'workflows');
63
+ let ALLOWLIST_PATH =
64
+ process.env['LINT_WORKFLOW_SECURITY_ALLOWLIST'] ??
65
+ path.join(path.dirname(_HERE), 'lint_workflow_security_allowlist.json');
53
66
  const ALLOWLIST_CAP = 20;
54
67
 
55
68
  function _setWorkflowsDirForTest(p: string): void {
@@ -577,8 +590,147 @@ function _usageError(arg: string): string {
577
590
  );
578
591
  }
579
592
 
593
+ /**
594
+ * Prove, on demand, that the gate's rejections still fire.
595
+ *
596
+ * The CI invocation is warn-only, so the exit code `runSelfTest` reads cannot be
597
+ * moved by a finding there. The cases below therefore drive the two exits the
598
+ * gate really has — 2 for a dead scan scope or an over-cap allowlist, 1 for a
599
+ * HIGH under `--strict` — and pin the warn-only tier itself from the other side:
600
+ * a MEDIUM under `--strict` must still PASS, which is the direction a future
601
+ * re-tiering would silently break.
602
+ */
603
+ function selfTest(): number {
604
+ const plant = (name: string, files: Record<string, string>): string => {
605
+ const dir = fs.mkdtempSync(path.join(os.tmpdir(), `lws-selftest-${name}-`));
606
+ for (const [rel, body] of Object.entries(files)) {
607
+ fs.writeFileSync(path.join(dir, rel), body, 'utf-8');
608
+ }
609
+ return dir;
610
+ };
611
+ const allowlistFile = (entries: unknown[]): string => {
612
+ const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'lws-selftest-al-'));
613
+ const p = path.join(dir, 'allowlist.json');
614
+ fs.writeFileSync(p, JSON.stringify({ findings: entries }), 'utf-8');
615
+ return p;
616
+ };
617
+ const run = (wfDir: string, args: readonly string[], allowlist?: string): number => {
618
+ const prevDir = process.env['LINT_WORKFLOW_SECURITY_DIR'];
619
+ const prevAl = process.env['LINT_WORKFLOW_SECURITY_ALLOWLIST'];
620
+ process.env['LINT_WORKFLOW_SECURITY_DIR'] = wfDir;
621
+ if (allowlist !== undefined) {
622
+ process.env['LINT_WORKFLOW_SECURITY_ALLOWLIST'] = allowlist;
623
+ }
624
+ try {
625
+ return runGateCli(
626
+ REPO_ROOT,
627
+ path.join('src', 'scripts', 'lint_workflow_security.ts'),
628
+ args,
629
+ REPO_ROOT,
630
+ );
631
+ } finally {
632
+ if (prevDir === undefined) {
633
+ delete process.env['LINT_WORKFLOW_SECURITY_DIR'];
634
+ } else {
635
+ process.env['LINT_WORKFLOW_SECURITY_DIR'] = prevDir;
636
+ }
637
+ if (prevAl === undefined) {
638
+ delete process.env['LINT_WORKFLOW_SECURITY_ALLOWLIST'];
639
+ } else {
640
+ process.env['LINT_WORKFLOW_SECURITY_ALLOWLIST'] = prevAl;
641
+ }
642
+ }
643
+ };
644
+
645
+ const HIGH_WF = [
646
+ 'on:',
647
+ ' pull_request_target:',
648
+ 'jobs:',
649
+ ' build:',
650
+ ' steps:',
651
+ ' - uses: actions/checkout@0000000000000000000000000000000000000000',
652
+ ' with:',
653
+ ' persist-credentials: false',
654
+ ' ref: ${{ github.event.pull_request.head.sha }}',
655
+ '',
656
+ ].join('\n');
657
+ // Unpinned third-party action — MEDIUM, and MEDIUM alone.
658
+ const MEDIUM_WF = [
659
+ 'on:',
660
+ ' push:',
661
+ 'jobs:',
662
+ ' build:',
663
+ ' steps:',
664
+ ' - uses: somevendor/action@v1',
665
+ '',
666
+ ].join('\n');
667
+ const CLEAN_WF = [
668
+ 'on:',
669
+ ' push:',
670
+ 'jobs:',
671
+ ' build:',
672
+ ' steps:',
673
+ ' - uses: actions/checkout@0000000000000000000000000000000000000000',
674
+ ' with:',
675
+ ' persist-credentials: false',
676
+ ' - run: npm ci --ignore-scripts',
677
+ '',
678
+ ].join('\n');
679
+
680
+ return runSelfTest({
681
+ gate: 'lint_workflow_security',
682
+ minCases: 5,
683
+ minRejectCases: 3,
684
+ cases: [
685
+ {
686
+ name: 'an empty workflows directory is refused, not certified "0 HIGH, 0 MEDIUM"',
687
+ expect: 'reject',
688
+ run: () => run(plant('empty', {}), []),
689
+ },
690
+ {
691
+ name: 'a pull_request_target checkout of the untrusted ref fails under --strict',
692
+ expect: 'reject',
693
+ run: () => run(plant('high', { 'bad.yml': HIGH_WF }), ['--strict']),
694
+ },
695
+ {
696
+ name: 'an over-cap allowlist fails rather than suppressing silently',
697
+ expect: 'reject',
698
+ run: () =>
699
+ run(
700
+ plant('cap', { 'ok.yml': CLEAN_WF }),
701
+ [],
702
+ allowlistFile(
703
+ Array.from({ length: ALLOWLIST_CAP + 1 }, (_, n) => ({
704
+ workflow: `w${String(n)}.yml`,
705
+ rule: 'unpinned-action',
706
+ })),
707
+ ),
708
+ ),
709
+ },
710
+ {
711
+ name: 'a MEDIUM under --strict still PASSES — the tier split is real, not decorative',
712
+ expect: 'accept',
713
+ run: () => run(plant('medium', { 'med.yml': MEDIUM_WF }), ['--strict']),
714
+ },
715
+ {
716
+ name: 'a clean workflow passes under --strict',
717
+ expect: 'accept',
718
+ run: () => run(plant('clean', { 'ok.yml': CLEAN_WF }), ['--strict']),
719
+ },
720
+ ],
721
+ });
722
+ }
723
+
580
724
  export function main(argv?: string[]): number {
581
- const parsed = _parseArgs(argv ?? process.argv.slice(2));
725
+ const rawArgv = argv ?? process.argv.slice(2);
726
+ if (rawArgv.includes('--self-test')) {
727
+ if (process.env['GATE_SELF_TEST_CHILD'] === '1') {
728
+ process.stderr.write('lint_workflow_security: --self-test does not recurse\n');
729
+ return 2;
730
+ }
731
+ return selfTest();
732
+ }
733
+ const parsed = _parseArgs(rawArgv);
582
734
  if (parsed.exitCode !== undefined) {
583
735
  return parsed.exitCode;
584
736
  }
@@ -600,7 +752,14 @@ export function main(argv?: string[]): number {
600
752
  const yml = _sortedGlob('.yml');
601
753
  const yaml = _sortedGlob('.yaml');
602
754
  try {
603
- assertScanned({
755
+ // `reportScanned`, not `assertScanned`: the gate now carries a floor in
756
+ // src/config/gate-coverage.yml, and the guard there reads the
757
+ // machine-readable `scanned:` line. Asserting without publishing leaves
758
+ // the gate invisible to the coverage guard — the half-adoption
759
+ // `_lib/scan_scope.reportScanned` was written to close. The line goes to
760
+ // stdout unconditionally, `--quiet` included, because CI passes
761
+ // `--quiet` and a count only visible without it is not a count.
762
+ reportScanned({
604
763
  gate: 'lint_workflow_security',
605
764
  scanned: yml.length + yaml.length,
606
765
  units: 'workflow file(s)',
@@ -649,7 +808,9 @@ export function main(argv?: string[]): number {
649
808
  );
650
809
  if (high.length || medium.length) {
651
810
  process.stdout.write(
652
- ' (warn-only — run with --strict to make HIGH findings block CI)\n',
811
+ args.strict
812
+ ? ' (--strict — HIGH findings fail this run; MEDIUM stays advisory)\n'
813
+ : ' (warn-only — run with --strict to make HIGH findings block CI)\n',
653
814
  );
654
815
  } else {
655
816
  process.stdout.write(' no non-allowlisted findings\n');
@@ -657,6 +818,12 @@ export function main(argv?: string[]): number {
657
818
  }
658
819
 
659
820
  if (args.strict && high.length) {
821
+ if (args.quiet) {
822
+ // --quiet suppresses the report; a failing run still names its cause.
823
+ process.stderr.write(
824
+ `workflow-security: ${high.length} HIGH under --strict — rerun without --quiet for the findings\n`,
825
+ );
826
+ }
660
827
  return 1;
661
828
  }
662
829
  return 0;
@@ -283,6 +283,59 @@
283
283
  "readOnlyHint": false
284
284
  }
285
285
  },
286
+ {
287
+ "name": "graph_node",
288
+ "description": "One symbol in full: where it is declared, what reaches it, what it reaches, and how connected it is. Resolves EXACTLY (node id, then label) and refuses anything it cannot — it never scores free text, so an answer is always about the node you named.",
289
+ "side_effect": "ro",
290
+ "implemented_on": [
291
+ "stdio"
292
+ ],
293
+ "input_schema": {
294
+ "type": "object",
295
+ "required": [
296
+ "id"
297
+ ],
298
+ "properties": {
299
+ "id": {
300
+ "type": "string",
301
+ "description": "Node id `<relpath>#<sym>` or an exact label."
302
+ },
303
+ "direction": {
304
+ "type": "string",
305
+ "enum": [
306
+ "in",
307
+ "out",
308
+ "both"
309
+ ],
310
+ "default": "both",
311
+ "description": "Which edges to walk. `in` = who reaches it, `out` = what it reaches."
312
+ },
313
+ "depth": {
314
+ "type": "integer",
315
+ "minimum": 1,
316
+ "maximum": 3,
317
+ "default": 1,
318
+ "description": "Hop limit."
319
+ },
320
+ "relation": {
321
+ "type": "string",
322
+ "enum": [
323
+ "calls",
324
+ "imports",
325
+ "uses",
326
+ "inherits",
327
+ "member",
328
+ "tests"
329
+ ],
330
+ "description": "Restrict to one relation. Omit for all of them."
331
+ }
332
+ },
333
+ "additionalProperties": false
334
+ },
335
+ "annotations": {
336
+ "readOnlyHint": true
337
+ }
338
+ },
286
339
  {
287
340
  "name": "graph_path",
288
341
  "description": "The shortest relation chain between two symbols, direction preserved. Answers \"how does A reach B\" without reading the files between. `(no path found)` when unconnected is an answer.",
@@ -1,7 +1,13 @@
1
1
  /**
2
- * The five code-graph MCP tools (`road-to-a-graph-that-is-shipped` 4.1).
2
+ * The code-graph MCP tools (`road-to-a-graph-that-is-shipped` 4.1).
3
+ *
4
+ * `graph_impact`, `graph_tests_for`, `graph_dead`, `graph_query`, `graph_path`
5
+ * — and `graph_node`, added by `road-to-a-graph-that-feeds-the-gate` 3.1. The
6
+ * first five all answer about a NEIGHBOURHOOD or a SET; none answered "where
7
+ * does this live, who reaches it, what does it reach, how connected is it",
8
+ * which is the question an agent asks first and had to assemble from two calls
9
+ * and a file read.
3
10
  *
4
- * `graph_impact`, `graph_tests_for`, `graph_dead`, `graph_query`, `graph_path`.
5
11
  * They are the agent-facing half of Phase 3: the verbs exist on the CLI and an
6
12
  * agent that has to shell out to reach them will not, so the engine's answers
7
13
  * were unreachable from the surface the consumer actually talks to. Risk-Register
@@ -39,7 +45,15 @@ import { changedFiles } from '../code_graph/cli.js';
39
45
  import { detectSources, graphState, NATIVE_CACHE_REL, pickSource } from '../code_graph/detect.js';
40
46
  import { resolvePath } from './path_util.js';
41
47
  import { isTestFile } from '../code_graph/build.js';
42
- import { loadGraph, type LoadedGraph, path as graphPathVerb, query as graphQueryVerb } from '../code_graph/query.js';
48
+ import {
49
+ loadGraph,
50
+ type LoadedGraph,
51
+ node as graphNodeVerb,
52
+ type NodeOptions,
53
+ path as graphPathVerb,
54
+ query as graphQueryVerb,
55
+ } from '../code_graph/query.js';
56
+ import type { Relation } from '../code_graph/types.js';
43
57
  import {
44
58
  dead,
45
59
  entryPointsFromFile,
@@ -97,6 +111,16 @@ function str(args: Record<string, unknown>, key: string): string {
97
111
  return typeof v === 'string' ? v.trim() : '';
98
112
  }
99
113
 
114
+ /**
115
+ * The closed relation vocabulary, as a schema enum.
116
+ *
117
+ * Spelled out rather than derived from the `Relation` union, which erases at
118
+ * compile time — and pinned by a test against that union so the two cannot
119
+ * drift. An enum that silently lost a value would turn a legal filter into a
120
+ * rejected argument.
121
+ */
122
+ const RELATIONS = ['calls', 'imports', 'uses', 'inherits', 'member', 'tests'] as const;
123
+
100
124
  function num(args: Record<string, unknown>, key: string, dflt: number): number {
101
125
  const v = args[key];
102
126
  return typeof v === 'number' && Number.isFinite(v) && v > 0 ? v : dflt;
@@ -263,6 +287,51 @@ export const GRAPH_TOOLS: Record<string, BuiltinTool> = {
263
287
  },
264
288
  },
265
289
 
290
+ graph_node: {
291
+ name: 'graph_node',
292
+ side_effect: 'ro',
293
+ description:
294
+ 'One symbol in full: where it is declared, what reaches it, what it ' +
295
+ 'reaches, and how connected it is. Resolves EXACTLY (node id, then ' +
296
+ 'label) and refuses anything it cannot — it never scores free text, ' +
297
+ 'so an answer is always about the node you named.',
298
+ input_schema: {
299
+ type: 'object',
300
+ required: ['id'],
301
+ properties: {
302
+ id: { type: 'string', description: 'Node id `<relpath>#<sym>` or an exact label.' },
303
+ direction: {
304
+ type: 'string',
305
+ enum: ['in', 'out', 'both'],
306
+ default: 'both',
307
+ description: 'Which edges to walk. `in` = who reaches it, `out` = what it reaches.',
308
+ },
309
+ depth: { type: 'integer', minimum: 1, maximum: 3, default: 1, description: 'Hop limit.' },
310
+ relation: {
311
+ type: 'string',
312
+ enum: RELATIONS,
313
+ description: 'Restrict to one relation. Omit for all of them.',
314
+ },
315
+ },
316
+ additionalProperties: false,
317
+ },
318
+ handler: async (args, root) => {
319
+ const id = str(args, 'id');
320
+ if (id === '') return { status: 'error', error: 'id must be a non-empty string' };
321
+ const staleness = graphState(root);
322
+ const opts: NodeOptions = {};
323
+ const dir = str(args, 'direction');
324
+ if (dir === 'in' || dir === 'out' || dir === 'both') opts.direction = dir;
325
+ // `num` clamps at >0 only; the 1-3 band is the verb's, so an
326
+ // out-of-band value is clamped there rather than rejected here —
327
+ // two places enforcing one band is how they drift apart.
328
+ opts.depth = num(args, 'depth', 1);
329
+ const rel = str(args, 'relation');
330
+ if ((RELATIONS as readonly string[]).includes(rel)) opts.relation = rel as Relation;
331
+ return withGraph(root, (g) => ({ staleness, ...graphNodeVerb(g, id, opts) }));
332
+ },
333
+ },
334
+
266
335
  graph_path: {
267
336
  name: 'graph_path',
268
337
  side_effect: 'ro',
@@ -117,6 +117,59 @@ export function mcnemarExactP(gained: number, lost: number): number {
117
117
 
118
118
  const pp = (hits: number, total: number): number => (total === 0 ? 0 : (hits / total) * 100);
119
119
 
120
+ /** The inputs the pre-registered verdict function reads, and nothing else. */
121
+ export interface VerdictInputs {
122
+ readonly deltaRecall: number;
123
+ readonly deltaFalse: number;
124
+ readonly p: number;
125
+ readonly gained: number;
126
+ readonly lost: number;
127
+ }
128
+
129
+ /**
130
+ * The pre-registered verdict function, in its pre-registered ORDER.
131
+ *
132
+ * Extracted from `measure` on 2026-10-04 so the order can be tested against
133
+ * chosen inputs rather than against whatever the live corpus happens to
134
+ * produce. The behaviour is unchanged, deliberately: this is a move, not a
135
+ * rewrite, and the bars it reads are the same module-level constants.
136
+ *
137
+ * WHY IT HAD TO MOVE. The order is load-bearing — power floor, then guard,
138
+ * then primary — and the only thing pinning it was a test asserting that the
139
+ * LIVE run happened to be a case that discriminates: primary met AND guard
140
+ * breached, so a function checking the primary first would wrongly say
141
+ * `signal`. That witness is a property of the corpus, not of the code, and the
142
+ * corpus grows whenever a skill gains a trigger file. On 2026-10-04 one such
143
+ * growth moved delta-recall from 5.128 to 4.608 and the witness was gone,
144
+ * leaving the ordering guarded by nothing. Tested here against chosen inputs,
145
+ * the discriminating case is always available and no future corpus growth can
146
+ * take it away.
147
+ */
148
+ export function verdictOf(i: VerdictInputs): { verdict: Verdict; reason: string } {
149
+ if (i.gained + i.lost < POWER_FLOOR_DISCORDANT) {
150
+ return {
151
+ verdict: 'underpowered',
152
+ reason: `${i.gained + i.lost} discordant positive pairs < power floor ${POWER_FLOOR_DISCORDANT}`,
153
+ };
154
+ }
155
+ if (i.deltaFalse > FALSE_ACTIVATION_GUARD_PP) {
156
+ return {
157
+ verdict: 'harmful',
158
+ reason: `false activation +${i.deltaFalse.toFixed(2)} pp breaches the +${FALSE_ACTIVATION_GUARD_PP.toFixed(1)} pp guard`,
159
+ };
160
+ }
161
+ if (i.deltaRecall >= RECALL_GAIN_BAR_PP && i.p < ALPHA) {
162
+ return {
163
+ verdict: 'signal',
164
+ reason: `recall +${i.deltaRecall.toFixed(2)} pp at p=${i.p.toExponential(2)}`,
165
+ };
166
+ }
167
+ return {
168
+ verdict: 'null',
169
+ reason: `recall +${i.deltaRecall.toFixed(2)} pp at p=${i.p.toExponential(2)} does not clear +${RECALL_GAIN_BAR_PP.toFixed(1)} pp and p<${ALPHA}`,
170
+ };
171
+ }
172
+
120
173
  export function measure(repo = REPO, k = K): Measurement {
121
174
  const catalogue: CatalogueEntry[] = loadCatalogue(repo);
122
175
  const cases: CorpusCase[] = loadTrainCases(repo);
@@ -170,22 +223,7 @@ export function measure(repo = REPO, k = K): Measurement {
170
223
  (falsePp['description+body'] as number) - (falsePp['description'] as number);
171
224
  const p = mcnemarExactP(gained, lost);
172
225
 
173
- // The pre-registered verdict function, in its pre-registered order.
174
- let verdict: Verdict;
175
- let reason: string;
176
- if (gained + lost < POWER_FLOOR_DISCORDANT) {
177
- verdict = 'underpowered';
178
- reason = `${gained + lost} discordant positive pairs < power floor ${POWER_FLOOR_DISCORDANT}`;
179
- } else if (deltaFalse > FALSE_ACTIVATION_GUARD_PP) {
180
- verdict = 'harmful';
181
- reason = `false activation +${deltaFalse.toFixed(2)} pp breaches the +${FALSE_ACTIVATION_GUARD_PP.toFixed(1)} pp guard`;
182
- } else if (deltaRecall >= RECALL_GAIN_BAR_PP && p < ALPHA) {
183
- verdict = 'signal';
184
- reason = `recall +${deltaRecall.toFixed(2)} pp at p=${p.toExponential(2)}`;
185
- } else {
186
- verdict = 'null';
187
- reason = `recall +${deltaRecall.toFixed(2)} pp at p=${p.toExponential(2)} does not clear +${RECALL_GAIN_BAR_PP.toFixed(1)} pp and p<${ALPHA}`;
188
- }
226
+ const { verdict, reason } = verdictOf({ deltaRecall, deltaFalse, p, gained, lost });
189
227
 
190
228
  return {
191
229
  k,