@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
@@ -170,6 +170,50 @@ var init_settingsCarveOut = __esm({
170
170
  }
171
171
  });
172
172
 
173
+ // src/scripts/_lib/settings_renamed_keys.ts
174
+ function _read(tree, dotted) {
175
+ let cur = tree;
176
+ for (const part of dotted.split(".")) {
177
+ if (cur === null || typeof cur !== "object" || Array.isArray(cur)) return void 0;
178
+ cur = cur[part];
179
+ }
180
+ return cur;
181
+ }
182
+ function _write(tree, dotted, value) {
183
+ const parts = dotted.split(".");
184
+ let cur = tree;
185
+ for (const part of parts.slice(0, -1)) {
186
+ const next = cur[part];
187
+ if (next === null || typeof next !== "object" || Array.isArray(next)) cur[part] = {};
188
+ cur = cur[part];
189
+ }
190
+ cur[parts[parts.length - 1]] = value;
191
+ }
192
+ function applyRenamedKeys(layer) {
193
+ for (const [oldKey, newKey] of RENAMED_KEYS) {
194
+ const oldValue = _read(layer, oldKey);
195
+ if (oldValue === void 0) continue;
196
+ if (_read(layer, newKey) === void 0) _write(layer, newKey, oldValue);
197
+ if (_warned.has(oldKey)) continue;
198
+ _warned.add(oldKey);
199
+ process.stderr.write(
200
+ `\u26A0\uFE0F settings: \`${oldKey}\` was renamed to \`${newKey}\`. The old key still works for one minor; rename it in your .agent-settings.yml.
201
+ `
202
+ );
203
+ }
204
+ return layer;
205
+ }
206
+ var RENAMED_KEYS, _warned;
207
+ var init_settings_renamed_keys = __esm({
208
+ "src/scripts/_lib/settings_renamed_keys.ts"() {
209
+ "use strict";
210
+ RENAMED_KEYS = /* @__PURE__ */ new Map([
211
+ ["planning.challenge_on_create", "planning.closure_pass"]
212
+ ]);
213
+ _warned = /* @__PURE__ */ new Set();
214
+ }
215
+ });
216
+
173
217
  // src/scripts/_lib/agent_settings.ts
174
218
  var agent_settings_exports = {};
