@event4u/agent-config 9.28.0 → 9.30.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 (209) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/AGENTS.md +6 -6
  3. package/CHANGELOG.md +172 -5
  4. package/README.md +2 -1
  5. package/agents/templates/.ai-council.yml.example +55 -24
  6. package/dist/agent-src/commands/analyze/inbox.md +22 -1
  7. package/dist/agent-src/commands/cost/report.md +2 -2
  8. package/dist/agent-src/commands/explain-run.md +31 -1
  9. package/dist/agent-src/commands/team/adversarial.md +8 -7
  10. package/dist/agent-src/commands/team/delegate.md +14 -12
  11. package/dist/agent-src/commands/team/review.md +9 -8
  12. package/dist/agent-src/commands/team/status.md +9 -8
  13. package/dist/agent-src/commands/team.md +29 -19
  14. package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +88 -2
  15. package/dist/agent-src/contexts/execution/auto-orchestration-activation.md +29 -21
  16. package/dist/agent-src/contexts/execution/host-capability-manifest.md +26 -15
  17. package/dist/agent-src/contexts/execution/orchestration-telemetry.md +22 -1
  18. package/dist/agent-src/contexts/execution/roadmap-process-loop.md +17 -0
  19. package/dist/agent-src/contexts/execution/subagent-response-contract.md +65 -1
  20. package/dist/agent-src/contexts/execution/subagent-routing.md +13 -11
  21. package/dist/agent-src/contexts/execution/subagent-spawn-contract.md +25 -0
  22. package/dist/agent-src/contexts/execution/subagent-steering.md +6 -3
  23. package/dist/agent-src/rules/delegation-policy.md +11 -7
  24. package/dist/agent-src/rules/preservation-guard.md +9 -0
  25. package/dist/agent-src/rules/settings-ask-protocol.md +8 -7
  26. package/dist/agent-src/rules/token-budget-discipline.md +1 -1
  27. package/dist/agent-src/scripts/roadmap_gates.ts +312 -0
  28. package/dist/agent-src/scripts/update_roadmap_progress.ts +72 -4
  29. package/dist/agent-src/skills/forensics-report/SKILL.md +114 -0
  30. package/dist/agent-src/skills/forensics-report/evals/triggers.json +17 -0
  31. package/dist/agent-src/skills/premortem/SKILL.md +30 -1
  32. package/dist/agent-src/skills/reasoning-orchestrator/SKILL.md +2 -1
  33. package/dist/agent-src/skills/subagent-orchestration/SKILL.md +17 -5
  34. package/dist/agent-src/skills/subagent-orchestration/schemas/subagent-status.json +61 -3
  35. package/dist/agent-src/skills/test-case-discovery/SKILL.md +1 -1
  36. package/dist/agent-src/templates/AGENTS.md +4 -4
  37. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  38. package/dist/agent-src/templates/roadmaps.md +23 -0
  39. package/dist/cli/registry.js +2 -0
  40. package/dist/cli/registry.js.map +1 -1
  41. package/dist/cli-delegate/{chunk-22GCIJ2O.js → chunk-66OVWGB5.js} +1 -1
  42. package/dist/cli-delegate/{chunk-7OMQCH4V.js → chunk-BTJNRUX3.js} +22 -35
  43. package/dist/cli-delegate/{chunk-DVRS2KVR.js → chunk-DDUNNFYX.js} +24 -17
  44. package/dist/cli-delegate/{chunk-PQSAQKHW.js → chunk-EQY4FLJB.js} +3 -3
  45. package/dist/cli-delegate/{chunk-2BE5I2MN.js → chunk-IYTGIG2Y.js} +155 -91
  46. package/dist/cli-delegate/{chunk-GB2FSUEE.js → chunk-LCFJIQ4J.js} +32 -0
  47. package/dist/cli-delegate/{chunk-VSYT7OHO.js → chunk-LVRYBKTI.js} +31 -2
  48. package/dist/cli-delegate/chunk-MMJL4TIX.js +18 -0
  49. package/dist/cli-delegate/{chunk-JXARCGVN.js → chunk-MP3JT3IU.js} +1 -1
  50. package/dist/cli-delegate/chunk-O3CO5BFB.js +161 -0
  51. package/dist/cli-delegate/{chunk-REKCMYOU.js → chunk-PFBV6XRT.js} +36 -20
  52. package/dist/cli-delegate/chunk-RVGBH4XK.js +142 -0
  53. package/dist/cli-delegate/cmd_analyze_session.js +1 -1
  54. package/dist/cli-delegate/cmd_brand_status.js +1 -1
  55. package/dist/cli-delegate/cmd_conformance.js +2803 -137
  56. package/dist/cli-delegate/cmd_doctor.js +10 -5
  57. package/dist/cli-delegate/cmd_explain.js +2 -2
  58. package/dist/cli-delegate/cmd_export.js +4 -4
  59. package/dist/cli-delegate/cmd_handoff.js +88 -8
  60. package/dist/cli-delegate/cmd_mcp_available.js +1 -1
  61. package/dist/cli-delegate/cmd_migrate.js +2 -2
  62. package/dist/cli-delegate/cmd_packs_active.js +2 -2
  63. package/dist/cli-delegate/cmd_prune.js +4 -4
  64. package/dist/cli-delegate/cmd_route_audit.js +3 -2
  65. package/dist/cli-delegate/cmd_route_explain.js +1 -1
  66. package/dist/cli-delegate/cmd_session_recycle.js +177 -0
  67. package/dist/cli-delegate/cmd_settings_get.js +2 -8
  68. package/dist/cli-delegate/cmd_settings_migrate.js +4 -4
  69. package/dist/cli-delegate/cmd_settings_set.js +2 -2
  70. package/dist/cli-delegate/cmd_sync.js +4 -4
  71. package/dist/cli-delegate/cmd_uninstall.js +4 -4
  72. package/dist/cli-delegate/cmd_update.js +1 -1
  73. package/dist/cli-delegate/cmd_upgrade.js +1 -1
  74. package/dist/cli-delegate/cmd_validate.js +4 -4
  75. package/dist/cli-delegate/cmd_versions.js +1 -1
  76. package/dist/discovery/deprecation-report.md +1 -1
  77. package/dist/discovery/discovery-manifest.json +72 -23
  78. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  79. package/dist/discovery/discovery-manifest.summary.md +3 -2
  80. package/dist/discovery/orphan-report.md +1 -1
  81. package/dist/discovery/packs.json +39 -2
  82. package/dist/discovery/trust-report.md +2 -2
  83. package/dist/discovery/workspaces.json +12 -4
  84. package/dist/hooks/dispatch.js +2278 -611
  85. package/dist/install/install.mjs +56 -17
  86. package/dist/mcp/registry-manifest.json +3 -3
  87. package/dist/mcp/server.json +2 -2
  88. package/dist/mcp/server.mjs +4122 -699
  89. package/dist/router.json +1 -1
  90. package/dist/scripts/_lib/agent_settings.js +54 -0
  91. package/dist/scripts/_lib/agent_settings.js.map +1 -1
  92. package/dist/scripts/condense.js +147 -2
  93. package/dist/scripts/condense.js.map +1 -1
  94. package/dist/server/schemas/settings.js +12 -7
  95. package/dist/server/schemas/settings.js.map +1 -1
  96. package/dist/shared/settingsCarveOut.js +0 -9
  97. package/dist/shared/settingsCarveOut.js.map +1 -1
  98. package/dist/shared/settingsClasses.js +11 -9
  99. package/dist/shared/settingsClasses.js.map +1 -1
  100. package/dist/ui/assets/index-B5qGYOJo.js +26 -0
  101. package/dist/ui/assets/index-B5qGYOJo.js.map +1 -0
  102. package/dist/ui/index.html +1 -1
  103. package/docs/contracts/settings-classes.md +58 -12
  104. package/package.json +1 -1
  105. package/src/agent-src/scripts/roadmap_gates.ts +312 -0
  106. package/src/agent-src/scripts/update_roadmap_progress.ts +72 -4
  107. package/src/agent-src/templates/AGENTS.md +4 -4
  108. package/src/config/agent-settings.template.yml +88 -66
  109. package/src/config/discovery/packs.yml +11 -0
  110. package/src/config/discovery/workspaces.yml +1 -1
  111. package/src/config/dispatch-economy-metrics.json +61 -0
  112. package/src/config/evaluator-budgets.json +4 -4
  113. package/src/config/gate-violation-baselines.json +3 -3
  114. package/src/config/hook-token-budget.json +91 -0
  115. package/src/config/recycle-threshold-budget.json +12 -0
  116. package/src/config/rule-enforcement-baseline.json +86 -0
  117. package/src/scripts/_cli/cmd_conformance.ts +31 -44
  118. package/src/scripts/_cli/cmd_doctor.ts +65 -48
  119. package/src/scripts/_cli/cmd_session_recycle.ts +226 -0
  120. package/src/scripts/_dispatch.bash +23 -0
  121. package/src/scripts/_lib/agent_settings.ts +58 -0
  122. package/src/scripts/_lib/auto_dispatch.corpus.test.ts +1 -1
  123. package/src/scripts/_lib/auto_dispatch.ts +23 -18
  124. package/src/scripts/_lib/capsule_trigger.ts +124 -0
  125. package/src/scripts/_lib/host_capability.ts +63 -6
  126. package/src/scripts/_lib/judgment_ladder.ts +634 -0
  127. package/src/scripts/_lib/orchestration_gate.ts +8 -0
  128. package/src/scripts/_lib/orchestration_record.ts +78 -10
  129. package/src/scripts/_lib/orchestration_savings.ts +1 -1
  130. package/src/scripts/_lib/recycle_envelope_paths.ts +35 -0
  131. package/src/scripts/_lib/self_repair.ts +354 -13
  132. package/src/scripts/_lib/self_repair_store.ts +28 -0
  133. package/src/scripts/_lib/session_eol.ts +230 -0
  134. package/src/scripts/_lib/session_role.ts +42 -0
  135. package/src/scripts/_lib/subagent_capsule.ts +341 -0
  136. package/src/scripts/_lib/subagent_response.ts +94 -0
  137. package/src/scripts/_lib/subagent_spawn.ts +13 -0
  138. package/src/scripts/_lib/subagent_steering.ts +9 -4
  139. package/src/scripts/_lib/tier_budget_routing.ts +6 -1
  140. package/src/scripts/_lib/worker_budget.ts +37 -2
  141. package/src/scripts/ai_council/clients.ts +126 -55
  142. package/src/scripts/ai_council/config.ts +94 -6
  143. package/src/scripts/ai_council/handoff.ts +113 -0
  144. package/src/scripts/ai_council/modes.ts +19 -4
  145. package/src/scripts/ai_council/orchestrator.ts +105 -0
  146. package/src/scripts/ai_council/quorum.ts +84 -0
  147. package/src/scripts/ai_council/session.ts +44 -0
  148. package/src/scripts/ai_council/transport_resolver.ts +127 -1
  149. package/src/scripts/ai_team/availability.ts +110 -0
  150. package/src/scripts/ai_team/config.ts +34 -14
  151. package/src/scripts/ai_team/team_dispatch.ts +71 -29
  152. package/src/scripts/ask_transport.ts +221 -0
  153. package/src/scripts/bench_critic_protocol.ts +396 -0
  154. package/src/scripts/bench_hook_injection.ts +234 -0
  155. package/src/scripts/check_adr_frontmatter.ts +84 -40
  156. package/src/scripts/check_branch_freshness.ts +1 -0
  157. package/src/scripts/check_corpus_staleness.ts +18 -4
  158. package/src/scripts/check_detector_corpus.ts +219 -0
  159. package/src/scripts/check_gitignore_freshness.ts +42 -8
  160. package/src/scripts/check_hook_bundle_freshness.ts +24 -1
  161. package/src/scripts/check_kernel_prefix_stability.ts +1 -0
  162. package/src/scripts/check_standing_rule_delivery.ts +73 -32
  163. package/src/scripts/check_static_layer_stability.ts +154 -0
  164. package/src/scripts/check_suppression_hygiene.ts +48 -0
  165. package/src/scripts/condense.ts +162 -2
  166. package/src/scripts/council_cli.ts +401 -25
  167. package/src/scripts/dispatch_economy_report.ts +448 -0
  168. package/src/scripts/dispatch_r2_reviewer.ts +15 -2
  169. package/src/scripts/explain_run.ts +206 -4
  170. package/src/scripts/forensics_report.ts +333 -0
  171. package/src/scripts/generate_settings_reference.ts +1 -0
  172. package/src/scripts/handoff_context_hook.ts +112 -4
  173. package/src/scripts/hook_manifest.yaml +117 -10
  174. package/src/scripts/hooks/concern_registry.ts +8 -0
  175. package/src/scripts/hooks/delegation_nudge_hook.ts +106 -35
  176. package/src/scripts/hooks/dispatch_hook.ts +39 -2
  177. package/src/scripts/hooks/edit_shape_hook.ts +303 -0
  178. package/src/scripts/hooks/orchestration_record_hook.ts +19 -1
  179. package/src/scripts/hooks/reread_guard_hook.ts +314 -0
  180. package/src/scripts/hooks/rtk_wrap_hook.ts +133 -14
  181. package/src/scripts/hooks/session_eol_hook.ts +268 -0
  182. package/src/scripts/hooks/turn_end_gate_hook.ts +507 -0
  183. package/src/scripts/install-hooks.sh +1 -1
  184. package/src/scripts/language_mirror_hook.ts +89 -0
  185. package/src/scripts/lint_decision_impact.ts +14 -1
  186. package/src/scripts/lint_discovery_vocabulary.ts +2 -0
  187. package/src/scripts/lint_hook_manifest.ts +82 -0
  188. package/src/scripts/lint_never_silent.ts +276 -0
  189. package/src/scripts/lint_no_activation_gates.ts +271 -0
  190. package/src/scripts/lint_readme_serial_comma.ts +1 -0
  191. package/src/scripts/lint_rule_enforcement_declaration.ts +347 -0
  192. package/src/scripts/measure_turn_end_gate.ts +194 -0
  193. package/src/scripts/orchestration_record.ts +12 -1
  194. package/src/scripts/rebuild_hook_bundle.ts +178 -0
  195. package/src/scripts/release.ts +74 -2
  196. package/src/scripts/report_conformance_funnel.ts +284 -0
  197. package/src/scripts/report_imperative_density.ts +1 -0
  198. package/src/scripts/routing_doctor.ts +118 -36
  199. package/src/scripts/score_skill_selection.ts +19 -5
  200. package/src/scripts/self_repair_cli.ts +337 -59
  201. package/src/scripts/session_eol_report.ts +261 -0
  202. package/src/scripts/team_events_spike.ts +271 -0
  203. package/src/scripts/team_review_gate_hook.ts +31 -9
  204. package/src/server/schemas/settings.ts +24 -17
  205. package/src/shared/settingsCarveOut.ts +0 -10
  206. package/src/shared/settingsClasses.ts +11 -9
  207. package/src/templates/compact-instructions.md +40 -0
  208. package/dist/ui/assets/index-DmR0mbk4.js +0 -26
  209. package/dist/ui/assets/index-DmR0mbk4.js.map +0 -1
