@claudexor/cli 3.3.16 → 3.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/dist/acp-surface-runner.d.ts +3 -2
  2. package/dist/acp-surface-runner.d.ts.map +1 -1
  3. package/dist/acp-surface-runner.js +20 -17
  4. package/dist/acp-surface-runner.js.map +1 -1
  5. package/dist/claudexord-entry.d.ts +7 -0
  6. package/dist/claudexord-entry.d.ts.map +1 -1
  7. package/dist/claudexord-entry.js +14 -0
  8. package/dist/claudexord-entry.js.map +1 -1
  9. package/dist/claudexord.d.ts +0 -10
  10. package/dist/claudexord.d.ts.map +1 -1
  11. package/dist/claudexord.js +95 -100
  12. package/dist/claudexord.js.map +1 -1
  13. package/dist/cli.js +10 -12
  14. package/dist/cli.js.map +1 -1
  15. package/dist/control-services.d.ts +4 -1
  16. package/dist/control-services.d.ts.map +1 -1
  17. package/dist/control-services.js +22 -21
  18. package/dist/control-services.js.map +1 -1
  19. package/dist/daemon-admission-runtime.d.ts +63 -0
  20. package/dist/daemon-admission-runtime.d.ts.map +1 -0
  21. package/dist/daemon-admission-runtime.js +180 -0
  22. package/dist/daemon-admission-runtime.js.map +1 -0
  23. package/dist/daemon-launch.d.ts +53 -0
  24. package/dist/daemon-launch.d.ts.map +1 -0
  25. package/dist/daemon-launch.js +211 -0
  26. package/dist/daemon-launch.js.map +1 -0
  27. package/dist/daemon-lifecycle.d.ts +14 -2
  28. package/dist/daemon-lifecycle.d.ts.map +1 -1
  29. package/dist/daemon-lifecycle.js +53 -10
  30. package/dist/daemon-lifecycle.js.map +1 -1
  31. package/dist/daemon-run.d.ts +6 -1
  32. package/dist/daemon-run.d.ts.map +1 -1
  33. package/dist/daemon-run.js +70 -19
  34. package/dist/daemon-run.js.map +1 -1
  35. package/dist/daemon-start-report.d.ts +8 -0
  36. package/dist/daemon-start-report.d.ts.map +1 -0
  37. package/dist/daemon-start-report.js +24 -0
  38. package/dist/daemon-start-report.js.map +1 -0
  39. package/dist/daemon-startup.d.ts +90 -0
  40. package/dist/daemon-startup.d.ts.map +1 -0
  41. package/dist/daemon-startup.js +156 -0
  42. package/dist/daemon-startup.js.map +1 -0
  43. package/dist/engine-skew.d.ts +4 -0
  44. package/dist/engine-skew.d.ts.map +1 -1
  45. package/dist/engine-skew.js +10 -3
  46. package/dist/engine-skew.js.map +1 -1
  47. package/dist/mcp-run-projections.d.ts +78 -1
  48. package/dist/mcp-run-projections.d.ts.map +1 -1
  49. package/dist/mcp-run-projections.js +57 -3
  50. package/dist/mcp-run-projections.js.map +1 -1
  51. package/dist/mcp-runner.d.ts.map +1 -1
  52. package/dist/mcp-runner.js +41 -37
  53. package/dist/mcp-runner.js.map +1 -1
  54. package/dist/ops-commands.d.ts +9 -0
  55. package/dist/ops-commands.d.ts.map +1 -1
  56. package/dist/ops-commands.js +61 -66
  57. package/dist/ops-commands.js.map +1 -1
  58. package/dist/ops-harness-selection.d.ts +6 -0
  59. package/dist/ops-harness-selection.d.ts.map +1 -0
  60. package/dist/ops-harness-selection.js +29 -0
  61. package/dist/ops-harness-selection.js.map +1 -0
  62. package/dist/orphan-sweeper.js +13 -3
  63. package/dist/orphan-sweeper.js.map +1 -1
  64. package/dist/remote-command.d.ts +10 -1
  65. package/dist/remote-command.d.ts.map +1 -1
  66. package/dist/remote-command.js +34 -10
  67. package/dist/remote-command.js.map +1 -1
  68. package/dist/runtime-replacement-stop.d.ts +13 -2
  69. package/dist/runtime-replacement-stop.d.ts.map +1 -1
  70. package/dist/runtime-replacement-stop.js +46 -11
  71. package/dist/runtime-replacement-stop.js.map +1 -1
  72. package/dist/setup-lifecycle-binding.d.ts +7 -1
  73. package/dist/setup-lifecycle-binding.d.ts.map +1 -1
  74. package/dist/setup-lifecycle-binding.js +27 -17
  75. package/dist/setup-lifecycle-binding.js.map +1 -1
  76. package/dist/startup-diagnostics.d.ts +61 -0
  77. package/dist/startup-diagnostics.d.ts.map +1 -0
  78. package/dist/startup-diagnostics.js +416 -0
  79. package/dist/startup-diagnostics.js.map +1 -0
  80. package/dist/thread-turn-services.d.ts +1 -1
  81. package/dist/thread-turn-services.d.ts.map +1 -1
  82. package/dist/thread-turn-services.js.map +1 -1
  83. package/package.json +23 -23
