@event4u/agent-config 16.2.0 → 16.3.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 (332) 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 +89 -237
  5. package/README.md +14 -12
  6. package/dist/agent-src/commands/analyze/inbox.md +1 -1
  7. package/dist/agent-src/commands/analyze/roadmap-repos.md +1 -1
  8. package/dist/agent-src/commands/bug/fix.md +17 -2
  9. package/dist/agent-src/commands/feature/plan.md +1 -1
  10. package/dist/agent-src/commands/feature/roadmap.md +1 -1
  11. package/dist/agent-src/commands/fix/ci.md +1 -1
  12. package/dist/agent-src/commands/implement-ticket.md +1 -1
  13. package/dist/agent-src/commands/jira-ticket.md +1 -1
  14. package/dist/agent-src/commands/roadmap/create.md +1 -1
  15. package/dist/agent-src/commands/roadmap/materialize.md +1 -1
  16. package/dist/agent-src/commands/roadmap/process-full.md +4 -4
  17. package/dist/agent-src/commands/roadmap/resolve-blockers.md +361 -0
  18. package/dist/agent-src/commands/roadmap/triage-parked.md +325 -0
  19. package/dist/agent-src/commands/roadmap.md +18 -4
  20. package/dist/agent-src/commands/tests/create.md +17 -3
  21. package/dist/agent-src/commands/tests/execute.md +22 -5
  22. package/dist/agent-src/contexts/authority/decision-revisit-gate-enforcement.md +43 -0
  23. package/dist/agent-src/contexts/communication/rules-auto/design-fidelity-enforcement.md +24 -0
  24. package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +6 -6
  25. package/dist/agent-src/contexts/execution/roadmap-process-loop.md +32 -2
  26. package/dist/agent-src/contexts/execution/session-canary-enforcement-history.md +67 -0
  27. package/dist/agent-src/contexts/execution/toolchain-resolver.md +101 -7
  28. package/dist/agent-src/rules/active-remediation.md +1 -1
  29. package/dist/agent-src/rules/autonomous-execution.md +1 -0
  30. package/dist/agent-src/rules/broken-access-control.md +1 -0
  31. package/dist/agent-src/rules/command-suggestion-policy.md +1 -0
  32. package/dist/agent-src/rules/context-hygiene.md +1 -1
  33. package/dist/agent-src/rules/decision-revisit-gate.md +16 -33
  34. package/dist/agent-src/rules/design-fidelity.md +13 -16
  35. package/dist/agent-src/rules/doc-screenshot-hygiene.md +1 -0
  36. package/dist/agent-src/rules/domain-safety-disclaimer.md +1 -0
  37. package/dist/agent-src/rules/domain-safety-pii.md +1 -0
  38. package/dist/agent-src/rules/domain-safety-retention.md +1 -0
  39. package/dist/agent-src/rules/engineering-safety-floor.md +1 -0
  40. package/dist/agent-src/rules/evaluator-independence.md +3 -2
  41. package/dist/agent-src/rules/fast-path-marker-visibility.md +1 -0
  42. package/dist/agent-src/rules/finance-safety-floor.md +1 -0
  43. package/dist/agent-src/rules/git-history-discipline.md +1 -0
  44. package/dist/agent-src/rules/image-likeness-and-rights.md +1 -0
  45. package/dist/agent-src/rules/legal-safety-floor.md +3 -2
  46. package/dist/agent-src/rules/lethal-trifecta-guard.md +1 -0
  47. package/dist/agent-src/rules/low-impact-corpus-privacy-floor.md +1 -0
  48. package/dist/agent-src/rules/media-governance-routing.md +14 -17
  49. package/dist/agent-src/rules/persona-governance.md +2 -2
  50. package/dist/agent-src/rules/provider-lifecycle-discipline.md +1 -1
  51. package/dist/agent-src/rules/question-not-instruction.md +1 -0
  52. package/dist/agent-src/rules/roadmap-progress-sync.md +1 -1
  53. package/dist/agent-src/rules/runtime-safety.md +1 -0
  54. package/dist/agent-src/rules/secret-vcs-guard.md +1 -0
  55. package/dist/agent-src/rules/security-sensitive-stop.md +3 -2
  56. package/dist/agent-src/rules/session-canary.md +8 -62
  57. package/dist/agent-src/rules/settings-ask-protocol.md +1 -0
  58. package/dist/agent-src/rules/source-confidentiality.md +1 -0
  59. package/dist/agent-src/rules/strategy-safety-floor.md +1 -0
  60. package/dist/agent-src/rules/tool-safety.md +1 -0
  61. package/dist/agent-src/rules/untrusted-input-defense.md +1 -0
  62. package/dist/agent-src/rules/user-interrupt-priority.md +1 -0
  63. package/dist/agent-src/scripts/archive_completed_roadmaps.ts +115 -20
  64. package/dist/agent-src/scripts/deferral_carry.ts +339 -0
  65. package/dist/agent-src/scripts/update_roadmap_progress.ts +4 -1
  66. package/dist/agent-src/skills/api-design/data/manifest.json +2 -2
  67. package/dist/agent-src/skills/api-testing/SKILL.md +17 -0
  68. package/dist/agent-src/skills/code-intelligence/SKILL.md +14 -2
  69. package/dist/agent-src/skills/design-system-capture/references/import-procedure.md +1 -1
  70. package/dist/agent-src/skills/existing-ui-audit/SKILL.md +2 -2
  71. package/dist/agent-src/skills/fe-design/SKILL.md +1 -1
  72. package/dist/agent-src/skills/iconography/SKILL.md +1 -1
  73. package/dist/agent-src/skills/js-library-packaging/SKILL.md +2 -2
  74. package/dist/agent-src/skills/monorepo-workspace/SKILL.md +1 -1
  75. package/dist/agent-src/skills/quality-tools/SKILL.md +11 -1
  76. package/dist/agent-src/skills/quality-tools/references/go-tools.md +76 -0
  77. package/dist/agent-src/skills/quality-tools/references/python-tools.md +104 -0
  78. package/dist/agent-src/skills/review-routing/SKILL.md +2 -2
  79. package/dist/agent-src/skills/skill-improvement-pipeline/SKILL.md +1 -1
  80. package/dist/agent-src/skills/storybook-workshop/SKILL.md +3 -3
  81. package/dist/agent-src/skills/tailwind-engineer/SKILL.md +1 -1
  82. package/dist/agent-src/skills/test-case-discovery/SKILL.md +7 -0
  83. package/dist/agent-src/skills/test-driven-development/SKILL.md +17 -0
  84. package/dist/agent-src/skills/test-performance/SKILL.md +19 -1
  85. package/dist/agent-src/skills/ui-component-architect/SKILL.md +2 -2
  86. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  87. package/dist/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +48 -6
  88. package/dist/agent-src/templates/scripts/work_engine/stack/runner.ts +774 -109
  89. package/dist/cli/registry.js +1 -1
  90. package/dist/cli-delegate/archive_completed_roadmaps.js +92 -12
  91. package/dist/cli-delegate/check_update_banner.js +12 -1
  92. package/dist/cli-delegate/chunk-523HCFYO.js +90 -0
  93. package/dist/cli-delegate/{chunk-M2DPGFZ4.js → chunk-6V6TA25H.js} +22 -152
  94. package/dist/cli-delegate/chunk-7IQE3D5S.js +191 -0
  95. package/dist/cli-delegate/{chunk-6KFEC3G7.js → chunk-CQWX336L.js} +1 -1
  96. package/dist/cli-delegate/chunk-DEIV7XP7.js +108 -0
  97. package/dist/cli-delegate/chunk-EEHDXSYD.js +2040 -0
  98. package/dist/cli-delegate/{chunk-P6ZHP5W2.js → chunk-GKE7ZVFA.js} +4 -4
  99. package/dist/cli-delegate/chunk-JQOM7TTM.js +1201 -0
  100. package/dist/cli-delegate/{chunk-IGD6ERX6.js → chunk-JQVYKIZA.js} +10 -0
  101. package/dist/cli-delegate/{chunk-FC75PGJE.js → chunk-JY2I2DXV.js} +12 -1
  102. package/dist/cli-delegate/chunk-KB5FZ655.js +208 -0
  103. package/dist/cli-delegate/{chunk-7RQP4UDH.js → chunk-KR6EM23A.js} +235 -1455
  104. package/dist/cli-delegate/{chunk-LTYVIY76.js → chunk-LIYTLH6O.js} +1 -1
  105. package/dist/cli-delegate/{chunk-YJ72UIAK.js → chunk-NQ7WT43P.js} +1186 -244
  106. package/dist/cli-delegate/chunk-NXEILF2K.js +2160 -0
  107. package/dist/cli-delegate/{chunk-5R7HOLAF.js → chunk-NYX3L2PZ.js} +1 -1
  108. package/dist/cli-delegate/{chunk-4E2W63DA.js → chunk-OKJUIAPS.js} +62 -1
  109. package/dist/cli-delegate/{chunk-QAJS5YWY.js → chunk-PHD7OOLE.js} +2 -1
  110. package/dist/cli-delegate/{chunk-RGNIWTEA.js → chunk-QLDHIPWR.js} +1 -1
  111. package/dist/cli-delegate/{chunk-7XGBX6ZH.js → chunk-RQNNW7IF.js} +1314 -560
  112. package/dist/cli-delegate/{chunk-4XFP2Y3E.js → chunk-S4UMZNES.js} +1 -1
  113. package/dist/cli-delegate/{chunk-6KM6ORRY.js → chunk-S4YWNRKO.js} +24 -8
  114. package/dist/cli-delegate/{chunk-FP36SWJD.js → chunk-TRI6DQZ6.js} +2781 -340
  115. package/dist/cli-delegate/chunk-ULQRUR23.js +208 -0
  116. package/dist/cli-delegate/{chunk-NUHLI2RX.js → chunk-YCU3TIXH.js} +2 -0
  117. package/dist/cli-delegate/chunk-ZBZV2G5R.js +210 -0
  118. package/dist/cli-delegate/{chunk-WGXTVKCQ.js → chunk-ZUZKZYCN.js} +5 -3
  119. package/dist/cli-delegate/cmd_analyze_session.js +1 -1
  120. package/dist/cli-delegate/cmd_brand_status.js +1 -1
  121. package/dist/cli-delegate/cmd_conformance.js +1167 -234
  122. package/dist/cli-delegate/cmd_doctor.js +13 -6
  123. package/dist/cli-delegate/cmd_doctor_neighbours.js +23 -0
  124. package/dist/cli-delegate/cmd_explain.js +5 -5
  125. package/dist/cli-delegate/cmd_export.js +11 -8
  126. package/dist/cli-delegate/cmd_fleet.js +3 -3
  127. package/dist/cli-delegate/cmd_handoff.js +10 -7
  128. package/dist/cli-delegate/cmd_mcp_available.js +1 -1
  129. package/dist/cli-delegate/cmd_memory_get.js +3 -1
  130. package/dist/cli-delegate/cmd_migrate.js +2 -2
  131. package/dist/cli-delegate/cmd_packs_active.js +3 -3
  132. package/dist/cli-delegate/cmd_preflight.js +6 -6
  133. package/dist/cli-delegate/cmd_prune.js +11 -8
  134. package/dist/cli-delegate/cmd_refresh.js +2 -1
  135. package/dist/cli-delegate/cmd_route_audit.js +8 -6
  136. package/dist/cli-delegate/cmd_route_explain.js +4 -4
  137. package/dist/cli-delegate/cmd_session_recycle.js +4 -3
  138. package/dist/cli-delegate/cmd_settings_get.js +1 -1
  139. package/dist/cli-delegate/cmd_settings_migrate.js +11 -8
  140. package/dist/cli-delegate/cmd_settings_set.js +4 -4
  141. package/dist/cli-delegate/cmd_sync.js +11 -8
  142. package/dist/cli-delegate/cmd_uninstall.js +11 -8
  143. package/dist/cli-delegate/cmd_update.js +1 -1
  144. package/dist/cli-delegate/cmd_upgrade.js +3 -2
  145. package/dist/cli-delegate/cmd_validate.js +11 -8
  146. package/dist/cli-delegate/cmd_versions.js +1 -1
  147. package/dist/cli-delegate/deferral_carry.js +16 -0
  148. package/dist/cli-delegate/gate_execute.js +2 -2
  149. package/dist/cli-delegate/roadmap_gates.js +5 -5
  150. package/dist/cli-delegate/update_roadmap_progress.js +1 -1
  151. package/dist/discovery/deprecation-report.md +1 -1
  152. package/dist/discovery/discovery-manifest.json +127 -75
  153. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  154. package/dist/discovery/discovery-manifest.summary.md +3 -3
  155. package/dist/discovery/dormancy-report.md +1 -1
  156. package/dist/discovery/orphan-report.md +1 -1
  157. package/dist/discovery/packs.json +7 -5
  158. package/dist/discovery/trust-report.md +2 -2
  159. package/dist/discovery/workspaces.json +6 -4
  160. package/dist/hooks/dispatch.js +5357 -6656
  161. package/dist/hooks/dispatch.sha256 +1 -1
  162. package/dist/install/claudePathsPlan.js +47 -6
  163. package/dist/install/claudeRuleRewrite.js +7 -0
  164. package/dist/install/emit_host_rules_cli.js +39 -36
  165. package/dist/install/globalRuleScope.js +87 -0
  166. package/dist/install/host_rule_ownership.js +160 -0
  167. package/dist/install/install.mjs +2080 -1024
  168. package/dist/install/installThinLayer.js +261 -0
  169. package/dist/install/installedRuleLinks.js +176 -0
  170. package/dist/install/wizard-plan.js +24 -0
  171. package/dist/mcp/registry-manifest.json +3 -3
  172. package/dist/mcp/server.json +2 -2
  173. package/dist/mcp/server.mjs +31965 -27154
  174. package/dist/scripts/_lib/agent_settings.js +11 -0
  175. package/dist/scripts/_lib/claude_settings_hooks.js +10 -8
  176. package/dist/scripts/_lib/installed_layer.js +378 -0
  177. package/dist/scripts/_lib/lean_projection_mode.js +218 -15
  178. package/dist/scripts/_lib/rule_consequence_class.js +45 -0
  179. package/dist/scripts/_lib/rule_injection.js +67 -10
  180. package/dist/scripts/_lib/rule_law_section.js +122 -0
  181. package/dist/scripts/_lib/thin_rules.js +458 -0
  182. package/dist/scripts/_lib/windsurf_render.js +60 -0
  183. package/dist/scripts/condense.js +14 -26
  184. package/dist/scripts/project_thin_rules.js +14 -294
  185. package/dist/server/schemas/settings.js +6 -0
  186. package/dist/shared/skillRanking.js +74 -13
  187. package/docs/contracts/settings-classes.md +7 -5
  188. package/package.json +1 -1
  189. package/src/agent-src/scripts/archive_completed_roadmaps.ts +115 -20
  190. package/src/agent-src/scripts/deferral_carry.ts +339 -0
  191. package/src/agent-src/scripts/update_roadmap_progress.ts +4 -1
  192. package/src/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +48 -6
  193. package/src/agent-src/templates/scripts/work_engine/stack/runner.ts +774 -109
  194. package/src/config/agent-settings.template.yml +62 -22
  195. package/src/config/continuity-surface.json +7 -0
  196. package/src/config/evaluator-budgets.json +4 -4
  197. package/src/config/gate-coverage.yml +96 -3
  198. package/src/config/gate-violation-baselines.json +17 -9
  199. package/src/config/hook-bundle-budget.json +25 -0
  200. package/src/config/hook-token-budget.json +6 -1
  201. package/src/config/host-instruction-limits.json +33 -0
  202. package/src/config/routing-coverage-seed.json +24 -3
  203. package/src/config/rule-activation-census.json +7 -3
  204. package/src/config/rule-consequence-class.json +161 -0
  205. package/src/config/rule-law-ceilings.json +99 -0
  206. package/src/install/claudePathsPlan.ts +46 -4
  207. package/src/install/claudeRuleRewrite.ts +10 -1
  208. package/src/install/emit_host_rules_cli.ts +43 -34
  209. package/src/install/globalRuleScope.ts +109 -0
  210. package/src/install/host_rule_ownership.ts +170 -0
  211. package/src/install/installThinLayer.ts +312 -0
  212. package/src/install/installedRuleLinks.ts +220 -0
  213. package/src/install/wizard-plan.ts +24 -0
  214. package/src/scripts/_cli/cmd_doctor.ts +23 -71
  215. package/src/scripts/_cli/cmd_doctor_neighbours.ts +293 -0
  216. package/src/scripts/_dispatch.bash +16 -2
  217. package/src/scripts/_lib/agent_settings.ts +11 -0
  218. package/src/scripts/_lib/claude_settings_hooks.ts +10 -8
  219. package/src/scripts/_lib/estate_offsets.ts +241 -0
  220. package/src/scripts/_lib/exemption_shape.ts +143 -0
  221. package/src/scripts/_lib/fnv.ts +23 -0
  222. package/src/scripts/_lib/foreign_scan.ts +106 -0
  223. package/src/scripts/_lib/gitignore_block.ts +314 -0
  224. package/src/scripts/_lib/global_deploy_inventory.ts +32 -0
  225. package/src/scripts/_lib/graph_feeder_record.ts +214 -0
  226. package/src/scripts/_lib/hook_settings.ts +73 -0
  227. package/src/scripts/_lib/host_capability.ts +40 -19
  228. package/src/scripts/_lib/host_hook_merge.ts +165 -0
  229. package/src/scripts/_lib/installed_layer.ts +538 -0
  230. package/src/scripts/_lib/json_merge.ts +82 -0
  231. package/src/scripts/_lib/json_pointers.ts +93 -11
  232. package/src/scripts/_lib/lean_projection_mode.ts +275 -15
  233. package/src/scripts/_lib/machine_wake.ts +16 -3
  234. package/src/scripts/_lib/neighbour_census.ts +760 -0
  235. package/src/scripts/_lib/neighbour_scan.ts +122 -0
  236. package/src/scripts/_lib/neighbour_tool_use.ts +189 -0
  237. package/src/scripts/_lib/prompt_shape.ts +46 -0
  238. package/src/scripts/_lib/release_migration_gate.ts +19 -3
  239. package/src/scripts/_lib/reserved_name_sweep.ts +73 -0
  240. package/src/scripts/_lib/review_coverage.ts +134 -0
  241. package/src/scripts/_lib/rule_consequence_class.ts +71 -0
  242. package/src/scripts/_lib/rule_injection.ts +130 -10
  243. package/src/scripts/_lib/rule_law_section.ts +147 -0
  244. package/src/scripts/_lib/rule_layer_overlap.ts +58 -0
  245. package/src/scripts/_lib/skill_origin.ts +254 -0
  246. package/src/scripts/_lib/structured_ask.ts +64 -21
  247. package/src/scripts/_lib/thin_rules.ts +540 -0
  248. package/src/scripts/_lib/touched_file_quality.ts +434 -0
  249. package/src/scripts/_lib/turn_end_refusals.ts +77 -2
  250. package/src/scripts/_lib/windsurf_render.ts +63 -0
  251. package/src/scripts/ai_council/cli_call_budget.ts +13 -5
  252. package/src/scripts/ai_council/clients.ts +26 -57
  253. package/src/scripts/ai_council/config.ts +1 -1
  254. package/src/scripts/ai_council/vendor_defaults.ts +45 -0
  255. package/src/scripts/audit_skill_overlap.ts +261 -0
  256. package/src/scripts/before_complete_hook.ts +243 -12
  257. package/src/scripts/bench_touched_file_quality.ts +238 -0
  258. package/src/scripts/check_enforcement_matrix.ts +377 -20
  259. package/src/scripts/check_estate_count.ts +130 -153
  260. package/src/scripts/check_finding_dispositions.ts +116 -4
  261. package/src/scripts/check_hook_bundle_composition.ts +370 -0
  262. package/src/scripts/check_kernel_edit_ratified.ts +49 -11
  263. package/src/scripts/check_memory.ts +7 -1
  264. package/src/scripts/check_release_highlights.ts +10 -0
  265. package/src/scripts/check_release_pr_shape.ts +38 -15
  266. package/src/scripts/check_standing_rule_delivery.ts +33 -13
  267. package/src/scripts/check_verify_expectation_delta.ts +521 -0
  268. package/src/scripts/code_graph/detect.ts +127 -7
  269. package/src/scripts/code_graph/foreign.ts +194 -0
  270. package/src/scripts/code_graph/query.ts +217 -4
  271. package/src/scripts/code_graph/types.ts +26 -2
  272. package/src/scripts/code_graph/validate.ts +3 -1
  273. package/src/scripts/code_graph/verbs.ts +103 -0
  274. package/src/scripts/compile_hook_manifest.ts +33 -1
  275. package/src/scripts/condense.ts +14 -27
  276. package/src/scripts/estate_exemption_shape.ts +202 -0
  277. package/src/scripts/generate_host_cost_table.ts +1 -1
  278. package/src/scripts/hook_manifest.json +1 -1
  279. package/src/scripts/hook_manifest.yaml +150 -9
  280. package/src/scripts/hooks/block_config_weakening.ts +67 -2
  281. package/src/scripts/hooks/block_plumbing_writes.ts +29 -1
  282. package/src/scripts/hooks/code_graph_context_hook.ts +252 -23
  283. package/src/scripts/hooks/concern_failure_policy.ts +280 -0
  284. package/src/scripts/hooks/dispatch_hook.ts +52 -52
  285. package/src/scripts/hooks/exit_codes.ts +2 -1
  286. package/src/scripts/hooks/host_lowering.json +1 -1
  287. package/src/scripts/hooks/host_lowering.ts +19 -1
  288. package/src/scripts/hooks/one_question_per_ask_hook.ts +41 -25
  289. package/src/scripts/hooks/payload_stub.ts +10 -1
  290. package/src/scripts/hooks/rule_inject_hook.ts +757 -63
  291. package/src/scripts/hooks/table_fingerprint.ts +21 -0
  292. package/src/scripts/hooks/telemetry_usage_hook.ts +64 -8
  293. package/src/scripts/hooks/turn_end_gate_hook.ts +84 -0
  294. package/src/scripts/hooks_status.ts +112 -0
  295. package/src/scripts/injection_scan_hook.ts +7 -0
  296. package/src/scripts/install.ts +72 -185
  297. package/src/scripts/installed_layer_report.ts +103 -0
  298. package/src/scripts/language_mirror_hook.ts +15 -6
  299. package/src/scripts/learning_sidecar.ts +119 -8
  300. package/src/scripts/lint_hook_manifest.ts +53 -0
  301. package/src/scripts/lint_major_migration_sections.ts +156 -26
  302. package/src/scripts/lint_pack_boundaries.ts +63 -5
  303. package/src/scripts/lint_rule_law_section.ts +517 -0
  304. package/src/scripts/lint_workflow_security.ts +161 -5
  305. package/src/scripts/mcp_server/consumer_tool_catalog.json +53 -0
  306. package/src/scripts/mcp_server/graph_tools.ts +72 -3
  307. package/src/scripts/measure_routing_signal.ts +54 -16
  308. package/src/scripts/measure_skill_ranker_baseline.ts +216 -8
  309. package/src/scripts/memory_learn_hook.ts +91 -6
  310. package/src/scripts/model_rule_injection.ts +52 -5
  311. package/src/scripts/project_thin_rules.ts +34 -327
  312. package/src/scripts/report_evidence_temperature.ts +657 -0
  313. package/src/scripts/report_installed_rule_links.ts +157 -0
  314. package/src/scripts/report_label_agreement.ts +233 -0
  315. package/src/scripts/report_obligation_mechanism.ts +230 -0
  316. package/src/scripts/report_single_token_triggers.ts +277 -0
  317. package/src/scripts/report_skill_ranker_confusion.ts +442 -0
  318. package/src/scripts/report_standing_payload_by_host.ts +188 -15
  319. package/src/scripts/report_verification_record_coverage.ts +306 -0
  320. package/src/scripts/rule_activation_census.ts +5 -2
  321. package/src/scripts/rule_trigger_eval.ts +9 -9
  322. package/src/scripts/schemas/review-findings.schema.json +3 -2
  323. package/src/scripts/schemas/rule.schema.json +5 -0
  324. package/src/scripts/self_review_gate.ts +62 -7
  325. package/src/scripts/skill_tools/score_skill_relevance.ts +290 -25
  326. package/src/scripts/sweep_skill_ranker_signals.ts +129 -0
  327. package/src/scripts/sync_gitignore.ts +29 -235
  328. package/src/scripts/trigger_eval_grandfather.json +0 -5
  329. package/src/server/schemas/settings.ts +10 -0
  330. package/src/shared/skillRanking.ts +117 -11
  331. package/dist/cli-delegate/chunk-JNMVLWLR.js +0 -4457
  332. package/dist/cli-delegate/chunk-YDPILCOL.js +0 -152
