@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
@@ -71,6 +71,21 @@ function expanduser(p: string): string {
71
71
  return p;
72
72
  }
73
73
 
74
+ /**
75
+ * `expanduser`, against a STATED home rather than the process's own.
76
+ *
77
+ * `home` omitted or empty falls back to {@link expanduser}, so every existing
78
+ * caller is unchanged.
79
+ */
80
+ function expanduser_at(p: string, home?: string | null): string {
81
+ if (home === undefined || home === null || home === "") return expanduser(p);
82
+ if (p === "~") return home;
83
+ if (p.startsWith("~/") || (process.platform === "win32" && p.startsWith("~\\"))) {
84
+ return path.join(home, p.slice(2));
85
+ }
86
+ return p;
87
+ }
88
+
74
89
  /**
75
90
  * Resolve a path the way `Path.resolve()` does: expand-free `realpath`-style
76
91
  * resolution that follows existing symlinks and normalises `..`, but does not
@@ -658,6 +673,97 @@ function difference(prev: unknown[], current: Set<string>): unknown[] {
658
673
  return out;
659
674
  }
660
675
 
676
+ /**
677
+ * The anchor-relative paths a previous deploy of `tool_id` recorded.
678
+ *
679
+ * Empty whenever the inventory has no entry, the recorded anchor differs from
680
+ * `anchor`, or the entry is malformed — the same "not provably ours anymore"
681
+ * discipline `reap_stale` applies before it deletes anything. Callers use it
682
+ * to answer "did this package write that file" for a file the CURRENT run did
683
+ * not write.
684
+ */
685
+ export function recorded_rel_files(
686
+ tool_id: string,
687
+ anchor: string,
688
+ inventory?: Inventory | null,
689
+ ): ReadonlySet<string> {
690
+ const inv = inventory ?? load_inventory();
691
+ const tools = (inv["tools"] as Record<string, unknown> | undefined) ?? {};
692
+ const entry = tools[tool_id];
693
+ if (typeof entry !== "object" || entry === null || Array.isArray(entry)) {
694
+ return new Set<string>();
695
+ }
696
+ const e = entry as Record<string, unknown>;
697
+ const recorded_anchor = e["anchor"];
698
+ const files = e["files"];
699
+ if (typeof recorded_anchor !== "string" || !Array.isArray(files)) {
700
+ return new Set<string>();
701
+ }
702
+ if (resolve_path(expanduser(recorded_anchor)) !== resolve_path(expanduser(anchor))) {
703
+ return new Set<string>();
704
+ }
705
+ return new Set(files.filter((f): f is string => typeof f === "string"));
706
+ }
707
+
708
+ /**
709
+ * Every file a previous deploy recorded, as ABSOLUTE paths, across all tools.
710
+ *
711
+ * `recorded_rel_files` answers "did this package write that file" for one tool
712
+ * whose anchor the caller already knows. This answers the ownership question a
713
+ * READER has — the installed-layer report and the install receipt both walk
714
+ * host rule directories and hold absolute paths, with no tool id and no anchor
715
+ * in hand — so asking the inventory per tool would mean the reader guessing
716
+ * anchors it never recorded.
717
+ *
718
+ * `home` IS A PARAMETER, AND NOT A CONVENIENCE. The installer records the
719
+ * anchor TILDE-RELATIVE — the real inventory reads `"anchor": "~/.claude/"` —
720
+ * so the recorded path is only meaningful against a stated home. Expanding it
721
+ * against `os.homedir()` makes the answer depend on which process is asking,
722
+ * which is exactly how a reader measuring a staged install under a temporary
723
+ * HOME gets back a set naming the maintainer's own machine and claims nothing.
724
+ * Omitted, it falls back to `os.homedir()`, which is right for a caller asking
725
+ * about the install it is itself running under.
726
+ *
727
+ * BOTH SPELLINGS OF EVERY PATH ARE EMITTED — the symlink-resolved one and the
728
+ * merely-normalised one. Callers compare by set membership against a path they
729
+ * built with `path.join(dir, name)` while walking a directory, which is
730
+ * lexical; the inventory's anchor is resolved with `realpath` the way
731
+ * `recorded_rel_files` resolves its anchor comparison. On macOS those two
732
+ * differ for anything under `/var`, which realpaths to `/private/var`, and a
733
+ * one-spelling set silently claimed nothing there — the reader asked about
734
+ * `/var/...`, the set held `/private/var/...`, and every file read foreign.
735
+ * Emitting both is the cheap direction: a set is a membership test, so a second
736
+ * spelling can only make a true answer reachable, never a false one.
737
+ *
738
+ * A malformed tool entry contributes nothing rather than throwing: a corrupt
739
+ * inventory is "no evidence", never a finding, which is the same discipline
740
+ * `reap_stale` applies before it deletes anything.
741
+ */
742
+ export function recorded_absolute_files(
743
+ inventory?: Inventory | null,
744
+ home?: string | null,
745
+ ): ReadonlySet<string> {
746
+ const inv = inventory ?? load_inventory();
747
+ const tools = (inv["tools"] as Record<string, unknown> | undefined) ?? {};
748
+ const out = new Set<string>();
749
+ if (typeof tools !== "object" || tools === null || Array.isArray(tools)) return out;
750
+ for (const entry of Object.values(tools)) {
751
+ if (typeof entry !== "object" || entry === null || Array.isArray(entry)) continue;
752
+ const e = entry as Record<string, unknown>;
753
+ const anchor = e["anchor"];
754
+ const files = e["files"];
755
+ if (typeof anchor !== "string" || !Array.isArray(files)) continue;
756
+ const expanded = expanduser_at(anchor, home);
757
+ for (const rel of files) {
758
+ if (typeof rel !== "string") continue;
759
+ const lexical = path.resolve(expanded, rel);
760
+ out.add(lexical);
761
+ out.add(resolve_path(lexical));
762
+ }
763
+ }
764
+ return out;
765
+ }
766
+
661
767
  /** Sort string members ascending by codepoint (non-strings filtered out). */