@@ -0,0 +1,156 @@
1
+ /**
2
+ * Two-stage daemon startup admission (issue #165 D5).
3
+ *
4
+ * Stage order enforced by main(): (1) acquire the root authority barrier with
5
+ * its epoch/floor refusals; (2) read-only prepare + validate the global AND
6
+ * every registered project partition — zero recovery writes; (3) bind the
7
+ * REAL transport (socket + control API) with product admission CLOSED and
8
+ * prove self-health/exact identity through it; (4) only then advance the
9
+ * semantic floor, run destructive recovery (crash-GC, prepared activation,
10
+ * recoverAfterStartup terminalization) and open normal admission. A
11
+ * recovery-needed partition leaves the recovery plane online with the floor
12
+ * UNCHANGED and cleanup OFF.
13
+ */
14
+ import { appendFileSync, writeFileSync } from "node:fs";
15
+ import { join } from "node:path";
16
+ import { JournalRecoveryRequiredError } from "@claudexor/journal";
17
+ import { CONTROL_PROTOCOL_MAJOR } from "@claudexor/schema";
18
+ /** Single canonical admission snapshot; both transports read the SAME fact. */
19
+ export class DaemonStartupAdmission {
20
+ mode = "recovery_only";
21
+ snapshot = () => this.mode;
22
+ openNormal() {
23
+ this.mode = "normal";
24
+ }
25
+ }
26
+ /** Stage-2 verdict: every partition that blocks destructive recovery. The
27
+ * loose Picks let the C6 in-process reopen feed LIVE inspections through the
28
+ * same verdict the frozen stage-2 receipts use. */
29
+ export function recoveryBlockedPartitions(input) {
30
+ const blocked = [];
31
+ if (input.globalPreparation.inspection.status !== "ready")
32
+ blocked.push("global");
33
+ if (input.partitionsPreparation.coverage !== "complete") {
34
+ blocked.push("project-registry");
35
+ }
36
+ blocked.push(...input.partitionsPreparation.recoveryRequiredPartitions);
37
+ return blocked;
38
+ }
39
+ /** C6a: whether the control API binds this startup. CLAUDEXOR_NO_CONTROL_API=1
40
+ * is honored only on a clean verdict — the recovery surface IS the point of
41
+ * the recovery plane, so a recovery-required verdict overrides it (logged). */
42
+ export function controlApiEnabledForStartup(input) {
43
+ if (!input.disabledByEnv)
44
+ return true;
45
+ if (input.blockedPartitions.length === 0)
46
+ return false;
47
+ input.log("recovery-required startup verdict overrides CLAUDEXOR_NO_CONTROL_API=1: binding the control API to serve the recovery surface");
48
+ return true;
49
+ }
50
+ /** Stage 3 bind: start the REAL socket + control transports (product
51
+ * admission still closed) and publish their addresses. Returns the control
52
+ * address, or null when the control API is disabled or shutdown began. */
53
+ export async function bindRecoveryTransport(input) {
54
+ const stamp = () => `[${new Date().toISOString()}]`;
55
+ if (!input.requested())
56
+ await input.server.start();
57
+ if (!input.requested()) {
58
+ appendFileSync(input.logPath, `${stamp()} claudexord listening on ${input.socketPath} (recovery-only admission)\n`);
59
+ }
60
+ if (!input.control) {
61
+ if (!input.requested()) {
62
+ appendFileSync(input.logPath, `${stamp()} claudexor control-api disabled by CLAUDEXOR_NO_CONTROL_API=1\n`);
63
+ }
64
+ return null;
65
+ }
66
+ if (input.requested())
67
+ return null;
68
+ const controlAddr = await input.control.start();
69
+ if (input.requested())
70
+ return null;
71
+ writeFileSync(join(input.daemonDir, "control-api.json"), `${JSON.stringify({ ...controlAddr, tokenPath: join(input.daemonDir, "token") }, null, 2)}\n`, { mode: 0o600 });
72
+ appendFileSync(input.logPath, `${stamp()} claudexor control-api listening on http://${controlAddr.host}:${controlAddr.port}\n`);
73
+ return controlAddr;
74
+ }
75
+ /** Stage 3 proof: prove self-health and exact identity through the REAL
76
+ * transport while product admission is still closed. */
77
+ export async function proveRecoveryTransport(input) {
78
+ const health = (await input.socket.health());
79
+ if (health?.ok !== true || health.servingMode !== "recovery_only") {
80
+ throw new Error("daemon transport proof failed: socket health did not report a recovery-only serving daemon");
81
+ }
82
+ if (!input.control)
83
+ return;
84
+ const response = await fetch(`http://${input.control.host}:${input.control.port}/v2/handshake`, {
85
+ method: "POST",
86
+ headers: {
87
+ authorization: `Bearer ${input.token}`,
88
+ "content-type": "application/json",
89
+ },
90
+ body: JSON.stringify({ protocolMajor: CONTROL_PROTOCOL_MAJOR, client: "claudexord-startup" }),
91
+ });
92
+ if (!response.ok) {
93
+ throw new Error(`daemon transport proof failed: control handshake HTTP ${response.status}`);
94
+ }
95
+ const body = (await response.json());
96
+ if (body?.engine?.version !== input.identity.version ||
97
+ body.engine.sha !== input.identity.sha ||
98
+ body.servingMode !== "recovery_only") {
99
+ throw new Error("daemon transport proof failed: control handshake did not prove this exact recovery-only runtime");
100
+ }
101
+ }
102
+ /** Stage 4: revalidate every read-only preparation FIRST; only on all-green
103
+ * advance the floor, run destructive recovery and open normal admission — or
104
+ * the protected recovery-only outcome (floor unchanged, cleanup off). */
105
+ export async function completeStartupAdmission(input) {
106
+ if (input.blockedPartitions.length > 0) {
107
+ input.log(`startup admission: serving recovery only — floor unchanged, destructive recovery and cleanup OFF (recovery required: ${input.blockedPartitions.join(", ")})`);
108
+ return "recovery_only";
109
+ }
110
+ // C3: prove the filesystem still matches every stage-2 preparation BEFORE
111
+ // the first irreversible act. Any revalidation failure leaves the floor
112
+ // UNCHANGED and zero destructive work done.
113
+ try {
114
+ input.global.revalidatePreparation();
115
+ input.partitions.revalidatePreparation();
116
+ }
117
+ catch (error) {
118
+ if (error instanceof JournalRecoveryRequiredError) {
119
+ input.log(`startup admission: preparation revalidation failed; serving recovery only with floor unchanged (${error.message})`);
120
+ return "recovery_only";
121
+ }
122
+ throw error;
123
+ }
124
+ input.grant.advanceFloor();
125
+ await input.crashGc();
126
+ try {
127
+ input.global.activatePrepared();
128
+ input.partitions.activatePrepared();
129
+ input.global.recoverAfterStartup();
130
+ input.partitions.recoverAfterStartup();
131
+ }
132
+ catch (error) {
133
+ if (error instanceof JournalRecoveryRequiredError) {
134
+ // Activation re-revalidates and raced a journal mutation: stay on the
135
+ // recovery plane instead of serving a partition we could not activate.
136
+ input.log(`startup admission: prepared activation entered recovery; serving recovery only (${error.message})`);
137
+ return "recovery_only";
138
+ }
139
+ throw error;
140
+ }
141
+ input.admission.openNormal();
142
+ input.log("startup admission: normal product admission open");
143
+ return "normal";
144
+ }
145
+ /** Post-admission ghost-project quarantine (F2), normal admission only. */
146
+ export function quarantineGhostProjectsAtStartup(threads, log) {
147
+ try {
148
+ for (const ghost of threads.quarantineGhostProjects()) {
149
+ log(`projects: quarantined ghost ${ghost.projectId} (${ghost.reason}): ${ghost.root}`);
150
+ }
151
+ }
152
+ catch (error) {
153
+ log(`projects: ghost sweep failed: ${error instanceof Error ? error.message : String(error)}`);
154
+ }
155
+ }
156
+ //# sourceMappingURL=daemon-startup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon-startup.js","sourceRoot":"","sources":["../src/daemon-startup.ts"],"names":[],"mappings":"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"}
@@ -12,6 +12,10 @@ export interface EngineSkew {
12
12
  export interface EngineIdentity {
13
13
  engineVersion: string | null;
14
14
  engineBuildSha: string | null;
15
+ /** Product admission at handshake time (issue #165 D5). A pre-#165 daemon
16
+ * reports nothing and is always serving normally, so absent maps to
17
+ * `normal`; `recovery_only` means product routes are typed-closed. */
18
+ servingMode: "normal" | "recovery_only";
15
19
  }
16
20
  /** The ONE remedy wording — stderr advisory and typed requiredActions speak
17
21
  * with the same voice, so it must stay CALLER-NEUTRAL: acting commands
@@ -1 +1 @@
1
- {"version":3,"file":"engine-skew.d.ts","sourceRoot":"","sources":["../src/engine-skew.ts"],"names":[],"mappings":"AA0BA,gFAAgF;AAChF,MAAM,WAAW,UAAU;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,4EAA4E;IAC5E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;kFAGkF;AAClF,MAAM,WAAW,cAAc;IAC7B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED;;;;;;sEAMsE;AACtE,eAAO,MAAM,kBAAkB,uJACkH,CAAC;AAIlJ;;sEAEsE;AACtE,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,GAAG,IAAI,CAE9D;AAED,uEAAuE;AACvE,wBAAgB,kBAAkB,IAAI,UAAU,GAAG,IAAI,CAEtD;AAQD,MAAM,WAAW,iBAAiB;IAChC,8EAA8E;IAC9E,MAAM,EAAE,cAAc,CAAC;IACvB;uEACmE;IACnE,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,OAAO,GAAG,iBAAiB,CAyBzE;AAED;;2DAE2D;AAC3D,MAAM,WAAW,mBAAmB;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACvC,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,mBAAmB,EAC3B,qBAAqB,CAAC,EAAE,MAAM,EAAE,GAC/B,mBAAmB,CAYrB"}
1
+ {"version":3,"file":"engine-skew.d.ts","sourceRoot":"","sources":["../src/engine-skew.ts"],"names":[],"mappings":"AA0BA,gFAAgF;AAChF,MAAM,WAAW,UAAU;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,4EAA4E;IAC5E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;kFAGkF;AAClF,MAAM,WAAW,cAAc;IAC7B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B;;0EAEsE;IACtE,WAAW,EAAE,QAAQ,GAAG,eAAe,CAAC;CACzC;AAED;;;;;;sEAMsE;AACtE,eAAO,MAAM,kBAAkB,uJACkH,CAAC;AAIlJ;;sEAEsE;AACtE,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,GAAG,IAAI,CAE9D;AAED,uEAAuE;AACvE,wBAAgB,kBAAkB,IAAI,UAAU,GAAG,IAAI,CAEtD;AAQD,MAAM,WAAW,iBAAiB;IAChC,8EAA8E;IAC9E,MAAM,EAAE,cAAc,CAAC;IACvB;uEACmE;IACnE,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,OAAO,GAAG,iBAAiB,CAgCzE;AAED;;2DAE2D;AAC3D,MAAM,WAAW,mBAAmB;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACvC,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,mBAAmB,EAC3B,qBAAqB,CAAC,EAAE,MAAM,EAAE,GAC/B,mBAAmB,CAYrB"}
@@ -58,9 +58,13 @@ export function consumeHandshakeIdentity(body) {
58
58
  if (!parsed.success) {
59
59
  // Identity is advisory; a malformed body never fails the handshake.
60
60
  recordEngineSkew(null);
61
- return { engine: { engineVersion: null, engineBuildSha: null }, skewAdvisory: null };
61
+ return {
62
+ engine: { engineVersion: null, engineBuildSha: null, servingMode: "normal" },
63
+ skewAdvisory: null,
64
+ };
62
65
  }
63
66
  const { version, sha } = parsed.data.engine;
67
+ const servingMode = parsed.data.servingMode ?? "normal";
64
68
  const daemonVersion = ENGINE_VERSION_RE.test(version) ? version : null;
65
69
  const engineBuildSha = sha === "unknown" || BUILD_SHA_RE.test(sha) ? sha : null;
66
70
  if (daemonVersion && daemonVersion !== CLAUDEXOR_VERSION) {
@@ -70,13 +74,16 @@ export function consumeHandshakeIdentity(body) {
70
74
  cliVersion: CLAUDEXOR_VERSION,
71
75
  });
72
76
  return {
73
- engine: { engineVersion: daemonVersion, engineBuildSha },
77
+ engine: { engineVersion: daemonVersion, engineBuildSha, servingMode },
74
78
  skewAdvisory: `claudexor: daemon is engine ${daemonVersion} but this CLI is ${CLAUDEXOR_VERSION}; ` +
75
79
  `${ENGINE_STOP_REMEDY}\n`,
76
80
  };
77
81
  }
78
82
  recordEngineSkew(null);
79
- return { engine: { engineVersion: daemonVersion, engineBuildSha }, skewAdvisory: null };
83
+ return {
84
+ engine: { engineVersion: daemonVersion, engineBuildSha, servingMode },
85
+ skewAdvisory: null,
86
+ };
80
87
  }
81
88
  /**
82
89
  * Shape a typed problem's fields at the controlProblemError choke point:
@@ -1 +1 @@
1
- {"version":3,"file":"engine-skew.js","sourceRoot":"","sources":["../src/engine-skew.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,OAAO,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAmBpD;;;;;;sEAMsE;AACtE,MAAM,CAAC,MAAM,kBAAkB,GAC7B,+IAA+I,CAAC;AAElJ,IAAI,YAAY,GAAsB,IAAI,CAAC;AAE3C;;sEAEsE;AACtE,MAAM,UAAU,gBAAgB,CAAC,IAAuB;IACtD,YAAY,GAAG,IAAI,CAAC;AACtB,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,kBAAkB;IAChC,OAAO,YAAY,CAAC,CAAC,CAAC,EAAE,GAAG,YAAY,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AACnD,CAAC;AAED,2EAA2E;AAC3E,6EAA6E;AAC7E,qCAAqC;AACrC,MAAM,iBAAiB,GAAG,iBAAiB,CAAC;AAC5C,MAAM,YAAY,GAAG,gBAAgB,CAAC;AAUtC;;;;;GAKG;AACH,MAAM,UAAU,wBAAwB,CAAC,IAAa;IACpD,MAAM,MAAM,GAAG,wBAAwB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACxD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,oEAAoE;QACpE,gBAAgB,CAAC,IAAI,CAAC,CAAC;QACvB,OAAO,EAAE,MAAM,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC;IACvF,CAAC;IACD,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;IAC5C,MAAM,aAAa,GAAG,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;IACvE,MAAM,cAAc,GAAG,GAAG,KAAK,SAAS,IAAI,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;IAChF,IAAI,aAAa,IAAI,aAAa,KAAK,iBAAiB,EAAE,CAAC;QACzD,gBAAgB,CAAC;YACf,aAAa;YACb,GAAG,CAAC,cAAc,IAAI,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACxF,UAAU,EAAE,iBAAiB;SAC9B,CAAC,CAAC;QACH,OAAO;YACL,MAAM,EAAE,EAAE,aAAa,EAAE,aAAa,EAAE,cAAc,EAAE;YACxD,YAAY,EACV,+BAA+B,aAAa,oBAAoB,iBAAiB,IAAI;gBACrF,GAAG,kBAAkB,IAAI;SAC5B,CAAC;IACJ,CAAC;IACD,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACvB,OAAO,EAAE,MAAM,EAAE,EAAE,aAAa,EAAE,aAAa,EAAE,cAAc,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC;AAC1F,CAAC;AAcD;;;;;;;GAOG;AACH,MAAM,UAAU,eAAe,CAC7B,MAA2B,EAC3B,qBAAgC;IAEhC,MAAM,IAAI,GAAG,YAAY,CAAC;IAC1B,MAAM,QAAQ,GAAG,MAAM,CAAC,eAAe,IAAI,EAAE,CAAC;IAC9C,MAAM,QAAQ,GAAG,CAAC,GAAG,CAAC,qBAAqB,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAC/F,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,KAAK,CACpF,CAAC;IACF,IAAI,CAAC,IAAI,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,MAAM,CAAC;IAClD,OAAO;QACL,GAAG,MAAM;QACT,eAAe,EAAE,CAAC,GAAG,QAAQ,EAAE,GAAG,QAAQ,CAAC;QAC3C,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,GAAG,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC,EAAE,UAAU,EAAE,EAAE,GAAG,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACrF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"engine-skew.js","sourceRoot":"","sources":["../src/engine-skew.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,OAAO,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAuBpD;;;;;;sEAMsE;AACtE,MAAM,CAAC,MAAM,kBAAkB,GAC7B,+IAA+I,CAAC;AAElJ,IAAI,YAAY,GAAsB,IAAI,CAAC;AAE3C;;sEAEsE;AACtE,MAAM,UAAU,gBAAgB,CAAC,IAAuB;IACtD,YAAY,GAAG,IAAI,CAAC;AACtB,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,kBAAkB;IAChC,OAAO,YAAY,CAAC,CAAC,CAAC,EAAE,GAAG,YAAY,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AACnD,CAAC;AAED,2EAA2E;AAC3E,6EAA6E;AAC7E,qCAAqC;AACrC,MAAM,iBAAiB,GAAG,iBAAiB,CAAC;AAC5C,MAAM,YAAY,GAAG,gBAAgB,CAAC;AAUtC;;;;;GAKG;AACH,MAAM,UAAU,wBAAwB,CAAC,IAAa;IACpD,MAAM,MAAM,GAAG,wBAAwB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACxD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,oEAAoE;QACpE,gBAAgB,CAAC,IAAI,CAAC,CAAC;QACvB,OAAO;YACL,MAAM,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE;YAC5E,YAAY,EAAE,IAAI;SACnB,CAAC;IACJ,CAAC;IACD,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;IAC5C,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,IAAI,QAAQ,CAAC;IACxD,MAAM,aAAa,GAAG,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;IACvE,MAAM,cAAc,GAAG,GAAG,KAAK,SAAS,IAAI,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;IAChF,IAAI,aAAa,IAAI,aAAa,KAAK,iBAAiB,EAAE,CAAC;QACzD,gBAAgB,CAAC;YACf,aAAa;YACb,GAAG,CAAC,cAAc,IAAI,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACxF,UAAU,EAAE,iBAAiB;SAC9B,CAAC,CAAC;QACH,OAAO;YACL,MAAM,EAAE,EAAE,aAAa,EAAE,aAAa,EAAE,cAAc,EAAE,WAAW,EAAE;YACrE,YAAY,EACV,+BAA+B,aAAa,oBAAoB,iBAAiB,IAAI;gBACrF,GAAG,kBAAkB,IAAI;SAC5B,CAAC;IACJ,CAAC;IACD,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACvB,OAAO;QACL,MAAM,EAAE,EAAE,aAAa,EAAE,aAAa,EAAE,cAAc,EAAE,WAAW,EAAE;QACrE,YAAY,EAAE,IAAI;KACnB,CAAC;AACJ,CAAC;AAcD;;;;;;;GAOG;AACH,MAAM,UAAU,eAAe,CAC7B,MAA2B,EAC3B,qBAAgC;IAEhC,MAAM,IAAI,GAAG,YAAY,CAAC;IAC1B,MAAM,QAAQ,GAAG,MAAM,CAAC,eAAe,IAAI,EAAE,CAAC;IAC9C,MAAM,QAAQ,GAAG,CAAC,GAAG,CAAC,qBAAqB,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAC/F,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,KAAK,CACpF,CAAC;IACF,IAAI,CAAC,IAAI,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,MAAM,CAAC;IAClD,OAAO;QACL,GAAG,MAAM;QACT,eAAe,EAAE,CAAC,GAAG,QAAQ,EAAE,GAAG,QAAQ,CAAC;QAC3C,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,GAAG,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC,EAAE,UAAU,EAAE,EAAE,GAAG,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACrF,CAAC;AACJ,CAAC"}
@@ -1,7 +1,80 @@
1
- export declare function projectImmediateRunDetail(detail: Record<string, unknown> | null): {
1
+ import { type ExpectedRunFactsIdentity } from "./run-facts-projection.js";
2
+ export declare function projectImmediateRunDetail(detail: Record<string, unknown> | null, expected?: ExpectedRunFactsIdentity): {
2
3
  parentRunId: string | null;
3
4
  delegatedFromRunId: string | null;
4
5
  delegation: Record<string, unknown> | null;
6
+ runFacts: {
7
+ schema_version: 2;
8
+ run_id: string;
9
+ task_id: string;
10
+ mode: "agent" | "ask" | "plan";
11
+ outcome: {
12
+ lifecycle: "cancelled" | "failed" | "interrupted" | "succeeded";
13
+ noChanges: boolean;
14
+ checks: "failed" | "not_configured" | "passed";
15
+ review: "approved" | "blocked" | "not_run";
16
+ reason: "budget_exhausted" | "budget_overshoot" | "checks_failed" | "context_capacity_exhausted" | "cost_unverifiable" | "crash_interrupted" | "harness_failed" | "input_required" | "no_changes" | "not_converged" | "review_blocked" | "stuck_no_progress" | "user_cancelled" | "wall_clock_exceeded" | "work_incomplete" | "work_report_contract" | "workspace_unavailable" | null;
17
+ work_state?: {
18
+ state: "completed" | "incomplete" | "needs_input" | "unverified";
19
+ source: "absent" | "constrained" | "validated";
20
+ required_inputs?: {
21
+ kind: "context" | "credential" | "decision" | "external_dependency" | "file" | "permission";
22
+ locator: string | null;
23
+ description: string;
24
+ }[] | undefined;
25
+ } | undefined;
26
+ };
27
+ deliverable: {
28
+ present: boolean;
29
+ kind: "answer" | "patch" | "plan" | "report" | "structured_output" | null;
30
+ path: string | null;
31
+ producer_attempt_id: string | null;
32
+ };
33
+ presentation?: {
34
+ state: "diagnostic" | "ready";
35
+ primary: {
36
+ kind: "answer" | "diagnostic" | "patch" | "plan" | "report" | "structured_output";
37
+ path: string;
38
+ } | null;
39
+ } | undefined;
40
+ participants: {
41
+ planners: number;
42
+ attempts: {
43
+ attempt_id: string | null;
44
+ harness_id: string;
45
+ role: "candidate" | "merge" | "planner" | "reducer" | "reviewer" | "scout";
46
+ deliverable_present: boolean;
47
+ status: "blocked" | "failed" | "success" | "success_with_warnings" | null;
48
+ }[];
49
+ };
50
+ gates: {
51
+ configured: boolean;
52
+ required: number;
53
+ total: number;
54
+ executed: boolean;
55
+ state: "failed" | "not_configured" | "passed" | "skipped";
56
+ receipt_attempt_id: string | null;
57
+ };
58
+ review: {
59
+ state: "approved" | "blocked" | "not_run";
60
+ blocker_ids: string[];
61
+ blockers: number;
62
+ };
63
+ apply: {
64
+ eligibility: {
65
+ eligible: boolean;
66
+ state: string | null;
67
+ reason: string | null;
68
+ requiredAction: string | null;
69
+ } | null;
70
+ operator_decision_present: boolean;
71
+ };
72
+ required_actions: {
73
+ id: "complete_incomplete_work" | "fix_failed_checks" | "provide_required_input" | "record_operator_decision" | "resolve_review_block";
74
+ detail: string;
75
+ }[];
76
+ generated_at: string;
77
+ } | null;
5
78
  outcomeFacts: {
6
79
  lifecycle: "cancelled" | "failed" | "interrupted" | "succeeded";
7
80
  noChanges: boolean;
@@ -40,4 +113,8 @@ export declare function projectImmediateRunDetail(detail: Record<string, unknown
40
113
  };
41
114
  /** One typed read projection for inspect/status/result from a single detail snapshot. */
42
115
  export declare function projectRecoveryRunDetail(mode: string, runId: string, detail: Record<string, unknown>, delegationParentRunId?: string): Record<string, unknown>;
116
+ /** Only canonical detail-integrity failures preserve a public recovery handle. */
117
+ export declare function isRecoverableRunDetailIntegrityProblem(error: unknown): boolean;
118
+ /** Minimal schema-valid handle when public recovery cannot trust run detail. */
119
+ export declare function projectDegradedRecoveryRunDetail(runId: string, error: unknown): Record<string, unknown>;
43
120
  //# sourceMappingURL=mcp-run-projections.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-run-projections.d.ts","sourceRoot":"","sources":["../src/mcp-run-projections.ts"],"names":[],"mappings":"AAYA,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAc/E;AAED,yFAAyF;AACzF,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,qBAAqB,CAAC,EAAE,MAAM,GAC7B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CA4DzB"}
1
+ {"version":3,"file":"mcp-run-projections.d.ts","sourceRoot":"","sources":["../src/mcp-run-projections.ts"],"names":[],"mappings":"AAcA,OAAO,EAAmB,KAAK,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AAE3F,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,EACtC,QAAQ,GAAE,wBAA6B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgBxC;AAED,yFAAyF;AACzF,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,qBAAqB,CAAC,EAAE,MAAM,GAC7B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CA+EzB;AAED,kFAAkF;AAClF,wBAAgB,sCAAsC,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAQ9E;AAED,gFAAgF;AAChF,wBAAgB,gCAAgC,CAC9C,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,OAAO,GACb,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAqBzB"}
@@ -1,7 +1,11 @@
1
- import { projectApplyEligibility, projectOutcomeBanner, presentRunPrimaryOutput, projectRunFailure, projectRunCouncil, projectRunLineage, projectRunPrimaryOutput, projectRunSpendUsd, } from "./run-detail-projections.js";
1
+ import { isTerminalLifecycle, RunFactsInvalidError } from "@claudexor/schema";
2
+ import { CliError } from "./cli-error.js";
3
+ import { describeRunDetailProblem, projectApplyEligibility, projectOutcomeBanner, presentRunPrimaryOutput, projectRunFailure, projectRunCouncil, projectRunLineage, projectRunPrimaryOutput, projectRunSpendUsd, } from "./run-detail-projections.js";
2
4
  import { projectRunOutcomeFacts } from "./daemon-outcome.js";
3
- export function projectImmediateRunDetail(detail) {
5
+ import { projectRunFacts } from "./run-facts-projection.js";
6
+ export function projectImmediateRunDetail(detail, expected = {}) {
4
7
  return {
8
+ runFacts: projectRunFacts(detail, expected),
5
9
  outcomeFacts: projectRunOutcomeFacts(detail),
6
10
  applyEligibility: projectApplyEligibility(detail),
7
11
  spendUsd: projectRunSpendUsd(detail),
@@ -17,7 +21,14 @@ export function projectImmediateRunDetail(detail) {
17
21
  /** One typed read projection for inspect/status/result from a single detail snapshot. */
18
22
  export function projectRecoveryRunDetail(mode, runId, detail, delegationParentRunId) {
19
23
  const summary = (detail["summary"] ?? {});
20
- if (delegationParentRunId && summary["delegatedFromRunId"] !== delegationParentRunId) {
24
+ if (summary["runId"] !== runId) {
25
+ throw new CliError("operational", `run detail identity does not match requested run ${runId}`, {
26
+ code: "invalid_service_response",
27
+ retryable: true,
28
+ });
29
+ }
30
+ if (delegationParentRunId !== undefined &&
31
+ summary["delegatedFromRunId"] !== delegationParentRunId) {
21
32
  throw Object.assign(new Error(`run ${runId} is not a child of this delegation parent`), {
22
33
  code: "delegation_child_scope_violation",
23
34
  status: 403,
@@ -27,10 +38,19 @@ export function projectRecoveryRunDetail(mode, runId, detail, delegationParentRu
27
38
  const status = (typeof summary["state"] === "string" ? summary["state"] : null) ??
28
39
  (typeof summary["status"] === "string" ? summary["status"] : null) ??
29
40
  null;
41
+ const runFacts = status === "queued" || status === "running"
42
+ ? null
43
+ : projectRunFacts(detail, {
44
+ runId,
45
+ ...(status && isTerminalLifecycle(status)
46
+ ? { lifecycle: status }
47
+ : {}),
48
+ });
30
49
  const base = {
31
50
  runId,
32
51
  runDir: typeof summary["runDir"] === "string" ? summary["runDir"] : null,
33
52
  status,
53
+ runFacts,
34
54
  decisionStatus: decision ? (decision["status"] ?? null) : null,
35
55
  pendingInteractions: Array.isArray(detail["pendingInteractions"])
36
56
  ? detail["pendingInteractions"].length
@@ -71,4 +91,38 @@ export function projectRecoveryRunDetail(mode, runId, detail, delegationParentRu
71
91
  : `run ${runId}: ${String(status ?? "unknown")}`;
72
92
  return { summary: terminalSummary, ...base };
73
93
  }
94
+ /** Only canonical detail-integrity failures preserve a public recovery handle. */
95
+ export function isRecoverableRunDetailIntegrityProblem(error) {
96
+ const record = error && typeof error === "object" ? error : {};
97
+ const code = record["code"];
98
+ if (code !== "run_facts_invalid" && code !== "invalid_service_response")
99
+ return false;
100
+ if (typeof record["mcpRecoveryTypedControlProblem"] === "boolean") {
101
+ return record["mcpRecoveryTypedControlProblem"] === true;
102
+ }
103
+ return error instanceof RunFactsInvalidError || error instanceof CliError;
104
+ }
105
+ /** Minimal schema-valid handle when public recovery cannot trust run detail. */
106
+ export function projectDegradedRecoveryRunDetail(runId, error) {
107
+ return {
108
+ summary: `run ${runId}: detail unavailable`,
109
+ runId,
110
+ runDir: null,
111
+ status: null,
112
+ runFacts: null,
113
+ decisionStatus: null,
114
+ pendingInteractions: null,
115
+ outcomeFacts: null,
116
+ failure: null,
117
+ outcomeBanner: null,
118
+ applyEligibility: null,
119
+ planReadiness: null,
120
+ council: null,
121
+ budget: null,
122
+ parentRunId: null,
123
+ delegatedFromRunId: null,
124
+ delegation: null,
125
+ detailProblem: describeRunDetailProblem(error),
126
+ };
127
+ }
74
128
  //# sourceMappingURL=mcp-run-projections.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-run-projections.js","sourceRoot":"","sources":["../src/mcp-run-projections.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mcp-run-projections.js","sourceRoot":"","sources":["../src/mcp-run-projections.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-runner.d.ts","sourceRoot":"","sources":["../src/mcp-runner.ts"],"names":[],"mappings":"AAeA,OAAO,EAAmB,KAAK,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAIpE,MAAM,WAAW,kBAAkB;IACjC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;IAC/B,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC;IAClD,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,MAAM,WAAW,uBAAuB;IACtC;8DAC0D;IAC1D,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC;oFACgF;IAChF,qBAAqB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC;qFACiF;IACjF,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC;;0CAEsC;IACtC,eAAe,CAAC,EAAE,CAChB,KAAK,EAAE,GAAG,EACV,KAAK,EAAE,kBAAkB,GAAG,SAAS,EACrC,OAAO,EAAE;QACP,MAAM,EAAE,OAAO,gBAAgB,CAAC;QAChC,YAAY,EAAE,OAAO,qBAAqB,CAAC;KAC5C,KACE,OAAO,CAAC,OAAO,CAAC,CAAC;CACvB;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,GAAE,uBAA4B,OACnD,GAAG,UAAU,kBAAkB,sBAwLjD;AA8OD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,iBAAiB,EACvB,MAAM,EAAE,WAAW,GAClB,CAAC,IAAI,EAAE;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAqB5C;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,iBAAiB,EACvB,aAAa,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,GAC/C,CAAC,IAAI,EAAE;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CA0E5C"}
1
+ {"version":3,"file":"mcp-runner.d.ts","sourceRoot":"","sources":["../src/mcp-runner.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAmB,KAAK,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAUpE,MAAM,WAAW,kBAAkB;IACjC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;IAC/B,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC;IAClD,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,MAAM,WAAW,uBAAuB;IACtC;8DAC0D;IAC1D,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC;oFACgF;IAChF,qBAAqB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC;qFACiF;IACjF,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC;;0CAEsC;IACtC,eAAe,CAAC,EAAE,CAChB,KAAK,EAAE,GAAG,EACV,KAAK,EAAE,kBAAkB,GAAG,SAAS,EACrC,OAAO,EAAE;QACP,MAAM,EAAE,OAAO,gBAAgB,CAAC;QAChC,YAAY,EAAE,OAAO,qBAAqB,CAAC;KAC5C,KACE,OAAO,CAAC,OAAO,CAAC,CAAC;CACvB;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,GAAE,uBAA4B,OACnD,GAAG,UAAU,kBAAkB,sBA6KjD;AAoPD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,iBAAiB,EACvB,MAAM,EAAE,WAAW,GAClB,CAAC,IAAI,EAAE;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAqB5C;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,iBAAiB,EACvB,aAAa,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,GAC/C,CAAC,IAAI,EAAE;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CA0E5C"}
@@ -1,10 +1,12 @@
1
- import { isTerminalLifecycle, ModeKind } from "@claudexor/schema";
1
+ import { ControlProblem, isTerminalLifecycle, ModeKind, } from "@claudexor/schema";
2
2
  import { connectDaemonIfRunning, daemonOutcomeSummary, ensureDaemon, enqueueAndAwait, fetchRunDetail, } from "./daemon-run.js";
3
3
  import { describeRunDetailProblem, presentRunPrimaryOutput, projectRunFailure, projectRunPrimaryOutput, } from "./run-detail-projections.js";
4
4
  import { primaryOutputForCli } from "./primary-output.js";
5
+ import { controlProblemError } from "./cli-error.js";
5
6
  import { controlApiFetch } from "./live.js";
6
7
  import { absentDaemonRecovery, BELT_DAEMON_LOST } from "./mcp-daemon-unavailable.js";
7
- import { projectImmediateRunDetail, projectRecoveryRunDetail } from "./mcp-run-projections.js";
8
+ import { isRecoverableRunDetailIntegrityProblem, projectDegradedRecoveryRunDetail, projectImmediateRunDetail, projectRecoveryRunDetail, } from "./mcp-run-projections.js";
9
+ import { readRunDetailResponse } from "./run-detail-response.js";
8
10
  /**
9
11
  * Shared MCP/ACP runner. All product modes cross the daemon's /v2 boundary;
10
12
  * interactive questions bridge through pendingInteractions and typed answers.
@@ -112,30 +114,28 @@ export function mcpSurfaceRunner(options = {}) {
112
114
  ...(onPollTick ? { onPollTick } : {}),
113
115
  });
114
116
  try {
115
- // The derived apply verdict rides the result (single producer: the run
116
- // detail endpoint). The post-terminal detail read DEGRADES: a missing/
117
- // legacy detail projects null fields, and a raised typed problem —
118
- // especially 500 run_facts_invalid, the server's verdict that the run's
119
- // receipt cannot be trusted — rides the result as `detailProblem` with
120
- // the runId preserved instead of erasing the finished run's outcome.
121
- // A deferred MCP call normally returns while the run is still live, but
122
- // the bind/status race may already observe a terminal. Project detail
123
- // from ACTUAL lifecycle truth; never delay an ordinary running handle.
124
117
  let detail = null;
118
+ let canonicalPrimary = null;
119
+ let detailProjection = projectImmediateRunDetail(null, { runId: out.runId });
125
120
  let detailProblem = null;
126
121
  if (p?.deferred !== true || isTerminalLifecycle(out.status)) {
127
122
  try {
128
123
  detail = await fetchRunDetail(addr, out.runId);
124
+ detailProjection = projectImmediateRunDetail(detail, {
125
+ runId: out.runId,
126
+ ...(isTerminalLifecycle(out.status)
127
+ ? { lifecycle: out.status }
128
+ : {}),
129
+ });
130
+ canonicalPrimary = projectRunPrimaryOutput(detail);
129
131
  }
130
132
  catch (error) {
133
+ detail = null;
131
134
  detailProblem = describeRunDetailProblem(error);
135
+ detailProjection = projectImmediateRunDetail(null, { runId: out.runId });
132
136
  }
133
137
  }
134
- // Canonical output comes from that same detail read (bounded, redacted,
135
- // mode-aware). Read local artifacts only when detail was attempted but
136
- // unavailable; this preserves a useful terminal result without creating a
137
- // second normal-path artifact owner.
138
- const canonicalPrimary = projectRunPrimaryOutput(detail);
138
+ // Local artifacts remain only the established soft-absence fallback.
139
139
  const localFallback = (p?.deferred !== true || isTerminalLifecycle(out.status)) &&
140
140
  !detail &&
141
141
  !detailProblem &&
@@ -149,7 +149,6 @@ export function mcpSurfaceRunner(options = {}) {
149
149
  : null;
150
150
  const primary = canonicalPrimary ?? localFallback;
151
151
  const presented = presentRunPrimaryOutput(primary);
152
- const detailProjection = projectImmediateRunDetail(detail);
153
152
  const reason = daemonOutcomeSummary({
154
153
  ...out,
155
154
  outcomeFacts: detailProjection.outcomeFacts ?? undefined,
@@ -158,14 +157,6 @@ export function mcpSurfaceRunner(options = {}) {
158
157
  detailProjection.outcomeBanner ??
159
158
  reason ??
160
159
  (primary?.kind === "patch" ? "patch produced (see artifacts)" : `run ${out.status}`);
161
- // The sub-run's real settled spend rides the result so the delegation belt
162
- // can reconcile its budget reservation against the actual drawn amount
163
- // (single producer: the run-detail budget projection). Deferred calls return
164
- // before terminal, so spend is not yet settled — null (the belt then keeps
165
- // its reservation committed fail-closed rather than seeing spend 0).
166
- // Council membership + merge disclosure (QA-023b) rides the result so an MCP
167
- // host that asked for `--council` can machine-verify it was really N/N and
168
- // who merged. Terminal projection — null on a deferred (still-live) handle.
169
160
  return {
170
161
  runId: out.runId,
171
162
  runDir: out.runDir,
@@ -220,18 +211,21 @@ async function recoveryQuery(mode, runId, input = {}, context = {}) {
220
211
  if (!conn)
221
212
  return absentDaemonRecovery(mode, context.beltContext);
222
213
  const { addr } = conn;
223
- const get = async (path) => {
214
+ const get = async (path, runDetail = false) => {
224
215
  const res = await controlApiFetch(addr, path, {
225
216
  headers: { authorization: `Bearer ${addr.token}` },
226
217
  });
227
- const body = (await res.json().catch(() => ({})));
228
- if (!res.ok)
229
- throw new Error(typeof body["message"] === "string"
230
- ? body["message"]
231
- : typeof body["error"] === "string"
232
- ? body["error"]
233
- : `HTTP ${res.status} for ${path}`);
234
- return body;
218
+ if (res.ok) {
219
+ return runDetail
220
+ ? readRunDetailResponse(res)
221
+ : (await res.json());
222
+ }
223
+ const body = await res.json().catch(() => ({}));
224
+ const error = controlProblemError(res.status, body, `HTTP ${res.status} for ${path}`);
225
+ Object.assign(error, {
226
+ mcpRecoveryTypedControlProblem: ControlProblem.safeParse(body).success,
227
+ });
228
+ throw error;
235
229
  };
236
230
  if (mode === "__runs_list") {
237
231
  // GET /runs is a BOUNDED keyset page (QA-052): a single read undercounts the
@@ -285,10 +279,20 @@ async function recoveryQuery(mode, runId, input = {}, context = {}) {
285
279
  if (!runId)
286
280
  throw new Error("runId is required");
287
281
  if (mode === "__run_inspect" || mode === "__run_status" || mode === "__run_result") {
288
- const detail = await get(`/runs/${encodeURIComponent(runId)}`);
289
- return projectRecoveryRunDetail(mode, runId, detail, typeof input["delegatedFromRunId"] === "string"
282
+ const parent = typeof input["delegatedFromRunId"] === "string"
290
283
  ? input["delegatedFromRunId"]
291
- : undefined);
284
+ : undefined;
285
+ const scopedRecovery = context.beltContext || parent !== undefined;
286
+ try {
287
+ const detail = await get(`/runs/${encodeURIComponent(runId)}`, true);
288
+ return projectRecoveryRunDetail(mode, runId, detail, parent);
289
+ }
290
+ catch (error) {
291
+ if (scopedRecovery || !isRecoverableRunDetailIntegrityProblem(error)) {
292
+ throw error;
293
+ }
294
+ return projectDegradedRecoveryRunDetail(runId, error);
295
+ }
292
296
  }
293
297
  if (mode === "__run_cancel") {
294
298
  const res = await controlApiFetch(addr, `/runs/${encodeURIComponent(runId)}/control`, {