@@ -35,6 +35,7 @@
35
35
  * processes are the two freshness checks, both themselves read-only.
36
36
  */
37
37
  import fs from "node:fs";
38
+ import os from "node:os";
38
39
  import path from "node:path";
39
40
  import { spawnSync } from "node:child_process";
40
41
  import { fileURLToPath, pathToFileURL } from "node:url";
@@ -53,7 +54,7 @@ import {
53
54
  import * as hooks_status from "./hooks_status.js";
54
55
  import { load_agent_settings } from "./_lib/agent_settings.js";
55
56
  import {
56
- resolveHostCapabilities,
57
+ probeHostCapabilities,
57
58
  type HostCapabilityManifest,
58
59
  } from "./_lib/host_capability.js";
59
60
  import {
@@ -62,6 +63,11 @@ import {
62
63
  type ActivationInputs,
63
64
  } from "./_lib/auto_dispatch.js";
64
65
  import { TIER_ORDER, readCooldowns } from "./_lib/tier_budget_routing.js";
66
+ import {
67
+ instructionsLoadedRecord,
68
+ measureStandingDelivery,
69
+ type StandingDeliveryMeasure,
70
+ } from "./check_standing_rule_delivery.js";
65
71
 
66
72
  const REPO_ROOT = path.resolve(
67
73
  path.dirname(fileURLToPath(import.meta.url)),
@@ -99,10 +105,9 @@ export interface FreshnessReport {
99
105
  }
100
106
 
101
107
  export interface OrchestrationReport {
102
- enabled: boolean;
103
- auto: string;
108
+ /** `emergency.orchestration_halt` — the one audited incident switch. */
109
+ halted: boolean;
104
110
  downshift: boolean;
105
- budget_routing: string;
106
111
  /** cost.budgets.per_tier ceilings + live cool-down state per tier. */
107
112
  tier_budgets: Record<string, { ceiling_usd: number | null; cooldown_until_ms: number }>;
108
113
  host_manifest: HostCapabilityManifest;
@@ -141,22 +146,19 @@ export interface OrchestrationReport {
141
146
  }
142
147
 
143
148
  /**
144
- * Adherence ≠ delivery: budget routing binds via policy prose, so the
145
- * doctor checks the DELIVERY evidence — orchestration audit lines that
146
- * carry a tier decision. Eligible dispatches recorded while
147
- * `budget_routing != off` but ZERO tier-carrying lines → WARN with the
148
- * exact reason. Read-only over agents/runtime/state/audit/*.jsonl; no
149
- * new state. This closes the same blind-spot class the session-canary
150
- * incident exposed (policy present, delivery silently absent).
149
+ * Adherence ≠ delivery: budget-aware tier routing has no on/off setting any
150
+ * more (always-on orchestration removed `subagents.budget_routing`), so the
151
+ * doctor always checks the DELIVERY evidence — orchestration audit lines
152
+ * that carry a tier decision. Dispatches recorded with ZERO tier-carrying
153
+ * lines → WARN with the exact reason. Read-only over
154
+ * agents/runtime/state/audit/*.jsonl; no new state. This closes the same
155
+ * blind-spot class the session-canary incident exposed (policy present,
156
+ * delivery silently absent).
151
157
  */
152
158
  export function check_budget_delivery(
153
159
  workspace_root: string,
154
- budget_routing: string,
155
160
  ): OrchestrationReport["delivery"] {
156
161
  const out = { eligible_dispatches: 0, budget_evidence_lines: 0, warning: "" };
157
- if (budget_routing === "off") {
158
- return out;
159
- }
160
162
  const auditDir = path.join(workspace_root, "agents", "runtime", "state", "audit");
161
163
  let files: string[] = [];
162
164
  try {
@@ -188,7 +190,7 @@ export function check_budget_delivery(
188
190
  }
189
191
  if (out.eligible_dispatches > 0 && out.budget_evidence_lines === 0) {
190
192
  out.warning =
191
- `budget_routing=${budget_routing} is policy-bound but shows no delivery evidence: ` +
193
+ `budget-aware tier routing shows no delivery evidence: ` +
192
194
  `${out.eligible_dispatches} orchestration dispatch(es) recorded, 0 carry a tier decision — ` +
193
195
  `the relation may not be running (adherence != delivery)`;
194
196
  }
@@ -201,9 +203,93 @@ export interface DoctorReport {
201
203
  gates: GateReport[];
202
204
  freshness: FreshnessReport;
203
205
  orchestration: OrchestrationReport;
206
+ standing_delivery: StandingDeliveryMeasure | null;
204
207
  bridge_table: string;
205
208
  }
206
209
 
210
+ /**
211
+ * Standing-rule-delivery savings for the doctor surface — the measurement is
212
+ * `check_standing_rule_delivery`'s, reused rather than re-derived, so the gate
213
+ * and the doctor can never report different numbers for the same layers.
214
+ * Read-only, like everything else here. `null` = no rule layer installed.
215
+ */
216
+ export function collect_standing_delivery(
217
+ workspace_root: string,
218
+ global_rules_dir: string = path.join(os.homedir(), ".claude", "rules"),
219
+ ): StandingDeliveryMeasure | null {
220
+ return measureStandingDelivery(
221
+ global_rules_dir,
222
+ path.join(workspace_root, ".claude", "rules"),
223
+ instructionsLoadedRecord(workspace_root),
224
+ );
225
+ }
226
+
227
+ /**
228
+ * Render the delivery line in one of its states — scoped-clean (one layer,
229
+ * nothing duplicated) or both-layers-active (red, pointing at
230
+ * `install --layer`). Every number printed is one the measurement produced:
231
+ * the received total, the measured overlap, and the received-minus-overlap
232
+ * total suppression would leave. No baseline is invented for the layer that
233
+ * is not installed, so no percentage is derived from one either. The
234
+ * filesystem-vs-host-confirmed caveat is the gate's own honest-scope
235
+ * sentence, carried here so the doctor never claims the host confirmed what
236
+ * only the filesystem projects.
237
+ */
238
+ export function render_standing_delivery(m: StandingDeliveryMeasure | null): string[] {
239
+ if (m === null) {
240
+ return [
241
+ "Standing delivery: no rule layer installed (neither ~/.claude/rules nor .claude/rules) — nothing delivered, nothing to save.",
242
+ ];
243
+ }
244
+ const lines: string[] = [];
245
+ if (m.layers.length === 2 && m.overlap_rules > 0) {
246
+ const scoped = m.received_tokens - m.overlap_tokens;
247
+ lines.push(
248
+ `⚠️ Standing delivery: both rule layers active — ${m.overlap_rules} rule(s) delivered twice ` +
249
+ `(~${m.overlap_tokens} tok). This session's host receives ${m.received_tokens} rule tokens; ` +
250
+ `scoped delivery would be ~${scoped} — run \`agent-config install --layer=<global|project>\`.`,
251
+ );
252
+ if (m.divergent_rules > 0) {
253
+ // Suppressing a layer whose copies differ drops whichever obligations only
254
+ // the suppressed copy carried — the same guard `decideLayerAction` applies.
255
+ lines.push(
256
+ ` ${m.divergent_rules} of the shared rule(s) differ in body — refresh before suppressing, ` +
257
+ "or obligations only the suppressed copy carries are lost.",
258
+ );
259
+ }
260
+ } else if (m.layers.length === 2) {
261
+ lines.push(
262
+ `Standing delivery: this session's host receives ${m.received_tokens} rule tokens across two ` +
263
+ "non-overlapping layers — nothing delivered twice, Δ0 to save.",
264
+ );
265
+ } else {
266
+ // One layer = the scoped state, and the honest report of it is the received
267
+ // total plus the measured fact that nothing is delivered twice.
268
+ //
269
+ // This line used to invent an "unscoped both-layers baseline" of
270
+ // `received × 2` and report the arithmetic consequence — which is always
271
+ // exactly 50%, for every non-zero input, i.e. a tautology dressed as a
272
+ // measurement. It also assumed the absent second layer would carry an
273
+ // identical corpus; the branch directly above exists because two installed
274
+ // layers can be wholly disjoint, so even with both present the doubling
275
+ // does not follow. A saving needs a second layer to measure against, and
276
+ // here there is none.
277
+ const layer = m.layers[0]?.label ?? "one";
278
+ lines.push(
279
+ `Standing delivery: this session's host receives ${m.received_tokens} rule tokens (scoped, ` +
280
+ `${layer} layer only); 0 tokens delivered twice — one layer is installed, so there is no ` +
281
+ "second layer to measure a saving against.",
282
+ );
283
+ }
284
+ if (m.input === "filesystem") {
285
+ lines.push(
286
+ " note: filesystem projection, not host-confirmed — no InstructionsLoaded record; a rule " +
287
+ "projected but never loaded, or loaded from an unprojected layer, is invisible to this input.",
288
+ );
289
+ }
290
+ return lines;
291
+ }
292
+
207
293
  /**
208
294
  * Orchestration-routing state: settings gates, host capability, budget
209
295
  * inputs, and (optionally) a dry-run classification for a sample prompt.
@@ -237,17 +323,16 @@ export function collect_orchestration(
237
323
  ): OrchestrationReport {
238
324
  const settings = load_agent_settings({ cwd: workspace_root });
239
325
  const sub = (settings["subagents"] ?? {}) as Record<string, unknown>;
240
- const enabled = sub["enabled"] !== false;
241
- const auto = typeof sub["auto"] === "string" ? (sub["auto"] as string) : "ask";
326
+ const emergency = (settings["emergency"] ?? {}) as Record<string, unknown>;
327
+ const halted = emergency["orchestration_halt"] === true;
242
328
  const downshift = sub["downshift"] !== false;
243
- const host_manifest = resolveHostCapabilities(platform, sub["host_capabilities"]);
329
+ const host_manifest = probeHostCapabilities(platform);
244
330
  const activationInputs: ActivationInputs = {
245
- enabled,
246
- auto: (auto === "on" || auto === "off" ? auto : "ask") as ActivationInputs["auto"],
331
+ halted,
247
332
  subagent_spawn: host_manifest.subagent_spawn,
248
333
  };
249
334
  // Canonical delegable probe: the gate verdict shows which activation
250
- // layer (settings / host primitive) decides on THIS installation.
335
+ // layer (emergency halt / host primitive) decides on THIS installation.
251
336
  const probe = classifyTask(
252
337
  { size_estimate: 5, independent_slices: 3 },
253
338
  activationInputs,
@@ -256,14 +341,6 @@ export function collect_orchestration(
256
341
  const cost_budgets = (cost["budgets"] ?? {}) as Record<string, unknown>;
257
342
  const tracking_dir = path.join(workspace_root, "agents", "cost-tracking");
258
343
  const ledger_present = fs.existsSync(path.join(tracking_dir, "sessions.jsonl"));
259
- // YAML 1.1 trap: an unquoted `off` parses as boolean false — coerce it
260
- // back to the enum string so the check honors the user's intent.
261
- const budget_routing =
262
- sub["budget_routing"] === false
263
- ? "off"
264
- : typeof sub["budget_routing"] === "string"
265
- ? (sub["budget_routing"] as string)
266
- : "ask";
267
344
  const per_tier = (cost_budgets["per_tier"] ?? {}) as Record<string, unknown>;
268
345
  const cooldowns = readCooldowns(tracking_dir);
269
346
  const tier_budgets: OrchestrationReport["tier_budgets"] = {};
@@ -289,10 +366,8 @@ export function collect_orchestration(
289
366
  };
290
367
  }
291
368
  return {
292
- enabled,
293
- auto,
369
+ halted,
294
370
  downshift,
295
- budget_routing,
296
371
  tier_budgets,
297
372
  host_manifest,
298
373
  host_platform: platform,
@@ -301,7 +376,7 @@ export function collect_orchestration(
301
376
  cost_budgets,
302
377
  ledger_present,
303
378
  sample,
304
- delivery: check_budget_delivery(workspace_root, budget_routing),
379
+ delivery: check_budget_delivery(workspace_root),
305
380
  };
306
381
  }
307
382
 
@@ -459,6 +534,8 @@ export function collect_report(options: {
459
534
  workspace_root: string;
460
535
  no_freshness: boolean;
461
536
  classify?: string | null;
537
+ /** Test seam: fixture global rules dir. Defaults to the real `~/.claude/rules`. */
538
+ global_rules_dir?: string;
462
539
  }): DoctorReport {
463
540
  const manifest = _load_yaml(MANIFEST_PATH);
464
541
  const chain = resolve_chain(manifest, options.platform);
@@ -492,6 +569,9 @@ export function collect_report(options: {
492
569
  options.platform,
493
570
  options.platform_assumed ?? true,
494
571
  ),
572
+ standing_delivery: options.global_rules_dir === undefined
573
+ ? collect_standing_delivery(options.workspace_root)
574
+ : collect_standing_delivery(options.workspace_root, options.global_rules_dir),
495
575
  bridge_table,
496
576
  };
497
577
  }
@@ -514,10 +594,12 @@ function _render(report: DoctorReport): string {
514
594
  ` · dispatch bundle=${report.freshness.dispatch_bundle}`,
515
595
  );
516
596
  lines.push("");
597
+ lines.push(...render_standing_delivery(report.standing_delivery));
598
+ lines.push("");
517
599
  const o = report.orchestration;
518
600
  lines.push(
519
- `Orchestration: enabled=${o.enabled} · auto=${o.auto} · downshift=${o.downshift} · ` +
520
- `budget_routing=${o.budget_routing} · subagent_spawn=${o.host_manifest.subagent_spawn} ` +
601
+ `Orchestration: halted=${o.halted} · downshift=${o.downshift} · ` +
602
+ `subagent_spawn=${o.host_manifest.subagent_spawn} ` +
521
603
  `(host=${o.host_platform}${o.host_platform_assumed ? ", ASSUMED" : ", observed"}) · ` +
522
604
  `ledger=${o.ledger_present ? "present" : "absent"}`,
523
605
  );
@@ -19,10 +19,22 @@
19
19
  * pass = (a) >= 0.90 OR (b) >= 0.95
20
20
  * fail = (a) < 0.80 AND (b) < 0.80 → cluster needs `routes_to`
21
21
  *
22
- * NOTE: the .py reads the legacy `.agent-src.uncondensed/skills` literal;
23
- * this faithful twin replicates it byte-for-byte. When inputs are missing
24
- * the .py raises an uncaught FileNotFoundError → exit 1; this twin mirrors
25
- * that by throwing.
22
+ * REPOINTED 2026-08-09 (P2.2 of road-to-rule-delivery-integrity). The original
23
+ * read the uncondensed legacy skills tree, faithfully replicating a `.py` twin —
24
+ * but ADR-051 retired that tree as dead and it does not exist in this checkout.
25
+ * A scorer pointed at a missing directory does not fail: its glob yields
26
+ * nothing, every fixture scores against an empty skill set, and the output is a
27
+ * baseline of silent zeros. That is worse than an error, because a baseline is
28
+ * exactly what P2.2's pre-registered criteria compare against — the measurement
29
+ * would have been void and would have looked fine.
30
+ *
31
+ * Now reads `SRC_SKILLS()` from the shared resolver. `dist/agent-src/skills`
32
+ * would be equally valid (ADR-201 makes the projection a byte-exact copy, so
33
+ * the frontmatter is identical); `src/` is chosen because it is the source of
34
+ * truth and is present even before a sync.
35
+ *
36
+ * When inputs are missing the original raised an uncaught FileNotFoundError →
37
+ * exit 1; this twin mirrors that by throwing.
26
38
  */
27
39
 
28
40
  import * as fs from 'node:fs';
@@ -30,12 +42,14 @@ import * as path from 'node:path';
30
42
  import { fileURLToPath, pathToFileURL } from 'node:url';
31
43
  import { parse as parseYaml } from 'yaml';
32
44
 
45
+ import { SRC_SKILLS } from './_lib/agent_src.js';
46
+
33
47
  const _HERE = fileURLToPath(import.meta.url);
34
48
  // src/scripts/score_skill_selection.ts → parents[2] is the repo root.
35
49
  const REPO_ROOT = path.resolve(path.dirname(_HERE), '..', '..');
36
50
  const FIXTURES = path.join(REPO_ROOT, 'tests', 'fixtures', 'skill_selection', 'fixtures.yml');
37
51
  const CLUSTERS = path.join(REPO_ROOT, 'agents', 'reports', 'skill-collision-clusters.json');
38
- const SKILLS_DIR = path.join(REPO_ROOT, '.agent-src.uncondensed', 'skills');
52
+ const SKILLS_DIR = SRC_SKILLS();
39
53
  const DEFAULT_OUT = path.join(REPO_ROOT, 'agents', 'reports', 'skill-selection-accuracy.json');
40
54
 
41
55
  const PASS_A = 0.9;