@@ -1,4 +1,7 @@
1
1
  import { createRequire as __acCreateRequire } from 'node:module'; const require = globalThis.require ?? __acCreateRequire(import.meta.url);
2
+ import {
3
+ readRecentEntries
4
+ } from "./chunk-NYX3L2PZ.js";
2
5
  import {
3
6
  NO_RED_EVIDENCE_REASON,
4
7
  deriveSessionKey,
@@ -17,17 +20,24 @@ import {
17
20
  readTurnRunState,
18
21
  sessionRefusalFile,
19
22
  sessionShadowFile,
23
+ shadowSetBy,
20
24
  statePathFor,
21
25
  validateAssumption
22
- } from "./chunk-YJ72UIAK.js";
26
+ } from "./chunk-NQ7WT43P.js";
23
27
  import {
24
28
  readHookStdin
25
29
  } from "./chunk-F7DQWYR5.js";
26
30
  import {
27
- DeadScopeError,
28
- assertScanned,
29
- reportScanned
30
- } from "./chunk-I3EIN2YG.js";
31
+ LexicalIndex,
32
+ isSqliteAvailableSync,
33
+ loadSqliteSync,
34
+ readUserVersion,
35
+ stampUserVersion,
36
+ tokenize
37
+ } from "./chunk-ZBZV2G5R.js";
38
+ import {
39
+ detectToolPresence
40
+ } from "./chunk-A4QJ6ENT.js";
31
41
  import {
32
42
  ArgparseExit,
33
43
  STATUS_SYMBOLS,
@@ -44,16 +54,22 @@ import {
44
54
  comparePair,
45
55
  frontmatterPaths,
46
56
  proseEqual,
57
+ resolveSessionRole,
47
58
  splitFrontmatter
48
- } from "./chunk-FP36SWJD.js";
59
+ } from "./chunk-TRI6DQZ6.js";
49
60
  import "./chunk-FTAISGDQ.js";
50
- import "./chunk-M2DPGFZ4.js";
61
+ import "./chunk-6V6TA25H.js";
51
62
  import "./chunk-ROYYTEZU.js";
52
63
  import "./chunk-BTWUYDGN.js";
53
64
  import {
54
- projectStoreSlug,
55
- resolveSessionRole
56
- } from "./chunk-JNMVLWLR.js";
65
+ atomicAppendLine,
66
+ probeHostCapabilities
67
+ } from "./chunk-S4YWNRKO.js";
68
+ import "./chunk-ULQRUR23.js";
69
+ import {
70
+ hardenedSpawnEnv,
71
+ projectStoreSlug
72
+ } from "./chunk-EEHDXSYD.js";
57
73
  import {
58
74
  atomic_write_json,
59
75
  atomic_write_text,
@@ -64,26 +80,22 @@ import {
64
80
  prune_stale_session_states,
65
81
  session_state_file
66
82
  } from "./chunk-E4XIZDIB.js";
67
- import {
68
- artefact_roots
69
- } from "./chunk-NUHLI2RX.js";
70
- import {
71
- readRecentEntries
72
- } from "./chunk-5R7HOLAF.js";
73
- import {
74
- detectToolPresence
75
- } from "./chunk-A4QJ6ENT.js";
76
- import {
77
- atomicAppendLine,
78
- probeHostCapabilities
79
- } from "./chunk-6KM6ORRY.js";
80
83
  import "./chunk-T7L2QK3K.js";
81
84
  import "./chunk-DMSZHXZS.js";
85
+ import "./chunk-NXEILF2K.js";
86
+ import "./chunk-DEIV7XP7.js";
87
+ import "./chunk-KB5FZ655.js";
88
+ import "./chunk-JQOM7TTM.js";
82
89
  import {
83
90
  manifest_path,
84
91
  read_manifest
85
- } from "./chunk-4E2W63DA.js";
92
+ } from "./chunk-OKJUIAPS.js";
86
93
  import "./chunk-MWRD5YOH.js";
94
+ import {
95
+ DeadScopeError,
96
+ assertScanned,
97
+ reportScanned
98
+ } from "./chunk-I3EIN2YG.js";
87
99
  import {
88
100
  require_dist
89
101
  } from "./chunk-OY53J6II.js";
@@ -92,17 +104,20 @@ import {
92
104
  } from "./chunk-MCJYCQPF.js";
93
105
  import {
94
106
  load_agent_settings
95
- } from "./chunk-FC75PGJE.js";
107
+ } from "./chunk-JY2I2DXV.js";
96
108
  import "./chunk-NDJLNC6Q.js";
109
+ import {
110
+ artefact_roots
111
+ } from "./chunk-YCU3TIXH.js";
97
112
  import {
98
113
  __toESM
99
114
  } from "./chunk-J55WI3RR.js";
100
115
 
101
116
  // src/scripts/_cli/cmd_conformance.ts
102
117
  var YAML = __toESM(require_dist(), 1);
103
- import * as fs16 from "node:fs";
118
+ import * as fs20 from "node:fs";
104
119
  import * as os7 from "node:os";
105
- import * as path15 from "node:path";
120
+ import * as path18 from "node:path";
106
121
  import process5 from "node:process";
107
122
  import { spawnSync as spawnSync4 } from "node:child_process";
108
123
  import { fileURLToPath as fileURLToPath14, pathToFileURL as pathToFileURL14 } from "node:url";
@@ -118,10 +133,10 @@ var ROUTE_TARGET_TEMPLATES = Object.freeze({
118
133
  ])
119
134
  });
