@event4u/agent-config 15.0.0 → 16.1.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 (283) 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 +301 -347
  5. package/CONTRIBUTING.md +9 -0
  6. package/README.md +2 -2
  7. package/dist/agent-src/commands/analyze/inbox.md +26 -0
  8. package/dist/agent-src/commands/analyze/roadmap-repos.md +27 -0
  9. package/dist/agent-src/commands/challenge-me/closure.md +178 -0
  10. package/dist/agent-src/commands/challenge-me.md +9 -2
  11. package/dist/agent-src/commands/council/default.md +25 -5
  12. package/dist/agent-src/commands/feature/plan.md +28 -1
  13. package/dist/agent-src/commands/feature/roadmap.md +28 -1
  14. package/dist/agent-src/commands/implement-ticket.md +27 -0
  15. package/dist/agent-src/commands/jira-ticket.md +27 -0
  16. package/dist/agent-src/commands/pr/create.md +29 -0
  17. package/dist/agent-src/commands/pr/merge.md +60 -9
  18. package/dist/agent-src/commands/roadmap/ai-council.md +7 -1
  19. package/dist/agent-src/commands/roadmap/create.md +77 -29
  20. package/dist/agent-src/commands/roadmap/materialize.md +27 -0
  21. package/dist/agent-src/commands/roadmap/process-full.md +123 -18
  22. package/dist/agent-src/commands/team.md +22 -0
  23. package/dist/agent-src/contexts/authority/scope-growth-ownership.md +80 -0
  24. package/dist/agent-src/contexts/communication/rules-auto/user-interaction-mechanics.md +97 -0
  25. package/dist/agent-src/contexts/execution/auto-orchestration-activation.md +44 -3
  26. package/dist/agent-src/contexts/execution/autonomy-mechanics.md +15 -15
  27. package/dist/agent-src/contexts/execution/decision-closure-execution.md +93 -0
  28. package/dist/agent-src/contexts/execution/fix-loop-ladder.md +108 -0
  29. package/dist/agent-src/contexts/execution/plan-confidence-gate.md +4 -2
  30. package/dist/agent-src/contexts/execution/roadmap-process-loop.md +75 -6
  31. package/dist/agent-src/guidelines/agent-infra/active-remediation-mechanics.md +57 -0
  32. package/dist/agent-src/guidelines/agent-infra/evaluator-independence-mechanics.md +102 -0
  33. package/dist/agent-src/guidelines/design-fidelity-routing.md +29 -0
  34. package/dist/agent-src/rules/autonomous-execution.md +15 -8
  35. package/dist/agent-src/rules/delegation-policy.md +23 -45
  36. package/dist/agent-src/rules/design-fidelity.md +32 -37
  37. package/dist/agent-src/rules/evaluator-independence.md +43 -49
  38. package/dist/agent-src/rules/test-first.md +41 -0
  39. package/dist/agent-src/rules/user-interaction.md +31 -30
  40. package/dist/agent-src/skills/accessibility-auditor/data/manifest.json +3 -3
  41. package/dist/agent-src/skills/ai-council/SKILL.md +11 -3
  42. package/dist/agent-src/skills/api-design/data/manifest.json +3 -3
  43. package/dist/agent-src/skills/database/data/manifest.json +4 -4
  44. package/dist/agent-src/skills/database/data/query-tuning.csv +3 -3
  45. package/dist/agent-src/skills/design-review/SKILL.md +50 -0
  46. package/dist/agent-src/skills/error-handling-patterns/SKILL.md +9 -0
  47. package/dist/agent-src/skills/existing-ui-audit/SKILL.md +14 -4
  48. package/dist/agent-src/skills/experiment-loop/SKILL.md +31 -1
  49. package/dist/agent-src/skills/roadmap-writing/SKILL.md +1 -1
  50. package/dist/agent-src/skills/storybook-workshop/SKILL.md +42 -3
  51. package/dist/agent-src/skills/threat-modeling/SKILL.md +9 -4
  52. package/dist/agent-src/skills/threat-modeling/data/manifest.json +4 -4
  53. package/dist/agent-src/skills/verify-repair-loop/SKILL.md +37 -3
  54. package/dist/agent-src/templates/agent-settings.md +1 -1
  55. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  56. package/dist/agent-src/templates/roadmaps.md +188 -0
  57. package/dist/agent-src/templates/scripts/work_engine/directives/backend/_self_fix.ts +62 -2
  58. package/dist/agent-src/templates/scripts/work_engine/directives/backend/test.ts +1 -0
  59. package/dist/agent-src/templates/scripts/work_engine/directives/backend/verify.ts +1 -0
  60. package/dist/cli-delegate/check_update_banner.js +40 -2
  61. package/dist/cli-delegate/chunk-4E2W63DA.js +335 -0
  62. package/dist/cli-delegate/chunk-5R7HOLAF.js +99 -0
  63. package/dist/cli-delegate/{chunk-IVBPRCQO.js → chunk-6KFEC3G7.js} +1 -1
  64. package/dist/cli-delegate/{chunk-2TAQ2K4V.js → chunk-6KM6ORRY.js} +55 -386
  65. package/dist/cli-delegate/{chunk-2XY7ILBT.js → chunk-FC75PGJE.js} +42 -2
  66. package/dist/cli-delegate/{chunk-GYC3VRYN.js → chunk-FXYUYU4N.js} +57 -13
  67. package/dist/cli-delegate/{chunk-55ACLDUE.js → chunk-GJCBB2UG.js} +168 -10
  68. package/dist/cli-delegate/{chunk-AK6HODNQ.js → chunk-HDVVGPQW.js} +873 -539
  69. package/dist/cli-delegate/chunk-NUHLI2RX.js +80 -0
  70. package/dist/cli-delegate/{chunk-HZ52BRGG.js → chunk-P6ZHP5W2.js} +15 -90
  71. package/dist/cli-delegate/{chunk-TYSY33MD.js → chunk-QJWAUMJW.js} +12 -2
  72. package/dist/cli-delegate/{chunk-57PN4GYJ.js → chunk-RGNIWTEA.js} +1 -1
  73. package/dist/cli-delegate/chunk-ROYYTEZU.js +39 -0
  74. package/dist/cli-delegate/{chunk-2KKXJW25.js → chunk-S3VFXMTM.js} +1 -1
  75. package/dist/cli-delegate/{chunk-3FKR64R5.js → chunk-UNCRJBT3.js} +31 -7
  76. package/dist/cli-delegate/{chunk-2DK2VJWG.js → chunk-WGXTVKCQ.js} +20 -6
  77. package/dist/cli-delegate/chunk-YDPILCOL.js +152 -0
  78. package/dist/cli-delegate/cmd_analyze_session.js +1 -1
  79. package/dist/cli-delegate/cmd_brand_status.js +1 -1
  80. package/dist/cli-delegate/cmd_conformance.js +918 -325
  81. package/dist/cli-delegate/cmd_doctor.js +7 -5
  82. package/dist/cli-delegate/cmd_explain.js +5 -3
  83. package/dist/cli-delegate/cmd_export.js +9 -7
  84. package/dist/cli-delegate/cmd_fleet.js +4 -2
  85. package/dist/cli-delegate/cmd_handoff.js +6 -6
  86. package/dist/cli-delegate/cmd_mcp_available.js +1 -1
  87. package/dist/cli-delegate/cmd_migrate.js +2 -2
  88. package/dist/cli-delegate/cmd_packs_active.js +3 -2
  89. package/dist/cli-delegate/cmd_preflight.js +4 -2
  90. package/dist/cli-delegate/cmd_prune.js +10 -8
  91. package/dist/cli-delegate/cmd_route_audit.js +2 -2
  92. package/dist/cli-delegate/cmd_route_explain.js +1 -1
  93. package/dist/cli-delegate/cmd_session_recycle.js +4 -4
  94. package/dist/cli-delegate/cmd_settings_get.js +28 -2
  95. package/dist/cli-delegate/cmd_settings_migrate.js +9 -7
  96. package/dist/cli-delegate/cmd_settings_set.js +14 -1
  97. package/dist/cli-delegate/cmd_sync.js +10 -8
  98. package/dist/cli-delegate/cmd_uninstall.js +16 -13
  99. package/dist/cli-delegate/cmd_update.js +1 -1
  100. package/dist/cli-delegate/cmd_upgrade.js +1 -1
  101. package/dist/cli-delegate/cmd_validate.js +12 -10
  102. package/dist/cli-delegate/cmd_versions.js +1 -1
  103. package/dist/discovery/deprecation-report.md +1 -1
  104. package/dist/discovery/discovery-manifest.json +87 -40
  105. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  106. package/dist/discovery/discovery-manifest.summary.md +4 -4
  107. package/dist/discovery/dormancy-report.md +1 -1
  108. package/dist/discovery/orphan-report.md +1 -1
  109. package/dist/discovery/packs.json +10 -8
  110. package/dist/discovery/trust-report.md +3 -3
  111. package/dist/discovery/workspaces.json +8 -6
  112. package/dist/hooks/dispatch.js +2601 -1073
  113. package/dist/install/claudeRuleRewrite.js +14 -3
  114. package/dist/install/conflict.js +60 -10
  115. package/dist/install/conflictTracker.js +218 -0
  116. package/dist/install/fsPrimitives.js +54 -0
  117. package/dist/install/install.mjs +2008 -1481
  118. package/dist/install/manifestFiles.js +259 -0
  119. package/dist/install/preflight.js +14 -2
  120. package/dist/install/preserve.js +157 -0
  121. package/dist/install/recordedOwnership.js +132 -0
  122. package/dist/install/txlog.js +11 -2
  123. package/dist/mcp/registry-manifest.json +3 -3
  124. package/dist/mcp/server.json +2 -2
  125. package/dist/mcp/server.mjs +1612 -667
  126. package/dist/router.json +1 -1
  127. package/dist/scripts/_lib/agent_settings.js +3 -2
  128. package/dist/scripts/_lib/fs_atomic.js +167 -0
  129. package/dist/scripts/_lib/installed_lock.js +1 -1
  130. package/dist/scripts/_lib/installed_tools.js +460 -0
  131. package/dist/scripts/_lib/lean_projection_mode.js +3 -2
  132. package/dist/scripts/_lib/settings_renamed_keys.js +78 -0
  133. package/dist/server/io/yamlIO.js +50 -0
  134. package/dist/server/routes/install.js +8 -0
  135. package/dist/server/routes/wizard.js +9 -3
  136. package/dist/server/schemas/settings.js +17 -5
  137. package/dist/shared/missionExecution.js +97 -0
  138. package/dist/ui/assets/{index-D0jaCRPM.js → index-DH1xc62v.js} +17 -17
  139. package/dist/ui/index.html +1 -1
  140. package/docs/MIGRATION.md +103 -0
  141. package/docs/contracts/settings-classes.md +26 -7
  142. package/docs/guidelines/agent-infra/active-remediation-mechanics.md +57 -0
  143. package/docs/guidelines/agent-infra/evaluator-independence-mechanics.md +102 -0
  144. package/docs/guidelines/design-fidelity-routing.md +29 -0
  145. package/package.json +1 -1
  146. package/src/agent-src/templates/scripts/work_engine/directives/backend/_self_fix.ts +62 -2
  147. package/src/agent-src/templates/scripts/work_engine/directives/backend/test.ts +1 -0
  148. package/src/agent-src/templates/scripts/work_engine/directives/backend/verify.ts +1 -0
  149. package/src/config/agent-settings.template.yml +139 -27
  150. package/src/config/auto-rule-budget.json +16 -0
  151. package/src/config/ci-local-parity.yml +18 -5
  152. package/src/config/continuity-surface.json +28 -0
  153. package/src/config/gate-coverage.yml +146 -13
  154. package/src/config/gate-violation-baselines.json +6 -6
  155. package/src/config/hook-token-budget.json +2 -0
  156. package/src/config/host-injection-effect.json +1 -1
  157. package/src/config/loop-surfaces.yaml +215 -0
  158. package/src/config/platform-anchor.json +3 -2
  159. package/src/config/preamble-payload-budget.json +12 -7
  160. package/src/config/preamble-payload-exceptions.json +28 -0
  161. package/src/config/release-gate-locality.yml +11 -0
  162. package/src/config/routing-coverage-seed.json +18 -4
  163. package/src/config/rule-enforcement-baseline.json +0 -1
  164. package/src/install/claudeRuleRewrite.ts +16 -2
  165. package/src/install/conflict.ts +65 -9
  166. package/src/install/conflictTracker.ts +299 -0
  167. package/src/install/fsPrimitives.ts +54 -0
  168. package/src/install/manifestFiles.ts +312 -0
  169. package/src/install/preflight.ts +16 -2
  170. package/src/install/preserve.ts +205 -0
  171. package/src/install/recordedOwnership.ts +149 -0
  172. package/src/install/txlog.ts +11 -2
  173. package/src/install/types.ts +19 -4
  174. package/src/scripts/_cli/cmd_conformance.ts +88 -15
  175. package/src/scripts/_cli/cmd_doctor.ts +4 -3
  176. package/src/scripts/_cli/cmd_route_explain.ts +9 -2
  177. package/src/scripts/_cli/cmd_settings_get.ts +44 -0
  178. package/src/scripts/_cli/doctor_execution.ts +90 -0
  179. package/src/scripts/_dispatch.bash +3 -1
  180. package/src/scripts/_lib/activation_payload.ts +247 -0
  181. package/src/scripts/_lib/agent_settings.ts +4 -2
  182. package/src/scripts/_lib/authority_path.ts +102 -0
  183. package/src/scripts/_lib/base_ref_payload.ts +315 -0
  184. package/src/scripts/_lib/cascade_base.ts +94 -0
  185. package/src/scripts/_lib/changelog_eras.ts +7 -2
  186. package/src/scripts/_lib/continuation_ladder.ts +149 -2
  187. package/src/scripts/_lib/council_transport.ts +129 -0
  188. package/src/scripts/_lib/delivery_ready.ts +112 -0
  189. package/src/scripts/_lib/dropped_decision.ts +142 -0
  190. package/src/scripts/_lib/forge_protection.ts +267 -0
  191. package/src/scripts/_lib/hook_platform_keys.ts +27 -0
  192. package/src/scripts/_lib/installed_lock.ts +1 -1
  193. package/src/scripts/_lib/json_python_parity.ts +127 -0
  194. package/src/scripts/_lib/lean_projection_mode.ts +14 -3
  195. package/src/scripts/_lib/loop_surfaces.ts +382 -0
  196. package/src/scripts/_lib/measured_payload_ceiling.ts +424 -0
  197. package/src/scripts/_lib/mission_record.ts +190 -0
  198. package/src/scripts/_lib/obligation_frequency.ts +217 -0
  199. package/src/scripts/_lib/obligations.ts +402 -0
  200. package/src/scripts/_lib/orchestration_record.ts +11 -20
  201. package/src/scripts/_lib/payload_catalogue_completeness.ts +211 -0
  202. package/src/scripts/_lib/release_findings_ingest.ts +324 -0
  203. package/src/scripts/_lib/release_highlights.ts +199 -10
  204. package/src/scripts/_lib/release_holds.ts +493 -0
  205. package/src/scripts/_lib/release_migration_gate.ts +184 -0
  206. package/src/scripts/_lib/release_tag_dispatch.ts +63 -0
  207. package/src/scripts/_lib/review_baseline.ts +254 -0
  208. package/src/scripts/_lib/review_skipped_record.ts +61 -1
  209. package/src/scripts/_lib/rides_along.ts +102 -0
  210. package/src/scripts/_lib/settings_renamed_keys.ts +82 -0
  211. package/src/scripts/_lib/standing_bound_ratchet.ts +216 -103
  212. package/src/scripts/_lib/test_delta.ts +166 -0
  213. package/src/scripts/_lib/test_provenance.ts +171 -0
  214. package/src/scripts/_lib/turn_end_refusals.ts +51 -4
  215. package/src/scripts/_lib/typed_op_grant.ts +246 -0
  216. package/src/scripts/_lib/typed_op_watch.ts +185 -0
  217. package/src/scripts/ai_council/config.ts +8 -11
  218. package/src/scripts/ai_council/fallback_config.ts +5 -3
  219. package/src/scripts/ai_council/ownership_classes.ts +118 -0
  220. package/src/scripts/ask_block_census.ts +285 -15
  221. package/src/scripts/check_beta_review_markers.ts +35 -4
  222. package/src/scripts/check_enforcement_matrix.ts +624 -0
  223. package/src/scripts/check_finding_dispositions.ts +167 -16
  224. package/src/scripts/check_gate_reachability.ts +173 -10
  225. package/src/scripts/check_generator_sync.ts +954 -0
  226. package/src/scripts/check_held_object_arrivals.ts +381 -0
  227. package/src/scripts/check_preamble_payload_budget.ts +474 -124
  228. package/src/scripts/check_release_highlights.ts +33 -1
  229. package/src/scripts/check_release_holds.ts +567 -0
  230. package/src/scripts/check_release_published.ts +1 -1
  231. package/src/scripts/check_reply_consistency.ts +86 -17
  232. package/src/scripts/check_rule_projection_integrity.ts +22 -12
  233. package/src/scripts/check_test_delta.ts +294 -0
  234. package/src/scripts/check_test_weakening.ts +299 -0
  235. package/src/scripts/closure_scan.ts +333 -0
  236. package/src/scripts/compile_hook_manifest.ts +43 -3
  237. package/src/scripts/council_record_shape.ts +209 -0
  238. package/src/scripts/hook_manifest.json +1 -1
  239. package/src/scripts/hook_manifest.yaml +127 -12
  240. package/src/scripts/hooks/block_kernel_rule_writes.ts +12 -2
  241. package/src/scripts/hooks/concern_registry.ts +6 -0
  242. package/src/scripts/hooks/design_pass_hook.ts +128 -3
  243. package/src/scripts/hooks/end_review_nudge_hook.ts +101 -21
  244. package/src/scripts/hooks/evidence_independence.ts +96 -0
  245. package/src/scripts/hooks/memory_recall_hook.ts +540 -0
  246. package/src/scripts/hooks/obligation_settle_hook.ts +182 -0
  247. package/src/scripts/hooks/review_baseline_hook.ts +130 -0
  248. package/src/scripts/hooks/rule_inject_hook.ts +49 -1
  249. package/src/scripts/hooks/run_continuation_hook.ts +17 -20
  250. package/src/scripts/hooks/turn_end_gate_hook.ts +232 -14
  251. package/src/scripts/hooks_doctor.ts +89 -1
  252. package/src/scripts/hooks_status.ts +19 -0
  253. package/src/scripts/install.ts +107 -207
  254. package/src/scripts/interruption_report.ts +8 -2
  255. package/src/scripts/janitor.ts +15 -1
  256. package/src/scripts/lint_decision_classes.ts +464 -0
  257. package/src/scripts/lint_hook_manifest.ts +11 -0
  258. package/src/scripts/lint_major_migration_sections.ts +450 -0
  259. package/src/scripts/lint_plan_risk_register.ts +47 -3
  260. package/src/scripts/lint_roadmap_blockers.ts +61 -0
  261. package/src/scripts/lint_roadmap_producers.ts +202 -0
  262. package/src/scripts/measure_rule_budget.ts +101 -5
  263. package/src/scripts/measure_turn_end_gate.ts +302 -5
  264. package/src/scripts/new_roadmap.ts +37 -0
  265. package/src/scripts/orchestration_record.ts +0 -5
  266. package/src/scripts/release.ts +66 -162
  267. package/src/scripts/release_drill.ts +460 -15
  268. package/src/scripts/release_env.ts +1 -1
  269. package/src/scripts/release_publication.ts +52 -1
  270. package/src/scripts/report_enforcement_drift.ts +566 -0
  271. package/src/scripts/report_held_object_arrivals.ts +456 -0
  272. package/src/scripts/report_host_injection_effect.ts +3 -11
  273. package/src/scripts/report_standing_payload_by_host.ts +26 -152
  274. package/src/scripts/schemas/agent-settings.schema.json +23 -0
  275. package/src/scripts/schemas/command.schema.json +4 -0
  276. package/src/scripts/scope_growth.ts +219 -0
  277. package/src/scripts/sync_agent_settings.ts +140 -18
  278. package/src/scripts/trigger_eval_grandfather.json +0 -1
  279. package/src/scripts/ui_conformance_probe.ts +622 -0
  280. package/src/server/io/yamlIO.ts +48 -0
  281. package/src/server/schemas/settings.ts +31 -7
  282. package/src/shared/missionExecution.ts +126 -0
  283. package/dist/cli-delegate/chunk-523HCFYO.js +0 -90