175
219
  __export(agent_settings_exports, {
@@ -598,9 +642,9 @@ function load_agent_settings(options = {}) {
598
642
  }
599
643
  const cascade = _resolve_cascade_paths(cwd, project_path);
600
644
  const merged = template_defaults(template_path ?? void 0);
601
- _deep_merge(merged, user_global_filtered);
645
+ _deep_merge(merged, applyRenamedKeys(user_global_filtered));
602
646
  for (const p of cascade) {
603
- const layer = _read_yaml(p) ?? {};
647
+ const layer = applyRenamedKeys(_read_yaml(p) ?? {});
604
648
  if (Object.keys(layer).length > 0) {
605
649
  _deep_merge(merged, layer);
606
650
  }
@@ -911,6 +955,7 @@ var init_agent_settings = __esm({
911
955
  "use strict";
912
956
  init_user_global_paths();
913
957
  init_settingsCarveOut();
958
+ init_settings_renamed_keys();
914
959
  _require = createRequire(import.meta.url);
915
960
  Logger = class {
916
961
  name = "scripts._lib.agent_settings";
@@ -1080,17 +1125,17 @@ function _strip_frontmatter(text) {
1080
1125
  }
1081
1126
  return [meta, _lstripNewlines(body)];
1082
1127
  }
1083
- function _splitMax(text, sep20, maxsplit) {
1128
+ function _splitMax(text, sep21, maxsplit) {
1084
1129
  const out = [];
1085
1130
  let rest = text;
1086
1131
  let count = 0;
1087
1132
  while (count < maxsplit) {
1088
- const idx = rest.indexOf(sep20);
1133
+ const idx = rest.indexOf(sep21);
1089
1134
  if (idx === -1) {
1090
1135
  break;
1091
1136
  }
1092
1137
  out.push(rest.slice(0, idx));
1093
- rest = rest.slice(idx + sep20.length);
1138
+ rest = rest.slice(idx + sep21.length);
1094
1139
  count += 1;
1095
1140
  }
1096
1141
  out.push(rest);
@@ -1900,17 +1945,17 @@ var require_visit = __commonJS({
1900
1945
  visit.BREAK = BREAK;
1901
1946
  visit.SKIP = SKIP;
1902
1947
  visit.REMOVE = REMOVE;
1903
- function visit_(key, node, visitor, path103) {
1904
- const ctrl = callVisitor(key, node, visitor, path103);
1948
+ function visit_(key, node, visitor, path105) {
1949
+ const ctrl = callVisitor(key, node, visitor, path105);
1905
1950
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
1906
- replaceNode(key, path103, ctrl);
1907
- return visit_(key, ctrl, visitor, path103);
1951
+ replaceNode(key, path105, ctrl);
1952
+ return visit_(key, ctrl, visitor, path105);
1908
1953
  }
1909
1954
  if (typeof ctrl !== "symbol") {
1910
1955
  if (identity.isCollection(node)) {
1911
- path103 = Object.freeze(path103.concat(node));
1956
+ path105 = Object.freeze(path105.concat(node));
1912
1957
  for (let i = 0; i < node.items.length; ++i) {
1913
- const ci = visit_(i, node.items[i], visitor, path103);
1958
+ const ci = visit_(i, node.items[i], visitor, path105);
1914
1959
  if (typeof ci === "number")
1915
1960
  i = ci - 1;
1916
1961
  else if (ci === BREAK)
@@ -1921,13 +1966,13 @@ var require_visit = __commonJS({
1921
1966
  }
1922
1967
  }
1923
1968
  } else if (identity.isPair(node)) {
1924
- path103 = Object.freeze(path103.concat(node));
1925
- const ck = visit_("key", node.key, visitor, path103);
1969
+ path105 = Object.freeze(path105.concat(node));
1970
+ const ck = visit_("key", node.key, visitor, path105);
1926
1971
  if (ck === BREAK)
1927
1972
  return BREAK;
1928
1973
  else if (ck === REMOVE)
1929
1974
  node.key = null;
1930
- const cv = visit_("value", node.value, visitor, path103);
1975
+ const cv = visit_("value", node.value, visitor, path105);
1931
1976
  if (cv === BREAK)
1932
1977
  return BREAK;
1933
1978
  else if (cv === REMOVE)
@@ -1948,17 +1993,17 @@ var require_visit = __commonJS({
1948
1993
  visitAsync.BREAK = BREAK;
1949
1994
  visitAsync.SKIP = SKIP;
1950
1995
  visitAsync.REMOVE = REMOVE;
1951
- async function visitAsync_(key, node, visitor, path103) {
1952
- const ctrl = await callVisitor(key, node, visitor, path103);
1996
+ async function visitAsync_(key, node, visitor, path105) {
1997
+ const ctrl = await callVisitor(key, node, visitor, path105);
1953
1998
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
1954
- replaceNode(key, path103, ctrl);
1955
- return visitAsync_(key, ctrl, visitor, path103);
1999
+ replaceNode(key, path105, ctrl);
2000
+ return visitAsync_(key, ctrl, visitor, path105);
1956
2001
  }
1957
2002
  if (typeof ctrl !== "symbol") {
1958
2003
  if (identity.isCollection(node)) {
1959
- path103 = Object.freeze(path103.concat(node));
2004
+ path105 = Object.freeze(path105.concat(node));
1960
2005
  for (let i = 0; i < node.items.length; ++i) {
1961
- const ci = await visitAsync_(i, node.items[i], visitor, path103);
2006
+ const ci = await visitAsync_(i, node.items[i], visitor, path105);
1962
2007
  if (typeof ci === "number")
1963
2008
  i = ci - 1;
1964
2009
  else if (ci === BREAK)
@@ -1969,13 +2014,13 @@ var require_visit = __commonJS({
1969
2014
  }
1970
2015
  }
1971
2016
  } else if (identity.isPair(node)) {
1972
- path103 = Object.freeze(path103.concat(node));
1973
- const ck = await visitAsync_("key", node.key, visitor, path103);
2017
+ path105 = Object.freeze(path105.concat(node));
2018
+ const ck = await visitAsync_("key", node.key, visitor, path105);
1974
2019
  if (ck === BREAK)
1975
2020
  return BREAK;
1976
2021
  else if (ck === REMOVE)
1977
2022
  node.key = null;
1978
- const cv = await visitAsync_("value", node.value, visitor, path103);
2023
+ const cv = await visitAsync_("value", node.value, visitor, path105);
1979
2024
  if (cv === BREAK)
1980
2025
  return BREAK;
1981
2026
  else if (cv === REMOVE)
@@ -2002,23 +2047,23 @@ var require_visit = __commonJS({
2002
2047
  }
2003
2048
  return visitor;
2004
2049
  }
2005
- function callVisitor(key, node, visitor, path103) {
2050
+ function callVisitor(key, node, visitor, path105) {
2006
2051
  if (typeof visitor === "function")
2007
- return visitor(key, node, path103);
2052
+ return visitor(key, node, path105);
2008
2053
  if (identity.isMap(node))
2009
- return visitor.Map?.(key, node, path103);
2054
+ return visitor.Map?.(key, node, path105);
2010
2055
  if (identity.isSeq(node))
2011
- return visitor.Seq?.(key, node, path103);
2056
+ return visitor.Seq?.(key, node, path105);
2012
2057
  if (identity.isPair(node))
2013
- return visitor.Pair?.(key, node, path103);
2058
+ return visitor.Pair?.(key, node, path105);
2014
2059
  if (identity.isScalar(node))
2015
- return visitor.Scalar?.(key, node, path103);
2060
+ return visitor.Scalar?.(key, node, path105);
2016
2061
  if (identity.isAlias(node))
2017
- return visitor.Alias?.(key, node, path103);
2062
+ return visitor.Alias?.(key, node, path105);
2018
2063
  return void 0;
2019
2064
  }
2020
- function replaceNode(key, path103, node) {
2021
- const parent = path103[path103.length - 1];
2065
+ function replaceNode(key, path105, node) {
2066
+ const parent = path105[path105.length - 1];
2022
2067
  if (identity.isCollection(parent)) {
2023
2068
  parent.items[key] = node;
2024
2069
  } else if (identity.isPair(parent)) {
@@ -2628,10 +2673,10 @@ var require_Collection = __commonJS({
2628
2673
  var createNode = require_createNode();
2629
2674
  var identity = require_identity();
2630
2675
  var Node = require_Node();
2631
- function collectionFromPath(schema, path103, value) {
2676
+ function collectionFromPath(schema, path105, value) {
2632
2677
  let v = value;
2633
- for (let i = path103.length - 1; i >= 0; --i) {
2634
- const k = path103[i];
2678
+ for (let i = path105.length - 1; i >= 0; --i) {
2679
+ const k = path105[i];
2635
2680
  if (typeof k === "number" && Number.isInteger(k) && k >= 0) {
2636
2681
  const a = [];
2637
2682
  a[k] = v;
@@ -2650,7 +2695,7 @@ var require_Collection = __commonJS({
2650
2695
  sourceObjects: /* @__PURE__ */ new Map()
2651
2696
  });
2652
2697
  }
2653
- var isEmptyPath = (path103) => path103 == null || typeof path103 === "object" && !!path103[Symbol.iterator]().next().done;
2698
+ var isEmptyPath = (path105) => path105 == null || typeof path105 === "object" && !!path105[Symbol.iterator]().next().done;
2654
2699
  var Collection = class extends Node.NodeBase {
2655
2700
  constructor(type, schema) {
2656
2701
  super(type);
@@ -2680,11 +2725,11 @@ var require_Collection = __commonJS({
2680
2725
  * be a Pair instance or a `{ key, value }` object, which may not have a key
2681
2726
  * that already exists in the map.
2682
2727
  */
2683
- addIn(path103, value) {
2684
- if (isEmptyPath(path103))
2728
+ addIn(path105, value) {
2729
+ if (isEmptyPath(path105))
2685
2730
  this.add(value);
2686
2731
  else {
2687
- const [key, ...rest] = path103;
2732
+ const [key, ...rest] = path105;
2688
2733
  const node = this.get(key, true);
2689
2734
  if (identity.isCollection(node))
2690
2735
  node.addIn(rest, value);
@@ -2698,8 +2743,8 @@ var require_Collection = __commonJS({
2698
2743
  * Removes a value from the collection.
2699
2744
  * @returns `true` if the item was found and removed.
2700
2745
  */
2701
- deleteIn(path103) {
2702
- const [key, ...rest] = path103;
2746
+ deleteIn(path105) {
2747
+ const [key, ...rest] = path105;
2703
2748
  if (rest.length === 0)
2704
2749
  return this.delete(key);
2705
2750
  const node = this.get(key, true);
@@ -2713,8 +2758,8 @@ var require_Collection = __commonJS({
2713
2758
  * scalar values from their surrounding node; to disable set `keepScalar` to
2714
2759
  * `true` (collections are always returned intact).
2715
2760
  */
2716
- getIn(path103, keepScalar) {
2717
- const [key, ...rest] = path103;
2761
+ getIn(path105, keepScalar) {
2762
+ const [key, ...rest] = path105;
2718
2763
  const node = this.get(key, true);
2719
2764
  if (rest.length === 0)
2720
2765
  return !keepScalar && identity.isScalar(node) ? node.value : node;
@@ -2732,8 +2777,8 @@ var require_Collection = __commonJS({
2732
2777
  /**
2733
2778
  * Checks if the collection includes a value with the key `key`.
2734
2779
  */
2735
- hasIn(path103) {
2736
- const [key, ...rest] = path103;
2780
+ hasIn(path105) {
2781
+ const [key, ...rest] = path105;
2737
2782
  if (rest.length === 0)
2738
2783
  return this.has(key);
2739
2784
  const node = this.get(key, true);
@@ -2743,8 +2788,8 @@ var require_Collection = __commonJS({
2743
2788
  * Sets a value in this collection. For `!!set`, `value` needs to be a
2744
2789
  * boolean to add/remove the item from the set.
2745
2790
  */
2746
- setIn(path103, value) {
2747
- const [key, ...rest] = path103;
2791
+ setIn(path105, value) {
2792
+ const [key, ...rest] = path105;
2748
2793
  if (rest.length === 0) {
2749
2794
  this.set(key, value);
2750
2795
  } else {
@@ -5259,9 +5304,9 @@ var require_Document = __commonJS({
5259
5304
  this.contents.add(value);
5260
5305
  }
5261
5306
  /** Adds a value to the document. */
5262
- addIn(path103, value) {
5307
+ addIn(path105, value) {
5263
5308
  if (assertCollection(this.contents))
5264
- this.contents.addIn(path103, value);
5309
+ this.contents.addIn(path105, value);
5265
5310
  }
5266
5311
  /**
5267
5312
  * Create a new `Alias` node, ensuring that the target `node` has the required anchor.
@@ -5336,14 +5381,14 @@ var require_Document = __commonJS({
5336
5381
  * Removes a value from the document.
5337
5382
  * @returns `true` if the item was found and removed.
5338
5383
  */
5339
- deleteIn(path103) {
5340
- if (Collection.isEmptyPath(path103)) {
5384
+ deleteIn(path105) {
5385
+ if (Collection.isEmptyPath(path105)) {
5341
5386
  if (this.contents == null)
5342
5387
  return false;
5343
5388
  this.contents = null;
5344
5389
  return true;
5345
5390
  }
5346
- return assertCollection(this.contents) ? this.contents.deleteIn(path103) : false;
5391
+ return assertCollection(this.contents) ? this.contents.deleteIn(path105) : false;
5347
5392
  }
5348
5393
  /**
5349
5394
  * Returns item at `key`, or `undefined` if not found. By default unwraps
@@ -5358,10 +5403,10 @@ var require_Document = __commonJS({
5358
5403
  * scalar values from their surrounding node; to disable set `keepScalar` to
5359
5404
  * `true` (collections are always returned intact).
5360
5405
  */
5361
- getIn(path103, keepScalar) {
5362
- if (Collection.isEmptyPath(path103))
5406
+ getIn(path105, keepScalar) {
5407
+ if (Collection.isEmptyPath(path105))
5363
5408
  return !keepScalar && identity.isScalar(this.contents) ? this.contents.value : this.contents;
5364
- return identity.isCollection(this.contents) ? this.contents.getIn(path103, keepScalar) : void 0;
5409
+ return identity.isCollection(this.contents) ? this.contents.getIn(path105, keepScalar) : void 0;
5365
5410
  }
5366
5411
  /**
5367
5412
  * Checks if the document includes a value with the key `key`.
@@ -5372,10 +5417,10 @@ var require_Document = __commonJS({
5372
5417
  /**
5373
5418
  * Checks if the document includes a value at `path`.
5374
5419
  */
5375
- hasIn(path103) {
5376
- if (Collection.isEmptyPath(path103))
5420
+ hasIn(path105) {
5421
+ if (Collection.isEmptyPath(path105))
5377
5422
  return this.contents !== void 0;
5378
- return identity.isCollection(this.contents) ? this.contents.hasIn(path103) : false;
5423
+ return identity.isCollection(this.contents) ? this.contents.hasIn(path105) : false;
5379
5424
  }
5380
5425
  /**
5381
5426
  * Sets a value in this document. For `!!set`, `value` needs to be a
@@ -5392,13 +5437,13 @@ var require_Document = __commonJS({
5392
5437
  * Sets a value in this document. For `!!set`, `value` needs to be a
5393
5438
  * boolean to add/remove the item from the set.
5394
5439
  */
5395
- setIn(path103, value) {
5396
- if (Collection.isEmptyPath(path103)) {
5440
+ setIn(path105, value) {
5441
+ if (Collection.isEmptyPath(path105)) {
5397
5442
  this.contents = value;
5398
5443
  } else if (this.contents == null) {
5399
- this.contents = Collection.collectionFromPath(this.schema, Array.from(path103), value);
5444
+ this.contents = Collection.collectionFromPath(this.schema, Array.from(path105), value);
5400
5445
  } else if (assertCollection(this.contents)) {
5401
- this.contents.setIn(path103, value);
5446
+ this.contents.setIn(path105, value);
5402
5447
  }
5403
5448
  }
5404
5449
  /**
@@ -5784,10 +5829,10 @@ var require_resolve_block_map = __commonJS({
5784
5829
  let offset = bm.offset;
5785
5830
  let commentEnd = null;
5786
5831
  for (const collItem of bm.items) {
5787
- const { start, key, sep: sep20, value } = collItem;
5832
+ const { start, key, sep: sep21, value } = collItem;
5788
5833
  const keyProps = resolveProps.resolveProps(start, {
5789
5834
  indicator: "explicit-key-ind",
5790
- next: key ?? sep20?.[0],
5835
+ next: key ?? sep21?.[0],
5791
5836
  offset,
5792
5837
  onError,
5793
5838
  parentIndent: bm.indent,
@@ -5801,7 +5846,7 @@ var require_resolve_block_map = __commonJS({
5801
5846
  else if ("indent" in key && key.indent !== bm.indent)
5802
5847
  onError(offset, "BAD_INDENT", startColMsg);
5803
5848
  }
5804
- if (!keyProps.anchor && !keyProps.tag && !sep20) {
5849
+ if (!keyProps.anchor && !keyProps.tag && !sep21) {
5805
5850
  commentEnd = keyProps.end;
5806
5851
  if (keyProps.comment) {
5807
5852
  if (map.comment)
@@ -5825,7 +5870,7 @@ var require_resolve_block_map = __commonJS({
5825
5870
  ctx.atKey = false;
5826
5871
  if (utilMapIncludes.mapIncludes(ctx, map.items, keyNode))
5827
5872
  onError(keyStart, "DUPLICATE_KEY", "Map keys must be unique");
5828
- const valueProps = resolveProps.resolveProps(sep20 ?? [], {
5873
+ const valueProps = resolveProps.resolveProps(sep21 ?? [], {
5829
5874
  indicator: "map-value-ind",
5830
5875
  next: value,
5831
5876
  offset: keyNode.range[2],
@@ -5841,7 +5886,7 @@ var require_resolve_block_map = __commonJS({
5841
5886
  if (ctx.options.strict && keyProps.start < valueProps.found.offset - 1024)
5842
5887
  onError(keyNode.range, "KEY_OVER_1024_CHARS", "The : indicator must be at most 1024 chars after the start of an implicit block mapping key");
5843
5888
  }
5844
- const valueNode = value ? composeNode(ctx, value, valueProps, onError) : composeEmptyNode(ctx, offset, sep20, null, valueProps, onError);
5889
+ const valueNode = value ? composeNode(ctx, value, valueProps, onError) : composeEmptyNode(ctx, offset, sep21, null, valueProps, onError);
5845
5890
  if (ctx.schema.compat)
5846
5891
  utilFlowIndentCheck.flowIndentCheck(bm.indent, value, onError);
5847
5892
  offset = valueNode.range[2];
@@ -5932,7 +5977,7 @@ var require_resolve_end = __commonJS({
5932
5977
  let comment = "";
5933
5978
  if (end) {
5934
5979
  let hasSpace = false;
5935
- let sep20 = "";
5980
+ let sep21 = "";
5936
5981
  for (const token of end) {
5937
5982
  const { source, type } = token;
5938
5983
  switch (type) {
@@ -5946,13 +5991,13 @@ var require_resolve_end = __commonJS({
5946
5991
  if (!comment)
5947
5992
  comment = cb;
5948
5993
  else
5949
- comment += sep20 + cb;
5950
- sep20 = "";
5994
+ comment += sep21 + cb;
5995
+ sep21 = "";
5951
5996
  break;
5952
5997
  }
5953
5998
  case "newline":
5954
5999
  if (comment)
5955
- sep20 += source;
6000
+ sep21 += source;
5956
6001
  hasSpace = true;
5957
6002
  break;
5958
6003
  default:
@@ -5995,18 +6040,18 @@ var require_resolve_flow_collection = __commonJS({
5995
6040
  let offset = fc.offset + fc.start.source.length;
5996
6041
  for (let i = 0; i < fc.items.length; ++i) {
5997
6042
  const collItem = fc.items[i];
5998
- const { start, key, sep: sep20, value } = collItem;
6043
+ const { start, key, sep: sep21, value } = collItem;
5999
6044
  const props = resolveProps.resolveProps(start, {
6000
6045
  flow: fcName,
6001
6046
  indicator: "explicit-key-ind",
6002
- next: key ?? sep20?.[0],
6047
+ next: key ?? sep21?.[0],
6003
6048
  offset,
6004
6049
  onError,
6005
6050
  parentIndent: fc.indent,
6006
6051
  startOnNewline: false
6007
6052
  });
6008
6053
  if (!props.found) {
6009
- if (!props.anchor && !props.tag && !sep20 && !value) {
6054
+ if (!props.anchor && !props.tag && !sep21 && !value) {
6010
6055
  if (i === 0 && props.comma)
6011
6056
  onError(props.comma, "UNEXPECTED_TOKEN", `Unexpected , in ${fcName}`);
6012
6057
  else if (i < fc.items.length - 1)
@@ -6060,8 +6105,8 @@ var require_resolve_flow_collection = __commonJS({
6060
6105
  }
6061
6106
  }
6062
6107
  }
6063
- if (!isMap && !sep20 && !props.found) {
6064
- const valueNode = value ? composeNode(ctx, value, props, onError) : composeEmptyNode(ctx, props.end, sep20, null, props, onError);
6108
+ if (!isMap && !sep21 && !props.found) {
6109
+ const valueNode = value ? composeNode(ctx, value, props, onError) : composeEmptyNode(ctx, props.end, sep21, null, props, onError);
6065
6110
  coll.items.push(valueNode);
6066
6111
  offset = valueNode.range[2];
6067
6112
  if (isBlock(value))
@@ -6073,7 +6118,7 @@ var require_resolve_flow_collection = __commonJS({
6073
6118
  if (isBlock(key))
6074
6119
  onError(keyNode.range, "BLOCK_IN_FLOW", blockMsg);
6075
6120
  ctx.atKey = false;
6076
- const valueProps = resolveProps.resolveProps(sep20 ?? [], {
6121
+ const valueProps = resolveProps.resolveProps(sep21 ?? [], {
6077
6122
  flow: fcName,
6078
6123
  indicator: "map-value-ind",
6079
6124
  next: value,
@@ -6084,8 +6129,8 @@ var require_resolve_flow_collection = __commonJS({
6084
6129
  });
6085
6130
  if (valueProps.found) {
6086
6131
  if (!isMap && !props.found && ctx.options.strict) {
6087
- if (sep20)
6088
- for (const st of sep20) {
6132
+ if (sep21)
6133
+ for (const st of sep21) {
6089
6134
  if (st === valueProps.found)
6090
6135
  break;
6091
6136
  if (st.type === "newline") {
@@ -6102,7 +6147,7 @@ var require_resolve_flow_collection = __commonJS({
6102
6147
  else
6103
6148
  onError(valueProps.start, "MISSING_CHAR", `Missing , or : between ${fcName} items`);
6104
6149
  }
6105
- const valueNode = value ? composeNode(ctx, value, valueProps, onError) : valueProps.found ? composeEmptyNode(ctx, valueProps.end, sep20, null, valueProps, onError) : null;
6150
+ const valueNode = value ? composeNode(ctx, value, valueProps, onError) : valueProps.found ? composeEmptyNode(ctx, valueProps.end, sep21, null, valueProps, onError) : null;
6106
6151
  if (valueNode) {
6107
6152
  if (isBlock(value))
6108
6153
  onError(valueNode.range, "BLOCK_IN_FLOW", blockMsg);
@@ -6282,7 +6327,7 @@ var require_resolve_block_scalar = __commonJS({
6282
6327
  chompStart = i + 1;
6283
6328
  }
6284
6329
  let value = "";
6285
- let sep20 = "";
6330
+ let sep21 = "";
6286
6331
  let prevMoreIndented = false;
6287
6332
  for (let i = 0; i < contentStart; ++i)
6288
6333
  value += lines[i][0].slice(trimIndent) + "\n";
@@ -6299,24 +6344,24 @@ var require_resolve_block_scalar = __commonJS({
6299
6344
  indent = "";
6300
6345
  }
6301
6346
  if (type === Scalar.Scalar.BLOCK_LITERAL) {
6302
- value += sep20 + indent.slice(trimIndent) + content;
6303
- sep20 = "\n";
6347
+ value += sep21 + indent.slice(trimIndent) + content;
6348
+ sep21 = "\n";
6304
6349
  } else if (indent.length > trimIndent || content[0] === " ") {
6305
- if (sep20 === " ")
6306
- sep20 = "\n";
6307
- else if (!prevMoreIndented && sep20 === "\n")
6308
- sep20 = "\n\n";
6309
- value += sep20 + indent.slice(trimIndent) + content;
6310
- sep20 = "\n";
6350
+ if (sep21 === " ")
6351
+ sep21 = "\n";
6352
+ else if (!prevMoreIndented && sep21 === "\n")
6353
+ sep21 = "\n\n";
6354
+ value += sep21 + indent.slice(trimIndent) + content;
6355
+ sep21 = "\n";
6311
6356
  prevMoreIndented = true;
6312
6357
  } else if (content === "") {
6313
- if (sep20 === "\n")
6358
+ if (sep21 === "\n")
6314
6359
  value += "\n";
6315
6360
  else
6316
- sep20 = "\n";
6361
+ sep21 = "\n";
6317
6362
  } else {
6318
- value += sep20 + content;
6319
- sep20 = " ";
6363
+ value += sep21 + content;
6364
+ sep21 = " ";
6320
6365
  prevMoreIndented = false;
6321
6366
  }
6322
6367
  }
@@ -6498,25 +6543,25 @@ var require_resolve_flow_scalar = __commonJS({
6498
6543
  if (!match)
6499
6544
  return source;
6500
6545
  let res = match[1];
6501
- let sep20 = " ";
6546
+ let sep21 = " ";
6502
6547
  let pos = first.lastIndex;
6503
6548
  line.lastIndex = pos;
6504
6549
  while (match = line.exec(source)) {
6505
6550
  if (match[1] === "") {
6506
- if (sep20 === "\n")
6507
- res += sep20;
6551
+ if (sep21 === "\n")
6552
+ res += sep21;
6508
6553
  else
6509
- sep20 = "\n";
6554
+ sep21 = "\n";
6510
6555
  } else {
6511
- res += sep20 + match[1];
6512
- sep20 = " ";
6556
+ res += sep21 + match[1];
6557
+ sep21 = " ";
6513
6558
  }
6514
6559
  pos = line.lastIndex;
6515
6560
  }
6516
6561
  const last = /[ \t]*(.*)/sy;
6517
6562
  last.lastIndex = pos;
6518
6563
  match = last.exec(source);
6519
- return res + sep20 + (match?.[1] ?? "");
6564
+ return res + sep21 + (match?.[1] ?? "");
6520
6565
  }
6521
6566
  function doubleQuotedValue(source, onError) {
6522
6567
  let res = "";
@@ -7326,14 +7371,14 @@ var require_cst_stringify = __commonJS({
7326
7371
  }
7327
7372
  }
7328
7373
  }
7329
- function stringifyItem({ start, key, sep: sep20, value }) {
7374
+ function stringifyItem({ start, key, sep: sep21, value }) {
7330
7375
  let res = "";
7331
7376
  for (const st of start)
7332
7377
  res += st.source;
7333
7378
  if (key)
7334
7379
  res += stringifyToken(key);
7335
- if (sep20)
7336
- for (const st of sep20)
7380
+ if (sep21)
7381
+ for (const st of sep21)
7337
7382
  res += st.source;
7338
7383
  if (value)
7339
7384
  res += stringifyToken(value);
@@ -7358,9 +7403,9 @@ var require_cst_visit = __commonJS({
7358
7403
  visit.BREAK = BREAK;
7359
7404
  visit.SKIP = SKIP;
7360
7405
  visit.REMOVE = REMOVE;
7361
- visit.itemAtPath = (cst, path103) => {
7406
+ visit.itemAtPath = (cst, path105) => {
7362
7407
  let item = cst;
7363
- for (const [field, index] of path103) {
7408
+ for (const [field, index] of path105) {
7364
7409
  const tok = item?.[field];
7365
7410
  if (tok && "items" in tok) {
7366
7411
  item = tok.items[index];
@@ -7369,23 +7414,23 @@ var require_cst_visit = __commonJS({
7369
7414
  }
7370
7415
  return item;
7371
7416
  };
7372
- visit.parentCollection = (cst, path103) => {
7373
- const parent = visit.itemAtPath(cst, path103.slice(0, -1));
7374
- const field = path103[path103.length - 1][0];
7417
+ visit.parentCollection = (cst, path105) => {
7418
+ const parent = visit.itemAtPath(cst, path105.slice(0, -1));
7419
+ const field = path105[path105.length - 1][0];
7375
7420
  const coll = parent?.[field];
7376
7421
  if (coll && "items" in coll)
7377
7422
  return coll;
7378
7423
  throw new Error("Parent collection not found");
7379
7424
  };
7380
- function _visit(path103, item, visitor) {
7381
- let ctrl = visitor(item, path103);
7425
+ function _visit(path105, item, visitor) {
7426
+ let ctrl = visitor(item, path105);
7382
7427
  if (typeof ctrl === "symbol")
7383
7428
  return ctrl;
7384
7429
  for (const field of ["key", "value"]) {
7385
7430
  const token = item[field];
7386
7431
  if (token && "items" in token) {
7387
7432
  for (let i = 0; i < token.items.length; ++i) {
7388
- const ci = _visit(Object.freeze(path103.concat([[field, i]])), token.items[i], visitor);
7433
+ const ci = _visit(Object.freeze(path105.concat([[field, i]])), token.items[i], visitor);
7389
7434
  if (typeof ci === "number")
7390
7435
  i = ci - 1;
7391
7436
  else if (ci === BREAK)
@@ -7396,10 +7441,10 @@ var require_cst_visit = __commonJS({
7396
7441
  }
7397
7442
  }
7398
7443
  if (typeof ctrl === "function" && field === "key")
7399
- ctrl = ctrl(item, path103);
7444
+ ctrl = ctrl(item, path105);
7400
7445
  }
7401
7446
  }
7402
- return typeof ctrl === "function" ? ctrl(item, path103) : ctrl;
7447
+ return typeof ctrl === "function" ? ctrl(item, path105) : ctrl;
7403
7448
  }
7404
7449
  exports.visit = visit;
7405
7450
  }
@@ -8500,18 +8545,18 @@ var require_parser = __commonJS({
8500
8545
  if (this.type === "map-value-ind") {
8501
8546
  const prev = getPrevProps(this.peek(2));
8502
8547
  const start = getFirstKeyStartProps(prev);
8503
- let sep20;
8548
+ let sep21;
8504
8549
  if (scalar.end) {
8505
- sep20 = scalar.end;
8506
- sep20.push(this.sourceToken);
8550
+ sep21 = scalar.end;
8551
+ sep21.push(this.sourceToken);
8507
8552
  delete scalar.end;
8508
8553
  } else
8509
- sep20 = [this.sourceToken];
8554
+ sep21 = [this.sourceToken];
8510
8555
  const map = {
8511
8556
  type: "block-map",
8512
8557
  offset: scalar.offset,
8513
8558
  indent: scalar.indent,
8514
- items: [{ start, key: scalar, sep: sep20 }]
8559
+ items: [{ start, key: scalar, sep: sep21 }]
8515
8560
  };
8516
8561
  this.onKeyLine = true;
8517
8562
  this.stack[this.stack.length - 1] = map;
@@ -8664,15 +8709,15 @@ var require_parser = __commonJS({
8664
8709
  } else if (isFlowToken(it.key) && !includesToken(it.sep, "newline")) {
8665
8710
  const start2 = getFirstKeyStartProps(it.start);
8666
8711
  const key = it.key;
8667
- const sep20 = it.sep;
8668
- sep20.push(this.sourceToken);
8712
+ const sep21 = it.sep;
8713
+ sep21.push(this.sourceToken);
8669
8714
  delete it.key;
8670
8715
  delete it.sep;
8671
8716
  this.stack.push({
8672
8717
  type: "block-map",
8673
8718
  offset: this.offset,
8674
8719
  indent: this.indent,
8675
- items: [{ start: start2, key, sep: sep20 }]
8720
+ items: [{ start: start2, key, sep: sep21 }]
8676
8721
  });
8677
8722
  } else if (start.length > 0) {
8678
8723
  it.sep = it.sep.concat(start, this.sourceToken);
@@ -8701,14 +8746,14 @@ var require_parser = __commonJS({
8701
8746
  case "scalar":
8702
8747
  case "single-quoted-scalar":
8703
8748
  case "double-quoted-scalar": {
8704
- const fs106 = this.flowScalar(this.type);
8749
+ const fs108 = this.flowScalar(this.type);
8705
8750
  if (atNextItem || it.value) {
8706
- map.items.push({ start, key: fs106, sep: [] });
8751
+ map.items.push({ start, key: fs108, sep: [] });
8707
8752
  this.onKeyLine = true;
8708
8753
  } else if (it.sep) {
8709
- this.stack.push(fs106);
8754
+ this.stack.push(fs108);
8710
8755
  } else {
8711
- Object.assign(it, { key: fs106, sep: [] });
8756
+ Object.assign(it, { key: fs108, sep: [] });
8712
8757
  this.onKeyLine = true;
8713
8758
  }
8714
8759
  return;
@@ -8836,13 +8881,13 @@ var require_parser = __commonJS({
8836
8881
  case "scalar":
8837
8882
  case "single-quoted-scalar":
8838
8883
  case "double-quoted-scalar": {
8839
- const fs106 = this.flowScalar(this.type);
8884
+ const fs108 = this.flowScalar(this.type);
8840
8885
  if (!it || it.value)
8841
- fc.items.push({ start: [], key: fs106, sep: [] });
8886
+ fc.items.push({ start: [], key: fs108, sep: [] });
8842
8887
  else if (it.sep)
8843
- this.stack.push(fs106);
8888
+ this.stack.push(fs108);
8844
8889
  else
8845
- Object.assign(it, { key: fs106, sep: [] });
8890
+ Object.assign(it, { key: fs108, sep: [] });
8846
8891
  return;
8847
8892
  }
8848
8893
  case "flow-map-end":
@@ -8866,13 +8911,13 @@ var require_parser = __commonJS({
8866
8911
  const prev = getPrevProps(parent);
8867
8912
  const start = getFirstKeyStartProps(prev);
8868
8913
  fixFlowSeqItems(fc);
8869
- const sep20 = fc.end.splice(1, fc.end.length);
8870
- sep20.push(this.sourceToken);
8914
+ const sep21 = fc.end.splice(1, fc.end.length);
8915
+ sep21.push(this.sourceToken);
8871
8916
  const map = {
8872
8917
  type: "block-map",
8873
8918
  offset: fc.offset,
8874
8919
  indent: fc.indent,
8875
- items: [{ start, key: fc, sep: sep20 }]
8920
+ items: [{ start, key: fc, sep: sep21 }]
8876
8921
  };
8877
8922
  this.onKeyLine = true;
8878
8923
  this.stack[this.stack.length - 1] = map;
@@ -19565,17 +19610,17 @@ function freshMatch(pattern, text) {
19565
19610
  const re = new RegExp(pattern.source, pattern.flags);
19566
19611
  return re.exec(text);
19567
19612
  }
19568
- function splitN(text, sep20, maxsplit) {
19613
+ function splitN(text, sep21, maxsplit) {
19569
19614
  const parts = [];
19570
19615
  let rest = text;
19571
19616
  let count = 0;
19572
19617
  while (count < maxsplit) {
19573
- const idx = rest.indexOf(sep20);
19618
+ const idx = rest.indexOf(sep21);
19574
19619
  if (idx === -1) {
19575
19620
  break;
19576
19621
  }
19577
19622
  parts.push(rest.slice(0, idx));
19578
- rest = rest.slice(idx + sep20.length);
19623
+ rest = rest.slice(idx + sep21.length);
19579
19624
  count += 1;
19580
19625
  }
19581
19626
  parts.push(rest);
@@ -23337,8 +23382,8 @@ function atomicAppendLine(target, line) {
23337
23382
  } catch {
23338
23383
  existing = "";
23339
23384
  }
23340
- const sep20 = existing.length > 0 && !existing.endsWith("\n") ? "\n" : "";
23341
- atomicWriteFile(target, `${existing}${sep20}${line}
23385
+ const sep21 = existing.length > 0 && !existing.endsWith("\n") ? "\n" : "";
23386
+ atomicWriteFile(target, `${existing}${sep21}${line}
23342
23387
  `);
23343
23388
  }
23344
23389
  function randSuffix() {
@@ -24564,8 +24609,8 @@ function lockfile_path(env) {
24564
24609
  }
24565
24610
  return write_target("installed.lock", { env: env ?? null });
24566
24611
  }
24567
- function read_lockfile(path103) {
24568
- const target = path103 ?? lockfile_path();
24612
+ function read_lockfile(path105) {
24613
+ const target = path105 ?? lockfile_path();
24569
24614
  let text;
24570
24615
  try {
24571
24616
  text = fs52.readFileSync(target, { encoding: "utf-8" });
@@ -24682,18 +24727,18 @@ function manifest_path(project_root, env) {
24682
24727
  }
24683
24728
  return fsPath.join(project_root, DEFAULT_MANIFEST_RELATIVE);
24684
24729
  }
24685
- function read_manifest(path103) {
24730
+ function read_manifest(path105) {
24686
24731
  let text;
24687
24732
  try {
24688
- text = require_read_text(path103);
24733
+ text = require_read_text(path105);
24689
24734
  } catch {
24690
24735
  return null;
24691
24736
  }
24692
24737
  const data = _parse_manual(text);
24693
24738
  return _normalise_v2_shape(data);
24694
24739
  }
24695
- function require_read_text(path103) {
24696
- return fs53.readFileSync(path103, { encoding: "utf-8" });
24740
+ function require_read_text(path105) {
24741
+ return fs53.readFileSync(path105, { encoding: "utf-8" });
24697
24742
  }
24698
24743
  function _normalise_v2_shape(data) {
24699
24744
  if (data["tools"] === void 0 || data["tools"] === null) {
@@ -24874,9 +24919,9 @@ function stable_sort(items, key) {
24874
24919
  return a.index - b.index;
24875
24920
  }).map((entry) => entry.item);
24876
24921
  }
24877
- function write_manifest(path103, version, tools, options = {}) {
24922
+ function write_manifest(path105, version, tools, options = {}) {
24878
24923
  const rendered = _render(version, tools, { deploy_roots: options.deploy_roots ?? null });
24879
- return write_atomic(path103, rendered);
24924
+ return write_atomic(path105, rendered);
24880
24925
  }
24881
24926
  function upsert_tool(existing, options) {
24882
24927
  const {
@@ -27478,17 +27523,17 @@ function _split_frontmatter(text) {
27478
27523
  }
27479
27524
  return [parts[1], parts[2]];
27480
27525
  }
27481
- function _pySplit(s, sep20, maxsplit) {
27526
+ function _pySplit(s, sep21, maxsplit) {
27482
27527
  const out = [];
27483
27528
  let rest = s;
27484
27529
  let n = 0;
27485
27530
  while (n < maxsplit) {
27486
- const idx = rest.indexOf(sep20);
27531
+ const idx = rest.indexOf(sep21);
27487
27532
  if (idx === -1) {
27488
27533
  break;
27489
27534
  }
27490
27535
  out.push(rest.slice(0, idx));
27491
- rest = rest.slice(idx + sep20.length);
27536
+ rest = rest.slice(idx + sep21.length);
27492
27537
  n++;
27493
27538
  }
27494
27539
  out.push(rest);
@@ -29720,6 +29765,203 @@ var init_git_common_dir = __esm({
29720
29765
  }
29721
29766
  });
29722
29767
 
29768
+ // src/shared/missionExecution.ts
29769
+ function executionPostureFromOverrides(layers) {
29770
+ const raw = {};
29771
+ for (const [key, value] of layers) {
29772
+ if (key === "execution.fix_loop_max") raw["fix_loop_max"] = value;
29773
+ else if (key === "execution.escalation") raw["escalation"] = value;
29774
+ }
29775
+ return resolveExecutionPosture(raw);
29776
+ }
29777
+ function resolveExecutionPosture(raw) {
29778
+ const block = raw ?? {};
29779
+ const rawMax = block["fix_loop_max"];
29780
+ const max = typeof rawMax === "number" && Number.isInteger(rawMax) && rawMax > 0 ? rawMax : FIX_LOOP_MAX_DEFAULT;
29781
+ const rawLadder = block["escalation"];
29782
+ const ladder = Array.isArray(rawLadder) && rawLadder.length > 0 && rawLadder.every((r) => typeof r === "string") ? rawLadder : ESCALATION_LADDER;
29783
+ return { fix_loop_max: max, escalation: ladder };
29784
+ }
29785
+ var ESCALATION_LADDER, FIX_LOOP_MAX_DEFAULT;
29786
+ var init_missionExecution = __esm({
29787
+ "src/shared/missionExecution.ts"() {
29788
+ "use strict";
29789
+ ESCALATION_LADDER = [
29790
+ "independent",
29791
+ "council",
29792
+ "team",
29793
+ "owner_owned_check"
29794
+ ];
29795
+ FIX_LOOP_MAX_DEFAULT = 10;
29796
+ }
29797
+ });
29798
+
29799
+ // src/scripts/_lib/forge_protection.ts
29800
+ function isActiveBranchRuleset(rs) {
29801
+ return rs.enforcement === "active" && rs.target === "branch";
29802
+ }
29803
+ function reachesDefaultBranch(rs, defaultBranch) {
29804
+ const include = rs.conditions?.ref_name?.include ?? [];
29805
+ return include.some(
29806
+ (p) => p === "~DEFAULT_BRANCH" || p === "~ALL" || p === `refs/heads/${defaultBranch}`
29807
+ );
29808
+ }
29809
+ function hasRule(rs, type) {
29810
+ return (rs.rules ?? []).some((r) => r.type === type);
29811
+ }
29812
+ function requiredContexts(rs) {
29813
+ for (const r of rs.rules ?? []) {
29814
+ if (r.type !== "required_status_checks") continue;
29815
+ const p = r.parameters;
29816
+ if (p === null || typeof p !== "object") continue;
29817
+ const list = p["required_status_checks"];
29818
+ if (!Array.isArray(list)) continue;
29819
+ return list.map(
29820
+ (e) => e !== null && typeof e === "object" ? e["context"] : null
29821
+ ).filter((c) => typeof c === "string");
29822
+ }
29823
+ return [];
29824
+ }
29825
+ function forgeProtectionRows(reading) {
29826
+ const rows = [];
29827
+ const rulesets = reading.rulesets;
29828
+ const branch = reading.defaultBranch;
29829
+ const covering = rulesets === null || branch === null ? null : rulesets.filter((rs) => isActiveBranchRuleset(rs) && reachesDefaultBranch(rs, branch));
29830
+ rows.push(
29831
+ covering === null ? {
29832
+ id: "default_branch_protected",
29833
+ state: "unread",
29834
+ source: SOURCE.rulesets,
29835
+ detail: "the rulesets were not queried"
29836
+ } : covering.length > 0 ? {
29837
+ id: "default_branch_protected",
29838
+ state: "satisfied",
29839
+ source: SOURCE.rulesets,
29840
+ detail: `${String(covering.length)} active branch ruleset(s) cover the default branch`
29841
+ } : {
29842
+ id: "default_branch_protected",
29843
+ state: "unsatisfied",
29844
+ source: SOURCE.rulesets,
29845
+ detail: "no active branch ruleset covers the default branch. NOTE: the classic branches/<b>/protection endpoint 404s on a ruleset-protected repository, so a 404 there is not evidence for this row."
29846
+ }
29847
+ );
29848
+ const contexts = covering === null ? null : covering.flatMap(requiredContexts);
29849
+ rows.push(
29850
+ contexts === null ? {
29851
+ id: "required_checks_present",
29852
+ state: "unread",
29853
+ source: SOURCE.rulesets,
29854
+ detail: "the rulesets were not queried"
29855
+ } : contexts.length > 0 ? {
29856
+ id: "required_checks_present",
29857
+ state: "satisfied",
29858
+ source: SOURCE.rulesets,
29859
+ detail: `${String(contexts.length)} required context(s): ${contexts.join(", ")}`
29860
+ } : {
29861
+ id: "required_checks_present",
29862
+ state: "unsatisfied",
29863
+ source: SOURCE.rulesets,
29864
+ detail: "no required status check context is configured"
29865
+ }
29866
+ );
29867
+ const noFastForward = covering === null ? null : covering.some((rs) => hasRule(rs, "non_fast_forward"));
29868
+ rows.push(
29869
+ noFastForward === null ? {
29870
+ id: "force_push_disabled",
29871
+ state: "unread",
29872
+ source: SOURCE.rulesets,
29873
+ detail: "the rulesets were not queried"
29874
+ } : {
29875
+ id: "force_push_disabled",
29876
+ state: noFastForward ? "satisfied" : "unsatisfied",
29877
+ source: SOURCE.rulesets,
29878
+ detail: noFastForward ? "a non_fast_forward rule is active on the default branch" : "no non_fast_forward rule covers the default branch"
29879
+ }
29880
+ );
29881
+ rows.push(
29882
+ reading.allowAutoMerge === null ? {
29883
+ id: "auto_merge_available",
29884
+ state: "unread",
29885
+ source: SOURCE.repo,
29886
+ detail: "the repository record was not queried"
29887
+ } : {
29888
+ id: "auto_merge_available",
29889
+ state: reading.allowAutoMerge ? "satisfied" : "unsatisfied",
29890
+ source: SOURCE.repo,
29891
+ detail: reading.allowAutoMerge ? "allow_auto_merge is enabled" : "allow_auto_merge is disabled \u2014 merge delivery cannot queue behind checks"
29892
+ }
29893
+ );
29894
+ rows.push(
29895
+ reading.deployRestricted === null ? {
29896
+ id: "deploy_via_pipeline_only",
29897
+ state: "unread",
29898
+ source: SOURCE.environments,
29899
+ detail: "the environments were not queried"
29900
+ } : {
29901
+ id: "deploy_via_pipeline_only",
29902
+ state: reading.deployRestricted ? "satisfied" : "unsatisfied",
29903
+ source: SOURCE.environments,
29904
+ detail: reading.deployRestricted ? "every environment restricts its deployment branches" : "at least one environment accepts a deployment from any branch"
29905
+ }
29906
+ );
29907
+ return rows;
29908
+ }
29909
+ function protectionActions(rows) {
29910
+ return rows.filter((r) => r.state !== "satisfied").map((r) => `${r.id}: ${r.state} \u2014 ${r.detail} (source: ${r.source})`);
29911
+ }
29912
+ var SOURCE;
29913
+ var init_forge_protection = __esm({
29914
+ "src/scripts/_lib/forge_protection.ts"() {
29915
+ "use strict";
29916
+ SOURCE = {
29917
+ rulesets: "GET repos/{owner}/{repo}/rulesets + GET .../rulesets/{id}",
29918
+ repo: "GET repos/{owner}/{repo} (allow_auto_merge)",
29919
+ environments: "GET repos/{owner}/{repo}/environments (deployment_branch_policy)"
29920
+ };
29921
+ }
29922
+ });
29923
+
29924
+ // src/scripts/_cli/doctor_execution.ts
29925
+ function executionJson(overrides) {
29926
+ let posture;
29927
+ try {
29928
+ posture = executionPostureFromOverrides(overrides());
29929
+ } catch {
29930
+ posture = resolveExecutionPosture({});
29931
+ }
29932
+ return {
29933
+ fix_loop_max: posture.fix_loop_max,
29934
+ escalation: [...posture.escalation]
29935
+ };
29936
+ }
29937
+ function forgeProtectionJson(reading) {
29938
+ const rows = forgeProtectionRows(reading);
29939
+ return {
29940
+ rows: rows.map((r) => ({
29941
+ id: r.id,
29942
+ state: r.state,
29943
+ source: r.source,
29944
+ detail: r.detail
29945
+ })),
29946
+ actions: protectionActions(rows),
29947
+ read_from_forge: rows.some((r) => r.state !== "unread")
29948
+ };
29949
+ }
29950
+ var UNREAD_FORGE;
29951
+ var init_doctor_execution = __esm({
29952
+ "src/scripts/_cli/doctor_execution.ts"() {
29953
+ "use strict";
29954
+ init_missionExecution();
29955
+ init_forge_protection();
29956
+ UNREAD_FORGE = {
29957
+ rulesets: null,
29958
+ defaultBranch: null,
29959
+ allowAutoMerge: null,
29960
+ deployRestricted: null
29961
+ };
29962
+ }
29963
+ });
29964
+
29723
29965
  // src/scripts/ai_council/cli_agency_bounds.ts
29724
29966
  function boundFor(member) {
29725
29967
  return AGENCY_BOUNDS.find((b) => b.member === member)?.bound ?? [];
@@ -32615,7 +32857,7 @@ function buildSecondModel(entry, cls, locked, d) {
32615
32857
  if (!("second_model" in entry)) return null;
32616
32858
  if (locked.has(cls)) {
32617
32859
  throw d.error(
32618
- `decision_resolution.classes.${cls}.second_model=${d.repr(entry["second_model"])}: a second-model rung is not configurable for high-impact / user-required decisions \u2014 those classes are LOCKED to \`user\` (Iron Law) and never resolve on a model of any kind.`
32860
+ `decision_resolution.classes.${cls}.second_model=${d.repr(entry["second_model"])}: a second-model rung is not configurable for an owner-routed class (high-impact / user-required on the impact axis; product-owned / business-owned / destructive-owned on the ownership axis) \u2014 those classes are LOCKED to \`user\` (Iron Law) and never resolve on a model of any kind.`
32619
32861
  );
32620
32862
  }
32621
32863
  const raw = entry["second_model"];
@@ -32639,6 +32881,60 @@ var init_fallback_config = __esm({
32639
32881
  }
32640
32882
  });
32641
32883
 
32884
+ // src/scripts/ai_council/ownership_classes.ts
32885
+ function allOwnerLocked(impactLocked) {
32886
+ return /* @__PURE__ */ new Set([...impactLocked, ...OWNER_LOCKED_CLASSES]);
32887
+ }
32888
+ function defaultModeFor(cls) {
32889
+ return DEFAULT_RESOLUTION_MODES[cls] ?? "agent";
32890
+ }
32891
+ function ownershipModeError(cls, mode, repr) {
32892
+ if (OWNER_LOCKED_CLASSES.has(cls) && mode !== "user") {
32893
+ return `decision_resolution.classes.${cls}.mode=${repr(mode)}: class \`${cls}\` is LOCKED to \`user\` (Iron Law) \u2014 product, business and destructive decisions are owner-owned and never resolve on a model.`;
32894
+ }
32895
+ if (NEVER_OWNER_CLASSES.has(cls) && mode === "user") {
32896
+ return `decision_resolution.classes.${cls}.mode=${repr(mode)}: class \`${cls}\` is never owner-routed (Iron Law) \u2014 spend exhaustion pauses and reports, it does not ask.`;
32897
+ }
32898
+ return null;
32899
+ }
32900
+ var OWNERSHIP_CLASSES, OWNER_LOCKED_CLASSES, NEVER_OWNER_CLASSES, DEFAULT_RESOLUTION_MODES;
32901
+ var init_ownership_classes = __esm({
32902
+ "src/scripts/ai_council/ownership_classes.ts"() {
32903
+ "use strict";
32904
+ OWNERSHIP_CLASSES = [
32905
+ "deterministic",
32906
+ "reversible-technical",
32907
+ "contested-technical",
32908
+ "critical-technical",
32909
+ "product-owned",
32910
+ "business-owned",
32911
+ "destructive-owned",
32912
+ "spend-exhaustion"
32913
+ ];
32914
+ OWNER_LOCKED_CLASSES = /* @__PURE__ */ new Set([
32915
+ "product-owned",
32916
+ "business-owned",
32917
+ "destructive-owned"
32918
+ ]);
32919
+ NEVER_OWNER_CLASSES = /* @__PURE__ */ new Set(["spend-exhaustion"]);
32920
+ DEFAULT_RESOLUTION_MODES = {
32921
+ trivial: "agent",
32922
+ low_impact: "agent",
32923
+ medium_impact: "council",
32924
+ high_impact: "user",
32925
+ user_required: "user",
32926
+ deterministic: "agent",
32927
+ "reversible-technical": "agent",
32928
+ "contested-technical": "council",
32929
+ "critical-technical": "council",
32930
+ "product-owned": "user",
32931
+ "business-owned": "user",
32932
+ "destructive-owned": "user",
32933
+ "spend-exhaustion": "agent"
32934
+ };
32935
+ }
32936
+ });
32937
+
32642
32938
  // src/scripts/ai_council/py_format.ts
32643
32939
  function _pyReprStr(s) {
32644
32940
  const hasSingle = s.includes("'");
@@ -33243,14 +33539,14 @@ function _build_decision_resolution(d) {
33243
33539
  );
33244
33540
  }
33245
33541
  const classes = /* @__PURE__ */ new Map();
33246
- for (const cls of _IMPACT_CLASSES) {
33542
+ for (const cls of [..._IMPACT_CLASSES, ...OWNERSHIP_CLASSES]) {
33247
33543
  const entry_raw = _orEmpty(classes_raw[cls] ?? null);
33248
33544
  if (!_isDict(entry_raw)) {
33249
33545
  throw new CouncilConfigError(
33250
33546
  `\`decision_resolution.classes.${cls}\` must be a mapping.`
33251
33547
  );
33252
33548
  }
33253
- const mode = _get(entry_raw, "mode", _DEFAULT_RESOLUTION_MODES[cls]);
33549
+ const mode = _get(entry_raw, "mode", defaultModeFor(cls));
33254
33550
  if (!(_isStr(mode) && _VALID_RESOLUTION_MODES.has(mode))) {
33255
33551
  throw new CouncilConfigError(
33256
33552
  `decision_resolution.classes.${cls}.mode=${_pyRepr6(mode)} not in ${_sortedListRepr(_VALID_RESOLUTION_MODES)}.`
@@ -33261,7 +33557,9 @@ function _build_decision_resolution(d) {
33261
33557
  `decision_resolution.classes.${cls}.mode=${_pyRepr6(mode)}: class \`${cls}\` is LOCKED to \`user\` (Iron Law) \u2014 high-impact and user-required decisions never bypass the user.`
33262
33558
  );
33263
33559
  }
33264
- if (_LOCKED_IMPACT_CLASSES.has(cls) && "dispatch" in entry_raw) {
33560
+ const ownErr = ownershipModeError(cls, mode, _pyRepr6);
33561
+ if (ownErr !== null) throw new CouncilConfigError(ownErr);
33562
+ if (_ALL_OWNER_LOCKED.has(cls) && "dispatch" in entry_raw) {
33265
33563
  throw new CouncilConfigError(
33266
33564
  `decision_resolution.classes.${cls}.dispatch=${_pyRepr6(entry_raw.dispatch)}: dispatch is not configurable for high-impact / user-required decisions \u2014 always full council.`
33267
33565
  );
@@ -33275,7 +33573,7 @@ function _build_decision_resolution(d) {
33275
33573
  const second_model = buildSecondModel(
33276
33574
  entry_raw,
33277
33575
  cls,
33278
- _LOCKED_IMPACT_CLASSES,
33576
+ _ALL_OWNER_LOCKED,
33279
33577
  _FALLBACK_DEPS
33280
33578
  );
33281
33579
  classes.set(cls, { mode, confidence_threshold: threshold, second_model });
@@ -33967,7 +34265,7 @@ function _pyTruthy3(value) {
33967
34265
  }
33968
34266
  return Object.keys(value).length > 0;
33969
34267
  }
33970
- var import_yaml6, _VALID_PROVIDERS, _FALLBACK_DEPS, _RAW_KEY_PREFIXES, CouncilConfigError, _VALID_NECESSITY_MODES, _VALID_DISCLOSURE_MODES, _VALID_CHAIRMAN_MODES, COUNCIL_CONFIG_RELNAME, COUNCIL_CONFIG_USER_GLOBAL_REL, COUNCIL_CONFIG_ENV, _VALID_CRITIC_PROTOCOLS, _VALID_RESOLUTION_MODES, _IMPACT_CLASSES, _LOCKED_IMPACT_CLASSES, _DEFAULT_RESOLUTION_MODES, _VALID_MEMBER_MODES, _VALID_DISPATCH_MODES, DEFAULT_CLI_CALLS_PER_DAY2;
34268
+ var import_yaml6, _VALID_PROVIDERS, _FALLBACK_DEPS, _RAW_KEY_PREFIXES, CouncilConfigError, _VALID_NECESSITY_MODES, _VALID_DISCLOSURE_MODES, _VALID_CHAIRMAN_MODES, COUNCIL_CONFIG_RELNAME, COUNCIL_CONFIG_USER_GLOBAL_REL, COUNCIL_CONFIG_ENV, _VALID_CRITIC_PROTOCOLS, _VALID_RESOLUTION_MODES, _IMPACT_CLASSES, _LOCKED_IMPACT_CLASSES, _ALL_OWNER_LOCKED, _VALID_MEMBER_MODES, _VALID_DISPATCH_MODES, DEFAULT_CLI_CALLS_PER_DAY2;
33971
34269
  var init_config = __esm({
33972
34270
  "src/scripts/ai_council/config.ts"() {
33973
34271
  "use strict";
@@ -33978,6 +34276,7 @@ var init_config = __esm({
33978
34276
  init_seat_policy();
33979
34277
  init_quorum();
33980
34278
  init_fallback_config();
34279
+ init_ownership_classes();
33981
34280
  init_py_format();
33982
34281
  _VALID_PROVIDERS = /* @__PURE__ */ new Set([
33983
34282
  "anthropic",
@@ -34042,13 +34341,7 @@ var init_config = __esm({
34042
34341
  "high_impact",
34043
34342
  "user_required"
34044
34343
  ]);
34045
- _DEFAULT_RESOLUTION_MODES = {
34046
- trivial: "agent",
34047
- low_impact: "agent",
34048
- medium_impact: "council",
34049
- high_impact: "user",
34050
- user_required: "user"
34051
- };
34344
+ _ALL_OWNER_LOCKED = allOwnerLocked(_LOCKED_IMPACT_CLASSES);
34052
34345
  _VALID_MEMBER_MODES = /* @__PURE__ */ new Set(["cli", "api"]);
34053
34346
  _VALID_DISPATCH_MODES = /* @__PURE__ */ new Set(["full", "single"]);
34054
34347
  DEFAULT_CLI_CALLS_PER_DAY2 = DEFAULT_CLI_CALLS_PER_DAY;
@@ -36536,8 +36829,8 @@ function shutilWhich(name) {
36536
36829
  return isExecutableFile(name) ? name : null;
36537
36830
  }
36538
36831
  const pathEnv = process19.env["PATH"] || "";
36539
- const sep20 = process19.platform === "win32" ? ";" : ":";
36540
- const dirs = pathEnv.split(sep20);
36832
+ const sep21 = process19.platform === "win32" ? ";" : ":";
36833
+ const dirs = pathEnv.split(sep21);
36541
36834
  const exts = process19.platform === "win32" ? (process19.env["PATHEXT"] || ".COM;.EXE;.BAT;.CMD").split(";") : [""];
36542
36835
  const seenDirs = /* @__PURE__ */ new Set();
36543
36836
  for (const dir of dirs) {
@@ -37990,9 +38283,9 @@ function _emit_json(project_root, missing, modified, foreign, tag_drift, checks
37990
38283
  foreign,
37991
38284
  tag_drift
37992
38285
  };
37993
- if (origin !== null) {
37994
- payload["project_root_origin"] = origin;
37995
- }
38286
+ if (origin !== null) payload["project_root_origin"] = origin;
38287
+ payload["execution"] = executionJson(() => iter_setting_overrides({ cwd: project_root }));
38288
+ payload["forge_protection"] = forgeProtectionJson(UNREAD_FORGE);
37996
38289
  if (checks !== null) {
37997
38290
  payload["checks"] = checks;
37998
38291
  const drift = missing.length + modified.length + foreign.length + tag_drift.length;
@@ -38353,6 +38646,7 @@ var init_cmd_doctor = __esm({
38353
38646
  init_git_common_dir();
38354
38647
  init_sync_gitattributes();
38355
38648
  init_agent_settings();
38649
+ init_doctor_execution();
38356
38650
  init_clients();
38357
38651
  init_config();
38358
38652
  init_environment_detector();
@@ -38551,9 +38845,9 @@ function detectToolPresence(root) {
38551
38845
  agentsMd: existsSync41(join68(root, "AGENTS.md"))
38552
38846
  };
38553
38847
  }
38554
- function isDir5(path103) {
38848
+ function isDir5(path105) {
38555
38849
  try {
38556
- return statSync44(path103).isDirectory();
38850
+ return statSync44(path105).isDirectory();
38557
38851
  } catch {
38558
38852
  return false;
38559
38853
  }
@@ -38566,10 +38860,10 @@ var init_detect = __esm({
38566
38860
 
38567
38861
  // src/scripts/router_target_paths.mjs
38568
38862
  function parseRouteTarget(target) {
38569
- const sep20 = target.indexOf(":");
38570
- if (sep20 <= 0) return null;
38571
- const kind = target.slice(0, sep20);
38572
- const id = target.slice(sep20 + 1);
38863
+ const sep21 = target.indexOf(":");
38864
+ if (sep21 <= 0) return null;
38865
+ const kind = target.slice(0, sep21);
38866
+ const id = target.slice(sep21 + 1);
38573
38867
  if (!id) return null;
38574
38868
  if (!Object.prototype.hasOwnProperty.call(ROUTE_TARGET_TEMPLATES, kind)) return null;
38575
38869
  return { kind, id };
@@ -40754,6 +41048,473 @@ var init_before_complete_hook = __esm({
40754
41048
  }
40755
41049
  });
40756
41050
 
41051
+ // src/scripts/check_reply_consistency.ts
41052
+ import * as fs81 from "node:fs";
41053
+ import * as path81 from "node:path";
41054
+ import { fileURLToPath as fileURLToPath39, pathToFileURL as pathToFileURL24 } from "node:url";
41055
+ function _strip_codespans(line) {
41056
+ return line.replace(CODESPAN_RE, "``");
41057
+ }
41058
+ function splitAndMask(text) {
41059
+ return mask_fences(_splitlines8(text));
41060
+ }
41061
+ function _splitlines8(text) {
41062
+ if (text === "") return [];
41063
+ const parts = text.split(/\r\n|\r|\n/);
41064
+ if (parts.length > 0 && parts[parts.length - 1] === "") {
41065
+ parts.pop();
41066
+ }
41067
+ return parts;
41068
+ }
41069
+ function mask_fences(lines) {
41070
+ const out = [];
41071
+ let fence = null;
41072
+ for (const raw of lines) {
41073
+ const m = FENCE_RE2.exec(raw);
41074
+ if (m) {
41075
+ const marker = m[1];
41076
+ if (fence === null) {
41077
+ fence = marker;
41078
+ } else if (fence === marker) {
41079
+ fence = null;
41080
+ }
41081
+ out.push("");
41082
+ continue;
41083
+ }
41084
+ out.push(fence === null ? raw : "");
41085
+ }
41086
+ return out;
41087
+ }
41088
+ function find_option_blocks(text) {
41089
+ const lines = mask_fences(_splitlines8(text));
41090
+ const blocks = [];
41091
+ let current = null;
41092
+ for (let idx = 0; idx < lines.length; idx++) {
41093
+ const m = OPTION_LINE_RE.exec(lines[idx]);
41094
+ if (m) {
41095
+ const num2 = parseInt(m[1], 10);
41096
+ if (current === null) {
41097
+ current = { startLine: idx + 1, endLine: idx + 1, numbers: [num2] };
41098
+ } else {
41099
+ current.endLine = idx + 1;
41100
+ current.numbers.push(num2);
41101
+ }
41102
+ } else {
41103
+ if (current !== null && current.numbers.length >= 2) {
41104
+ blocks.push(current);
41105
+ }
41106
+ current = null;
41107
+ }
41108
+ }
41109
+ if (current !== null && current.numbers.length >= 2) {
41110
+ blocks.push(current);
41111
+ }
41112
+ return blocks;
41113
+ }
41114
+ function recommendationsUnder(text, block, maskedLines) {
41115
+ const lines = maskedLines ?? mask_fences(_splitlines8(text));
41116
+ const recs = [];
41117
+ let inspected = 0;
41118
+ for (let idx = block.endLine; idx < lines.length && inspected < REC_ADJACENCY_WINDOW; idx++) {
41119
+ const line = lines[idx];
41120
+ if (line.trim() === "") {
41121
+ continue;
41122
+ }
41123
+ if (HEADING_RE.test(line) || OPTION_LINE_RE.test(line)) {
41124
+ break;
41125
+ }
41126
+ inspected += 1;
41127
+ const m = REC_LINE_RE.exec(line);
41128
+ if (m) {
41129
+ recs.push({ line: idx + 1, num: parseInt(m[1], 10) });
41130
+ }
41131
+ }
41132
+ return recs;
41133
+ }
41134
+ function check_reply(text) {
41135
+ const rawLines = _splitlines8(text);
41136
+ const lines = mask_fences(rawLines);
41137
+ const findings = [];
41138
+ for (let idx = 0; idx < lines.length; idx++) {
41139
+ const stripped = _strip_codespans(lines[idx]);
41140
+ if (OPTION_LINE_RE.test(stripped) && TAG_RE.test(stripped)) {
41141
+ findings.push({
41142
+ line: idx + 1,
41143
+ message: `inline tag on numbered option \u2014 ${rawLines[idx].trim()}`
41144
+ });
41145
+ }
41146
+ }
41147
+ const blocks = find_option_blocks(text);
41148
+ for (const block of blocks) {
41149
+ const recs = recommendationsUnder(text, block);
41150
+ if (recs.length === 0) {
41151
+ findings.push({
41152
+ line: block.startLine,
41153
+ message: "numbered options block without a Recommendation:/Empfehlung: line directly under it"
41154
+ });
41155
+ continue;
41156
+ }
41157
+ if (recs.length > 1) {
41158
+ findings.push({
41159
+ line: recs[1].line,
41160
+ message: `multiple recommendation lines under one options block: [${recs.map((r) => r.num).join(", ")}]`
41161
+ });
41162
+ continue;
41163
+ }
41164
+ const rec = recs[0];
41165
+ if (!block.numbers.includes(rec.num)) {
41166
+ findings.push({
41167
+ line: rec.line,
41168
+ message: `recommendation ${String(rec.num)} not present in the options block above it (options: [${block.numbers.join(", ")}])`
41169
+ });
41170
+ }
41171
+ }
41172
+ findings.sort((a, b) => a.line - b.line);
41173
+ return findings;
41174
+ }
41175
+ function _isDir12(p) {
41176
+ try {
41177
+ return fs81.statSync(p).isDirectory();
41178
+ } catch {
41179
+ return false;
41180
+ }
41181
+ }
41182
+ function _rglobMdSorted4(dir) {
41183
+ const out = [];
41184
+ const walk = (current) => {
41185
+ let entries;
41186
+ try {
41187
+ entries = fs81.readdirSync(current, { withFileTypes: true });
41188
+ } catch {
41189
+ return;
41190
+ }
41191
+ for (const ent of entries) {
41192
+ const full = path81.join(current, ent.name);
41193
+ if (ent.isDirectory() || ent.isSymbolicLink() && _isDir12(full)) {
41194
+ walk(full);
41195
+ } else if (ent.name.endsWith(".md")) {
41196
+ out.push(full);
41197
+ }
41198
+ }
41199
+ };
41200
+ walk(dir);
41201
+ out.sort();
41202
+ return out;
41203
+ }
41204
+ function _relToPosixOrAbs(child, root) {
41205
+ const rel = path81.relative(root, child);
41206
+ if (rel === "" || rel.startsWith("..") || path81.isAbsolute(rel)) {
41207
+ return child.split(path81.sep).join("/");
41208
+ }
41209
+ return rel.split(path81.sep).join("/");
41210
+ }
41211
+ function cmd_scan_dir(root) {
41212
+ let roots;
41213
+ if (!_isDir12(root)) {
41214
+ const legacy = path81.join(ROOT4, ".agent-src.uncondensed");
41215
+ if (path81.resolve(root) === path81.resolve(legacy)) {
41216
+ roots = artefact_roots();
41217
+ if (roots.length === 0) {
41218
+ process.stderr.write("error: no artefact roots found (legacy or packages/*)\n");
41219
+ return 1;
41220
+ }
41221
+ } else {
41222
+ process.stderr.write(`error: not a directory: ${root}
41223
+ `);
41224
+ return 1;
41225
+ }
41226
+ } else {
41227
+ roots = [root];
41228
+ }
41229
+ const violations = [];
41230
+ let scanned = 0;
41231
+ for (const r of roots) {
41232
+ for (const md of _rglobMdSorted4(r)) {
41233
+ scanned += 1;
41234
+ const text = fs81.readFileSync(md, "utf-8");
41235
+ const lines = _splitlines8(text);
41236
+ for (let idx = 0; idx < lines.length; idx++) {
41237
+ const raw = lines[idx];
41238
+ const stripped = _strip_codespans(raw);
41239
+ if (OPTION_LINE_RE.test(stripped) && TAG_RE.test(stripped)) {
41240
+ violations.push([md, idx + 1, raw.trim()]);
41241
+ }
41242
+ }
41243
+ }
41244
+ }
41245
+ try {
41246
+ assertScanned({
41247
+ gate: "check_reply_consistency",
41248
+ scanned,
41249
+ units: "markdown file(s)",
41250
+ roots: roots.map((r) => _relToPosixOrAbs(r, ROOT4))
41251
+ });
41252
+ } catch (exc) {
41253
+ if (exc instanceof DeadScopeError) {
41254
+ process.stderr.write(`\u274C ${exc.message}
41255
+ `);
41256
+ return 1;
41257
+ }
41258
+ throw exc;
41259
+ }
41260
+ if (violations.length > 0) {
41261
+ for (const [p, line, snippet] of violations) {
41262
+ process.stderr.write(` \u{1F534} ${p}:${String(line)} \u2014 inline-tag \u2014 ${snippet}
41263
+ `);
41264
+ }
41265
+ process.stderr.write(`
41266
+ \u274C ${String(violations.length)} legacy-pattern violation(s)
41267
+ `);
41268
+ return 2;
41269
+ }
41270
+ if (!QUIET) {
41271
+ const scanned2 = roots.map((r) => _relToPosixOrAbs(r, ROOT4)).join(", ");
41272
+ process.stdout.write(`\u2705 No legacy (recommended) tags found under ${scanned2}
41273
+ `);
41274
+ }
41275
+ return 0;
41276
+ }
41277
+ function _usage_error(message) {
41278
+ process.stderr.write(USAGE3);
41279
+ process.stderr.write(`check_reply_consistency: error: ${message}
41280
+ `);
41281
+ process.exit(1);
41282
+ }
41283
+ function _readStdin3() {
41284
+ try {
41285
+ return fs81.readFileSync(0, "utf-8");
41286
+ } catch {
41287
+ return "";
41288
+ }
41289
+ }
41290
+ function parse_args8(argv) {
41291
+ let stdin = false;
41292
+ let file = null;
41293
+ let scan_dir2 = null;
41294
+ let verbose = false;
41295
+ const groupSeen = [];
41296
+ const need = (i, name) => {
41297
+ const v = argv[i];
41298
+ if (v === void 0) {
41299
+ _usage_error(`argument ${name}: expected one argument`);
41300
+ }
41301
+ return v;
41302
+ };
41303
+ for (let i = 0; i < argv.length; i++) {
41304
+ const arg = argv[i];
41305
+ if (arg === "--stdin") {
41306
+ stdin = true;
41307
+ groupSeen.push("--stdin");
41308
+ } else if (arg === "--file") {
41309
+ file = need(++i, "--file");
41310
+ groupSeen.push("--file");
41311
+ } else if (arg.startsWith("--file=")) {
41312
+ file = arg.slice("--file=".length);
41313
+ groupSeen.push("--file");
41314
+ } else if (arg === "--scan-dir") {
41315
+ scan_dir2 = need(++i, "--scan-dir");
41316
+ groupSeen.push("--scan-dir");
41317
+ } else if (arg.startsWith("--scan-dir=")) {
41318
+ scan_dir2 = arg.slice("--scan-dir=".length);
41319
+ groupSeen.push("--scan-dir");
41320
+ } else if (arg === "-v" || arg === "--verbose") {
41321
+ verbose = true;
41322
+ } else if (arg === "--quiet") {
41323
+ } else if (arg === "-h" || arg === "--help") {
41324
+ process.stdout.write(USAGE3);
41325
+ process.exit(0);
41326
+ } else {
41327
+ _usage_error(`unrecognized arguments: ${arg}`);
41328
+ }
41329
+ }
41330
+ if (groupSeen.length === 0) {
41331
+ _usage_error("one of the arguments --stdin --file --scan-dir is required");
41332
+ }
41333
+ if (groupSeen.length > 1) {
41334
+ _usage_error(`argument ${groupSeen[1]}: not allowed with argument ${groupSeen[0]}`);
41335
+ }
41336
+ return { stdin, file, scan_dir: scan_dir2, verbose };
41337
+ }
41338
+ function main27(argv = process.argv.slice(2)) {
41339
+ const args = parse_args8(argv);
41340
+ if (args.scan_dir !== null) {
41341
+ return cmd_scan_dir(args.scan_dir);
41342
+ }
41343
+ let text;
41344
+ try {
41345
+ text = args.stdin ? _readStdin3() : fs81.readFileSync(args.file, "utf-8");
41346
+ } catch (e) {
41347
+ process.stderr.write(`error: ${String(e)}
41348
+ `);
41349
+ return 1;
41350
+ }
41351
+ const findings = check_reply(text);
41352
+ if (findings.length === 0) {
41353
+ if (args.verbose && !QUIET) {
41354
+ process.stdout.write("\u2705 reply consistent (every options block carries one adjacent recommendation)\n");
41355
+ }
41356
+ return 0;
41357
+ }
41358
+ for (const f of findings) {
41359
+ process.stderr.write(`\u274C line ${String(f.line)}: ${f.message}
41360
+ `);
41361
+ }
41362
+ return 2;
41363
+ }
41364
+ function _isCliEntry19() {
41365
+ if (true) {
41366
+ return false;
41367
+ }
41368
+ if (process.argv[1] === void 0) {
41369
+ return false;
41370
+ }
41371
+ const argvUrl = pathToFileURL24(path81.resolve(process.argv[1])).href;
41372
+ if (import.meta.url === argvUrl) {
41373
+ return true;
41374
+ }
41375
+ try {
41376
+ const here = fs81.realpathSync(fileURLToPath39(import.meta.url));
41377
+ const argv = fs81.realpathSync(path81.resolve(process.argv[1]));
41378
+ return here === argv;
41379
+ } catch {
41380
+ return false;
41381
+ }
41382
+ }
41383
+ var _HERE21, ROOT4, QUIET, OPTION_LINE_RE, REC_LINE_RE, TAG_RE, CODESPAN_RE, HEADING_RE, FENCE_RE2, REC_ADJACENCY_WINDOW, USAGE3, _IN_BUNDLE;
41384
+ var init_check_reply_consistency = __esm({
41385
+ "src/scripts/check_reply_consistency.ts"() {
41386
+ "use strict";
41387
+ init_agent_src();
41388
+ init_scan_scope();
41389
+ _HERE21 = fileURLToPath39(import.meta.url);
41390
+ ROOT4 = path81.resolve(path81.dirname(_HERE21), "..", "..");
41391
+ QUIET = process.argv.slice(2).includes("--quiet");
41392
+ OPTION_LINE_RE = /^\s*>?\s*(\d+)\.\s+\S/;
41393
+ REC_LINE_RE = /(?:Recommendation|Empfehlung)\s*:\s*(\d+)\b/i;
41394
+ TAG_RE = /\((?:recommended|rec|empfohlen)\)/i;
41395
+ CODESPAN_RE = /`[^`\n]*`/g;
41396
+ HEADING_RE = /^#{1,6}\s/;
41397
+ FENCE_RE2 = /^\s*(```|~~~)/;
41398
+ REC_ADJACENCY_WINDOW = 2;
41399
+ USAGE3 = "usage: check_reply_consistency [-h] (--stdin | --file FILE | --scan-dir SCAN_DIR)\n [-v] [--quiet]\n";
41400
+ _IN_BUNDLE = true;
41401
+ if (!_IN_BUNDLE && (_isCliEntry19() || process.argv[1] === _HERE21)) {
41402
+ process.exit(main27());
41403
+ }
41404
+ }
41405
+ });
41406
+
41407
+ // src/scripts/_lib/dropped_decision.ts
41408
+ function detectDroppedDecision(assistantTurnTexts, closingFromPayload = false) {
41409
+ if (assistantTurnTexts.length < 2) return null;
41410
+ const asksIn = (text) => {
41411
+ const blocks = find_option_blocks(text);
41412
+ if (blocks.length === 0) return blocks;
41413
+ const masked = splitAndMask(text);
41414
+ return blocks.filter((b) => recommendationsUnder(text, b, masked).length > 0);
41415
+ };
41416
+ const closing = assistantTurnTexts[assistantTurnTexts.length - 1];
41417
+ if (asksIn(closing).length > 0) return null;
41418
+ for (let i = assistantTurnTexts.length - 2; i >= 0; i -= 1) {
41419
+ const earlier = assistantTurnTexts[i];
41420
+ const blocks = asksIn(earlier);
41421
+ if (blocks.length === 0) continue;
41422
+ const block = blocks[blocks.length - 1];
41423
+ return {
41424
+ detector: "pending-decision",
41425
+ // The option NUMBERS and the line span, never the option text: the
41426
+ // evidence is quoted into a refusal that reaches the transcript, and
41427
+ // an options block can carry anything the reply carried.
41428
+ 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"})`,
41429
+ 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"
41430
+ };
41431
+ }
41432
+ return null;
41433
+ }
41434
+ var init_dropped_decision = __esm({
41435
+ "src/scripts/_lib/dropped_decision.ts"() {
41436
+ "use strict";
41437
+ init_check_reply_consistency();
41438
+ }
41439
+ });
41440
+
41441
+ // src/scripts/_lib/review_baseline.ts
41442
+ import { spawnSync as spawnSync13 } from "node:child_process";
41443
+ import * as fs82 from "node:fs";
41444
+ import * as path82 from "node:path";
41445
+ function currentHeadSha(cwd) {
41446
+ try {
41447
+ const r = spawnSync13("git", ["rev-parse", "HEAD"], { cwd, encoding: "utf8" });
41448
+ if (r.status !== 0) return null;
41449
+ const out = (r.stdout ?? "").trim();
41450
+ return out === "" ? null : out;
41451
+ } catch {
41452
+ return null;
41453
+ }
41454
+ }
41455
+ function baselineStateDir(workspaceRoot) {
41456
+ return path82.join(workspaceRoot, BASELINE_STATE_REL);
41457
+ }
41458
+ function baselineStateFile(workspaceRoot, sessionKey) {
41459
+ return path82.join(baselineStateDir(workspaceRoot), `${sessionKey}.json`);
41460
+ }
41461
+ function parseBaseline(raw) {
41462
+ let decoded;
41463
+ try {
41464
+ decoded = JSON.parse(raw);
41465
+ } catch {
41466
+ return null;
41467
+ }
41468
+ if (typeof decoded !== "object" || decoded === null || Array.isArray(decoded)) return null;
41469
+ const o = decoded;
41470
+ const lines = o["baseline_lines"];
41471
+ if (typeof lines !== "number" || !Number.isFinite(lines) || lines < 0) return null;
41472
+ const written = o["written_at"];
41473
+ if (typeof written !== "string") return null;
41474
+ const head = o["head_sha"];
41475
+ const measure = o["measure"];
41476
+ return {
41477
+ head_sha: typeof head === "string" && head !== "" ? head : null,
41478
+ baseline_lines: lines,
41479
+ ...measure === "exact" || measure === "capped_approximation" ? { measure } : {},
41480
+ written_at: written
41481
+ };
41482
+ }
41483
+ function readBaseline(workspaceRoot, sessionKey) {
41484
+ const file = baselineStateFile(workspaceRoot, sessionKey);
41485
+ let raw;
41486
+ try {
41487
+ raw = fs82.readFileSync(file, "utf-8");
41488
+ } catch (exc) {
41489
+ const code = exc?.code;
41490
+ return code === "ENOENT" ? "absent" : "unreadable";
41491
+ }
41492
+ return parseBaseline(raw) ?? "unreadable";
41493
+ }
41494
+ function applyBaseline(measuredLines, baseline, headSha, measuredMeasure = "exact") {
41495
+ if (baseline === "absent" || baseline === "unreadable") {
41496
+ return { applied: false, fallback: baseline, lines: measuredLines };
41497
+ }
41498
+ if (baseline.measure !== "exact" || measuredMeasure !== "exact") {
41499
+ return { applied: false, fallback: "mixed-measure", lines: measuredLines };
41500
+ }
41501
+ if (baseline.head_sha !== headSha()) {
41502
+ return { applied: false, fallback: "head-moved", lines: measuredLines };
41503
+ }
41504
+ return {
41505
+ applied: true,
41506
+ baseline,
41507
+ lines: Math.max(0, measuredLines - baseline.baseline_lines)
41508
+ };
41509
+ }
41510
+ var BASELINE_STATE_REL;
41511
+ var init_review_baseline = __esm({
41512
+ "src/scripts/_lib/review_baseline.ts"() {
41513
+ "use strict";
41514
+ BASELINE_STATE_REL = path82.join("agents", "runtime", "state", "review-baseline");
41515
+ }
41516
+ });
41517
+
40757
41518
  // src/scripts/_lib/audit_field_provenance.ts
40758
41519
  function appliedIds(values) {
40759
41520
  const out = [];
@@ -40787,6 +41548,9 @@ function buildReviewSkippedLine(input) {
40787
41548
  }
40788
41549
  if (!input.ts) errors.push("ts (ISO-8601 UTC) is required");
40789
41550
  if (!input.id) errors.push("id (ULID, UUID, or content hash) is required");
41551
+ if (input.baseline !== void 0 && !BASELINE_APPLICATIONS.includes(input.baseline)) {
41552
+ errors.push(`baseline must be one of ${BASELINE_APPLICATIONS.join(", ")}`);
41553
+ }
40790
41554
  if (errors.length) return { line: null, errors };
40791
41555
  const line = {
40792
41556
  schema_version: 1,
@@ -40813,15 +41577,29 @@ function buildReviewSkippedLine(input) {
40813
41577
  persona: null,
40814
41578
  input_kind: "prompt",
40815
41579
  type: "note",
40816
- review_skipped: { diff_lines: input.diff_lines, mutation_measure: input.mutation_measure }
41580
+ review_skipped: {
41581
+ diff_lines: input.diff_lines,
41582
+ mutation_measure: input.mutation_measure,
41583
+ // Omitted, not defaulted, when the producer recorded nothing —
41584
+ // audit-log-v1's absent-versus-present split is the same one
41585
+ // `skills_applied` uses above, for the same reason.
41586
+ ...input.baseline === void 0 ? {} : { baseline: input.baseline }
41587
+ }
40817
41588
  };
40818
41589
  return { line, errors: [] };
40819
41590
  }
40820
- var PRODUCER_PRIVACY_CLASS, HIGH_RISK_DIFF_LINES;
41591
+ var BASELINE_APPLICATIONS, PRODUCER_PRIVACY_CLASS, HIGH_RISK_DIFF_LINES;
40821
41592
  var init_review_skipped_record = __esm({
40822
41593
  "src/scripts/_lib/review_skipped_record.ts"() {
40823
41594
  "use strict";
40824
41595
  init_audit_field_provenance();
41596
+ BASELINE_APPLICATIONS = [
41597
+ "applied",
41598
+ "absent",
41599
+ "unreadable",
41600
+ "head_moved",
41601
+ "mixed_measure"
41602
+ ];
40825
41603
  PRODUCER_PRIVACY_CLASS = "ids-only";
40826
41604
  HIGH_RISK_DIFF_LINES = 200;
40827
41605
  }
@@ -40888,24 +41666,24 @@ var init_envelope = __esm({
40888
41666
  });
40889
41667
 
40890
41668
  // src/scripts/hooks/end_review_nudge_hook.ts
40891
- import { spawnSync as spawnSync13 } from "node:child_process";
41669
+ import { spawnSync as spawnSync14 } from "node:child_process";
40892
41670
  import * as crypto7 from "node:crypto";
40893
- import * as fs81 from "node:fs";
41671
+ import * as fs83 from "node:fs";
40894
41672
  import * as os16 from "node:os";
40895
- import * as path81 from "node:path";
40896
- import { fileURLToPath as fileURLToPath39, pathToFileURL as pathToFileURL24 } from "node:url";
41673
+ import * as path83 from "node:path";
41674
+ import { fileURLToPath as fileURLToPath40, pathToFileURL as pathToFileURL25 } from "node:url";
40897
41675
  function isSafeTranscriptPath(rawPath, opts = {}) {
40898
41676
  if (!rawPath || !/\.jsonl$/i.test(rawPath)) return false;
40899
41677
  const homeDir = opts.homeDir ?? os16.homedir();
40900
41678
  const maxBytes = opts.maxBytes ?? TRANSCRIPT_SCAN_MAX_BYTES;
40901
41679
  try {
40902
- const realHome = fs81.realpathSync(homeDir);
40903
- const realPath = fs81.realpathSync(rawPath);
40904
- const relative21 = path81.relative(realHome, realPath);
40905
- if (relative21 === "" || relative21.startsWith("..") || path81.isAbsolute(relative21)) {
41680
+ const realHome = fs83.realpathSync(homeDir);
41681
+ const realPath = fs83.realpathSync(rawPath);
41682
+ const relative22 = path83.relative(realHome, realPath);
41683
+ if (relative22 === "" || relative22.startsWith("..") || path83.isAbsolute(relative22)) {
40906
41684
  return false;
40907
41685
  }
40908
- const { size } = fs81.statSync(realPath);
41686
+ const { size } = fs83.statSync(realPath);
40909
41687
  return size <= maxBytes;
40910
41688
  } catch {
40911
41689
  return false;
@@ -40934,7 +41712,7 @@ function nonDocMutatedLines(rows) {
40934
41712
  }
40935
41713
  function gitNumstatRows(cwd) {
40936
41714
  try {
40937
- const r = spawnSync13("git", ["diff", "--numstat", "HEAD"], {
41715
+ const r = spawnSync14("git", ["diff", "--numstat", "HEAD"], {
40938
41716
  cwd,
40939
41717
  encoding: "utf8",
40940
41718
  maxBuffer: 16 * 1024 * 1024
@@ -40947,7 +41725,7 @@ function gitNumstatRows(cwd) {
40947
41725
  }
40948
41726
  function untrackedNonDocFiles(cwd) {
40949
41727
  try {
40950
- const r = spawnSync13("git", ["ls-files", "--others", "--exclude-standard"], {
41728
+ const r = spawnSync14("git", ["ls-files", "--others", "--exclude-standard"], {
40951
41729
  cwd,
40952
41730
  encoding: "utf8",
40953
41731
  maxBuffer: 16 * 1024 * 1024
@@ -40960,13 +41738,13 @@ function untrackedNonDocFiles(cwd) {
40960
41738
  }
40961
41739
  function untrackedFileLineCount(cwd, relPath) {
40962
41740
  try {
40963
- const abs = path81.resolve(cwd, relPath);
40964
- const size = fs81.statSync(abs).size;
41741
+ const abs = path83.resolve(cwd, relPath);
41742
+ const size = fs83.statSync(abs).size;
40965
41743
  if (size === 0) return 0;
40966
41744
  if (size > UNTRACKED_FILE_READ_CAP_BYTES) {
40967
41745
  return MUTATION_LINE_THRESHOLD + 1;
40968
41746
  }
40969
- const buf = fs81.readFileSync(abs);
41747
+ const buf = fs83.readFileSync(abs);
40970
41748
  if (buf.length === 0) return 0;
40971
41749
  const probe = buf.subarray(0, Math.min(buf.length, BINARY_PROBE_BYTES));
40972
41750
  if (probe.includes(0)) return 0;
@@ -41041,30 +41819,31 @@ function scanTranscriptForReviewer(transcriptText) {
41041
41819
  function buildAdvisoryLine(diffLines) {
41042
41820
  return `this session mutated ${diffLines} lines without a neutral review; spawn a cross-model reviewer before claiming done (delegation-policy / verify-budget)`;
41043
41821
  }
41044
- function appendReviewSkippedTelemetry(workspaceRoot, diffLines, mutationMeasure) {
41822
+ function appendReviewSkippedTelemetry(workspaceRoot, diffLines, mutationMeasure, baseline) {
41045
41823
  if (is_replay_mode()) return;
41046
41824
  const ts = (/* @__PURE__ */ new Date()).toISOString();
41047
41825
  const { line, errors } = buildReviewSkippedLine({
41048
41826
  diff_lines: diffLines,
41049
41827
  mutation_measure: mutationMeasure,
41050
41828
  ts,
41051
- id: crypto7.randomUUID()
41829
+ id: crypto7.randomUUID(),
41830
+ baseline
41052
41831
  });
41053
41832
  if (errors.length || line === null) return;
41054
41833
  try {
41055
- const dir = path81.join(workspaceRoot, "agents", "runtime", "state", "audit");
41056
- fs81.mkdirSync(dir, { recursive: true });
41057
- const file = path81.join(dir, `${ts.slice(0, 7)}.jsonl`);
41058
- fs81.appendFileSync(file, `${JSON.stringify(line)}
41834
+ const dir = path83.join(workspaceRoot, "agents", "runtime", "state", "audit");
41835
+ fs83.mkdirSync(dir, { recursive: true });
41836
+ const file = path83.join(dir, `${ts.slice(0, 7)}.jsonl`);
41837
+ fs83.appendFileSync(file, `${JSON.stringify(line)}
41059
41838
  `, "utf8");
41060
41839
  } catch {
41061
41840
  }
41062
41841
  }
41063
41842
  function sessionStateDir(workspaceRoot) {
41064
- return path81.join(workspaceRoot, "agents", "runtime", "state", "end-review-nudge");
41843
+ return path83.join(workspaceRoot, "agents", "runtime", "state", "end-review-nudge");
41065
41844
  }
41066
41845
  function sessionStateFile(workspaceRoot, sessionKey) {
41067
- return path81.join(sessionStateDir(workspaceRoot), `${sessionKey}.json`);
41846
+ return path83.join(sessionStateDir(workspaceRoot), `${sessionKey}.json`);
41068
41847
  }
41069
41848
  function deriveSessionKey(envelope, payload) {
41070
41849
  const raw = str2(envelope["session_id"]) || str2(payload["transcript_path"] ?? payload["transcriptPath"]);
@@ -41073,7 +41852,7 @@ function deriveSessionKey(envelope, payload) {
41073
41852
  }
41074
41853
  function hasFiredThisSession(workspaceRoot, sessionKey) {
41075
41854
  try {
41076
- return fs81.existsSync(sessionStateFile(workspaceRoot, sessionKey));
41855
+ return fs83.existsSync(sessionStateFile(workspaceRoot, sessionKey));
41077
41856
  } catch {
41078
41857
  return false;
41079
41858
  }
@@ -41087,26 +41866,39 @@ function markFiredThisSession(workspaceRoot, sessionKey, ts) {
41087
41866
  function _read_stdin() {
41088
41867
  return readHookStdin();
41089
41868
  }
41090
- function main27() {
41869
+ function main28() {
41091
41870
  const [envelope, payload] = unwrap(_read_stdin(), "claude");
41092
41871
  const event = String(envelope["event"] ?? "");
41093
41872
  if (event !== "" && event !== "stop") {
41094
41873
  return 0;
41095
41874
  }
41096
41875
  const workspace_root = String(envelope["workspace_root"] ?? "").trim() || process.cwd();
41097
- let diffLines;
41876
+ let measuredLines;
41098
41877
  let mutationMeasure;
41099
41878
  try {
41100
41879
  const measured = totalNonDocMutatedLinesWithMeasure(workspace_root);
41101
- diffLines = measured.lines;
41880
+ measuredLines = measured.lines;
41102
41881
  mutationMeasure = measured.measure;
41103
41882
  } catch {
41104
41883
  return 0;
41105
41884
  }
41885
+ const sessionKey = deriveSessionKey(envelope, payload);
41886
+ const baselineOutcome = applyBaseline(
41887
+ measuredLines,
41888
+ readBaseline(workspace_root, sessionKey),
41889
+ // A THUNK, not a value: on the `absent` and `unreadable` branches the
41890
+ // result is discarded, and those two are the steady state on every host
41891
+ // without this nudge and on every session before its first baseline
41892
+ // write. Passing the value eagerly spent an 11-14 ms `git rev-parse` on
41893
+ // each of those stops for nothing.
41894
+ () => currentHeadSha(workspace_root),
41895
+ mutationMeasure
41896
+ );
41897
+ const diffLines = baselineOutcome.lines;
41898
+ const baselineApplication = baselineOutcome.applied ? "applied" : FALLBACK_TO_TELEMETRY[baselineOutcome.fallback];
41106
41899
  if (diffLines <= MUTATION_LINE_THRESHOLD) {
41107
41900
  return 0;
41108
41901
  }
41109
- const sessionKey = deriveSessionKey(envelope, payload);
41110
41902
  if (hasFiredThisSession(workspace_root, sessionKey)) {
41111
41903
  return 0;
41112
41904
  }
@@ -41116,7 +41908,7 @@ function main27() {
41116
41908
  let reviewerRan = false;
41117
41909
  if (transcriptPath && isSafeTranscriptPath(transcriptPath)) {
41118
41910
  try {
41119
- reviewerRan = scanTranscriptForReviewer(fs81.readFileSync(transcriptPath, "utf-8"));
41911
+ reviewerRan = scanTranscriptForReviewer(fs83.readFileSync(transcriptPath, "utf-8"));
41120
41912
  } catch {
41121
41913
  reviewerRan = false;
41122
41914
  }
@@ -41126,7 +41918,12 @@ function main27() {
41126
41918
  }
41127
41919
  markFiredThisSession(workspace_root, sessionKey, (/* @__PURE__ */ new Date()).toISOString());
41128
41920
  try {
41129
- appendReviewSkippedTelemetry(workspace_root, diffLines, mutationMeasure);
41921
+ appendReviewSkippedTelemetry(
41922
+ workspace_root,
41923
+ diffLines,
41924
+ mutationMeasure,
41925
+ baselineApplication
41926
+ );
41130
41927
  } catch {
41131
41928
  }
41132
41929
  process.stdout.write(
@@ -41139,29 +41936,30 @@ function main27() {
41139
41936
  );
41140
41937
  return EXIT_WARN2;
41141
41938
  }
41142
- function _isCliEntry19() {
41939
+ function _isCliEntry20() {
41143
41940
  if (true) {
41144
41941
  return false;
41145
41942
  }
41146
41943
  if (process.argv[1] === void 0) {
41147
41944
  return false;
41148
41945
  }
41149
- const argvUrl = pathToFileURL24(path81.resolve(process.argv[1])).href;
41946
+ const argvUrl = pathToFileURL25(path83.resolve(process.argv[1])).href;
41150
41947
  if (import.meta.url === argvUrl) {
41151
41948
  return true;
41152
41949
  }
41153
41950
  try {
41154
- const here = fs81.realpathSync(fileURLToPath39(import.meta.url));
41155
- const argv = fs81.realpathSync(path81.resolve(process.argv[1]));
41951
+ const here = fs83.realpathSync(fileURLToPath40(import.meta.url));
41952
+ const argv = fs83.realpathSync(path83.resolve(process.argv[1]));
41156
41953
  return here === argv;
41157
41954
  } catch {
41158
41955
  return false;
41159
41956
  }
41160
41957
  }
41161
- var MUTATION_LINE_THRESHOLD, UNTRACKED_FILE_CAP, TRANSCRIPT_SCAN_MAX_BYTES, EXIT_WARN2, DOC_PATH_RE, BINARY_PROBE_BYTES, UNTRACKED_FILE_READ_CAP_BYTES, DISPATCH_TOOL_RE, REVIEW_SHAPED_LABEL_RE, REVIEW_SHAPED_PROMPT_RE, REVIEW_SKILL_NAME_RE;
41958
+ var MUTATION_LINE_THRESHOLD, UNTRACKED_FILE_CAP, TRANSCRIPT_SCAN_MAX_BYTES, EXIT_WARN2, DOC_PATH_RE, BINARY_PROBE_BYTES, UNTRACKED_FILE_READ_CAP_BYTES, DISPATCH_TOOL_RE, REVIEW_SHAPED_LABEL_RE, REVIEW_SHAPED_PROMPT_RE, REVIEW_SKILL_NAME_RE, FALLBACK_TO_TELEMETRY;
41162
41959
  var init_end_review_nudge_hook = __esm({
41163
41960
  "src/scripts/hooks/end_review_nudge_hook.ts"() {
41164
41961
  "use strict";
41962
+ init_review_baseline();
41165
41963
  init_review_skipped_record();
41166
41964
  init_envelope();
41167
41965
  init_hook_stdin();
@@ -41177,8 +41975,14 @@ var init_end_review_nudge_hook = __esm({
41177
41975
  REVIEW_SHAPED_LABEL_RE = /\b(review|judge|adversarial|critique|second[- ]opinion|blind\s+(pass|review)|cross-model)\b/i;
41178
41976
  REVIEW_SHAPED_PROMPT_RE = /\b(code\s+review|neutral\s+review|adversarial|judge|critique|second[- ]opinion|blind\s+(pass|review)|cross-model)\b/i;
41179
41977
  REVIEW_SKILL_NAME_RE = /^(review[-:]changes|judge[-:][a-z0-9-]+|adversarial-review|code-review)$/i;
41180
- if (_isCliEntry19()) {
41181
- process.exit(main27());
41978
+ FALLBACK_TO_TELEMETRY = {
41979
+ absent: "absent",
41980
+ unreadable: "unreadable",
41981
+ "head-moved": "head_moved",
41982
+ "mixed-measure": "mixed_measure"
41983
+ };
41984
+ if (_isCliEntry20()) {
41985
+ process.exit(main28());
41182
41986
  }
41183
41987
  }
41184
41988
  });
@@ -41331,9 +42135,9 @@ var init_subagent_response = __esm({
41331
42135
 
41332
42136
  // src/scripts/hooks/subagent_ledger_hook.ts
41333
42137
  import * as crypto8 from "node:crypto";
41334
- import * as fs82 from "node:fs";
41335
- import * as path82 from "node:path";
41336
- import { fileURLToPath as fileURLToPath40, pathToFileURL as pathToFileURL25 } from "node:url";
42138
+ import * as fs84 from "node:fs";
42139
+ import * as path84 from "node:path";
42140
+ import { fileURLToPath as fileURLToPath41, pathToFileURL as pathToFileURL26 } from "node:url";
41337
42141
  function isObject2(v) {
41338
42142
  return typeof v === "object" && v !== null && !Array.isArray(v);
41339
42143
  }
@@ -41424,10 +42228,10 @@ function _jsonObjectCandidates(message) {
41424
42228
  return out;
41425
42229
  }
41426
42230
  function openDir(root) {
41427
- return path82.join(root, LEDGER_DIR, OPEN_SUBDIR);
42231
+ return path84.join(root, LEDGER_DIR, OPEN_SUBDIR);
41428
42232
  }
41429
42233
  function openFile(root, ref) {
41430
- return path82.join(openDir(root), `${ref}.json`);
42234
+ return path84.join(openDir(root), `${ref}.json`);
41431
42235
  }
41432
42236
  function _asOpenRecord(value, expectedRef) {
41433
42237
  if (!isObject2(value)) return null;
@@ -41453,7 +42257,7 @@ function readOpenRecords(root) {
41453
42257
  const out = /* @__PURE__ */ new Map();
41454
42258
  let names;
41455
42259
  try {
41456
- names = fs82.readdirSync(openDir(root));
42260
+ names = fs84.readdirSync(openDir(root));
41457
42261
  } catch {
41458
42262
  return out;
41459
42263
  }
@@ -41461,7 +42265,7 @@ function readOpenRecords(root) {
41461
42265
  if (!name.endsWith(".json")) continue;
41462
42266
  const expectedRef = name.slice(0, -".json".length);
41463
42267
  try {
41464
- const raw = fs82.readFileSync(path82.join(openDir(root), name), "utf8");
42268
+ const raw = fs84.readFileSync(path84.join(openDir(root), name), "utf8");
41465
42269
  const rec = _asOpenRecord(JSON.parse(raw), expectedRef);
41466
42270
  if (rec) out.set(rec.ref, rec);
41467
42271
  } catch {
@@ -41476,13 +42280,13 @@ function resolveDepth(parentRef, open) {
41476
42280
  return { depth: parent.depth + 1, depth_basis: "observed" };
41477
42281
  }
41478
42282
  function ledgerFileFor2(root, ts) {
41479
- return path82.join(root, LEDGER_DIR, `${ts.slice(0, 7)}.jsonl`);
42283
+ return path84.join(root, LEDGER_DIR, `${ts.slice(0, 7)}.jsonl`);
41480
42284
  }
41481
42285
  function appendLedgerLine(root, ts, line) {
41482
42286
  if (is_replay_mode()) return;
41483
42287
  const file = ledgerFileFor2(root, ts);
41484
- fs82.mkdirSync(path82.dirname(file), { recursive: true });
41485
- fs82.appendFileSync(file, `${JSON.stringify(line)}
42288
+ fs84.mkdirSync(path84.dirname(file), { recursive: true });
42289
+ fs84.appendFileSync(file, `${JSON.stringify(line)}
41486
42290
  `, "utf8");
41487
42291
  }
41488
42292
  function armsExceeded(elapsedMs) {
@@ -41490,7 +42294,7 @@ function armsExceeded(elapsedMs) {
41490
42294
  return WALL_CLOCK_ARMS_MS.filter((a) => elapsedMs >= a.ms).map((a) => a.label);
41491
42295
  }
41492
42296
  function openRecordStats(root, nowMs = Date.now()) {
41493
- const ledgerPresent = fs82.existsSync(path82.join(root, LEDGER_DIR));
42297
+ const ledgerPresent = fs84.existsSync(path84.join(root, LEDGER_DIR));
41494
42298
  const open = readOpenRecords(root);
41495
42299
  let maxDepth = 0;
41496
42300
  let counted = 0;
@@ -41518,13 +42322,13 @@ function writeOpenRecord(root, rec) {
41518
42322
  function removeOpenRecord(root, ref) {
41519
42323
  if (is_replay_mode()) return;
41520
42324
  try {
41521
- fs82.unlinkSync(openFile(root, ref));
42325
+ fs84.unlinkSync(openFile(root, ref));
41522
42326
  } catch {
41523
42327
  }
41524
42328
  }
41525
42329
  function countOpen(root) {
41526
42330
  try {
41527
- return fs82.readdirSync(openDir(root)).filter((n) => n.endsWith(".json")).length;
42331
+ return fs84.readdirSync(openDir(root)).filter((n) => n.endsWith(".json")).length;
41528
42332
  } catch {
41529
42333
  return 0;
41530
42334
  }
@@ -41675,7 +42479,7 @@ function resolveConsumerRoot(envelope) {
41675
42479
  }
41676
42480
  return process.cwd();
41677
42481
  }
41678
- function main28() {
42482
+ function main29() {
41679
42483
  const raw = readHookStdin();
41680
42484
  let envelope = {};
41681
42485
  try {
@@ -41685,15 +42489,15 @@ function main28() {
41685
42489
  }
41686
42490
  return processEnvelope(envelope, resolveConsumerRoot(envelope));
41687
42491
  }
41688
- function _isCliEntry20() {
42492
+ function _isCliEntry21() {
41689
42493
  if (true) {
41690
42494
  return false;
41691
42495
  }
41692
42496
  if (process.argv[1] === void 0) return false;
41693
- const argvUrl = pathToFileURL25(path82.resolve(process.argv[1])).href;
42497
+ const argvUrl = pathToFileURL26(path84.resolve(process.argv[1])).href;
41694
42498
  if (import.meta.url === argvUrl) return true;
41695
42499
  try {
41696
- return fs82.realpathSync(fileURLToPath40(import.meta.url)) === fs82.realpathSync(path82.resolve(process.argv[1]));
42500
+ return fs84.realpathSync(fileURLToPath41(import.meta.url)) === fs84.realpathSync(path84.resolve(process.argv[1]));
41697
42501
  } catch {
41698
42502
  return false;
41699
42503
  }
@@ -41706,7 +42510,7 @@ var init_subagent_ledger_hook = __esm({
41706
42510
  init_state_io();
41707
42511
  init_hook_stdin();
41708
42512
  EXIT_ALLOW3 = 0;
41709
- LEDGER_DIR = path82.join("agents", "runtime", "state", "subagent-ledger");
42513
+ LEDGER_DIR = path84.join("agents", "runtime", "state", "subagent-ledger");
41710
42514
  OPEN_SUBDIR = "open";
41711
42515
  OPEN_RECORD_TTL_MS = 24 * 60 * 60 * 1e3;
41712
42516
  DEPTH_BASES = /* @__PURE__ */ new Set(["observed", "asserted-parent", "assumed-root"]);
@@ -41716,24 +42520,26 @@ var init_subagent_ledger_hook = __esm({
41716
42520
  { label: "30m", ms: 30 * 60 * 1e3 },
41717
42521
  { label: "2h", ms: 2 * 60 * 60 * 1e3 }
41718
42522
  ];
41719
- if (_isCliEntry20()) process.exit(main28());
42523
+ if (_isCliEntry21()) process.exit(main29());
41720
42524
  }
41721
42525
  });
41722
42526
 
41723
42527
  // src/scripts/_lib/turn_end_refusals.ts
41724
42528
  import * as crypto9 from "node:crypto";
41725
- import * as path83 from "node:path";
42529
+ import * as path85 from "node:path";
41726
42530
  function refusalStateDir(workspaceRoot) {
41727
- return path83.join(workspaceRoot, REFUSAL_STATE_REL);
42531
+ return path85.join(workspaceRoot, REFUSAL_STATE_REL);
41728
42532
  }
41729
42533
  function deriveSessionKey2(sessionId) {
41730
42534
  return crypto9.createHash("sha256").update(sessionId).digest("hex").slice(0, 32);
41731
42535
  }
41732
42536
  function sessionRefusalFile(workspaceRoot, sessionKey) {
41733
- return path83.join(refusalStateDir(workspaceRoot), `${sessionKey}.json`);
42537
+ return path85.join(refusalStateDir(workspaceRoot), `${sessionKey}.json`);
41734
42538
  }
41735
42539
  function emptyCounts() {
41736
- return { promissory: 0, language: 0, verification: 0, completion: 0 };
42540
+ const out = {};
42541
+ for (const id of DETECTOR_IDS) out[id] = 0;
42542
+ return out;
41737
42543
  }
41738
42544
  function isDetector(v) {
41739
42545
  return typeof v === "string" && DETECTOR_IDS.includes(v);
@@ -41759,6 +42565,9 @@ function parseRecord(raw) {
41759
42565
  if (typeof o["agent_config_version"] === "string") {
41760
42566
  rec.agent_config_version = o["agent_config_version"];
41761
42567
  }
42568
+ if (typeof o["refused_prompt_id"] === "string") {
42569
+ rec.refused_prompt_id = o["refused_prompt_id"];
42570
+ }
41762
42571
  const counts2 = o["counts"];
41763
42572
  if (typeof counts2 === "object" && counts2 !== null && !Array.isArray(counts2)) {
41764
42573
  const parsed = {};
@@ -41802,6 +42611,9 @@ function foldRefusal(prev, input) {
41802
42611
  else if (prev?.agent_config_version !== void 0) {
41803
42612
  rec.agent_config_version = prev.agent_config_version;
41804
42613
  }
42614
+ if (input.promptId !== void 0 && input.promptId !== "") {
42615
+ rec.refused_prompt_id = input.promptId;
42616
+ }
41805
42617
  return rec;
41806
42618
  }
41807
42619
  function readInstallBoundary() {
@@ -41825,16 +42637,18 @@ var init_turn_end_refusals = __esm({
41825
42637
  "promissory",
41826
42638
  "language",
41827
42639
  "verification",
41828
- "completion"
42640
+ "completion",
42641
+ "pending-decision",
42642
+ "untested"
41829
42643
  ];
41830
- REFUSAL_STATE_REL = path83.join("agents", "runtime", "state", "turn-end-gate");
42644
+ REFUSAL_STATE_REL = path85.join("agents", "runtime", "state", "turn-end-gate");
41831
42645
  }
41832
42646
  });
41833
42647
 
41834
42648
  // src/scripts/hooks/turn_end_gate_hook.ts
41835
- import * as fs83 from "node:fs";
41836
- import * as path84 from "node:path";
41837
- import { fileURLToPath as fileURLToPath41, pathToFileURL as pathToFileURL26 } from "node:url";
42649
+ import * as fs85 from "node:fs";
42650
+ import * as path86 from "node:path";
42651
+ import { fileURLToPath as fileURLToPath42, pathToFileURL as pathToFileURL27 } from "node:url";
41838
42652
  function stripFencedBlocks(text) {
41839
42653
  const out = [];
41840
42654
  let open = null;
@@ -41891,7 +42705,7 @@ function detectPromissory(reply) {
41891
42705
  function readCiSettled(workspaceRoot, session_id) {
41892
42706
  if (!hasStableSessionId(session_id)) return { seen: false, settled: false };
41893
42707
  try {
41894
- const raw = fs83.readFileSync(path84.join(workspaceRoot, statePathFor2(session_id)), "utf-8");
42708
+ const raw = fs85.readFileSync(path86.join(workspaceRoot, statePathFor2(session_id)), "utf-8");
41895
42709
  const decoded = JSON.parse(raw);
41896
42710
  if (!owns_session_state(decoded, session_id)) return { seen: false, settled: false };
41897
42711
  if (typeof decoded === "object" && decoded !== null && !Array.isArray(decoded)) {
@@ -41925,8 +42739,8 @@ function detectCompletionClaim(reply, ci) {
41925
42739
  function readLanguagePin(workspaceRoot, session_id) {
41926
42740
  if (!hasStableSessionId(session_id)) return "und";
41927
42741
  try {
41928
- const raw = fs83.readFileSync(
41929
- path84.join(workspaceRoot, statePathFor(session_id)),
42742
+ const raw = fs85.readFileSync(
42743
+ path86.join(workspaceRoot, statePathFor(session_id)),
41930
42744
  "utf-8"
41931
42745
  );
41932
42746
  const decoded = JSON.parse(raw);
@@ -41975,12 +42789,34 @@ function detectUnverifiedEdit(toolCalls) {
41975
42789
  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)"
41976
42790
  };
41977
42791
  }
42792
+ function _isTestPath(p) {
42793
+ return _TEST_PATH_RE.test(p) || _TEST_FILE_RE.test(p);
42794
+ }
42795
+ function _isProductionSource(p) {
42796
+ return _SOURCE_RE.test(p) && !_isTestPath(p);
42797
+ }
42798
+ function detectUntestedChange(reply, toolCalls) {
42799
+ const edited = toolCalls.filter((c) => _EDIT_TOOLS.has(c.name) && c.path !== void 0).map((c) => c.path);
42800
+ const source = edited.filter(_isProductionSource);
42801
+ if (source.length === 0) return null;
42802
+ if (edited.some(_isTestPath)) return null;
42803
+ const prose = visibleProse(reply);
42804
+ const m = _COMPLETION_RE.exec(prose);
42805
+ if (!m) return null;
42806
+ if (_NEGATED_CLAIM_RE.test(_lineAround(prose, m.index))) return null;
42807
+ const shown = source.slice(0, 3).join(", ");
42808
+ return {
42809
+ detector: "untested",
42810
+ evidence: shown + (source.length > 3 ? ` (+${String(source.length - 3)} more)` : ""),
42811
+ 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"
42812
+ };
42813
+ }
41978
42814
  function sessionStateFile2(workspaceRoot, sessionKey) {
41979
42815
  return sessionRefusalFile(workspaceRoot, sessionKey);
41980
42816
  }
41981
42817
  function alreadyRefusedTurn(workspaceRoot, sessionKey, turnOrdinal) {
41982
42818
  try {
41983
- const raw = fs83.readFileSync(sessionStateFile2(workspaceRoot, sessionKey), "utf-8");
42819
+ const raw = fs85.readFileSync(sessionStateFile2(workspaceRoot, sessionKey), "utf-8");
41984
42820
  const decoded = JSON.parse(raw);
41985
42821
  if (typeof decoded === "object" && decoded !== null && !Array.isArray(decoded)) {
41986
42822
  return decoded["refused_turn"] === turnOrdinal;
@@ -41989,12 +42825,12 @@ function alreadyRefusedTurn(workspaceRoot, sessionKey, turnOrdinal) {
41989
42825
  }
41990
42826
  return false;
41991
42827
  }
41992
- function markRefusedTurn(workspaceRoot, sessionKey, turnOrdinal, detectors) {
42828
+ function markRefusedTurn(workspaceRoot, sessionKey, turnOrdinal, detectors, promptId) {
41993
42829
  if (is_replay_mode()) return;
41994
42830
  const file = sessionStateFile2(workspaceRoot, sessionKey);
41995
42831
  let prev = null;
41996
42832
  try {
41997
- prev = parseRecord(fs83.readFileSync(file, "utf-8"));
42833
+ prev = parseRecord(fs85.readFileSync(file, "utf-8"));
41998
42834
  } catch {
41999
42835
  }
42000
42836
  let version;
@@ -42010,27 +42846,34 @@ function markRefusedTurn(workspaceRoot, sessionKey, turnOrdinal, detectors) {
42010
42846
  detectors,
42011
42847
  turnOrdinal,
42012
42848
  at: (/* @__PURE__ */ new Date()).toISOString(),
42013
- version
42849
+ version,
42850
+ promptId
42014
42851
  })
42015
42852
  );
42016
42853
  } catch {
42017
42854
  }
42018
42855
  }
42019
42856
  function readTranscriptTail(transcriptPath, opts = {}) {
42020
- const empty = { lastAssistant: "", turnOrdinal: 0, toolCalls: [] };
42857
+ const empty = {
42858
+ lastAssistant: "",
42859
+ turnOrdinal: 0,
42860
+ toolCalls: [],
42861
+ assistantTurnTexts: []
42862
+ };
42021
42863
  if (!transcriptPath || !isSafeTranscriptPath(transcriptPath, opts)) return empty;
42022
42864
  let lines;
42023
42865
  try {
42024
- if (opts.maxBytes !== void 0 && fs83.statSync(transcriptPath).size > opts.maxBytes) {
42866
+ if (opts.maxBytes !== void 0 && fs85.statSync(transcriptPath).size > opts.maxBytes) {
42025
42867
  return empty;
42026
42868
  }
42027
- lines = fs83.readFileSync(transcriptPath, "utf-8").split("\n");
42869
+ lines = fs85.readFileSync(transcriptPath, "utf-8").split("\n");
42028
42870
  } catch {
42029
42871
  return empty;
42030
42872
  }
42031
42873
  let lastAssistant = "";
42032
42874
  let turnOrdinal = 0;
42033
42875
  let toolCalls = [];
42876
+ let assistantTurnTexts = [];
42034
42877
  for (const rawLine of lines) {
42035
42878
  const line = rawLine.trim();
42036
42879
  if (!line) continue;
@@ -42049,20 +42892,27 @@ function readTranscriptTail(transcriptPath, opts = {}) {
42049
42892
  if (typeof msg !== "object" || msg === null || Array.isArray(msg)) continue;
42050
42893
  const content = msg["content"];
42051
42894
  if (role === "assistant") {
42052
- toolCalls.push(..._toolCalls(content));
42895
+ toolCalls.push(...extractToolCalls(content));
42053
42896
  }
42054
42897
  const text = _messageText(content);
42055
42898
  if (text === null) continue;
42056
42899
  if (role === "assistant") {
42057
42900
  lastAssistant = text;
42901
+ assistantTurnTexts.push(text);
42058
42902
  } else if (!isSyntheticPrompt(text)) {
42059
42903
  turnOrdinal += 1;
42060
42904
  toolCalls = [];
42905
+ assistantTurnTexts = [];
42061
42906
  }
42062
42907
  }
42063
- return { lastAssistant: lastAssistant.trim(), turnOrdinal, toolCalls };
42908
+ return {
42909
+ lastAssistant: lastAssistant.trim(),
42910
+ turnOrdinal,
42911
+ toolCalls,
42912
+ assistantTurnTexts
42913
+ };
42064
42914
  }
42065
- function _toolCalls(content) {
42915
+ function extractToolCalls(content) {
42066
42916
  if (!Array.isArray(content)) return [];
42067
42917
  const out = [];
42068
42918
  for (const blk of content) {
@@ -42100,7 +42950,7 @@ function _messageText(content) {
42100
42950
  function str4(v) {
42101
42951
  return typeof v === "string" ? v : "";
42102
42952
  }
42103
- function main29() {
42953
+ function main30() {
42104
42954
  let envelope;
42105
42955
  let payload;
42106
42956
  try {
@@ -42118,10 +42968,19 @@ function main29() {
42118
42968
  const transcriptPath = str4(
42119
42969
  payload["transcript_path"] ?? payload["transcriptPath"]
42120
42970
  );
42121
- const { lastAssistant, turnOrdinal, toolCalls } = readTranscriptTail(transcriptPath, {
42122
- maxBytes: TRANSCRIPT_READ_MAX_BYTES
42123
- });
42971
+ const { lastAssistant, turnOrdinal, toolCalls, assistantTurnTexts } = readTranscriptTail(
42972
+ transcriptPath,
42973
+ { maxBytes: TRANSCRIPT_READ_MAX_BYTES }
42974
+ );
42124
42975
  if (!lastAssistant) return EXIT_ALLOW4;
42976
+ const payloadClosing = str4(
42977
+ payload["last_assistant_message"] ?? payload["lastAssistantMessage"]
42978
+ );
42979
+ const closingFromPayload = payloadClosing !== "" && !assistantTurnTexts.includes(payloadClosing);
42980
+ const turnTexts = closingFromPayload ? [...assistantTurnTexts, payloadClosing] : assistantTurnTexts;
42981
+ const promptId = str4(
42982
+ payload["prompt_id"] ?? payload["promptId"]
42983
+ );
42125
42984
  const rawSessionId = str4(envelope["session_id"]) || "";
42126
42985
  const sessionKey = deriveSessionKey2(rawSessionId || "unknown-session");
42127
42986
  if (alreadyRefusedTurn(workspaceRoot, sessionKey, turnOrdinal)) return EXIT_ALLOW4;
@@ -42143,7 +43002,23 @@ function main29() {
42143
43002
  // gating is where the comment above says gating belongs — inside the
42144
43003
  // detector: no CI observed, or a settled read, or no completion claim
42145
43004
  // ⇒ no finding.
42146
- dispatchOpen ? null : detectCompletionClaim(lastAssistant, readCiSettled(workspaceRoot, rawSessionId))
43005
+ dispatchOpen ? null : detectCompletionClaim(lastAssistant, readCiSettled(workspaceRoot, rawSessionId)),
43006
+ // Detector E is UNCONDITIONAL, and that is the opposite choice from A
43007
+ // and D one line above rather than an oversight. An open dispatch
43008
+ // excuses a promissory closing because the work is genuinely still
43009
+ // running; it excuses nothing about a question the user was already
43010
+ // asked. Worse: a dispatch — or the `end-review-nudge` stop concern
43011
+ // that produced the measured failure — IS the continuation that drops
43012
+ // the decision, so narrowing E the same way would silence it in exactly
43013
+ // the case it exists for.
43014
+ detectDroppedDecision(turnTexts, closingFromPayload),
43015
+ // Detector F takes the OTHER side of that same question, and the two
43016
+ // sitting adjacent is the clearest place to say why. E fires on a
43017
+ // question already asked, which an open dispatch cannot excuse. F fires
43018
+ // on a completion CLAIM, and a turn waiting on a subagent has not
43019
+ // finished — so its closing is not the claim F is about. Same slot,
43020
+ // opposite trigger, opposite treatment of `dispatchOpen`.
43021
+ dispatchOpen ? null : detectUntestedChange(lastAssistant, toolCalls)
42147
43022
  ]) {
42148
43023
  if (f) findings.push(f);
42149
43024
  }
@@ -42152,7 +43027,8 @@ function main29() {
42152
43027
  workspaceRoot,
42153
43028
  sessionKey,
42154
43029
  turnOrdinal,
42155
- findings.map((f) => f.detector)
43030
+ findings.map((f) => f.detector),
43031
+ promptId
42156
43032
  );
42157
43033
  const lines = findings.map(
42158
43034
  (f) => ` \xB7 ${f.detector}: ${f.reason}
@@ -42161,37 +43037,38 @@ function main29() {
42161
43037
  process.stderr.write(
42162
43038
  `turn-end-gate: REFUSED \u2014 this turn is not finished.
42163
43039
  ${lines.join("\n")}
42164
- 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.
43040
+ 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.
42165
43041
  This turn will not be refused a second time.
42166
43042
  `
42167
43043
  );
42168
43044
  return EXIT_BLOCK;
42169
43045
  }
42170
- function _isCliEntry21() {
43046
+ function _isCliEntry22() {
42171
43047
  if (true) {
42172
43048
  return false;
42173
43049
  }
42174
43050
  if (process.argv[1] === void 0) {
42175
43051
  return false;
42176
43052
  }
42177
- const argvUrl = pathToFileURL26(path84.resolve(process.argv[1])).href;
43053
+ const argvUrl = pathToFileURL27(path86.resolve(process.argv[1])).href;
42178
43054
  if (import.meta.url === argvUrl) {
42179
43055
  return true;
42180
43056
  }
42181
43057
  try {
42182
- const here = fs83.realpathSync(fileURLToPath41(import.meta.url));
42183
- const argv = fs83.realpathSync(path84.resolve(process.argv[1]));
43058
+ const here = fs85.realpathSync(fileURLToPath42(import.meta.url));
43059
+ const argv = fs85.realpathSync(path86.resolve(process.argv[1]));
42184
43060
  return here === argv;
42185
43061
  } catch {
42186
43062
  return false;
42187
43063
  }
42188
43064
  }
42189
- var EXIT_BLOCK, EXIT_ALLOW4, TRANSCRIPT_READ_MAX_BYTES, PROMISSORY, HANDBACK, _COMPLETION_RE, _NEGATED_CLAIM_RE, _EDIT_TOOLS, _VERIFY_RE;
43065
+ var EXIT_BLOCK, EXIT_ALLOW4, TRANSCRIPT_READ_MAX_BYTES, PROMISSORY, HANDBACK, _COMPLETION_RE, _NEGATED_CLAIM_RE, _EDIT_TOOLS, _VERIFY_RE, _SOURCE_RE, _TEST_PATH_RE, _TEST_FILE_RE;
42190
43066
  var init_turn_end_gate_hook = __esm({
42191
43067
  "src/scripts/hooks/turn_end_gate_hook.ts"() {
42192
43068
  "use strict";
42193
43069
  init_language_mirror_hook();
42194
43070
  init_before_complete_hook();
43071
+ init_dropped_decision();
42195
43072
  init_end_review_nudge_hook();
42196
43073
  init_envelope();
42197
43074
  init_hook_stdin();
@@ -42252,17 +43129,41 @@ var init_turn_end_gate_hook = __esm({
42252
43129
  _NEGATED_CLAIM_RE = /\b(noch nicht|nicht fertig|nicht durch|wäre verfrüht|ist verfrüht|not yet|not done|isn'?t done|nein)\b/i;
42253
43130
  _EDIT_TOOLS = /* @__PURE__ */ new Set(["Edit", "Write", "MultiEdit", "NotebookEdit"]);
42254
43131
  _VERIFY_RE = /\b(test|tests|vitest|jest|pytest|phpunit|pest|tsc|eslint|ruff|mypy|pyright|clippy|phpstan|typecheck|lint[-_:a-z]*|build|ci|preflight|smoke[-_:a-z]*|check[-_:a-z]*|validate[-_:a-z]*)\b|\b(task|npm|pnpm|yarn|composer|cargo|go|make|php artisan|bun)\s+(run\s+)?\S*(test|check|lint|build|ci|typecheck)/i;
42255
- if (_isCliEntry21()) {
42256
- process.exit(main29());
43132
+ _SOURCE_RE = /\.(?:ts|tsx|js|jsx|mjs|cjs|vue|svelte|php|py|rb|go|rs|java|kt|swift|cs|scala|ex|exs)$/i;
43133
+ _TEST_PATH_RE = /(?:^|\/)(?:tests?|specs?|__tests__|__specs__|e2e|cypress|playwright|features)\//i;
43134
+ _TEST_FILE_RE = /(?:\.(?:test|spec)\.[a-z]+$)|(?:_test\.[a-z]+$)|(?:(?:^|\/)test_[^/]+$)|(?:Test\.php$)|(?:Spec\.php$)|(?:\.feature$)/i;
43135
+ if (_isCliEntry22()) {
43136
+ process.exit(main30());
42257
43137
  }
42258
43138
  }
42259
43139
  });
42260
43140
 
43141
+ // src/scripts/_lib/test_delta.ts
43142
+ function isCodePath(p) {
43143
+ const f = p.replace(/\\/g, "/");
43144
+ if (isTestPath(f)) return false;
43145
+ if (!/\.(ts|tsx|js|mjs|cjs)$/.test(f)) return false;
43146
+ if (f.endsWith(".d.ts")) return false;
43147
+ if (/^(dist|\.augment|\.claude|\.cursor|node_modules)\//.test(f)) return false;
43148
+ return /^(src|scripts)\//.test(f);
43149
+ }
43150
+ function isTestPath(p) {
43151
+ const f = p.replace(/\\/g, "/");
43152
+ if (/^tests\//.test(f)) return true;
43153
+ return /\.(test|spec)\.(ts|tsx|js|mjs|cjs)$/.test(f);
43154
+ }
43155
+ var init_test_delta = __esm({
43156
+ "src/scripts/_lib/test_delta.ts"() {
43157
+ "use strict";
43158
+ }
43159
+ });
43160
+
42261
43161
  // src/scripts/hooks/evidence_independence.ts
43162
+ import { spawnSync as spawnSync15 } from "node:child_process";
42262
43163
  import crypto10 from "node:crypto";
42263
- import fs84 from "node:fs";
42264
- import path85 from "node:path";
42265
- import { fileURLToPath as fileURLToPath42, pathToFileURL as pathToFileURL27 } from "node:url";
43164
+ import fs86 from "node:fs";
43165
+ import path87 from "node:path";
43166
+ import { fileURLToPath as fileURLToPath43, pathToFileURL as pathToFileURL28 } from "node:url";
42266
43167
  function _isObject6(v) {
42267
43168
  return typeof v === "object" && v !== null && !Array.isArray(v);
42268
43169
  }
@@ -42299,8 +43200,8 @@ function extractDispatch(envelope) {
42299
43200
  }
42300
43201
  function _ledgerStamp(consumer_root) {
42301
43202
  try {
42302
- const raw = fs84.readFileSync(
42303
- path85.join(consumer_root, "agents", "state", "git-authorization.json"),
43203
+ const raw = fs86.readFileSync(
43204
+ path87.join(consumer_root, "agents", "state", "git-authorization.json"),
42304
43205
  "utf8"
42305
43206
  );
42306
43207
  const d = JSON.parse(raw);
@@ -42311,7 +43212,7 @@ function _ledgerStamp(consumer_root) {
42311
43212
  }
42312
43213
  function _load2(target) {
42313
43214
  try {
42314
- const decoded = JSON.parse(fs84.readFileSync(target, "utf8"));
43215
+ const decoded = JSON.parse(fs86.readFileSync(target, "utf8"));
42315
43216
  if (_isObject6(decoded) && Array.isArray(decoded["evaluations"])) {
42316
43217
  return decoded;
42317
43218
  }
@@ -42356,6 +43257,31 @@ function decide(tool, prompt, priorEvaluations) {
42356
43257
  evaluations: priorEvaluations + 1
42357
43258
  };
42358
43259
  }
43260
+ function sameSessionTestFlag(command) {
43261
+ if (command === null || !/\bgit\b[^|;&]*\bcommit\b/.test(command)) return null;
43262
+ return SAME_SESSION_TEXT;
43263
+ }
43264
+ function touchesTestAndCode(paths) {
43265
+ return paths.some(isTestPath) && paths.some(isCodePath);
43266
+ }
43267
+ function _commandOf(envelope) {
43268
+ const payload = _isObject6(envelope["payload"]) ? envelope["payload"] : envelope;
43269
+ const input = _isObject6(payload["tool_input"]) ? payload["tool_input"] : payload;
43270
+ for (const key of ["command", "cmd", "shell_command"]) {
43271
+ const v = input[key];
43272
+ if (typeof v === "string" && v !== "") return v;
43273
+ }
43274
+ return null;
43275
+ }
43276
+ function _stagedPaths(consumer_root) {
43277
+ const r = spawnSync15("git", ["diff", "--cached", "--name-only"], {
43278
+ cwd: consumer_root,
43279
+ encoding: "utf8"
43280
+ });
43281
+ if (r.status !== 0) return null;
43282
+ const out = r.stdout.split("\n").map((s) => s.trim()).filter((s) => s !== "");
43283
+ return out.length === 0 ? null : out;
43284
+ }
42359
43285
  function run4(stdin_text, options) {
42360
43286
  let envelope = {};
42361
43287
  if (stdin_text.trim()) {
@@ -42368,7 +43294,7 @@ function run4(stdin_text, options) {
42368
43294
  return EXIT_ALLOW5;
42369
43295
  }
42370
43296
  }
42371
- const target = path85.join(options.consumer_root, STATE_FILE4);
43297
+ const target = path87.join(options.consumer_root, STATE_FILE4);
42372
43298
  const state = _load2(target);
42373
43299
  const session_id = typeof envelope["session_id"] === "string" ? envelope["session_id"] : "";
42374
43300
  const turnMarker = `${session_id}:${_ledgerStamp(options.consumer_root)}`;
@@ -42378,6 +43304,15 @@ function run4(stdin_text, options) {
42378
43304
  state.evaluations = [];
42379
43305
  }
42380
43306
  const [tool, prompt] = extractDispatch(envelope);
43307
+ const flag2 = sameSessionTestFlag(_commandOf(envelope));
43308
+ if (flag2 !== null) {
43309
+ const staged = _stagedPaths(options.consumer_root);
43310
+ if (staged !== null && touchesTestAndCode(staged)) {
43311
+ process.stdout.write(`${JSON.stringify({ decision: "warn", reason: flag2 })}
43312
+ `);
43313
+ return EXIT_ALLOW5;
43314
+ }
43315
+ }
42381
43316
  const decision = decide(tool, prompt, state.evaluations.length);
42382
43317
  if (decision.evaluations > state.evaluations.length) {
42383
43318
  state.evaluations.push({
@@ -42406,7 +43341,7 @@ function _errText3(err) {
42406
43341
  const t = err instanceof Error ? err.message : String(err);
42407
43342
  return t.replace(/\s+/g, " ").trim().slice(0, 200);
42408
43343
  }
42409
- function main30(argv) {
43344
+ function main31(argv) {
42410
43345
  const args = argv ?? process.argv.slice(2);
42411
43346
  let consumer_root = process.cwd();
42412
43347
  for (let i = 0; i < args.length; i += 1) {
@@ -42420,34 +43355,35 @@ function main30(argv) {
42420
43355
  }
42421
43356
  return run4(readHookStdin(), { consumer_root });
42422
43357
  }
42423
- function _isCliEntry22() {
43358
+ function _isCliEntry23() {
42424
43359
  if (true) {
42425
43360
  return false;
42426
43361
  }
42427
43362
  if (process.argv[1] === void 0) {
42428
43363
  return false;
42429
43364
  }
42430
- const argvUrl = pathToFileURL27(path85.resolve(process.argv[1])).href;
43365
+ const argvUrl = pathToFileURL28(path87.resolve(process.argv[1])).href;
42431
43366
  if (import.meta.url === argvUrl) {
42432
43367
  return true;
42433
43368
  }
42434
43369
  try {
42435
- const here = fs84.realpathSync(fileURLToPath42(import.meta.url));
42436
- const argv = fs84.realpathSync(path85.resolve(process.argv[1]));
43370
+ const here = fs86.realpathSync(fileURLToPath43(import.meta.url));
43371
+ const argv = fs86.realpathSync(path87.resolve(process.argv[1]));
42437
43372
  return here === argv;
42438
43373
  } catch {
42439
43374
  return false;
42440
43375
  }
42441
43376
  }
42442
- var EXIT_ALLOW5, EXIT_BLOCK2, STATE_FILE4, DISPATCH_TOOLS, EVALUATION_RE, PRELOADED_VERDICT_RE, SELF_SCOPE_RE, WARN_TEXT;
43377
+ var EXIT_ALLOW5, EXIT_BLOCK2, STATE_FILE4, DISPATCH_TOOLS, EVALUATION_RE, PRELOADED_VERDICT_RE, SELF_SCOPE_RE, WARN_TEXT, SAME_SESSION_TEXT;
42443
43378
  var init_evidence_independence = __esm({
42444
43379
  "src/scripts/hooks/evidence_independence.ts"() {
42445
43380
  "use strict";
42446
43381
  init_state_io();
42447
43382
  init_hook_stdin();
43383
+ init_test_delta();
42448
43384
  EXIT_ALLOW5 = 0;
42449
43385
  EXIT_BLOCK2 = 1;
42450
- STATE_FILE4 = path85.join("agents", "state", "evidence-dispatch.json");
43386
+ STATE_FILE4 = path87.join("agents", "state", "evidence-dispatch.json");
42451
43387
  DISPATCH_TOOLS = /* @__PURE__ */ new Set([
42452
43388
  "Agent",
42453
43389
  "Task",
@@ -42480,8 +43416,9 @@ var init_evidence_independence = __esm({
42480
43416
  ];
42481
43417
  SELF_SCOPE_RE = /\b(my (work|change|diff|implementation|code|fix|patch|branch|pr)|this (diff|change|pr|delta|implementation|patch)|the delta|the change i|what i (wrote|built|changed|implemented)|i just (wrote|built|changed|implemented))\b/i;
42482
43418
  WARN_TEXT = "First evaluation dispatch this turn. Two shapes fabricated a binding honest-null in the audited sessions \u2014 check your prompt for both before it goes out: (1) a verdict pre-loaded into the prompt, and (2) a scope narrowed to files you chose. A review you commissioned on your own work is admissible as gate evidence only when the prompt is recorded alongside the verdict.";
42483
- if (_isCliEntry22()) {
42484
- process.exit(main30());
43419
+ 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.";
43420
+ if (_isCliEntry23()) {
43421
+ process.exit(main31());
42485
43422
  }
42486
43423
  }
42487
43424
  });
@@ -42782,9 +43719,9 @@ var init_subagent_routing = __esm({
42782
43719
  });
42783
43720
 
42784
43721
  // src/scripts/hooks/delegation_nudge_hook.ts
42785
- import fs85 from "node:fs";
42786
- import path86 from "node:path";
42787
- import { fileURLToPath as fileURLToPath43, pathToFileURL as pathToFileURL28 } from "node:url";
43722
+ import fs87 from "node:fs";
43723
+ import path88 from "node:path";
43724
+ import { fileURLToPath as fileURLToPath44, pathToFileURL as pathToFileURL29 } from "node:url";
42788
43725
  function _isObject7(v) {
42789
43726
  return typeof v === "object" && v !== null && !Array.isArray(v);
42790
43727
  }
@@ -42950,7 +43887,7 @@ function _workspaceRoot(envelope) {
42950
43887
  }
42951
43888
  return process.cwd();
42952
43889
  }
42953
- function main31() {
43890
+ function main32() {
42954
43891
  let envelope = {};
42955
43892
  try {
42956
43893
  const raw = readHookStdin();
@@ -42989,20 +43926,20 @@ function main31() {
42989
43926
  );
42990
43927
  return EXIT_WARN3;
42991
43928
  }
42992
- function _isCliEntry23() {
43929
+ function _isCliEntry24() {
42993
43930
  if (true) {
42994
43931
  return false;
42995
43932
  }
42996
43933
  if (process.argv[1] === void 0) {
42997
43934
  return false;
42998
43935
  }
42999
- const argvUrl = pathToFileURL28(path86.resolve(process.argv[1])).href;
43936
+ const argvUrl = pathToFileURL29(path88.resolve(process.argv[1])).href;
43000
43937
  if (import.meta.url === argvUrl) {
43001
43938
  return true;
43002
43939
  }
43003
43940
  try {
43004
- const here = fs85.realpathSync(fileURLToPath43(import.meta.url));
43005
- const argv = fs85.realpathSync(path86.resolve(process.argv[1]));
43941
+ const here = fs87.realpathSync(fileURLToPath44(import.meta.url));
43942
+ const argv = fs87.realpathSync(path88.resolve(process.argv[1]));
43006
43943
  return here === argv;
43007
43944
  } catch {
43008
43945
  return false;
@@ -43029,18 +43966,18 @@ var init_delegation_nudge_hook = __esm({
43029
43966
  STEP_LINE_RE = /^\s*\d+[.)]\s+\S/gm;
43030
43967
  ORDERED_LINE_FLOOR = 3;
43031
43968
  ORDERED_WORD_FLOOR = 2;
43032
- if (_isCliEntry23()) {
43033
- process.exit(main31());
43969
+ if (_isCliEntry24()) {
43970
+ process.exit(main32());
43034
43971
  }
43035
43972
  }
43036
43973
  });
43037
43974
 
43038
43975
  // src/scripts/conformance_scan.ts
43039
43976
  import { createHash as createHash14 } from "node:crypto";
43040
- import fs86 from "node:fs";
43977
+ import fs88 from "node:fs";
43041
43978
  import os17 from "node:os";
43042
- import path87 from "node:path";
43043
- import { fileURLToPath as fileURLToPath44, pathToFileURL as pathToFileURL29 } from "node:url";
43979
+ import path89 from "node:path";
43980
+ import { fileURLToPath as fileURLToPath45, pathToFileURL as pathToFileURL30 } from "node:url";
43044
43981
  function spansCarrierChange(firstAts) {
43045
43982
  const stamps = firstAts.filter((s) => s !== "").sort();
43046
43983
  if (stamps.length === 0) {
@@ -43382,7 +44319,7 @@ function scanSession(sessionId, lines) {
43382
44319
  }
43383
44320
  function defaultStore(projectDir) {
43384
44321
  const slug = projectStoreSlug(projectDir);
43385
- return path87.join(process.env["HOME"] ?? "", ".claude", "projects", slug);
44322
+ return path89.join(process.env["HOME"] ?? "", ".claude", "projects", slug);
43386
44323
  }
43387
44324
  function _tokens(chars) {
43388
44325
  return Math.round(chars / 4);
@@ -43393,13 +44330,13 @@ function measureDelivered(projectRulesDir, globalRulesDir) {
43393
44330
  return {
43394
44331
  project: {
43395
44332
  dir: projectRulesDir,
43396
- present: fs86.existsSync(projectRulesDir),
44333
+ present: fs88.existsSync(projectRulesDir),
43397
44334
  files: p.files,
43398
44335
  tokens: _tokens(p.chars)
43399
44336
  },
43400
44337
  global: {
43401
44338
  dir: globalRulesDir,
43402
- present: fs86.existsSync(globalRulesDir),
44339
+ present: fs88.existsSync(globalRulesDir),
43403
44340
  files: g.files,
43404
44341
  tokens: _tokens(g.chars)
43405
44342
  },
@@ -43407,13 +44344,13 @@ function measureDelivered(projectRulesDir, globalRulesDir) {
43407
44344
  };
43408
44345
  }
43409
44346
  function storeKey(store) {
43410
- return createHash14("sha256").update(path87.resolve(store)).digest("hex").slice(0, 12);
44347
+ return createHash14("sha256").update(path89.resolve(store)).digest("hex").slice(0, 12);
43411
44348
  }
43412
44349
  function scanStore(store, limit) {
43413
- const files = fs86.readdirSync(store).filter((f) => f.endsWith(".jsonl")).map((f) => ({ f, m: fs86.statSync(path87.join(store, f)).mtimeMs })).sort((a, b) => b.m - a.m).slice(0, limit).map((x) => x.f);
44350
+ const files = fs88.readdirSync(store).filter((f) => f.endsWith(".jsonl")).map((f) => ({ f, m: fs88.statSync(path89.join(store, f)).mtimeMs })).sort((a, b) => b.m - a.m).slice(0, limit).map((x) => x.f);
43414
44351
  const per_session = [];
43415
44352
  for (const f of files) {
43416
- const lines = fs86.readFileSync(path87.join(store, f), "utf8").split("\n");
44353
+ const lines = fs88.readFileSync(path89.join(store, f), "utf8").split("\n");
43417
44354
  const r = scanSession(f.replace(/\.jsonl$/, "").slice(0, 8), lines);
43418
44355
  if (r.assistant_turns > 0) {
43419
44356
  per_session.push(r);
@@ -43441,10 +44378,10 @@ function scanStore(store, limit) {
43441
44378
  const task_completeness_rate_pct = completeness_windows === 0 ? 0 : Number((100 * task_completeness / completeness_windows).toFixed(1));
43442
44379
  const era = spansCarrierChange(per_session.map((s) => s.first_at));
43443
44380
  const delivered = measureDelivered(
43444
- path87.join(REPO_ROOT7, ".claude", "rules"),
43445
- path87.join(process.env["HOME"] ?? os17.homedir(), ".claude", "rules")
44381
+ path89.join(REPO_ROOT7, ".claude", "rules"),
44382
+ path89.join(process.env["HOME"] ?? os17.homedir(), ".claude", "rules")
43446
44383
  );
43447
- const ownStore = path87.resolve(store) === path87.resolve(defaultStore(REPO_ROOT7));
44384
+ const ownStore = path89.resolve(store) === path89.resolve(defaultStore(REPO_ROOT7));
43448
44385
  return {
43449
44386
  scanned_at: (/* @__PURE__ */ new Date()).toISOString(),
43450
44387
  store,
@@ -43474,8 +44411,8 @@ function scanStore(store, limit) {
43474
44411
  };
43475
44412
  }
43476
44413
  function recordRate(file, scanned_at, rate) {
43477
- fs86.mkdirSync(path87.dirname(file), { recursive: true });
43478
- fs86.appendFileSync(file, `${JSON.stringify({ measured_at: scanned_at, ...rate })}
44414
+ fs88.mkdirSync(path89.dirname(file), { recursive: true });
44415
+ fs88.appendFileSync(file, `${JSON.stringify({ measured_at: scanned_at, ...rate })}
43479
44416
  `, "utf8");
43480
44417
  }
43481
44418
  function render3(report2) {
@@ -43574,7 +44511,7 @@ function render3(report2) {
43574
44511
  lines.push(" checkbox batching \u2014 measured NOWHERE. ~5 low-severity findings.");
43575
44512
  return lines.join("\n");
43576
44513
  }
43577
- function main32(argv) {
44514
+ function main33(argv) {
43578
44515
  const args = argv ?? process.argv.slice(2);
43579
44516
  let store = null;
43580
44517
  let limit = 30;
@@ -43606,14 +44543,14 @@ function main32(argv) {
43606
44543
  return 2;
43607
44544
  }
43608
44545
  const resolved = store ?? defaultStore(process.cwd());
43609
- if (!fs86.existsSync(resolved)) {
44546
+ if (!fs88.existsSync(resolved)) {
43610
44547
  process.stderr.write(`conformance:behavior: no transcript store at ${resolved}
43611
44548
  `);
43612
44549
  return 1;
43613
44550
  }
43614
44551
  const report2 = scanStore(resolved, Number.isFinite(limit) && limit > 0 ? limit : 30);
43615
44552
  if (out) {
43616
- fs86.writeFileSync(out, `${JSON.stringify(report2, null, 2)}
44553
+ fs88.writeFileSync(out, `${JSON.stringify(report2, null, 2)}
43617
44554
  `, "utf8");
43618
44555
  }
43619
44556
  if (record) {
@@ -43621,7 +44558,7 @@ function main32(argv) {
43621
44558
  }
43622
44559
  if (why !== null) {
43623
44560
  const id = why;
43624
- fs86.writeSync(
44561
+ fs88.writeSync(
43625
44562
  1,
43626
44563
  json ? `${JSON.stringify(
43627
44564
  {
@@ -43641,25 +44578,25 @@ function main32(argv) {
43641
44578
  );
43642
44579
  return 0;
43643
44580
  }
43644
- fs86.writeSync(1, json ? `${JSON.stringify(report2, null, 2)}
44581
+ fs88.writeSync(1, json ? `${JSON.stringify(report2, null, 2)}
43645
44582
  ` : `${render3(report2)}
43646
44583
  `);
43647
44584
  return 0;
43648
44585
  }
43649
- function _isCliEntry24() {
44586
+ function _isCliEntry25() {
43650
44587
  if (true) {
43651
44588
  return false;
43652
44589
  }
43653
44590
  if (process.argv[1] === void 0) {
43654
44591
  return false;
43655
44592
  }
43656
- const argvUrl = pathToFileURL29(path87.resolve(process.argv[1])).href;
44593
+ const argvUrl = pathToFileURL30(path89.resolve(process.argv[1])).href;
43657
44594
  if (import.meta.url === argvUrl) {
43658
44595
  return true;
43659
44596
  }
43660
44597
  try {
43661
- const here = fs86.realpathSync(fileURLToPath44(import.meta.url));
43662
- const argv = fs86.realpathSync(path87.resolve(process.argv[1]));
44598
+ const here = fs88.realpathSync(fileURLToPath45(import.meta.url));
44599
+ const argv = fs88.realpathSync(path89.resolve(process.argv[1]));
43663
44600
  return here === argv;
43664
44601
  } catch {
43665
44602
  return false;
@@ -43680,7 +44617,7 @@ var init_conformance_scan = __esm({
43680
44617
  init_turn_end_gate_hook();
43681
44618
  init_evidence_independence();
43682
44619
  init_delegation_nudge_hook();
43683
- REPO_ROOT7 = path87.resolve(path87.dirname(fileURLToPath44(import.meta.url)), "..", "..");
44620
+ REPO_ROOT7 = path89.resolve(path89.dirname(fileURLToPath45(import.meta.url)), "..", "..");
43684
44621
  OBSERVED_BAND = { low: 9.1, high: 39.2 };
43685
44622
  BAND_MIN_TURNS = 1978;
43686
44623
  CARRIER_CHANGES = [
@@ -43707,28 +44644,28 @@ var init_conformance_scan = __esm({
43707
44644
  };
43708
44645
  HARNESS_TEXT = /^(API Error:|Request (timed out|was aborted)|\[Request interrupted|Error: |Credit balance is too low|You've hit your|Prompt is too long)/i;
43709
44646
  EN_OPENER = /^(let me|i'?ll |i'?m |found it|ok[,. ]|okay|alright|here'?s|now[,. ]|looking|checking|reading|running|the |this |that |there |we |you |good |right[,. ]|perfect|done[.,]|all |confirmed|correct)/i;
43710
- DEFAULT_RATE_SERIES = path87.join(
44647
+ DEFAULT_RATE_SERIES = path89.join(
43711
44648
  REPO_ROOT7,
43712
44649
  "agents",
43713
44650
  "runtime",
43714
44651
  "state",
43715
44652
  "conformance-rates.jsonl"
43716
44653
  );
43717
- if (_isCliEntry24()) {
43718
- process.exit(main32());
44654
+ if (_isCliEntry25()) {
44655
+ process.exit(main33());
43719
44656
  }
43720
44657
  }
43721
44658
  });
43722
44659
 
43723
44660
  // src/scripts/report_carrier_divergence.ts
43724
- import * as fs87 from "node:fs";
44661
+ import * as fs89 from "node:fs";
43725
44662
  import * as os18 from "node:os";
43726
- import * as path88 from "node:path";
44663
+ import * as path90 from "node:path";
43727
44664
  import process20 from "node:process";
43728
- import { fileURLToPath as fileURLToPath45, pathToFileURL as pathToFileURL30 } from "node:url";
44665
+ import { fileURLToPath as fileURLToPath46, pathToFileURL as pathToFileURL31 } from "node:url";
43729
44666
  function _listRules(dir) {
43730
44667
  try {
43731
- return fs87.readdirSync(dir).filter((f) => f.endsWith(".md")).sort();
44668
+ return fs89.readdirSync(dir).filter((f) => f.endsWith(".md")).sort();
43732
44669
  } catch {
43733
44670
  return [];
43734
44671
  }
@@ -43736,7 +44673,7 @@ function _listRules(dir) {
43736
44673
  function _ruleType(file) {
43737
44674
  let text;
43738
44675
  try {
43739
- text = fs87.readFileSync(file, "utf-8");
44676
+ text = fs89.readFileSync(file, "utf-8");
43740
44677
  } catch {
43741
44678
  return "";
43742
44679
  }
@@ -43747,8 +44684,8 @@ function compareCarriers(projectDir, globalDir, sourceDir) {
43747
44684
  const out = {
43748
44685
  projectDir,
43749
44686
  globalDir,
43750
- globalPresent: fs87.existsSync(globalDir),
43751
- projectPresent: fs87.existsSync(projectDir),
44687
+ globalPresent: fs89.existsSync(globalDir),
44688
+ projectPresent: fs89.existsSync(projectDir),
43752
44689
  shared: 0,
43753
44690
  identical: [],
43754
44691
  provenanceOnly: [],
@@ -43771,7 +44708,7 @@ function compareCarriers(projectDir, globalDir, sourceDir) {
43771
44708
  }
43772
44709
  if (!inP && inG) {
43773
44710
  out.globalOnly.push(rule);
43774
- if (sourceDir !== void 0 && _ruleType(path88.join(sourceDir, rule)) === "manual") {
44711
+ if (sourceDir !== void 0 && _ruleType(path90.join(sourceDir, rule)) === "manual") {
43775
44712
  out.manualOnlyGlobal.push(rule);
43776
44713
  }
43777
44714
  continue;
@@ -43781,8 +44718,8 @@ function compareCarriers(projectDir, globalDir, sourceDir) {
43781
44718
  let projectCopy;
43782
44719
  let globalCopy;
43783
44720
  try {
43784
- projectCopy = fs87.readFileSync(path88.join(projectDir, rule));
43785
- globalCopy = fs87.readFileSync(path88.join(globalDir, rule));
44721
+ projectCopy = fs89.readFileSync(path90.join(projectDir, rule));
44722
+ globalCopy = fs89.readFileSync(path90.join(globalDir, rule));
43786
44723
  verdict = comparePair(projectCopy, globalCopy);
43787
44724
  } catch {
43788
44725
  out.shared -= 1;
@@ -43927,11 +44864,11 @@ function render4(d) {
43927
44864
  }
43928
44865
  return lines.join("\n");
43929
44866
  }
43930
- function main33(argv) {
44867
+ function main34(argv) {
43931
44868
  const args = argv ?? process20.argv.slice(2);
43932
- let projectDir = path88.join(REPO_ROOT8, PROJECT_RULES);
43933
- let globalDir = path88.join(os18.homedir(), GLOBAL_RULES);
43934
- let sourceDir = path88.join(REPO_ROOT8, PROJECTION_SOURCE);
44869
+ let projectDir = path90.join(REPO_ROOT8, PROJECT_RULES);
44870
+ let globalDir = path90.join(os18.homedir(), GLOBAL_RULES);
44871
+ let sourceDir = path90.join(REPO_ROOT8, PROJECTION_SOURCE);
43935
44872
  const value = (i) => {
43936
44873
  const v = args[i + 1];
43937
44874
  return v === void 0 || v.startsWith("-") ? null : v;
@@ -43945,7 +44882,7 @@ function main33(argv) {
43945
44882
  `);
43946
44883
  return 1;
43947
44884
  }
43948
- const resolved = path88.resolve(v);
44885
+ const resolved = path90.resolve(v);
43949
44886
  if (a === "--project") projectDir = resolved;
43950
44887
  else if (a === "--global") globalDir = resolved;
43951
44888
  else sourceDir = resolved;
@@ -43965,36 +44902,36 @@ function main33(argv) {
43965
44902
  `);
43966
44903
  return 0;
43967
44904
  }
43968
- function _isCliEntry25() {
44905
+ function _isCliEntry26() {
43969
44906
  if (process20.argv[1] === void 0) return false;
43970
- if (import.meta.url === pathToFileURL30(path88.resolve(process20.argv[1])).href) return true;
44907
+ if (import.meta.url === pathToFileURL31(path90.resolve(process20.argv[1])).href) return true;
43971
44908
  try {
43972
- return fs87.realpathSync(_HERE21) === fs87.realpathSync(path88.resolve(process20.argv[1]));
44909
+ return fs89.realpathSync(_HERE22) === fs89.realpathSync(path90.resolve(process20.argv[1]));
43973
44910
  } catch {
43974
44911
  return false;
43975
44912
  }
43976
44913
  }
43977
- var _HERE21, REPO_ROOT8, PROJECT_RULES, PROJECTION_SOURCE, GLOBAL_RULES;
44914
+ var _HERE22, REPO_ROOT8, PROJECT_RULES, PROJECTION_SOURCE, GLOBAL_RULES;
43978
44915
  var init_report_carrier_divergence = __esm({
43979
44916
  "src/scripts/report_carrier_divergence.ts"() {
43980
44917
  "use strict";
43981
44918
  init_carrier_divergence();
43982
- _HERE21 = fileURLToPath45(import.meta.url);
43983
- REPO_ROOT8 = path88.resolve(path88.dirname(_HERE21), "..", "..");
43984
- PROJECT_RULES = path88.join(".claude", "rules");
43985
- PROJECTION_SOURCE = path88.join("dist", "agent-src", "rules");
43986
- GLOBAL_RULES = path88.join(".claude", "rules");
43987
- if (_isCliEntry25()) {
43988
- process20.exit(main33());
44919
+ _HERE22 = fileURLToPath46(import.meta.url);
44920
+ REPO_ROOT8 = path90.resolve(path90.dirname(_HERE22), "..", "..");
44921
+ PROJECT_RULES = path90.join(".claude", "rules");
44922
+ PROJECTION_SOURCE = path90.join("dist", "agent-src", "rules");
44923
+ GLOBAL_RULES = path90.join(".claude", "rules");
44924
+ if (_isCliEntry26()) {
44925
+ process20.exit(main34());
43989
44926
  }
43990
44927
  }
43991
44928
  });
43992
44929
 
43993
44930
  // src/scripts/report_skill_activation.ts
43994
- import * as fs88 from "node:fs";
44931
+ import * as fs90 from "node:fs";
43995
44932
  import * as os19 from "node:os";
43996
- import * as path89 from "node:path";
43997
- import { fileURLToPath as fileURLToPath46, pathToFileURL as pathToFileURL31 } from "node:url";
44933
+ import * as path91 from "node:path";
44934
+ import { fileURLToPath as fileURLToPath47, pathToFileURL as pathToFileURL32 } from "node:url";
43998
44935
  function censusSkills(root) {
43999
44936
  const out = {
44000
44937
  total: 0,
@@ -44002,25 +44939,25 @@ function censusSkills(root) {
44002
44939
  withTriggerCorpus: [],
44003
44940
  withDeterministicObligation: []
44004
44941
  };
44005
- if (!fs88.existsSync(root)) {
44942
+ if (!fs90.existsSync(root)) {
44006
44943
  return out;
44007
44944
  }
44008
- for (const entry of fs88.readdirSync(root, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
44945
+ for (const entry of fs90.readdirSync(root, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
44009
44946
  if (!entry.isDirectory()) {
44010
44947
  continue;
44011
44948
  }
44012
- const file = path89.join(root, entry.name, "SKILL.md");
44013
- if (!fs88.existsSync(file)) {
44949
+ const file = path91.join(root, entry.name, "SKILL.md");
44950
+ if (!fs90.existsSync(file)) {
44014
44951
  continue;
44015
44952
  }
44016
44953
  out.total += 1;
44017
- const text = fs88.readFileSync(file, "utf8");
44954
+ const text = fs90.readFileSync(file, "utf8");
44018
44955
  const fmEnd = text.startsWith("---") ? text.indexOf("\n---", 3) : -1;
44019
44956
  const fm = fmEnd === -1 ? "" : text.slice(0, fmEnd);
44020
44957
  if (TRIGGER_KEYS.some((k) => new RegExp(`^${k}`, "m").test(fm))) {
44021
44958
  out.withTriggerKey.push(entry.name);
44022
44959
  }
44023
- if (fs88.existsSync(path89.join(root, entry.name, "evals", "triggers.json"))) {
44960
+ if (fs90.existsSync(path91.join(root, entry.name, "evals", "triggers.json"))) {
44024
44961
  out.withTriggerCorpus.push(entry.name);
44025
44962
  }
44026
44963
  const body = fmEnd === -1 ? text : text.slice(fmEnd + 4);
@@ -44031,17 +44968,17 @@ function censusSkills(root) {
44031
44968
  return out;
44032
44969
  }
44033
44970
  function defaultStore2(cwd) {
44034
- return path89.join(os19.homedir(), ".claude", "projects", projectStoreSlug(cwd));
44971
+ return path91.join(os19.homedir(), ".claude", "projects", projectStoreSlug(cwd));
44035
44972
  }
44036
44973
  function measureUsage(store, limit) {
44037
44974
  const rep = { store, sessions: 0, assistantTurns: 0, invocations: 0, bySkill: {} };
44038
- if (!fs88.existsSync(store)) {
44975
+ if (!fs90.existsSync(store)) {
44039
44976
  return rep;
44040
44977
  }
44041
- const files = fs88.readdirSync(store).filter((f) => f.endsWith(".jsonl")).map((f) => path89.join(store, f)).sort((a, b) => fs88.statSync(b).mtimeMs - fs88.statSync(a).mtimeMs).slice(0, limit);
44978
+ const files = fs90.readdirSync(store).filter((f) => f.endsWith(".jsonl")).map((f) => path91.join(store, f)).sort((a, b) => fs90.statSync(b).mtimeMs - fs90.statSync(a).mtimeMs).slice(0, limit);
44042
44979
  rep.sessions = files.length;
44043
44980
  for (const file of files) {
44044
- for (const line of fs88.readFileSync(file, "utf8").split("\n")) {
44981
+ for (const line of fs90.readFileSync(file, "utf8").split("\n")) {
44045
44982
  if (!line.trim()) {
44046
44983
  continue;
44047
44984
  }
@@ -44113,15 +45050,15 @@ function buildRecord(census, usage, today) {
44113
45050
  assistant_turns: usage.reduce((a, u) => a + u.assistantTurns, 0),
44114
45051
  invocations: usage.reduce((a, u) => a + u.invocations, 0),
44115
45052
  distinct_skills_invoked: distinct.size,
44116
- stores: usage.map((u) => path89.basename(u.store))
45053
+ stores: usage.map((u) => path91.basename(u.store))
44117
45054
  };
44118
45055
  }
44119
45056
  function readRecord(repoRoot) {
44120
- const file = path89.join(repoRoot, RECORD_PATH);
44121
- if (!fs88.existsSync(file)) {
45057
+ const file = path91.join(repoRoot, RECORD_PATH);
45058
+ if (!fs90.existsSync(file)) {
44122
45059
  return null;
44123
45060
  }
44124
- return JSON.parse(fs88.readFileSync(file, "utf8"));
45061
+ return JSON.parse(fs90.readFileSync(file, "utf8"));
44125
45062
  }
44126
45063
  function render5(census, usage, published = null) {
44127
45064
  const lines = [];
@@ -44156,7 +45093,7 @@ function render5(census, usage, published = null) {
44156
45093
  }
44157
45094
  totalInv += u.invocations;
44158
45095
  lines.push(
44159
- ` ${path89.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)}`
45096
+ ` ${path91.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)}`
44160
45097
  );
44161
45098
  }
44162
45099
  lines.push("");
@@ -44226,7 +45163,7 @@ function render5(census, usage, published = null) {
44226
45163
  lines.push(" catalogue once per session, then count descriptions against bare names.");
44227
45164
  return lines.join("\n");
44228
45165
  }
44229
- function main34(argv) {
45166
+ function main35(argv) {
44230
45167
  let limit = 30;
44231
45168
  let emit2 = false;
44232
45169
  let allowEmpty = false;
@@ -44248,7 +45185,7 @@ function main34(argv) {
44248
45185
  } else if (a === "--allow-empty-store") {
44249
45186
  allowEmpty = true;
44250
45187
  } else if (a === "--help" || a === "-h") {
44251
- process.stdout.write(USAGE3);
45188
+ process.stdout.write(USAGE4);
44252
45189
  return 0;
44253
45190
  }
44254
45191
  }
@@ -44259,7 +45196,7 @@ function main34(argv) {
44259
45196
  if (stores.length === 0) {
44260
45197
  stores.push(defaultStore2(REPO_ROOT9));
44261
45198
  }
44262
- const census = censusSkills(path89.join(root, SKILLS_ROOT));
45199
+ const census = censusSkills(path91.join(root, SKILLS_ROOT));
44263
45200
  const usage = stores.map((s) => measureUsage(s, limit));
44264
45201
  process.stdout.write(`${render5(census, usage, readRecord(root))}
44265
45202
  `);
@@ -44280,40 +45217,40 @@ function main34(argv) {
44280
45217
  return 1;
44281
45218
  }
44282
45219
  const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
44283
- const file = path89.join(root, RECORD_PATH);
44284
- fs88.mkdirSync(path89.dirname(file), { recursive: true });
44285
- fs88.writeFileSync(file, `${JSON.stringify(buildRecord(census, usage, today), null, 2)}
45220
+ const file = path91.join(root, RECORD_PATH);
45221
+ fs90.mkdirSync(path91.dirname(file), { recursive: true });
45222
+ fs90.writeFileSync(file, `${JSON.stringify(buildRecord(census, usage, today), null, 2)}
44286
45223
  `);
44287
45224
  process.stdout.write(`
44288
45225
  wrote ${RECORD_PATH} (measured ${today})
44289
45226
  `);
44290
45227
  return 0;
44291
45228
  }
44292
- var _HERE22, REPO_ROOT9, SKILLS_ROOT, TRIGGER_KEYS, DETERMINISTIC_RE, RECORD_PATH, USAGE3;
45229
+ var _HERE23, REPO_ROOT9, SKILLS_ROOT, TRIGGER_KEYS, DETERMINISTIC_RE, RECORD_PATH, USAGE4;
44293
45230
  var init_report_skill_activation = __esm({
44294
45231
  "src/scripts/report_skill_activation.ts"() {
44295
45232
  "use strict";
44296
45233
  init_cc_transcript();
44297
45234
  init_scan_scope();
44298
- _HERE22 = fileURLToPath46(import.meta.url);
44299
- REPO_ROOT9 = path89.resolve(path89.dirname(_HERE22), "..", "..");
45235
+ _HERE23 = fileURLToPath47(import.meta.url);
45236
+ REPO_ROOT9 = path91.resolve(path91.dirname(_HERE23), "..", "..");
44300
45237
  SKILLS_ROOT = "src/skills";
44301
45238
  TRIGGER_KEYS = ["triggers:", "trigger_description:", "file_pattern:", "path_prefix:"];
44302
45239
  DETERMINISTIC_RE = /^\s*(?:[-*]\s*)?(?:\*\*)?(MUST|NEVER|ALWAYS)\b/m;
44303
45240
  RECORD_PATH = "agents/evidence/metrics/skill-activation-census.json";
44304
- USAGE3 = "usage: report_skill_activation [--root DIR] [--limit N] [--store PATH]... [--emit] [--allow-empty-store]\n";
44305
- if (process.argv[1] !== void 0 && import.meta.url === pathToFileURL31(path89.resolve(process.argv[1])).href) {
44306
- process.exit(main34(process.argv.slice(2)));
45241
+ USAGE4 = "usage: report_skill_activation [--root DIR] [--limit N] [--store PATH]... [--emit] [--allow-empty-store]\n";
45242
+ if (process.argv[1] !== void 0 && import.meta.url === pathToFileURL32(path91.resolve(process.argv[1])).href) {
45243
+ process.exit(main35(process.argv.slice(2)));
44307
45244
  }
44308
45245
  }
44309
45246
  });
44310
45247
 
44311
45248
  // src/scripts/report_skill_obligation_violations.ts
44312
- import * as fs89 from "node:fs";
45249
+ import * as fs91 from "node:fs";
44313
45250
  import * as os20 from "node:os";
44314
- import * as path90 from "node:path";
45251
+ import * as path92 from "node:path";
44315
45252
  import process21 from "node:process";
44316
- import { fileURLToPath as fileURLToPath47, pathToFileURL as pathToFileURL32 } from "node:url";
45253
+ import { fileURLToPath as fileURLToPath48, pathToFileURL as pathToFileURL33 } from "node:url";
44317
45254
  function _verb(line) {
44318
45255
  const m = /\b(NEVER|MUST|ALWAYS)\b/.exec(line);
44319
45256
  return m?.[1] ?? "NEVER";
@@ -44332,7 +45269,7 @@ function _artefacts(line) {
44332
45269
  return out;
44333
45270
  }
44334
45271
  function extractObligations(repoRoot) {
44335
- const skillsRoot = path90.join(repoRoot, SKILLS_ROOT);
45272
+ const skillsRoot = path92.join(repoRoot, SKILLS_ROOT);
44336
45273
  const census = censusSkills(skillsRoot);
44337
45274
  const out = {
44338
45275
  skills: census.withDeterministicObligation,
@@ -44346,7 +45283,7 @@ function extractObligations(repoRoot) {
44346
45283
  for (const skill of census.withDeterministicObligation) {
44347
45284
  let text;
44348
45285
  try {
44349
- text = fs89.readFileSync(path90.join(skillsRoot, skill, "SKILL.md"), "utf-8");
45286
+ text = fs91.readFileSync(path92.join(skillsRoot, skill, "SKILL.md"), "utf-8");
44350
45287
  } catch {
44351
45288
  continue;
44352
45289
  }
@@ -44448,7 +45385,7 @@ function scanSessionForViolations(session, lines, forbidden, parsed) {
44448
45385
  return flags;
44449
45386
  }
44450
45387
  function defaultStore3(cwd) {
44451
- return path90.join(os20.homedir(), ".claude", "projects", projectStoreSlug(cwd));
45388
+ return path92.join(os20.homedir(), ".claude", "projects", projectStoreSlug(cwd));
44452
45389
  }
44453
45390
  function scanStore2(repoRoot, store, limit) {
44454
45391
  const census = extractObligations(repoRoot);
@@ -44461,14 +45398,14 @@ function scanStore2(repoRoot, store, limit) {
44461
45398
  };
44462
45399
  let files;
44463
45400
  try {
44464
- files = fs89.readdirSync(store).filter((f) => f.endsWith(".jsonl")).map((f) => ({ p: path90.join(store, f), m: fs89.statSync(path90.join(store, f)).mtimeMs })).sort((a, b) => b.m - a.m).slice(0, limit).map((x) => x.p);
45401
+ files = fs91.readdirSync(store).filter((f) => f.endsWith(".jsonl")).map((f) => ({ p: path92.join(store, f), m: fs91.statSync(path92.join(store, f)).mtimeMs })).sort((a, b) => b.m - a.m).slice(0, limit).map((x) => x.p);
44465
45402
  } catch {
44466
45403
  return report2;
44467
45404
  }
44468
45405
  report2.sessions = files.length;
44469
45406
  for (const file of files) {
44470
- const lines = fs89.readFileSync(file, "utf-8").split("\n");
44471
- const id = path90.basename(file).replace(/\.jsonl$/, "").slice(0, 8);
45407
+ const lines = fs91.readFileSync(file, "utf-8").split("\n");
45408
+ const id = path92.basename(file).replace(/\.jsonl$/, "").slice(0, 8);
44472
45409
  const entries = _parseSession(lines);
44473
45410
  if (loadedSkillsFrom(entries).size > 0) report2.sessionsWithASkill += 1;
44474
45411
  report2.flags.push(...scanSessionForViolations(id, lines, census.forbidden, entries));
@@ -44538,7 +45475,7 @@ function render6(r) {
44538
45475
  lines.push(" ships as detection-only, and this one says so.");
44539
45476
  return lines.join("\n");
44540
45477
  }
44541
- function main35(argv) {
45478
+ function main36(argv) {
44542
45479
  const args = argv ?? process21.argv.slice(2);
44543
45480
  let limit = 30;
44544
45481
  let json = false;
@@ -44591,24 +45528,24 @@ function main35(argv) {
44591
45528
  }
44592
45529
  return 0;
44593
45530
  }
44594
- function _isCliEntry26() {
45531
+ function _isCliEntry27() {
44595
45532
  if (process21.argv[1] === void 0) return false;
44596
- if (import.meta.url === pathToFileURL32(path90.resolve(process21.argv[1])).href) return true;
45533
+ if (import.meta.url === pathToFileURL33(path92.resolve(process21.argv[1])).href) return true;
44597
45534
  try {
44598
- return fs89.realpathSync(_HERE23) === fs89.realpathSync(path90.resolve(process21.argv[1]));
45535
+ return fs91.realpathSync(_HERE24) === fs91.realpathSync(path92.resolve(process21.argv[1]));
44599
45536
  } catch {
44600
45537
  return false;
44601
45538
  }
44602
45539
  }
44603
- var _HERE23, REPO_ROOT10, OBLIGATION_LINE_RE, PATH_RE2, CMD_RE, CMD_HEADS, PIVOT_RE, WRITE_TOOLS, SHELL_TOOLS, SKILL_BODY_RE, PATH_FIELDS, COMMAND_FIELDS;
45540
+ var _HERE24, REPO_ROOT10, OBLIGATION_LINE_RE, PATH_RE2, CMD_RE, CMD_HEADS, PIVOT_RE, WRITE_TOOLS, SHELL_TOOLS, SKILL_BODY_RE, PATH_FIELDS, COMMAND_FIELDS;
44604
45541
  var init_report_skill_obligation_violations = __esm({
44605
45542
  "src/scripts/report_skill_obligation_violations.ts"() {
44606
45543
  "use strict";
44607
45544
  init_cc_transcript();
44608
45545
  init_transcript_entry();
44609
45546
  init_report_skill_activation();
44610
- _HERE23 = fileURLToPath47(import.meta.url);
44611
- REPO_ROOT10 = path90.resolve(path90.dirname(_HERE23), "..", "..");
45547
+ _HERE24 = fileURLToPath48(import.meta.url);
45548
+ REPO_ROOT10 = path92.resolve(path92.dirname(_HERE24), "..", "..");
44612
45549
  OBLIGATION_LINE_RE = new RegExp(`${DETERMINISTIC_RE.source}.*`, "gm");
44613
45550
  PATH_RE2 = /`([A-Za-z0-9_./-]*\/[A-Za-z0-9_.-]+\.[a-z]{2,6})`/g;
44614
45551
  CMD_RE = /`([a-z][a-z0-9-]*(?: [a-z][a-z0-9:._-]*){1,3})`/g;
@@ -44642,31 +45579,31 @@ var init_report_skill_obligation_violations = __esm({
44642
45579
  SKILL_BODY_RE = /Base directory for this skill:\s*\S*?\/skills\/([A-Za-z0-9_-]+)/;
44643
45580
  PATH_FIELDS = ["file_path", "path", "filePath", "notebook_path", "target_file"];
44644
45581
  COMMAND_FIELDS = ["command", "cmd"];
44645
- if (_isCliEntry26()) {
44646
- process21.exit(main35());
45582
+ if (_isCliEntry27()) {
45583
+ process21.exit(main36());
44647
45584
  }
44648
45585
  }
44649
45586
  });
44650
45587
 
44651
45588
  // src/scripts/report_conformance_funnel.ts
44652
- import * as fs90 from "node:fs";
45589
+ import * as fs92 from "node:fs";
44653
45590
  import * as os21 from "node:os";
44654
- import * as path91 from "node:path";
45591
+ import * as path93 from "node:path";
44655
45592
  import process22 from "node:process";
44656
- import { fileURLToPath as fileURLToPath48, pathToFileURL as pathToFileURL33 } from "node:url";
45593
+ import { fileURLToPath as fileURLToPath49, pathToFileURL as pathToFileURL34 } from "node:url";
44657
45594
  function buildFunnel(opts = {}) {
44658
45595
  const repoRoot = opts.repoRoot ?? REPO_ROOT11;
44659
- const projectRulesDir = opts.projectRulesDir ?? path91.join(repoRoot, PROJECT_RULES);
44660
- const globalRulesDir = opts.globalRulesDir ?? path91.join(os21.homedir(), GLOBAL_RULES);
44661
- const sourceDir = opts.sourceDir ?? path91.join(repoRoot, PROJECTION_SOURCE);
45596
+ const projectRulesDir = opts.projectRulesDir ?? path93.join(repoRoot, PROJECT_RULES);
45597
+ const globalRulesDir = opts.globalRulesDir ?? path93.join(os21.homedir(), GLOBAL_RULES);
45598
+ const sourceDir = opts.sourceDir ?? path93.join(repoRoot, PROJECTION_SOURCE);
44662
45599
  const store = opts.store ?? defaultStore(repoRoot);
44663
45600
  const limit = opts.limit ?? 30;
44664
45601
  return {
44665
45602
  delivered: measureDelivered(projectRulesDir, globalRulesDir),
44666
45603
  divergence: compareCarriers(projectRulesDir, globalRulesDir, sourceDir),
44667
- skills: censusSkills(path91.join(repoRoot, SKILLS_ROOT)),
45604
+ skills: censusSkills(path93.join(repoRoot, SKILLS_ROOT)),
44668
45605
  usage: measureUsage(store, limit),
44669
- storePresent: fs90.existsSync(store),
45606
+ storePresent: fs92.existsSync(store),
44670
45607
  sk2: scanStore2(repoRoot, store, limit)
44671
45608
  };
44672
45609
  }
@@ -44791,7 +45728,7 @@ function render7(r) {
44791
45728
  lines.push("workflow without a measured false-positive rate first (locked policy).");
44792
45729
  return lines.join("\n");
44793
45730
  }
44794
- function main36(argv) {
45731
+ function main37(argv) {
44795
45732
  const args = argv ?? process22.argv.slice(2);
44796
45733
  const opts = {};
44797
45734
  const value = (i) => {
@@ -44807,7 +45744,7 @@ function main36(argv) {
44807
45744
  `);
44808
45745
  return 1;
44809
45746
  }
44810
- const resolved = path91.resolve(v);
45747
+ const resolved = path93.resolve(v);
44811
45748
  if (a === "--store") opts.store = resolved;
44812
45749
  else if (a === "--project") opts.projectRulesDir = resolved;
44813
45750
  else if (a === "--global") opts.globalRulesDir = resolved;
@@ -44837,16 +45774,16 @@ function main36(argv) {
44837
45774
  `);
44838
45775
  return 0;
44839
45776
  }
44840
- function _isCliEntry27() {
45777
+ function _isCliEntry28() {
44841
45778
  if (process22.argv[1] === void 0) return false;
44842
- if (import.meta.url === pathToFileURL33(path91.resolve(process22.argv[1])).href) return true;
45779
+ if (import.meta.url === pathToFileURL34(path93.resolve(process22.argv[1])).href) return true;
44843
45780
  try {
44844
- return fs90.realpathSync(_HERE24) === fs90.realpathSync(path91.resolve(process22.argv[1]));
45781
+ return fs92.realpathSync(_HERE25) === fs92.realpathSync(path93.resolve(process22.argv[1]));
44845
45782
  } catch {
44846
45783
  return false;
44847
45784
  }
44848
45785
  }
44849
- var _HERE24, REPO_ROOT11;
45786
+ var _HERE25, REPO_ROOT11;
44850
45787
  var init_report_conformance_funnel = __esm({
44851
45788
  "src/scripts/report_conformance_funnel.ts"() {
44852
45789
  "use strict";
@@ -44854,10 +45791,10 @@ var init_report_conformance_funnel = __esm({
44854
45791
  init_report_carrier_divergence();
44855
45792
  init_report_skill_activation();
44856
45793
  init_report_skill_obligation_violations();
44857
- _HERE24 = fileURLToPath48(import.meta.url);
44858
- REPO_ROOT11 = path91.resolve(path91.dirname(_HERE24), "..", "..");
44859
- if (_isCliEntry27()) {
44860
- process22.exit(main36());
45794
+ _HERE25 = fileURLToPath49(import.meta.url);
45795
+ REPO_ROOT11 = path93.resolve(path93.dirname(_HERE25), "..", "..");
45796
+ if (_isCliEntry28()) {
45797
+ process22.exit(main37());
44861
45798
  }
44862
45799
  }
44863
45800
  });
@@ -44873,21 +45810,22 @@ __export(cmd_conformance_exports, {
44873
45810
  _check_lean_projection: () => _check_lean_projection,
44874
45811
  _check_router_pointers: () => _check_router_pointers,
44875
45812
  _check_txlog_clean: () => _check_txlog_clean,
45813
+ _installLogExpected: () => _installLogExpected,
44876
45814
  _parse: () => _parse4,
44877
45815
  appendConformanceReport: () => appendConformanceReport,
44878
45816
  conformanceLogPath: () => conformanceLogPath,
44879
45817
  detectSmokePlatform: () => detectSmokePlatform,
44880
45818
  installLogPath: () => installLogPath,
44881
- main: () => main37,
45819
+ main: () => main38,
44882
45820
  routeTargetPaths: () => routeTargetPaths,
44883
45821
  runConformanceChecks: () => runConformanceChecks
44884
45822
  });
44885
- import * as fs91 from "node:fs";
45823
+ import * as fs93 from "node:fs";
44886
45824
  import * as os22 from "node:os";
44887
- import * as path92 from "node:path";
45825
+ import * as path94 from "node:path";
44888
45826
  import process23 from "node:process";
44889
- import { spawnSync as spawnSync14 } from "node:child_process";
44890
- import { fileURLToPath as fileURLToPath49, pathToFileURL as pathToFileURL34 } from "node:url";
45827
+ import { spawnSync as spawnSync16 } from "node:child_process";
45828
+ import { fileURLToPath as fileURLToPath50, pathToFileURL as pathToFileURL35 } from "node:url";
44891
45829
  function print3(s = "") {
44892
45830
  process23.stdout.write(`${s}
44893
45831
  `);
@@ -44901,30 +45839,33 @@ function conformanceLogPath() {
44901
45839
  if (override && override.trim().length > 0) {
44902
45840
  return override;
44903
45841
  }
44904
- return path92.join(os22.homedir(), ".event4u", "agent-config", "conformance-log.jsonl");
45842
+ return path94.join(os22.homedir(), ".event4u", "agent-config", "conformance-log.jsonl");
44905
45843
  }
44906
45844
  function installLogPath() {
44907
45845
  const override = process23.env["AGENT_CONFIG_INSTALL_LOG"];
44908
45846
  if (override && override.trim().length > 0) {
44909
45847
  return override;
44910
45848
  }
44911
- return path92.join(os22.homedir(), ".event4u", "agent-config", "install-log.jsonl");
45849
+ return path94.join(os22.homedir(), ".event4u", "agent-config", "install-log.jsonl");
44912
45850
  }
44913
- function _check_txlog_clean(logPath = installLogPath()) {
44914
- if (!fs91.existsSync(logPath)) {
44915
- return {
44916
- id: "txlog-clean",
44917
- status: "ok",
44918
- message: "no install transaction log \u2014 nothing to recover",
44919
- remedy: ""
44920
- };
44921
- }
44922
- const entries = readRecentEntries(logPath);
45851
+ function _installLogExpected(projectRoot) {
45852
+ return fs93.existsSync(manifest_path(projectRoot));
45853
+ }
45854
+ function _check_txlog_clean(logPath = installLogPath(), projectRoot = null) {
45855
+ const entries = fs93.existsSync(logPath) ? readRecentEntries(logPath) : [];
44923
45856
  if (entries.length === 0) {
45857
+ if (projectRoot !== null && _installLogExpected(projectRoot)) {
45858
+ return {
45859
+ id: "txlog-clean",
45860
+ status: "unknown",
45861
+ message: "install manifest present, no usable install transaction log \u2014 nothing recorded this install, so the last run cannot be confirmed complete",
45862
+ remedy: "no install path writes this log today; run `agent-config doctor` for the drift answer this check cannot give"
45863
+ };
45864
+ }
44924
45865
  return {
44925
45866
  id: "txlog-clean",
44926
45867
  status: "ok",
44927
- message: "install transaction log is empty",
45868
+ message: "no usable install transaction log and no install manifest \u2014 nothing was installed here",
44928
45869
  remedy: ""
44929
45870
  };
44930
45871
  }
@@ -44934,7 +45875,7 @@ function _check_txlog_clean(logPath = installLogPath()) {
44934
45875
  id: "txlog-clean",
44935
45876
  status: "fail",
44936
45877
  message: `install log tail is an abandoned run (abort at ${last.ts}${last.note ? `: ${last.note}` : ""})`,
44937
- remedy: "re-run `agent-config init` (recovery reverse-applies the aborted tail)"
45878
+ 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"
44938
45879
  };
44939
45880
  }
44940
45881
  return {
@@ -44945,11 +45886,11 @@ function _check_txlog_clean(logPath = installLogPath()) {
44945
45886
  };
44946
45887
  }
44947
45888
  function routeTargetPaths(target) {
44948
- return routeTargetPathsPosix(target).map((rel) => path92.join(...rel.split("/")));
45889
+ return routeTargetPathsPosix(target).map((rel) => path94.join(...rel.split("/")));
44949
45890
  }
44950
45891
  function _check_router_pointers(packageRoot = PACKAGE_ROOT2) {
44951
- const routerPath = path92.join(packageRoot, "dist", "router.json");
44952
- if (!fs91.existsSync(routerPath)) {
45892
+ const routerPath = path94.join(packageRoot, "dist", "router.json");
45893
+ if (!fs93.existsSync(routerPath)) {
44953
45894
  return {
44954
45895
  id: "router-pointers",
44955
45896
  status: "fail",
@@ -44959,7 +45900,7 @@ function _check_router_pointers(packageRoot = PACKAGE_ROOT2) {
44959
45900
  }
44960
45901
  let router;
44961
45902
  try {
44962
- router = JSON.parse(fs91.readFileSync(routerPath, "utf8"));
45903
+ router = JSON.parse(fs93.readFileSync(routerPath, "utf8"));
44963
45904
  } catch (exc) {
44964
45905
  return {
44965
45906
  id: "router-pointers",
@@ -44968,13 +45909,13 @@ function _check_router_pointers(packageRoot = PACKAGE_ROOT2) {
44968
45909
  remedy: "reinstall the package \u2014 dist/router.json is corrupt"
44969
45910
  };
44970
45911
  }
44971
- const rulesDir = path92.join(packageRoot, "dist", "agent-src", "rules");
45912
+ const rulesDir = path94.join(packageRoot, "dist", "agent-src", "rules");
44972
45913
  const broken = [];
44973
45914
  let ids = 0;
44974
45915
  let targets = 0;
44975
45916
  for (const kernelId of router["kernel"] ?? []) {
44976
45917
  ids += 1;
44977
- if (!fs91.existsSync(path92.join(rulesDir, `${kernelId}.md`))) {
45918
+ if (!fs93.existsSync(path94.join(rulesDir, `${kernelId}.md`))) {
44978
45919
  broken.push(`kernel:${kernelId} \u2192 rules/${kernelId}.md missing`);
44979
45920
  }
44980
45921
  }
@@ -44982,7 +45923,7 @@ function _check_router_pointers(packageRoot = PACKAGE_ROOT2) {
44982
45923
  for (const entry of router[tier] ?? []) {
44983
45924
  const ruleId = String(entry["id"] ?? "");
44984
45925
  ids += 1;
44985
- if (!fs91.existsSync(path92.join(rulesDir, `${ruleId}.md`))) {
45926
+ if (!fs93.existsSync(path94.join(rulesDir, `${ruleId}.md`))) {
44986
45927
  broken.push(`${tier}:${ruleId} \u2192 rules/${ruleId}.md missing`);
44987
45928
  }
44988
45929
  for (const target of entry["routes_to"] ?? []) {
@@ -44992,7 +45933,7 @@ function _check_router_pointers(packageRoot = PACKAGE_ROOT2) {
44992
45933
  broken.push(`${ruleId} \u2192 unparseable routes_to ${JSON.stringify(target)}`);
44993
45934
  continue;
44994
45935
  }
44995
- if (!candidates.some((rel) => fs91.existsSync(path92.join(packageRoot, rel)))) {
45936
+ if (!candidates.some((rel) => fs93.existsSync(path94.join(packageRoot, rel)))) {
44996
45937
  broken.push(`${ruleId} \u2192 ${target} (${candidates[0]} missing)`);
44997
45938
  }
44998
45939
  }
@@ -45024,9 +45965,9 @@ function detectSmokePlatform(projectRoot) {
45024
45965
  return "claude";
45025
45966
  }
45026
45967
  function dispatcherRunner(packageRoot) {
45027
- const localTsx = path92.join(packageRoot, "node_modules", ".bin", "tsx");
45028
- const script = path92.join(packageRoot, "src", "scripts", "hooks", "dispatch_hook.ts");
45029
- if (fs91.existsSync(localTsx)) {
45968
+ const localTsx = path94.join(packageRoot, "node_modules", ".bin", "tsx");
45969
+ const script = path94.join(packageRoot, "src", "scripts", "hooks", "dispatch_hook.ts");
45970
+ if (fs93.existsSync(localTsx)) {
45030
45971
  return [localTsx, script];
45031
45972
  }
45032
45973
  return ["npx", "tsx", script];
@@ -45043,7 +45984,7 @@ function _check_hook_dispatcher(projectRoot, packageRoot = PACKAGE_ROOT2, opts =
45043
45984
  ...event === "stop" ? { stop_reason: "conformance-smoke" } : { source: "startup" }
45044
45985
  });
45045
45986
  const argv = [...runner, "--platform", platform, "--event", event];
45046
- const proc = spawnSync14(argv[0], argv.slice(1), {
45987
+ const proc = spawnSync16(argv[0], argv.slice(1), {
45047
45988
  input: payload,
45048
45989
  cwd: projectRoot,
45049
45990
  encoding: "utf8",
@@ -45076,12 +46017,12 @@ function _check_hook_dispatcher(projectRoot, packageRoot = PACKAGE_ROOT2, opts =
45076
46017
  };
45077
46018
  }
45078
46019
  function readSettingsMode(projectRoot) {
45079
- const settingsPath = path92.join(projectRoot, ".agent-settings.yml");
45080
- if (!fs91.existsSync(settingsPath)) {
46020
+ const settingsPath = path94.join(projectRoot, ".agent-settings.yml");
46021
+ if (!fs93.existsSync(settingsPath)) {
45081
46022
  return "eager-all";
45082
46023
  }
45083
46024
  try {
45084
- const parsed = YAML7.parse(fs91.readFileSync(settingsPath, "utf8"));
46025
+ const parsed = YAML7.parse(fs93.readFileSync(settingsPath, "utf8"));
45085
46026
  const lean = parsed?.["lean_projection"] ?? null;
45086
46027
  const mode = lean?.["mode"];
45087
46028
  return typeof mode === "string" && mode.length > 0 ? mode : "eager-all";
@@ -45092,7 +46033,7 @@ function readSettingsMode(projectRoot) {
45092
46033
  function kernelIdsFromRouter(packageRoot) {
45093
46034
  try {
45094
46035
  const router = JSON.parse(
45095
- fs91.readFileSync(path92.join(packageRoot, "dist", "router.json"), "utf8")
46036
+ fs93.readFileSync(path94.join(packageRoot, "dist", "router.json"), "utf8")
45096
46037
  );
45097
46038
  return new Set((router["kernel"] ?? []).map(String));
45098
46039
  } catch {
@@ -45109,8 +46050,8 @@ function _check_lean_projection(projectRoot, packageRoot = PACKAGE_ROOT2, projec
45109
46050
  remedy: "set lean_projection.mode to 'eager-all' or 'thin' in .agent-settings.yml"
45110
46051
  };
45111
46052
  }
45112
- const rulesDir = projectedRulesDir ?? path92.join(projectRoot, ".augment", "rules");
45113
- if (!fs91.existsSync(rulesDir)) {
46053
+ const rulesDir = projectedRulesDir ?? path94.join(projectRoot, ".augment", "rules");
46054
+ if (!fs93.existsSync(rulesDir)) {
45114
46055
  return {
45115
46056
  id: "lean-projection",
45116
46057
  status: "skipped",
@@ -45119,7 +46060,7 @@ function _check_lean_projection(projectRoot, packageRoot = PACKAGE_ROOT2, projec
45119
46060
  };
45120
46061
  }
45121
46062
  const kernel = kernelIdsFromRouter(packageRoot);
45122
- const files = fs91.readdirSync(rulesDir).filter((f) => f.endsWith(".md") && f !== "INDEX.md").sort();
46063
+ const files = fs93.readdirSync(rulesDir).filter((f) => f.endsWith(".md") && f !== "INDEX.md").sort();
45123
46064
  const nonKernel = files.filter((f) => !kernel.has(f.replace(/\.md$/, "")));
45124
46065
  if (nonKernel.length === 0) {
45125
46066
  return {
@@ -45133,7 +46074,7 @@ function _check_lean_projection(projectRoot, packageRoot = PACKAGE_ROOT2, projec
45133
46074
  for (const f of nonKernel) {
45134
46075
  let text = "";
45135
46076
  try {
45136
- text = fs91.readFileSync(path92.join(rulesDir, f), "utf8");
46077
+ text = fs93.readFileSync(path94.join(rulesDir, f), "utf8");
45137
46078
  } catch {
45138
46079
  continue;
45139
46080
  }
@@ -45164,8 +46105,8 @@ function _check_lean_projection(projectRoot, packageRoot = PACKAGE_ROOT2, projec
45164
46105
  function _check_host_manifest(projectRoot) {
45165
46106
  const detected = Object.entries(detectToolPresence(projectRoot)).filter(([, v]) => v === true).map(([k]) => k);
45166
46107
  const detectedNote = detected.length > 0 ? `detected surfaces: ${detected.join(", ")}` : "no surfaces detected";
45167
- const settingsPath = path92.join(projectRoot, ".agent-settings.yml");
45168
- if (!fs91.existsSync(settingsPath)) {
46108
+ const settingsPath = path94.join(projectRoot, ".agent-settings.yml");
46109
+ if (!fs93.existsSync(settingsPath)) {
45169
46110
  return {
45170
46111
  id: "host-manifest",
45171
46112
  status: "ok",
@@ -45175,7 +46116,7 @@ function _check_host_manifest(projectRoot) {
45175
46116
  }
45176
46117
  let parsed = null;
45177
46118
  try {
45178
- parsed = YAML7.parse(fs91.readFileSync(settingsPath, "utf8"));
46119
+ parsed = YAML7.parse(fs93.readFileSync(settingsPath, "utf8"));
45179
46120
  } catch (exc) {
45180
46121
  return {
45181
46122
  id: "host-manifest",
@@ -45205,7 +46146,7 @@ function runConformanceChecks(opts = {}) {
45205
46146
  const projectRoot = opts.projectRoot ?? process23.cwd();
45206
46147
  const packageRoot = opts.packageRoot ?? PACKAGE_ROOT2;
45207
46148
  const checks = [];
45208
- checks.push(_check_txlog_clean());
46149
+ checks.push(_check_txlog_clean(installLogPath(), projectRoot));
45209
46150
  checks.push(_check_router_pointers(packageRoot));
45210
46151
  if (opts.skipDispatcher === true) {
45211
46152
  checks.push({
@@ -45242,7 +46183,7 @@ function _parse4(argv) {
45242
46183
  while (i < argv.length) {
45243
46184
  const a = argv[i];
45244
46185
  if (a === "-h" || a === "--help") {
45245
- process23.stdout.write(USAGE4);
46186
+ process23.stdout.write(USAGE5);
45246
46187
  throw new ArgparseExit4(0);
45247
46188
  }
45248
46189
  if (a === "--json") {
@@ -45256,7 +46197,7 @@ function _parse4(argv) {
45256
46197
  opts.project = a.slice(a.indexOf("=") + 1);
45257
46198
  } else {
45258
46199
  if (i + 1 >= argv.length) {
45259
- process23.stderr.write(USAGE4);
46200
+ process23.stderr.write(USAGE5);
45260
46201
  process23.stderr.write("agent-config conformance: error: --project expects a value\n");
45261
46202
  throw new ArgparseExit4(2);
45262
46203
  }
@@ -45264,7 +46205,7 @@ function _parse4(argv) {
45264
46205
  i += 1;
45265
46206
  }
45266
46207
  } else {
45267
- process23.stderr.write(USAGE4);
46208
+ process23.stderr.write(USAGE5);
45268
46209
  process23.stderr.write(`agent-config conformance: error: unrecognized argument ${a}
45269
46210
  `);
45270
46211
  throw new ArgparseExit4(2);
@@ -45273,7 +46214,7 @@ function _parse4(argv) {
45273
46214
  }
45274
46215
  return opts;
45275
46216
  }
45276
- function main37(argv = null) {
46217
+ function main38(argv = null) {
45277
46218
  const opts = _parse4(argv !== null ? Array.from(argv) : process23.argv.slice(2));
45278
46219
  if (opts.funnel) {
45279
46220
  print3(render7(buildFunnel()));
@@ -45328,7 +46269,7 @@ function main37(argv = null) {
45328
46269
  print3(` \u{1F4CD} project_root: ${project_root}`);
45329
46270
  print3("conformance:");
45330
46271
  for (const c of allChecks) {
45331
- const sym = STATUS_SYMBOLS[c["status"]] ?? "?";
46272
+ const sym = CONFORMANCE_STATUS_SYMBOLS[c["status"]] ?? "?";
45332
46273
  print3(` ${sym} ${c["id"]}: ${c["message"]}`);
45333
46274
  if (c["status"] !== "ok" && c["remedy"]) {
45334
46275
  print3(` fix: ${c["remedy"]}`);
@@ -45344,23 +46285,23 @@ function main37(argv = null) {
45344
46285
  }
45345
46286
  return failed ? 1 : 0;
45346
46287
  }
45347
- function _isCliEntry28() {
46288
+ function _isCliEntry29() {
45348
46289
  if (process23.argv[1] === void 0) {
45349
46290
  return false;
45350
46291
  }
45351
- const argvUrl = pathToFileURL34(path92.resolve(process23.argv[1])).href;
46292
+ const argvUrl = pathToFileURL35(path94.resolve(process23.argv[1])).href;
45352
46293
  if (import.meta.url === argvUrl) {
45353
46294
  return true;
45354
46295
  }
45355
46296
  try {
45356
- const here = fs91.realpathSync(fileURLToPath49(import.meta.url));
45357
- const argv = fs91.realpathSync(path92.resolve(process23.argv[1]));
46297
+ const here = fs93.realpathSync(fileURLToPath50(import.meta.url));
46298
+ const argv = fs93.realpathSync(path94.resolve(process23.argv[1]));
45358
46299
  return here === argv;
45359
46300
  } catch {
45360
46301
  return false;
45361
46302
  }
45362
46303
  }
45363
- var YAML7, _HERE25, PACKAGE_ROOT2, CONFORMANCE_CHECK_IDS, THIN_STUB_MARKER, USAGE4;
46304
+ var YAML7, _HERE26, PACKAGE_ROOT2, CONFORMANCE_CHECK_IDS, THIN_STUB_MARKER, CONFORMANCE_STATUS_SYMBOLS, USAGE5;
45364
46305
  var init_cmd_conformance = __esm({
45365
46306
  "src/scripts/_cli/cmd_conformance.ts"() {
45366
46307
  "use strict";
@@ -45373,7 +46314,7 @@ var init_cmd_conformance = __esm({
45373
46314
  init_router_target_paths();
45374
46315
  init_report_conformance_funnel();
45375
46316
  init_cmd_doctor();
45376
- _HERE25 = fileURLToPath49(import.meta.url);
46317
+ _HERE26 = fileURLToPath50(import.meta.url);
45377
46318
  PACKAGE_ROOT2 = resolvePackageRoot(import.meta.url);
45378
46319
  CONFORMANCE_CHECK_IDS = [
45379
46320
  "txlog-clean",
@@ -45383,10 +46324,14 @@ var init_cmd_conformance = __esm({
45383
46324
  "host-manifest"
45384
46325
  ];
45385
46326
  THIN_STUB_MARKER = "Routed rule \u2014 load the body on trigger-match";
45386
- USAGE4 = "usage: agent-config conformance [-h] [--project PROJECT] [--json]\n [--skip-dispatcher] [--funnel]\n";
45387
- if (_isCliEntry28() || process23.argv[1] === _HERE25) {
46327
+ CONFORMANCE_STATUS_SYMBOLS = {
46328
+ ...STATUS_SYMBOLS,
46329
+ unknown: "\u2754"
46330
+ };
46331
+ USAGE5 = "usage: agent-config conformance [-h] [--project PROJECT] [--json]\n [--skip-dispatcher] [--funnel]\n";
46332
+ if (_isCliEntry29() || process23.argv[1] === _HERE26) {
45388
46333
  try {
45389
- process23.exitCode = main37(process23.argv.slice(2));
46334
+ process23.exitCode = main38(process23.argv.slice(2));
45390
46335
  } catch (e) {
45391
46336
  if (e instanceof ArgparseExit4) {
45392
46337
  process23.exitCode = e.code;
@@ -45421,7 +46366,7 @@ __export(settings_exports, {
45421
46366
  read_tier_usage_settings: () => read_tier_usage_settings
45422
46367
  });
45423
46368
  import { createRequire as createRequire7 } from "node:module";
45424
- import * as fs92 from "node:fs";
46369
+ import * as fs94 from "node:fs";
45425
46370
  function _isPlainObject8(v) {
45426
46371
  return typeof v === "object" && v !== null && !Array.isArray(v) && !(v instanceof Date);
45427
46372
  }
@@ -45458,7 +46403,7 @@ function _coerce_path(value, def) {
45458
46403
  }
45459
46404
  function _isFile15(p) {
45460
46405
  try {
45461
- return fs92.statSync(p).isFile();
46406
+ return fs94.statSync(p).isFile();
45462
46407
  } catch {
45463
46408
  return false;
45464
46409
  }
@@ -45469,7 +46414,7 @@ function _read_telemetry_section(p, key) {
45469
46414
  }
45470
46415
  let raw = {};
45471
46416
  try {
45472
- raw = YAML8.parse(fs92.readFileSync(p, "utf-8"), { version: "1.1" });
46417
+ raw = YAML8.parse(fs94.readFileSync(p, "utf-8"), { version: "1.1" });
45473
46418
  if (raw === null || raw === void 0) {
45474
46419
  raw = {};
45475
46420
  }
@@ -46113,7 +47058,7 @@ __export(aggregator_exports, {
46113
47058
  aggregate: () => aggregate2,
46114
47059
  rank_artefacts: () => rank_artefacts
46115
47060
  });
46116
- import * as fs93 from "node:fs";
47061
+ import * as fs95 from "node:fs";
46117
47062
  function _key(kind, artId) {
46118
47063
  return `${kind}\0${artId}`;
46119
47064
  }
@@ -46150,7 +47095,7 @@ function* _iter_events(log_path) {
46150
47095
  if (!_isFile16(log_path)) {
46151
47096
  return;
46152
47097
  }
46153
- const text = fs93.readFileSync(log_path, "utf-8");
47098
+ const text = fs95.readFileSync(log_path, "utf-8");
46154
47099
  const lines = _pyFileLines(text);
46155
47100
  let lineNo = 0;
46156
47101
  for (const line of lines) {
@@ -46184,7 +47129,7 @@ function _pyFileLines(text) {
46184
47129
  }
46185
47130
  function _isFile16(p) {
46186
47131
  try {
46187
- return fs93.statSync(p).isFile();
47132
+ return fs95.statSync(p).isFile();
46188
47133
  } catch {
46189
47134
  return false;
46190
47135
  }
@@ -46772,14 +47717,14 @@ var init_report_renderer = __esm({
46772
47717
  });
46773
47718
 
46774
47719
  // src/scripts/ai_council/bundler.ts
46775
- import * as fs94 from "node:fs";
47720
+ import * as fs96 from "node:fs";
46776
47721
  function _context(mode, text, manifest = [], excluded = []) {
46777
47722
  return { mode, text, manifest, excluded };
46778
47723
  }
46779
47724
  function _utf8Len(s) {
46780
47725
  return Buffer.byteLength(s, "utf-8");
46781
47726
  }
46782
- function _splitlines8(s) {
47727
+ function _splitlines9(s) {
46783
47728
  if (s === "") {
46784
47729
  return [];
46785
47730
  }
@@ -46791,7 +47736,7 @@ function _splitlines8(s) {
46791
47736
  }
46792
47737
  function redact(text) {
46793
47738
  const out = [];
46794
- for (const line of _splitlines8(text)) {
47739
+ for (const line of _splitlines9(text)) {
46795
47740
  let replaced = line;
46796
47741
  for (const [pattern, placeholder] of _REDACTION_LINE_PATTERNS) {
46797
47742
  if (pattern.test(replaced)) {
@@ -46830,10 +47775,10 @@ function bundle_prompt(text) {
46830
47775
  return _context("prompt", _enforceSize(redacted, "prompt"), ["<inline prompt>"]);
46831
47776
  }
46832
47777
  function bundle_roadmap(p) {
46833
- if (!fs94.existsSync(p)) {
47778
+ if (!fs96.existsSync(p)) {
46834
47779
  throw new FileNotFoundError2(`Roadmap not found: ${p}`);
46835
47780
  }
46836
- const raw = fs94.readFileSync(p, { encoding: "utf-8" });
47781
+ const raw = fs96.readFileSync(p, { encoding: "utf-8" });
46837
47782
  const redacted = redact(raw);
46838
47783
  return _context(
46839
47784
  "roadmap",
@@ -47011,8 +47956,8 @@ function aggregate_scores(findings, scores) {
47011
47956
  by_id.get(s.finding_id).push(s);
47012
47957
  }
47013
47958
  const out = /* @__PURE__ */ new Map();
47014
- for (const [fid, fs106] of by_id) {
47015
- if (fs106.length === 0) {
47959
+ for (const [fid, fs108] of by_id) {
47960
+ if (fs108.length === 0) {
47016
47961
  out.set(
47017
47962
  fid,
47018
47963
  new ConsensusMetadata({
@@ -47028,13 +47973,13 @@ function aggregate_scores(findings, scores) {
47028
47973
  );
47029
47974
  continue;
47030
47975
  }
47031
- const mean2 = fs106.reduce((acc, s) => acc + s.score, 0) / fs106.length;
47032
- const agree_rate = fs106.filter((s) => s.agree).length / fs106.length;
47976
+ const mean2 = fs108.reduce((acc, s) => acc + s.score, 0) / fs108.length;
47977
+ const agree_rate = fs108.filter((s) => s.agree).length / fs108.length;
47033
47978
  const strength = mean2 / 10 * agree_rate;
47034
- const dissent = fs106.filter((s) => !s.agree).length;
47035
- const concur = fs106.filter((s) => s.agree).length;
47036
- const scorers = fs106.map((s) => s.scorer);
47037
- const dissent_reasons = fs106.filter((s) => !s.agree).map((s) => [s.scorer, s.reason]);
47979
+ const dissent = fs108.filter((s) => !s.agree).length;
47980
+ const concur = fs108.filter((s) => s.agree).length;
47981
+ const scorers = fs108.map((s) => s.scorer);
47982
+ const dissent_reasons = fs108.filter((s) => !s.agree).map((s) => [s.scorer, s.reason]);
47038
47983
  const mean_rounded = pyRound(mean2, 2);
47039
47984
  out.set(
47040
47985
  fid,
@@ -47474,26 +48419,26 @@ One sentence, and the single strongest reason.`;
47474
48419
  });
47475
48420
 
47476
48421
  // src/scripts/ai_council/recouncil_guard.ts
47477
- import * as fs95 from "node:fs";
47478
- import * as path93 from "node:path";
48422
+ import * as fs97 from "node:fs";
48423
+ import * as path95 from "node:path";
47479
48424
  function configFingerprint(members, rounds) {
47480
48425
  return `${[...members].sort().join(",")}|rounds=${String(rounds)}`;
47481
48426
  }
47482
48427
  function readPriorRuns(responsesDir, repoRoot) {
47483
48428
  let names;
47484
48429
  try {
47485
- names = fs95.readdirSync(responsesDir).filter((f) => f.endsWith(".md"));
48430
+ names = fs97.readdirSync(responsesDir).filter((f) => f.endsWith(".md"));
47486
48431
  } catch {
47487
48432
  return [];
47488
48433
  }
47489
48434
  const out = [];
47490
48435
  for (const name of names) {
47491
- const abs = path93.join(responsesDir, name);
48436
+ const abs = path95.join(responsesDir, name);
47492
48437
  let head;
47493
48438
  let stat;
47494
48439
  try {
47495
- stat = fs95.statSync(abs);
47496
- const text = fs95.readFileSync(abs, "utf8");
48440
+ stat = fs97.statSync(abs);
48441
+ const text = fs97.readFileSync(abs, "utf8");
47497
48442
  const json = _leadingJson(text);
47498
48443
  if (json === null) continue;
47499
48444
  head = JSON.parse(json);
@@ -47507,7 +48452,7 @@ function readPriorRuns(responsesDir, repoRoot) {
47507
48452
  let questionText = null;
47508
48453
  if (questionPath !== "") {
47509
48454
  try {
47510
- const q = fs95.readFileSync(path93.join(repoRoot, questionPath), "utf8");
48455
+ const q = fs97.readFileSync(path95.join(repoRoot, questionPath), "utf8");
47511
48456
  questionHash = _sha256_hex(q);
47512
48457
  questionText = q;
47513
48458
  } catch {
@@ -47588,14 +48533,14 @@ function warnIfRecounciled(repoRoot, questionFile, fallbackText, members, rounds
47588
48533
  try {
47589
48534
  let text = fallbackText;
47590
48535
  try {
47591
- text = fs95.readFileSync(path93.resolve(repoRoot, questionFile), "utf8");
48536
+ text = fs97.readFileSync(path95.resolve(repoRoot, questionFile), "utf8");
47592
48537
  } catch {
47593
48538
  }
47594
48539
  const v = checkRecouncil(
47595
48540
  text,
47596
48541
  // `name/model` — the SAME shape the artefact writer records.
47597
48542
  configFingerprint(members.map((m) => `${m.name}/${m.model}`), rounds),
47598
- readPriorRuns(path93.join(repoRoot, "agents/runtime/council/responses"), repoRoot)
48543
+ readPriorRuns(path95.join(repoRoot, "agents/runtime/council/responses"), repoRoot)
47599
48544
  );
47600
48545
  if (v !== null) write(renderRecouncilWarning(v));
47601
48546
  } catch {
@@ -47707,7 +48652,7 @@ function _pyReprStr2(s) {
47707
48652
  function _pyRepr9(value) {
47708
48653
  return value === null ? "None" : _pyReprStr2(value);
47709
48654
  }
47710
- function _splitlines9(text) {
48655
+ function _splitlines10(text) {
47711
48656
  if (text === "") {
47712
48657
  return [];
47713
48658
  }
@@ -47787,7 +48732,7 @@ function _strip_host_identity(text) {
47787
48732
  return text;
47788
48733
  }
47789
48734
  const kept = [];
47790
- for (const line of _splitlines9(text)) {
48735
+ for (const line of _splitlines10(text)) {
47791
48736
  const low = line.toLowerCase();
47792
48737
  if (HOST_AGENT_IDENTITY_PATTERNS.some((needle) => low.includes(needle))) {
47793
48738
  continue;
@@ -47816,7 +48761,7 @@ function handoff_preamble(project, original_ask) {
47816
48761
  }
47817
48762
  const cleaned_ask = _pyStrip3(_strip_host_identity(original_ask || ""));
47818
48763
  if (cleaned_ask) {
47819
- const quoted = _splitlines9(cleaned_ask).map((ln) => `> ${ln}`).join("\n");
48764
+ const quoted = _splitlines10(cleaned_ask).map((ln) => `> ${ln}`).join("\n");
47820
48765
  blocks.push(`The user originally asked:
47821
48766
  ${quoted}`);
47822
48767
  }
@@ -48224,8 +49169,8 @@ not. Cite the peer-reviewer label and the targeted response label
48224
49169
  });
48225
49170
 
48226
49171
  // src/scripts/ai_council/advisors.ts
48227
- import * as fs96 from "node:fs";
48228
- import * as path94 from "node:path";
49172
+ import * as fs98 from "node:fs";
49173
+ import * as path96 from "node:path";
48229
49174
  function _split_frontmatter2(raw) {
48230
49175
  const match = _FRONTMATTER_RE2.exec(raw);
48231
49176
  if (!match) {
@@ -48253,12 +49198,12 @@ function _display_name_from(advisor_name, frontmatter) {
48253
49198
  }
48254
49199
  function resolve_persona_text(persona_path, repo_root2) {
48255
49200
  const candidates = [
48256
- path94.join(repo_root2, "dist/agent-src", persona_path),
48257
- path94.join(repo_root2, ".agent-src.uncondensed", persona_path)
49201
+ path96.join(repo_root2, "dist/agent-src", persona_path),
49202
+ path96.join(repo_root2, ".agent-src.uncondensed", persona_path)
48258
49203
  ];
48259
49204
  for (const candidate of candidates) {
48260
- if (fs96.existsSync(candidate)) {
48261
- const raw = fs96.readFileSync(candidate, "utf-8");
49205
+ if (fs98.existsSync(candidate)) {
49206
+ const raw = fs98.readFileSync(candidate, "utf-8");
48262
49207
  const [meta, body] = _split_frontmatter2(raw);
48263
49208
  return [body.trim(), meta];
48264
49209
  }
@@ -49066,15 +50011,15 @@ var init_qualification = __esm({
49066
50011
  });
49067
50012
 
49068
50013
  // src/scripts/ai_council/probe_store.ts
49069
- import fs97 from "node:fs";
49070
- import path95 from "node:path";
50014
+ import fs99 from "node:fs";
50015
+ import path97 from "node:path";
49071
50016
  function probeStorePath(root) {
49072
- return path95.join(root, PROBE_STORE_RELPATH);
50017
+ return path97.join(root, PROBE_STORE_RELPATH);
49073
50018
  }
49074
50019
  function readProbeStore(root) {
49075
50020
  let raw;
49076
50021
  try {
49077
- raw = fs97.readFileSync(probeStorePath(root), "utf8");
50022
+ raw = fs99.readFileSync(probeStorePath(root), "utf8");
49078
50023
  } catch {
49079
50024
  return EMPTY;
49080
50025
  }
@@ -49124,8 +50069,8 @@ function recordProbes(root, entries) {
49124
50069
  members[e.name] = { at: e.at, outcome: e.outcome };
49125
50070
  }
49126
50071
  const target = probeStorePath(root);
49127
- fs97.mkdirSync(path95.dirname(target), { recursive: true });
49128
- fs97.writeFileSync(target, `${JSON.stringify({ schema: 1, members }, null, 2)}
50072
+ fs99.mkdirSync(path97.dirname(target), { recursive: true });
50073
+ fs99.writeFileSync(target, `${JSON.stringify({ schema: 1, members }, null, 2)}
49129
50074
  `, "utf8");
49130
50075
  } catch {
49131
50076
  }
@@ -49139,7 +50084,7 @@ var init_probe_store = __esm({
49139
50084
  "use strict";
49140
50085
  init_env_kill_switch();
49141
50086
  _KILL_SWITCH_ENV2 = "AGENT_CONFIG_NO_EVENTS_LOG";
49142
- PROBE_STORE_RELPATH = path95.join("agents", "runtime", "state", "council-probes.json");
50087
+ PROBE_STORE_RELPATH = path97.join("agents", "runtime", "state", "council-probes.json");
49143
50088
  EMPTY = { schema: 1, members: {} };
49144
50089
  VALID_OUTCOMES = /* @__PURE__ */ new Set([
49145
50090
  "ok",
@@ -49443,10 +50388,10 @@ var init_council_fallback_posture = __esm({
49443
50388
  });
49444
50389
 
49445
50390
  // src/scripts/_lib/billing_grant.ts
49446
- import * as fs98 from "node:fs";
49447
- import * as path96 from "node:path";
50391
+ import * as fs100 from "node:fs";
50392
+ import * as path98 from "node:path";
49448
50393
  function grantFile(repoRoot, runId) {
49449
- return path96.join(
50394
+ return path98.join(
49450
50395
  repoRoot,
49451
50396
  BILLING_GRANT_DIR_REL,
49452
50397
  `${runId.replace(/[^A-Za-z0-9_-]/g, "_")}.json`
@@ -49454,17 +50399,17 @@ function grantFile(repoRoot, runId) {
49454
50399
  }
49455
50400
  function issueBillingGrant(repoRoot, runId, now = () => /* @__PURE__ */ new Date()) {
49456
50401
  const file = grantFile(repoRoot, runId);
49457
- const existing = _read(file);
50402
+ const existing = _read2(file);
49458
50403
  if (existing !== null && existing.run_id === runId) return existing;
49459
50404
  const grant = { run_id: runId, issued_at: now().toISOString() };
49460
- fs98.mkdirSync(path96.dirname(file), { recursive: true });
49461
- fs98.writeFileSync(file, `${JSON.stringify(grant, null, 2)}
50405
+ fs100.mkdirSync(path98.dirname(file), { recursive: true });
50406
+ fs100.writeFileSync(file, `${JSON.stringify(grant, null, 2)}
49462
50407
  `, "utf8");
49463
50408
  return grant;
49464
50409
  }
49465
50410
  function isBillingGrantActive(repoRoot, runId, env = process.env, now = () => /* @__PURE__ */ new Date()) {
49466
50411
  if ((env[BILLING_GRANT_ENV] ?? "").trim() !== runId) return false;
49467
- const grant = _read(grantFile(repoRoot, runId));
50412
+ const grant = _read2(grantFile(repoRoot, runId));
49468
50413
  if (grant === null || grant.run_id !== runId) return false;
49469
50414
  const age = now().getTime() - Date.parse(grant.issued_at);
49470
50415
  return Number.isFinite(age) && age >= 0 && age <= BILLING_GRANT_MAX_AGE_MS;
@@ -49476,13 +50421,13 @@ function hasBillingGrant(repoRoot, env = process.env, now = () => /* @__PURE__ *
49476
50421
  }
49477
50422
  function revokeBillingGrant(repoRoot, runId) {
49478
50423
  try {
49479
- fs98.unlinkSync(grantFile(repoRoot, runId));
50424
+ fs100.unlinkSync(grantFile(repoRoot, runId));
49480
50425
  } catch {
49481
50426
  }
49482
50427
  }
49483
- function _read(file) {
50428
+ function _read2(file) {
49484
50429
  try {
49485
- const raw = JSON.parse(fs98.readFileSync(file, "utf8"));
50430
+ const raw = JSON.parse(fs100.readFileSync(file, "utf8"));
49486
50431
  if (raw === null || typeof raw !== "object") return null;
49487
50432
  const o = raw;
49488
50433
  if (typeof o.run_id !== "string" || typeof o.issued_at !== "string") return null;
@@ -49503,7 +50448,7 @@ var init_billing_grant = __esm({
49503
50448
  "src/scripts/_lib/billing_grant.ts"() {
49504
50449
  "use strict";
49505
50450
  BILLING_GRANT_ENV = "AC_BILLING_GRANT";
49506
- BILLING_GRANT_DIR_REL = path96.join("agents", "runtime", "billing-grants");
50451
+ BILLING_GRANT_DIR_REL = path98.join("agents", "runtime", "billing-grants");
49507
50452
  BILLING_GRANT_MAX_AGE_MS = 24 * 60 * 60 * 1e3;
49508
50453
  }
49509
50454
  });
@@ -49592,10 +50537,10 @@ var init_council_fallback_wiring = __esm({
49592
50537
  });
49593
50538
 
49594
50539
  // src/scripts/_lib/quota_parked.ts
49595
- import * as fs99 from "node:fs";
49596
- import * as path97 from "node:path";
50540
+ import * as fs101 from "node:fs";
50541
+ import * as path99 from "node:path";
49597
50542
  function markerFile(repoRoot, runId) {
49598
- return path97.join(
50543
+ return path99.join(
49599
50544
  repoRoot,
49600
50545
  QUOTA_PARKED_DIR_REL,
49601
50546
  `${runId.replace(/[^A-Za-z0-9_-]/g, "_")}.json`
@@ -49610,14 +50555,14 @@ function writeQuotaParked(repoRoot, runId, providers, now = () => /* @__PURE__ *
49610
50555
  providers: merged,
49611
50556
  parked_at: existing?.parked_at ?? now().toISOString()
49612
50557
  };
49613
- fs99.mkdirSync(path97.dirname(file), { recursive: true });
49614
- fs99.writeFileSync(file, `${JSON.stringify(marker, null, 2)}
50558
+ fs101.mkdirSync(path99.dirname(file), { recursive: true });
50559
+ fs101.writeFileSync(file, `${JSON.stringify(marker, null, 2)}
49615
50560
  `, "utf8");
49616
50561
  return marker;
49617
50562
  }
49618
50563
  function readMarker(file) {
49619
50564
  try {
49620
- const raw = JSON.parse(fs99.readFileSync(file, "utf8"));
50565
+ const raw = JSON.parse(fs101.readFileSync(file, "utf8"));
49621
50566
  if (raw === null || typeof raw !== "object") return null;
49622
50567
  const o = raw;
49623
50568
  if (typeof o["run_id"] !== "string" || typeof o["parked_at"] !== "string") return null;
@@ -49632,7 +50577,7 @@ var QUOTA_PARKED_DIR_REL;
49632
50577
  var init_quota_parked = __esm({
49633
50578
  "src/scripts/_lib/quota_parked.ts"() {
49634
50579
  "use strict";
49635
- QUOTA_PARKED_DIR_REL = path97.join("agents", "runtime", "state", "quota-parked");
50580
+ QUOTA_PARKED_DIR_REL = path99.join("agents", "runtime", "state", "quota-parked");
49636
50581
  }
49637
50582
  });
49638
50583
 
@@ -49702,7 +50647,7 @@ __export(low_impact_corpus_exports, {
49702
50647
  load_validated_phrases: () => load_validated_phrases,
49703
50648
  parse_corpus_strict: () => parse_corpus_strict
49704
50649
  });
49705
- import * as fs100 from "node:fs";
50650
+ import * as fs102 from "node:fs";
49706
50651
  function _entry(phrase, normalised, section, line_no, trailing_metadata = "") {
49707
50652
  return { phrase, normalised, section, line_no, trailing_metadata };
49708
50653
  }
@@ -49749,7 +50694,7 @@ function _lineNoAt(text, offset) {
49749
50694
  }
49750
50695
  return count + 1;
49751
50696
  }
49752
- function _splitlines10(s) {
50697
+ function _splitlines11(s) {
49753
50698
  if (s === "") {
49754
50699
  return [];
49755
50700
  }
@@ -49764,7 +50709,7 @@ function _scanSection(text, section, bodyStart, bodyEnd, strict) {
49764
50709
  const warnings = [];
49765
50710
  const body = text.slice(bodyStart, bodyEnd);
49766
50711
  const baseLine = _lineNoAt(text, bodyStart);
49767
- const bodyLines = _splitlines10(body);
50712
+ const bodyLines = _splitlines11(body);
49768
50713
  for (let offset = 0; offset < bodyLines.length; offset += 1) {
49769
50714
  const rawLine = bodyLines[offset];
49770
50715
  const lineNo = baseLine + offset;
@@ -49875,10 +50820,10 @@ function _checkHeadingDrift(text, title) {
49875
50820
  }
49876
50821
  function parse_corpus_strict(corpusPath) {
49877
50822
  const p = corpusPath;
49878
- if (!fs100.existsSync(p)) {
50823
+ if (!fs102.existsSync(p)) {
49879
50824
  return new CorpusParseResult();
49880
50825
  }
49881
- const text = fs100.readFileSync(p, { encoding: "utf-8" });
50826
+ const text = fs102.readFileSync(p, { encoding: "utf-8" });
49882
50827
  const allTitles = _SECTION_KEYS.map((k) => _SECTION_TITLES[k]);
49883
50828
  const resultSections = {
49884
50829
  validated: [],
@@ -49941,10 +50886,10 @@ function load_anti_example_phrases(corpusPath) {
49941
50886
  }
49942
50887
  function load_corpus_lock(yamlPath) {
49943
50888
  const p = yamlPath;
49944
- if (!fs100.existsSync(p)) {
50889
+ if (!fs102.existsSync(p)) {
49945
50890
  return new CorpusParseResult();
49946
50891
  }
49947
- const parsed = (0, import_yaml8.parse)(fs100.readFileSync(p, { encoding: "utf-8" }), { version: "1.1" });
50892
+ const parsed = (0, import_yaml8.parse)(fs102.readFileSync(p, { encoding: "utf-8" }), { version: "1.1" });
49948
50893
  const doc = parsed === null || parsed === void 0 ? {} : parsed;
49949
50894
  const schemaVersion = doc["schema_version"];
49950
50895
  if (schemaVersion !== 1) {
@@ -50006,7 +50951,7 @@ function _deriveLockPath(corpusPath) {
50006
50951
  }
50007
50952
  function _loadSectionFromLock(corpusPath, section) {
50008
50953
  const lockPath = _deriveLockPath(corpusPath);
50009
- if (!fs100.existsSync(lockPath)) {
50954
+ if (!fs102.existsSync(lockPath)) {
50010
50955
  return null;
50011
50956
  }
50012
50957
  try {
@@ -50018,10 +50963,10 @@ function _loadSectionFromLock(corpusPath, section) {
50018
50963
  }
50019
50964
  function _loadSectionLenient(corpusPath, section) {
50020
50965
  const p = corpusPath;
50021
- if (!fs100.existsSync(p)) {
50966
+ if (!fs102.existsSync(p)) {
50022
50967
  return [];
50023
50968
  }
50024
- const text = fs100.readFileSync(p, { encoding: "utf-8" });
50969
+ const text = fs102.readFileSync(p, { encoding: "utf-8" });
50025
50970
  const allTitles = _SECTION_KEYS.map((k) => _SECTION_TITLES[k]);
50026
50971
  const bounds = _sectionBounds(text, _SECTION_TITLES[section], allTitles);
50027
50972
  if (bounds === null) {
@@ -51149,8 +52094,8 @@ var init_consensus_round = __esm({
51149
52094
  });
51150
52095
 
51151
52096
  // src/scripts/ai_council/budget_guard.ts
51152
- import * as fs101 from "node:fs";
51153
- import * as path98 from "node:path";
52097
+ import * as fs103 from "node:fs";
52098
+ import * as path100 from "node:path";
51154
52099
  function _resolveLedgerPath(p) {
51155
52100
  if (p !== null) {
51156
52101
  return p;
@@ -51165,18 +52110,18 @@ function _nowUtcMs() {
51165
52110
  return Date.now();
51166
52111
  }
51167
52112
  function _ensureLedgerDir(p) {
51168
- const parent = path98.dirname(p);
52113
+ const parent = path100.dirname(p);
51169
52114
  try {
51170
- fs101.mkdirSync(parent, { recursive: true });
52115
+ fs103.mkdirSync(parent, { recursive: true });
51171
52116
  let mode;
51172
52117
  try {
51173
- mode = fs101.statSync(parent).mode & 511;
52118
+ mode = fs103.statSync(parent).mode & 511;
51174
52119
  } catch {
51175
52120
  mode = 448;
51176
52121
  }
51177
52122
  if (mode !== 448) {
51178
52123
  try {
51179
- fs101.chmodSync(parent, 448);
52124
+ fs103.chmodSync(parent, 448);
51180
52125
  } catch {
51181
52126
  }
51182
52127
  }
@@ -51188,18 +52133,18 @@ function _ensureLedgerDir(p) {
51188
52133
  }
51189
52134
  }
51190
52135
  function _ensureLedgerFileMode(p) {
51191
- if (!fs101.existsSync(p)) {
52136
+ if (!fs103.existsSync(p)) {
51192
52137
  return;
51193
52138
  }
51194
52139
  let current;
51195
52140
  try {
51196
- current = fs101.statSync(p).mode & 511;
52141
+ current = fs103.statSync(p).mode & 511;
51197
52142
  } catch {
51198
52143
  return;
51199
52144
  }
51200
52145
  if (current !== 384) {
51201
52146
  try {
51202
- fs101.chmodSync(p, 384);
52147
+ fs103.chmodSync(p, 384);
51203
52148
  } catch {
51204
52149
  }
51205
52150
  }
@@ -51351,11 +52296,11 @@ function pyNumToStr(n) {
51351
52296
  }
51352
52297
  function read_entries2(p = null) {
51353
52298
  const resolved = _resolveLedgerPath(p);
51354
- if (!fs101.existsSync(resolved)) {
52299
+ if (!fs103.existsSync(resolved)) {
51355
52300
  return [];
51356
52301
  }
51357
52302
  const out = [];
51358
- const text = fs101.readFileSync(resolved, "utf-8");
52303
+ const text = fs103.readFileSync(resolved, "utf-8");
51359
52304
  for (const rawLine of text.split(/\r\n|\r|\n/u)) {
51360
52305
  const line = rawLine.trim();
51361
52306
  if (line === "") {
@@ -51458,7 +52403,7 @@ function record_spend(usd, provider, model, options = {}) {
51458
52403
  )}
51459
52404
  `;
51460
52405
  try {
51461
- fs101.appendFileSync(p, entry, { encoding: "utf-8" });
52406
+ fs103.appendFileSync(p, entry, { encoding: "utf-8" });
51462
52407
  } catch (exc) {
51463
52408
  process.stderr.write(`[council:budget_guard] write failed: ${_errStr(exc)}
51464
52409
  `);
@@ -53119,18 +54064,18 @@ __export(project_context_exports, {
53119
54064
  REPO_PURPOSE_MAX_CHARS: () => REPO_PURPOSE_MAX_CHARS,
53120
54065
  detect_project_context: () => detect_project_context
53121
54066
  });
53122
- import * as fs102 from "node:fs";
53123
- import * as path99 from "node:path";
54067
+ import * as fs104 from "node:fs";
54068
+ import * as path101 from "node:path";
53124
54069
  function _isPlainObject11(v) {
53125
54070
  return typeof v === "object" && v !== null && !Array.isArray(v);
53126
54071
  }
53127
54072
  function _read_json(p) {
53128
- if (!fs102.existsSync(p)) {
54073
+ if (!fs104.existsSync(p)) {
53129
54074
  return null;
53130
54075
  }
53131
54076
  let raw;
53132
54077
  try {
53133
- raw = fs102.readFileSync(p, "utf-8");
54078
+ raw = fs104.readFileSync(p, "utf-8");
53134
54079
  } catch {
53135
54080
  return null;
53136
54081
  }
@@ -53152,7 +54097,7 @@ function _name_from(composer, pkg, root) {
53152
54097
  }
53153
54098
  }
53154
54099
  try {
53155
- const base = path99.basename(root);
54100
+ const base = path101.basename(root);
53156
54101
  return base || null;
53157
54102
  } catch {
53158
54103
  return null;
@@ -53210,7 +54155,7 @@ function _stack_from(composer, pkg) {
53210
54155
  }
53211
54156
  return parts.join(" \xB7 ");
53212
54157
  }
53213
- function _splitlines11(text) {
54158
+ function _splitlines12(text) {
53214
54159
  if (text === "") {
53215
54160
  return [];
53216
54161
  }
@@ -53221,17 +54166,17 @@ function _splitlines11(text) {
53221
54166
  return parts;
53222
54167
  }
53223
54168
  function _purpose_from_readme(p) {
53224
- if (!fs102.existsSync(p)) {
54169
+ if (!fs104.existsSync(p)) {
53225
54170
  return null;
53226
54171
  }
53227
54172
  let text;
53228
54173
  try {
53229
- text = fs102.readFileSync(p, "utf-8");
54174
+ text = fs104.readFileSync(p, "utf-8");
53230
54175
  } catch {
53231
54176
  return null;
53232
54177
  }
53233
54178
  const paragraph = [];
53234
- for (const raw of _splitlines11(text)) {
54179
+ for (const raw of _splitlines12(text)) {
53235
54180
  const stripped = raw.trim();
53236
54181
  if (!stripped) {
53237
54182
  if (paragraph.length > 0) {
@@ -53310,13 +54255,13 @@ function _rfind(haystack, needle) {
53310
54255
  return -1;
53311
54256
  }
53312
54257
  function detect_project_context(root) {
53313
- const resolvedRoot = path99.resolve(root ?? process.cwd());
53314
- const composer = _read_json(path99.join(resolvedRoot, "composer.json"));
53315
- const pkg = _read_json(path99.join(resolvedRoot, "package.json"));
54258
+ const resolvedRoot = path101.resolve(root ?? process.cwd());
54259
+ const composer = _read_json(path101.join(resolvedRoot, "composer.json"));
54260
+ const pkg = _read_json(path101.join(resolvedRoot, "package.json"));
53316
54261
  return new ProjectContext(
53317
54262
  _name_from(composer, pkg, resolvedRoot),
53318
54263
  _stack_from(composer, pkg),
53319
- _purpose_from_readme(path99.join(resolvedRoot, "README.md"))
54264
+ _purpose_from_readme(path101.join(resolvedRoot, "README.md"))
53320
54265
  );
53321
54266
  }
53322
54267
  var REPO_PURPOSE_MAX_CHARS, _HEADING_RE, _BADGE_RE, _HTML_RE, ProjectContext;
@@ -53586,7 +54531,7 @@ __export(shadow_dispatch_exports, {
53586
54531
  slo_banner: () => slo_banner,
53587
54532
  slo_status: () => slo_status
53588
54533
  });
53589
- import * as fs103 from "node:fs";
54534
+ import * as fs105 from "node:fs";
53590
54535
  import { createHash as createHash16 } from "node:crypto";
53591
54536
  function should_shadow(sampleRate, opts = {}) {
53592
54537
  const rate = Math.max(0, Math.min(1, sampleRate));
@@ -53624,7 +54569,7 @@ function record_shadow_decision(logPath, opts) {
53624
54569
  escalated,
53625
54570
  escalation_reason: escalationReason
53626
54571
  };
53627
- fs103.mkdirSync(_dirname2(logPath), { recursive: true });
54572
+ fs105.mkdirSync(_dirname2(logPath), { recursive: true });
53628
54573
  const row = _pyJsonDumps2({
53629
54574
  timestamp: decision.timestamp,
53630
54575
  query_hash: decision.query_hash,
@@ -53634,7 +54579,7 @@ function record_shadow_decision(logPath, opts) {
53634
54579
  escalated: decision.escalated,
53635
54580
  escalation_reason: decision.escalation_reason
53636
54581
  }) + "\n";
53637
- fs103.appendFileSync(logPath, row, { encoding: "utf-8" });
54582
+ fs105.appendFileSync(logPath, row, { encoding: "utf-8" });
53638
54583
  return decision;
53639
54584
  }
53640
54585
  function _isoNowSeconds() {
@@ -53643,11 +54588,11 @@ function _isoNowSeconds() {
53643
54588
  return `${pad(d.getUTCFullYear(), 4)}-${pad(d.getUTCMonth() + 1)}-${pad(d.getUTCDate())}T${pad(d.getUTCHours())}:${pad(d.getUTCMinutes())}:${pad(d.getUTCSeconds())}+00:00`;
53644
54589
  }
53645
54590
  function* _iterLog(logPath) {
53646
- if (!fs103.existsSync(logPath)) {
54591
+ if (!fs105.existsSync(logPath)) {
53647
54592
  return;
53648
54593
  }
53649
- const content = fs103.readFileSync(logPath, { encoding: "utf-8" });
53650
- for (const rawLine of _splitlines12(content)) {
54594
+ const content = fs105.readFileSync(logPath, { encoding: "utf-8" });
54595
+ for (const rawLine of _splitlines13(content)) {
53651
54596
  const line = _strip8(rawLine);
53652
54597
  if (!line) {
53653
54598
  continue;
@@ -53842,7 +54787,7 @@ function _dirname2(p) {
53842
54787
  function _strip8(s) {
53843
54788
  return s.trim();
53844
54789
  }
53845
- function _splitlines12(s) {
54790
+ function _splitlines13(s) {
53846
54791
  if (s === "") {
53847
54792
  return [];
53848
54793
  }
@@ -54001,7 +54946,7 @@ function _pySlice3(s, n) {
54001
54946
  function _pyStrip8(s) {
54002
54947
  return s.trim();
54003
54948
  }
54004
- function _splitlines13(s) {
54949
+ function _splitlines14(s) {
54005
54950
  if (s === "") {
54006
54951
  return [];
54007
54952
  }
@@ -54063,7 +55008,7 @@ function _aborted_marker(reason, members) {
54063
55008
  return `> Low-impact council aborted (${reason}) \u2014 escalating to user: members tried: ${names}.`;
54064
55009
  }
54065
55010
  function _split_marker(answers) {
54066
- const parts = answers.filter((a) => a.ok).map((a) => `${a.member}: ${_pySlice3(_pyStrip8(_splitlines13(a.text)[0] ?? ""), 80)}`).join(" / ");
55011
+ const parts = answers.filter((a) => a.ok).map((a) => `${a.member}: ${_pySlice3(_pyStrip8(_splitlines14(a.text)[0] ?? ""), 80)}`).join(" / ");
54067
55012
  return `> Low-impact council split \u2014 escalating to user (${parts}):`;
54068
55013
  }
54069
55014
  function _unavailable_marker() {
@@ -54079,7 +55024,7 @@ function _resolved_marker(ok_answers) {
54079
55024
  return `> Resolved via low-impact council fast-path: ${verdict}.`;
54080
55025
  }
54081
55026
  function _answer_line(text) {
54082
- for (const line of _splitlines13(text)) {
55027
+ for (const line of _splitlines14(text)) {
54083
55028
  const stripped = _pyStrip8(line);
54084
55029
  if (stripped !== "") {
54085
55030
  return stripped;
@@ -54307,7 +55252,7 @@ function parse_low_impact_log(text) {
54307
55252
  const by_member = /* @__PURE__ */ new Map();
54308
55253
  let total = 0;
54309
55254
  let total_cost = 0;
54310
- for (const raw of _splitlines13(text)) {
55255
+ for (const raw of _splitlines14(text)) {
54311
55256
  const m = _LOG_LINE_RE.exec(_pyStrip8(raw));
54312
55257
  if (!m) {
54313
55258
  continue;
@@ -54571,11 +55516,11 @@ __export(council_cli_exports, {
54571
55516
  cmd_status: () => cmd_status,
54572
55517
  format_estimate_table: () => format_estimate_table,
54573
55518
  load_settings: () => load_settings,
54574
- main: () => main38
55519
+ main: () => main39
54575
55520
  });
54576
- import * as fs104 from "node:fs";
54577
- import * as path100 from "node:path";
54578
- import { fileURLToPath as fileURLToPath50, pathToFileURL as pathToFileURL35 } from "node:url";
55521
+ import * as fs106 from "node:fs";
55522
+ import * as path102 from "node:path";
55523
+ import { fileURLToPath as fileURLToPath51, pathToFileURL as pathToFileURL36 } from "node:url";
54579
55524
  function _pyFixed6(x, ndigits) {
54580
55525
  if (!Number.isFinite(x)) {
54581
55526
  return String(x);
@@ -54783,7 +55728,7 @@ function _stderr2(s) {
54783
55728
  function load_settings(p = SETTINGS_FILE2, opts = {}) {
54784
55729
  const ai_council_path = opts.ai_council_path ?? AI_COUNCIL_FILE;
54785
55730
  const settings = load_agent_settings({ project_path: p });
54786
- if (fs104.existsSync(ai_council_path)) {
55731
+ if (fs106.existsSync(ai_council_path)) {
54787
55732
  const cfg = load_council_config(ai_council_path);
54788
55733
  settings["ai_council"] = synthesizeAiCouncilBlock(cfg);
54789
55734
  }
@@ -55149,7 +56094,7 @@ function build_question(opts) {
55149
56094
  let ctx;
55150
56095
  let artefact;
55151
56096
  if (input_mode === "prompt") {
55152
- const text = fs104.readFileSync(input_path, "utf-8");
56097
+ const text = fs106.readFileSync(input_path, "utf-8");
55153
56098
  ctx = bundle_prompt(text);
55154
56099
  artefact = String(input_path);
55155
56100
  } else if (input_mode === "roadmap") {
@@ -55293,9 +56238,9 @@ function _maybe_write_decision_replay(opts) {
55293
56238
  include_member_arguments: include_args
55294
56239
  })
55295
56240
  );
55296
- const target = path100.join(path100.dirname(opts.out_path), "decision-replay.md");
55297
- fs104.mkdirSync(path100.dirname(target), { recursive: true });
55298
- fs104.writeFileSync(target, replay, { encoding: "utf-8" });
56241
+ const target = path102.join(path102.dirname(opts.out_path), "decision-replay.md");
56242
+ fs106.mkdirSync(path102.dirname(target), { recursive: true });
56243
+ fs106.writeFileSync(target, replay, { encoding: "utf-8" });
55299
56244
  return target;
55300
56245
  }
55301
56246
  function _peer_review_active(ai_cfg, args) {
@@ -55968,7 +56913,7 @@ function cmd_status(args, opts = {}) {
55968
56913
  const env = opts.env ?? process.env;
55969
56914
  const override = env[COUNCIL_CONFIG_ENV];
55970
56915
  const path_ = resolve_config_path(REPO_ROOT12, { env });
55971
- const exists3 = fs104.existsSync(String(path_));
56916
+ const exists3 = fs106.existsSync(String(path_));
55972
56917
  const provenance = override ? `${COUNCIL_CONFIG_ENV} override` : "user-global";
55973
56918
  let cfg = null;
55974
56919
  let parse_error = null;
@@ -56436,8 +57381,8 @@ function cmd_run(args, opts = {}) {
56436
57381
  kind: "responses",
56437
57382
  subcommand: "run"
56438
57383
  });
56439
- fs104.mkdirSync(path100.dirname(_resolveTarget(out_path)), { recursive: true });
56440
- fs104.writeFileSync(_resolveTarget(out_path), _jsonDumpsIndent2(payload) + "\n", { encoding: "utf-8" });
57384
+ fs106.mkdirSync(path102.dirname(_resolveTarget(out_path)), { recursive: true });
57385
+ fs106.writeFileSync(_resolveTarget(out_path), _jsonDumpsIndent2(payload) + "\n", { encoding: "utf-8" });
56441
57386
  const _all_subscription = allSeatsNonBillable(all_responses);
56442
57387
  _stdout2(
56443
57388
  `
@@ -56463,7 +57408,7 @@ function _debate_round_filename(round_number) {
56463
57408
  return `debate-round-${round_number}.json`;
56464
57409
  }
56465
57410
  function _write_debate_round(out_dir, round_number, responses, opts) {
56466
- fs104.mkdirSync(_resolveTarget(out_dir), { recursive: true });
57411
+ fs106.mkdirSync(_resolveTarget(out_dir), { recursive: true });
56467
57412
  const actual_total = sumBillableCost(responses, opts.table);
56468
57413
  const payload = {
56469
57414
  schema_version: SCHEMA_VERSION9,
@@ -56480,15 +57425,15 @@ function _write_debate_round(out_dir, round_number, responses, opts) {
56480
57425
  prompt_cache_round_gap_ms: opts.cache_gap_ms_since_previous_round ?? null,
56481
57426
  responses: serializeResponses(responses)
56482
57427
  };
56483
- const out_path = path100.join(_resolveTarget(out_dir), _debate_round_filename(round_number));
56484
- fs104.writeFileSync(out_path, _jsonDumpsIndent2(payload) + "\n", { encoding: "utf-8" });
57428
+ const out_path = path102.join(_resolveTarget(out_dir), _debate_round_filename(round_number));
57429
+ fs106.writeFileSync(out_path, _jsonDumpsIndent2(payload) + "\n", { encoding: "utf-8" });
56485
57430
  return out_path;
56486
57431
  }
56487
57432
  function _load_debate_seed(p, expected_members) {
56488
- if (!fs104.existsSync(p)) {
57433
+ if (!fs106.existsSync(p)) {
56489
57434
  throw new FileNotFoundError3(`--continue-as-debate path not found: ${p}`);
56490
57435
  }
56491
- const payload = JSON.parse(fs104.readFileSync(p, "utf-8"));
57436
+ const payload = JSON.parse(fs106.readFileSync(p, "utf-8"));
56492
57437
  const source_members = (payload["members"] || []).slice();
56493
57438
  const expected_labels = expected_members.map((m) => `${m.name}/${m.model}`);
56494
57439
  if (!_listEq(source_members, expected_labels)) {
@@ -56534,7 +57479,7 @@ function _readStdinLine() {
56534
57479
  try {
56535
57480
  const buf = Buffer.alloc(4096);
56536
57481
  const fd = 0;
56537
- const n = fs104.readSync(fd, buf, 0, buf.length, null);
57482
+ const n = fs106.readSync(fd, buf, 0, buf.length, null);
56538
57483
  return buf.toString("utf-8", 0, n).split("\n")[0]?.trim().toLowerCase() ?? "";
56539
57484
  } catch {
56540
57485
  return "";
@@ -56762,7 +57707,7 @@ council:debate \xB7 ${all_rounds.length} round(s) complete \xB7 actual $${_pyFix
56762
57707
  return errors_last.length > 0 && errors_last.length === last.length ? 1 : 0;
56763
57708
  }
56764
57709
  function cmd_render(args) {
56765
- const payload = JSON.parse(fs104.readFileSync(args.responses, "utf-8"));
57710
+ const payload = JSON.parse(fs106.readFileSync(args.responses, "utf-8"));
56766
57711
  const items = payload["responses"] || [];
56767
57712
  const explicit = _getattr3(args, "prompt_mode", null);
56768
57713
  const mode = explicit || payload["prompt_mode"] || payload["mode"];
@@ -56791,8 +57736,8 @@ function cmd_render(args) {
56791
57736
  kind: "sessions",
56792
57737
  subcommand: "render"
56793
57738
  });
56794
- fs104.mkdirSync(path100.dirname(_resolveTarget(out_path)), { recursive: true });
56795
- fs104.writeFileSync(_resolveTarget(out_path), body + "\n", { encoding: "utf-8" });
57739
+ fs106.mkdirSync(path102.dirname(_resolveTarget(out_path)), { recursive: true });
57740
+ fs106.writeFileSync(_resolveTarget(out_path), body + "\n", { encoding: "utf-8" });
56796
57741
  _stdout2(`council:render \xB7 wrote ${out_path}
56797
57742
  `);
56798
57743
  return 0;
@@ -56803,15 +57748,15 @@ function cmd_render(args) {
56803
57748
  function _cmd_replay_low_impact_stats(args) {
56804
57749
  const li = low_impact_exports;
56805
57750
  const responses_path = args.responses;
56806
- const log_path = path100.join(path100.dirname(responses_path), "low-impact-resolutions.md");
56807
- if (!fs104.existsSync(log_path)) {
57751
+ const log_path = path102.join(path102.dirname(responses_path), "low-impact-resolutions.md");
57752
+ if (!fs106.existsSync(log_path)) {
56808
57753
  _stdout2(
56809
57754
  `council:replay \xB7 no low-impact-resolutions.md alongside ${responses_path} \u2014 session had no fast-path entries.
56810
57755
  `
56811
57756
  );
56812
57757
  return 0;
56813
57758
  }
56814
- const body = fs104.readFileSync(log_path, "utf-8");
57759
+ const body = fs106.readFileSync(log_path, "utf-8");
56815
57760
  const stats = li.parse_low_impact_log(body);
56816
57761
  const out = li.render_low_impact_stats(stats);
56817
57762
  if (_getattr3(args, "output", null)) {
@@ -56819,8 +57764,8 @@ function _cmd_replay_low_impact_stats(args) {
56819
57764
  kind: "sessions",
56820
57765
  subcommand: "replay"
56821
57766
  });
56822
- fs104.mkdirSync(path100.dirname(_resolveTarget(target)), { recursive: true });
56823
- fs104.writeFileSync(_resolveTarget(target), out, { encoding: "utf-8" });
57767
+ fs106.mkdirSync(path102.dirname(_resolveTarget(target)), { recursive: true });
57768
+ fs106.writeFileSync(_resolveTarget(target), out, { encoding: "utf-8" });
56824
57769
  _stdout2(`council:replay \xB7 wrote ${target}
56825
57770
  `);
56826
57771
  return 0;
@@ -56832,7 +57777,7 @@ function cmd_replay(args) {
56832
57777
  if (_getattr3(args, "low_impact_stats", false)) {
56833
57778
  return _cmd_replay_low_impact_stats(args);
56834
57779
  }
56835
- const payload = JSON.parse(fs104.readFileSync(args.responses, "utf-8"));
57780
+ const payload = JSON.parse(fs106.readFileSync(args.responses, "utf-8"));
56836
57781
  const consensus = _deserialise_consensus(payload["consensus"]);
56837
57782
  if (consensus === null) {
56838
57783
  _stderr2(
@@ -56857,8 +57802,8 @@ function cmd_replay(args) {
56857
57802
  kind: "sessions",
56858
57803
  subcommand: "replay"
56859
57804
  });
56860
- fs104.mkdirSync(path100.dirname(_resolveTarget(out_path)), { recursive: true });
56861
- fs104.writeFileSync(_resolveTarget(out_path), body, { encoding: "utf-8" });
57805
+ fs106.mkdirSync(path102.dirname(_resolveTarget(out_path)), { recursive: true });
57806
+ fs106.writeFileSync(_resolveTarget(out_path), body, { encoding: "utf-8" });
56862
57807
  _stdout2(`council:replay \xB7 wrote ${out_path}
56863
57808
  `);
56864
57809
  } else {
@@ -56915,8 +57860,8 @@ function cmd_quota(args, opts = {}) {
56915
57860
  }
56916
57861
  function _validate_council_output_path(path_str, opts) {
56917
57862
  const expected_rel = COUNCIL_CANONICAL_DIRS[opts.kind];
56918
- const expected_abs = _resolveReal(path100.join(REPO_ROOT12, expected_rel));
56919
- const target = path100.isAbsolute(path_str) ? path_str : path100.join(REPO_ROOT12, path_str);
57863
+ const expected_abs = _resolveReal(path102.join(REPO_ROOT12, expected_rel));
57864
+ const target = path102.isAbsolute(path_str) ? path_str : path102.join(REPO_ROOT12, path_str);
56920
57865
  const target_resolved = _resolveReal(target);
56921
57866
  if (!_isRelativeTo(target_resolved, expected_abs)) {
56922
57867
  throw new ArgumentTypeError(
@@ -56926,12 +57871,12 @@ function _validate_council_output_path(path_str, opts) {
56926
57871
  return path_str;
56927
57872
  }
56928
57873
  function _resolveTarget(path_str) {
56929
- return path100.isAbsolute(path_str) ? path_str : path100.join(REPO_ROOT12, path_str);
57874
+ return path102.isAbsolute(path_str) ? path_str : path102.join(REPO_ROOT12, path_str);
56930
57875
  }
56931
57876
  function _resolveReal(p) {
56932
- const abs = path100.resolve(p);
57877
+ const abs = path102.resolve(p);
56933
57878
  try {
56934
- return fs104.realpathSync(abs);
57879
+ return fs106.realpathSync(abs);
56935
57880
  } catch {
56936
57881
  return abs;
56937
57882
  }
@@ -56940,8 +57885,8 @@ function _isRelativeTo(target, base) {
56940
57885
  if (target === base) {
56941
57886
  return true;
56942
57887
  }
56943
- const rel = path100.relative(base, target);
56944
- return rel !== "" && !rel.startsWith("..") && !path100.isAbsolute(rel);
57888
+ const rel = path102.relative(base, target);
57889
+ return rel !== "" && !rel.startsWith("..") && !path102.isAbsolute(rel);
56945
57890
  }
56946
57891
  function _topError(message) {
56947
57892
  _stderr2(_TOP_USAGE2);
@@ -57266,7 +58211,7 @@ function _parse_siblings_overrides(items) {
57266
58211
  function _isFileNotFound(exc) {
57267
58212
  return exc instanceof FileNotFoundError3 || exc instanceof Error && exc.code === "ENOENT";
57268
58213
  }
57269
- function main38(argv = null) {
58214
+ function main39(argv = null) {
57270
58215
  const args = _parseArgs7(argv ?? process.argv.slice(2));
57271
58216
  try {
57272
58217
  if (args.cmd === "estimate") {
@@ -57310,23 +58255,23 @@ function main38(argv = null) {
57310
58255
  }
57311
58256
  return 1;
57312
58257
  }
57313
- function _isCliEntry29() {
58258
+ function _isCliEntry30() {
57314
58259
  if (process.argv[1] === void 0) {
57315
58260
  return false;
57316
58261
  }
57317
- const argvUrl = pathToFileURL35(path100.resolve(process.argv[1])).href;
58262
+ const argvUrl = pathToFileURL36(path102.resolve(process.argv[1])).href;
57318
58263
  if (import.meta.url === argvUrl) {
57319
58264
  return true;
57320
58265
  }
57321
58266
  try {
57322
- const here = fs104.realpathSync(fileURLToPath50(import.meta.url));
57323
- const argv = fs104.realpathSync(path100.resolve(process.argv[1]));
58267
+ const here = fs106.realpathSync(fileURLToPath51(import.meta.url));
58268
+ const argv = fs106.realpathSync(path102.resolve(process.argv[1]));
57324
58269
  return here === argv;
57325
58270
  } catch {
57326
58271
  return false;
57327
58272
  }
57328
58273
  }
57329
- var _ArgExit2, ArgumentTypeError, _PROG9, SCHEMA_VERSION9, _API_PROVIDERS, _CLI_PROVIDERS, _HERE26, REPO_ROOT12, SETTINGS_FILE2, AI_COUNCIL_FILE, COUNCIL_CANONICAL_DIRS, CouncilDisabledError, _CLI_FACTORY, ValueError4, _VALID_ABSENT_REASONS, FileNotFoundError3, _SUBCOMMANDS, _TOP_USAGE2;
58274
+ var _ArgExit2, ArgumentTypeError, _PROG9, SCHEMA_VERSION9, _API_PROVIDERS, _CLI_PROVIDERS, _HERE27, REPO_ROOT12, SETTINGS_FILE2, AI_COUNCIL_FILE, COUNCIL_CANONICAL_DIRS, CouncilDisabledError, _CLI_FACTORY, ValueError4, _VALID_ABSENT_REASONS, FileNotFoundError3, _SUBCOMMANDS, _TOP_USAGE2;
57330
58275
  var init_council_cli = __esm({
57331
58276
  "src/scripts/council_cli.ts"() {
57332
58277
  "use strict";
@@ -57392,7 +58337,7 @@ var init_council_cli = __esm({
57392
58337
  "xai",
57393
58338
  "perplexity"
57394
58339
  ]);
57395
- _HERE26 = path100.dirname(fileURLToPath50(import.meta.url));
58340
+ _HERE27 = path102.dirname(fileURLToPath51(import.meta.url));
57396
58341
  [REPO_ROOT12] = resolve_project_root(null);
57397
58342
  SETTINGS_FILE2 = project_settings_path(REPO_ROOT12);
57398
58343
  AI_COUNCIL_FILE = resolve_config_path(REPO_ROOT12);
@@ -57425,9 +58370,9 @@ var init_council_cli = __esm({
57425
58370
  {estimate,run,debate,render,replay,quota,shadow-report,status}
57426
58371
  ...
57427
58372
  `;
57428
- if (_isCliEntry29()) {
58373
+ if (_isCliEntry30()) {
57429
58374
  try {
57430
- process.exitCode = main38(process.argv.slice(2));
58375
+ process.exitCode = main39(process.argv.slice(2));
57431
58376
  } catch (err) {
57432
58377
  if (!(err instanceof _ArgExit2)) {
57433
58378
  throw err;
@@ -57456,7 +58401,7 @@ function run_enveloped(spec) {
57456
58401
  if (cmd === void 0) {
57457
58402
  throw new Error("envelope argv must not be empty");
57458
58403
  }
57459
- return new Promise((resolve56) => {
58404
+ return new Promise((resolve57) => {
57460
58405
  execFile(
57461
58406
  cmd,
57462
58407
  args,
@@ -57479,7 +58424,7 @@ function run_enveloped(spec) {
57479
58424
  }
57480
58425
  const [out, outTrunc] = _truncate(String(stdout ?? ""), spec.max_output_bytes);
57481
58426
  const [err, errTrunc] = _truncate(String(stderr ?? ""), spec.max_output_bytes);
57482
- resolve56({
58427
+ resolve57({
57483
58428
  exit_code: timedOut ? null : exitCode,
57484
58429
  timed_out: timedOut,
57485
58430
  stdout: out,
@@ -57500,8 +58445,8 @@ var init_safety_envelope = __esm({
57500
58445
  });
57501
58446
 
57502
58447
  // src/scripts/mcp_server/__main__.ts
57503
- import * as path102 from "node:path";
57504
- import { fileURLToPath as fileURLToPath52 } from "node:url";
58448
+ import * as path104 from "node:path";
58449
+ import { fileURLToPath as fileURLToPath53 } from "node:url";
57505
58450
 
57506
58451
  // src/scripts/mcp_server/index.ts
57507
58452
  var __version__ = "0.1.0";
@@ -57548,9 +58493,9 @@ init_prompts();
57548
58493
  init_resources();
57549
58494
 
57550
58495
  // src/scripts/mcp_server/tools.ts
57551
- import * as fs105 from "node:fs";
57552
- import * as path101 from "node:path";
57553
- import { fileURLToPath as fileURLToPath51 } from "node:url";
58496
+ import * as fs107 from "node:fs";
58497
+ import * as path103 from "node:path";
58498
+ import { fileURLToPath as fileURLToPath52 } from "node:url";
57554
58499
 
57555
58500
  // src/scripts/chat_history.ts
57556
58501
  init_memory_lookup();
@@ -60969,8 +61914,8 @@ function buildGraph(files, extracts, resolution = EMPTY_RESOLUTION_CONFIG) {
60969
61914
  }
60970
61915
  function resolveRawEdge(r, ex) {
60971
61916
  if (r.relation === "member") {
60972
- const sep20 = r.sourceId.includes("#") ? "::" : "#";
60973
- const target = `${r.sourceId}${sep20}${r.targetName}`;
61917
+ const sep21 = r.sourceId.includes("#") ? "::" : "#";
61918
+ const target = `${r.sourceId}${sep21}${r.targetName}`;
60974
61919
  emit2({
60975
61920
  source: r.sourceId,
60976
61921
  target: nodeIds.has(target) ? target : `symbol:${r.targetName}`,
@@ -62780,14 +63725,14 @@ function _resolveConsumerRoot(override) {
62780
63725
  return resolvePath(process.cwd());
62781
63726
  }
62782
63727
  function _relativeUnder(target, root) {
62783
- const rel = path101.relative(root, target);
63728
+ const rel = path103.relative(root, target);
62784
63729
  if (rel === "") {
62785
63730
  return "";
62786
63731
  }
62787
- if (rel.startsWith("..") || path101.isAbsolute(rel)) {
63732
+ if (rel.startsWith("..") || path103.isAbsolute(rel)) {
62788
63733
  return null;
62789
63734
  }
62790
- return rel.split(path101.sep).join("/");
63735
+ return rel.split(path103.sep).join("/");
62791
63736
  }
62792
63737
  function _reprStrList(values) {
62793
63738
  return `[${values.map((v) => `'${v}'`).join(", ")}]`;
@@ -62796,11 +63741,11 @@ function _validateInTreePath(raw, consumerRoot) {
62796
63741
  const root = resolvePath(consumerRoot);
62797
63742
  let target;
62798
63743
  if (raw === null || raw === void 0 || raw === "") {
62799
- target = path101.join(root, "agents", "runtime", ".agent-chat-history");
62800
- } else if (path101.isAbsolute(raw)) {
63744
+ target = path103.join(root, "agents", "runtime", ".agent-chat-history");
63745
+ } else if (path103.isAbsolute(raw)) {
62801
63746
  target = resolvePath(raw);
62802
63747
  } else {
62803
- target = resolvePath(path101.join(root, raw));
63748
+ target = resolvePath(path103.join(root, raw));
62804
63749
  }
62805
63750
  const rel = _relativeUnder(target, root);
62806
63751
  if (rel === null) {
@@ -62838,11 +63783,11 @@ async function _lintSkillsHandler(args, consumerRoot) {
62838
63783
  if (typeof raw !== "string") {
62839
63784
  throw new Error("'paths' entries must be strings");
62840
63785
  }
62841
- const resolved = path101.isAbsolute(raw) ? resolvePath(raw) : resolvePath(path101.join(root, raw));
63786
+ const resolved = path103.isAbsolute(raw) ? resolvePath(raw) : resolvePath(path103.join(root, raw));
62842
63787
  if (_relativeUnder(resolved, root) === null) {
62843
63788
  throw new Error(`path escapes consumer_root: ${resolved}`);
62844
63789
  }
62845
- if (fs105.existsSync(resolved)) {
63790
+ if (fs107.existsSync(resolved)) {
62846
63791
  paths.push(resolved);
62847
63792
  }
62848
63793
  }
@@ -62879,7 +63824,7 @@ async function _chatHistoryAppendHandler(args, consumerRoot) {
62879
63824
  if (typeof minSchema !== "number" || !Number.isInteger(minSchema) || typeof minSchema === "boolean") {
62880
63825
  throw new Error("'min_schema_version' must be an integer");
62881
63826
  }
62882
- const existingHeader = fs105.existsSync(target) ? _chReadHeader(target) : null;
63827
+ const existingHeader = fs107.existsSync(target) ? _chReadHeader(target) : null;
62883
63828
  const observed = existingHeader !== null && typeof existingHeader === "object" ? _pyInt7(existingHeader.v ?? 0) : SCHEMA_VERSION3;
62884
63829
  if (observed < minSchema) {
62885
63830
  throw new Error(`chat-history schema ${observed} below required ${minSchema}`);
@@ -62894,8 +63839,8 @@ async function _chatHistoryAppendHandler(args, consumerRoot) {
62894
63839
  session: session === void 0 ? null : session
62895
63840
  };
62896
63841
  }
62897
- if (!fs105.existsSync(target) || _chReadHeader(target) === null) {
62898
- fs105.mkdirSync(path101.dirname(target), { recursive: true });
63842
+ if (!fs107.existsSync(target) || _chReadHeader(target) === null) {
63843
+ fs107.mkdirSync(path103.dirname(target), { recursive: true });
62899
63844
  _chInit(target);
62900
63845
  }
62901
63846
  _chAppend(entry, target, session ?? null);
@@ -62939,7 +63884,7 @@ async function _chatHistoryReadHandler(args, consumerRoot) {
62939
63884
  if (detail !== "full" && detail !== "index") {
62940
63885
  throw new Error("'detail' must be 'index' or 'full'");
62941
63886
  }
62942
- if (!fs105.existsSync(target)) {
63887
+ if (!fs107.existsSync(target)) {
62943
63888
  return { path: target, entries: [], count: 0 };
62944
63889
  }
62945
63890
  if (around !== void 0 && around !== null) {
@@ -63041,8 +63986,8 @@ async function _memoryStatusHandler(_args, consumerRoot) {
63041
63986
  }
63042
63987
  return result;
63043
63988
  }
63044
- var _PACKAGE_ROOT3 = path101.resolve(
63045
- path101.dirname(fileURLToPath51(import.meta.url)),
63989
+ var _PACKAGE_ROOT3 = path103.resolve(
63990
+ path103.dirname(fileURLToPath52(import.meta.url)),
63046
63991
  "..",
63047
63992
  "..",
63048
63993
  ".."
@@ -63086,10 +64031,10 @@ async function _memorySignalHandler(args, consumerRoot) {
63086
64031
  async function _roadmapProgressHandler(args, consumerRoot) {
63087
64032
  const dryRun = _pyTruthy6(args.dry_run ?? false);
63088
64033
  const root = resolvePath(consumerRoot);
63089
- const roadmapRoot = path101.join(root, "agents", "roadmaps");
63090
- const target = path101.join(root, "agents", "roadmaps-progress.md");
64034
+ const roadmapRoot = path103.join(root, "agents", "roadmaps");
64035
+ const target = path103.join(root, "agents", "roadmaps-progress.md");
63091
64036
  const urp = await Promise.resolve().then(() => (init_update_roadmap_progress(), update_roadmap_progress_exports));
63092
- if (!fs105.existsSync(roadmapRoot)) {
64037
+ if (!fs107.existsSync(roadmapRoot)) {
63093
64038
  return {
63094
64039
  written: false,
63095
64040
  path: target,
@@ -63104,7 +64049,7 @@ async function _roadmapProgressHandler(args, consumerRoot) {
63104
64049
  const stepsDone = roadmaps.reduce((s, r) => s + r.done, 0);
63105
64050
  const stepsTotal = roadmaps.reduce((s, r) => s + r.total_active, 0);
63106
64051
  if (!dryRun) {
63107
- fs105.writeFileSync(target, content, "utf-8");
64052
+ fs107.writeFileSync(target, content, "utf-8");
63108
64053
  }
63109
64054
  return {
63110
64055
  written: !dryRun,
@@ -63125,11 +64070,11 @@ async function _roadmapArchiveHandler(_args, consumerRoot) {
63125
64070
  let dashboardRegenerated = false;
63126
64071
  if (archived.length > 0) {
63127
64072
  const urp = await Promise.resolve().then(() => (init_update_roadmap_progress(), update_roadmap_progress_exports));
63128
- const roadmapRoot = path101.join(root, "agents", "roadmaps");
63129
- if (fs105.existsSync(roadmapRoot)) {
64073
+ const roadmapRoot = path103.join(root, "agents", "roadmaps");
64074
+ if (fs107.existsSync(roadmapRoot)) {
63130
64075
  const roadmaps = urp.collect(roadmapRoot);
63131
- fs105.writeFileSync(
63132
- path101.join(root, "agents", "roadmaps-progress.md"),
64076
+ fs107.writeFileSync(
64077
+ path103.join(root, "agents", "roadmaps-progress.md"),
63133
64078
  urp.render(roadmaps, urp.collect_bundles(root), roadmapRoot),
63134
64079
  "utf-8"
63135
64080
  );
@@ -63145,9 +64090,9 @@ async function _roadmapArchiveHandler(_args, consumerRoot) {
63145
64090
  async function _capabilitiesIndexHandler(args, consumerRoot) {
63146
64091
  const check = _pyTruthy6(args.check ?? false);
63147
64092
  const cap = await Promise.resolve().then(() => (init_generate_capabilities_index(), generate_capabilities_index_exports));
63148
- const out = path101.join(_PACKAGE_ROOT3, "CAPABILITIES.yaml");
64093
+ const out = path103.join(_PACKAGE_ROOT3, "CAPABILITIES.yaml");
63149
64094
  const content = cap.build();
63150
- const onDisk = fs105.existsSync(out) ? fs105.readFileSync(out, "utf-8") : "";
64095
+ const onDisk = fs107.existsSync(out) ? fs107.readFileSync(out, "utf-8") : "";
63151
64096
  const drift = onDisk !== content;
63152
64097
  if (check) {
63153
64098
  return { check: true, written: false, drift, path: out };
@@ -63158,7 +64103,7 @@ async function _capabilitiesIndexHandler(args, consumerRoot) {
63158
64103
  `CAPABILITIES.yaml path escapes consumer_root: ${out} not under ${root}`
63159
64104
  );
63160
64105
  }
63161
- fs105.writeFileSync(out, content, "utf-8");
64106
+ fs107.writeFileSync(out, content, "utf-8");
63162
64107
  return { check: false, written: true, drift, path: out };
63163
64108
  }
63164
64109
  async function _runDoctorLeg(consumerRoot) {
@@ -63258,11 +64203,11 @@ async function _councilEstimateHandler(args, consumerRoot) {
63258
64203
  throw new Error("'depth' must be 'shallow' or 'deep' when provided");
63259
64204
  }
63260
64205
  const root = resolvePath(consumerRoot);
63261
- const target = path101.isAbsolute(inputRaw) ? resolvePath(inputRaw) : resolvePath(path101.join(root, inputRaw));
64206
+ const target = path103.isAbsolute(inputRaw) ? resolvePath(inputRaw) : resolvePath(path103.join(root, inputRaw));
63262
64207
  if (_relativeUnder(target, root) === null) {
63263
64208
  throw new Error(`path escapes consumer_root: ${target}`);
63264
64209
  }
63265
- if (!fs105.existsSync(target)) {
64210
+ if (!fs107.existsSync(target)) {
63266
64211
  throw new Error(`input_path not found: ${target}`);
63267
64212
  }
63268
64213
  const cli = await Promise.resolve().then(() => (init_council_cli(), council_cli_exports));
@@ -63324,18 +64269,18 @@ async function _runTestsHandler(args, consumerRoot) {
63324
64269
  if (typeof relPathRaw !== "string" || !strip(relPathRaw)) {
63325
64270
  throw new Error("'path' must be a non-empty string when provided");
63326
64271
  }
63327
- const resolved = path101.isAbsolute(relPathRaw) ? resolvePath(relPathRaw) : resolvePath(path101.join(root, relPathRaw));
64272
+ const resolved = path103.isAbsolute(relPathRaw) ? resolvePath(relPathRaw) : resolvePath(path103.join(root, relPathRaw));
63328
64273
  const rel = _relativeUnder(resolved, root);
63329
64274
  if (rel === null) {
63330
64275
  throw new Error(`path escapes consumer_root: ${resolved}`);
63331
64276
  }
63332
- if (!fs105.existsSync(resolved)) {
64277
+ if (!fs107.existsSync(resolved)) {
63333
64278
  throw new Error(`path not found: ${resolved}`);
63334
64279
  }
63335
64280
  relArg = rel;
63336
64281
  }
63337
- const vitestEntry = path101.join(root, "node_modules", "vitest", "vitest.mjs");
63338
- if (!fs105.existsSync(vitestEntry)) {
64282
+ const vitestEntry = path103.join(root, "node_modules", "vitest", "vitest.mjs");
64283
+ if (!fs107.existsSync(vitestEntry)) {
63339
64284
  throw new Error(
63340
64285
  "run_tests pilot supports vitest projects only \u2014 node_modules/vitest/vitest.mjs not found under consumer_root"
63341
64286
  );
@@ -63965,8 +64910,8 @@ function _strCmp3(a, b) {
63965
64910
  return a < b ? -1 : a > b ? 1 : 0;
63966
64911
  }
63967
64912
  function _pathlibCompare3(a, b) {
63968
- const pa = a.split(path101.sep);
63969
- const pb = b.split(path101.sep);
64913
+ const pa = a.split(path103.sep);
64914
+ const pb = b.split(path103.sep);
63970
64915
  const n = Math.min(pa.length, pb.length);
63971
64916
  for (let i = 0; i < n; i++) {
63972
64917
  const c = _strCmp3(pa[i], pb[i]);
@@ -64185,18 +65130,18 @@ async function _serveOverSdk(server) {
64185
65130
  const transport = new StdioServerTransport();
64186
65131
  await sdkServer.connect(transport);
64187
65132
  }
64188
- function main39() {
65133
+ function main40() {
64189
65134
  void run_stdio();
64190
65135
  }
64191
65136
 
64192
65137
  // src/scripts/mcp_server/__main__.ts
64193
- var _selfPath = fileURLToPath52(import.meta.url);
64194
- var _invokedDirectly3 = globalThis.__AC_MCP_BUNDLE_DIRECT === true || process.argv[1] !== void 0 && path102.resolve(process.argv[1]) === path102.resolve(_selfPath);
65138
+ var _selfPath = fileURLToPath53(import.meta.url);
65139
+ var _invokedDirectly3 = globalThis.__AC_MCP_BUNDLE_DIRECT === true || process.argv[1] !== void 0 && path104.resolve(process.argv[1]) === path104.resolve(_selfPath);
64195
65140
  if (_invokedDirectly3) {
64196
- main39();
65141
+ main40();
64197
65142
  }
64198
65143
  export {
64199
- main39 as main
65144
+ main40 as main
64200
65145
  };
64201
65146
  /*! Bundled license information:
64202
65147