120
135
  function parseRouteTarget(target) {
121
- const sep2 = target.indexOf(":");
122
- if (sep2 <= 0) return null;
123
- const kind = target.slice(0, sep2);
124
- const id = target.slice(sep2 + 1);
136
+ const sep3 = target.indexOf(":");
137
+ if (sep3 <= 0) return null;
138
+ const kind = target.slice(0, sep3);
139
+ const id = target.slice(sep3 + 1);
125
140
  if (!id) return null;
126
141
  if (!Object.prototype.hasOwnProperty.call(ROUTE_TARGET_TEMPLATES, kind)) return null;
127
142
  return { kind, id };
@@ -133,17 +148,17 @@ function routeTargetPathsPosix(target) {
133
148
  }
134
149
 
135
150
  // src/scripts/report_conformance_funnel.ts
136
- import * as fs15 from "node:fs";
151
+ import * as fs19 from "node:fs";
137
152
  import * as os6 from "node:os";
138
- import * as path14 from "node:path";
153
+ import * as path17 from "node:path";
139
154
  import process4 from "node:process";
140
155
  import { fileURLToPath as fileURLToPath13, pathToFileURL as pathToFileURL13 } from "node:url";
141
156
 
142
157
  // src/scripts/conformance_scan.ts
143
- import { createHash as createHash3 } from "node:crypto";
144
- import fs11 from "node:fs";
158
+ import { createHash as createHash4 } from "node:crypto";
159
+ import fs15 from "node:fs";
145
160
  import os2 from "node:os";
146
- import path10 from "node:path";
161
+ import path13 from "node:path";
147
162
  import { fileURLToPath as fileURLToPath9, pathToFileURL as pathToFileURL9 } from "node:url";
148
163
 
149
164
  // src/scripts/_lib/transcript_entry.ts
@@ -191,7 +206,7 @@ import { fileURLToPath, pathToFileURL } from "node:url";
191
206
  // src/scripts/_lib/prompt_shape.ts
192
207
  function isSyntheticPrompt(prompt) {
193
208
  const head = prompt.trimStart().slice(0, 400);
194
- return head.startsWith("[SYSTEM NOTIFICATION - NOT USER INPUT]") || head.startsWith("<task-notification>") || head.startsWith("<system-reminder>") || head.startsWith("<local-command-caveat>") || /^\[SYSTEM NOTIFICATION\b/.test(head);
209
+ return head.startsWith("[SYSTEM NOTIFICATION - NOT USER INPUT]") || head.startsWith("<task-notification>") || head.startsWith("<system-reminder>") || head.startsWith("<local-command-caveat>") || head.startsWith("<agent-message") || head.startsWith("Your claude.ai usage limit has reset") || /^\[SYSTEM NOTIFICATION\b/.test(head);
195
210
  }
196
211
  var DOCUMENT_HEAD = /^\s*(#{1,6}\s|-{3,}\s*$|={3,}\s*$|<[A-Za-z][\w-]*>\s*$)/;
197
212
  function humanAuthoredLead(text) {
@@ -348,7 +363,7 @@ This is the WEAKER of the two provenances \u2014 it reflects the machine, not th
348
363
  return `<language-pin>
349
364
  The user submitted this turn's prompt in ${name}. That is the mirror target for EVERY user-visible token of your replies this turn \u2014 including the short inter-tool lines between tool calls, headings, table cells, bullets, status lines, and the recommendation label under any numbered-options block.
350
365
 
351
- This pin exists because the trigger is not observable from the transcript alone: slash-command and skill bodies arrive in the user role and can be long and English, which is what drove the 626 wrong-language turns measured in the 30-session audit this hook was built from. Tool output, file contents, and an injected skill body are NOT the trigger \u2014 this pin is.
366
+ Tool output, file contents, and an injected skill body are NOT the trigger \u2014 this pin is.
352
367
  </language-pin>`;
353
368
  }
354
369
  function _loadState(target) {
@@ -716,7 +731,8 @@ import { fileURLToPath as fileURLToPath2, pathToFileURL as pathToFileURL2 } from
716
731
  // src/scripts/_lib/machine_wake.ts
717
732
  var MACHINE_WAKE_PREFIXES = [
718
733
  "<task-notification>",
719
- "<system-reminder>"
734
+ "<system-reminder>",
735
+ "<agent-message"
720
736
  ];
721
737
  function humanTypedThisTurn(prompt) {
722
738
  const head = prompt.trimStart();
@@ -1927,8 +1943,8 @@ var COMMAND_OBJECTS = {
1927
1943
  };
1928
1944
 
1929
1945
  // src/scripts/hooks/turn_end_gate_hook.ts
1930
- import * as fs8 from "node:fs";
1931
- import * as path7 from "node:path";
1946
+ import * as fs12 from "node:fs";
1947
+ import * as path10 from "node:path";
1932
1948
  import { fileURLToPath as fileURLToPath6, pathToFileURL as pathToFileURL6 } from "node:url";
1933
1949
 
1934
1950
  // src/scripts/check_reply_consistency.ts
@@ -2307,6 +2323,891 @@ function detectDroppedDecision(assistantTurnTexts, closingFromPayload = false) {
2307
2323
  return null;
2308
2324
  }
2309
2325
 
2326
+ // src/scripts/_lib/graph_feeder_record.ts
2327
+ import * as fs7 from "node:fs";
2328
+ import * as path6 from "node:path";
2329
+
2330
+ // src/scripts/code_graph/detect.ts
2331
+ import { execFileSync } from "node:child_process";
2332
+ import * as fs4 from "node:fs";
2333
+ import * as path4 from "node:path";
2334
+
2335
+ // src/scripts/code_graph/types.ts
2336
+ var GUESS_RESOLVED_VIA = /* @__PURE__ */ new Set([
2337
+ "name-lookup",
2338
+ "dynamic",
2339
+ // The accepted-edge filter is a DENYLIST, so a new value is accepted by
2340
+ // default — which is exactly backwards for this one. `foreign` must be
2341
+ // listed here or a consumer's graph would silently answer the gate verbs
2342
+ // as if this package had resolved its edges.
2343
+ "foreign"
2344
+ ]);
2345
+ function isStatedResolution(resolved_via) {
2346
+ return !GUESS_RESOLVED_VIA.has(resolved_via);
2347
+ }
2348
+ var SCHEMA_VERSION = 4;
2349
+ var EXT_LANG = {
2350
+ ".php": "php",
2351
+ ".ts": "typescript",
2352
+ ".tsx": "typescript",
2353
+ ".mts": "typescript",
2354
+ ".cts": "typescript",
2355
+ ".js": "javascript",
2356
+ ".jsx": "javascript",
2357
+ ".mjs": "javascript",
2358
+ ".cjs": "javascript"
2359
+ };
2360
+
2361
+ // src/scripts/code_graph/validate.ts
2362
+ var RELATIONS = /* @__PURE__ */ new Set(["calls", "imports", "uses", "inherits", "member", "tests"]);
2363
+ var CONFIDENCES = /* @__PURE__ */ new Set(["EXTRACTED", "INFERRED", "AMBIGUOUS"]);
2364
+ var RESOLVED_VIA = /* @__PURE__ */ new Set([
2365
+ "same-file",
2366
+ "import-specifier",
2367
+ "path-alias",
2368
+ "psr4",
2369
+ "route-table",
2370
+ "test-import",
2371
+ "name-lookup",
2372
+ "dynamic",
2373
+ // Adapted from a consumer's own graph file; see `foreign.ts`.
2374
+ "foreign"
2375
+ ]);
2376
+ var PROVIDERS = /* @__PURE__ */ new Set(["native", "foreign"]);
2377
+ var KINDS = /* @__PURE__ */ new Set([
2378
+ "file",
2379
+ "class",
2380
+ "interface",
2381
+ "trait",
2382
+ "function",
2383
+ "method",
2384
+ "constant",
2385
+ "type",
2386
+ "enum",
2387
+ "skipped"
2388
+ ]);
2389
+ function validateGraph(g) {
2390
+ const errors = [];
2391
+ const push = (m) => {
2392
+ if (errors.length < 50) errors.push(m);
2393
+ };
2394
+ if (typeof g !== "object" || g === null) return { ok: false, errors: ["graph is not an object"] };
2395
+ const obj = g;
2396
+ if (typeof obj["schema_version"] !== "number") push("schema_version must be a number");
2397
+ if (typeof obj["source_checksum"] !== "string") push("source_checksum must be a string");
2398
+ if (!Array.isArray(obj["nodes"])) push("nodes must be an array");
2399
+ if (!Array.isArray(obj["edges"])) push("edges must be an array");
2400
+ if (errors.length) return { ok: false, errors };
2401
+ const nodes = obj["nodes"];
2402
+ const ids = /* @__PURE__ */ new Set();
2403
+ nodes.forEach((n, i) => {
2404
+ if (typeof n !== "object" || n === null) return push(`node[${i}] not an object`);
2405
+ const nn = n;
2406
+ if (typeof nn["id"] !== "string") push(`node[${i}].id must be a string`);
2407
+ else ids.add(nn["id"]);
2408
+ if (!KINDS.has(nn["kind"])) push(`node[${i}].kind invalid: ${String(nn["kind"])}`);
2409
+ if (typeof nn["source_file"] !== "string") push(`node[${i}].source_file must be a string`);
2410
+ if (!Array.isArray(nn["source_location"])) push(`node[${i}].source_location must be an array`);
2411
+ });
2412
+ obj["edges"].forEach((e, i) => {
2413
+ if (typeof e !== "object" || e === null) return push(`edge[${i}] not an object`);
2414
+ const ee = e;
2415
+ if (typeof ee["source"] !== "string") push(`edge[${i}].source must be a string`);
2416
+ if (typeof ee["target"] !== "string") push(`edge[${i}].target must be a string`);
2417
+ if (!RELATIONS.has(ee["relation"])) push(`edge[${i}].relation invalid: ${String(ee["relation"])}`);
2418
+ if (!CONFIDENCES.has(ee["confidence"]))
2419
+ push(`edge[${i}].confidence invalid: ${String(ee["confidence"])}`);
2420
+ if (ee["resolved_via"] === void 0) push(`edge[${i}].resolved_via is required`);
2421
+ else if (!RESOLVED_VIA.has(ee["resolved_via"]))
2422
+ push(`edge[${i}].resolved_via invalid: ${String(ee["resolved_via"])}`);
2423
+ if (ee["provider"] === void 0) push(`edge[${i}].provider is required`);
2424
+ else if (!PROVIDERS.has(ee["provider"]))
2425
+ push(`edge[${i}].provider invalid: ${String(ee["provider"])}`);
2426
+ if (typeof ee["source"] === "string" && !ids.has(ee["source"]))
2427
+ push(`edge[${i}].source is not a known node: ${String(ee["source"])}`);
2428
+ if (ee["candidates"] !== void 0 && !Array.isArray(ee["candidates"]))
2429
+ push(`edge[${i}].candidates must be an array when present`);
2430
+ });
2431
+ return { ok: errors.length === 0, errors };
2432
+ }
2433
+
2434
+ // src/scripts/code_graph/detect.ts
2435
+ var CONSUMER_CANDIDATES = ["graph.json", "code-graph.json", ".code-graph/graph.json"];
2436
+ function consumerCandidates(root) {
2437
+ let declared;
2438
+ try {
2439
+ const settings = load_agent_settings({ cwd: root }) ?? {};
2440
+ const section = settings["code_graph"];
2441
+ declared = section !== null && typeof section === "object" && !Array.isArray(section) ? section["consumer_index_paths"] : void 0;
2442
+ } catch {
2443
+ declared = void 0;
2444
+ }
2445
+ const extra = Array.isArray(declared) ? declared.filter(
2446
+ (p) => typeof p === "string" && p !== "" && !path4.isAbsolute(p) && !path4.normalize(p).startsWith("..")
2447
+ ) : [];
2448
+ return [...CONSUMER_CANDIDATES, ...extra.filter((p) => !CONSUMER_CANDIDATES.includes(p))];
2449
+ }
2450
+ function gitLastCommitEpoch(root) {
2451
+ try {
2452
+ const out = execFileSync("git", ["-C", root, "log", "-1", "--format=%ct"], {
2453
+ env: hardenedSpawnEnv(),
2454
+ encoding: "utf-8",
2455
+ stdio: ["ignore", "pipe", "ignore"]
2456
+ }).trim();
2457
+ const n = Number(out);
2458
+ return Number.isFinite(n) ? n : null;
2459
+ } catch {
2460
+ return null;
2461
+ }
2462
+ }
2463
+ function commitsBehind(root, sha) {
2464
+ try {
2465
+ const out = execFileSync("git", ["-C", root, "rev-list", "--count", `${sha}..HEAD`], {
2466
+ env: hardenedSpawnEnv(),
2467
+ encoding: "utf-8",
2468
+ stdio: ["ignore", "pipe", "ignore"]
2469
+ }).trim();
2470
+ const n = Number(out);
2471
+ return Number.isFinite(n) ? n : null;
2472
+ } catch {
2473
+ return null;
2474
+ }
2475
+ }
2476
+ function freshness(root, file, embeddedSha) {
2477
+ if (embeddedSha) {
2478
+ const behind = commitsBehind(root, embeddedSha);
2479
+ if (behind !== null) return { stale: behind > 0, commits_behind: behind };
2480
+ }
2481
+ const last = gitLastCommitEpoch(root);
2482
+ if (last === null) return {};
2483
+ try {
2484
+ const mtime = Math.floor(fs4.statSync(file).mtimeMs / 1e3);
2485
+ return { stale: mtime < last };
2486
+ } catch {
2487
+ return {};
2488
+ }
2489
+ }
2490
+ function looksLikeGraph(p) {
2491
+ try {
2492
+ const raw = JSON.parse(fs4.readFileSync(p, "utf-8"));
2493
+ if (validateGraph(raw).ok) return { ok: true, sha: raw["head_at_build"] ?? null };
2494
+ const nodes = raw["nodes"];
2495
+ const edges = raw["edges"] ?? raw["links"];
2496
+ const okShape = Array.isArray(nodes) && Array.isArray(edges) && (edges.length === 0 || typeof edges[0] === "object" && edges[0] !== null && "source" in edges[0] && "target" in edges[0]);
2497
+ return { ok: okShape, sha: raw["head_at_build"] ?? null };
2498
+ } catch {
2499
+ return { ok: false, sha: null };
2500
+ }
2501
+ }
2502
+ function detectSources(root, nativeCache) {
2503
+ const abs = path4.resolve(root);
2504
+ const out = [];
2505
+ for (const rel of consumerCandidates(abs)) {
2506
+ const p = path4.join(abs, rel);
2507
+ if (fs4.existsSync(p)) {
2508
+ const { ok, sha } = looksLikeGraph(p);
2509
+ if (ok) out.push({ kind: "consumer", path: p, present: true, ...freshness(abs, p, sha) });
2510
+ }
2511
+ }
2512
+ const scipCandidates = [path4.join(abs, "index.scip")];
2513
+ try {
2514
+ for (const e of fs4.readdirSync(abs)) if (e.endsWith(".scip")) scipCandidates.push(path4.join(abs, e));
2515
+ } catch {
2516
+ }
2517
+ const scip = scipCandidates.find((p) => fs4.existsSync(p));
2518
+ if (scip) out.push({ kind: "scip", path: scip, present: true, note: "SCIP detected \u2014 peer tooling required (no owned reader)" });
2519
+ if (fs4.existsSync(nativeCache)) out.push({ kind: "native", path: nativeCache, present: true, ...freshness(abs, nativeCache, null) });
2520
+ return out;
2521
+ }
2522
+ function pickSource(verdicts) {
2523
+ const consumer = verdicts.find((v) => v.kind === "consumer" && v.stale !== true);
2524
+ if (consumer) return consumer;
2525
+ const native = verdicts.find((v) => v.kind === "native");
2526
+ if (native) return native;
2527
+ return verdicts.find((v) => v.kind === "consumer") ?? null;
2528
+ }
2529
+ var NATIVE_CACHE_REL = path4.join("agents", "runtime", "state", "code-graph-v1.json");
2530
+ function hasUncommittedIndexedEdit(root) {
2531
+ let out;
2532
+ try {
2533
+ out = execFileSync("git", ["-C", root, "status", "--porcelain", "--untracked-files=all"], {
2534
+ env: hardenedSpawnEnv(),
2535
+ encoding: "utf-8",
2536
+ stdio: ["ignore", "pipe", "ignore"],
2537
+ // Both bounds are the review's: Node's 1 MB default would throw
2538
+ // ENOBUFS on a large working tree, the catch below would return
2539
+ // false, and the state would read `fresh` — a second silent
2540
+ // under-report on a probe that runs at PreToolUse and at every stop.
2541
+ // The timeout bounds the other failure: this probe sits in front of
2542
+ // a tool call, so a hung git must not hold one up.
2543
+ maxBuffer: 32 * 1024 * 1024,
2544
+ timeout: 5e3
2545
+ });
2546
+ } catch {
2547
+ return false;
2548
+ }
2549
+ for (const raw of out.split("\n")) {
2550
+ if (raw.length < 4) continue;
2551
+ let p = raw.slice(3);
2552
+ const arrow = p.indexOf(" -> ");
2553
+ if (arrow !== -1) p = p.slice(arrow + 4);
2554
+ p = p.trim().replace(/^"|"$/g, "");
2555
+ const dot = p.lastIndexOf(".");
2556
+ if (dot === -1) continue;
2557
+ if (p.slice(dot).toLowerCase() in EXT_LANG) return true;
2558
+ }
2559
+ return false;
2560
+ }
2561
+ function graphState(root, nativeCache) {
2562
+ const picked = pickSource(detectSources(root, nativeCache ?? path4.join(root, NATIVE_CACHE_REL)));
2563
+ if (!picked) return "absent";
2564
+ if (picked.stale === true) {
2565
+ const behind = picked.commits_behind;
2566
+ return `behind:${typeof behind === "number" ? behind : 0}`;
2567
+ }
2568
+ return hasUncommittedIndexedEdit(root) ? "edited" : "fresh";
2569
+ }
2570
+
2571
+ // src/scripts/code_graph/query.ts
2572
+ import * as fs6 from "node:fs";
2573
+
2574
+ // src/scripts/code_graph/sqlite_store.ts
2575
+ import * as fs5 from "node:fs";
2576
+ var GRAPH_STORE_VERSION = 4;
2577
+ var INDEXED_READ_MIN_EDGES = 5e4;
2578
+ function sqliteTwinPath(jsonPath) {
2579
+ return jsonPath.endsWith(".json") ? `${jsonPath.slice(0, -5)}.sqlite3` : `${jsonPath}.sqlite3`;
2580
+ }
2581
+ function emitSqliteTwin(graph, serialized, jsonPath) {
2582
+ if (!isSqliteAvailableSync()) return false;
2583
+ const twin = sqliteTwinPath(jsonPath);
2584
+ const tmp = `${twin}.tmp-${process.pid}`;
2585
+ try {
2586
+ const { DatabaseSync } = loadSqliteSync("code_graph.sqlite_store");
2587
+ let stat;
2588
+ try {
2589
+ stat = fs5.statSync(jsonPath);
2590
+ } catch {
2591
+ return false;
2592
+ }
2593
+ fs5.rmSync(tmp, { force: true });
2594
+ const db = new DatabaseSync(tmp);
2595
+ try {
2596
+ db.exec("PRAGMA journal_mode = MEMORY");
2597
+ db.exec(
2598
+ "CREATE TABLE meta (key TEXT PRIMARY KEY, value TEXT NOT NULL);CREATE TABLE nodes (id TEXT PRIMARY KEY, label TEXT NOT NULL, kind TEXT, source_file TEXT, l0 INTEGER, l1 INTEGER, l2 INTEGER, l3 INTEGER);CREATE TABLE edges (source TEXT NOT NULL, target TEXT NOT NULL, relation TEXT NOT NULL, confidence TEXT NOT NULL, candidates TEXT, ambiguity_reason TEXT, resolved_via TEXT, provider TEXT);CREATE INDEX edges_source ON edges(source);CREATE INDEX edges_target ON edges(target);CREATE INDEX nodes_label ON nodes(label);CREATE INDEX nodes_source_file ON nodes(source_file);"
2599
+ );
2600
+ const meta = db.prepare("INSERT INTO meta (key, value) VALUES (?, ?)");
2601
+ meta.run("source_checksum", graph.source_checksum);
2602
+ meta.run("json_size", String(stat.size));
2603
+ meta.run("json_mtime_ms", String(stat.mtimeMs));
2604
+ meta.run("graph_json", serialized);
2605
+ meta.run("node_count", String(graph.nodes.length));
2606
+ meta.run("edge_count", String(graph.edges.length));
2607
+ const insNode = db.prepare(
2608
+ "INSERT INTO nodes (id, label, kind, source_file, l0, l1, l2, l3) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"
2609
+ );
2610
+ for (const n of graph.nodes) {
2611
+ const loc = n.source_location ?? [];
2612
+ insNode.run(
2613
+ n.id,
2614
+ n.label,
2615
+ n.kind ?? null,
2616
+ n.source_file ?? null,
2617
+ loc[0] ?? null,
2618
+ loc[1] ?? null,
2619
+ loc[2] ?? null,
2620
+ loc[3] ?? null
2621
+ );
2622
+ }
2623
+ const insEdge = db.prepare(
2624
+ "INSERT INTO edges (source, target, relation, confidence, candidates, ambiguity_reason, resolved_via, provider) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"
2625
+ );
2626
+ for (const e of graph.edges) {
2627
+ insEdge.run(
2628
+ e.source,
2629
+ e.target,
2630
+ e.relation,
2631
+ e.confidence,
2632
+ e.candidates ? JSON.stringify(e.candidates) : null,
2633
+ e.ambiguity_reason ?? null,
2634
+ e.resolved_via,
2635
+ e.provider
2636
+ );
2637
+ }
2638
+ stampUserVersion(db, GRAPH_STORE_VERSION);
2639
+ } finally {
2640
+ db.close();
2641
+ }
2642
+ fs5.renameSync(tmp, twin);
2643
+ return true;
2644
+ } catch {
2645
+ fs5.rmSync(tmp, { force: true });
2646
+ return false;
2647
+ }
2648
+ }
2649
+ function loadSerializedFromTwin(jsonPath) {
2650
+ if (!isSqliteAvailableSync()) return null;
2651
+ const twin = sqliteTwinPath(jsonPath);
2652
+ if (!fs5.existsSync(twin)) return null;
2653
+ let stat;
2654
+ try {
2655
+ stat = fs5.statSync(jsonPath);
2656
+ } catch {
2657
+ return null;
2658
+ }
2659
+ try {
2660
+ const { DatabaseSync } = loadSqliteSync("code_graph.sqlite_store");
2661
+ const db = new DatabaseSync(twin, { readOnly: true });
2662
+ try {
2663
+ if (readUserVersion(db) !== GRAPH_STORE_VERSION) return null;
2664
+ const rows = db.prepare("SELECT key, value FROM meta").all();
2665
+ const meta = new Map(rows.map((r) => [r.key, r.value]));
2666
+ if (meta.get("json_size") !== String(stat.size)) return null;
2667
+ if (meta.get("json_mtime_ms") !== String(stat.mtimeMs)) return null;
2668
+ const serialized = meta.get("graph_json");
2669
+ return serialized && serialized.length > 0 ? serialized : null;
2670
+ } finally {
2671
+ db.close();
2672
+ }
2673
+ } catch {
2674
+ fs5.rmSync(twin, { force: true });
2675
+ return null;
2676
+ }
2677
+ }
2678
+ function toNode(r) {
2679
+ const loc = [r.l0, r.l1, r.l2, r.l3].filter((v) => typeof v === "number");
2680
+ return {
2681
+ id: r.id,
2682
+ label: r.label,
2683
+ kind: r.kind ?? "file",
2684
+ source_file: r.source_file ?? "",
2685
+ source_location: loc
2686
+ };
2687
+ }
2688
+ function toEdge(r) {
2689
+ const e = {
2690
+ source: r.source,
2691
+ target: r.target,
2692
+ relation: r.relation,
2693
+ confidence: r.confidence,
2694
+ // The SQL columns are nullable, the TypeScript fields are not. A null
2695
+ // can only come from a twin emitted before these fields existed, which
2696
+ // GRAPH_STORE_VERSION already refuses — so this coalesce is unreachable
2697
+ // in a healthy tree and is written to fail READABLE rather than to
2698
+ // fabricate: `name-lookup` is the weakest mechanism, so a mislabelled
2699
+ // edge is under-trusted rather than over-trusted by Phase 3's filter.
2700
+ resolved_via: r.resolved_via ?? "name-lookup",
2701
+ provider: r.provider ?? "native"
2702
+ };
2703
+ if (r.candidates) e.candidates = JSON.parse(r.candidates);
2704
+ if (r.ambiguity_reason === "receiver-unknown" || r.ambiguity_reason === "hierarchy-unresolved") {
2705
+ e.ambiguity_reason = r.ambiguity_reason;
2706
+ }
2707
+ return e;
2708
+ }
2709
+ function openGraphIndex(jsonPath) {
2710
+ if (!isSqliteAvailableSync()) return null;
2711
+ const twin = sqliteTwinPath(jsonPath);
2712
+ if (!fs5.existsSync(twin)) return null;
2713
+ let stat;
2714
+ try {
2715
+ stat = fs5.statSync(jsonPath);
2716
+ } catch {
2717
+ return null;
2718
+ }
2719
+ try {
2720
+ const { DatabaseSync } = loadSqliteSync("code_graph.sqlite_store");
2721
+ const db = new DatabaseSync(twin, { readOnly: true });
2722
+ try {
2723
+ if (readUserVersion(db) !== GRAPH_STORE_VERSION) {
2724
+ db.close();
2725
+ return null;
2726
+ }
2727
+ const rows = db.prepare("SELECT key, value FROM meta").all();
2728
+ const meta = new Map(rows.map((r) => [r.key, r.value]));
2729
+ if (meta.get("json_size") !== String(stat.size) || meta.get("json_mtime_ms") !== String(stat.mtimeMs)) {
2730
+ db.close();
2731
+ return null;
2732
+ }
2733
+ const nodeCount = Number(meta.get("node_count") ?? NaN);
2734
+ const edgeCount = Number(meta.get("edge_count") ?? NaN);
2735
+ if (!Number.isFinite(nodeCount) || !Number.isFinite(edgeCount)) {
2736
+ db.close();
2737
+ return null;
2738
+ }
2739
+ const qNode = db.prepare("SELECT * FROM nodes WHERE id = ?");
2740
+ const qFrom = db.prepare("SELECT * FROM edges WHERE source = ?");
2741
+ const qTo = db.prepare("SELECT * FROM edges WHERE target = ?");
2742
+ const qLabel = db.prepare("SELECT id FROM nodes WHERE label = ? LIMIT ?");
2743
+ return {
2744
+ nodeCount,
2745
+ edgeCount,
2746
+ sourceChecksum: meta.get("source_checksum") ?? "",
2747
+ getNode(id) {
2748
+ const r = qNode.get(id);
2749
+ return r ? toNode(r) : void 0;
2750
+ },
2751
+ hasNode(id) {
2752
+ return qNode.get(id) !== void 0;
2753
+ },
2754
+ edgesFrom(id) {
2755
+ return qFrom.all(id).map(toEdge);
2756
+ },
2757
+ edgesTo(id) {
2758
+ return qTo.all(id).map(toEdge);
2759
+ },
2760
+ idsByLabel(labelText, limit) {
2761
+ return qLabel.all(labelText, limit).map((r) => r.id);
2762
+ },
2763
+ idsInFiles(files) {
2764
+ if (files.length === 0) return [];
2765
+ const out = [];
2766
+ const CHUNK = 400;
2767
+ for (let i = 0; i < files.length; i += CHUNK) {
2768
+ const slice = files.slice(i, i + CHUNK);
2769
+ const marks = slice.map(() => "?").join(",");
2770
+ const stmt = db.prepare(
2771
+ `SELECT id FROM nodes WHERE kind != 'file' AND source_file IN (${marks})`
2772
+ );
2773
+ for (const r of stmt.all(...slice)) out.push(r.id);
2774
+ }
2775
+ return out;
2776
+ },
2777
+ allNodeIds() {
2778
+ return db.prepare("SELECT id FROM nodes ORDER BY id").all().map(
2779
+ (r) => r.id
2780
+ );
2781
+ },
2782
+ lexicalCorpus() {
2783
+ return db.prepare("SELECT id, label FROM nodes").all().map(
2784
+ (r) => ({ id: r.id, text: `${r.label} ${r.id}` })
2785
+ );
2786
+ },
2787
+ close() {
2788
+ db.close();
2789
+ }
2790
+ };
2791
+ } catch (err) {
2792
+ db.close();
2793
+ throw err;
2794
+ }
2795
+ } catch {
2796
+ return null;
2797
+ }
2798
+ }
2799
+
2800
+ // src/scripts/code_graph/foreign.ts
2801
+ import { createHash } from "node:crypto";
2802
+ var RELATION_MAP = {
2803
+ calls: "calls",
2804
+ call: "calls",
2805
+ invokes: "calls",
2806
+ imports: "imports",
2807
+ import: "imports",
2808
+ requires: "imports",
2809
+ uses: "uses",
2810
+ use: "uses",
2811
+ references: "uses",
2812
+ inherits: "inherits",
2813
+ extends: "inherits",
2814
+ implements: "inherits",
2815
+ member: "member",
2816
+ contains: "member",
2817
+ tests: "tests",
2818
+ test: "tests"
2819
+ };
2820
+ var KINDS2 = /* @__PURE__ */ new Set([
2821
+ "file",
2822
+ "class",
2823
+ "interface",
2824
+ "trait",
2825
+ "function",
2826
+ "method",
2827
+ "constant",
2828
+ "type",
2829
+ "enum",
2830
+ "skipped"
2831
+ ]);
2832
+ function isObject(v) {
2833
+ return typeof v === "object" && v !== null && !Array.isArray(v);
2834
+ }
2835
+ function looksForeign(doc) {
2836
+ if (!isObject(doc)) return false;
2837
+ if (!Array.isArray(doc["nodes"])) return false;
2838
+ if (Array.isArray(doc["links"])) return true;
2839
+ return Array.isArray(doc["edges"]) && typeof doc["schema_version"] !== "number";
2840
+ }
2841
+ function adaptForeignGraph(doc) {
2842
+ if (!isObject(doc)) return null;
2843
+ const rawNodes = doc["nodes"];
2844
+ const rawEdges = doc["links"] ?? doc["edges"];
2845
+ if (!Array.isArray(rawNodes) || !Array.isArray(rawEdges)) return null;
2846
+ const nodes = [];
2847
+ const ids = /* @__PURE__ */ new Set();
2848
+ for (const n of rawNodes) {
2849
+ if (!isObject(n)) continue;
2850
+ const id = n["id"];
2851
+ if (typeof id !== "string" || id === "") continue;
2852
+ const kind = typeof n["kind"] === "string" && KINDS2.has(n["kind"]) ? n["kind"] : "skipped";
2853
+ const sourceFile = typeof n["source_file"] === "string" ? n["source_file"] : typeof n["file"] === "string" ? n["file"] : "";
2854
+ nodes.push({
2855
+ id,
2856
+ label: typeof n["label"] === "string" ? n["label"] : id,
2857
+ kind,
2858
+ source_file: sourceFile,
2859
+ // A foreign node rarely carries a span. An empty one is honest —
2860
+ // it says "no location recorded", where a fabricated [1,1] would
2861
+ // point a reader at the top of a file for no reason.
2862
+ source_location: Array.isArray(n["source_location"]) ? n["source_location"] : []
2863
+ });
2864
+ ids.add(id);
2865
+ }
2866
+ const edges = [];
2867
+ const unmapped = {};
2868
+ let malformed = 0;
2869
+ for (const e of rawEdges) {
2870
+ if (!isObject(e)) {
2871
+ malformed += 1;
2872
+ continue;
2873
+ }
2874
+ const source = e["source"];
2875
+ const target = e["target"];
2876
+ if (typeof source !== "string" || typeof target !== "string" || !ids.has(source)) {
2877
+ malformed += 1;
2878
+ continue;
2879
+ }
2880
+ const rawRelation = typeof e["relation"] === "string" ? e["relation"] : "";
2881
+ const relation = RELATION_MAP[rawRelation.toLowerCase()];
2882
+ if (relation === void 0) {
2883
+ const key = rawRelation === "" ? "(none)" : rawRelation;
2884
+ unmapped[key] = (unmapped[key] ?? 0) + 1;
2885
+ continue;
2886
+ }
2887
+ edges.push({
2888
+ source,
2889
+ target,
2890
+ relation,
2891
+ // Not EXTRACTED: this package did not extract it and cannot say
2892
+ // how the tool that did arrived at it.
2893
+ confidence: "AMBIGUOUS",
2894
+ resolved_via: "foreign",
2895
+ provider: "foreign"
2896
+ });
2897
+ }
2898
+ const counts = { EXTRACTED: 0, INFERRED: 0, AMBIGUOUS: edges.length };
2899
+ const graph = {
2900
+ schema_version: SCHEMA_VERSION,
2901
+ source_checksum: createHash("sha256").update(JSON.stringify(doc), "utf-8").digest("hex"),
2902
+ languages: [],
2903
+ grammar_abi: 0,
2904
+ edge_confidence_counts: counts,
2905
+ suppressed_edge_counts: { dynamic_no_candidate: 0 },
2906
+ nodes,
2907
+ edges
2908
+ };
2909
+ return { graph, unmapped_relations: unmapped, malformed_edges: malformed };
2910
+ }
2911
+
2912
+ // src/scripts/code_graph/query.ts
2913
+ function indexBackedGraph(index, source, answeredBy) {
2914
+ const nodeCache = /* @__PURE__ */ new Map();
2915
+ const readNode = (id) => {
2916
+ if (nodeCache.has(id)) return nodeCache.get(id);
2917
+ const n = index.getNode(id);
2918
+ nodeCache.set(id, n);
2919
+ return n;
2920
+ };
2921
+ let lexical = null;
2922
+ return {
2923
+ graph: null,
2924
+ source,
2925
+ answeredBy,
2926
+ byId: { get: readNode, has: (id) => readNode(id) !== void 0 },
2927
+ out: { get: (id) => index.edgesFrom(id) },
2928
+ in: { get: (id) => index.edgesTo(id) },
2929
+ idsByLabel: (labelText, limit) => index.idsByLabel(labelText, limit),
2930
+ idsInFiles: (files) => index.idsInFiles(files),
2931
+ allNodeIds: () => index.allNodeIds(),
2932
+ lex: () => {
2933
+ lexical ??= new LexicalIndex(index.lexicalCorpus());
2934
+ return lexical;
2935
+ },
2936
+ close: () => index.close()
2937
+ };
2938
+ }
2939
+ function loadGraph(graphPath, source = graphPath) {
2940
+ const index = openGraphIndex(graphPath);
2941
+ if (index) {
2942
+ if (index.edgeCount >= INDEXED_READ_MIN_EDGES) return indexBackedGraph(index, source, graphPath);
2943
+ index.close();
2944
+ }
2945
+ const fromTwin = loadSerializedFromTwin(graphPath);
2946
+ const raw = fromTwin ?? fs6.readFileSync(graphPath, "utf-8");
2947
+ const parsed = JSON.parse(raw);
2948
+ let foreignAdapted = false;
2949
+ let candidate = parsed;
2950
+ if (looksForeign(parsed)) {
2951
+ const adapted = adaptForeignGraph(parsed);
2952
+ if (adapted !== null) {
2953
+ candidate = adapted.graph;
2954
+ foreignAdapted = true;
2955
+ }
2956
+ }
2957
+ const v = validateGraph(candidate);
2958
+ if (!v.ok) throw new Error(`invalid graph at ${graphPath}: ${v.errors.slice(0, 3).join("; ")}`);
2959
+ const graph = candidate;
2960
+ if (fromTwin === null && !foreignAdapted) {
2961
+ emitSqliteTwin(graph, raw, graphPath);
2962
+ }
2963
+ const byId = new Map(graph.nodes.map((n) => [n.id, n]));
2964
+ const outM = /* @__PURE__ */ new Map();
2965
+ const inM = /* @__PURE__ */ new Map();
2966
+ const add = (m, k, e) => {
2967
+ const arr = m.get(k);
2968
+ if (arr) arr.push(e);
2969
+ else m.set(k, [e]);
2970
+ };
2971
+ for (const e of graph.edges) {
2972
+ add(outM, e.source, e);
2973
+ add(inM, e.target, e);
2974
+ }
2975
+ const lex = new LexicalIndex(graph.nodes.map((n) => ({ id: n.id, text: `${n.label} ${n.id}` })));
2976
+ return {
2977
+ graph,
2978
+ source,
2979
+ answeredBy: graphPath,
2980
+ byId,
2981
+ out: outM,
2982
+ in: inM,
2983
+ idsByLabel: (labelText, limit) => graph.nodes.filter((n) => n.label === labelText).slice(0, limit).map((n) => n.id),
2984
+ idsInFiles: (files) => {
2985
+ const set = new Set(files);
2986
+ return graph.nodes.filter((n) => set.has(n.source_file) && n.kind !== "file").map((n) => n.id);
2987
+ },
2988
+ allNodeIds: () => graph.nodes.map((n) => n.id).sort((a, b) => a < b ? -1 : a > b ? 1 : 0),
2989
+ lex: () => lex,
2990
+ close: () => {
2991
+ }
2992
+ };
2993
+ }
2994
+ function resolveSeedsTiered(g, seed, limit = 5) {
2995
+ if (g.byId.has(seed)) return { ids: [seed], weak: false };
2996
+ const exactLabel = g.idsByLabel(seed, limit);
2997
+ if (exactLabel.length) return { ids: exactLabel, weak: false };
2998
+ const ranked = g.lex().rank(tokenize(seed)).filter((r) => r.score > 0);
2999
+ return { ids: ranked.slice(0, limit).map((r) => r.id), weak: true };
3000
+ }
3001
+ function resolveSeeds(g, seed, limit = 5) {
3002
+ return resolveSeedsTiered(g, seed, limit).ids;
3003
+ }
3004
+
3005
+ // src/scripts/code_graph/verbs.ts
3006
+ import * as path5 from "node:path";
3007
+ function isAcceptedEdge(e) {
3008
+ return isStatedResolution(e.resolved_via);
3009
+ }
3010
+ function foreignRefusal(g) {
3011
+ const edges = g.graph?.edges ?? [];
3012
+ if (edges.length === 0) return null;
3013
+ if (!edges.every((e) => e.resolved_via === "foreign")) return null;
3014
+ return 'every edge in this graph was read from a file this package did not build, so all of them are guesses and none is gate-grade. A gate verb would accept no edge and report an empty answer, which reads as "nothing found" rather than "nothing trusted". Build a native graph (`agent-config graph build`) to use this verb, or use `query` and `explain`, which answer from foreign edges and say so.';
3015
+ }
3016
+ function viaHistogram(edges) {
3017
+ const counts = /* @__PURE__ */ new Map();
3018
+ for (const e of edges) counts.set(e.resolved_via, (counts.get(e.resolved_via) ?? 0) + 1);
3019
+ if (counts.size === 0) return "(none)";
3020
+ return [...counts.entries()].sort((a, b) => b[1] - a[1] || (a[0] < b[0] ? -1 : 1)).map(([via, n]) => `${via} ${n}`).join(" \xB7 ");
3021
+ }
3022
+ function readFor(g, id) {
3023
+ const n = g.byId.get(id);
3024
+ if (!n) return null;
3025
+ const loc = n.source_location;
3026
+ return { path: n.source_file, lines: loc.length >= 3 ? [loc[0], loc[2]] : null };
3027
+ }
3028
+ function dedupeReads(reads) {
3029
+ const m = /* @__PURE__ */ new Map();
3030
+ for (const r of reads) {
3031
+ if (!r) continue;
3032
+ m.set(r.lines ? `${r.path}:${r.lines[0]}-${r.lines[1]}` : r.path, r);
3033
+ }
3034
+ return [...m.values()];
3035
+ }
3036
+ function seedsForFiles(g, files) {
3037
+ const symbols = g.idsInFiles(files);
3038
+ const seeds = new Set(symbols);
3039
+ const unresolved = [];
3040
+ const notIndexed = [];
3041
+ for (const f of files) {
3042
+ if (g.byId.has(f)) {
3043
+ seeds.add(f);
3044
+ continue;
3045
+ }
3046
+ if (symbols.some((s) => s.startsWith(`${f}#`))) continue;
3047
+ if (EXT_LANG[path5.extname(f).toLowerCase()] === void 0) notIndexed.push(f);
3048
+ else unresolved.push(f);
3049
+ }
3050
+ return {
3051
+ seeds: [...seeds].sort(),
3052
+ unresolved: unresolved.sort(),
3053
+ not_indexed: notIndexed.sort()
3054
+ };
3055
+ }
3056
+ function testsFor(g, symbol, state) {
3057
+ const seeds = resolveSeeds(g, symbol);
3058
+ const targets = new Set(seeds);
3059
+ for (const s of seeds) {
3060
+ const f = g.byId.get(s)?.source_file;
3061
+ if (f && g.byId.has(f)) targets.add(f);
3062
+ }
3063
+ const accepted = [];
3064
+ const rejected = [];
3065
+ const tests = /* @__PURE__ */ new Set();
3066
+ for (const t of targets) {
3067
+ for (const e of g.in.get(t) ?? []) {
3068
+ if (e.relation !== "tests") continue;
3069
+ if (!isAcceptedEdge(e)) {
3070
+ rejected.push(e);
3071
+ continue;
3072
+ }
3073
+ accepted.push(e);
3074
+ tests.add(e.source);
3075
+ }
3076
+ }
3077
+ const list = [...tests].sort();
3078
+ return {
3079
+ source: g.source,
3080
+ state,
3081
+ accepted_via: viaHistogram(accepted),
3082
+ rejected_via: viaHistogram(rejected),
3083
+ seeds,
3084
+ tests: list,
3085
+ accepted_edges: accepted,
3086
+ rejected_edges: rejected,
3087
+ lines: list,
3088
+ recommended_reads: dedupeReads(list.map((t) => readFor(g, t)))
3089
+ };
3090
+ }
3091
+ function untested(g, files, state) {
3092
+ const foreign = foreignRefusal(g);
3093
+ if (foreign !== null) {
3094
+ return {
3095
+ source: g.source,
3096
+ state,
3097
+ accepted_via: "(none)",
3098
+ rejected_via: "(none)",
3099
+ refusal: foreign,
3100
+ refusal_reason: "foreign-edges-not-accepted",
3101
+ seeds: [],
3102
+ unresolved_files: [],
3103
+ not_indexed_files: [],
3104
+ untested: [],
3105
+ tested: [],
3106
+ lines: [],
3107
+ recommended_reads: []
3108
+ };
3109
+ }
3110
+ const { seeds, unresolved, not_indexed } = seedsForFiles(g, files);
3111
+ const accepted = [];
3112
+ const rejected = [];
3113
+ const tested = [];
3114
+ const bare = [];
3115
+ for (const s of seeds) {
3116
+ if (g.byId.get(s)?.kind === "file") continue;
3117
+ const r = testsFor(g, s, state);
3118
+ accepted.push(...r.accepted_edges);
3119
+ rejected.push(...r.rejected_edges);
3120
+ if (r.tests.length) tested.push(s);
3121
+ else bare.push(s);
3122
+ }
3123
+ return {
3124
+ source: g.source,
3125
+ state,
3126
+ accepted_via: viaHistogram(accepted),
3127
+ rejected_via: viaHistogram(rejected),
3128
+ refusal: null,
3129
+ refusal_reason: null,
3130
+ seeds,
3131
+ unresolved_files: unresolved,
3132
+ not_indexed_files: not_indexed,
3133
+ untested: bare.sort(),
3134
+ tested: tested.sort(),
3135
+ lines: bare.sort(),
3136
+ recommended_reads: dedupeReads(bare.map((b) => readFor(g, b)))
3137
+ };
3138
+ }
3139
+
3140
+ // src/scripts/_lib/graph_feeder_record.ts
3141
+ var MAX_PATHS = 5;
3142
+ var MAX_ROWS_PER_SESSION = 200;
3143
+ function feederFile(workspaceRoot, sessionKey) {
3144
+ return path6.join(workspaceRoot, "agents", "state", "graph-feeder", `${sessionKey}.jsonl`);
3145
+ }
3146
+ function graphUntestedVerdict(root, state, paths) {
3147
+ const none = { verdict: null, untested: 0, tested: 0 };
3148
+ if (state !== "fresh" && state !== "edited") return none;
3149
+ if (paths.length === 0) return none;
3150
+ let picked;
3151
+ try {
3152
+ picked = pickSource(detectSources(root, path6.join(root, NATIVE_CACHE_REL)));
3153
+ } catch {
3154
+ return none;
3155
+ }
3156
+ if (!picked || picked.kind === "scip") return none;
3157
+ let g;
3158
+ try {
3159
+ g = loadGraph(picked.path, `${picked.kind}:${path6.relative(root, picked.path)}`);
3160
+ } catch {
3161
+ return none;
3162
+ }
3163
+ try {
3164
+ const r = untested(g, paths, state);
3165
+ if (r.seeds.length === 0) return { verdict: "no-seeds", untested: 0, tested: 0 };
3166
+ return {
3167
+ verdict: r.untested.length > 0 ? "untested" : "tested",
3168
+ untested: r.untested.length,
3169
+ tested: r.tested.length
3170
+ };
3171
+ } catch {
3172
+ return none;
3173
+ } finally {
3174
+ try {
3175
+ g.close();
3176
+ } catch {
3177
+ }
3178
+ }
3179
+ }
3180
+ function appendFeederRow(workspaceRoot, sessionKey, row) {
3181
+ try {
3182
+ const file = feederFile(workspaceRoot, sessionKey);
3183
+ let existing = 0;
3184
+ try {
3185
+ existing = fs7.readFileSync(file, "utf-8").split("\n").filter((l) => l.trim() !== "").length;
3186
+ } catch {
3187
+ }
3188
+ if (existing >= MAX_ROWS_PER_SESSION) return;
3189
+ fs7.mkdirSync(path6.dirname(file), { recursive: true });
3190
+ fs7.appendFileSync(file, `${JSON.stringify(row)}
3191
+ `);
3192
+ } catch {
3193
+ }
3194
+ }
3195
+ function buildFeederRow(input) {
3196
+ return {
3197
+ at: input.at ?? (/* @__PURE__ */ new Date()).toISOString(),
3198
+ turn: input.turn,
3199
+ layer: input.layer,
3200
+ graph_state: input.state,
3201
+ f: input.fFired,
3202
+ f_mode: input.fMode,
3203
+ graph: input.graph.verdict,
3204
+ graph_untested: input.graph.untested,
3205
+ graph_tested: input.graph.tested,
3206
+ paths: input.paths.slice(0, MAX_PATHS).map((p) => p),
3207
+ path_count: input.paths.length
3208
+ };
3209
+ }
3210
+
2310
3211
  // src/scripts/hooks/envelope.ts
2311
3212
  var ENVELOPE_KEYS = [
2312
3213
  "schema_version",
@@ -2363,8 +3264,8 @@ function unwrap(stdin_text, default_platform = "generic") {
2363
3264
 
2364
3265
  // src/scripts/hooks/subagent_ledger_hook.ts
2365
3266
  import * as crypto from "node:crypto";
2366
- import * as fs4 from "node:fs";
2367
- import * as path4 from "node:path";
3267
+ import * as fs8 from "node:fs";
3268
+ import * as path7 from "node:path";
2368
3269
  import { fileURLToPath as fileURLToPath4, pathToFileURL as pathToFileURL4 } from "node:url";
2369
3270
 
2370
3271
  // src/scripts/_lib/subagent_response.ts
@@ -2498,15 +3399,15 @@ var EXIT_CODES = Object.freeze([
2498
3399
  name: "error",
2499
3400
  meaning: "the concern crashed, timed out, or could not decide \u2014 any rc >= 3. The dispatcher resolves it by the concern`s declared severity, never by the number itself",
2500
3401
  owner: "no concern emits this on purpose; the runtime does",
2501
- authorizedBy: "hook_manifest.yaml `fail_closed` and `severity` together \u2014 see docs/contracts/hook-architecture-v1.md \xA7 Exit-code semantics"
3402
+ authorizedBy: "hook_manifest.yaml `severity` alone \u2014 blocking refuses, anything else fails open; `fail_closed` is no longer read on this branch. See docs/contracts/hook-architecture-v1.md \xA7 Exit-code semantics"
2502
3403
  })
2503
3404
  ]);
2504
3405
 
2505
3406
  // src/scripts/hooks/subagent_ledger_hook.ts
2506
- function isObject(v) {
3407
+ function isObject2(v) {
2507
3408
  return typeof v === "object" && v !== null && !Array.isArray(v);
2508
3409
  }
2509
- var LEDGER_DIR = path4.join("agents", "runtime", "state", "subagent-ledger");
3410
+ var LEDGER_DIR = path7.join("agents", "runtime", "state", "subagent-ledger");
2510
3411
  var OPEN_SUBDIR = "open";
2511
3412
  var OPEN_RECORD_TTL_MS = 24 * 60 * 60 * 1e3;
2512
3413
  function refFor(agentId) {
@@ -2514,7 +3415,7 @@ function refFor(agentId) {
2514
3415
  }
2515
3416
  function unwrapPayload(envelope) {
2516
3417
  const inner = envelope["payload"];
2517
- return isObject(inner) ? inner : envelope;
3418
+ return isObject2(inner) ? inner : envelope;
2518
3419
  }
2519
3420
  function str(payload, ...keys) {
2520
3421
  for (const k of keys) {
@@ -2527,7 +3428,7 @@ function extractParentId(payload, ownId) {
2527
3428
  const explicit = str(payload, "parent_agent_id", "parentAgentId");
2528
3429
  if (explicit) return explicit;
2529
3430
  const session = payload["session"];
2530
- if (isObject(session)) {
3431
+ if (isObject2(session)) {
2531
3432
  const sessionAgent = str(session, "agent_id", "agentId");
2532
3433
  if (sessionAgent && sessionAgent !== ownId) return sessionAgent;
2533
3434
  }
@@ -2596,14 +3497,14 @@ function _jsonObjectCandidates(message) {
2596
3497
  return out;
2597
3498
  }
2598
3499
  function openDir(root) {
2599
- return path4.join(root, LEDGER_DIR, OPEN_SUBDIR);
3500
+ return path7.join(root, LEDGER_DIR, OPEN_SUBDIR);
2600
3501
  }
2601
3502
  function openFile(root, ref) {
2602
- return path4.join(openDir(root), `${ref}.json`);
3503
+ return path7.join(openDir(root), `${ref}.json`);
2603
3504
  }
2604
3505
  var DEPTH_BASES = /* @__PURE__ */ new Set(["observed", "asserted-parent", "assumed-root"]);
2605
3506
  function _asOpenRecord(value, expectedRef) {
2606
- if (!isObject(value)) return null;
3507
+ if (!isObject2(value)) return null;
2607
3508
  const ref = value["ref"];
2608
3509
  if (typeof ref !== "string" || ref !== expectedRef) return null;
2609
3510
  if (typeof value["started_at"] !== "string") return null;
@@ -2626,7 +3527,7 @@ function readOpenRecords(root) {
2626
3527
  const out = /* @__PURE__ */ new Map();
2627
3528
  let names;
2628
3529
  try {
2629
- names = fs4.readdirSync(openDir(root));
3530
+ names = fs8.readdirSync(openDir(root));
2630
3531
  } catch {
2631
3532
  return out;
2632
3533
  }
@@ -2634,7 +3535,7 @@ function readOpenRecords(root) {
2634
3535
  if (!name.endsWith(".json")) continue;
2635
3536
  const expectedRef = name.slice(0, -".json".length);
2636
3537
  try {
2637
- const raw = fs4.readFileSync(path4.join(openDir(root), name), "utf8");
3538
+ const raw = fs8.readFileSync(path7.join(openDir(root), name), "utf8");
2638
3539
  const rec = _asOpenRecord(JSON.parse(raw), expectedRef);
2639
3540
  if (rec) out.set(rec.ref, rec);
2640
3541
  } catch {
@@ -2649,13 +3550,13 @@ function resolveDepth(parentRef, open) {
2649
3550
  return { depth: parent.depth + 1, depth_basis: "observed" };
2650
3551
  }
2651
3552
  function ledgerFileFor2(root, ts) {
2652
- return path4.join(root, LEDGER_DIR, `${ts.slice(0, 7)}.jsonl`);
3553
+ return path7.join(root, LEDGER_DIR, `${ts.slice(0, 7)}.jsonl`);
2653
3554
  }
2654
3555
  function appendLedgerLine(root, ts, line) {
2655
3556
  if (is_replay_mode()) return;
2656
3557
  const file = ledgerFileFor2(root, ts);
2657
- fs4.mkdirSync(path4.dirname(file), { recursive: true });
2658
- fs4.appendFileSync(file, `${JSON.stringify(line)}
3558
+ fs8.mkdirSync(path7.dirname(file), { recursive: true });
3559
+ fs8.appendFileSync(file, `${JSON.stringify(line)}
2659
3560
  `, "utf8");
2660
3561
  }
2661
3562
  var WALL_CLOCK_ARMS_MS = [
@@ -2669,7 +3570,7 @@ function armsExceeded(elapsedMs) {
2669
3570
  return WALL_CLOCK_ARMS_MS.filter((a) => elapsedMs >= a.ms).map((a) => a.label);
2670
3571
  }
2671
3572
  function openRecordStats(root, nowMs = Date.now()) {
2672
- const ledgerPresent = fs4.existsSync(path4.join(root, LEDGER_DIR));
3573
+ const ledgerPresent = fs8.existsSync(path7.join(root, LEDGER_DIR));
2673
3574
  const open = readOpenRecords(root);
2674
3575
  let maxDepth = 0;
2675
3576
  let counted = 0;
@@ -2697,13 +3598,13 @@ function writeOpenRecord(root, rec) {
2697
3598
  function removeOpenRecord(root, ref) {
2698
3599
  if (is_replay_mode()) return;
2699
3600
  try {
2700
- fs4.unlinkSync(openFile(root, ref));
3601
+ fs8.unlinkSync(openFile(root, ref));
2701
3602
  } catch {
2702
3603
  }
2703
3604
  }
2704
3605
  function countOpen(root) {
2705
3606
  try {
2706
- return fs4.readdirSync(openDir(root)).filter((n) => n.endsWith(".json")).length;
3607
+ return fs8.readdirSync(openDir(root)).filter((n) => n.endsWith(".json")).length;
2707
3608
  } catch {
2708
3609
  return 0;
2709
3610
  }
@@ -2830,7 +3731,7 @@ function handleStop(root, payload, nowIso, sessionId) {
2830
3731
  }
2831
3732
  function processEnvelope(envelope, consumerRoot) {
2832
3733
  try {
2833
- if (!isObject(envelope)) return EXIT_ALLOW3;
3734
+ if (!isObject2(envelope)) return EXIT_ALLOW3;
2834
3735
  const event = envelope["event"];
2835
3736
  if (event !== "subagent_start" && event !== "subagent_stop") return EXIT_ALLOW3;
2836
3737
  const payload = unwrapPayload(envelope);
@@ -2845,7 +3746,7 @@ function processEnvelope(envelope, consumerRoot) {
2845
3746
  return EXIT_ALLOW3;
2846
3747
  }
2847
3748
  function resolveConsumerRoot(envelope) {
2848
- if (isObject(envelope)) {
3749
+ if (isObject2(envelope)) {
2849
3750
  const pr = str(envelope, "workspace_root", "project_root");
2850
3751
  if (pr) return pr;
2851
3752
  const payload = unwrapPayload(envelope);
@@ -2869,10 +3770,10 @@ function _isCliEntry4() {
2869
3770
  return false;
2870
3771
  }
2871
3772
  if (process.argv[1] === void 0) return false;
2872
- const argvUrl = pathToFileURL4(path4.resolve(process.argv[1])).href;
3773
+ const argvUrl = pathToFileURL4(path7.resolve(process.argv[1])).href;
2873
3774
  if (import.meta.url === argvUrl) return true;
2874
3775
  try {
2875
- return fs4.realpathSync(fileURLToPath4(import.meta.url)) === fs4.realpathSync(path4.resolve(process.argv[1]));
3776
+ return fs8.realpathSync(fileURLToPath4(import.meta.url)) === fs8.realpathSync(path7.resolve(process.argv[1]));
2876
3777
  } catch {
2877
3778
  return false;
2878
3779
  }
@@ -2880,20 +3781,20 @@ function _isCliEntry4() {
2880
3781
  if (_isCliEntry4()) process.exit(main4());
2881
3782
 
2882
3783
  // src/scripts/_lib/turn_end_transcript.ts
2883
- import * as fs7 from "node:fs";
3784
+ import * as fs11 from "node:fs";
2884
3785
 
2885
3786
  // src/scripts/hooks/end_review_nudge_hook.ts
2886
3787
  import { spawnSync as spawnSync2 } from "node:child_process";
2887
3788
  import * as crypto2 from "node:crypto";
2888
- import * as fs6 from "node:fs";
3789
+ import * as fs10 from "node:fs";
2889
3790
  import * as os from "node:os";
2890
- import * as path6 from "node:path";
3791
+ import * as path9 from "node:path";
2891
3792
  import { fileURLToPath as fileURLToPath5, pathToFileURL as pathToFileURL5 } from "node:url";
2892
3793
 
2893
3794
  // src/scripts/_lib/review_baseline.ts
2894
3795
  import { spawnSync } from "node:child_process";
2895
- import * as fs5 from "node:fs";
2896
- import * as path5 from "node:path";
3796
+ import * as fs9 from "node:fs";
3797
+ import * as path8 from "node:path";
2897
3798
  function currentHeadSha(cwd) {
2898
3799
  try {
2899
3800
  const r = spawnSync("git", ["rev-parse", "HEAD"], { cwd, encoding: "utf8" });
@@ -2904,12 +3805,12 @@ function currentHeadSha(cwd) {
2904
3805
  return null;
2905
3806
  }
2906
3807
  }
2907
- var BASELINE_STATE_REL = path5.join("agents", "runtime", "state", "review-baseline");
3808
+ var BASELINE_STATE_REL = path8.join("agents", "runtime", "state", "review-baseline");
2908
3809
  function baselineStateDir(workspaceRoot) {
2909
- return path5.join(workspaceRoot, BASELINE_STATE_REL);
3810
+ return path8.join(workspaceRoot, BASELINE_STATE_REL);
2910
3811
  }
2911
3812
  function baselineStateFile(workspaceRoot, sessionKey) {
2912
- return path5.join(baselineStateDir(workspaceRoot), `${sessionKey}.json`);
3813
+ return path8.join(baselineStateDir(workspaceRoot), `${sessionKey}.json`);
2913
3814
  }
2914
3815
  function parseBaseline(raw) {
2915
3816
  let decoded;
@@ -2937,7 +3838,7 @@ function readBaseline(workspaceRoot, sessionKey) {
2937
3838
  const file = baselineStateFile(workspaceRoot, sessionKey);
2938
3839
  let raw;
2939
3840
  try {
2940
- raw = fs5.readFileSync(file, "utf-8");
3841
+ raw = fs9.readFileSync(file, "utf-8");
2941
3842
  } catch (exc) {
2942
3843
  const code = exc?.code;
2943
3844
  return code === "ENOENT" ? "absent" : "unreadable";
@@ -3047,13 +3948,13 @@ function isSafeTranscriptPath(rawPath, opts = {}) {
3047
3948
  const homeDir = opts.homeDir ?? os.homedir();
3048
3949
  const maxBytes = opts.maxBytes ?? TRANSCRIPT_SCAN_MAX_BYTES;
3049
3950
  try {
3050
- const realHome = fs6.realpathSync(homeDir);
3051
- const realPath = fs6.realpathSync(rawPath);
3052
- const relative3 = path6.relative(realHome, realPath);
3053
- if (relative3 === "" || relative3.startsWith("..") || path6.isAbsolute(relative3)) {
3951
+ const realHome = fs10.realpathSync(homeDir);
3952
+ const realPath = fs10.realpathSync(rawPath);
3953
+ const relative5 = path9.relative(realHome, realPath);
3954
+ if (relative5 === "" || relative5.startsWith("..") || path9.isAbsolute(relative5)) {
3054
3955
  return false;
3055
3956
  }
3056
- const { size } = fs6.statSync(realPath);
3957
+ const { size } = fs10.statSync(realPath);
3057
3958
  return size <= maxBytes;
3058
3959
  } catch {
3059
3960
  return false;
@@ -3111,13 +4012,13 @@ var BINARY_PROBE_BYTES = 8e3;
3111
4012
  var UNTRACKED_FILE_READ_CAP_BYTES = 8 * 1024 * 1024;
3112
4013
  function untrackedFileLineCount(cwd, relPath) {
3113
4014
  try {
3114
- const abs = path6.resolve(cwd, relPath);
3115
- const size = fs6.statSync(abs).size;
4015
+ const abs = path9.resolve(cwd, relPath);
4016
+ const size = fs10.statSync(abs).size;
3116
4017
  if (size === 0) return 0;
3117
4018
  if (size > UNTRACKED_FILE_READ_CAP_BYTES) {
3118
4019
  return MUTATION_LINE_THRESHOLD + 1;
3119
4020
  }
3120
- const buf = fs6.readFileSync(abs);
4021
+ const buf = fs10.readFileSync(abs);
3121
4022
  if (buf.length === 0) return 0;
3122
4023
  const probe = buf.subarray(0, Math.min(buf.length, BINARY_PROBE_BYTES));
3123
4024
  if (probe.includes(0)) return 0;
@@ -3143,7 +4044,7 @@ function totalNonDocMutatedLinesWithMeasure(cwd) {
3143
4044
  );
3144
4045
  return { lines: trackedLines + untrackedLines, measure: "exact" };
3145
4046
  }
3146
- function isObject2(v) {
4047
+ function isObject3(v) {
3147
4048
  return typeof v === "object" && v !== null && !Array.isArray(v);
3148
4049
  }
3149
4050
  function str2(v) {
@@ -3163,16 +4064,16 @@ function scanTranscriptForReviewer(transcriptText) {
3163
4064
  } catch {
3164
4065
  continue;
3165
4066
  }
3166
- if (!isObject2(obj) || obj["type"] !== "assistant") continue;
4067
+ if (!isObject3(obj) || obj["type"] !== "assistant") continue;
3167
4068
  const msg = obj["message"];
3168
- if (!isObject2(msg)) continue;
4069
+ if (!isObject3(msg)) continue;
3169
4070
  const content = msg["content"];
3170
4071
  if (!Array.isArray(content)) continue;
3171
4072
  for (const blk of content) {
3172
- if (!isObject2(blk) || blk["type"] !== "tool_use") continue;
4073
+ if (!isObject3(blk) || blk["type"] !== "tool_use") continue;
3173
4074
  const name = str2(blk["name"]);
3174
4075
  const input = blk["input"];
3175
- const inputObj = isObject2(input) ? input : {};
4076
+ const inputObj = isObject3(input) ? input : {};
3176
4077
  if (DISPATCH_TOOL_RE.test(name)) {
3177
4078
  const label = [
3178
4079
  str2(inputObj["description"]),
@@ -3208,19 +4109,19 @@ function appendReviewSkippedTelemetry(workspaceRoot, diffLines, mutationMeasure,
3208
4109
  });
3209
4110
  if (errors.length || line === null) return;
3210
4111
  try {
3211
- const dir = path6.join(workspaceRoot, "agents", "runtime", "state", "audit");
3212
- fs6.mkdirSync(dir, { recursive: true });
3213
- const file = path6.join(dir, `${ts.slice(0, 7)}.jsonl`);
3214
- fs6.appendFileSync(file, `${JSON.stringify(line)}
4112
+ const dir = path9.join(workspaceRoot, "agents", "runtime", "state", "audit");
4113
+ fs10.mkdirSync(dir, { recursive: true });
4114
+ const file = path9.join(dir, `${ts.slice(0, 7)}.jsonl`);
4115
+ fs10.appendFileSync(file, `${JSON.stringify(line)}
3215
4116
  `, "utf8");
3216
4117
  } catch {
3217
4118
  }
3218
4119
  }
3219
4120
  function sessionStateDir(workspaceRoot) {
3220
- return path6.join(workspaceRoot, "agents", "runtime", "state", "end-review-nudge");
4121
+ return path9.join(workspaceRoot, "agents", "runtime", "state", "end-review-nudge");
3221
4122
  }
3222
4123
  function sessionStateFile(workspaceRoot, sessionKey) {
3223
- return path6.join(sessionStateDir(workspaceRoot), `${sessionKey}.json`);
4124
+ return path9.join(sessionStateDir(workspaceRoot), `${sessionKey}.json`);
3224
4125
  }
3225
4126
  function deriveSessionKey2(envelope, payload) {
3226
4127
  const raw = str2(envelope["session_id"]) || str2(payload["transcript_path"] ?? payload["transcriptPath"]);
@@ -3229,7 +4130,7 @@ function deriveSessionKey2(envelope, payload) {
3229
4130
  }
3230
4131
  function hasFiredThisSession(workspaceRoot, sessionKey) {
3231
4132
  try {
3232
- return fs6.existsSync(sessionStateFile(workspaceRoot, sessionKey));
4133
+ return fs10.existsSync(sessionStateFile(workspaceRoot, sessionKey));
3233
4134
  } catch {
3234
4135
  return false;
3235
4136
  }
@@ -3291,7 +4192,7 @@ function main5() {
3291
4192
  let reviewerRan = false;
3292
4193
  if (transcriptPath && isSafeTranscriptPath(transcriptPath)) {
3293
4194
  try {
3294
- reviewerRan = scanTranscriptForReviewer(fs6.readFileSync(transcriptPath, "utf-8"));
4195
+ reviewerRan = scanTranscriptForReviewer(fs10.readFileSync(transcriptPath, "utf-8"));
3295
4196
  } catch {
3296
4197
  reviewerRan = false;
3297
4198
  }
@@ -3326,13 +4227,13 @@ function _isCliEntry5() {
3326
4227
  if (process.argv[1] === void 0) {
3327
4228
  return false;
3328
4229
  }
3329
- const argvUrl = pathToFileURL5(path6.resolve(process.argv[1])).href;
4230
+ const argvUrl = pathToFileURL5(path9.resolve(process.argv[1])).href;
3330
4231
  if (import.meta.url === argvUrl) {
3331
4232
  return true;
3332
4233
  }
3333
4234
  try {
3334
- const here = fs6.realpathSync(fileURLToPath5(import.meta.url));
3335
- const argv = fs6.realpathSync(path6.resolve(process.argv[1]));
4235
+ const here = fs10.realpathSync(fileURLToPath5(import.meta.url));
4236
+ const argv = fs10.realpathSync(path9.resolve(process.argv[1]));
3336
4237
  return here === argv;
3337
4238
  } catch {
3338
4239
  return false;
@@ -3353,10 +4254,10 @@ function readTranscriptTail(transcriptPath, opts = {}) {
3353
4254
  if (!transcriptPath || !isSafeTranscriptPath(transcriptPath, opts)) return empty;
3354
4255
  let lines;
3355
4256
  try {
3356
- if (opts.maxBytes !== void 0 && fs7.statSync(transcriptPath).size > opts.maxBytes) {
4257
+ if (opts.maxBytes !== void 0 && fs11.statSync(transcriptPath).size > opts.maxBytes) {
3357
4258
  return empty;
3358
4259
  }
3359
- lines = fs7.readFileSync(transcriptPath, "utf-8").split("\n");
4260
+ lines = fs11.readFileSync(transcriptPath, "utf-8").split("\n");
3360
4261
  } catch {
3361
4262
  return empty;
3362
4263
  }
@@ -3543,7 +4444,7 @@ function detectPromissory(reply) {
3543
4444
  function readCiSettled(workspaceRoot, session_id) {
3544
4445
  if (!hasStableSessionId(session_id)) return { seen: false, settled: false };
3545
4446
  try {
3546
- const raw = fs8.readFileSync(path7.join(workspaceRoot, statePathFor(session_id)), "utf-8");
4447
+ const raw = fs12.readFileSync(path10.join(workspaceRoot, statePathFor(session_id)), "utf-8");
3547
4448
  const decoded = JSON.parse(raw);
3548
4449
  if (!owns_session_state(decoded, session_id)) return { seen: false, settled: false };
3549
4450
  if (typeof decoded === "object" && decoded !== null && !Array.isArray(decoded)) {
@@ -3579,8 +4480,8 @@ function detectCompletionClaim(reply, ci) {
3579
4480
  function readLanguagePin(workspaceRoot, session_id) {
3580
4481
  if (!hasStableSessionId(session_id)) return "und";
3581
4482
  try {
3582
- const raw = fs8.readFileSync(
3583
- path7.join(workspaceRoot, statePathFor2(session_id)),
4483
+ const raw = fs12.readFileSync(
4484
+ path10.join(workspaceRoot, statePathFor2(session_id)),
3584
4485
  "utf-8"
3585
4486
  );
3586
4487
  const decoded = JSON.parse(raw);
@@ -3689,7 +4590,7 @@ function sessionStateFile2(workspaceRoot, sessionKey) {
3689
4590
  }
3690
4591
  function alreadyRefusedTurn(workspaceRoot, sessionKey, turnOrdinal) {
3691
4592
  try {
3692
- const raw = fs8.readFileSync(sessionStateFile2(workspaceRoot, sessionKey), "utf-8");
4593
+ const raw = fs12.readFileSync(sessionStateFile2(workspaceRoot, sessionKey), "utf-8");
3693
4594
  const decoded = JSON.parse(raw);
3694
4595
  if (typeof decoded === "object" && decoded !== null && !Array.isArray(decoded)) {
3695
4596
  return decoded["refused_turn"] === turnOrdinal;
@@ -3703,7 +4604,7 @@ function markRefusedTurn(workspaceRoot, sessionKey, turnOrdinal, detectors, prom
3703
4604
  const file = sessionStateFile2(workspaceRoot, sessionKey);
3704
4605
  let prev = null;
3705
4606
  try {
3706
- prev = parseRecord(fs8.readFileSync(file, "utf-8"));
4607
+ prev = parseRecord(fs12.readFileSync(file, "utf-8"));
3707
4608
  } catch {
3708
4609
  }
3709
4610
  let version;
@@ -3806,14 +4707,44 @@ function runDetectors(inputs) {
3806
4707
  }
3807
4708
  return findings;
3808
4709
  }
4710
+ function recordGraphFeeder(inputs, findings, layer) {
4711
+ if (is_replay_mode()) return;
4712
+ try {
4713
+ let state;
4714
+ try {
4715
+ state = graphState(inputs.workspaceRoot);
4716
+ } catch {
4717
+ return;
4718
+ }
4719
+ if (state === "absent") return;
4720
+ const paths = inputs.toolCalls.filter((c) => _EDIT_TOOLS.has(c.name) && c.path !== void 0).map((c) => c.path).filter(_isProductionSource);
4721
+ const f = findings.find((x) => x.detector === "untested");
4722
+ appendFeederRow(
4723
+ inputs.workspaceRoot,
4724
+ inputs.sessionKey,
4725
+ buildFeederRow({
4726
+ turn: inputs.turnOrdinal,
4727
+ layer,
4728
+ state,
4729
+ fFired: f !== void 0,
4730
+ fMode: f?.mode ?? null,
4731
+ paths,
4732
+ graph: graphUntestedVerdict(inputs.workspaceRoot, state, paths)
4733
+ })
4734
+ );
4735
+ } catch {
4736
+ }
4737
+ }
3809
4738
  function recordShadow(inputs, layer) {
3810
4739
  if (is_replay_mode()) return;
3811
4740
  try {
3812
4741
  const findings = runDetectors(inputs);
4742
+ const setBy = layer === "refused_turn" ? "ours" : shadowSetBy(inputs.workspaceRoot, inputs.sessionKey);
4743
+ recordGraphFeeder(inputs, findings, layer);
3813
4744
  const file = sessionShadowFile(inputs.workspaceRoot, inputs.sessionKey);
3814
4745
  let prev = null;
3815
4746
  try {
3816
- prev = parseShadowRecord(fs8.readFileSync(file, "utf-8"));
4747
+ prev = parseShadowRecord(fs12.readFileSync(file, "utf-8"));
3817
4748
  } catch {
3818
4749
  }
3819
4750
  atomic_write_json(
@@ -3822,7 +4753,8 @@ function recordShadow(inputs, layer) {
3822
4753
  detectors: findings.map((f) => f.detector),
3823
4754
  turnOrdinal: inputs.turnOrdinal,
3824
4755
  at: (/* @__PURE__ */ new Date()).toISOString(),
3825
- layer
4756
+ layer,
4757
+ setBy
3826
4758
  })
3827
4759
  );
3828
4760
  } catch {
@@ -3851,6 +4783,7 @@ function main6() {
3851
4783
  return EXIT_ALLOW3;
3852
4784
  }
3853
4785
  const findings = runDetectors(inputs);
4786
+ recordGraphFeeder(inputs, findings, "live");
3854
4787
  if (findings.length === 0) return EXIT_ALLOW3;
3855
4788
  markRefusedTurn(
3856
4789
  inputs.workspaceRoot,
@@ -3879,13 +4812,13 @@ function _isCliEntry6() {
3879
4812
  if (process.argv[1] === void 0) {
3880
4813
  return false;
3881
4814
  }
3882
- const argvUrl = pathToFileURL6(path7.resolve(process.argv[1])).href;
4815
+ const argvUrl = pathToFileURL6(path10.resolve(process.argv[1])).href;
3883
4816
  if (import.meta.url === argvUrl) {
3884
4817
  return true;
3885
4818
  }
3886
4819
  try {
3887
- const here = fs8.realpathSync(fileURLToPath6(import.meta.url));
3888
- const argv = fs8.realpathSync(path7.resolve(process.argv[1]));
4820
+ const here = fs12.realpathSync(fileURLToPath6(import.meta.url));
4821
+ const argv = fs12.realpathSync(path10.resolve(process.argv[1]));
3889
4822
  return here === argv;
3890
4823
  } catch {
3891
4824
  return false;
@@ -3898,8 +4831,8 @@ if (_isCliEntry6()) {
3898
4831
  // src/scripts/hooks/evidence_independence.ts
3899
4832
  import { spawnSync as spawnSync3 } from "node:child_process";
3900
4833
  import crypto3 from "node:crypto";
3901
- import fs9 from "node:fs";
3902
- import path8 from "node:path";
4834
+ import fs13 from "node:fs";
4835
+ import path11 from "node:path";
3903
4836
  import { fileURLToPath as fileURLToPath7, pathToFileURL as pathToFileURL7 } from "node:url";
3904
4837
 
3905
4838
  // src/scripts/_lib/test_delta.ts
@@ -3918,7 +4851,7 @@ function isTestPath(p) {
3918
4851
  }
3919
4852
 
3920
4853
  // src/scripts/hooks/evidence_independence.ts
3921
- var STATE_FILE3 = path8.join("agents", "state", "evidence-dispatch.json");
4854
+ var STATE_FILE3 = path11.join("agents", "state", "evidence-dispatch.json");
3922
4855
  function _isObject5(v) {
3923
4856
  return typeof v === "object" && v !== null && !Array.isArray(v);
3924
4857
  }
@@ -3986,8 +4919,8 @@ function extractDispatch(envelope) {
3986
4919
  }
3987
4920
  function _ledgerStamp(consumer_root) {
3988
4921
  try {
3989
- const raw = fs9.readFileSync(
3990
- path8.join(consumer_root, "agents", "state", "git-authorization.json"),
4922
+ const raw = fs13.readFileSync(
4923
+ path11.join(consumer_root, "agents", "state", "git-authorization.json"),
3991
4924
  "utf8"
3992
4925
  );
3993
4926
  const d = JSON.parse(raw);
@@ -3998,7 +4931,7 @@ function _ledgerStamp(consumer_root) {
3998
4931
  }
3999
4932
  function _load(target) {
4000
4933
  try {
4001
- const decoded = JSON.parse(fs9.readFileSync(target, "utf8"));
4934
+ const decoded = JSON.parse(fs13.readFileSync(target, "utf8"));
4002
4935
  if (_isObject5(decoded) && Array.isArray(decoded["evaluations"])) {
4003
4936
  return decoded;
4004
4937
  }
@@ -4082,7 +5015,7 @@ function run3(stdin_text, options) {
4082
5015
  return EXIT_ALLOW3;
4083
5016
  }
4084
5017
  }
4085
- const target = path8.join(options.consumer_root, STATE_FILE3);
5018
+ const target = path11.join(options.consumer_root, STATE_FILE3);
4086
5019
  const state = _load(target);
4087
5020
  const session_id = typeof envelope["session_id"] === "string" ? envelope["session_id"] : "";
4088
5021
  const turnMarker = `${session_id}:${_ledgerStamp(options.consumer_root)}`;
@@ -4150,13 +5083,13 @@ function _isCliEntry7() {
4150
5083
  if (process.argv[1] === void 0) {
4151
5084
  return false;
4152
5085
  }
4153
- const argvUrl = pathToFileURL7(path8.resolve(process.argv[1])).href;
5086
+ const argvUrl = pathToFileURL7(path11.resolve(process.argv[1])).href;
4154
5087
  if (import.meta.url === argvUrl) {
4155
5088
  return true;
4156
5089
  }
4157
5090
  try {
4158
- const here = fs9.realpathSync(fileURLToPath7(import.meta.url));
4159
- const argv = fs9.realpathSync(path8.resolve(process.argv[1]));
5091
+ const here = fs13.realpathSync(fileURLToPath7(import.meta.url));
5092
+ const argv = fs13.realpathSync(path11.resolve(process.argv[1]));
4160
5093
  return here === argv;
4161
5094
  } catch {
4162
5095
  return false;
@@ -4167,8 +5100,8 @@ if (_isCliEntry7()) {
4167
5100
  }
4168
5101
 
4169
5102
  // src/scripts/hooks/delegation_nudge_hook.ts
4170
- import fs10 from "node:fs";
4171
- import path9 from "node:path";
5103
+ import fs14 from "node:fs";
5104
+ import path12 from "node:path";
4172
5105
  import { fileURLToPath as fileURLToPath8, pathToFileURL as pathToFileURL8 } from "node:url";
4173
5106
 
4174
5107
  // src/scripts/_lib/auto_dispatch.ts
@@ -4668,13 +5601,13 @@ function _isCliEntry8() {
4668
5601
  if (process.argv[1] === void 0) {
4669
5602
  return false;
4670
5603
  }
4671
- const argvUrl = pathToFileURL8(path9.resolve(process.argv[1])).href;
5604
+ const argvUrl = pathToFileURL8(path12.resolve(process.argv[1])).href;
4672
5605
  if (import.meta.url === argvUrl) {
4673
5606
  return true;
4674
5607
  }
4675
5608
  try {
4676
- const here = fs10.realpathSync(fileURLToPath8(import.meta.url));
4677
- const argv = fs10.realpathSync(path9.resolve(process.argv[1]));
5609
+ const here = fs14.realpathSync(fileURLToPath8(import.meta.url));
5610
+ const argv = fs14.realpathSync(path12.resolve(process.argv[1]));
4678
5611
  return here === argv;
4679
5612
  } catch {
4680
5613
  return false;
@@ -4685,7 +5618,7 @@ if (_isCliEntry8()) {
4685
5618
  }
4686
5619
 
4687
5620
  // src/scripts/conformance_scan.ts
4688
- var REPO_ROOT = path10.resolve(path10.dirname(fileURLToPath9(import.meta.url)), "..", "..");
5621
+ var REPO_ROOT = path13.resolve(path13.dirname(fileURLToPath9(import.meta.url)), "..", "..");
4689
5622
  var OBSERVED_BAND = { low: 9.1, high: 39.2 };
4690
5623
  var BAND_MIN_TURNS = 1978;
4691
5624
  var CARRIER_CHANGES = [
@@ -5051,7 +5984,7 @@ function scanSession(sessionId, lines) {
5051
5984
  closeWindow();
5052
5985
  return report;
5053
5986
  }
5054
- var DEFAULT_RATE_SERIES = path10.join(
5987
+ var DEFAULT_RATE_SERIES = path13.join(
5055
5988
  REPO_ROOT,
5056
5989
  "agents",
5057
5990
  "runtime",
@@ -5060,7 +5993,7 @@ var DEFAULT_RATE_SERIES = path10.join(
5060
5993
  );
5061
5994
  function defaultStore(projectDir) {
5062
5995
  const slug = projectStoreSlug(projectDir);
5063
- return path10.join(process.env["HOME"] ?? "", ".claude", "projects", slug);
5996
+ return path13.join(process.env["HOME"] ?? "", ".claude", "projects", slug);
5064
5997
  }
5065
5998
  function _tokens(chars) {
5066
5999
  return Math.round(chars / 4);
@@ -5071,13 +6004,13 @@ function measureDelivered(projectRulesDir, globalRulesDir) {
5071
6004
  return {
5072
6005
  project: {
5073
6006
  dir: projectRulesDir,
5074
- present: fs11.existsSync(projectRulesDir),
6007
+ present: fs15.existsSync(projectRulesDir),
5075
6008
  files: p.files,
5076
6009
  tokens: _tokens(p.chars)
5077
6010
  },
5078
6011
  global: {
5079
6012
  dir: globalRulesDir,
5080
- present: fs11.existsSync(globalRulesDir),
6013
+ present: fs15.existsSync(globalRulesDir),
5081
6014
  files: g.files,
5082
6015
  tokens: _tokens(g.chars)
5083
6016
  },
@@ -5085,13 +6018,13 @@ function measureDelivered(projectRulesDir, globalRulesDir) {
5085
6018
  };
5086
6019
  }
5087
6020
  function storeKey(store) {
5088
- return createHash3("sha256").update(path10.resolve(store)).digest("hex").slice(0, 12);
6021
+ return createHash4("sha256").update(path13.resolve(store)).digest("hex").slice(0, 12);
5089
6022
  }
5090
6023
  function scanStore(store, limit) {
5091
- const files = fs11.readdirSync(store).filter((f) => f.endsWith(".jsonl")).map((f) => ({ f, m: fs11.statSync(path10.join(store, f)).mtimeMs })).sort((a, b) => b.m - a.m).slice(0, limit).map((x) => x.f);
6024
+ const files = fs15.readdirSync(store).filter((f) => f.endsWith(".jsonl")).map((f) => ({ f, m: fs15.statSync(path13.join(store, f)).mtimeMs })).sort((a, b) => b.m - a.m).slice(0, limit).map((x) => x.f);
5092
6025
  const per_session = [];
5093
6026
  for (const f of files) {
5094
- const lines = fs11.readFileSync(path10.join(store, f), "utf8").split("\n");
6027
+ const lines = fs15.readFileSync(path13.join(store, f), "utf8").split("\n");
5095
6028
  const r = scanSession(f.replace(/\.jsonl$/, "").slice(0, 8), lines);
5096
6029
  if (r.assistant_turns > 0) {
5097
6030
  per_session.push(r);
@@ -5119,10 +6052,10 @@ function scanStore(store, limit) {
5119
6052
  const task_completeness_rate_pct = completeness_windows === 0 ? 0 : Number((100 * task_completeness / completeness_windows).toFixed(1));
5120
6053
  const era = spansCarrierChange(per_session.map((s) => s.first_at));
5121
6054
  const delivered = measureDelivered(
5122
- path10.join(REPO_ROOT, ".claude", "rules"),
5123
- path10.join(process.env["HOME"] ?? os2.homedir(), ".claude", "rules")
6055
+ path13.join(REPO_ROOT, ".claude", "rules"),
6056
+ path13.join(process.env["HOME"] ?? os2.homedir(), ".claude", "rules")
5124
6057
  );
5125
- const ownStore = path10.resolve(store) === path10.resolve(defaultStore(REPO_ROOT));
6058
+ const ownStore = path13.resolve(store) === path13.resolve(defaultStore(REPO_ROOT));
5126
6059
  return {
5127
6060
  scanned_at: (/* @__PURE__ */ new Date()).toISOString(),
5128
6061
  store,
@@ -5152,8 +6085,8 @@ function scanStore(store, limit) {
5152
6085
  };
5153
6086
  }
5154
6087
  function recordRate(file, scanned_at, rate) {
5155
- fs11.mkdirSync(path10.dirname(file), { recursive: true });
5156
- fs11.appendFileSync(file, `${JSON.stringify({ measured_at: scanned_at, ...rate })}
6088
+ fs15.mkdirSync(path13.dirname(file), { recursive: true });
6089
+ fs15.appendFileSync(file, `${JSON.stringify({ measured_at: scanned_at, ...rate })}
5157
6090
  `, "utf8");
5158
6091
  }
5159
6092
  function render(report) {
@@ -5284,14 +6217,14 @@ function main9(argv) {
5284
6217
  return 2;
5285
6218
  }
5286
6219
  const resolved = store ?? defaultStore(process.cwd());
5287
- if (!fs11.existsSync(resolved)) {
6220
+ if (!fs15.existsSync(resolved)) {
5288
6221
  process.stderr.write(`conformance:behavior: no transcript store at ${resolved}
5289
6222
  `);
5290
6223
  return 1;
5291
6224
  }
5292
6225
  const report = scanStore(resolved, Number.isFinite(limit) && limit > 0 ? limit : 30);
5293
6226
  if (out) {
5294
- fs11.writeFileSync(out, `${JSON.stringify(report, null, 2)}
6227
+ fs15.writeFileSync(out, `${JSON.stringify(report, null, 2)}
5295
6228
  `, "utf8");
5296
6229
  }
5297
6230
  if (record) {
@@ -5299,7 +6232,7 @@ function main9(argv) {
5299
6232
  }
5300
6233
  if (why !== null) {
5301
6234
  const id = why;
5302
- fs11.writeSync(
6235
+ fs15.writeSync(
5303
6236
  1,
5304
6237
  json ? `${JSON.stringify(
5305
6238
  {
@@ -5319,7 +6252,7 @@ function main9(argv) {
5319
6252
  );
5320
6253
  return 0;
5321
6254
  }
5322
- fs11.writeSync(1, json ? `${JSON.stringify(report, null, 2)}
6255
+ fs15.writeSync(1, json ? `${JSON.stringify(report, null, 2)}
5323
6256
  ` : `${render(report)}
5324
6257
  `);
5325
6258
  return 0;
@@ -5331,13 +6264,13 @@ function _isCliEntry9() {
5331
6264
  if (process.argv[1] === void 0) {
5332
6265
  return false;
5333
6266
  }
5334
- const argvUrl = pathToFileURL9(path10.resolve(process.argv[1])).href;
6267
+ const argvUrl = pathToFileURL9(path13.resolve(process.argv[1])).href;
5335
6268
  if (import.meta.url === argvUrl) {
5336
6269
  return true;
5337
6270
  }
5338
6271
  try {
5339
- const here = fs11.realpathSync(fileURLToPath9(import.meta.url));
5340
- const argv = fs11.realpathSync(path10.resolve(process.argv[1]));
6272
+ const here = fs15.realpathSync(fileURLToPath9(import.meta.url));
6273
+ const argv = fs15.realpathSync(path13.resolve(process.argv[1]));
5341
6274
  return here === argv;
5342
6275
  } catch {
5343
6276
  return false;
@@ -5348,19 +6281,19 @@ if (_isCliEntry9()) {
5348
6281
  }
5349
6282
 
5350
6283
  // src/scripts/report_carrier_divergence.ts
5351
- import * as fs12 from "node:fs";
6284
+ import * as fs16 from "node:fs";
5352
6285
  import * as os3 from "node:os";
5353
- import * as path11 from "node:path";
6286
+ import * as path14 from "node:path";
5354
6287
  import process2 from "node:process";
5355
6288
  import { fileURLToPath as fileURLToPath10, pathToFileURL as pathToFileURL10 } from "node:url";
5356
6289
  var _HERE2 = fileURLToPath10(import.meta.url);
5357
- var REPO_ROOT2 = path11.resolve(path11.dirname(_HERE2), "..", "..");
5358
- var PROJECT_RULES = path11.join(".claude", "rules");
5359
- var PROJECTION_SOURCE = path11.join("dist", "agent-src", "rules");
5360
- var GLOBAL_RULES = path11.join(".claude", "rules");
6290
+ var REPO_ROOT2 = path14.resolve(path14.dirname(_HERE2), "..", "..");
6291
+ var PROJECT_RULES = path14.join(".claude", "rules");
6292
+ var PROJECTION_SOURCE = path14.join("dist", "agent-src", "rules");
6293
+ var GLOBAL_RULES = path14.join(".claude", "rules");
5361
6294
  function _listRules(dir) {
5362
6295
  try {
5363
- return fs12.readdirSync(dir).filter((f) => f.endsWith(".md")).sort();
6296
+ return fs16.readdirSync(dir).filter((f) => f.endsWith(".md")).sort();
5364
6297
  } catch {
5365
6298
  return [];
5366
6299
  }
@@ -5368,7 +6301,7 @@ function _listRules(dir) {
5368
6301
  function _ruleType(file) {
5369
6302
  let text;
5370
6303
  try {
5371
- text = fs12.readFileSync(file, "utf-8");
6304
+ text = fs16.readFileSync(file, "utf-8");
5372
6305
  } catch {
5373
6306
  return "";
5374
6307
  }
@@ -5379,8 +6312,8 @@ function compareCarriers(projectDir, globalDir, sourceDir) {
5379
6312
  const out = {
5380
6313
  projectDir,
5381
6314
  globalDir,
5382
- globalPresent: fs12.existsSync(globalDir),
5383
- projectPresent: fs12.existsSync(projectDir),
6315
+ globalPresent: fs16.existsSync(globalDir),
6316
+ projectPresent: fs16.existsSync(projectDir),
5384
6317
  shared: 0,
5385
6318
  identical: [],
5386
6319
  provenanceOnly: [],
@@ -5403,7 +6336,7 @@ function compareCarriers(projectDir, globalDir, sourceDir) {
5403
6336
  }
5404
6337
  if (!inP && inG) {
5405
6338
  out.globalOnly.push(rule);
5406
- if (sourceDir !== void 0 && _ruleType(path11.join(sourceDir, rule)) === "manual") {
6339
+ if (sourceDir !== void 0 && _ruleType(path14.join(sourceDir, rule)) === "manual") {
5407
6340
  out.manualOnlyGlobal.push(rule);
5408
6341
  }
5409
6342
  continue;
@@ -5413,8 +6346,8 @@ function compareCarriers(projectDir, globalDir, sourceDir) {
5413
6346
  let projectCopy;
5414
6347
  let globalCopy;
5415
6348
  try {
5416
- projectCopy = fs12.readFileSync(path11.join(projectDir, rule));
5417
- globalCopy = fs12.readFileSync(path11.join(globalDir, rule));
6349
+ projectCopy = fs16.readFileSync(path14.join(projectDir, rule));
6350
+ globalCopy = fs16.readFileSync(path14.join(globalDir, rule));
5418
6351
  verdict = comparePair(projectCopy, globalCopy);
5419
6352
  } catch {
5420
6353
  out.shared -= 1;
@@ -5561,9 +6494,9 @@ function render2(d) {
5561
6494
  }
5562
6495
  function main10(argv) {
5563
6496
  const args = argv ?? process2.argv.slice(2);
5564
- let projectDir = path11.join(REPO_ROOT2, PROJECT_RULES);
5565
- let globalDir = path11.join(os3.homedir(), GLOBAL_RULES);
5566
- let sourceDir = path11.join(REPO_ROOT2, PROJECTION_SOURCE);
6497
+ let projectDir = path14.join(REPO_ROOT2, PROJECT_RULES);
6498
+ let globalDir = path14.join(os3.homedir(), GLOBAL_RULES);
6499
+ let sourceDir = path14.join(REPO_ROOT2, PROJECTION_SOURCE);
5567
6500
  const value = (i) => {
5568
6501
  const v = args[i + 1];
5569
6502
  return v === void 0 || v.startsWith("-") ? null : v;
@@ -5577,7 +6510,7 @@ function main10(argv) {
5577
6510
  `);
5578
6511
  return 1;
5579
6512
  }
5580
- const resolved = path11.resolve(v);
6513
+ const resolved = path14.resolve(v);
5581
6514
  if (a === "--project") projectDir = resolved;
5582
6515
  else if (a === "--global") globalDir = resolved;
5583
6516
  else sourceDir = resolved;
@@ -5599,9 +6532,9 @@ function main10(argv) {
5599
6532
  }
5600
6533
  function _isCliEntry10() {
5601
6534
  if (process2.argv[1] === void 0) return false;
5602
- if (import.meta.url === pathToFileURL10(path11.resolve(process2.argv[1])).href) return true;
6535
+ if (import.meta.url === pathToFileURL10(path14.resolve(process2.argv[1])).href) return true;
5603
6536
  try {
5604
- return fs12.realpathSync(_HERE2) === fs12.realpathSync(path11.resolve(process2.argv[1]));
6537
+ return fs16.realpathSync(_HERE2) === fs16.realpathSync(path14.resolve(process2.argv[1]));
5605
6538
  } catch {
5606
6539
  return false;
5607
6540
  }
@@ -5611,12 +6544,12 @@ if (_isCliEntry10()) {
5611
6544
  }
5612
6545
 
5613
6546
  // src/scripts/report_skill_activation.ts
5614
- import * as fs13 from "node:fs";
6547
+ import * as fs17 from "node:fs";
5615
6548
  import * as os4 from "node:os";
5616
- import * as path12 from "node:path";
6549
+ import * as path15 from "node:path";
5617
6550
  import { fileURLToPath as fileURLToPath11, pathToFileURL as pathToFileURL11 } from "node:url";
5618
6551
  var _HERE3 = fileURLToPath11(import.meta.url);
5619
- var REPO_ROOT3 = path12.resolve(path12.dirname(_HERE3), "..", "..");
6552
+ var REPO_ROOT3 = path15.resolve(path15.dirname(_HERE3), "..", "..");
5620
6553
  var SKILLS_ROOT = "src/skills";
5621
6554
  var TRIGGER_KEYS = ["triggers:", "trigger_description:", "file_pattern:", "path_prefix:"];
5622
6555
  var DETERMINISTIC_RE = /^\s*(?:[-*]\s*)?(?:\*\*)?(MUST|NEVER|ALWAYS)\b/m;
@@ -5627,25 +6560,25 @@ function censusSkills(root) {
5627
6560
  withTriggerCorpus: [],
5628
6561
  withDeterministicObligation: []
5629
6562
  };
5630
- if (!fs13.existsSync(root)) {
6563
+ if (!fs17.existsSync(root)) {
5631
6564
  return out;
5632
6565
  }
5633
- for (const entry of fs13.readdirSync(root, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
6566
+ for (const entry of fs17.readdirSync(root, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
5634
6567
  if (!entry.isDirectory()) {
5635
6568
  continue;
5636
6569
  }
5637
- const file = path12.join(root, entry.name, "SKILL.md");
5638
- if (!fs13.existsSync(file)) {
6570
+ const file = path15.join(root, entry.name, "SKILL.md");
6571
+ if (!fs17.existsSync(file)) {
5639
6572
  continue;
5640
6573
  }
5641
6574
  out.total += 1;
5642
- const text = fs13.readFileSync(file, "utf8");
6575
+ const text = fs17.readFileSync(file, "utf8");
5643
6576
  const fmEnd = text.startsWith("---") ? text.indexOf("\n---", 3) : -1;
5644
6577
  const fm = fmEnd === -1 ? "" : text.slice(0, fmEnd);
5645
6578
  if (TRIGGER_KEYS.some((k) => new RegExp(`^${k}`, "m").test(fm))) {
5646
6579
  out.withTriggerKey.push(entry.name);
5647
6580
  }
5648
- if (fs13.existsSync(path12.join(root, entry.name, "evals", "triggers.json"))) {
6581
+ if (fs17.existsSync(path15.join(root, entry.name, "evals", "triggers.json"))) {
5649
6582
  out.withTriggerCorpus.push(entry.name);
5650
6583
  }
5651
6584
  const body = fmEnd === -1 ? text : text.slice(fmEnd + 4);
@@ -5656,17 +6589,17 @@ function censusSkills(root) {
5656
6589
  return out;
5657
6590
  }
5658
6591
  function defaultStore2(cwd) {
5659
- return path12.join(os4.homedir(), ".claude", "projects", projectStoreSlug(cwd));
6592
+ return path15.join(os4.homedir(), ".claude", "projects", projectStoreSlug(cwd));
5660
6593
  }
5661
6594
  function measureUsage(store, limit) {
5662
6595
  const rep = { store, sessions: 0, assistantTurns: 0, invocations: 0, bySkill: {} };
5663
- if (!fs13.existsSync(store)) {
6596
+ if (!fs17.existsSync(store)) {
5664
6597
  return rep;
5665
6598
  }
5666
- const files = fs13.readdirSync(store).filter((f) => f.endsWith(".jsonl")).map((f) => path12.join(store, f)).sort((a, b) => fs13.statSync(b).mtimeMs - fs13.statSync(a).mtimeMs).slice(0, limit);
6599
+ const files = fs17.readdirSync(store).filter((f) => f.endsWith(".jsonl")).map((f) => path15.join(store, f)).sort((a, b) => fs17.statSync(b).mtimeMs - fs17.statSync(a).mtimeMs).slice(0, limit);
5667
6600
  rep.sessions = files.length;
5668
6601
  for (const file of files) {
5669
- for (const line of fs13.readFileSync(file, "utf8").split("\n")) {
6602
+ for (const line of fs17.readFileSync(file, "utf8").split("\n")) {
5670
6603
  if (!line.trim()) {
5671
6604
  continue;
5672
6605
  }
@@ -5739,15 +6672,15 @@ function buildRecord(census, usage, today) {
5739
6672
  assistant_turns: usage.reduce((a, u) => a + u.assistantTurns, 0),
5740
6673
  invocations: usage.reduce((a, u) => a + u.invocations, 0),
5741
6674
  distinct_skills_invoked: distinct.size,
5742
- stores: usage.map((u) => path12.basename(u.store))
6675
+ stores: usage.map((u) => path15.basename(u.store))
5743
6676
  };
5744
6677
  }
5745
6678
  function readRecord(repoRoot) {
5746
- const file = path12.join(repoRoot, RECORD_PATH);
5747
- if (!fs13.existsSync(file)) {
6679
+ const file = path15.join(repoRoot, RECORD_PATH);
6680
+ if (!fs17.existsSync(file)) {
5748
6681
  return null;
5749
6682
  }
5750
- return JSON.parse(fs13.readFileSync(file, "utf8"));
6683
+ return JSON.parse(fs17.readFileSync(file, "utf8"));
5751
6684
  }
5752
6685
  function render3(census, usage, published = null) {
5753
6686
  const lines = [];
@@ -5782,7 +6715,7 @@ function render3(census, usage, published = null) {
5782
6715
  }
5783
6716
  totalInv += u.invocations;
5784
6717
  lines.push(
5785
- ` ${path12.basename(u.store).slice(-38).padEnd(38)} sessions=${String(u.sessions).padStart(3)} asst=${String(u.assistantTurns).padStart(6)} Skill calls=${String(u.invocations).padStart(3)}`
6718
+ ` ${path15.basename(u.store).slice(-38).padEnd(38)} sessions=${String(u.sessions).padStart(3)} asst=${String(u.assistantTurns).padStart(6)} Skill calls=${String(u.invocations).padStart(3)}`
5786
6719
  );
5787
6720
  }
5788
6721
  lines.push("");
@@ -5886,7 +6819,7 @@ function main11(argv) {
5886
6819
  if (stores.length === 0) {
5887
6820
  stores.push(defaultStore2(REPO_ROOT3));
5888
6821
  }
5889
- const census = censusSkills(path12.join(root, SKILLS_ROOT));
6822
+ const census = censusSkills(path15.join(root, SKILLS_ROOT));
5890
6823
  const usage = stores.map((s) => measureUsage(s, limit));
5891
6824
  process.stdout.write(`${render3(census, usage, readRecord(root))}
5892
6825
  `);
@@ -5907,27 +6840,27 @@ function main11(argv) {
5907
6840
  return 1;
5908
6841
  }
5909
6842
  const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
5910
- const file = path12.join(root, RECORD_PATH);
5911
- fs13.mkdirSync(path12.dirname(file), { recursive: true });
5912
- fs13.writeFileSync(file, `${JSON.stringify(buildRecord(census, usage, today), null, 2)}
6843
+ const file = path15.join(root, RECORD_PATH);
6844
+ fs17.mkdirSync(path15.dirname(file), { recursive: true });
6845
+ fs17.writeFileSync(file, `${JSON.stringify(buildRecord(census, usage, today), null, 2)}
5913
6846
  `);
5914
6847
  process.stdout.write(`
5915
6848
  wrote ${RECORD_PATH} (measured ${today})
5916
6849
  `);
5917
6850
  return 0;
5918
6851
  }
5919
- if (process.argv[1] !== void 0 && import.meta.url === pathToFileURL11(path12.resolve(process.argv[1])).href) {
6852
+ if (process.argv[1] !== void 0 && import.meta.url === pathToFileURL11(path15.resolve(process.argv[1])).href) {
5920
6853
  process.exit(main11(process.argv.slice(2)));
5921
6854
  }
5922
6855
 
5923
6856
  // src/scripts/report_skill_obligation_violations.ts
5924
- import * as fs14 from "node:fs";
6857
+ import * as fs18 from "node:fs";
5925
6858
  import * as os5 from "node:os";
5926
- import * as path13 from "node:path";
6859
+ import * as path16 from "node:path";
5927
6860
  import process3 from "node:process";
5928
6861
  import { fileURLToPath as fileURLToPath12, pathToFileURL as pathToFileURL12 } from "node:url";
5929
6862
  var _HERE4 = fileURLToPath12(import.meta.url);
5930
- var REPO_ROOT4 = path13.resolve(path13.dirname(_HERE4), "..", "..");
6863
+ var REPO_ROOT4 = path16.resolve(path16.dirname(_HERE4), "..", "..");
5931
6864
  var OBLIGATION_LINE_RE = new RegExp(`${DETERMINISTIC_RE.source}.*`, "gm");
5932
6865
  var PATH_RE = /`([A-Za-z0-9_./-]*\/[A-Za-z0-9_.-]+\.[a-z]{2,6})`/g;
5933
6866
  var CMD_RE = /`([a-z][a-z0-9-]*(?: [a-z][a-z0-9:._-]*){1,3})`/g;
@@ -5965,7 +6898,7 @@ function _artefacts(line) {
5965
6898
  return out;
5966
6899
  }
5967
6900
  function extractObligations(repoRoot) {
5968
- const skillsRoot = path13.join(repoRoot, SKILLS_ROOT);
6901
+ const skillsRoot = path16.join(repoRoot, SKILLS_ROOT);
5969
6902
  const census = censusSkills(skillsRoot);
5970
6903
  const out = {
5971
6904
  skills: census.withDeterministicObligation,
@@ -5979,7 +6912,7 @@ function extractObligations(repoRoot) {
5979
6912
  for (const skill of census.withDeterministicObligation) {
5980
6913
  let text;
5981
6914
  try {
5982
- text = fs14.readFileSync(path13.join(skillsRoot, skill, "SKILL.md"), "utf-8");
6915
+ text = fs18.readFileSync(path16.join(skillsRoot, skill, "SKILL.md"), "utf-8");
5983
6916
  } catch {
5984
6917
  continue;
5985
6918
  }
@@ -6095,7 +7028,7 @@ function scanSessionForViolations(session, lines, forbidden, parsed) {
6095
7028
  return flags;
6096
7029
  }
6097
7030
  function defaultStore3(cwd) {
6098
- return path13.join(os5.homedir(), ".claude", "projects", projectStoreSlug(cwd));
7031
+ return path16.join(os5.homedir(), ".claude", "projects", projectStoreSlug(cwd));
6099
7032
  }
6100
7033
  function scanStore2(repoRoot, store, limit) {
6101
7034
  const census = extractObligations(repoRoot);
@@ -6108,14 +7041,14 @@ function scanStore2(repoRoot, store, limit) {
6108
7041
  };
6109
7042
  let files;
6110
7043
  try {
6111
- files = fs14.readdirSync(store).filter((f) => f.endsWith(".jsonl")).map((f) => ({ p: path13.join(store, f), m: fs14.statSync(path13.join(store, f)).mtimeMs })).sort((a, b) => b.m - a.m).slice(0, limit).map((x) => x.p);
7044
+ files = fs18.readdirSync(store).filter((f) => f.endsWith(".jsonl")).map((f) => ({ p: path16.join(store, f), m: fs18.statSync(path16.join(store, f)).mtimeMs })).sort((a, b) => b.m - a.m).slice(0, limit).map((x) => x.p);
6112
7045
  } catch {
6113
7046
  return report;
6114
7047
  }
6115
7048
  report.sessions = files.length;
6116
7049
  for (const file of files) {
6117
- const lines = fs14.readFileSync(file, "utf-8").split("\n");
6118
- const id = path13.basename(file).replace(/\.jsonl$/, "").slice(0, 8);
7050
+ const lines = fs18.readFileSync(file, "utf-8").split("\n");
7051
+ const id = path16.basename(file).replace(/\.jsonl$/, "").slice(0, 8);
6119
7052
  const entries = _parseSession(lines);
6120
7053
  if (loadedSkillsFrom(entries).size > 0) report.sessionsWithASkill += 1;
6121
7054
  report.flags.push(...scanSessionForViolations(id, lines, census.forbidden, entries));
@@ -6240,9 +7173,9 @@ function main12(argv) {
6240
7173
  }
6241
7174
  function _isCliEntry11() {
6242
7175
  if (process3.argv[1] === void 0) return false;
6243
- if (import.meta.url === pathToFileURL12(path13.resolve(process3.argv[1])).href) return true;
7176
+ if (import.meta.url === pathToFileURL12(path16.resolve(process3.argv[1])).href) return true;
6244
7177
  try {
6245
- return fs14.realpathSync(_HERE4) === fs14.realpathSync(path13.resolve(process3.argv[1]));
7178
+ return fs18.realpathSync(_HERE4) === fs18.realpathSync(path16.resolve(process3.argv[1]));
6246
7179
  } catch {
6247
7180
  return false;
6248
7181
  }
@@ -6253,20 +7186,20 @@ if (_isCliEntry11()) {
6253
7186
 
6254
7187
  // src/scripts/report_conformance_funnel.ts
6255
7188
  var _HERE5 = fileURLToPath13(import.meta.url);
6256
- var REPO_ROOT5 = path14.resolve(path14.dirname(_HERE5), "..", "..");
7189
+ var REPO_ROOT5 = path17.resolve(path17.dirname(_HERE5), "..", "..");
6257
7190
  function buildFunnel(opts = {}) {
6258
7191
  const repoRoot = opts.repoRoot ?? REPO_ROOT5;
6259
- const projectRulesDir = opts.projectRulesDir ?? path14.join(repoRoot, PROJECT_RULES);
6260
- const globalRulesDir = opts.globalRulesDir ?? path14.join(os6.homedir(), GLOBAL_RULES);
6261
- const sourceDir = opts.sourceDir ?? path14.join(repoRoot, PROJECTION_SOURCE);
7192
+ const projectRulesDir = opts.projectRulesDir ?? path17.join(repoRoot, PROJECT_RULES);
7193
+ const globalRulesDir = opts.globalRulesDir ?? path17.join(os6.homedir(), GLOBAL_RULES);
7194
+ const sourceDir = opts.sourceDir ?? path17.join(repoRoot, PROJECTION_SOURCE);
6262
7195
  const store = opts.store ?? defaultStore(repoRoot);
6263
7196
  const limit = opts.limit ?? 30;
6264
7197
  return {
6265
7198
  delivered: measureDelivered(projectRulesDir, globalRulesDir),
6266
7199
  divergence: compareCarriers(projectRulesDir, globalRulesDir, sourceDir),
6267
- skills: censusSkills(path14.join(repoRoot, SKILLS_ROOT)),
7200
+ skills: censusSkills(path17.join(repoRoot, SKILLS_ROOT)),
6268
7201
  usage: measureUsage(store, limit),
6269
- storePresent: fs15.existsSync(store),
7202
+ storePresent: fs19.existsSync(store),
6270
7203
  sk2: scanStore2(repoRoot, store, limit)
6271
7204
  };
6272
7205
  }
@@ -6407,7 +7340,7 @@ function main13(argv) {
6407
7340
  `);
6408
7341
  return 1;
6409
7342
  }
6410
- const resolved = path14.resolve(v);
7343
+ const resolved = path17.resolve(v);
6411
7344
  if (a === "--store") opts.store = resolved;
6412
7345
  else if (a === "--project") opts.projectRulesDir = resolved;
6413
7346
  else if (a === "--global") opts.globalRulesDir = resolved;
@@ -6439,9 +7372,9 @@ function main13(argv) {
6439
7372
  }
6440
7373
  function _isCliEntry12() {
6441
7374
  if (process4.argv[1] === void 0) return false;
6442
- if (import.meta.url === pathToFileURL13(path14.resolve(process4.argv[1])).href) return true;
7375
+ if (import.meta.url === pathToFileURL13(path17.resolve(process4.argv[1])).href) return true;
6443
7376
  try {
6444
- return fs15.realpathSync(_HERE5) === fs15.realpathSync(path14.resolve(process4.argv[1]));
7377
+ return fs19.realpathSync(_HERE5) === fs19.realpathSync(path17.resolve(process4.argv[1]));
6445
7378
  } catch {
6446
7379
  return false;
6447
7380
  }
@@ -6478,20 +7411,20 @@ function conformanceLogPath() {
6478
7411
  if (override && override.trim().length > 0) {
6479
7412
  return override;
6480
7413
  }
6481
- return path15.join(os7.homedir(), ".event4u", "agent-config", "conformance-log.jsonl");
7414
+ return path18.join(os7.homedir(), ".event4u", "agent-config", "conformance-log.jsonl");
6482
7415
  }
6483
7416
  function installLogPath() {
6484
7417
  const override = process5.env["AGENT_CONFIG_INSTALL_LOG"];
6485
7418
  if (override && override.trim().length > 0) {
6486
7419
  return override;
6487
7420
  }
6488
- return path15.join(os7.homedir(), ".event4u", "agent-config", "install-log.jsonl");
7421
+ return path18.join(os7.homedir(), ".event4u", "agent-config", "install-log.jsonl");
6489
7422
  }
6490
7423
  function _installLogExpected(projectRoot) {
6491
- return fs16.existsSync(manifest_path(projectRoot));
7424
+ return fs20.existsSync(manifest_path(projectRoot));
6492
7425
  }
6493
7426
  function _check_txlog_clean(logPath = installLogPath(), projectRoot = null) {
6494
- const entries = fs16.existsSync(logPath) ? readRecentEntries(logPath) : [];
7427
+ const entries = fs20.existsSync(logPath) ? readRecentEntries(logPath) : [];
6495
7428
  if (entries.length === 0) {
6496
7429
  if (projectRoot !== null && _installLogExpected(projectRoot)) {
6497
7430
  return {
@@ -6525,11 +7458,11 @@ function _check_txlog_clean(logPath = installLogPath(), projectRoot = null) {
6525
7458
  };
6526
7459
  }
6527
7460
  function routeTargetPaths(target) {
6528
- return routeTargetPathsPosix(target).map((rel) => path15.join(...rel.split("/")));
7461
+ return routeTargetPathsPosix(target).map((rel) => path18.join(...rel.split("/")));
6529
7462
  }
6530
7463
  function _check_router_pointers(packageRoot = PACKAGE_ROOT) {
6531
- const routerPath = path15.join(packageRoot, "dist", "router.json");
6532
- if (!fs16.existsSync(routerPath)) {
7464
+ const routerPath = path18.join(packageRoot, "dist", "router.json");
7465
+ if (!fs20.existsSync(routerPath)) {
6533
7466
  return {
6534
7467
  id: "router-pointers",
6535
7468
  status: "fail",
@@ -6539,7 +7472,7 @@ function _check_router_pointers(packageRoot = PACKAGE_ROOT) {
6539
7472
  }
6540
7473
  let router;
6541
7474
  try {
6542
- router = JSON.parse(fs16.readFileSync(routerPath, "utf8"));
7475
+ router = JSON.parse(fs20.readFileSync(routerPath, "utf8"));
6543
7476
  } catch (exc) {
6544
7477
  return {
6545
7478
  id: "router-pointers",
@@ -6548,13 +7481,13 @@ function _check_router_pointers(packageRoot = PACKAGE_ROOT) {
6548
7481
  remedy: "reinstall the package \u2014 dist/router.json is corrupt"
6549
7482
  };
6550
7483
  }
6551
- const rulesDir = path15.join(packageRoot, "dist", "agent-src", "rules");
7484
+ const rulesDir = path18.join(packageRoot, "dist", "agent-src", "rules");
6552
7485
  const broken = [];
6553
7486
  let ids = 0;
6554
7487
  let targets = 0;
6555
7488
  for (const kernelId of router["kernel"] ?? []) {
6556
7489
  ids += 1;
6557
- if (!fs16.existsSync(path15.join(rulesDir, `${kernelId}.md`))) {
7490
+ if (!fs20.existsSync(path18.join(rulesDir, `${kernelId}.md`))) {
6558
7491
  broken.push(`kernel:${kernelId} \u2192 rules/${kernelId}.md missing`);
6559
7492
  }
6560
7493
  }
@@ -6562,7 +7495,7 @@ function _check_router_pointers(packageRoot = PACKAGE_ROOT) {
6562
7495
  for (const entry of router[tier] ?? []) {
6563
7496
  const ruleId = String(entry["id"] ?? "");
6564
7497
  ids += 1;
6565
- if (!fs16.existsSync(path15.join(rulesDir, `${ruleId}.md`))) {
7498
+ if (!fs20.existsSync(path18.join(rulesDir, `${ruleId}.md`))) {
6566
7499
  broken.push(`${tier}:${ruleId} \u2192 rules/${ruleId}.md missing`);
6567
7500
  }
6568
7501
  for (const target of entry["routes_to"] ?? []) {
@@ -6572,7 +7505,7 @@ function _check_router_pointers(packageRoot = PACKAGE_ROOT) {
6572
7505
  broken.push(`${ruleId} \u2192 unparseable routes_to ${JSON.stringify(target)}`);
6573
7506
  continue;
6574
7507
  }
6575
- if (!candidates.some((rel) => fs16.existsSync(path15.join(packageRoot, rel)))) {
7508
+ if (!candidates.some((rel) => fs20.existsSync(path18.join(packageRoot, rel)))) {
6576
7509
  broken.push(`${ruleId} \u2192 ${target} (${candidates[0]} missing)`);
6577
7510
  }
6578
7511
  }
@@ -6604,9 +7537,9 @@ function detectSmokePlatform(projectRoot) {
6604
7537
  return "claude";
6605
7538
  }
6606
7539
  function dispatcherRunner(packageRoot) {
6607
- const localTsx = path15.join(packageRoot, "node_modules", ".bin", "tsx");
6608
- const script = path15.join(packageRoot, "src", "scripts", "hooks", "dispatch_hook.ts");
6609
- if (fs16.existsSync(localTsx)) {
7540
+ const localTsx = path18.join(packageRoot, "node_modules", ".bin", "tsx");
7541
+ const script = path18.join(packageRoot, "src", "scripts", "hooks", "dispatch_hook.ts");
7542
+ if (fs20.existsSync(localTsx)) {
6610
7543
  return [localTsx, script];
6611
7544
  }
6612
7545
  return ["npx", "tsx", script];
@@ -6656,12 +7589,12 @@ function _check_hook_dispatcher(projectRoot, packageRoot = PACKAGE_ROOT, opts =
6656
7589
  };
6657
7590
  }
6658
7591
  function readSettingsMode(projectRoot) {
6659
- const settingsPath = path15.join(projectRoot, ".agent-settings.yml");
6660
- if (!fs16.existsSync(settingsPath)) {
7592
+ const settingsPath = path18.join(projectRoot, ".agent-settings.yml");
7593
+ if (!fs20.existsSync(settingsPath)) {
6661
7594
  return "eager-all";
6662
7595
  }
6663
7596
  try {
6664
- const parsed = YAML.parse(fs16.readFileSync(settingsPath, "utf8"));
7597
+ const parsed = YAML.parse(fs20.readFileSync(settingsPath, "utf8"));
6665
7598
  const lean = parsed?.["lean_projection"] ?? null;
6666
7599
  const mode = lean?.["mode"];
6667
7600
  return typeof mode === "string" && mode.length > 0 ? mode : "eager-all";
@@ -6672,7 +7605,7 @@ function readSettingsMode(projectRoot) {
6672
7605
  function kernelIdsFromRouter(packageRoot) {
6673
7606
  try {
6674
7607
  const router = JSON.parse(
6675
- fs16.readFileSync(path15.join(packageRoot, "dist", "router.json"), "utf8")
7608
+ fs20.readFileSync(path18.join(packageRoot, "dist", "router.json"), "utf8")
6676
7609
  );
6677
7610
  return new Set((router["kernel"] ?? []).map(String));
6678
7611
  } catch {
@@ -6689,8 +7622,8 @@ function _check_lean_projection(projectRoot, packageRoot = PACKAGE_ROOT, project
6689
7622
  remedy: "set lean_projection.mode to 'eager-all' or 'thin' in .agent-settings.yml"
6690
7623
  };
6691
7624
  }
6692
- const rulesDir = projectedRulesDir ?? path15.join(projectRoot, ".augment", "rules");
6693
- if (!fs16.existsSync(rulesDir)) {
7625
+ const rulesDir = projectedRulesDir ?? path18.join(projectRoot, ".augment", "rules");
7626
+ if (!fs20.existsSync(rulesDir)) {
6694
7627
  return {
6695
7628
  id: "lean-projection",
6696
7629
  status: "skipped",
@@ -6699,7 +7632,7 @@ function _check_lean_projection(projectRoot, packageRoot = PACKAGE_ROOT, project
6699
7632
  };
6700
7633
  }
6701
7634
  const kernel = kernelIdsFromRouter(packageRoot);
6702
- const files = fs16.readdirSync(rulesDir).filter((f) => f.endsWith(".md") && f !== "INDEX.md").sort();
7635
+ const files = fs20.readdirSync(rulesDir).filter((f) => f.endsWith(".md") && f !== "INDEX.md").sort();
6703
7636
  const nonKernel = files.filter((f) => !kernel.has(f.replace(/\.md$/, "")));
6704
7637
  if (nonKernel.length === 0) {
6705
7638
  return {
@@ -6713,7 +7646,7 @@ function _check_lean_projection(projectRoot, packageRoot = PACKAGE_ROOT, project
6713
7646
  for (const f of nonKernel) {
6714
7647
  let text = "";
6715
7648
  try {
6716
- text = fs16.readFileSync(path15.join(rulesDir, f), "utf8");
7649
+ text = fs20.readFileSync(path18.join(rulesDir, f), "utf8");
6717
7650
  } catch {
6718
7651
  continue;
6719
7652
  }
@@ -6744,8 +7677,8 @@ function _check_lean_projection(projectRoot, packageRoot = PACKAGE_ROOT, project
6744
7677
  function _check_host_manifest(projectRoot) {
6745
7678
  const detected = Object.entries(detectToolPresence(projectRoot)).filter(([, v]) => v === true).map(([k]) => k);
6746
7679
  const detectedNote = detected.length > 0 ? `detected surfaces: ${detected.join(", ")}` : "no surfaces detected";
6747
- const settingsPath = path15.join(projectRoot, ".agent-settings.yml");
6748
- if (!fs16.existsSync(settingsPath)) {
7680
+ const settingsPath = path18.join(projectRoot, ".agent-settings.yml");
7681
+ if (!fs20.existsSync(settingsPath)) {
6749
7682
  return {
6750
7683
  id: "host-manifest",
6751
7684
  status: "ok",
@@ -6755,7 +7688,7 @@ function _check_host_manifest(projectRoot) {
6755
7688
  }
6756
7689
  let parsed = null;
6757
7690
  try {
6758
- parsed = YAML.parse(fs16.readFileSync(settingsPath, "utf8"));
7691
+ parsed = YAML.parse(fs20.readFileSync(settingsPath, "utf8"));
6759
7692
  } catch (exc) {
6760
7693
  return {
6761
7694
  id: "host-manifest",
@@ -6929,13 +7862,13 @@ function _isCliEntry13() {
6929
7862
  if (process5.argv[1] === void 0) {
6930
7863
  return false;
6931
7864
  }
6932
- const argvUrl = pathToFileURL14(path15.resolve(process5.argv[1])).href;
7865
+ const argvUrl = pathToFileURL14(path18.resolve(process5.argv[1])).href;
6933
7866
  if (import.meta.url === argvUrl) {
6934
7867
  return true;
6935
7868
  }
6936
7869
  try {
6937
- const here = fs16.realpathSync(fileURLToPath14(import.meta.url));
6938
- const argv = fs16.realpathSync(path15.resolve(process5.argv[1]));
7870
+ const here = fs20.realpathSync(fileURLToPath14(import.meta.url));
7871
+ const argv = fs20.realpathSync(path18.resolve(process5.argv[1]));
6939
7872
  return here === argv;
6940
7873
  } catch {
6941
7874
  return false;