662
768
  function sorted_strings(items: unknown[]): string[] {
663
769
  return items
@@ -0,0 +1,437 @@
1
+ /**
2
+ * The graph feeder record — detector F's verdict and the code graph's, side by
3
+ * side, on every stop where a graph existed (`road-to-a-graph-that-feeds-the-gate`
4
+ * step 3.2).
5
+ *
6
+ * WHY A SEPARATE RECORD AND NOT `ShadowRecord` (D3). `ShadowRecord` is written
7
+ * only on the `stop_hook_active` and `refused_turn` layers and is the Q1
8
+ * instrument of `road-to-a-stop-that-holds` — a live measurement window with its
9
+ * own denominator. Folding a second signal into it would contaminate a reading
10
+ * somebody else is taking, which is a worse failure than a second file.
11
+ *
12
+ * WHY IT CHANGES NO VERDICT, AND WHAT THAT CLAIM DOES NOT COVER. Every function
13
+ * here is wrapped, every failure path returns silently, and no caller branches on
14
+ * the result, so no in-process path can move an exit code. It is NOT a claim
15
+ * about latency, and an earlier version of this paragraph said "costs the turn
16
+ * nothing", which a review correctly read as one: a stop in a repository with a
17
+ * graph pays a `git status` spawn, a graph open and an `untested` walk.
18
+ * `bench_graph_feeder_latency.ts` measures it, and over a large index the graph
19
+ * open dominates. A host that timed a stop
20
+ * hook out would drop the gate's refusal — a failure the comparative exit-code
21
+ * test cannot see, because both of its runs complete. Step 3.4 — promoting the
22
+ * graph verdict into F — is DEFERRED behind step 3.3's recall measurement and
23
+ * behind an owner amendment to ADR-277, and nothing here anticipates it.
24
+ *
25
+ * WHAT A ROW MAY CONTAIN. The fields are a closed set of enums, counts and
26
+ * source paths, repo-relative wherever the edit lay inside the workspace. There
27
+ * is no field able to hold a prompt, a file body, a reply or a command — the same
28
+ * PII-exclusion-by-construction discipline `domain-safety-pii` § Surface 2 asks
29
+ * of a log line, and the same shape `ToolCall` already has. Paths are in the set
30
+ * because they are the evidence a human labeller needs in step 3.3 and because
31
+ * the gate's own refusal text already quotes them; they are capped so one turn
32
+ * cannot write an unbounded row. An edit OUTSIDE the workspace root is the one
33
+ * shape that could carry identifying content, and {@link buildFeederRow}
34
+ * REDACTS it to {@link OUTSIDE_WORKSPACE} — it does not drop it, which was tried
35
+ * and rejected for the reason recorded at that call site.
36
+ *
37
+ * WHERE THAT PROPERTY ACTUALLY HOLDS, stated at its real width. The redaction
38
+ * lives in `buildFeederRow`, so it covers every row THIS module builds, which is
39
+ * every row anything writes today. It is not enforced by the TYPE:
40
+ * `GraphFeederRow.paths` is a plain `string[]` and {@link appendFeederRow} is
41
+ * exported and checks nothing, so a future second writer could persist an
42
+ * unredacted path with no compile error and no runtime guard. A completion
43
+ * review pointed out that the previous wording — "true by construction" without
44
+ * qualification — claimed exactly the convention it was disclaiming. The
45
+ * field-shape half of the header IS by construction: there is no field a prompt
46
+ * or a file body could occupy. The path-redaction half is by call site, and the
47
+ * two are worth not conflating.
48
+ */
49
+ import * as fs from 'node:fs';
50
+ import * as path from 'node:path';
51
+
52
+ import { detectSources, type GraphState, NATIVE_CACHE_REL, pickSource } from '../code_graph/detect.js';
53
+ import { loadGraph } from '../code_graph/query.js';
54
+ import { untested } from '../code_graph/verbs.js';
55
+
56
+ /** At most this many edit paths per row. */
57
+ const MAX_PATHS = 5;
58
+
59
+ /**
60
+ * What a row stores in place of an edit that lay outside the workspace root.
61
+ *
62
+ * Not a path, deliberately: it carries no directory, no user name and no
63
+ * project name, so it cannot be an egress surface when `paths` is handed to an
64
+ * external labeller. It still tells that labeller an edit happened out of tree,
65
+ * which is the difference between answering `cannot tell` and being misled.
66
+ */
67
+ export const OUTSIDE_WORKSPACE = '<outside-workspace>';
68
+
69
+ /**
70
+ * At most this many rows per session file.
71
+ *
72
+ * `agents/state/` is local and gitignored, but "local" is not "free": a long
73
+ * session appends on every turn end, and an instrument that grows without a
74
+ * bound is the failure the gate's own refusal-state history already records.
75
+ * Past the cap the writer stops rather than rotating — a truncated tail is a
76
+ * readable sample, and a rotation would silently drop the earliest rows that a
77
+ * recall reading most wants.
78
+ */
79
+ export const MAX_ROWS_PER_SESSION = 200;
80
+
81
+ /** The graph's half of the verdict. `null` means the graph did not contribute. */
82
+ export type GraphVerdict = 'untested' | 'tested' | 'no-seeds' | null;
83
+
84
+ /** One stop, as the feeder records it. */
85
+ /**
86
+ * The stop layer a row came from.
87
+ *
88
+ * A closed union rather than `string`. The header below calls these fields "a
89
+ * closed set of enums", and a review pointed out the types did not enforce it —
90
+ * the sets lived only in the call sites, so a later caller could widen either
91
+ * with no type error and the prose would quietly become false.
92
+ */
93
+ export type FeederLayer = 'live' | 'stop_hook_active' | 'refused_turn';
94
+
95
+ /** Detector F's evidence class, from the same closed set the detector uses. */
96
+ export type FeederMode = 'transcript' | 'record';
97
+
98
+ export interface GraphFeederRow {
99
+ at: string;
100
+ /** The turn's ordinal — how many genuine user prompts preceded it. */
101
+ turn: number;
102
+ /** Which stop layer produced this row: the live verdict, or a retry. */
103
+ layer: FeederLayer;
104
+ graph_state: GraphState;
105
+ /** Did detector F fire on this turn? */
106
+ f: boolean;
107
+ /** F's evidence class when it fired — `transcript` or `record`. */
108
+ f_mode: FeederMode | null;
109
+ graph: GraphVerdict;
110
+ /** How many changed symbols the graph found no test edge for. */
111
+ graph_untested: number;
112
+ /** How many it did find one for — so the ratio is readable. */
113
+ graph_tested: number;
114
+ /** The turn's edit paths, capped at {@link MAX_PATHS}. */
115
+ paths: string[];
116
+ /** How many edit paths there were in total, when the list is capped. */
117
+ path_count: number;
118
+ }
119
+
120
+ export function feederFile(workspaceRoot: string, sessionKey: string): string {
121
+ return path.join(workspaceRoot, 'agents', 'state', 'graph-feeder', `${sessionKey}.jsonl`);
122
+ }
123
+
124
+ /**
125
+ * Put edit paths into the shape the graph indexes them in.
126
+ *
127
+ * THE DEFECT THIS REPAIRS, measured before it was fixed. `ToolCall.path` carries
128
+ * whatever the host wrote into `file_path`, and Claude Code writes an ABSOLUTE
129
+ * path. The graph keys its node ids on repo-relative paths, so `seedsForFiles`
130
+ * resolved nothing, `untested` returned an empty seed set, and the feeder wrote
131
+ * `no-seeds`. 19 accrued rows carried a path; the 18 that reached the graph at
132
+ * all recorded `no-seeds`, and the nineteenth was skipped on `behind:0`. Not one
133
+ * of them was a fact about the code: the graph arm was mute for its whole
134
+ * accrual window. Probed at `c58d7eae` against the real index —
135
+ * `src/scripts/check_memory.ts` resolves 60 seeds relative and 0 absolute.
136
+ *
137
+ * It survived review because every fixture fed a relative path. A test never run
138
+ * against the shape the host emits cannot see this, which is why the regression
139
+ * test added with this fix is written against the absolute form.
140
+ *
141
+ * Repaired HERE rather than at the one call site, because `graphUntestedVerdict`
142
+ * is exported and a second caller would meet the same silence.
143
+ *
144
+ * A path outside the workspace root is returned unchanged: it is not addressable
145
+ * in the graph under any spelling, and rewriting it to `../..` would turn an
146
+ * honest `no-seeds` into a relative-looking string that still indexes nothing.
147
+ *
148
+ * SEPARATORS ARE NORMALISED TO POSIX, and that is not cosmetic. The indexer
149
+ * writes `source_file` through its own `toPosixRel`, and the store matches it by
150
+ * exact string, so on a host whose `path.sep` is a backslash a raw
151
+ * `path.relative` would emit `src\service.ts`, resolve no seeds, and record
152
+ * `no-seeds` — reintroducing precisely the defect above as a platform-
153
+ * conditional one. Found by the completion review of the commit that first fixed
154
+ * it; neither regression test could have seen it, because both run on one
155
+ * platform.
156
+ */
157
+ export function toRepoRelative(root: string, paths: readonly string[]): string[] {
158
+ let realRoot: string | null = null;
159
+ return paths.map((p) => {
160
+ if (!path.isAbsolute(p)) return p;
161
+ // RAW FIRST, RESOLVED ONLY AS A FALLBACK. The indexer keys `source_file`
162
+ // through a plain tree walk with NO realpath, so the raw spelling is the
163
+ // one it agrees with. Resolving unconditionally fixes a symlinked ROOT
164
+ // and breaks the opposite shape: an in-tree file reached through an
165
+ // in-repo symlink whose target leaves the workspace would relativise to
166
+ // a `..` segment and be redacted off the row — destroying the labelling
167
+ // evidence for a path that is in the tree, which is the harm the
168
+ // redact-rather-than-drop argument exists to prevent. Trying the raw
169
+ // comparison first keeps both: the common case matches the indexer, and
170
+ // the resolved walk is spent only when the raw answer says foreign.
171
+ const raw = _relativeInside(root, p);
172
+ if (raw !== null) return raw;
173
+ realRoot ??= _resolveReal(root);
174
+ return _relativeInside(realRoot, _resolveReal(p)) ?? p;
175
+ });
176
+ }
177
+
178
+ /**
179
+ * `from` -> `to` as a POSIX repo-relative path, or `null` when `to` is outside.
180
+ *
181
+ * `rel === ''` means `to` IS the root, which is emphatically not outside it —
182
+ * folding that into the escape branch made the row say the opposite of the
183
+ * truth. The `..` test is for a leading `..` SEGMENT, not a leading `..` string:
184
+ * `startsWith('..')` also matches an in-tree first segment that merely begins
185
+ * with two dots, such as `..cache/service.ts`.
186
+ */
187
+ function _relativeInside(from: string, to: string): string | null {
188
+ let rel: string;
189
+ try {
190
+ rel = path.relative(from, to);
191
+ } catch {
192
+ return null;
193
+ }
194
+ if (rel === '') return '.';
195
+ if (rel === '..' || rel.startsWith(`..${path.sep}`) || path.isAbsolute(rel)) return null;
196
+ return rel.split(path.sep).join('/');
197
+ }
198
+
199
+ /**
200
+ * The real location of a path, for comparing one host-supplied string to
201
+ * another.
202
+ *
203
+ * WHY THIS IS NOT OPTIONAL. `workspace_root` and a tool call's `file_path` are
204
+ * two independently produced strings, and they routinely disagree about
205
+ * symlinks: macOS `/tmp` resolves to `/private/tmp`, and a worktree session's
206
+ * project dir can resolve to the parent checkout. Relativising them raw sends
207
+ * EVERY in-repo path down the foreign branch, which would return the graph to
208
+ * `no-seeds` and — now that the row redacts a foreign path — would also destroy
209
+ * the labelling evidence instead of merely failing to resolve it. That is
210
+ * strictly worse than the defect this module was repaired for, and it fails the
211
+ * same way: silently. A completion review found it; no fixture could, because
212
+ * every fixture builds its paths from the same realpathed root string.
213
+ *
214
+ * It walks up to the NEAREST EXISTING ancestor and rejoins the remainder, so a
215
+ * file the turn deleted — or a root that does not exist, as a pure unit test's
216
+ * does — still resolves through whatever part of the chain is real. The walk
217
+ * has to be symmetric or it introduces the very bug it fixes: resolving the root
218
+ * through an existing ancestor while leaving the path unresolved makes the two
219
+ * disagree by exactly the symlink prefix. That asymmetry was in the first
220
+ * version of this function and the suite's own POSIX test caught it.
221
+ *
222
+ * KNOWN REMAINING LIMIT: a case-insensitive filesystem can still present the
223
+ * same file under two spellings this does not reconcile. Named rather than
224
+ * silently assumed away.
225
+ */
226
+ function _resolveReal(p: string): string {
227
+ const abs = path.resolve(p);
228
+ const tail: string[] = [];
229
+ let cur = abs;
230
+ for (;;) {
231
+ try {
232
+ const real = fs.realpathSync(cur);
233
+ return tail.length === 0 ? real : path.join(real, ...[...tail].reverse());
234
+ } catch {
235
+ const parent = path.dirname(cur);
236
+ // Reached the filesystem root with nothing resolvable — the absolute
237
+ // form is the best answer available, and it is still symmetric
238
+ // because the other side took the same walk.
239
+ if (parent === cur) return abs;
240
+ tail.push(path.basename(cur));
241
+ cur = parent;
242
+ }
243
+ }
244
+ }
245
+
246
+ /**
247
+ * Would storing this path put content from outside the workspace on the row?
248
+ *
249
+ * Broader than `path.isAbsolute` on purpose. Two shapes bypass that test while
250
+ * carrying exactly the identifying content the marker exists to withhold from
251
+ * the external labeller: an out-of-tree path already in relative form
252
+ * (`../other-project/x.ts`), and a foreign-platform absolute path, which POSIX
253
+ * `path.isAbsolute` reports as relative. Both were found by a completion review.
254
+ */
255
+ function _escapesWorkspace(p: string): boolean {
256
+ return (
257
+ path.isAbsolute(p) ||
258
+ path.win32.isAbsolute(p) ||
259
+ p === '..' ||
260
+ p.startsWith('../') ||
261
+ p.startsWith(`..${path.sep}`)
262
+ );
263
+ }
264
+
265
+ /**
266
+ * Run `untested` over the turn's edit paths.
267
+ *
268
+ * Returns `null` — the graph contributed nothing — for every reason there is:
269
+ * no usable source, a SCIP index with no owned reader, no edit paths, or any
270
+ * throw at all. A verdict this module cannot stand behind is not a verdict.
271
+ */
272
+ export function graphUntestedVerdict(
273
+ root: string,
274
+ state: GraphState,
275
+ paths: readonly string[],
276
+ ): { verdict: GraphVerdict; untested: number; tested: number } {
277
+ const none = { verdict: null, untested: 0, tested: 0 } as const;
278
+ // `behind:N` and `absent` contribute nothing, by the step's own terms: an
279
+ // answer from an index that predates the change is not evidence about the
280
+ // change.
281
+ if (state !== 'fresh' && state !== 'edited') return none;
282
+ if (paths.length === 0) return none;
283
+ // The graph indexes repo-relative paths; a host hands us absolute ones.
284
+ // NOT before the early returns below. Relativising walks the filesystem once
285
+ // per absolute path, and this runs inside a stop hook whose latency the
286
+ // module header names as a risk — a host that timed the hook out
287
+ // would drop the gate's refusal. Spending those syscalls only to discover
288
+ // there is no usable source is cost for nothing.
289
+ let picked;
290
+ try {
291
+ picked = pickSource(detectSources(root, path.join(root, NATIVE_CACHE_REL)));
292
+ } catch {
293
+ return none;
294
+ }
295
+ if (!picked || picked.kind === 'scip') return none;
296
+ let g;
297
+ try {
298
+ g = loadGraph(picked.path, `${picked.kind}:${path.relative(root, picked.path)}`);
299
+ } catch {
300
+ return none;
301
+ }
302
+ try {
303
+ const r = untested(g, toRepoRelative(root, paths), state);
304
+ if (r.seeds.length === 0) return { verdict: 'no-seeds', untested: 0, tested: 0 };
305
+ return {
306
+ verdict: r.untested.length > 0 ? 'untested' : 'tested',
307
+ untested: r.untested.length,
308
+ tested: r.tested.length,
309
+ };
310
+ } catch {
311
+ return none;
312
+ } finally {
313
+ // The handle owns an open database; a stop hook that leaked one per turn
314
+ // would hold a descriptor for the life of the session.
315
+ try {
316
+ g.close();
317
+ } catch {
318
+ /* nothing to do about a failed close */
319
+ }
320
+ }
321
+ }
322
+
323
+ /** Append one row, or do nothing at all. Never throws, never returns a verdict. */
324
+ export function appendFeederRow(workspaceRoot: string, sessionKey: string, row: GraphFeederRow): void {
325
+ try {
326
+ const file = feederFile(workspaceRoot, sessionKey);
327
+ let existing = 0;
328
+ try {
329
+ existing = fs
330
+ .readFileSync(file, 'utf-8')
331
+ .split('\n')
332
+ .filter((l) => l.trim() !== '').length;
333
+ } catch {
334
+ /* absent is zero */
335
+ }
336
+ if (existing >= MAX_ROWS_PER_SESSION) return;
337
+ fs.mkdirSync(path.dirname(file), { recursive: true });
338
+ fs.appendFileSync(file, `${JSON.stringify(row)}\n`);
339
+ } catch {
340
+ // An instrument is never a reason to change what the gate does.
341
+ }
342
+ }
343
+
344
+ /** Read a session's rows back, skipping anything unparseable. */
345
+ export function readFeederRows(workspaceRoot: string, sessionKey: string): GraphFeederRow[] {
346
+ try {
347
+ return fs
348
+ .readFileSync(feederFile(workspaceRoot, sessionKey), 'utf-8')
349
+ .split('\n')
350
+ .filter((l) => l.trim() !== '')
351
+ .map((l) => {
352
+ try {
353
+ return JSON.parse(l) as GraphFeederRow;
354
+ } catch {
355
+ return null;
356
+ }
357
+ })
358
+ .filter((r): r is GraphFeederRow => r !== null);
359
+ } catch {
360
+ return [];
361
+ }
362
+ }
363
+
364
+ /**
365
+ * Build the row.
366
+ *
367
+ * NO LONGER PURE, and the previous line of this docstring still claimed it was.
368
+ * Relativising reads the filesystem — `toRepoRelative` falls back to
369
+ * `fs.realpathSync` when the raw comparison says foreign — so this touches disk
370
+ * for any absolute path outside the root, and the unit tests that pass a
371
+ * non-existent `/workspace` root walk real directories on the way to answering.
372
+ * It is still DETERMINISTIC given the tree, which is what the tests actually
373
+ * rely on. A completion review caught the stale claim; in a module whose header
374
+ * argues its guarantees hold by construction rather than by convention, a
375
+ * docstring that has quietly stopped being true is the same defect class as the
376
+ * rest of this change.
377
+ *
378
+ * `root` is required rather than optional, and relativising happens HERE rather
379
+ * than at the call site, for two reasons that point the same way. The caller is
380
+ * `turn_end_gate_hook.ts`, which sits against a shrink-only 1,500-line source
381
+ * budget it is exactly at — so the five lines this would cost there are five
382
+ * lines it does not have, and its own header already says such things belong in
383
+ * `_lib`. And a caller that can omit the root is a caller that can reintroduce
384
+ * the absolute-path defect {@link toRepoRelative} exists to close: the stored
385
+ * paths a step-3.3 labeller reads must be the paths the verdict was taken over.
386
+ */
387
+ export function buildFeederRow(input: {
388
+ /** The workspace root the paths are made relative to. */
389
+ root: string;
390
+ turn: number;
391
+ layer: FeederLayer;
392
+ state: GraphState;
393
+ fFired: boolean;
394
+ fMode: FeederMode | null;
395
+ paths: readonly string[];
396
+ graph: { verdict: GraphVerdict; untested: number; tested: number };
397
+ at?: string;
398
+ }): GraphFeederRow {
399
+ return {
400
+ at: input.at ?? new Date().toISOString(),
401
+ turn: input.turn,
402
+ layer: input.layer,
403
+ graph_state: input.state,
404
+ f: input.fFired,
405
+ f_mode: input.fMode,
406
+ graph: input.graph.verdict,
407
+ graph_untested: input.graph.untested,
408
+ graph_tested: input.graph.tested,
409
+ // An out-of-workspace edit is REDACTED, not dropped and not stored
410
+ // verbatim. After relativising, a still-absolute path is exactly one
411
+ // that lay outside the root.
412
+ //
413
+ // Verbatim is an egress surface: `paths` is handed to external council
414
+ // seats at step 3.3's labelling, and a home-rooted path names a real
415
+ // user and an unrelated project.
416
+ //
417
+ // Dropping it looked right and was worse, which a completion review
418
+ // caught before it shipped. It would have shortened `paths` below
419
+ // `path_count` and so reused the protocol's truncation signal for a
420
+ // second, different cause — two meanings on one wire, with no field
421
+ // separating them. Worse, a turn editing one in-repo file and one file
422
+ // outside the root would then be excluded from labelling altogether,
423
+ // losing a perfectly labellable in-repo path from a corpus that is
424
+ // blocked precisely for want of rows.
425
+ //
426
+ // The marker keeps the lengths equal, so truncation stays the only
427
+ // cause of `path_count > paths.length`; keeps the row honest that an
428
+ // edit happened outside the tree, so a labeller can answer
429
+ // `cannot tell` rather than be silently misled; and carries nothing
430
+ // identifying. The graph's answer is unchanged either way — the probe
431
+ // sees the real path and resolves no seeds for it.
432
+ paths: toRepoRelative(input.root, input.paths.slice(0, MAX_PATHS)).map((p) =>
433
+ _escapesWorkspace(p) ? OUTSIDE_WORKSPACE : p,
434
+ ),
435
+ path_count: input.paths.length,
436
+ };
437
+ }
@@ -78,6 +78,79 @@ export function hookSectionEnabled(root: string, section: string): boolean {
78
78
  return false;
79
79
  }
80
80
 
81
+ /**
82
+ * Raw scalar at `hooks.<section>.<key>` in `.agent-settings.yml`, or `''`.
83
+ *
84
+ * The `hookSectionEnabled` sibling above answers one boolean question and is
85
+ * the right shape for a default-OFF switch. This one exists because
86
+ * `hooks.verify_before_complete.touched_file_quality` is a three-valued mode
87
+ * (`off | shadow | warn`), and collapsing it into a boolean would lose exactly
88
+ * the distinction the roadmap's Phase 2 turns on — `shadow` records and says
89
+ * nothing, `warn` records and emits one line.
90
+ *
91
+ * It reuses the section scoping of `hookSectionEnabled` verbatim, including the
92
+ * ACTUAL-indent close that the 4-space-file defect produced: a reader that
93
+ * closed the section on a fixed depth would read a sibling section's value under
94
+ * this key's name, which for a mode string is worse than for a flag — the wrong
95
+ * value is a legal one.
96
+ *
97
+ * Interpretation is NOT done here. `''` means "nothing was written", and the
98
+ * caller decides what that defaults to — the same producer/consumer split
99
+ * `leanProjectionModeRaw` makes below, and for the same reason.
100
+ */
101
+ export function hookSectionValue(root: string, section: string, key: string): string {
102
+ const file = path.join(root, SETTINGS_FILE);
103
+ let text: string;
104
+ try {
105
+ if (!fs.statSync(file).isFile()) return '';
106
+ text = fs.readFileSync(file, 'utf-8');
107
+ } catch {
108
+ return '';
109
+ }
110
+
111
+ const esc = (s: string): string => s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
112
+ const sectionPattern = new RegExp(`^(\\s+)${esc(section)}\\s*:\\s*$`);
113
+ const keyPattern = new RegExp(`^\\s+${esc(key)}\\s*:\\s*(.+)$`);
114
+ let inHooks = false;
115
+ let sectionIndent: number | null = null;
116
+
117
+ const indentOf = (line: string): number => line.length - line.replace(/^\s+/, '').length;
118
+
119
+ for (const raw of text.split(/\r\n|\r|\n/)) {
120
+ const line = raw.replace(/\s+$/, '');
121
+ if (!line || line.replace(/^\s+/, '').startsWith('#')) continue;
122
+
123
+ if (!(line.startsWith(' ') || line.startsWith('\t'))) {
124
+ inHooks = /^hooks\s*:\s*$/.test(line);
125
+ sectionIndent = null;
126
+ continue;
127
+ }
128
+
129
+ if (inHooks) {
130
+ const opened = sectionPattern.exec(line);
131
+ if (opened) {
132
+ sectionIndent = opened[1]!.length;
133
+ continue;
134
+ }
135
+ if (sectionIndent !== null && indentOf(line) <= sectionIndent) {
136
+ sectionIndent = null;
137
+ }
138
+ }
139
+
140
+ if (sectionIndent !== null) {
141
+ const m = keyPattern.exec(line);
142
+ if (m) {
143
+ return (m[1] ?? '')
144
+ .replace(/\s+#.*$/, '')
145
+ .trim()
146
+ .replace(/^["']|["']$/g, '');
147
+ }
148
+ }
149
+ }
150
+
151
+ return '';
152
+ }
153
+
81
154
  /**
82
155
  * Raw `lean_projection.mode` string out of `.agent-settings.yml`, or `''`.
83
156
  *