@@ -10,11 +10,13 @@ import {
10
10
  sessionRefusalFile,
11
11
  statePathFor,
12
12
  validateAssumption
13
- } from "./chunk-TYSY33MD.js";
13
+ } from "./chunk-QJWAUMJW.js";
14
14
  import {
15
15
  readHookStdin
16
16
  } from "./chunk-F7DQWYR5.js";
17
17
  import {
18
+ DeadScopeError,
19
+ assertScanned,
18
20
  reportScanned
19
21
  } from "./chunk-I3EIN2YG.js";
20
22
  import {
@@ -34,14 +36,15 @@ import {
34
36
  frontmatterPaths,
35
37
  proseEqual,
36
38
  splitFrontmatter
37
- } from "./chunk-55ACLDUE.js";
39
+ } from "./chunk-GJCBB2UG.js";
38
40
  import "./chunk-FTAISGDQ.js";
39
41
  import "./chunk-M2DPGFZ4.js";
42
+ import "./chunk-ROYYTEZU.js";
40
43
  import "./chunk-BTWUYDGN.js";
41
44
  import {
42
45
  projectStoreSlug,
43
46
  resolveSessionRole
44
- } from "./chunk-GYC3VRYN.js";
47
+ } from "./chunk-FXYUYU4N.js";
45
48
  import {
46
49
  atomic_write_json,
47
50
  atomic_write_text,
@@ -52,18 +55,26 @@ import {
52
55
  prune_stale_session_states,
53
56
  session_state_file
54
57
  } from "./chunk-E4XIZDIB.js";
58
+ import {
59
+ artefact_roots
60
+ } from "./chunk-NUHLI2RX.js";
61
+ import {
62
+ readRecentEntries
63
+ } from "./chunk-5R7HOLAF.js";
55
64
  import {
56
65
  detectToolPresence
57
66
  } from "./chunk-A4QJ6ENT.js";
58
67
  import {
59
68
  atomicAppendLine,
69
+ probeHostCapabilities
70
+ } from "./chunk-6KM6ORRY.js";
71
+ import "./chunk-T7L2QK3K.js";
72
+ import "./chunk-DMSZHXZS.js";
73
+ import {
60
74
  manifest_path,
61
- probeHostCapabilities,
62
75
  read_manifest
63
- } from "./chunk-2TAQ2K4V.js";
76
+ } from "./chunk-4E2W63DA.js";
64
77
  import "./chunk-MWRD5YOH.js";
65
- import "./chunk-T7L2QK3K.js";
66
- import "./chunk-DMSZHXZS.js";
67
78
  import {
68
79
  require_dist
69
80
  } from "./chunk-OY53J6II.js";
@@ -72,7 +83,7 @@ import {
72
83
  } from "./chunk-MCJYCQPF.js";
73
84
  import {
74
85
  load_agent_settings
75
- } from "./chunk-2XY7ILBT.js";
86
+ } from "./chunk-FC75PGJE.js";
76
87
  import "./chunk-NDJLNC6Q.js";
77
88
  import {
78
89
  __toESM
@@ -80,45 +91,12 @@ import {
80
91
 
81
92
  // src/scripts/_cli/cmd_conformance.ts
82
93
  var YAML = __toESM(require_dist(), 1);
83
- import * as fs13 from "node:fs";
94
+ import * as fs15 from "node:fs";
84
95
  import * as os7 from "node:os";
85
- import * as path13 from "node:path";
96
+ import * as path15 from "node:path";
86
97
  import process5 from "node:process";
87
- import { spawnSync as spawnSync2 } from "node:child_process";
88
- import { fileURLToPath as fileURLToPath13, pathToFileURL as pathToFileURL13 } from "node:url";
89
-
90
- // src/install/txlog.ts
91
- import { createReadStream, createWriteStream, existsSync, readFileSync, renameSync, statSync, unlinkSync } from "node:fs";
92
- var ROTATION_MAX_BYTES = 10 * 1024 * 1024;
93
- var ROTATION_MAX_AGE_MS = 30 * 24 * 60 * 60 * 1e3;
94
- var RECOVERY_DEPTH_CAP = 500;
95
- function readRecentEntries(logPath) {
96
- if (!existsSync(logPath)) {
97
- return [];
98
- }
99
- const raw = readFileSync(logPath, "utf8");
100
- const lines = raw.split("\n").filter((l) => l.length > 0);
101
- const tail = lines.slice(-RECOVERY_DEPTH_CAP);
102
- const out = [];
103
- for (const line of tail) {
104
- const parsed = tryParseEntry(line);
105
- if (parsed !== null) {
106
- out.push(parsed);
107
- }
108
- }
109
- return out;
110
- }
111
- function tryParseEntry(line) {
112
- try {
113
- const obj = JSON.parse(line);
114
- if (typeof obj.ts !== "string" || typeof obj.kind !== "string" || typeof obj.path !== "string") {
115
- return null;
116
- }
117
- return obj;
118
- } catch {
119
- return null;
120
- }
121
- }
98
+ import { spawnSync as spawnSync4 } from "node:child_process";
99
+ import { fileURLToPath as fileURLToPath14, pathToFileURL as pathToFileURL14 } from "node:url";
122
100
 
123
101
  // src/scripts/router_target_paths.mjs
124
102
  var ROUTE_TARGET_TEMPLATES = Object.freeze({
@@ -131,10 +109,10 @@ var ROUTE_TARGET_TEMPLATES = Object.freeze({
131
109
  ])
132
110
  });
133
111
  function parseRouteTarget(target) {
134
- const sep = target.indexOf(":");
135
- if (sep <= 0) return null;
136
- const kind = target.slice(0, sep);
137
- const id = target.slice(sep + 1);
112
+ const sep2 = target.indexOf(":");
113
+ if (sep2 <= 0) return null;
114
+ const kind = target.slice(0, sep2);
115
+ const id = target.slice(sep2 + 1);
138
116
  if (!id) return null;
139
117
  if (!Object.prototype.hasOwnProperty.call(ROUTE_TARGET_TEMPLATES, kind)) return null;
140
118
  return { kind, id };
@@ -146,18 +124,18 @@ function routeTargetPathsPosix(target) {
146
124
  }
147
125
 
148
126
  // src/scripts/report_conformance_funnel.ts
149
- import * as fs12 from "node:fs";
127
+ import * as fs14 from "node:fs";
150
128
  import * as os6 from "node:os";
151
- import * as path12 from "node:path";
129
+ import * as path14 from "node:path";
152
130
  import process4 from "node:process";
153
- import { fileURLToPath as fileURLToPath12, pathToFileURL as pathToFileURL12 } from "node:url";
131
+ import { fileURLToPath as fileURLToPath13, pathToFileURL as pathToFileURL13 } from "node:url";
154
132
 
155
133
  // src/scripts/conformance_scan.ts
156
134
  import { createHash as createHash3 } from "node:crypto";
157
- import fs8 from "node:fs";
135
+ import fs10 from "node:fs";
158
136
  import os2 from "node:os";
159
- import path8 from "node:path";
160
- import { fileURLToPath as fileURLToPath8, pathToFileURL as pathToFileURL8 } from "node:url";
137
+ import path10 from "node:path";
138
+ import { fileURLToPath as fileURLToPath9, pathToFileURL as pathToFileURL9 } from "node:url";
161
139
 
162
140
  // src/scripts/_lib/transcript_entry.ts
163
141
  function _isObject(v) {
@@ -1940,17 +1918,464 @@ var COMMAND_OBJECTS = {
1940
1918
  };
1941
1919
 
1942
1920
  // src/scripts/hooks/turn_end_gate_hook.ts
1943
- import * as fs5 from "node:fs";
1944
- import * as path5 from "node:path";
1945
- import { fileURLToPath as fileURLToPath5, pathToFileURL as pathToFileURL5 } from "node:url";
1921
+ import * as fs7 from "node:fs";
1922
+ import * as path7 from "node:path";
1923
+ import { fileURLToPath as fileURLToPath6, pathToFileURL as pathToFileURL6 } from "node:url";
1946
1924
 
1947
- // src/scripts/hooks/end_review_nudge_hook.ts
1948
- import { spawnSync } from "node:child_process";
1949
- import * as crypto from "node:crypto";
1925
+ // src/scripts/check_reply_consistency.ts
1950
1926
  import * as fs3 from "node:fs";
1951
- import * as os from "node:os";
1952
1927
  import * as path3 from "node:path";
1953
1928
  import { fileURLToPath as fileURLToPath3, pathToFileURL as pathToFileURL3 } from "node:url";
1929
+ var _HERE = fileURLToPath3(import.meta.url);
1930
+ var ROOT = path3.resolve(path3.dirname(_HERE), "..", "..");
1931
+ var QUIET = process.argv.slice(2).includes("--quiet");
1932
+ var OPTION_LINE_RE = /^\s*>?\s*(\d+)\.\s+\S/;
1933
+ var REC_LINE_RE = /(?:Recommendation|Empfehlung)\s*:\s*(\d+)\b/i;
1934
+ var TAG_RE = /\((?:recommended|rec|empfohlen)\)/i;
1935
+ var CODESPAN_RE = /`[^`\n]*`/g;
1936
+ var HEADING_RE = /^#{1,6}\s/;
1937
+ var FENCE_RE = /^\s*(```|~~~)/;
1938
+ var REC_ADJACENCY_WINDOW = 2;
1939
+ function _strip_codespans(line) {
1940
+ return line.replace(CODESPAN_RE, "``");
1941
+ }
1942
+ function splitAndMask(text) {
1943
+ return mask_fences(_splitlines(text));
1944
+ }
1945
+ function _splitlines(text) {
1946
+ if (text === "") return [];
1947
+ const parts = text.split(/\r\n|\r|\n/);
1948
+ if (parts.length > 0 && parts[parts.length - 1] === "") {
1949
+ parts.pop();
1950
+ }
1951
+ return parts;
1952
+ }
1953
+ function mask_fences(lines) {
1954
+ const out = [];
1955
+ let fence = null;
1956
+ for (const raw of lines) {
1957
+ const m = FENCE_RE.exec(raw);
1958
+ if (m) {
1959
+ const marker = m[1];
1960
+ if (fence === null) {
1961
+ fence = marker;
1962
+ } else if (fence === marker) {
1963
+ fence = null;
1964
+ }
1965
+ out.push("");
1966
+ continue;
1967
+ }
1968
+ out.push(fence === null ? raw : "");
1969
+ }
1970
+ return out;
1971
+ }
1972
+ function find_option_blocks(text) {
1973
+ const lines = mask_fences(_splitlines(text));
1974
+ const blocks = [];
1975
+ let current = null;
1976
+ for (let idx = 0; idx < lines.length; idx++) {
1977
+ const m = OPTION_LINE_RE.exec(lines[idx]);
1978
+ if (m) {
1979
+ const num = parseInt(m[1], 10);
1980
+ if (current === null) {
1981
+ current = { startLine: idx + 1, endLine: idx + 1, numbers: [num] };
1982
+ } else {
1983
+ current.endLine = idx + 1;
1984
+ current.numbers.push(num);
1985
+ }
1986
+ } else {
1987
+ if (current !== null && current.numbers.length >= 2) {
1988
+ blocks.push(current);
1989
+ }
1990
+ current = null;
1991
+ }
1992
+ }
1993
+ if (current !== null && current.numbers.length >= 2) {
1994
+ blocks.push(current);
1995
+ }
1996
+ return blocks;
1997
+ }
1998
+ function recommendationsUnder(text, block, maskedLines) {
1999
+ const lines = maskedLines ?? mask_fences(_splitlines(text));
2000
+ const recs = [];
2001
+ let inspected = 0;
2002
+ for (let idx = block.endLine; idx < lines.length && inspected < REC_ADJACENCY_WINDOW; idx++) {
2003
+ const line = lines[idx];
2004
+ if (line.trim() === "") {
2005
+ continue;
2006
+ }
2007
+ if (HEADING_RE.test(line) || OPTION_LINE_RE.test(line)) {
2008
+ break;
2009
+ }
2010
+ inspected += 1;
2011
+ const m = REC_LINE_RE.exec(line);
2012
+ if (m) {
2013
+ recs.push({ line: idx + 1, num: parseInt(m[1], 10) });
2014
+ }
2015
+ }
2016
+ return recs;
2017
+ }
2018
+ function check_reply(text) {
2019
+ const rawLines = _splitlines(text);
2020
+ const lines = mask_fences(rawLines);
2021
+ const findings = [];
2022
+ for (let idx = 0; idx < lines.length; idx++) {
2023
+ const stripped = _strip_codespans(lines[idx]);
2024
+ if (OPTION_LINE_RE.test(stripped) && TAG_RE.test(stripped)) {
2025
+ findings.push({
2026
+ line: idx + 1,
2027
+ message: `inline tag on numbered option \u2014 ${rawLines[idx].trim()}`
2028
+ });
2029
+ }
2030
+ }
2031
+ const blocks = find_option_blocks(text);
2032
+ for (const block of blocks) {
2033
+ const recs = recommendationsUnder(text, block);
2034
+ if (recs.length === 0) {
2035
+ findings.push({
2036
+ line: block.startLine,
2037
+ message: "numbered options block without a Recommendation:/Empfehlung: line directly under it"
2038
+ });
2039
+ continue;
2040
+ }
2041
+ if (recs.length > 1) {
2042
+ findings.push({
2043
+ line: recs[1].line,
2044
+ message: `multiple recommendation lines under one options block: [${recs.map((r) => r.num).join(", ")}]`
2045
+ });
2046
+ continue;
2047
+ }
2048
+ const rec = recs[0];
2049
+ if (!block.numbers.includes(rec.num)) {
2050
+ findings.push({
2051
+ line: rec.line,
2052
+ message: `recommendation ${String(rec.num)} not present in the options block above it (options: [${block.numbers.join(", ")}])`
2053
+ });
2054
+ }
2055
+ }
2056
+ findings.sort((a, b) => a.line - b.line);
2057
+ return findings;
2058
+ }
2059
+ function _isDir(p) {
2060
+ try {
2061
+ return fs3.statSync(p).isDirectory();
2062
+ } catch {
2063
+ return false;
2064
+ }
2065
+ }
2066
+ function _rglobMdSorted(dir) {
2067
+ const out = [];
2068
+ const walk = (current) => {
2069
+ let entries;
2070
+ try {
2071
+ entries = fs3.readdirSync(current, { withFileTypes: true });
2072
+ } catch {
2073
+ return;
2074
+ }
2075
+ for (const ent of entries) {
2076
+ const full = path3.join(current, ent.name);
2077
+ if (ent.isDirectory() || ent.isSymbolicLink() && _isDir(full)) {
2078
+ walk(full);
2079
+ } else if (ent.name.endsWith(".md")) {
2080
+ out.push(full);
2081
+ }
2082
+ }
2083
+ };
2084
+ walk(dir);
2085
+ out.sort();
2086
+ return out;
2087
+ }
2088
+ function _relToPosixOrAbs(child, root) {
2089
+ const rel = path3.relative(root, child);
2090
+ if (rel === "" || rel.startsWith("..") || path3.isAbsolute(rel)) {
2091
+ return child.split(path3.sep).join("/");
2092
+ }
2093
+ return rel.split(path3.sep).join("/");
2094
+ }
2095
+ function cmd_scan_dir(root) {
2096
+ let roots;
2097
+ if (!_isDir(root)) {
2098
+ const legacy = path3.join(ROOT, ".agent-src.uncondensed");
2099
+ if (path3.resolve(root) === path3.resolve(legacy)) {
2100
+ roots = artefact_roots();
2101
+ if (roots.length === 0) {
2102
+ process.stderr.write("error: no artefact roots found (legacy or packages/*)\n");
2103
+ return 1;
2104
+ }
2105
+ } else {
2106
+ process.stderr.write(`error: not a directory: ${root}
2107
+ `);
2108
+ return 1;
2109
+ }
2110
+ } else {
2111
+ roots = [root];
2112
+ }
2113
+ const violations = [];
2114
+ let scanned = 0;
2115
+ for (const r of roots) {
2116
+ for (const md of _rglobMdSorted(r)) {
2117
+ scanned += 1;
2118
+ const text = fs3.readFileSync(md, "utf-8");
2119
+ const lines = _splitlines(text);
2120
+ for (let idx = 0; idx < lines.length; idx++) {
2121
+ const raw = lines[idx];
2122
+ const stripped = _strip_codespans(raw);
2123
+ if (OPTION_LINE_RE.test(stripped) && TAG_RE.test(stripped)) {
2124
+ violations.push([md, idx + 1, raw.trim()]);
2125
+ }
2126
+ }
2127
+ }
2128
+ }
2129
+ try {
2130
+ assertScanned({
2131
+ gate: "check_reply_consistency",
2132
+ scanned,
2133
+ units: "markdown file(s)",
2134
+ roots: roots.map((r) => _relToPosixOrAbs(r, ROOT))
2135
+ });
2136
+ } catch (exc) {
2137
+ if (exc instanceof DeadScopeError) {
2138
+ process.stderr.write(`\u274C ${exc.message}
2139
+ `);
2140
+ return 1;
2141
+ }
2142
+ throw exc;
2143
+ }
2144
+ if (violations.length > 0) {
2145
+ for (const [p, line, snippet] of violations) {
2146
+ process.stderr.write(` \u{1F534} ${p}:${String(line)} \u2014 inline-tag \u2014 ${snippet}
2147
+ `);
2148
+ }
2149
+ process.stderr.write(`
2150
+ \u274C ${String(violations.length)} legacy-pattern violation(s)
2151
+ `);
2152
+ return 2;
2153
+ }
2154
+ if (!QUIET) {
2155
+ const scanned2 = roots.map((r) => _relToPosixOrAbs(r, ROOT)).join(", ");
2156
+ process.stdout.write(`\u2705 No legacy (recommended) tags found under ${scanned2}
2157
+ `);
2158
+ }
2159
+ return 0;
2160
+ }
2161
+ var USAGE = "usage: check_reply_consistency [-h] (--stdin | --file FILE | --scan-dir SCAN_DIR)\n [-v] [--quiet]\n";
2162
+ function _usage_error(message) {
2163
+ process.stderr.write(USAGE);
2164
+ process.stderr.write(`check_reply_consistency: error: ${message}
2165
+ `);
2166
+ process.exit(1);
2167
+ }
2168
+ function _readStdin() {
2169
+ try {
2170
+ return fs3.readFileSync(0, "utf-8");
2171
+ } catch {
2172
+ return "";
2173
+ }
2174
+ }
2175
+ function parse_args(argv) {
2176
+ let stdin = false;
2177
+ let file = null;
2178
+ let scan_dir = null;
2179
+ let verbose = false;
2180
+ const groupSeen = [];
2181
+ const need = (i, name) => {
2182
+ const v = argv[i];
2183
+ if (v === void 0) {
2184
+ _usage_error(`argument ${name}: expected one argument`);
2185
+ }
2186
+ return v;
2187
+ };
2188
+ for (let i = 0; i < argv.length; i++) {
2189
+ const arg = argv[i];
2190
+ if (arg === "--stdin") {
2191
+ stdin = true;
2192
+ groupSeen.push("--stdin");
2193
+ } else if (arg === "--file") {
2194
+ file = need(++i, "--file");
2195
+ groupSeen.push("--file");
2196
+ } else if (arg.startsWith("--file=")) {
2197
+ file = arg.slice("--file=".length);
2198
+ groupSeen.push("--file");
2199
+ } else if (arg === "--scan-dir") {
2200
+ scan_dir = need(++i, "--scan-dir");
2201
+ groupSeen.push("--scan-dir");
2202
+ } else if (arg.startsWith("--scan-dir=")) {
2203
+ scan_dir = arg.slice("--scan-dir=".length);
2204
+ groupSeen.push("--scan-dir");
2205
+ } else if (arg === "-v" || arg === "--verbose") {
2206
+ verbose = true;
2207
+ } else if (arg === "--quiet") {
2208
+ } else if (arg === "-h" || arg === "--help") {
2209
+ process.stdout.write(USAGE);
2210
+ process.exit(0);
2211
+ } else {
2212
+ _usage_error(`unrecognized arguments: ${arg}`);
2213
+ }
2214
+ }
2215
+ if (groupSeen.length === 0) {
2216
+ _usage_error("one of the arguments --stdin --file --scan-dir is required");
2217
+ }
2218
+ if (groupSeen.length > 1) {
2219
+ _usage_error(`argument ${groupSeen[1]}: not allowed with argument ${groupSeen[0]}`);
2220
+ }
2221
+ return { stdin, file, scan_dir, verbose };
2222
+ }
2223
+ function main3(argv = process.argv.slice(2)) {
2224
+ const args = parse_args(argv);
2225
+ if (args.scan_dir !== null) {
2226
+ return cmd_scan_dir(args.scan_dir);
2227
+ }
2228
+ let text;
2229
+ try {
2230
+ text = args.stdin ? _readStdin() : fs3.readFileSync(args.file, "utf-8");
2231
+ } catch (e) {
2232
+ process.stderr.write(`error: ${String(e)}
2233
+ `);
2234
+ return 1;
2235
+ }
2236
+ const findings = check_reply(text);
2237
+ if (findings.length === 0) {
2238
+ if (args.verbose && !QUIET) {
2239
+ process.stdout.write("\u2705 reply consistent (every options block carries one adjacent recommendation)\n");
2240
+ }
2241
+ return 0;
2242
+ }
2243
+ for (const f of findings) {
2244
+ process.stderr.write(`\u274C line ${String(f.line)}: ${f.message}
2245
+ `);
2246
+ }
2247
+ return 2;
2248
+ }
2249
+ function _isCliEntry3() {
2250
+ if (true) {
2251
+ return false;
2252
+ }
2253
+ if (process.argv[1] === void 0) {
2254
+ return false;
2255
+ }
2256
+ const argvUrl = pathToFileURL3(path3.resolve(process.argv[1])).href;
2257
+ if (import.meta.url === argvUrl) {
2258
+ return true;
2259
+ }
2260
+ try {
2261
+ const here = fs3.realpathSync(fileURLToPath3(import.meta.url));
2262
+ const argv = fs3.realpathSync(path3.resolve(process.argv[1]));
2263
+ return here === argv;
2264
+ } catch {
2265
+ return false;
2266
+ }
2267
+ }
2268
+ var _IN_BUNDLE = true;
2269
+ if (!_IN_BUNDLE && (_isCliEntry3() || process.argv[1] === _HERE)) {
2270
+ process.exit(main3());
2271
+ }
2272
+
2273
+ // src/scripts/_lib/dropped_decision.ts
2274
+ function detectDroppedDecision(assistantTurnTexts, closingFromPayload = false) {
2275
+ if (assistantTurnTexts.length < 2) return null;
2276
+ const asksIn = (text) => {
2277
+ const blocks = find_option_blocks(text);
2278
+ if (blocks.length === 0) return blocks;
2279
+ const masked = splitAndMask(text);
2280
+ return blocks.filter((b) => recommendationsUnder(text, b, masked).length > 0);
2281
+ };
2282
+ const closing = assistantTurnTexts[assistantTurnTexts.length - 1];
2283
+ if (asksIn(closing).length > 0) return null;
2284
+ for (let i = assistantTurnTexts.length - 2; i >= 0; i -= 1) {
2285
+ const earlier = assistantTurnTexts[i];
2286
+ const blocks = asksIn(earlier);
2287
+ if (blocks.length === 0) continue;
2288
+ const block = blocks[blocks.length - 1];
2289
+ return {
2290
+ detector: "pending-decision",
2291
+ // The option NUMBERS and the line span, never the option text: the
2292
+ // evidence is quoted into a refusal that reaches the transcript, and
2293
+ // an options block can carry anything the reply carried.
2294
+ evidence: `options ${block.numbers.join("/")} at lines ${block.startLine}-${block.endLine} of an earlier reply this turn (closing reply read from ${closingFromPayload ? "the stop payload" : "the transcript"})`,
2295
+ reason: "an earlier reply in THIS turn put numbered options to the user and no user answer followed \u2014 this closing reply carries no options block, so the decision disappeared without being answered, cancelled or superseded. A hook nudge, a reviewer result or a task notification may ADD to a turn; it may not displace a question already asked (user-interaction Iron Law 3: a decision handed to the user outlives the turn). Re-present the block and its recommendation line at the end of this reply"
2296
+ };
2297
+ }
2298
+ return null;
2299
+ }
2300
+
2301
+ // src/scripts/hooks/end_review_nudge_hook.ts
2302
+ import { spawnSync as spawnSync2 } from "node:child_process";
2303
+ import * as crypto from "node:crypto";
2304
+ import * as fs5 from "node:fs";
2305
+ import * as os from "node:os";
2306
+ import * as path5 from "node:path";
2307
+ import { fileURLToPath as fileURLToPath4, pathToFileURL as pathToFileURL4 } from "node:url";
2308
+
2309
+ // src/scripts/_lib/review_baseline.ts
2310
+ import { spawnSync } from "node:child_process";
2311
+ import * as fs4 from "node:fs";
2312
+ import * as path4 from "node:path";
2313
+ function currentHeadSha(cwd) {
2314
+ try {
2315
+ const r = spawnSync("git", ["rev-parse", "HEAD"], { cwd, encoding: "utf8" });
2316
+ if (r.status !== 0) return null;
2317
+ const out = (r.stdout ?? "").trim();
2318
+ return out === "" ? null : out;
2319
+ } catch {
2320
+ return null;
2321
+ }
2322
+ }
2323
+ var BASELINE_STATE_REL = path4.join("agents", "runtime", "state", "review-baseline");
2324
+ function baselineStateDir(workspaceRoot) {
2325
+ return path4.join(workspaceRoot, BASELINE_STATE_REL);
2326
+ }
2327
+ function baselineStateFile(workspaceRoot, sessionKey) {
2328
+ return path4.join(baselineStateDir(workspaceRoot), `${sessionKey}.json`);
2329
+ }
2330
+ function parseBaseline(raw) {
2331
+ let decoded;
2332
+ try {
2333
+ decoded = JSON.parse(raw);
2334
+ } catch {
2335
+ return null;
2336
+ }
2337
+ if (typeof decoded !== "object" || decoded === null || Array.isArray(decoded)) return null;
2338
+ const o = decoded;
2339
+ const lines = o["baseline_lines"];
2340
+ if (typeof lines !== "number" || !Number.isFinite(lines) || lines < 0) return null;
2341
+ const written = o["written_at"];
2342
+ if (typeof written !== "string") return null;
2343
+ const head = o["head_sha"];
2344
+ const measure = o["measure"];
2345
+ return {
2346
+ head_sha: typeof head === "string" && head !== "" ? head : null,
2347
+ baseline_lines: lines,
2348
+ ...measure === "exact" || measure === "capped_approximation" ? { measure } : {},
2349
+ written_at: written
2350
+ };
2351
+ }
2352
+ function readBaseline(workspaceRoot, sessionKey) {
2353
+ const file = baselineStateFile(workspaceRoot, sessionKey);
2354
+ let raw;
2355
+ try {
2356
+ raw = fs4.readFileSync(file, "utf-8");
2357
+ } catch (exc) {
2358
+ const code = exc?.code;
2359
+ return code === "ENOENT" ? "absent" : "unreadable";
2360
+ }
2361
+ return parseBaseline(raw) ?? "unreadable";
2362
+ }
2363
+ function applyBaseline(measuredLines, baseline, headSha, measuredMeasure = "exact") {
2364
+ if (baseline === "absent" || baseline === "unreadable") {
2365
+ return { applied: false, fallback: baseline, lines: measuredLines };
2366
+ }
2367
+ if (baseline.measure !== "exact" || measuredMeasure !== "exact") {
2368
+ return { applied: false, fallback: "mixed-measure", lines: measuredLines };
2369
+ }
2370
+ if (baseline.head_sha !== headSha()) {
2371
+ return { applied: false, fallback: "head-moved", lines: measuredLines };
2372
+ }
2373
+ return {
2374
+ applied: true,
2375
+ baseline,
2376
+ lines: Math.max(0, measuredLines - baseline.baseline_lines)
2377
+ };
2378
+ }
1954
2379
 
1955
2380
  // src/scripts/_lib/audit_field_provenance.ts
1956
2381
  var MAX_APPLIED_IDS = 32;
@@ -1966,6 +2391,13 @@ function appliedIds(values) {
1966
2391
  }
1967
2392
 
1968
2393
  // src/scripts/_lib/review_skipped_record.ts
2394
+ var BASELINE_APPLICATIONS = [
2395
+ "applied",
2396
+ "absent",
2397
+ "unreadable",
2398
+ "head_moved",
2399
+ "mixed_measure"
2400
+ ];
1969
2401
  var PRODUCER_PRIVACY_CLASS = "ids-only";
1970
2402
  function isNonNegInt(n) {
1971
2403
  return typeof n === "number" && Number.isFinite(n) && Number.isInteger(n) && n >= 0;
@@ -1981,6 +2413,9 @@ function buildReviewSkippedLine(input) {
1981
2413
  }
1982
2414
  if (!input.ts) errors.push("ts (ISO-8601 UTC) is required");
1983
2415
  if (!input.id) errors.push("id (ULID, UUID, or content hash) is required");
2416
+ if (input.baseline !== void 0 && !BASELINE_APPLICATIONS.includes(input.baseline)) {
2417
+ errors.push(`baseline must be one of ${BASELINE_APPLICATIONS.join(", ")}`);
2418
+ }
1984
2419
  if (errors.length) return { line: null, errors };
1985
2420
  const line = {
1986
2421
  schema_version: 1,
@@ -2007,7 +2442,14 @@ function buildReviewSkippedLine(input) {
2007
2442
  persona: null,
2008
2443
  input_kind: "prompt",
2009
2444
  type: "note",
2010
- review_skipped: { diff_lines: input.diff_lines, mutation_measure: input.mutation_measure }
2445
+ review_skipped: {
2446
+ diff_lines: input.diff_lines,
2447
+ mutation_measure: input.mutation_measure,
2448
+ // Omitted, not defaulted, when the producer recorded nothing —
2449
+ // audit-log-v1's absent-versus-present split is the same one
2450
+ // `skills_applied` uses above, for the same reason.
2451
+ ...input.baseline === void 0 ? {} : { baseline: input.baseline }
2452
+ }
2011
2453
  };
2012
2454
  return { line, errors: [] };
2013
2455
  }
@@ -2075,13 +2517,13 @@ function isSafeTranscriptPath(rawPath, opts = {}) {
2075
2517
  const homeDir = opts.homeDir ?? os.homedir();
2076
2518
  const maxBytes = opts.maxBytes ?? TRANSCRIPT_SCAN_MAX_BYTES;
2077
2519
  try {
2078
- const realHome = fs3.realpathSync(homeDir);
2079
- const realPath = fs3.realpathSync(rawPath);
2080
- const relative2 = path3.relative(realHome, realPath);
2081
- if (relative2 === "" || relative2.startsWith("..") || path3.isAbsolute(relative2)) {
2520
+ const realHome = fs5.realpathSync(homeDir);
2521
+ const realPath = fs5.realpathSync(rawPath);
2522
+ const relative3 = path5.relative(realHome, realPath);
2523
+ if (relative3 === "" || relative3.startsWith("..") || path5.isAbsolute(relative3)) {
2082
2524
  return false;
2083
2525
  }
2084
- const { size } = fs3.statSync(realPath);
2526
+ const { size } = fs5.statSync(realPath);
2085
2527
  return size <= maxBytes;
2086
2528
  } catch {
2087
2529
  return false;
@@ -2112,7 +2554,7 @@ function nonDocMutatedLines(rows) {
2112
2554
  }
2113
2555
  function gitNumstatRows(cwd) {
2114
2556
  try {
2115
- const r = spawnSync("git", ["diff", "--numstat", "HEAD"], {
2557
+ const r = spawnSync2("git", ["diff", "--numstat", "HEAD"], {
2116
2558
  cwd,
2117
2559
  encoding: "utf8",
2118
2560
  maxBuffer: 16 * 1024 * 1024
@@ -2125,7 +2567,7 @@ function gitNumstatRows(cwd) {
2125
2567
  }
2126
2568
  function untrackedNonDocFiles(cwd) {
2127
2569
  try {
2128
- const r = spawnSync("git", ["ls-files", "--others", "--exclude-standard"], {
2570
+ const r = spawnSync2("git", ["ls-files", "--others", "--exclude-standard"], {
2129
2571
  cwd,
2130
2572
  encoding: "utf8",
2131
2573
  maxBuffer: 16 * 1024 * 1024
@@ -2140,13 +2582,13 @@ var BINARY_PROBE_BYTES = 8e3;
2140
2582
  var UNTRACKED_FILE_READ_CAP_BYTES = 8 * 1024 * 1024;
2141
2583
  function untrackedFileLineCount(cwd, relPath) {
2142
2584
  try {
2143
- const abs = path3.resolve(cwd, relPath);
2144
- const size = fs3.statSync(abs).size;
2585
+ const abs = path5.resolve(cwd, relPath);
2586
+ const size = fs5.statSync(abs).size;
2145
2587
  if (size === 0) return 0;
2146
2588
  if (size > UNTRACKED_FILE_READ_CAP_BYTES) {
2147
2589
  return MUTATION_LINE_THRESHOLD + 1;
2148
2590
  }
2149
- const buf = fs3.readFileSync(abs);
2591
+ const buf = fs5.readFileSync(abs);
2150
2592
  if (buf.length === 0) return 0;
2151
2593
  const probe = buf.subarray(0, Math.min(buf.length, BINARY_PROBE_BYTES));
2152
2594
  if (probe.includes(0)) return 0;
@@ -2225,30 +2667,31 @@ function scanTranscriptForReviewer(transcriptText) {
2225
2667
  function buildAdvisoryLine(diffLines) {
2226
2668
  return `this session mutated ${diffLines} lines without a neutral review; spawn a cross-model reviewer before claiming done (delegation-policy / verify-budget)`;
2227
2669
  }
2228
- function appendReviewSkippedTelemetry(workspaceRoot, diffLines, mutationMeasure) {
2670
+ function appendReviewSkippedTelemetry(workspaceRoot, diffLines, mutationMeasure, baseline) {
2229
2671
  if (is_replay_mode()) return;
2230
2672
  const ts = (/* @__PURE__ */ new Date()).toISOString();
2231
2673
  const { line, errors } = buildReviewSkippedLine({
2232
2674
  diff_lines: diffLines,
2233
2675
  mutation_measure: mutationMeasure,
2234
2676
  ts,
2235
- id: crypto.randomUUID()
2677
+ id: crypto.randomUUID(),
2678
+ baseline
2236
2679
  });
2237
2680
  if (errors.length || line === null) return;
2238
2681
  try {
2239
- const dir = path3.join(workspaceRoot, "agents", "runtime", "state", "audit");
2240
- fs3.mkdirSync(dir, { recursive: true });
2241
- const file = path3.join(dir, `${ts.slice(0, 7)}.jsonl`);
2242
- fs3.appendFileSync(file, `${JSON.stringify(line)}
2682
+ const dir = path5.join(workspaceRoot, "agents", "runtime", "state", "audit");
2683
+ fs5.mkdirSync(dir, { recursive: true });
2684
+ const file = path5.join(dir, `${ts.slice(0, 7)}.jsonl`);
2685
+ fs5.appendFileSync(file, `${JSON.stringify(line)}
2243
2686
  `, "utf8");
2244
2687
  } catch {
2245
2688
  }
2246
2689
  }
2247
2690
  function sessionStateDir(workspaceRoot) {
2248
- return path3.join(workspaceRoot, "agents", "runtime", "state", "end-review-nudge");
2691
+ return path5.join(workspaceRoot, "agents", "runtime", "state", "end-review-nudge");
2249
2692
  }
2250
2693
  function sessionStateFile(workspaceRoot, sessionKey) {
2251
- return path3.join(sessionStateDir(workspaceRoot), `${sessionKey}.json`);
2694
+ return path5.join(sessionStateDir(workspaceRoot), `${sessionKey}.json`);
2252
2695
  }
2253
2696
  function deriveSessionKey2(envelope, payload) {
2254
2697
  const raw = str(envelope["session_id"]) || str(payload["transcript_path"] ?? payload["transcriptPath"]);
@@ -2257,7 +2700,7 @@ function deriveSessionKey2(envelope, payload) {
2257
2700
  }
2258
2701
  function hasFiredThisSession(workspaceRoot, sessionKey) {
2259
2702
  try {
2260
- return fs3.existsSync(sessionStateFile(workspaceRoot, sessionKey));
2703
+ return fs5.existsSync(sessionStateFile(workspaceRoot, sessionKey));
2261
2704
  } catch {
2262
2705
  return false;
2263
2706
  }
@@ -2271,26 +2714,45 @@ function markFiredThisSession(workspaceRoot, sessionKey, ts) {
2271
2714
  function _read_stdin() {
2272
2715
  return readHookStdin();
2273
2716
  }
2274
- function main3() {
2717
+ var FALLBACK_TO_TELEMETRY = {
2718
+ absent: "absent",
2719
+ unreadable: "unreadable",
2720
+ "head-moved": "head_moved",
2721
+ "mixed-measure": "mixed_measure"
2722
+ };
2723
+ function main4() {
2275
2724
  const [envelope, payload] = unwrap(_read_stdin(), "claude");
2276
2725
  const event = String(envelope["event"] ?? "");
2277
2726
  if (event !== "" && event !== "stop") {
2278
2727
  return 0;
2279
2728
  }
2280
2729
  const workspace_root = String(envelope["workspace_root"] ?? "").trim() || process.cwd();
2281
- let diffLines;
2730
+ let measuredLines;
2282
2731
  let mutationMeasure;
2283
2732
  try {
2284
2733
  const measured = totalNonDocMutatedLinesWithMeasure(workspace_root);
2285
- diffLines = measured.lines;
2734
+ measuredLines = measured.lines;
2286
2735
  mutationMeasure = measured.measure;
2287
2736
  } catch {
2288
2737
  return 0;
2289
2738
  }
2739
+ const sessionKey = deriveSessionKey2(envelope, payload);
2740
+ const baselineOutcome = applyBaseline(
2741
+ measuredLines,
2742
+ readBaseline(workspace_root, sessionKey),
2743
+ // A THUNK, not a value: on the `absent` and `unreadable` branches the
2744
+ // result is discarded, and those two are the steady state on every host
2745
+ // without this nudge and on every session before its first baseline
2746
+ // write. Passing the value eagerly spent an 11-14 ms `git rev-parse` on
2747
+ // each of those stops for nothing.
2748
+ () => currentHeadSha(workspace_root),
2749
+ mutationMeasure
2750
+ );
2751
+ const diffLines = baselineOutcome.lines;
2752
+ const baselineApplication = baselineOutcome.applied ? "applied" : FALLBACK_TO_TELEMETRY[baselineOutcome.fallback];
2290
2753
  if (diffLines <= MUTATION_LINE_THRESHOLD) {
2291
2754
  return 0;
2292
2755
  }
2293
- const sessionKey = deriveSessionKey2(envelope, payload);
2294
2756
  if (hasFiredThisSession(workspace_root, sessionKey)) {
2295
2757
  return 0;
2296
2758
  }
@@ -2300,7 +2762,7 @@ function main3() {
2300
2762
  let reviewerRan = false;
2301
2763
  if (transcriptPath && isSafeTranscriptPath(transcriptPath)) {
2302
2764
  try {
2303
- reviewerRan = scanTranscriptForReviewer(fs3.readFileSync(transcriptPath, "utf-8"));
2765
+ reviewerRan = scanTranscriptForReviewer(fs5.readFileSync(transcriptPath, "utf-8"));
2304
2766
  } catch {
2305
2767
  reviewerRan = false;
2306
2768
  }
@@ -2310,7 +2772,12 @@ function main3() {
2310
2772
  }
2311
2773
  markFiredThisSession(workspace_root, sessionKey, (/* @__PURE__ */ new Date()).toISOString());
2312
2774
  try {
2313
- appendReviewSkippedTelemetry(workspace_root, diffLines, mutationMeasure);
2775
+ appendReviewSkippedTelemetry(
2776
+ workspace_root,
2777
+ diffLines,
2778
+ mutationMeasure,
2779
+ baselineApplication
2780
+ );
2314
2781
  } catch {
2315
2782
  }
2316
2783
  process.stdout.write(
@@ -2323,34 +2790,34 @@ function main3() {
2323
2790
  );
2324
2791
  return EXIT_WARN2;
2325
2792
  }
2326
- function _isCliEntry3() {
2793
+ function _isCliEntry4() {
2327
2794
  if (true) {
2328
2795
  return false;
2329
2796
  }
2330
2797
  if (process.argv[1] === void 0) {
2331
2798
  return false;
2332
2799
  }
2333
- const argvUrl = pathToFileURL3(path3.resolve(process.argv[1])).href;
2800
+ const argvUrl = pathToFileURL4(path5.resolve(process.argv[1])).href;
2334
2801
  if (import.meta.url === argvUrl) {
2335
2802
  return true;
2336
2803
  }
2337
2804
  try {
2338
- const here = fs3.realpathSync(fileURLToPath3(import.meta.url));
2339
- const argv = fs3.realpathSync(path3.resolve(process.argv[1]));
2805
+ const here = fs5.realpathSync(fileURLToPath4(import.meta.url));
2806
+ const argv = fs5.realpathSync(path5.resolve(process.argv[1]));
2340
2807
  return here === argv;
2341
2808
  } catch {
2342
2809
  return false;
2343
2810
  }
2344
2811
  }
2345
- if (_isCliEntry3()) {
2346
- process.exit(main3());
2812
+ if (_isCliEntry4()) {
2813
+ process.exit(main4());
2347
2814
  }
2348
2815
 
2349
2816
  // src/scripts/hooks/subagent_ledger_hook.ts
2350
2817
  import * as crypto2 from "node:crypto";
2351
- import * as fs4 from "node:fs";
2352
- import * as path4 from "node:path";
2353
- import { fileURLToPath as fileURLToPath4, pathToFileURL as pathToFileURL4 } from "node:url";
2818
+ import * as fs6 from "node:fs";
2819
+ import * as path6 from "node:path";
2820
+ import { fileURLToPath as fileURLToPath5, pathToFileURL as pathToFileURL5 } from "node:url";
2354
2821
 
2355
2822
  // src/scripts/_lib/subagent_response.ts
2356
2823
  var MAX_SUMMARY_CHARS = 2e3;
@@ -2456,7 +2923,7 @@ var EXIT_ALLOW3 = 0;
2456
2923
  function isObject2(v) {
2457
2924
  return typeof v === "object" && v !== null && !Array.isArray(v);
2458
2925
  }
2459
- var LEDGER_DIR = path4.join("agents", "runtime", "state", "subagent-ledger");
2926
+ var LEDGER_DIR = path6.join("agents", "runtime", "state", "subagent-ledger");
2460
2927
  var OPEN_SUBDIR = "open";
2461
2928
  var OPEN_RECORD_TTL_MS = 24 * 60 * 60 * 1e3;
2462
2929
  function refFor(agentId) {
@@ -2546,10 +3013,10 @@ function _jsonObjectCandidates(message) {
2546
3013
  return out;
2547
3014
  }
2548
3015
  function openDir(root) {
2549
- return path4.join(root, LEDGER_DIR, OPEN_SUBDIR);
3016
+ return path6.join(root, LEDGER_DIR, OPEN_SUBDIR);
2550
3017
  }
2551
3018
  function openFile(root, ref) {
2552
- return path4.join(openDir(root), `${ref}.json`);
3019
+ return path6.join(openDir(root), `${ref}.json`);
2553
3020
  }
2554
3021
  var DEPTH_BASES = /* @__PURE__ */ new Set(["observed", "asserted-parent", "assumed-root"]);
2555
3022
  function _asOpenRecord(value, expectedRef) {
@@ -2576,7 +3043,7 @@ function readOpenRecords(root) {
2576
3043
  const out = /* @__PURE__ */ new Map();
2577
3044
  let names;
2578
3045
  try {
2579
- names = fs4.readdirSync(openDir(root));
3046
+ names = fs6.readdirSync(openDir(root));
2580
3047
  } catch {
2581
3048
  return out;
2582
3049
  }
@@ -2584,7 +3051,7 @@ function readOpenRecords(root) {
2584
3051
  if (!name.endsWith(".json")) continue;
2585
3052
  const expectedRef = name.slice(0, -".json".length);
2586
3053
  try {
2587
- const raw = fs4.readFileSync(path4.join(openDir(root), name), "utf8");
3054
+ const raw = fs6.readFileSync(path6.join(openDir(root), name), "utf8");
2588
3055
  const rec = _asOpenRecord(JSON.parse(raw), expectedRef);
2589
3056
  if (rec) out.set(rec.ref, rec);
2590
3057
  } catch {
@@ -2599,13 +3066,13 @@ function resolveDepth(parentRef, open) {
2599
3066
  return { depth: parent.depth + 1, depth_basis: "observed" };
2600
3067
  }
2601
3068
  function ledgerFileFor2(root, ts) {
2602
- return path4.join(root, LEDGER_DIR, `${ts.slice(0, 7)}.jsonl`);
3069
+ return path6.join(root, LEDGER_DIR, `${ts.slice(0, 7)}.jsonl`);
2603
3070
  }
2604
3071
  function appendLedgerLine(root, ts, line) {
2605
3072
  if (is_replay_mode()) return;
2606
3073
  const file = ledgerFileFor2(root, ts);
2607
- fs4.mkdirSync(path4.dirname(file), { recursive: true });
2608
- fs4.appendFileSync(file, `${JSON.stringify(line)}
3074
+ fs6.mkdirSync(path6.dirname(file), { recursive: true });
3075
+ fs6.appendFileSync(file, `${JSON.stringify(line)}
2609
3076
  `, "utf8");
2610
3077
  }
2611
3078
  var WALL_CLOCK_ARMS_MS = [
@@ -2619,7 +3086,7 @@ function armsExceeded(elapsedMs) {
2619
3086
  return WALL_CLOCK_ARMS_MS.filter((a) => elapsedMs >= a.ms).map((a) => a.label);
2620
3087
  }
2621
3088
  function openRecordStats(root, nowMs = Date.now()) {
2622
- const ledgerPresent = fs4.existsSync(path4.join(root, LEDGER_DIR));
3089
+ const ledgerPresent = fs6.existsSync(path6.join(root, LEDGER_DIR));
2623
3090
  const open = readOpenRecords(root);
2624
3091
  let maxDepth = 0;
2625
3092
  let counted = 0;
@@ -2647,13 +3114,13 @@ function writeOpenRecord(root, rec) {
2647
3114
  function removeOpenRecord(root, ref) {
2648
3115
  if (is_replay_mode()) return;
2649
3116
  try {
2650
- fs4.unlinkSync(openFile(root, ref));
3117
+ fs6.unlinkSync(openFile(root, ref));
2651
3118
  } catch {
2652
3119
  }
2653
3120
  }
2654
3121
  function countOpen(root) {
2655
3122
  try {
2656
- return fs4.readdirSync(openDir(root)).filter((n) => n.endsWith(".json")).length;
3123
+ return fs6.readdirSync(openDir(root)).filter((n) => n.endsWith(".json")).length;
2657
3124
  } catch {
2658
3125
  return 0;
2659
3126
  }
@@ -2804,7 +3271,7 @@ function resolveConsumerRoot(envelope) {
2804
3271
  }
2805
3272
  return process.cwd();
2806
3273
  }
2807
- function main4() {
3274
+ function main5() {
2808
3275
  const raw = readHookStdin();
2809
3276
  let envelope = {};
2810
3277
  try {
@@ -2814,20 +3281,20 @@ function main4() {
2814
3281
  }
2815
3282
  return processEnvelope(envelope, resolveConsumerRoot(envelope));
2816
3283
  }
2817
- function _isCliEntry4() {
3284
+ function _isCliEntry5() {
2818
3285
  if (true) {
2819
3286
  return false;
2820
3287
  }
2821
3288
  if (process.argv[1] === void 0) return false;
2822
- const argvUrl = pathToFileURL4(path4.resolve(process.argv[1])).href;
3289
+ const argvUrl = pathToFileURL5(path6.resolve(process.argv[1])).href;
2823
3290
  if (import.meta.url === argvUrl) return true;
2824
3291
  try {
2825
- return fs4.realpathSync(fileURLToPath4(import.meta.url)) === fs4.realpathSync(path4.resolve(process.argv[1]));
3292
+ return fs6.realpathSync(fileURLToPath5(import.meta.url)) === fs6.realpathSync(path6.resolve(process.argv[1]));
2826
3293
  } catch {
2827
3294
  return false;
2828
3295
  }
2829
3296
  }
2830
- if (_isCliEntry4()) process.exit(main4());
3297
+ if (_isCliEntry5()) process.exit(main5());
2831
3298
 
2832
3299
  // src/scripts/hooks/turn_end_gate_hook.ts
2833
3300
  var EXIT_BLOCK = 1;
@@ -2936,7 +3403,7 @@ function detectPromissory(reply) {
2936
3403
  function readCiSettled(workspaceRoot, session_id) {
2937
3404
  if (!hasStableSessionId(session_id)) return { seen: false, settled: false };
2938
3405
  try {
2939
- const raw = fs5.readFileSync(path5.join(workspaceRoot, statePathFor(session_id)), "utf-8");
3406
+ const raw = fs7.readFileSync(path7.join(workspaceRoot, statePathFor(session_id)), "utf-8");
2940
3407
  const decoded = JSON.parse(raw);
2941
3408
  if (!owns_session_state(decoded, session_id)) return { seen: false, settled: false };
2942
3409
  if (typeof decoded === "object" && decoded !== null && !Array.isArray(decoded)) {
@@ -2972,8 +3439,8 @@ function detectCompletionClaim(reply, ci) {
2972
3439
  function readLanguagePin(workspaceRoot, session_id) {
2973
3440
  if (!hasStableSessionId(session_id)) return "und";
2974
3441
  try {
2975
- const raw = fs5.readFileSync(
2976
- path5.join(workspaceRoot, statePathFor2(session_id)),
3442
+ const raw = fs7.readFileSync(
3443
+ path7.join(workspaceRoot, statePathFor2(session_id)),
2977
3444
  "utf-8"
2978
3445
  );
2979
3446
  const decoded = JSON.parse(raw);
@@ -3024,12 +3491,37 @@ function detectUnverifiedEdit(toolCalls) {
3024
3491
  reason: "this turn changed a file and then ran no verification command \u2014 no test, type-check, lint or build call follows the last edit (verify-before-complete: a claim without a fresh run is unverified)"
3025
3492
  };
3026
3493
  }
3494
+ var _SOURCE_RE = /\.(?:ts|tsx|js|jsx|mjs|cjs|vue|svelte|php|py|rb|go|rs|java|kt|swift|cs|scala|ex|exs)$/i;
3495
+ var _TEST_PATH_RE = /(?:^|\/)(?:tests?|specs?|__tests__|__specs__|e2e|cypress|playwright|features)\//i;
3496
+ var _TEST_FILE_RE = /(?:\.(?:test|spec)\.[a-z]+$)|(?:_test\.[a-z]+$)|(?:(?:^|\/)test_[^/]+$)|(?:Test\.php$)|(?:Spec\.php$)|(?:\.feature$)/i;
3497
+ function _isTestPath(p) {
3498
+ return _TEST_PATH_RE.test(p) || _TEST_FILE_RE.test(p);
3499
+ }
3500
+ function _isProductionSource(p) {
3501
+ return _SOURCE_RE.test(p) && !_isTestPath(p);
3502
+ }
3503
+ function detectUntestedChange(reply, toolCalls) {
3504
+ const edited = toolCalls.filter((c) => _EDIT_TOOLS.has(c.name) && c.path !== void 0).map((c) => c.path);
3505
+ const source = edited.filter(_isProductionSource);
3506
+ if (source.length === 0) return null;
3507
+ if (edited.some(_isTestPath)) return null;
3508
+ const prose = visibleProse(reply);
3509
+ const m = _COMPLETION_RE.exec(prose);
3510
+ if (!m) return null;
3511
+ if (_NEGATED_CLAIM_RE.test(_lineAround(prose, m.index))) return null;
3512
+ const shown = source.slice(0, 3).join(", ");
3513
+ return {
3514
+ detector: "untested",
3515
+ evidence: shown + (source.length > 3 ? ` (+${String(source.length - 3)} more)` : ""),
3516
+ reason: "a completion claim over production code this turn changed, with NO test file touched anywhere in the turn \u2014 running a linter is not evidence the change works. Write the test that would have caught the failure, and enumerate the states the change actually has (every view, every CRUD path, the empty and error states) rather than the happy one. If a test genuinely does not belong here, say which file carries the coverage instead"
3517
+ };
3518
+ }
3027
3519
  function sessionStateFile2(workspaceRoot, sessionKey) {
3028
3520
  return sessionRefusalFile(workspaceRoot, sessionKey);
3029
3521
  }
3030
3522
  function alreadyRefusedTurn(workspaceRoot, sessionKey, turnOrdinal) {
3031
3523
  try {
3032
- const raw = fs5.readFileSync(sessionStateFile2(workspaceRoot, sessionKey), "utf-8");
3524
+ const raw = fs7.readFileSync(sessionStateFile2(workspaceRoot, sessionKey), "utf-8");
3033
3525
  const decoded = JSON.parse(raw);
3034
3526
  if (typeof decoded === "object" && decoded !== null && !Array.isArray(decoded)) {
3035
3527
  return decoded["refused_turn"] === turnOrdinal;
@@ -3038,12 +3530,12 @@ function alreadyRefusedTurn(workspaceRoot, sessionKey, turnOrdinal) {
3038
3530
  }
3039
3531
  return false;
3040
3532
  }
3041
- function markRefusedTurn(workspaceRoot, sessionKey, turnOrdinal, detectors) {
3533
+ function markRefusedTurn(workspaceRoot, sessionKey, turnOrdinal, detectors, promptId) {
3042
3534
  if (is_replay_mode()) return;
3043
3535
  const file = sessionStateFile2(workspaceRoot, sessionKey);
3044
3536
  let prev = null;
3045
3537
  try {
3046
- prev = parseRecord(fs5.readFileSync(file, "utf-8"));
3538
+ prev = parseRecord(fs7.readFileSync(file, "utf-8"));
3047
3539
  } catch {
3048
3540
  }
3049
3541
  let version;
@@ -3059,27 +3551,34 @@ function markRefusedTurn(workspaceRoot, sessionKey, turnOrdinal, detectors) {
3059
3551
  detectors,
3060
3552
  turnOrdinal,
3061
3553
  at: (/* @__PURE__ */ new Date()).toISOString(),
3062
- version
3554
+ version,
3555
+ promptId
3063
3556
  })
3064
3557
  );
3065
3558
  } catch {
3066
3559
  }
3067
3560
  }
3068
3561
  function readTranscriptTail(transcriptPath, opts = {}) {
3069
- const empty = { lastAssistant: "", turnOrdinal: 0, toolCalls: [] };
3562
+ const empty = {
3563
+ lastAssistant: "",
3564
+ turnOrdinal: 0,
3565
+ toolCalls: [],
3566
+ assistantTurnTexts: []
3567
+ };
3070
3568
  if (!transcriptPath || !isSafeTranscriptPath(transcriptPath, opts)) return empty;
3071
3569
  let lines;
3072
3570
  try {
3073
- if (opts.maxBytes !== void 0 && fs5.statSync(transcriptPath).size > opts.maxBytes) {
3571
+ if (opts.maxBytes !== void 0 && fs7.statSync(transcriptPath).size > opts.maxBytes) {
3074
3572
  return empty;
3075
3573
  }
3076
- lines = fs5.readFileSync(transcriptPath, "utf-8").split("\n");
3574
+ lines = fs7.readFileSync(transcriptPath, "utf-8").split("\n");
3077
3575
  } catch {
3078
3576
  return empty;
3079
3577
  }
3080
3578
  let lastAssistant = "";
3081
3579
  let turnOrdinal = 0;
3082
3580
  let toolCalls = [];
3581
+ let assistantTurnTexts = [];
3083
3582
  for (const rawLine of lines) {
3084
3583
  const line = rawLine.trim();
3085
3584
  if (!line) continue;
@@ -3098,20 +3597,27 @@ function readTranscriptTail(transcriptPath, opts = {}) {
3098
3597
  if (typeof msg !== "object" || msg === null || Array.isArray(msg)) continue;
3099
3598
  const content = msg["content"];
3100
3599
  if (role === "assistant") {
3101
- toolCalls.push(..._toolCalls(content));
3600
+ toolCalls.push(...extractToolCalls(content));
3102
3601
  }
3103
3602
  const text = _messageText(content);
3104
3603
  if (text === null) continue;
3105
3604
  if (role === "assistant") {
3106
3605
  lastAssistant = text;
3606
+ assistantTurnTexts.push(text);
3107
3607
  } else if (!isSyntheticPrompt(text)) {
3108
3608
  turnOrdinal += 1;
3109
3609
  toolCalls = [];
3610
+ assistantTurnTexts = [];
3110
3611
  }
3111
3612
  }
3112
- return { lastAssistant: lastAssistant.trim(), turnOrdinal, toolCalls };
3613
+ return {
3614
+ lastAssistant: lastAssistant.trim(),
3615
+ turnOrdinal,
3616
+ toolCalls,
3617
+ assistantTurnTexts
3618
+ };
3113
3619
  }
3114
- function _toolCalls(content) {
3620
+ function extractToolCalls(content) {
3115
3621
  if (!Array.isArray(content)) return [];
3116
3622
  const out = [];
3117
3623
  for (const blk of content) {
@@ -3149,7 +3655,7 @@ function _messageText(content) {
3149
3655
  function str3(v) {
3150
3656
  return typeof v === "string" ? v : "";
3151
3657
  }
3152
- function main5() {
3658
+ function main6() {
3153
3659
  let envelope;
3154
3660
  let payload;
3155
3661
  try {
@@ -3167,10 +3673,19 @@ function main5() {
3167
3673
  const transcriptPath = str3(
3168
3674
  payload["transcript_path"] ?? payload["transcriptPath"]
3169
3675
  );
3170
- const { lastAssistant, turnOrdinal, toolCalls } = readTranscriptTail(transcriptPath, {
3171
- maxBytes: TRANSCRIPT_READ_MAX_BYTES
3172
- });
3676
+ const { lastAssistant, turnOrdinal, toolCalls, assistantTurnTexts } = readTranscriptTail(
3677
+ transcriptPath,
3678
+ { maxBytes: TRANSCRIPT_READ_MAX_BYTES }
3679
+ );
3173
3680
  if (!lastAssistant) return EXIT_ALLOW4;
3681
+ const payloadClosing = str3(
3682
+ payload["last_assistant_message"] ?? payload["lastAssistantMessage"]
3683
+ );
3684
+ const closingFromPayload = payloadClosing !== "" && !assistantTurnTexts.includes(payloadClosing);
3685
+ const turnTexts = closingFromPayload ? [...assistantTurnTexts, payloadClosing] : assistantTurnTexts;
3686
+ const promptId = str3(
3687
+ payload["prompt_id"] ?? payload["promptId"]
3688
+ );
3174
3689
  const rawSessionId = str3(envelope["session_id"]) || "";
3175
3690
  const sessionKey = deriveSessionKey(rawSessionId || "unknown-session");
3176
3691
  if (alreadyRefusedTurn(workspaceRoot, sessionKey, turnOrdinal)) return EXIT_ALLOW4;
@@ -3192,7 +3707,23 @@ function main5() {
3192
3707
  // gating is where the comment above says gating belongs — inside the
3193
3708
  // detector: no CI observed, or a settled read, or no completion claim
3194
3709
  // ⇒ no finding.
3195
- dispatchOpen ? null : detectCompletionClaim(lastAssistant, readCiSettled(workspaceRoot, rawSessionId))
3710
+ dispatchOpen ? null : detectCompletionClaim(lastAssistant, readCiSettled(workspaceRoot, rawSessionId)),
3711
+ // Detector E is UNCONDITIONAL, and that is the opposite choice from A
3712
+ // and D one line above rather than an oversight. An open dispatch
3713
+ // excuses a promissory closing because the work is genuinely still
3714
+ // running; it excuses nothing about a question the user was already
3715
+ // asked. Worse: a dispatch — or the `end-review-nudge` stop concern
3716
+ // that produced the measured failure — IS the continuation that drops
3717
+ // the decision, so narrowing E the same way would silence it in exactly
3718
+ // the case it exists for.
3719
+ detectDroppedDecision(turnTexts, closingFromPayload),
3720
+ // Detector F takes the OTHER side of that same question, and the two
3721
+ // sitting adjacent is the clearest place to say why. E fires on a
3722
+ // question already asked, which an open dispatch cannot excuse. F fires
3723
+ // on a completion CLAIM, and a turn waiting on a subagent has not
3724
+ // finished — so its closing is not the claim F is about. Same slot,
3725
+ // opposite trigger, opposite treatment of `dispatchOpen`.
3726
+ dispatchOpen ? null : detectUntestedChange(lastAssistant, toolCalls)
3196
3727
  ]) {
3197
3728
  if (f) findings.push(f);
3198
3729
  }
@@ -3201,7 +3732,8 @@ function main5() {
3201
3732
  workspaceRoot,
3202
3733
  sessionKey,
3203
3734
  turnOrdinal,
3204
- findings.map((f) => f.detector)
3735
+ findings.map((f) => f.detector),
3736
+ promptId
3205
3737
  );
3206
3738
  const lines = findings.map(
3207
3739
  (f) => ` \xB7 ${f.detector}: ${f.reason}
@@ -3210,43 +3742,61 @@ function main5() {
3210
3742
  process.stderr.write(
3211
3743
  `turn-end-gate: REFUSED \u2014 this turn is not finished.
3212
3744
  ${lines.join("\n")}
3213
- Do the promised work now, correct the language, run the verification the edit needs, or read the CI verdict before claiming it \u2014 then end the turn.
3745
+ Do the promised work now, correct the language, run the verification the edit needs, read the CI verdict before claiming it, or re-present the options block this turn dropped \u2014 then end the turn.
3214
3746
  This turn will not be refused a second time.
3215
3747
  `
3216
3748
  );
3217
3749
  return EXIT_BLOCK;
3218
3750
  }
3219
- function _isCliEntry5() {
3751
+ function _isCliEntry6() {
3220
3752
  if (true) {
3221
3753
  return false;
3222
3754
  }
3223
3755
  if (process.argv[1] === void 0) {
3224
3756
  return false;
3225
3757
  }
3226
- const argvUrl = pathToFileURL5(path5.resolve(process.argv[1])).href;
3758
+ const argvUrl = pathToFileURL6(path7.resolve(process.argv[1])).href;
3227
3759
  if (import.meta.url === argvUrl) {
3228
3760
  return true;
3229
3761
  }
3230
3762
  try {
3231
- const here = fs5.realpathSync(fileURLToPath5(import.meta.url));
3232
- const argv = fs5.realpathSync(path5.resolve(process.argv[1]));
3763
+ const here = fs7.realpathSync(fileURLToPath6(import.meta.url));
3764
+ const argv = fs7.realpathSync(path7.resolve(process.argv[1]));
3233
3765
  return here === argv;
3234
3766
  } catch {
3235
3767
  return false;
3236
3768
  }
3237
3769
  }
3238
- if (_isCliEntry5()) {
3239
- process.exit(main5());
3770
+ if (_isCliEntry6()) {
3771
+ process.exit(main6());
3240
3772
  }
3241
3773
 
3242
3774
  // src/scripts/hooks/evidence_independence.ts
3775
+ import { spawnSync as spawnSync3 } from "node:child_process";
3243
3776
  import crypto3 from "node:crypto";
3244
- import fs6 from "node:fs";
3245
- import path6 from "node:path";
3246
- import { fileURLToPath as fileURLToPath6, pathToFileURL as pathToFileURL6 } from "node:url";
3777
+ import fs8 from "node:fs";
3778
+ import path8 from "node:path";
3779
+ import { fileURLToPath as fileURLToPath7, pathToFileURL as pathToFileURL7 } from "node:url";
3780
+
3781
+ // src/scripts/_lib/test_delta.ts
3782
+ function isCodePath(p) {
3783
+ const f = p.replace(/\\/g, "/");
3784
+ if (isTestPath(f)) return false;
3785
+ if (!/\.(ts|tsx|js|mjs|cjs)$/.test(f)) return false;
3786
+ if (f.endsWith(".d.ts")) return false;
3787
+ if (/^(dist|\.augment|\.claude|\.cursor|node_modules)\//.test(f)) return false;
3788
+ return /^(src|scripts)\//.test(f);
3789
+ }
3790
+ function isTestPath(p) {
3791
+ const f = p.replace(/\\/g, "/");
3792
+ if (/^tests\//.test(f)) return true;
3793
+ return /\.(test|spec)\.(ts|tsx|js|mjs|cjs)$/.test(f);
3794
+ }
3795
+
3796
+ // src/scripts/hooks/evidence_independence.ts
3247
3797
  var EXIT_ALLOW5 = 0;
3248
3798
  var EXIT_BLOCK2 = 1;
3249
- var STATE_FILE3 = path6.join("agents", "state", "evidence-dispatch.json");
3799
+ var STATE_FILE3 = path8.join("agents", "state", "evidence-dispatch.json");
3250
3800
  function _isObject5(v) {
3251
3801
  return typeof v === "object" && v !== null && !Array.isArray(v);
3252
3802
  }
@@ -3314,8 +3864,8 @@ function extractDispatch(envelope) {
3314
3864
  }
3315
3865
  function _ledgerStamp(consumer_root) {
3316
3866
  try {
3317
- const raw = fs6.readFileSync(
3318
- path6.join(consumer_root, "agents", "state", "git-authorization.json"),
3867
+ const raw = fs8.readFileSync(
3868
+ path8.join(consumer_root, "agents", "state", "git-authorization.json"),
3319
3869
  "utf8"
3320
3870
  );
3321
3871
  const d = JSON.parse(raw);
@@ -3326,7 +3876,7 @@ function _ledgerStamp(consumer_root) {
3326
3876
  }
3327
3877
  function _load(target) {
3328
3878
  try {
3329
- const decoded = JSON.parse(fs6.readFileSync(target, "utf8"));
3879
+ const decoded = JSON.parse(fs8.readFileSync(target, "utf8"));
3330
3880
  if (_isObject5(decoded) && Array.isArray(decoded["evaluations"])) {
3331
3881
  return decoded;
3332
3882
  }
@@ -3372,6 +3922,32 @@ function decide(tool, prompt, priorEvaluations) {
3372
3922
  evaluations: priorEvaluations + 1
3373
3923
  };
3374
3924
  }
3925
+ function sameSessionTestFlag(command) {
3926
+ if (command === null || !/\bgit\b[^|;&]*\bcommit\b/.test(command)) return null;
3927
+ return SAME_SESSION_TEXT;
3928
+ }
3929
+ var SAME_SESSION_TEXT = "This commit stages both a test and code it could cover \u2014 the shape L0 takes in a diff, where the implementer authored the evaluator. This check reads the staged set only: it cannot tell who wrote the test, so it is a prompt to STATE the level, not a finding that you are at L0. L0 is a permitted FALLBACK, not the default: where a second session, a second model or a second provider was available, the test should have come from one of them. Say which in the commit or the PR body \u2014 a diff looks identical either way. See evaluator-independence \xA7 Tests are evaluators.";
3930
+ function touchesTestAndCode(paths) {
3931
+ return paths.some(isTestPath) && paths.some(isCodePath);
3932
+ }
3933
+ function _commandOf(envelope) {
3934
+ const payload = _isObject5(envelope["payload"]) ? envelope["payload"] : envelope;
3935
+ const input = _isObject5(payload["tool_input"]) ? payload["tool_input"] : payload;
3936
+ for (const key of ["command", "cmd", "shell_command"]) {
3937
+ const v = input[key];
3938
+ if (typeof v === "string" && v !== "") return v;
3939
+ }
3940
+ return null;
3941
+ }
3942
+ function _stagedPaths(consumer_root) {
3943
+ const r = spawnSync3("git", ["diff", "--cached", "--name-only"], {
3944
+ cwd: consumer_root,
3945
+ encoding: "utf8"
3946
+ });
3947
+ if (r.status !== 0) return null;
3948
+ const out = r.stdout.split("\n").map((s) => s.trim()).filter((s) => s !== "");
3949
+ return out.length === 0 ? null : out;
3950
+ }
3375
3951
  function run3(stdin_text, options) {
3376
3952
  let envelope = {};
3377
3953
  if (stdin_text.trim()) {
@@ -3384,7 +3960,7 @@ function run3(stdin_text, options) {
3384
3960
  return EXIT_ALLOW5;
3385
3961
  }
3386
3962
  }
3387
- const target = path6.join(options.consumer_root, STATE_FILE3);
3963
+ const target = path8.join(options.consumer_root, STATE_FILE3);
3388
3964
  const state = _load(target);
3389
3965
  const session_id = typeof envelope["session_id"] === "string" ? envelope["session_id"] : "";
3390
3966
  const turnMarker = `${session_id}:${_ledgerStamp(options.consumer_root)}`;
@@ -3394,6 +3970,15 @@ function run3(stdin_text, options) {
3394
3970
  state.evaluations = [];
3395
3971
  }
3396
3972
  const [tool, prompt] = extractDispatch(envelope);
3973
+ const flag = sameSessionTestFlag(_commandOf(envelope));
3974
+ if (flag !== null) {
3975
+ const staged = _stagedPaths(options.consumer_root);
3976
+ if (staged !== null && touchesTestAndCode(staged)) {
3977
+ process.stdout.write(`${JSON.stringify({ decision: "warn", reason: flag })}
3978
+ `);
3979
+ return EXIT_ALLOW5;
3980
+ }
3981
+ }
3397
3982
  const decision = decide(tool, prompt, state.evaluations.length);
3398
3983
  if (decision.evaluations > state.evaluations.length) {
3399
3984
  state.evaluations.push({
@@ -3422,7 +4007,7 @@ function _errText3(err) {
3422
4007
  const t = err instanceof Error ? err.message : String(err);
3423
4008
  return t.replace(/\s+/g, " ").trim().slice(0, 200);
3424
4009
  }
3425
- function main6(argv) {
4010
+ function main7(argv) {
3426
4011
  const args = argv ?? process.argv.slice(2);
3427
4012
  let consumer_root = process.cwd();
3428
4013
  for (let i = 0; i < args.length; i += 1) {
@@ -3436,33 +4021,33 @@ function main6(argv) {
3436
4021
  }
3437
4022
  return run3(readHookStdin(), { consumer_root });
3438
4023
  }
3439
- function _isCliEntry6() {
4024
+ function _isCliEntry7() {
3440
4025
  if (true) {
3441
4026
  return false;
3442
4027
  }
3443
4028
  if (process.argv[1] === void 0) {
3444
4029
  return false;
3445
4030
  }
3446
- const argvUrl = pathToFileURL6(path6.resolve(process.argv[1])).href;
4031
+ const argvUrl = pathToFileURL7(path8.resolve(process.argv[1])).href;
3447
4032
  if (import.meta.url === argvUrl) {
3448
4033
  return true;
3449
4034
  }
3450
4035
  try {
3451
- const here = fs6.realpathSync(fileURLToPath6(import.meta.url));
3452
- const argv = fs6.realpathSync(path6.resolve(process.argv[1]));
4036
+ const here = fs8.realpathSync(fileURLToPath7(import.meta.url));
4037
+ const argv = fs8.realpathSync(path8.resolve(process.argv[1]));
3453
4038
  return here === argv;
3454
4039
  } catch {
3455
4040
  return false;
3456
4041
  }
3457
4042
  }
3458
- if (_isCliEntry6()) {
3459
- process.exit(main6());
4043
+ if (_isCliEntry7()) {
4044
+ process.exit(main7());
3460
4045
  }
3461
4046
 
3462
4047
  // src/scripts/hooks/delegation_nudge_hook.ts
3463
- import fs7 from "node:fs";
3464
- import path7 from "node:path";
3465
- import { fileURLToPath as fileURLToPath7, pathToFileURL as pathToFileURL7 } from "node:url";
4048
+ import fs9 from "node:fs";
4049
+ import path9 from "node:path";
4050
+ import { fileURLToPath as fileURLToPath8, pathToFileURL as pathToFileURL8 } from "node:url";
3466
4051
 
3467
4052
  // src/scripts/_lib/auto_dispatch.ts
3468
4053
  var SIZE_FLOOR = 1;
@@ -3917,7 +4502,7 @@ function _workspaceRoot(envelope) {
3917
4502
  }
3918
4503
  return process.cwd();
3919
4504
  }
3920
- function main7() {
4505
+ function main8() {
3921
4506
  let envelope = {};
3922
4507
  try {
3923
4508
  const raw = readHookStdin();
@@ -3956,31 +4541,31 @@ function main7() {
3956
4541
  );
3957
4542
  return EXIT_WARN3;
3958
4543
  }
3959
- function _isCliEntry7() {
4544
+ function _isCliEntry8() {
3960
4545
  if (true) {
3961
4546
  return false;
3962
4547
  }
3963
4548
  if (process.argv[1] === void 0) {
3964
4549
  return false;
3965
4550
  }
3966
- const argvUrl = pathToFileURL7(path7.resolve(process.argv[1])).href;
4551
+ const argvUrl = pathToFileURL8(path9.resolve(process.argv[1])).href;
3967
4552
  if (import.meta.url === argvUrl) {
3968
4553
  return true;
3969
4554
  }
3970
4555
  try {
3971
- const here = fs7.realpathSync(fileURLToPath7(import.meta.url));
3972
- const argv = fs7.realpathSync(path7.resolve(process.argv[1]));
4556
+ const here = fs9.realpathSync(fileURLToPath8(import.meta.url));
4557
+ const argv = fs9.realpathSync(path9.resolve(process.argv[1]));
3973
4558
  return here === argv;
3974
4559
  } catch {
3975
4560
  return false;
3976
4561
  }
3977
4562
  }
3978
- if (_isCliEntry7()) {
3979
- process.exit(main7());
4563
+ if (_isCliEntry8()) {
4564
+ process.exit(main8());
3980
4565
  }
3981
4566
 
3982
4567
  // src/scripts/conformance_scan.ts
3983
- var REPO_ROOT = path8.resolve(path8.dirname(fileURLToPath8(import.meta.url)), "..", "..");
4568
+ var REPO_ROOT = path10.resolve(path10.dirname(fileURLToPath9(import.meta.url)), "..", "..");
3984
4569
  var OBSERVED_BAND = { low: 9.1, high: 39.2 };
3985
4570
  var BAND_MIN_TURNS = 1978;
3986
4571
  var CARRIER_CHANGES = [
@@ -4346,7 +4931,7 @@ function scanSession(sessionId, lines) {
4346
4931
  closeWindow();
4347
4932
  return report;
4348
4933
  }
4349
- var DEFAULT_RATE_SERIES = path8.join(
4934
+ var DEFAULT_RATE_SERIES = path10.join(
4350
4935
  REPO_ROOT,
4351
4936
  "agents",
4352
4937
  "runtime",
@@ -4355,7 +4940,7 @@ var DEFAULT_RATE_SERIES = path8.join(
4355
4940
  );
4356
4941
  function defaultStore(projectDir) {
4357
4942
  const slug = projectStoreSlug(projectDir);
4358
- return path8.join(process.env["HOME"] ?? "", ".claude", "projects", slug);
4943
+ return path10.join(process.env["HOME"] ?? "", ".claude", "projects", slug);
4359
4944
  }
4360
4945
  function _tokens(chars) {
4361
4946
  return Math.round(chars / 4);
@@ -4366,13 +4951,13 @@ function measureDelivered(projectRulesDir, globalRulesDir) {
4366
4951
  return {
4367
4952
  project: {
4368
4953
  dir: projectRulesDir,
4369
- present: fs8.existsSync(projectRulesDir),
4954
+ present: fs10.existsSync(projectRulesDir),
4370
4955
  files: p.files,
4371
4956
  tokens: _tokens(p.chars)
4372
4957
  },
4373
4958
  global: {
4374
4959
  dir: globalRulesDir,
4375
- present: fs8.existsSync(globalRulesDir),
4960
+ present: fs10.existsSync(globalRulesDir),
4376
4961
  files: g.files,
4377
4962
  tokens: _tokens(g.chars)
4378
4963
  },
@@ -4380,13 +4965,13 @@ function measureDelivered(projectRulesDir, globalRulesDir) {
4380
4965
  };
4381
4966
  }
4382
4967
  function storeKey(store) {
4383
- return createHash3("sha256").update(path8.resolve(store)).digest("hex").slice(0, 12);
4968
+ return createHash3("sha256").update(path10.resolve(store)).digest("hex").slice(0, 12);
4384
4969
  }
4385
4970
  function scanStore(store, limit) {
4386
- const files = fs8.readdirSync(store).filter((f) => f.endsWith(".jsonl")).map((f) => ({ f, m: fs8.statSync(path8.join(store, f)).mtimeMs })).sort((a, b) => b.m - a.m).slice(0, limit).map((x) => x.f);
4971
+ const files = fs10.readdirSync(store).filter((f) => f.endsWith(".jsonl")).map((f) => ({ f, m: fs10.statSync(path10.join(store, f)).mtimeMs })).sort((a, b) => b.m - a.m).slice(0, limit).map((x) => x.f);
4387
4972
  const per_session = [];
4388
4973
  for (const f of files) {
4389
- const lines = fs8.readFileSync(path8.join(store, f), "utf8").split("\n");
4974
+ const lines = fs10.readFileSync(path10.join(store, f), "utf8").split("\n");
4390
4975
  const r = scanSession(f.replace(/\.jsonl$/, "").slice(0, 8), lines);
4391
4976
  if (r.assistant_turns > 0) {
4392
4977
  per_session.push(r);
@@ -4414,10 +4999,10 @@ function scanStore(store, limit) {
4414
4999
  const task_completeness_rate_pct = completeness_windows === 0 ? 0 : Number((100 * task_completeness / completeness_windows).toFixed(1));
4415
5000
  const era = spansCarrierChange(per_session.map((s) => s.first_at));
4416
5001
  const delivered = measureDelivered(
4417
- path8.join(REPO_ROOT, ".claude", "rules"),
4418
- path8.join(process.env["HOME"] ?? os2.homedir(), ".claude", "rules")
5002
+ path10.join(REPO_ROOT, ".claude", "rules"),
5003
+ path10.join(process.env["HOME"] ?? os2.homedir(), ".claude", "rules")
4419
5004
  );
4420
- const ownStore = path8.resolve(store) === path8.resolve(defaultStore(REPO_ROOT));
5005
+ const ownStore = path10.resolve(store) === path10.resolve(defaultStore(REPO_ROOT));
4421
5006
  return {
4422
5007
  scanned_at: (/* @__PURE__ */ new Date()).toISOString(),
4423
5008
  store,
@@ -4447,8 +5032,8 @@ function scanStore(store, limit) {
4447
5032
  };
4448
5033
  }
4449
5034
  function recordRate(file, scanned_at, rate) {
4450
- fs8.mkdirSync(path8.dirname(file), { recursive: true });
4451
- fs8.appendFileSync(file, `${JSON.stringify({ measured_at: scanned_at, ...rate })}
5035
+ fs10.mkdirSync(path10.dirname(file), { recursive: true });
5036
+ fs10.appendFileSync(file, `${JSON.stringify({ measured_at: scanned_at, ...rate })}
4452
5037
  `, "utf8");
4453
5038
  }
4454
5039
  function render(report) {
@@ -4547,7 +5132,7 @@ function render(report) {
4547
5132
  lines.push(" checkbox batching \u2014 measured NOWHERE. ~5 low-severity findings.");
4548
5133
  return lines.join("\n");
4549
5134
  }
4550
- function main8(argv) {
5135
+ function main9(argv) {
4551
5136
  const args = argv ?? process.argv.slice(2);
4552
5137
  let store = null;
4553
5138
  let limit = 30;
@@ -4579,14 +5164,14 @@ function main8(argv) {
4579
5164
  return 2;
4580
5165
  }
4581
5166
  const resolved = store ?? defaultStore(process.cwd());
4582
- if (!fs8.existsSync(resolved)) {
5167
+ if (!fs10.existsSync(resolved)) {
4583
5168
  process.stderr.write(`conformance:behavior: no transcript store at ${resolved}
4584
5169
  `);
4585
5170
  return 1;
4586
5171
  }
4587
5172
  const report = scanStore(resolved, Number.isFinite(limit) && limit > 0 ? limit : 30);
4588
5173
  if (out) {
4589
- fs8.writeFileSync(out, `${JSON.stringify(report, null, 2)}
5174
+ fs10.writeFileSync(out, `${JSON.stringify(report, null, 2)}
4590
5175
  `, "utf8");
4591
5176
  }
4592
5177
  if (record) {
@@ -4594,7 +5179,7 @@ function main8(argv) {
4594
5179
  }
4595
5180
  if (why !== null) {
4596
5181
  const id = why;
4597
- fs8.writeSync(
5182
+ fs10.writeSync(
4598
5183
  1,
4599
5184
  json ? `${JSON.stringify(
4600
5185
  {
@@ -4614,48 +5199,48 @@ function main8(argv) {
4614
5199
  );
4615
5200
  return 0;
4616
5201
  }
4617
- fs8.writeSync(1, json ? `${JSON.stringify(report, null, 2)}
5202
+ fs10.writeSync(1, json ? `${JSON.stringify(report, null, 2)}
4618
5203
  ` : `${render(report)}
4619
5204
  `);
4620
5205
  return 0;
4621
5206
  }
4622
- function _isCliEntry8() {
5207
+ function _isCliEntry9() {
4623
5208
  if (true) {
4624
5209
  return false;
4625
5210
  }
4626
5211
  if (process.argv[1] === void 0) {
4627
5212
  return false;
4628
5213
  }
4629
- const argvUrl = pathToFileURL8(path8.resolve(process.argv[1])).href;
5214
+ const argvUrl = pathToFileURL9(path10.resolve(process.argv[1])).href;
4630
5215
  if (import.meta.url === argvUrl) {
4631
5216
  return true;
4632
5217
  }
4633
5218
  try {
4634
- const here = fs8.realpathSync(fileURLToPath8(import.meta.url));
4635
- const argv = fs8.realpathSync(path8.resolve(process.argv[1]));
5219
+ const here = fs10.realpathSync(fileURLToPath9(import.meta.url));
5220
+ const argv = fs10.realpathSync(path10.resolve(process.argv[1]));
4636
5221
  return here === argv;
4637
5222
  } catch {
4638
5223
  return false;
4639
5224
  }
4640
5225
  }
4641
- if (_isCliEntry8()) {
4642
- process.exit(main8());
5226
+ if (_isCliEntry9()) {
5227
+ process.exit(main9());
4643
5228
  }
4644
5229
 
4645
5230
  // src/scripts/report_carrier_divergence.ts
4646
- import * as fs9 from "node:fs";
5231
+ import * as fs11 from "node:fs";
4647
5232
  import * as os3 from "node:os";
4648
- import * as path9 from "node:path";
5233
+ import * as path11 from "node:path";
4649
5234
  import process2 from "node:process";
4650
- import { fileURLToPath as fileURLToPath9, pathToFileURL as pathToFileURL9 } from "node:url";
4651
- var _HERE = fileURLToPath9(import.meta.url);
4652
- var REPO_ROOT2 = path9.resolve(path9.dirname(_HERE), "..", "..");
4653
- var PROJECT_RULES = path9.join(".claude", "rules");
4654
- var PROJECTION_SOURCE = path9.join("dist", "agent-src", "rules");
4655
- var GLOBAL_RULES = path9.join(".claude", "rules");
5235
+ import { fileURLToPath as fileURLToPath10, pathToFileURL as pathToFileURL10 } from "node:url";
5236
+ var _HERE2 = fileURLToPath10(import.meta.url);
5237
+ var REPO_ROOT2 = path11.resolve(path11.dirname(_HERE2), "..", "..");
5238
+ var PROJECT_RULES = path11.join(".claude", "rules");
5239
+ var PROJECTION_SOURCE = path11.join("dist", "agent-src", "rules");
5240
+ var GLOBAL_RULES = path11.join(".claude", "rules");
4656
5241
  function _listRules(dir) {
4657
5242
  try {
4658
- return fs9.readdirSync(dir).filter((f) => f.endsWith(".md")).sort();
5243
+ return fs11.readdirSync(dir).filter((f) => f.endsWith(".md")).sort();
4659
5244
  } catch {
4660
5245
  return [];
4661
5246
  }
@@ -4663,7 +5248,7 @@ function _listRules(dir) {
4663
5248
  function _ruleType(file) {
4664
5249
  let text;
4665
5250
  try {
4666
- text = fs9.readFileSync(file, "utf-8");
5251
+ text = fs11.readFileSync(file, "utf-8");
4667
5252
  } catch {
4668
5253
  return "";
4669
5254
  }
@@ -4674,8 +5259,8 @@ function compareCarriers(projectDir, globalDir, sourceDir) {
4674
5259
  const out = {
4675
5260
  projectDir,
4676
5261
  globalDir,
4677
- globalPresent: fs9.existsSync(globalDir),
4678
- projectPresent: fs9.existsSync(projectDir),
5262
+ globalPresent: fs11.existsSync(globalDir),
5263
+ projectPresent: fs11.existsSync(projectDir),
4679
5264
  shared: 0,
4680
5265
  identical: [],
4681
5266
  provenanceOnly: [],
@@ -4698,7 +5283,7 @@ function compareCarriers(projectDir, globalDir, sourceDir) {
4698
5283
  }
4699
5284
  if (!inP && inG) {
4700
5285
  out.globalOnly.push(rule);
4701
- if (sourceDir !== void 0 && _ruleType(path9.join(sourceDir, rule)) === "manual") {
5286
+ if (sourceDir !== void 0 && _ruleType(path11.join(sourceDir, rule)) === "manual") {
4702
5287
  out.manualOnlyGlobal.push(rule);
4703
5288
  }
4704
5289
  continue;
@@ -4708,8 +5293,8 @@ function compareCarriers(projectDir, globalDir, sourceDir) {
4708
5293
  let projectCopy;
4709
5294
  let globalCopy;
4710
5295
  try {
4711
- projectCopy = fs9.readFileSync(path9.join(projectDir, rule));
4712
- globalCopy = fs9.readFileSync(path9.join(globalDir, rule));
5296
+ projectCopy = fs11.readFileSync(path11.join(projectDir, rule));
5297
+ globalCopy = fs11.readFileSync(path11.join(globalDir, rule));
4713
5298
  verdict = comparePair(projectCopy, globalCopy);
4714
5299
  } catch {
4715
5300
  out.shared -= 1;
@@ -4854,11 +5439,11 @@ function render2(d) {
4854
5439
  }
4855
5440
  return lines.join("\n");
4856
5441
  }
4857
- function main9(argv) {
5442
+ function main10(argv) {
4858
5443
  const args = argv ?? process2.argv.slice(2);
4859
- let projectDir = path9.join(REPO_ROOT2, PROJECT_RULES);
4860
- let globalDir = path9.join(os3.homedir(), GLOBAL_RULES);
4861
- let sourceDir = path9.join(REPO_ROOT2, PROJECTION_SOURCE);
5444
+ let projectDir = path11.join(REPO_ROOT2, PROJECT_RULES);
5445
+ let globalDir = path11.join(os3.homedir(), GLOBAL_RULES);
5446
+ let sourceDir = path11.join(REPO_ROOT2, PROJECTION_SOURCE);
4862
5447
  const value = (i) => {
4863
5448
  const v = args[i + 1];
4864
5449
  return v === void 0 || v.startsWith("-") ? null : v;
@@ -4872,7 +5457,7 @@ function main9(argv) {
4872
5457
  `);
4873
5458
  return 1;
4874
5459
  }
4875
- const resolved = path9.resolve(v);
5460
+ const resolved = path11.resolve(v);
4876
5461
  if (a === "--project") projectDir = resolved;
4877
5462
  else if (a === "--global") globalDir = resolved;
4878
5463
  else sourceDir = resolved;
@@ -4892,26 +5477,26 @@ function main9(argv) {
4892
5477
  `);
4893
5478
  return 0;
4894
5479
  }
4895
- function _isCliEntry9() {
5480
+ function _isCliEntry10() {
4896
5481
  if (process2.argv[1] === void 0) return false;
4897
- if (import.meta.url === pathToFileURL9(path9.resolve(process2.argv[1])).href) return true;
5482
+ if (import.meta.url === pathToFileURL10(path11.resolve(process2.argv[1])).href) return true;
4898
5483
  try {
4899
- return fs9.realpathSync(_HERE) === fs9.realpathSync(path9.resolve(process2.argv[1]));
5484
+ return fs11.realpathSync(_HERE2) === fs11.realpathSync(path11.resolve(process2.argv[1]));
4900
5485
  } catch {
4901
5486
  return false;
4902
5487
  }
4903
5488
  }
4904
- if (_isCliEntry9()) {
4905
- process2.exit(main9());
5489
+ if (_isCliEntry10()) {
5490
+ process2.exit(main10());
4906
5491
  }
4907
5492
 
4908
5493
  // src/scripts/report_skill_activation.ts
4909
- import * as fs10 from "node:fs";
5494
+ import * as fs12 from "node:fs";
4910
5495
  import * as os4 from "node:os";
4911
- import * as path10 from "node:path";
4912
- import { fileURLToPath as fileURLToPath10, pathToFileURL as pathToFileURL10 } from "node:url";
4913
- var _HERE2 = fileURLToPath10(import.meta.url);
4914
- var REPO_ROOT3 = path10.resolve(path10.dirname(_HERE2), "..", "..");
5496
+ import * as path12 from "node:path";
5497
+ import { fileURLToPath as fileURLToPath11, pathToFileURL as pathToFileURL11 } from "node:url";
5498
+ var _HERE3 = fileURLToPath11(import.meta.url);
5499
+ var REPO_ROOT3 = path12.resolve(path12.dirname(_HERE3), "..", "..");
4915
5500
  var SKILLS_ROOT = "src/skills";
4916
5501
  var TRIGGER_KEYS = ["triggers:", "trigger_description:", "file_pattern:", "path_prefix:"];
4917
5502
  var DETERMINISTIC_RE = /^\s*(?:[-*]\s*)?(?:\*\*)?(MUST|NEVER|ALWAYS)\b/m;
@@ -4922,25 +5507,25 @@ function censusSkills(root) {
4922
5507
  withTriggerCorpus: [],
4923
5508
  withDeterministicObligation: []
4924
5509
  };
4925
- if (!fs10.existsSync(root)) {
5510
+ if (!fs12.existsSync(root)) {
4926
5511
  return out;
4927
5512
  }
4928
- for (const entry of fs10.readdirSync(root, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
5513
+ for (const entry of fs12.readdirSync(root, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
4929
5514
  if (!entry.isDirectory()) {
4930
5515
  continue;
4931
5516
  }
4932
- const file = path10.join(root, entry.name, "SKILL.md");
4933
- if (!fs10.existsSync(file)) {
5517
+ const file = path12.join(root, entry.name, "SKILL.md");
5518
+ if (!fs12.existsSync(file)) {
4934
5519
  continue;
4935
5520
  }
4936
5521
  out.total += 1;
4937
- const text = fs10.readFileSync(file, "utf8");
5522
+ const text = fs12.readFileSync(file, "utf8");
4938
5523
  const fmEnd = text.startsWith("---") ? text.indexOf("\n---", 3) : -1;
4939
5524
  const fm = fmEnd === -1 ? "" : text.slice(0, fmEnd);
4940
5525
  if (TRIGGER_KEYS.some((k) => new RegExp(`^${k}`, "m").test(fm))) {
4941
5526
  out.withTriggerKey.push(entry.name);
4942
5527
  }
4943
- if (fs10.existsSync(path10.join(root, entry.name, "evals", "triggers.json"))) {
5528
+ if (fs12.existsSync(path12.join(root, entry.name, "evals", "triggers.json"))) {
4944
5529
  out.withTriggerCorpus.push(entry.name);
4945
5530
  }
4946
5531
  const body = fmEnd === -1 ? text : text.slice(fmEnd + 4);
@@ -4951,17 +5536,17 @@ function censusSkills(root) {
4951
5536
  return out;
4952
5537
  }
4953
5538
  function defaultStore2(cwd) {
4954
- return path10.join(os4.homedir(), ".claude", "projects", projectStoreSlug(cwd));
5539
+ return path12.join(os4.homedir(), ".claude", "projects", projectStoreSlug(cwd));
4955
5540
  }
4956
5541
  function measureUsage(store, limit) {
4957
5542
  const rep = { store, sessions: 0, assistantTurns: 0, invocations: 0, bySkill: {} };
4958
- if (!fs10.existsSync(store)) {
5543
+ if (!fs12.existsSync(store)) {
4959
5544
  return rep;
4960
5545
  }
4961
- const files = fs10.readdirSync(store).filter((f) => f.endsWith(".jsonl")).map((f) => path10.join(store, f)).sort((a, b) => fs10.statSync(b).mtimeMs - fs10.statSync(a).mtimeMs).slice(0, limit);
5546
+ const files = fs12.readdirSync(store).filter((f) => f.endsWith(".jsonl")).map((f) => path12.join(store, f)).sort((a, b) => fs12.statSync(b).mtimeMs - fs12.statSync(a).mtimeMs).slice(0, limit);
4962
5547
  rep.sessions = files.length;
4963
5548
  for (const file of files) {
4964
- for (const line of fs10.readFileSync(file, "utf8").split("\n")) {
5549
+ for (const line of fs12.readFileSync(file, "utf8").split("\n")) {
4965
5550
  if (!line.trim()) {
4966
5551
  continue;
4967
5552
  }
@@ -5034,15 +5619,15 @@ function buildRecord(census, usage, today) {
5034
5619
  assistant_turns: usage.reduce((a, u) => a + u.assistantTurns, 0),
5035
5620
  invocations: usage.reduce((a, u) => a + u.invocations, 0),
5036
5621
  distinct_skills_invoked: distinct.size,
5037
- stores: usage.map((u) => path10.basename(u.store))
5622
+ stores: usage.map((u) => path12.basename(u.store))
5038
5623
  };
5039
5624
  }
5040
5625
  function readRecord(repoRoot) {
5041
- const file = path10.join(repoRoot, RECORD_PATH);
5042
- if (!fs10.existsSync(file)) {
5626
+ const file = path12.join(repoRoot, RECORD_PATH);
5627
+ if (!fs12.existsSync(file)) {
5043
5628
  return null;
5044
5629
  }
5045
- return JSON.parse(fs10.readFileSync(file, "utf8"));
5630
+ return JSON.parse(fs12.readFileSync(file, "utf8"));
5046
5631
  }
5047
5632
  function render3(census, usage, published = null) {
5048
5633
  const lines = [];
@@ -5077,7 +5662,7 @@ function render3(census, usage, published = null) {
5077
5662
  }
5078
5663
  totalInv += u.invocations;
5079
5664
  lines.push(
5080
- ` ${path10.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)}`
5665
+ ` ${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)}`
5081
5666
  );
5082
5667
  }
5083
5668
  lines.push("");
@@ -5147,8 +5732,8 @@ function render3(census, usage, published = null) {
5147
5732
  lines.push(" catalogue once per session, then count descriptions against bare names.");
5148
5733
  return lines.join("\n");
5149
5734
  }
5150
- var USAGE = "usage: report_skill_activation [--root DIR] [--limit N] [--store PATH]... [--emit] [--allow-empty-store]\n";
5151
- function main10(argv) {
5735
+ var USAGE2 = "usage: report_skill_activation [--root DIR] [--limit N] [--store PATH]... [--emit] [--allow-empty-store]\n";
5736
+ function main11(argv) {
5152
5737
  let limit = 30;
5153
5738
  let emit = false;
5154
5739
  let allowEmpty = false;
@@ -5170,7 +5755,7 @@ function main10(argv) {
5170
5755
  } else if (a === "--allow-empty-store") {
5171
5756
  allowEmpty = true;
5172
5757
  } else if (a === "--help" || a === "-h") {
5173
- process.stdout.write(USAGE);
5758
+ process.stdout.write(USAGE2);
5174
5759
  return 0;
5175
5760
  }
5176
5761
  }
@@ -5181,7 +5766,7 @@ function main10(argv) {
5181
5766
  if (stores.length === 0) {
5182
5767
  stores.push(defaultStore2(REPO_ROOT3));
5183
5768
  }
5184
- const census = censusSkills(path10.join(root, SKILLS_ROOT));
5769
+ const census = censusSkills(path12.join(root, SKILLS_ROOT));
5185
5770
  const usage = stores.map((s) => measureUsage(s, limit));
5186
5771
  process.stdout.write(`${render3(census, usage, readRecord(root))}
5187
5772
  `);
@@ -5202,27 +5787,27 @@ function main10(argv) {
5202
5787
  return 1;
5203
5788
  }
5204
5789
  const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
5205
- const file = path10.join(root, RECORD_PATH);
5206
- fs10.mkdirSync(path10.dirname(file), { recursive: true });
5207
- fs10.writeFileSync(file, `${JSON.stringify(buildRecord(census, usage, today), null, 2)}
5790
+ const file = path12.join(root, RECORD_PATH);
5791
+ fs12.mkdirSync(path12.dirname(file), { recursive: true });
5792
+ fs12.writeFileSync(file, `${JSON.stringify(buildRecord(census, usage, today), null, 2)}
5208
5793
  `);
5209
5794
  process.stdout.write(`
5210
5795
  wrote ${RECORD_PATH} (measured ${today})
5211
5796
  `);
5212
5797
  return 0;
5213
5798
  }
5214
- if (process.argv[1] !== void 0 && import.meta.url === pathToFileURL10(path10.resolve(process.argv[1])).href) {
5215
- process.exit(main10(process.argv.slice(2)));
5799
+ if (process.argv[1] !== void 0 && import.meta.url === pathToFileURL11(path12.resolve(process.argv[1])).href) {
5800
+ process.exit(main11(process.argv.slice(2)));
5216
5801
  }
5217
5802
 
5218
5803
  // src/scripts/report_skill_obligation_violations.ts
5219
- import * as fs11 from "node:fs";
5804
+ import * as fs13 from "node:fs";
5220
5805
  import * as os5 from "node:os";
5221
- import * as path11 from "node:path";
5806
+ import * as path13 from "node:path";
5222
5807
  import process3 from "node:process";
5223
- import { fileURLToPath as fileURLToPath11, pathToFileURL as pathToFileURL11 } from "node:url";
5224
- var _HERE3 = fileURLToPath11(import.meta.url);
5225
- var REPO_ROOT4 = path11.resolve(path11.dirname(_HERE3), "..", "..");
5808
+ import { fileURLToPath as fileURLToPath12, pathToFileURL as pathToFileURL12 } from "node:url";
5809
+ var _HERE4 = fileURLToPath12(import.meta.url);
5810
+ var REPO_ROOT4 = path13.resolve(path13.dirname(_HERE4), "..", "..");
5226
5811
  var OBLIGATION_LINE_RE = new RegExp(`${DETERMINISTIC_RE.source}.*`, "gm");
5227
5812
  var PATH_RE = /`([A-Za-z0-9_./-]*\/[A-Za-z0-9_.-]+\.[a-z]{2,6})`/g;
5228
5813
  var CMD_RE = /`([a-z][a-z0-9-]*(?: [a-z][a-z0-9:._-]*){1,3})`/g;
@@ -5260,7 +5845,7 @@ function _artefacts(line) {
5260
5845
  return out;
5261
5846
  }
5262
5847
  function extractObligations(repoRoot) {
5263
- const skillsRoot = path11.join(repoRoot, SKILLS_ROOT);
5848
+ const skillsRoot = path13.join(repoRoot, SKILLS_ROOT);
5264
5849
  const census = censusSkills(skillsRoot);
5265
5850
  const out = {
5266
5851
  skills: census.withDeterministicObligation,
@@ -5274,7 +5859,7 @@ function extractObligations(repoRoot) {
5274
5859
  for (const skill of census.withDeterministicObligation) {
5275
5860
  let text;
5276
5861
  try {
5277
- text = fs11.readFileSync(path11.join(skillsRoot, skill, "SKILL.md"), "utf-8");
5862
+ text = fs13.readFileSync(path13.join(skillsRoot, skill, "SKILL.md"), "utf-8");
5278
5863
  } catch {
5279
5864
  continue;
5280
5865
  }
@@ -5390,7 +5975,7 @@ function scanSessionForViolations(session, lines, forbidden, parsed) {
5390
5975
  return flags;
5391
5976
  }
5392
5977
  function defaultStore3(cwd) {
5393
- return path11.join(os5.homedir(), ".claude", "projects", projectStoreSlug(cwd));
5978
+ return path13.join(os5.homedir(), ".claude", "projects", projectStoreSlug(cwd));
5394
5979
  }
5395
5980
  function scanStore2(repoRoot, store, limit) {
5396
5981
  const census = extractObligations(repoRoot);
@@ -5403,14 +5988,14 @@ function scanStore2(repoRoot, store, limit) {
5403
5988
  };
5404
5989
  let files;
5405
5990
  try {
5406
- files = fs11.readdirSync(store).filter((f) => f.endsWith(".jsonl")).map((f) => ({ p: path11.join(store, f), m: fs11.statSync(path11.join(store, f)).mtimeMs })).sort((a, b) => b.m - a.m).slice(0, limit).map((x) => x.p);
5991
+ files = fs13.readdirSync(store).filter((f) => f.endsWith(".jsonl")).map((f) => ({ p: path13.join(store, f), m: fs13.statSync(path13.join(store, f)).mtimeMs })).sort((a, b) => b.m - a.m).slice(0, limit).map((x) => x.p);
5407
5992
  } catch {
5408
5993
  return report;
5409
5994
  }
5410
5995
  report.sessions = files.length;
5411
5996
  for (const file of files) {
5412
- const lines = fs11.readFileSync(file, "utf-8").split("\n");
5413
- const id = path11.basename(file).replace(/\.jsonl$/, "").slice(0, 8);
5997
+ const lines = fs13.readFileSync(file, "utf-8").split("\n");
5998
+ const id = path13.basename(file).replace(/\.jsonl$/, "").slice(0, 8);
5414
5999
  const entries = _parseSession(lines);
5415
6000
  if (loadedSkillsFrom(entries).size > 0) report.sessionsWithASkill += 1;
5416
6001
  report.flags.push(...scanSessionForViolations(id, lines, census.forbidden, entries));
@@ -5480,7 +6065,7 @@ function render4(r) {
5480
6065
  lines.push(" ships as detection-only, and this one says so.");
5481
6066
  return lines.join("\n");
5482
6067
  }
5483
- function main11(argv) {
6068
+ function main12(argv) {
5484
6069
  const args = argv ?? process3.argv.slice(2);
5485
6070
  let limit = 30;
5486
6071
  let json = false;
@@ -5533,35 +6118,35 @@ function main11(argv) {
5533
6118
  }
5534
6119
  return 0;
5535
6120
  }
5536
- function _isCliEntry10() {
6121
+ function _isCliEntry11() {
5537
6122
  if (process3.argv[1] === void 0) return false;
5538
- if (import.meta.url === pathToFileURL11(path11.resolve(process3.argv[1])).href) return true;
6123
+ if (import.meta.url === pathToFileURL12(path13.resolve(process3.argv[1])).href) return true;
5539
6124
  try {
5540
- return fs11.realpathSync(_HERE3) === fs11.realpathSync(path11.resolve(process3.argv[1]));
6125
+ return fs13.realpathSync(_HERE4) === fs13.realpathSync(path13.resolve(process3.argv[1]));
5541
6126
  } catch {
5542
6127
  return false;
5543
6128
  }
5544
6129
  }
5545
- if (_isCliEntry10()) {
5546
- process3.exit(main11());
6130
+ if (_isCliEntry11()) {
6131
+ process3.exit(main12());
5547
6132
  }
5548
6133
 
5549
6134
  // src/scripts/report_conformance_funnel.ts
5550
- var _HERE4 = fileURLToPath12(import.meta.url);
5551
- var REPO_ROOT5 = path12.resolve(path12.dirname(_HERE4), "..", "..");
6135
+ var _HERE5 = fileURLToPath13(import.meta.url);
6136
+ var REPO_ROOT5 = path14.resolve(path14.dirname(_HERE5), "..", "..");
5552
6137
  function buildFunnel(opts = {}) {
5553
6138
  const repoRoot = opts.repoRoot ?? REPO_ROOT5;
5554
- const projectRulesDir = opts.projectRulesDir ?? path12.join(repoRoot, PROJECT_RULES);
5555
- const globalRulesDir = opts.globalRulesDir ?? path12.join(os6.homedir(), GLOBAL_RULES);
5556
- const sourceDir = opts.sourceDir ?? path12.join(repoRoot, PROJECTION_SOURCE);
6139
+ const projectRulesDir = opts.projectRulesDir ?? path14.join(repoRoot, PROJECT_RULES);
6140
+ const globalRulesDir = opts.globalRulesDir ?? path14.join(os6.homedir(), GLOBAL_RULES);
6141
+ const sourceDir = opts.sourceDir ?? path14.join(repoRoot, PROJECTION_SOURCE);
5557
6142
  const store = opts.store ?? defaultStore(repoRoot);
5558
6143
  const limit = opts.limit ?? 30;
5559
6144
  return {
5560
6145
  delivered: measureDelivered(projectRulesDir, globalRulesDir),
5561
6146
  divergence: compareCarriers(projectRulesDir, globalRulesDir, sourceDir),
5562
- skills: censusSkills(path12.join(repoRoot, SKILLS_ROOT)),
6147
+ skills: censusSkills(path14.join(repoRoot, SKILLS_ROOT)),
5563
6148
  usage: measureUsage(store, limit),
5564
- storePresent: fs12.existsSync(store),
6149
+ storePresent: fs14.existsSync(store),
5565
6150
  sk2: scanStore2(repoRoot, store, limit)
5566
6151
  };
5567
6152
  }
@@ -5686,7 +6271,7 @@ function render5(r) {
5686
6271
  lines.push("workflow without a measured false-positive rate first (locked policy).");
5687
6272
  return lines.join("\n");
5688
6273
  }
5689
- function main12(argv) {
6274
+ function main13(argv) {
5690
6275
  const args = argv ?? process4.argv.slice(2);
5691
6276
  const opts = {};
5692
6277
  const value = (i) => {
@@ -5702,7 +6287,7 @@ function main12(argv) {
5702
6287
  `);
5703
6288
  return 1;
5704
6289
  }
5705
- const resolved = path12.resolve(v);
6290
+ const resolved = path14.resolve(v);
5706
6291
  if (a === "--store") opts.store = resolved;
5707
6292
  else if (a === "--project") opts.projectRulesDir = resolved;
5708
6293
  else if (a === "--global") opts.globalRulesDir = resolved;
@@ -5732,21 +6317,21 @@ function main12(argv) {
5732
6317
  `);
5733
6318
  return 0;
5734
6319
  }
5735
- function _isCliEntry11() {
6320
+ function _isCliEntry12() {
5736
6321
  if (process4.argv[1] === void 0) return false;
5737
- if (import.meta.url === pathToFileURL12(path12.resolve(process4.argv[1])).href) return true;
6322
+ if (import.meta.url === pathToFileURL13(path14.resolve(process4.argv[1])).href) return true;
5738
6323
  try {
5739
- return fs12.realpathSync(_HERE4) === fs12.realpathSync(path12.resolve(process4.argv[1]));
6324
+ return fs14.realpathSync(_HERE5) === fs14.realpathSync(path14.resolve(process4.argv[1]));
5740
6325
  } catch {
5741
6326
  return false;
5742
6327
  }
5743
6328
  }
5744
- if (_isCliEntry11()) {
5745
- process4.exit(main12());
6329
+ if (_isCliEntry12()) {
6330
+ process4.exit(main13());
5746
6331
  }
5747
6332
 
5748
6333
  // src/scripts/_cli/cmd_conformance.ts
5749
- var _HERE5 = fileURLToPath13(import.meta.url);
6334
+ var _HERE6 = fileURLToPath14(import.meta.url);
5750
6335
  var PACKAGE_ROOT = resolvePackageRoot(import.meta.url);
5751
6336
  var CONFORMANCE_CHECK_IDS = [
5752
6337
  "txlog-clean",
@@ -5756,6 +6341,10 @@ var CONFORMANCE_CHECK_IDS = [
5756
6341
  "host-manifest"
5757
6342
  ];
5758
6343
  var THIN_STUB_MARKER = "Routed rule \u2014 load the body on trigger-match";
6344
+ var CONFORMANCE_STATUS_SYMBOLS = {
6345
+ ...STATUS_SYMBOLS,
6346
+ unknown: "\u2754"
6347
+ };
5759
6348
  function print(s = "") {
5760
6349
  process5.stdout.write(`${s}
5761
6350
  `);
@@ -5769,30 +6358,33 @@ function conformanceLogPath() {
5769
6358
  if (override && override.trim().length > 0) {
5770
6359
  return override;
5771
6360
  }
5772
- return path13.join(os7.homedir(), ".event4u", "agent-config", "conformance-log.jsonl");
6361
+ return path15.join(os7.homedir(), ".event4u", "agent-config", "conformance-log.jsonl");
5773
6362
  }
5774
6363
  function installLogPath() {
5775
6364
  const override = process5.env["AGENT_CONFIG_INSTALL_LOG"];
5776
6365
  if (override && override.trim().length > 0) {
5777
6366
  return override;
5778
6367
  }
5779
- return path13.join(os7.homedir(), ".event4u", "agent-config", "install-log.jsonl");
6368
+ return path15.join(os7.homedir(), ".event4u", "agent-config", "install-log.jsonl");
5780
6369
  }
5781
- function _check_txlog_clean(logPath = installLogPath()) {
5782
- if (!fs13.existsSync(logPath)) {
5783
- return {
5784
- id: "txlog-clean",
5785
- status: "ok",
5786
- message: "no install transaction log \u2014 nothing to recover",
5787
- remedy: ""
5788
- };
5789
- }
5790
- const entries = readRecentEntries(logPath);
6370
+ function _installLogExpected(projectRoot) {
6371
+ return fs15.existsSync(manifest_path(projectRoot));
6372
+ }
6373
+ function _check_txlog_clean(logPath = installLogPath(), projectRoot = null) {
6374
+ const entries = fs15.existsSync(logPath) ? readRecentEntries(logPath) : [];
5791
6375
  if (entries.length === 0) {
6376
+ if (projectRoot !== null && _installLogExpected(projectRoot)) {
6377
+ return {
6378
+ id: "txlog-clean",
6379
+ status: "unknown",
6380
+ message: "install manifest present, no usable install transaction log \u2014 nothing recorded this install, so the last run cannot be confirmed complete",
6381
+ remedy: "no install path writes this log today; run `agent-config doctor` for the drift answer this check cannot give"
6382
+ };
6383
+ }
5792
6384
  return {
5793
6385
  id: "txlog-clean",
5794
6386
  status: "ok",
5795
- message: "install transaction log is empty",
6387
+ message: "no usable install transaction log and no install manifest \u2014 nothing was installed here",
5796
6388
  remedy: ""
5797
6389
  };
5798
6390
  }
@@ -5802,7 +6394,7 @@ function _check_txlog_clean(logPath = installLogPath()) {
5802
6394
  id: "txlog-clean",
5803
6395
  status: "fail",
5804
6396
  message: `install log tail is an abandoned run (abort at ${last.ts}${last.note ? `: ${last.note}` : ""})`,
5805
- remedy: "re-run `agent-config init` (recovery reverse-applies the aborted tail)"
6397
+ remedy: "re-run `agent-config init` \u2014 it re-applies the plan over the partial tail; the aborted run's writes stay on disk and are replaced only where the plan covers them"
5806
6398
  };
5807
6399
  }
5808
6400
  return {
@@ -5813,11 +6405,11 @@ function _check_txlog_clean(logPath = installLogPath()) {
5813
6405
  };
5814
6406
  }
5815
6407
  function routeTargetPaths(target) {
5816
- return routeTargetPathsPosix(target).map((rel) => path13.join(...rel.split("/")));
6408
+ return routeTargetPathsPosix(target).map((rel) => path15.join(...rel.split("/")));
5817
6409
  }
5818
6410
  function _check_router_pointers(packageRoot = PACKAGE_ROOT) {
5819
- const routerPath = path13.join(packageRoot, "dist", "router.json");
5820
- if (!fs13.existsSync(routerPath)) {
6411
+ const routerPath = path15.join(packageRoot, "dist", "router.json");
6412
+ if (!fs15.existsSync(routerPath)) {
5821
6413
  return {
5822
6414
  id: "router-pointers",
5823
6415
  status: "fail",
@@ -5827,7 +6419,7 @@ function _check_router_pointers(packageRoot = PACKAGE_ROOT) {
5827
6419
  }
5828
6420
  let router;
5829
6421
  try {
5830
- router = JSON.parse(fs13.readFileSync(routerPath, "utf8"));
6422
+ router = JSON.parse(fs15.readFileSync(routerPath, "utf8"));
5831
6423
  } catch (exc) {
5832
6424
  return {
5833
6425
  id: "router-pointers",
@@ -5836,13 +6428,13 @@ function _check_router_pointers(packageRoot = PACKAGE_ROOT) {
5836
6428
  remedy: "reinstall the package \u2014 dist/router.json is corrupt"
5837
6429
  };
5838
6430
  }
5839
- const rulesDir = path13.join(packageRoot, "dist", "agent-src", "rules");
6431
+ const rulesDir = path15.join(packageRoot, "dist", "agent-src", "rules");
5840
6432
  const broken = [];
5841
6433
  let ids = 0;
5842
6434
  let targets = 0;
5843
6435
  for (const kernelId of router["kernel"] ?? []) {
5844
6436
  ids += 1;
5845
- if (!fs13.existsSync(path13.join(rulesDir, `${kernelId}.md`))) {
6437
+ if (!fs15.existsSync(path15.join(rulesDir, `${kernelId}.md`))) {
5846
6438
  broken.push(`kernel:${kernelId} \u2192 rules/${kernelId}.md missing`);
5847
6439
  }
5848
6440
  }
@@ -5850,7 +6442,7 @@ function _check_router_pointers(packageRoot = PACKAGE_ROOT) {
5850
6442
  for (const entry of router[tier] ?? []) {
5851
6443
  const ruleId = String(entry["id"] ?? "");
5852
6444
  ids += 1;
5853
- if (!fs13.existsSync(path13.join(rulesDir, `${ruleId}.md`))) {
6445
+ if (!fs15.existsSync(path15.join(rulesDir, `${ruleId}.md`))) {
5854
6446
  broken.push(`${tier}:${ruleId} \u2192 rules/${ruleId}.md missing`);
5855
6447
  }
5856
6448
  for (const target of entry["routes_to"] ?? []) {
@@ -5860,7 +6452,7 @@ function _check_router_pointers(packageRoot = PACKAGE_ROOT) {
5860
6452
  broken.push(`${ruleId} \u2192 unparseable routes_to ${JSON.stringify(target)}`);
5861
6453
  continue;
5862
6454
  }
5863
- if (!candidates.some((rel) => fs13.existsSync(path13.join(packageRoot, rel)))) {
6455
+ if (!candidates.some((rel) => fs15.existsSync(path15.join(packageRoot, rel)))) {
5864
6456
  broken.push(`${ruleId} \u2192 ${target} (${candidates[0]} missing)`);
5865
6457
  }
5866
6458
  }
@@ -5892,9 +6484,9 @@ function detectSmokePlatform(projectRoot) {
5892
6484
  return "claude";
5893
6485
  }
5894
6486
  function dispatcherRunner(packageRoot) {
5895
- const localTsx = path13.join(packageRoot, "node_modules", ".bin", "tsx");
5896
- const script = path13.join(packageRoot, "src", "scripts", "hooks", "dispatch_hook.ts");
5897
- if (fs13.existsSync(localTsx)) {
6487
+ const localTsx = path15.join(packageRoot, "node_modules", ".bin", "tsx");
6488
+ const script = path15.join(packageRoot, "src", "scripts", "hooks", "dispatch_hook.ts");
6489
+ if (fs15.existsSync(localTsx)) {
5898
6490
  return [localTsx, script];
5899
6491
  }
5900
6492
  return ["npx", "tsx", script];
@@ -5911,7 +6503,7 @@ function _check_hook_dispatcher(projectRoot, packageRoot = PACKAGE_ROOT, opts =
5911
6503
  ...event === "stop" ? { stop_reason: "conformance-smoke" } : { source: "startup" }
5912
6504
  });
5913
6505
  const argv = [...runner, "--platform", platform, "--event", event];
5914
- const proc = spawnSync2(argv[0], argv.slice(1), {
6506
+ const proc = spawnSync4(argv[0], argv.slice(1), {
5915
6507
  input: payload,
5916
6508
  cwd: projectRoot,
5917
6509
  encoding: "utf8",
@@ -5944,12 +6536,12 @@ function _check_hook_dispatcher(projectRoot, packageRoot = PACKAGE_ROOT, opts =
5944
6536
  };
5945
6537
  }
5946
6538
  function readSettingsMode(projectRoot) {
5947
- const settingsPath = path13.join(projectRoot, ".agent-settings.yml");
5948
- if (!fs13.existsSync(settingsPath)) {
6539
+ const settingsPath = path15.join(projectRoot, ".agent-settings.yml");
6540
+ if (!fs15.existsSync(settingsPath)) {
5949
6541
  return "eager-all";
5950
6542
  }
5951
6543
  try {
5952
- const parsed = YAML.parse(fs13.readFileSync(settingsPath, "utf8"));
6544
+ const parsed = YAML.parse(fs15.readFileSync(settingsPath, "utf8"));
5953
6545
  const lean = parsed?.["lean_projection"] ?? null;
5954
6546
  const mode = lean?.["mode"];
5955
6547
  return typeof mode === "string" && mode.length > 0 ? mode : "eager-all";
@@ -5960,7 +6552,7 @@ function readSettingsMode(projectRoot) {
5960
6552
  function kernelIdsFromRouter(packageRoot) {
5961
6553
  try {
5962
6554
  const router = JSON.parse(
5963
- fs13.readFileSync(path13.join(packageRoot, "dist", "router.json"), "utf8")
6555
+ fs15.readFileSync(path15.join(packageRoot, "dist", "router.json"), "utf8")
5964
6556
  );
5965
6557
  return new Set((router["kernel"] ?? []).map(String));
5966
6558
  } catch {
@@ -5977,8 +6569,8 @@ function _check_lean_projection(projectRoot, packageRoot = PACKAGE_ROOT, project
5977
6569
  remedy: "set lean_projection.mode to 'eager-all' or 'thin' in .agent-settings.yml"
5978
6570
  };
5979
6571
  }
5980
- const rulesDir = projectedRulesDir ?? path13.join(projectRoot, ".augment", "rules");
5981
- if (!fs13.existsSync(rulesDir)) {
6572
+ const rulesDir = projectedRulesDir ?? path15.join(projectRoot, ".augment", "rules");
6573
+ if (!fs15.existsSync(rulesDir)) {
5982
6574
  return {
5983
6575
  id: "lean-projection",
5984
6576
  status: "skipped",
@@ -5987,7 +6579,7 @@ function _check_lean_projection(projectRoot, packageRoot = PACKAGE_ROOT, project
5987
6579
  };
5988
6580
  }
5989
6581
  const kernel = kernelIdsFromRouter(packageRoot);
5990
- const files = fs13.readdirSync(rulesDir).filter((f) => f.endsWith(".md") && f !== "INDEX.md").sort();
6582
+ const files = fs15.readdirSync(rulesDir).filter((f) => f.endsWith(".md") && f !== "INDEX.md").sort();
5991
6583
  const nonKernel = files.filter((f) => !kernel.has(f.replace(/\.md$/, "")));
5992
6584
  if (nonKernel.length === 0) {
5993
6585
  return {
@@ -6001,7 +6593,7 @@ function _check_lean_projection(projectRoot, packageRoot = PACKAGE_ROOT, project
6001
6593
  for (const f of nonKernel) {
6002
6594
  let text = "";
6003
6595
  try {
6004
- text = fs13.readFileSync(path13.join(rulesDir, f), "utf8");
6596
+ text = fs15.readFileSync(path15.join(rulesDir, f), "utf8");
6005
6597
  } catch {
6006
6598
  continue;
6007
6599
  }
@@ -6032,8 +6624,8 @@ function _check_lean_projection(projectRoot, packageRoot = PACKAGE_ROOT, project
6032
6624
  function _check_host_manifest(projectRoot) {
6033
6625
  const detected = Object.entries(detectToolPresence(projectRoot)).filter(([, v]) => v === true).map(([k]) => k);
6034
6626
  const detectedNote = detected.length > 0 ? `detected surfaces: ${detected.join(", ")}` : "no surfaces detected";
6035
- const settingsPath = path13.join(projectRoot, ".agent-settings.yml");
6036
- if (!fs13.existsSync(settingsPath)) {
6627
+ const settingsPath = path15.join(projectRoot, ".agent-settings.yml");
6628
+ if (!fs15.existsSync(settingsPath)) {
6037
6629
  return {
6038
6630
  id: "host-manifest",
6039
6631
  status: "ok",
@@ -6043,7 +6635,7 @@ function _check_host_manifest(projectRoot) {
6043
6635
  }
6044
6636
  let parsed = null;
6045
6637
  try {
6046
- parsed = YAML.parse(fs13.readFileSync(settingsPath, "utf8"));
6638
+ parsed = YAML.parse(fs15.readFileSync(settingsPath, "utf8"));
6047
6639
  } catch (exc) {
6048
6640
  return {
6049
6641
  id: "host-manifest",
@@ -6073,7 +6665,7 @@ function runConformanceChecks(opts = {}) {
6073
6665
  const projectRoot = opts.projectRoot ?? process5.cwd();
6074
6666
  const packageRoot = opts.packageRoot ?? PACKAGE_ROOT;
6075
6667
  const checks = [];
6076
- checks.push(_check_txlog_clean());
6668
+ checks.push(_check_txlog_clean(installLogPath(), projectRoot));
6077
6669
  checks.push(_check_router_pointers(packageRoot));
6078
6670
  if (opts.skipDispatcher === true) {
6079
6671
  checks.push({
@@ -6104,14 +6696,14 @@ function appendConformanceReport(checks, projectRoot, logPath = conformanceLogPa
6104
6696
  } catch {
6105
6697
  }
6106
6698
  }
6107
- var USAGE2 = "usage: agent-config conformance [-h] [--project PROJECT] [--json]\n [--skip-dispatcher] [--funnel]\n";
6699
+ var USAGE3 = "usage: agent-config conformance [-h] [--project PROJECT] [--json]\n [--skip-dispatcher] [--funnel]\n";
6108
6700
  function _parse(argv) {
6109
6701
  const opts = { project: null, json: false, skip_dispatcher: false, funnel: false };
6110
6702
  let i = 0;
6111
6703
  while (i < argv.length) {
6112
6704
  const a = argv[i];
6113
6705
  if (a === "-h" || a === "--help") {
6114
- process5.stdout.write(USAGE2);
6706
+ process5.stdout.write(USAGE3);
6115
6707
  throw new ArgparseExit(0);
6116
6708
  }
6117
6709
  if (a === "--json") {
@@ -6125,7 +6717,7 @@ function _parse(argv) {
6125
6717
  opts.project = a.slice(a.indexOf("=") + 1);
6126
6718
  } else {
6127
6719
  if (i + 1 >= argv.length) {
6128
- process5.stderr.write(USAGE2);
6720
+ process5.stderr.write(USAGE3);
6129
6721
  process5.stderr.write("agent-config conformance: error: --project expects a value\n");
6130
6722
  throw new ArgparseExit(2);
6131
6723
  }
@@ -6133,7 +6725,7 @@ function _parse(argv) {
6133
6725
  i += 1;
6134
6726
  }
6135
6727
  } else {
6136
- process5.stderr.write(USAGE2);
6728
+ process5.stderr.write(USAGE3);
6137
6729
  process5.stderr.write(`agent-config conformance: error: unrecognized argument ${a}
6138
6730
  `);
6139
6731
  throw new ArgparseExit(2);
@@ -6142,7 +6734,7 @@ function _parse(argv) {
6142
6734
  }
6143
6735
  return opts;
6144
6736
  }
6145
- function main13(argv = null) {
6737
+ function main14(argv = null) {
6146
6738
  const opts = _parse(argv !== null ? Array.from(argv) : process5.argv.slice(2));
6147
6739
  if (opts.funnel) {
6148
6740
  print(render5(buildFunnel()));
@@ -6197,7 +6789,7 @@ function main13(argv = null) {
6197
6789
  print(` \u{1F4CD} project_root: ${project_root}`);
6198
6790
  print("conformance:");
6199
6791
  for (const c of allChecks) {
6200
- const sym = STATUS_SYMBOLS[c["status"]] ?? "?";
6792
+ const sym = CONFORMANCE_STATUS_SYMBOLS[c["status"]] ?? "?";
6201
6793
  print(` ${sym} ${c["id"]}: ${c["message"]}`);
6202
6794
  if (c["status"] !== "ok" && c["remedy"]) {
6203
6795
  print(` fix: ${c["remedy"]}`);
@@ -6213,25 +6805,25 @@ function main13(argv = null) {
6213
6805
  }
6214
6806
  return failed ? 1 : 0;
6215
6807
  }
6216
- function _isCliEntry12() {
6808
+ function _isCliEntry13() {
6217
6809
  if (process5.argv[1] === void 0) {
6218
6810
  return false;
6219
6811
  }
6220
- const argvUrl = pathToFileURL13(path13.resolve(process5.argv[1])).href;
6812
+ const argvUrl = pathToFileURL14(path15.resolve(process5.argv[1])).href;
6221
6813
  if (import.meta.url === argvUrl) {
6222
6814
  return true;
6223
6815
  }
6224
6816
  try {
6225
- const here = fs13.realpathSync(fileURLToPath13(import.meta.url));
6226
- const argv = fs13.realpathSync(path13.resolve(process5.argv[1]));
6817
+ const here = fs15.realpathSync(fileURLToPath14(import.meta.url));
6818
+ const argv = fs15.realpathSync(path15.resolve(process5.argv[1]));
6227
6819
  return here === argv;
6228
6820
  } catch {
6229
6821
  return false;
6230
6822
  }
6231
6823
  }
6232
- if (_isCliEntry12() || process5.argv[1] === _HERE5) {
6824
+ if (_isCliEntry13() || process5.argv[1] === _HERE6) {
6233
6825
  try {
6234
- process5.exitCode = main13(process5.argv.slice(2));
6826
+ process5.exitCode = main14(process5.argv.slice(2));
6235
6827
  } catch (e) {
6236
6828
  if (e instanceof ArgparseExit) {
6237
6829
  process5.exitCode = e.code;
@@ -6249,12 +6841,13 @@ export {
6249
6841
  _check_lean_projection,
6250
6842
  _check_router_pointers,
6251
6843
  _check_txlog_clean,
6844
+ _installLogExpected,
6252
6845
  _parse,
6253
6846
  appendConformanceReport,
6254
6847
  conformanceLogPath,
6255
6848
  detectSmokePlatform,
6256
6849
  installLogPath,
6257
- main13 as main,
6850
+ main14 as main,
6258
6851
  routeTargetPaths,
6259
6852
  runConformanceChecks
6260
6853
  };