@amaster.ai/employee-runtime-connector 0.1.0-beta.49 → 0.1.0-beta.50

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.
@@ -3,9 +3,9 @@
3
3
 
4
4
  // src/amaster-runtime-daemon.mjs
5
5
  import { createHash as createHash12 } from "node:crypto";
6
- import { chmodSync as chmodSync6, copyFileSync as copyFileSync3, existsSync as existsSync13, lstatSync as lstatSync7, mkdirSync as mkdirSync8, readFileSync as readFileSync10, readdirSync as readdirSync8, realpathSync as realpathSync4, renameSync as renameSync5, rmSync as rmSync7, statSync as statSync7, symlinkSync as symlinkSync4, unlinkSync, writeFileSync as writeFileSync8 } from "node:fs";
6
+ import { chmodSync as chmodSync6, copyFileSync as copyFileSync3, existsSync as existsSync14, lstatSync as lstatSync7, mkdirSync as mkdirSync9, readFileSync as readFileSync11, readdirSync as readdirSync9, realpathSync as realpathSync5, renameSync as renameSync6, rmSync as rmSync7, statSync as statSync7, symlinkSync as symlinkSync4, unlinkSync as unlinkSync2, writeFileSync as writeFileSync9 } from "node:fs";
7
7
  import { arch as arch3, homedir as homedir3, hostname as hostname2, platform as platform3 } from "node:os";
8
- import { basename as basename6, delimiter as delimiter2, dirname as dirname9, extname as extname2, isAbsolute as isAbsolute8, join as join14, relative as relative9, resolve as resolve12 } from "node:path";
8
+ import { basename as basename6, delimiter as delimiter2, dirname as dirname9, extname as extname2, isAbsolute as isAbsolute8, join as join15, relative as relative9, resolve as resolve12 } from "node:path";
9
9
  import { spawn, spawnSync as spawnSync6 } from "node:child_process";
10
10
  import { createRequire } from "node:module";
11
11
 
@@ -59,7 +59,7 @@ function quoteShell(value) {
59
59
 
60
60
  // src/amaster-runtime-daemon/codex-managed-mcp-profile.mjs
61
61
  import { createHash } from "node:crypto";
62
- import { chmodSync, existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, rmSync, statSync, writeFileSync } from "node:fs";
62
+ import { chmodSync, existsSync, lstatSync, mkdirSync, readFileSync, realpathSync, readdirSync, rmSync, statSync, writeFileSync } from "node:fs";
63
63
  import { arch, platform } from "node:os";
64
64
  import { basename, dirname, isAbsolute, join as join2, relative, resolve } from "node:path";
65
65
  import { spawnSync } from "node:child_process";
@@ -1489,6 +1489,7 @@ function cleanupManagedCodexMcpProfile(profile, owner) {
1489
1489
  function reconcileManagedCodexMcpProfiles(rootPath, options = {}) {
1490
1490
  const root = resolve(rootPath);
1491
1491
  if (!existsSync(root)) return { scanned: 0, removed: 0, removedProfiles: 0, removedRollouts: 0, failed: 0, failures: [] };
1492
+ const canonicalRoot = realpathSync(root);
1492
1493
  const profileMarkers = [];
1493
1494
  const rolloutMarkers = [];
1494
1495
  const pending = [root];
@@ -1504,16 +1505,23 @@ function reconcileManagedCodexMcpProfiles(rootPath, options = {}) {
1504
1505
  }
1505
1506
  }
1506
1507
  let removedProfiles = 0;
1508
+ let preservedProfiles = 0;
1507
1509
  let removedRollouts = 0;
1508
1510
  const failures = [];
1511
+ const protectedCommandIds = new Set(Array.isArray(options.protectedCommandIds) ? options.protectedCommandIds.filter((value) => typeof value === "string" && value) : []);
1509
1512
  for (const markerPath of profileMarkers) {
1510
1513
  const profileRoot = dirname(markerPath);
1511
1514
  try {
1512
1515
  const marker = JSON.parse(readFileSync(markerPath, "utf8"));
1513
- if (!within(profileRoot, root) || marker?.profileRoot !== profileRoot) {
1516
+ const markerProfileRoot = typeof marker?.profileRoot === "string" ? resolve(marker.profileRoot) : null;
1517
+ if (!markerProfileRoot || !existsSync(markerProfileRoot) || !within(realpathSync(profileRoot), canonicalRoot) || realpathSync(markerProfileRoot) !== realpathSync(profileRoot)) {
1514
1518
  throw new Error("ownership marker root mismatch");
1515
1519
  }
1516
- cleanupManagedCodexMcpProfile({ profileRoot }, { commandId: marker.commandId, runId: marker.runId });
1520
+ if (protectedCommandIds.has(marker?.commandId)) {
1521
+ preservedProfiles += 1;
1522
+ continue;
1523
+ }
1524
+ cleanupManagedCodexMcpProfile({ profileRoot: markerProfileRoot }, { commandId: marker.commandId, runId: marker.runId });
1517
1525
  removedProfiles += 1;
1518
1526
  } catch (error) {
1519
1527
  failures.push({ profileRoot, error: error instanceof Error ? error.message : String(error) });
@@ -1527,7 +1535,8 @@ function reconcileManagedCodexMcpProfiles(rootPath, options = {}) {
1527
1535
  const markerStat = lstatSync(markerPath);
1528
1536
  const cacheStat = lstatSync(cacheRoot);
1529
1537
  const marker = JSON.parse(readFileSync(markerPath, "utf8"));
1530
- if (!within(cacheRoot, root) || basename(cacheRoot) !== "session-rollout" || markerStat.isSymbolicLink() || !markerStat.isFile() || cacheStat.isSymbolicLink() || !cacheStat.isDirectory() || marker?.version !== 1 || typeof marker?.companyId !== "string" || typeof marker?.agentId !== "string" || typeof marker?.sourceRunId !== "string" || typeof marker?.sourceCommandId !== "string" || typeof marker?.sessionId !== "string" || marker?.cacheRoot != null && marker.cacheRoot !== cacheRoot) {
1538
+ const markerCacheRoot = typeof marker?.cacheRoot === "string" ? resolve(marker.cacheRoot) : null;
1539
+ if (!within(realpathSync(cacheRoot), canonicalRoot) || basename(cacheRoot) !== "session-rollout" || markerStat.isSymbolicLink() || !markerStat.isFile() || cacheStat.isSymbolicLink() || !cacheStat.isDirectory() || marker?.version !== 1 || typeof marker?.companyId !== "string" || typeof marker?.agentId !== "string" || typeof marker?.sourceRunId !== "string" || typeof marker?.sourceCommandId !== "string" || typeof marker?.sessionId !== "string" || markerCacheRoot != null && (!existsSync(markerCacheRoot) || realpathSync(markerCacheRoot) !== realpathSync(cacheRoot))) {
1531
1540
  throw new Error("session rollout ownership marker mismatch");
1532
1541
  }
1533
1542
  const preservedAtMs = typeof marker.preservedAt === "string" ? Date.parse(marker.preservedAt) : Number.NaN;
@@ -1544,6 +1553,7 @@ function reconcileManagedCodexMcpProfiles(rootPath, options = {}) {
1544
1553
  scanned: profileMarkers.length + rolloutMarkers.length,
1545
1554
  removed: removedProfiles + removedRollouts,
1546
1555
  removedProfiles,
1556
+ preservedProfiles,
1547
1557
  removedRollouts,
1548
1558
  failed: failures.length,
1549
1559
  failures
@@ -1559,7 +1569,7 @@ import {
1559
1569
  lstatSync as lstatSync2,
1560
1570
  mkdirSync as mkdirSync3,
1561
1571
  readFileSync as readFileSync3,
1562
- realpathSync,
1572
+ realpathSync as realpathSync2,
1563
1573
  readdirSync as readdirSync2,
1564
1574
  rmSync as rmSync2,
1565
1575
  statSync as statSync2,
@@ -1886,7 +1896,7 @@ function createManagedPiMcpProfileApi(options = {}) {
1886
1896
  const PI_ATTESTATION_MAX_ATTEMPTS = 2;
1887
1897
  const PI_ATTESTATION_RECENT_LIVE_TTL_MS = Number.isFinite(options.recentLiveTtlMs) && options.recentLiveTtlMs > 0 ? options.recentLiveTtlMs : 30 * 60 * 1e3;
1888
1898
  const recentLivePiVersionProbes = /* @__PURE__ */ new Map();
1889
- function record4(value) {
1899
+ function record5(value) {
1890
1900
  return value && typeof value === "object" && !Array.isArray(value) ? value : {};
1891
1901
  }
1892
1902
  function npmPackageName(source) {
@@ -1942,7 +1952,7 @@ function createManagedPiMcpProfileApi(options = {}) {
1942
1952
  return matches[0];
1943
1953
  }
1944
1954
  function restoreManagedPiSessionRollout(input, sessionsRoot, runDir, executorHome, authority) {
1945
- const session = record4(input.nativeSession);
1955
+ const session = record5(input.nativeSession);
1946
1956
  if (session.mode !== "governed_action_approval" || session.required !== true) return null;
1947
1957
  const sessionId = nonEmpty2(session.sessionId, "nativeSession.sessionId");
1948
1958
  const sourceRunId = nonEmpty2(session.sourceRunId, "nativeSession.sourceRunId");
@@ -1998,7 +2008,7 @@ function createManagedPiMcpProfileApi(options = {}) {
1998
2008
  }
1999
2009
  function piExecutableIdentity(executorCommand) {
2000
2010
  try {
2001
- const realPath = realpathSync(executorCommand);
2011
+ const realPath = realpathSync2(executorCommand);
2002
2012
  const executableStat = lstatSync2(realPath);
2003
2013
  if (!executableStat.isFile() || executableStat.isSymbolicLink()) {
2004
2014
  throw Object.assign(new Error("Pi executable is not a regular file"), { code: "EUNSAFE" });
@@ -2019,8 +2029,8 @@ function createManagedPiMcpProfileApi(options = {}) {
2019
2029
  }
2020
2030
  }
2021
2031
  function validateAuthority2(input) {
2022
- const runtimeAuth = record4(input.runtimeAuth);
2023
- const gateway = record4(runtimeAuth.governedMcp);
2032
+ const runtimeAuth = record5(input.runtimeAuth);
2033
+ const gateway = record5(runtimeAuth.governedMcp);
2024
2034
  const runId = nonEmpty2(input.runId, "runId");
2025
2035
  if (runtimeAuth.runId !== runId) throw new Error("pi_managed_mcp_owner_mismatch: command runId does not match runtime authority");
2026
2036
  if (gateway.schemaVersion !== SUPPORTED_SCHEMA_VERSION2) throw new Error("pi_managed_mcp_invalid: unsupported schema version");
@@ -2036,7 +2046,7 @@ function createManagedPiMcpProfileApi(options = {}) {
2036
2046
  if (!Number.isFinite(expiresAt) || expiresAt <= Date.now() + 3e4) {
2037
2047
  throw new Error("pi_managed_mcp_session_expired: Gateway session must remain valid through spawn preflight");
2038
2048
  }
2039
- const headers = record4(gateway.headers);
2049
+ const headers = record5(gateway.headers);
2040
2050
  for (const name of REQUIRED_AUTHORITY_HEADERS2) nonEmpty2(headers[name], `headers.${name}`);
2041
2051
  const allowedHeaderNames = /* @__PURE__ */ new Set([...REQUIRED_AUTHORITY_HEADERS2, ...runtimeAuth.issueId ? ["x-amaster-issue-id"] : []]);
2042
2052
  if (Object.keys(headers).some((name) => !allowedHeaderNames.has(name)) || Object.keys(headers).length !== allowedHeaderNames.size) {
@@ -2065,7 +2075,7 @@ function createManagedPiMcpProfileApi(options = {}) {
2065
2075
  return output;
2066
2076
  }
2067
2077
  function assertInvocationIsolation2(input) {
2068
- for (const name of Object.keys(record4(input.commandEnv))) {
2078
+ for (const name of Object.keys(record5(input.commandEnv))) {
2069
2079
  if (FORBIDDEN_COMMAND_ENV2.has(name)) throw new Error(`pi_managed_mcp_env_override_blocked: ${name}`);
2070
2080
  if (!ALLOWED_COMMAND_ENV2.has(name)) throw new Error(`pi_managed_mcp_env_injection_blocked: ${name}`);
2071
2081
  }
@@ -2097,7 +2107,7 @@ function createManagedPiMcpProfileApi(options = {}) {
2097
2107
  const value = safeProxyValue2(baseEnv?.[name], name);
2098
2108
  if (value) env[name] = value;
2099
2109
  }
2100
- return { ...env, ...record4(commandEnv) };
2110
+ return { ...env, ...record5(commandEnv) };
2101
2111
  }
2102
2112
  function projectMcpConfigHasContent(filePath) {
2103
2113
  if (!existsSync3(filePath)) return false;
@@ -2107,8 +2117,8 @@ function createManagedPiMcpProfileApi(options = {}) {
2107
2117
  } catch {
2108
2118
  return true;
2109
2119
  }
2110
- const config = record4(parsed);
2111
- return Object.keys(record4(config.mcpServers)).length > 0 || Object.keys(record4(config.servers)).length > 0 || Array.isArray(config.imports) && config.imports.length > 0;
2120
+ const config = record5(parsed);
2121
+ return Object.keys(record5(config.mcpServers)).length > 0 || Object.keys(record5(config.servers)).length > 0 || Array.isArray(config.imports) && config.imports.length > 0;
2112
2122
  }
2113
2123
  function assertNoProjectMcpOverride(cwd, runDir) {
2114
2124
  let cursor = resolve2(cwd);
@@ -2124,7 +2134,7 @@ function createManagedPiMcpProfileApi(options = {}) {
2124
2134
  }
2125
2135
  }
2126
2136
  function selectManagedBrowserUse(sourceSettings, npmSource) {
2127
- const plugin = record4(record4(sourceSettings.plugins)[MANAGED_BROWSER_USE_PLUGIN]);
2137
+ const plugin = record5(record5(sourceSettings.plugins)[MANAGED_BROWSER_USE_PLUGIN]);
2128
2138
  if (plugin.enabled !== true || plugin.package !== MANAGED_BROWSER_USE_PACKAGE) return null;
2129
2139
  const packageSpec = Array.isArray(sourceSettings.packages) ? sourceSettings.packages.find((entry) => npmPackageName(entry) === MANAGED_BROWSER_USE_PACKAGE) : null;
2130
2140
  if (typeof packageSpec !== "string") return null;
@@ -2141,7 +2151,7 @@ function createManagedPiMcpProfileApi(options = {}) {
2141
2151
  if (packageMetadata.name !== MANAGED_BROWSER_USE_PACKAGE) {
2142
2152
  throw new Error(`pi_managed_mcp_attestation_failed: enabled ${MANAGED_BROWSER_USE_PACKAGE} package identity mismatch`);
2143
2153
  }
2144
- const sourceConfig = record4(sourceSettings["pi-browser-use"]);
2154
+ const sourceConfig = record5(sourceSettings["pi-browser-use"]);
2145
2155
  const config = {};
2146
2156
  for (const key of MANAGED_BROWSER_USE_BOOLEAN_SETTINGS) {
2147
2157
  if (typeof sourceConfig[key] === "boolean") config[key] = sourceConfig[key];
@@ -2185,7 +2195,7 @@ function createManagedPiMcpProfileApi(options = {}) {
2185
2195
  }
2186
2196
  return {
2187
2197
  packageSpec,
2188
- config: record4(sourceSettings["pi-telemetry"])
2198
+ config: record5(sourceSettings["pi-telemetry"])
2189
2199
  };
2190
2200
  }
2191
2201
  function seedPiRuntime(sourceHome, agentDir) {
@@ -2206,7 +2216,7 @@ function createManagedPiMcpProfileApi(options = {}) {
2206
2216
  let sourceSettings = {};
2207
2217
  if (existsSync3(settingsSource)) {
2208
2218
  try {
2209
- sourceSettings = record4(JSON.parse(readFileSync3(settingsSource, "utf8")));
2219
+ sourceSettings = record5(JSON.parse(readFileSync3(settingsSource, "utf8")));
2210
2220
  } catch {
2211
2221
  throw new Error("pi_managed_mcp_attestation_failed: source Pi settings are invalid");
2212
2222
  }
@@ -2337,7 +2347,7 @@ ${result3.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
2337
2347
  const owner = Object.freeze({ commandId: input.commandId, runId });
2338
2348
  writePrivateFile2(markerPath, `${JSON.stringify({ version: 1, ...owner, profileRoot })}
2339
2349
  `);
2340
- const runtimeAuth = record4(input.runtimeAuth);
2350
+ const runtimeAuth = record5(input.runtimeAuth);
2341
2351
  const authority = Object.freeze({
2342
2352
  companyId: nonEmpty2(runtimeAuth.companyId, "runtimeAuth.companyId"),
2343
2353
  agentId: nonEmpty2(runtimeAuth.agentId, "runtimeAuth.agentId"),
@@ -2472,6 +2482,7 @@ ${result3.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
2472
2482
  function reconcileManagedPiMcpProfiles2(rootPath, options2 = {}) {
2473
2483
  const root = resolve2(rootPath);
2474
2484
  if (!existsSync3(root)) return { scanned: 0, removed: 0, removedProfiles: 0, removedRollouts: 0, failed: 0, failures: [] };
2485
+ const canonicalRoot = realpathSync2(root);
2475
2486
  const profileMarkers = [];
2476
2487
  const rolloutMarkers = [];
2477
2488
  const pending = [root];
@@ -2487,14 +2498,21 @@ ${result3.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
2487
2498
  }
2488
2499
  }
2489
2500
  let removedProfiles = 0;
2501
+ let preservedProfiles = 0;
2490
2502
  let removedRollouts = 0;
2491
2503
  const failures = [];
2504
+ const protectedCommandIds = new Set(Array.isArray(options2.protectedCommandIds) ? options2.protectedCommandIds.filter((value) => typeof value === "string" && value) : []);
2492
2505
  for (const markerPath of profileMarkers) {
2493
2506
  const profileRoot = dirname3(markerPath);
2494
2507
  try {
2495
2508
  const marker = JSON.parse(readFileSync3(markerPath, "utf8"));
2496
- if (!within4(profileRoot, root) || marker?.profileRoot !== profileRoot) throw new Error("ownership marker root mismatch");
2497
- cleanupManagedPiMcpProfile2({ profileRoot }, { commandId: marker.commandId, runId: marker.runId });
2509
+ const markerProfileRoot = typeof marker?.profileRoot === "string" ? resolve2(marker.profileRoot) : null;
2510
+ if (!markerProfileRoot || !existsSync3(markerProfileRoot) || !within4(realpathSync2(profileRoot), canonicalRoot) || realpathSync2(markerProfileRoot) !== realpathSync2(profileRoot)) throw new Error("ownership marker root mismatch");
2511
+ if (protectedCommandIds.has(marker?.commandId)) {
2512
+ preservedProfiles += 1;
2513
+ continue;
2514
+ }
2515
+ cleanupManagedPiMcpProfile2({ profileRoot: markerProfileRoot }, { commandId: marker.commandId, runId: marker.runId });
2498
2516
  removedProfiles += 1;
2499
2517
  } catch (error) {
2500
2518
  failures.push({ profileRoot, error: error instanceof Error ? error.message : String(error) });
@@ -2508,7 +2526,8 @@ ${result3.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
2508
2526
  const markerStat = lstatSync2(markerPath);
2509
2527
  const cacheStat = lstatSync2(cacheRoot);
2510
2528
  const marker = JSON.parse(readFileSync3(markerPath, "utf8"));
2511
- if (!within4(cacheRoot, root) || basename2(cacheRoot) !== "session-rollout" || markerStat.isSymbolicLink() || !markerStat.isFile() || cacheStat.isSymbolicLink() || !cacheStat.isDirectory() || marker?.version !== 1 || typeof marker?.companyId !== "string" || typeof marker?.agentId !== "string" || typeof marker?.sourceRunId !== "string" || typeof marker?.sourceCommandId !== "string" || typeof marker?.sessionId !== "string" || marker?.cacheRoot !== cacheRoot) throw new Error("session rollout ownership marker mismatch");
2529
+ const markerCacheRoot = typeof marker?.cacheRoot === "string" ? resolve2(marker.cacheRoot) : null;
2530
+ if (!within4(realpathSync2(cacheRoot), canonicalRoot) || basename2(cacheRoot) !== "session-rollout" || markerStat.isSymbolicLink() || !markerStat.isFile() || cacheStat.isSymbolicLink() || !cacheStat.isDirectory() || marker?.version !== 1 || typeof marker?.companyId !== "string" || typeof marker?.agentId !== "string" || typeof marker?.sourceRunId !== "string" || typeof marker?.sourceCommandId !== "string" || typeof marker?.sessionId !== "string" || !markerCacheRoot || !existsSync3(markerCacheRoot) || realpathSync2(markerCacheRoot) !== realpathSync2(cacheRoot)) throw new Error("session rollout ownership marker mismatch");
2512
2531
  const preservedAtMs = typeof marker.preservedAt === "string" ? Date.parse(marker.preservedAt) : Number.NaN;
2513
2532
  const markerAgeMs = nowMs - (Number.isFinite(preservedAtMs) ? preservedAtMs : markerStat.mtimeMs);
2514
2533
  if (markerAgeMs < rolloutTtlMs) continue;
@@ -2523,6 +2542,7 @@ ${result3.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
2523
2542
  scanned: profileMarkers.length + rolloutMarkers.length,
2524
2543
  removed: removedProfiles + removedRollouts,
2525
2544
  removedProfiles,
2545
+ preservedProfiles,
2526
2546
  removedRollouts,
2527
2547
  failed: failures.length,
2528
2548
  failures
@@ -2631,8 +2651,8 @@ function resultOutboxFileName(commandId, now = Date.now()) {
2631
2651
  return `${now}-${safeCommandId}.json`;
2632
2652
  }
2633
2653
  function isValidResultOutboxEntry(entry) {
2634
- const record4 = asRecord(entry);
2635
- return record4.version === 1 && Boolean(readString(record4.path)) && Object.keys(asRecord(record4.payload)).length > 0;
2654
+ const record5 = asRecord(entry);
2655
+ return record5.version === 1 && Boolean(readString(record5.path)) && Object.keys(asRecord(record5.payload)).length > 0;
2636
2656
  }
2637
2657
  function resultOutboxEntryAgeMs(entry, nowMs) {
2638
2658
  const createdAt = Date.parse(readString(entry.createdAt) ?? "");
@@ -2642,6 +2662,247 @@ function isTerminalResultOutboxStatus(status) {
2642
2662
  return typeof status === "number" && status >= 400 && status < 500;
2643
2663
  }
2644
2664
 
2665
+ // src/amaster-runtime-daemon/run-completion-state.mjs
2666
+ import { existsSync as existsSync4, mkdirSync as mkdirSync4, readFileSync as readFileSync4, readdirSync as readdirSync3, renameSync as renameSync2, unlinkSync, writeFileSync as writeFileSync4 } from "node:fs";
2667
+ import { join as join5 } from "node:path";
2668
+ var RUN_COMPLETION_STATE_VERSION = 1;
2669
+ var RUN_COMPLETION_USAGE_SCHEMA_VERSION = "runtime-command-usage-v1";
2670
+ var RUN_COMPLETION_PHASES = /* @__PURE__ */ new Set([
2671
+ "executing",
2672
+ "usage_snapshot_persisted",
2673
+ "completion_check_pending",
2674
+ "check_failed_retry",
2675
+ "completion_check_outbox",
2676
+ "disposition_required",
2677
+ "closure_executing",
2678
+ "ready_to_terminalize",
2679
+ "cost_ingest_pending",
2680
+ "profile_cleanup",
2681
+ "result_post_pending",
2682
+ "terminal"
2683
+ ]);
2684
+ var PHASE_TRANSITIONS = /* @__PURE__ */ new Map([
2685
+ ["executing:turn_recorded", "usage_snapshot_persisted"],
2686
+ ["closure_executing:turn_recorded", "usage_snapshot_persisted"],
2687
+ ["closure_executing:completion_ready", "ready_to_terminalize"],
2688
+ ["closure_executing:completion_disposition_required", "disposition_required"],
2689
+ ["closure_executing:completion_check_failed", "check_failed_retry"],
2690
+ ["closure_executing:completion_authority_rejected", "ready_to_terminalize"],
2691
+ ["usage_snapshot_persisted:completion_check_requested", "completion_check_pending"],
2692
+ ["completion_check_pending:completion_ready", "ready_to_terminalize"],
2693
+ ["completion_check_pending:completion_disposition_required", "disposition_required"],
2694
+ ["completion_check_pending:completion_check_failed", "check_failed_retry"],
2695
+ ["completion_check_pending:completion_authority_rejected", "ready_to_terminalize"],
2696
+ ["check_failed_retry:completion_retry_scheduled", "completion_check_pending"],
2697
+ ["check_failed_retry:completion_retry_exhausted", "completion_check_outbox"],
2698
+ ["check_failed_retry:completion_retry_abandoned", "ready_to_terminalize"],
2699
+ ["completion_check_outbox:completion_retry_scheduled", "completion_check_pending"],
2700
+ ["disposition_required:closure_started", "closure_executing"],
2701
+ ["disposition_required:closure_exhausted", "ready_to_terminalize"],
2702
+ ["ready_to_terminalize:cost_ingest_started", "cost_ingest_pending"],
2703
+ ["cost_ingest_pending:cost_ingest_delivered", "profile_cleanup"],
2704
+ ["cost_ingest_pending:cost_ingest_abandoned", "profile_cleanup"],
2705
+ ["profile_cleanup:profile_cleaned", "result_post_pending"],
2706
+ ["profile_cleanup:profile_cleanup_abandoned", "result_post_pending"],
2707
+ ["result_post_pending:result_post_delivered", "terminal"]
2708
+ ]);
2709
+ function record3(value) {
2710
+ return value && typeof value === "object" && !Array.isArray(value) ? value : {};
2711
+ }
2712
+ function nonEmptyString(value, label) {
2713
+ if (typeof value !== "string" || value.trim() === "") {
2714
+ throw new Error(`run_completion_state_invalid:${label}`);
2715
+ }
2716
+ return value.trim();
2717
+ }
2718
+ function nonNegativeInteger(value) {
2719
+ const numeric = Number(value ?? 0);
2720
+ return Number.isInteger(numeric) && numeric >= 0 ? numeric : 0;
2721
+ }
2722
+ function nonNegativeNumber(value) {
2723
+ const numeric = Number(value ?? 0);
2724
+ return Number.isFinite(numeric) && numeric >= 0 ? numeric : 0;
2725
+ }
2726
+ function runtimeCommandCostIdempotencyKey(commandId) {
2727
+ return `runtime-command-cost:${nonEmptyString(commandId, "commandId")}`;
2728
+ }
2729
+ function runCompletionStateFileName(commandId) {
2730
+ const safeCommandId = nonEmptyString(commandId, "commandId").replace(/[^a-zA-Z0-9._-]/g, "_");
2731
+ return `${safeCommandId}.json`;
2732
+ }
2733
+ function normalizeRunTurnUsage(turn) {
2734
+ const source = record3(turn);
2735
+ const nestedUsage = record3(source.usage);
2736
+ const usage = Object.keys(nestedUsage).length > 0 ? nestedUsage : source;
2737
+ return {
2738
+ turn: source.turn === "closure" ? "closure" : "primary",
2739
+ attempt: source.turn === "closure" ? 1 : 0,
2740
+ inputTokens: nonNegativeInteger(usage.inputTokens),
2741
+ cachedInputTokens: nonNegativeInteger(usage.cachedInputTokens),
2742
+ outputTokens: nonNegativeInteger(usage.outputTokens),
2743
+ costUsd: nonNegativeNumber(usage.costUsd),
2744
+ recordedAt: typeof source.recordedAt === "string" && source.recordedAt ? source.recordedAt : (/* @__PURE__ */ new Date()).toISOString()
2745
+ };
2746
+ }
2747
+ function aggregateRunTurnUsage(turns) {
2748
+ const normalized = Array.isArray(turns) ? turns.map(normalizeRunTurnUsage) : [];
2749
+ const aggregate = normalized.reduce((total, turn) => ({
2750
+ inputTokens: total.inputTokens + turn.inputTokens,
2751
+ cachedInputTokens: total.cachedInputTokens + turn.cachedInputTokens,
2752
+ outputTokens: total.outputTokens + turn.outputTokens,
2753
+ costUsd: total.costUsd + turn.costUsd
2754
+ }), {
2755
+ inputTokens: 0,
2756
+ cachedInputTokens: 0,
2757
+ outputTokens: 0,
2758
+ costUsd: 0
2759
+ });
2760
+ const costUsd = Number(aggregate.costUsd.toFixed(12));
2761
+ return {
2762
+ ...aggregate,
2763
+ costUsd,
2764
+ costCents: costUsd > 0 ? Math.max(0, Math.round(costUsd * 100)) : 0
2765
+ };
2766
+ }
2767
+ function createRunCompletionState(input) {
2768
+ const command = record3(input.command);
2769
+ const commandId = nonEmptyString(command.commandId ?? command.id, "command.commandId");
2770
+ const connectorId = nonEmptyString(input.connectorId ?? command.connectorId, "connectorId");
2771
+ const now = typeof input.now === "string" && input.now ? input.now : (/* @__PURE__ */ new Date()).toISOString();
2772
+ const firstTurn = normalizeRunTurnUsage({ ...record3(input.turn), turn: "primary", recordedAt: now });
2773
+ return {
2774
+ version: RUN_COMPLETION_STATE_VERSION,
2775
+ commandId,
2776
+ connectorId,
2777
+ phase: "usage_snapshot_persisted",
2778
+ closureAttempt: 0,
2779
+ command,
2780
+ executor: record3(input.executor),
2781
+ completionRequest: record3(input.completionRequest),
2782
+ candidateStatus: nonEmptyString(input.candidateStatus, "candidateStatus"),
2783
+ candidateResult: record3(input.candidateResult),
2784
+ ...typeof input.candidateError === "string" && input.candidateError ? { candidateError: input.candidateError } : {},
2785
+ usageRecord: {
2786
+ schemaVersion: RUN_COMPLETION_USAGE_SCHEMA_VERSION,
2787
+ idempotencyKey: runtimeCommandCostIdempotencyKey(commandId),
2788
+ commandId,
2789
+ turns: [firstTurn],
2790
+ aggregate: aggregateRunTurnUsage([firstTurn]),
2791
+ ingestStatus: "pending"
2792
+ },
2793
+ createdAt: now,
2794
+ updatedAt: now
2795
+ };
2796
+ }
2797
+ function appendRunCompletionUsageTurn(state, input) {
2798
+ const current = assertValidRunCompletionState(state);
2799
+ const turn = normalizeRunTurnUsage(input);
2800
+ const priorTurns = current.usageRecord.turns.filter((entry) => entry.turn !== turn.turn);
2801
+ const turns = [...priorTurns, turn].sort((left, right) => left.attempt - right.attempt);
2802
+ return {
2803
+ ...current,
2804
+ closureAttempt: turn.turn === "closure" ? 1 : current.closureAttempt,
2805
+ phase: "usage_snapshot_persisted",
2806
+ usageRecord: {
2807
+ ...current.usageRecord,
2808
+ turns,
2809
+ aggregate: aggregateRunTurnUsage(turns),
2810
+ ingestStatus: "pending"
2811
+ },
2812
+ updatedAt: turn.recordedAt
2813
+ };
2814
+ }
2815
+ function transitionRunCompletionState(state, event, patch = {}, now = (/* @__PURE__ */ new Date()).toISOString()) {
2816
+ const current = assertValidRunCompletionState(state);
2817
+ const nextPhase = PHASE_TRANSITIONS.get(`${current.phase}:${event}`);
2818
+ if (!nextPhase) {
2819
+ throw new Error(`run_completion_state_transition_invalid:${current.phase}:${event}`);
2820
+ }
2821
+ return assertValidRunCompletionState({
2822
+ ...current,
2823
+ ...record3(patch),
2824
+ phase: nextPhase,
2825
+ updatedAt: now
2826
+ });
2827
+ }
2828
+ function markRunCompletionCostDelivered(state, receipt, now = (/* @__PURE__ */ new Date()).toISOString()) {
2829
+ const current = assertValidRunCompletionState(state);
2830
+ return transitionRunCompletionState({
2831
+ ...current,
2832
+ usageRecord: {
2833
+ ...current.usageRecord,
2834
+ ingestStatus: "delivered",
2835
+ deliveredAt: now,
2836
+ receipt: record3(receipt)
2837
+ }
2838
+ }, "cost_ingest_delivered", {}, now);
2839
+ }
2840
+ function assertValidRunCompletionState(value) {
2841
+ const state = record3(value);
2842
+ if (state.version !== RUN_COMPLETION_STATE_VERSION) throw new Error("run_completion_state_invalid:version");
2843
+ const commandId = nonEmptyString(state.commandId, "commandId");
2844
+ const connectorId = nonEmptyString(state.connectorId, "connectorId");
2845
+ if (!RUN_COMPLETION_PHASES.has(state.phase)) throw new Error("run_completion_state_invalid:phase");
2846
+ const command = record3(state.command);
2847
+ if (nonEmptyString(command.commandId ?? command.id, "command.commandId") !== commandId) {
2848
+ throw new Error("run_completion_state_invalid:command_binding");
2849
+ }
2850
+ if (nonEmptyString(command.connectorId, "command.connectorId") !== connectorId) {
2851
+ throw new Error("run_completion_state_invalid:connector_binding");
2852
+ }
2853
+ const usageRecord = record3(state.usageRecord);
2854
+ if (usageRecord.schemaVersion !== RUN_COMPLETION_USAGE_SCHEMA_VERSION) {
2855
+ throw new Error("run_completion_state_invalid:usage_schema");
2856
+ }
2857
+ if (usageRecord.commandId !== commandId) throw new Error("run_completion_state_invalid:usage_command_binding");
2858
+ if (usageRecord.idempotencyKey !== runtimeCommandCostIdempotencyKey(commandId)) {
2859
+ throw new Error("run_completion_state_invalid:usage_idempotency_key");
2860
+ }
2861
+ const turns = Array.isArray(usageRecord.turns) ? usageRecord.turns.map(normalizeRunTurnUsage) : [];
2862
+ if (turns.length < 1 || turns.length > 2) throw new Error("run_completion_state_invalid:usage_turns");
2863
+ const kinds = new Set(turns.map((turn) => turn.turn));
2864
+ if (kinds.size !== turns.length || !kinds.has("primary")) {
2865
+ throw new Error("run_completion_state_invalid:usage_turn_identity");
2866
+ }
2867
+ const aggregate = aggregateRunTurnUsage(turns);
2868
+ return {
2869
+ ...state,
2870
+ commandId,
2871
+ connectorId,
2872
+ command,
2873
+ executor: record3(state.executor),
2874
+ completionRequest: record3(state.completionRequest),
2875
+ candidateResult: record3(state.candidateResult),
2876
+ usageRecord: {
2877
+ ...usageRecord,
2878
+ turns,
2879
+ aggregate,
2880
+ ingestStatus: ["delivered", "failed"].includes(usageRecord.ingestStatus) ? usageRecord.ingestStatus : "pending"
2881
+ }
2882
+ };
2883
+ }
2884
+ function writeRunCompletionState(directory, state) {
2885
+ const valid = assertValidRunCompletionState(state);
2886
+ mkdirSync4(directory, { recursive: true, mode: 448 });
2887
+ const filePath = join5(directory, runCompletionStateFileName(valid.commandId));
2888
+ const temporaryPath = `${filePath}.${process.pid}.${Date.now()}.tmp`;
2889
+ writeFileSync4(temporaryPath, `${JSON.stringify(valid, null, 2)}
2890
+ `, { mode: 384 });
2891
+ renameSync2(temporaryPath, filePath);
2892
+ return filePath;
2893
+ }
2894
+ function readRunCompletionState(filePath) {
2895
+ return assertValidRunCompletionState(JSON.parse(readFileSync4(filePath, "utf8")));
2896
+ }
2897
+ function listRunCompletionStateFiles(directory) {
2898
+ if (!existsSync4(directory)) return [];
2899
+ return readdirSync3(directory).filter((name) => name.endsWith(".json")).sort().map((name) => join5(directory, name));
2900
+ }
2901
+ function removeRunCompletionState(directory, commandId) {
2902
+ const filePath = join5(directory, runCompletionStateFileName(commandId));
2903
+ if (existsSync4(filePath)) unlinkSync(filePath);
2904
+ }
2905
+
2645
2906
  // src/amaster-runtime-daemon/prompt-compiler.mjs
2646
2907
  var DEFAULT_PROMPT_BUDGET_CHARS = 32e3;
2647
2908
  var DEADLINE_POSTURE_GUARD = "Named-window:skip_this_window_and_continue; no lower-quality/approval-bypass/fabrication/whole-task-stop; deadline_posture_receipt=targetMilestoneRef,posture,onMiss,taskContinuation,next owner/action; not Server proof";
@@ -2720,8 +2981,8 @@ function governedReadSection(context) {
2720
2981
  const reads = Array.isArray(context.governedReadResults) ? context.governedReadResults : [];
2721
2982
  if (reads.length === 0) return { content: "", provenance: [] };
2722
2983
  const normalized = reads.map((entry, index) => {
2723
- const record4 = asRecord(entry);
2724
- const receipt = asRecord(record4.receipt);
2984
+ const record5 = asRecord(entry);
2985
+ const receipt = asRecord(record5.receipt);
2725
2986
  const provider = readString(receipt.provider) ?? readString(receipt.transport);
2726
2987
  const operation = readString(receipt.operation);
2727
2988
  const observedAt = readString(receipt.retrievedAt) ?? readString(receipt.observedAt);
@@ -2731,7 +2992,7 @@ function governedReadSection(context) {
2731
2992
  throw new Error(`governed_read_context_provenance_invalid: entry ${index} requires provider, operation, observedAt, and source`);
2732
2993
  }
2733
2994
  return {
2734
- content: record4.content,
2995
+ content: record5.content,
2735
2996
  receipt: {
2736
2997
  provider,
2737
2998
  operation,
@@ -2754,6 +3015,146 @@ function governedReadSection(context) {
2754
3015
  }))
2755
3016
  };
2756
3017
  }
3018
+ function canonicalJsonValue(value) {
3019
+ if (Array.isArray(value)) return value.map(canonicalJsonValue);
3020
+ const record5 = asRecord(value);
3021
+ if (Object.keys(record5).length === 0) return value;
3022
+ return Object.fromEntries(
3023
+ Object.keys(record5).sort().map((key) => [key, canonicalJsonValue(record5[key])])
3024
+ );
3025
+ }
3026
+ function resolvedDependencySections(context, input, contextScope, snapshotFreshness) {
3027
+ const wake = asRecord(context.paperclipWake);
3028
+ const hasContextCopy = Object.prototype.hasOwnProperty.call(context, "resolvedBlockerSummaries");
3029
+ const hasWakeCopy = Object.prototype.hasOwnProperty.call(wake, "resolvedBlockerSummaries");
3030
+ if (hasContextCopy && !Array.isArray(context.resolvedBlockerSummaries)) {
3031
+ throw new Error("Resolved dependency context invalid: resolvedBlockerSummaries must be an array");
3032
+ }
3033
+ if (hasWakeCopy && !Array.isArray(wake.resolvedBlockerSummaries)) {
3034
+ throw new Error("Resolved dependency wake context invalid: resolvedBlockerSummaries must be an array");
3035
+ }
3036
+ const contextCopy = hasContextCopy ? context.resolvedBlockerSummaries : null;
3037
+ const wakeCopy = hasWakeCopy ? wake.resolvedBlockerSummaries : null;
3038
+ if (contextCopy && wakeCopy && JSON.stringify(canonicalJsonValue(contextCopy)) !== JSON.stringify(canonicalJsonValue(wakeCopy))) {
3039
+ throw new Error("Resolved dependency snapshots diverge between contextSnapshot and paperclipWake");
3040
+ }
3041
+ const summaries = contextCopy ?? wakeCopy ?? [];
3042
+ const tuples = [];
3043
+ const seenTuples = /* @__PURE__ */ new Set();
3044
+ const detailLines = [];
3045
+ const detailSourceRefs = [];
3046
+ const detailObservedAt = [];
3047
+ for (let blockerIndex = 0; blockerIndex < summaries.length; blockerIndex += 1) {
3048
+ const blocker = asRecord(summaries[blockerIndex]);
3049
+ const blockerId = readString(blocker.id);
3050
+ const blockerIdentifier = readString(blocker.identifier);
3051
+ const blockerSelector = blockerIdentifier ?? blockerId;
3052
+ const documents = Array.isArray(blocker.documents) ? blocker.documents : [];
3053
+ const blockerObservedAt = readString(blocker.completedAt) ?? readString(blocker.updatedAt);
3054
+ if (!blockerSelector && documents.length > 0) {
3055
+ throw new Error(
3056
+ `Resolved dependency context invalid: blocker ${blockerIndex} requires an issue id or identifier`
3057
+ );
3058
+ }
3059
+ if (blockerSelector) {
3060
+ detailLines.push(
3061
+ `- ${blockerSelector}${readString(blocker.title) ? ` ${readString(blocker.title)}` : ""}${readString(blocker.status) ? ` (${readString(blocker.status)})` : ""}`
3062
+ );
3063
+ const summary = readString(blocker.summary);
3064
+ if (summary) detailLines.push(` Summary: ${summary}`);
3065
+ detailSourceRefs.push(`issue:${blockerId ?? blockerSelector}`);
3066
+ detailObservedAt.push(blockerObservedAt);
3067
+ }
3068
+ for (let documentIndex = 0; documentIndex < documents.length; documentIndex += 1) {
3069
+ const document = asRecord(documents[documentIndex]);
3070
+ const documentId = readString(document.documentId);
3071
+ const key = readString(document.key);
3072
+ const expectedLatestRevisionId = readString(document.latestRevisionId);
3073
+ if (!blockerSelector || !documentId || !key || !expectedLatestRevisionId) {
3074
+ throw new Error(
3075
+ `Resolved dependency context invalid: blocker ${blockerIndex} document ${documentIndex} requires blocker issue selector, documentId, key, and latestRevisionId`
3076
+ );
3077
+ }
3078
+ const latestRevisionNumber = document.latestRevisionNumber;
3079
+ if (latestRevisionNumber != null && (!Number.isInteger(latestRevisionNumber) || latestRevisionNumber < 1)) {
3080
+ throw new Error(
3081
+ `Resolved dependency context invalid: blocker ${blockerIndex} document ${documentIndex} latestRevisionNumber must be a positive integer`
3082
+ );
3083
+ }
3084
+ const tupleKey = JSON.stringify([
3085
+ blockerId,
3086
+ blockerSelector,
3087
+ documentId,
3088
+ key,
3089
+ expectedLatestRevisionId
3090
+ ]);
3091
+ if (seenTuples.has(tupleKey)) continue;
3092
+ seenTuples.add(tupleKey);
3093
+ tuples.push({
3094
+ blockerId,
3095
+ blockerSelector,
3096
+ documentId,
3097
+ key,
3098
+ expectedLatestRevisionId,
3099
+ expectedLatestRevisionNumber: latestRevisionNumber ?? null,
3100
+ observedAt: readString(document.updatedAt) ?? blockerObservedAt
3101
+ });
3102
+ const documentTitle = readString(document.title);
3103
+ detailLines.push(
3104
+ ` Document: ${key}${documentTitle ? ` (${documentTitle})` : ""}${latestRevisionNumber != null ? ` revision ${latestRevisionNumber}` : ""}`
3105
+ );
3106
+ }
3107
+ const workProducts = Array.isArray(blocker.workProducts) ? blocker.workProducts : [];
3108
+ for (const rawWorkProduct of workProducts) {
3109
+ const workProduct = asRecord(rawWorkProduct);
3110
+ const workProductId = readString(workProduct.id);
3111
+ const workProductTitle = readString(workProduct.title);
3112
+ if (!workProductId && !workProductTitle) continue;
3113
+ detailLines.push(
3114
+ ` Work product: ${workProductId ?? workProductTitle}${workProductTitle && workProductId ? ` (${workProductTitle})` : ""}`
3115
+ );
3116
+ const workProductSummary = readString(workProduct.summary);
3117
+ if (workProductSummary) detailLines.push(` ${workProductSummary}`);
3118
+ }
3119
+ }
3120
+ const requiredLines = tuples.length > 0 ? [
3121
+ "Accepted predecessor outputs are binding inputs unless this issue explicitly requests reconsideration.",
3122
+ "Before any downstream document/artifact write, review request, status mutation, or completion, perform every Required read.",
3123
+ "Current-issue documents, parent-issue documents, summaries, and workspace files are not substitutes for these predecessor documents.",
3124
+ "Compare each returned latestRevisionId with the expected value. On revision mismatch, do not perform downstream writes; report it.",
3125
+ ...tuples.flatMap((tuple, index) => {
3126
+ const readArguments = { issueId: tuple.blockerSelector, key: tuple.key };
3127
+ const call = input.executorKind === "pi" && input.managedMcpToolMode === "proxy_only" ? {
3128
+ server: "amaster",
3129
+ tool: "amaster.read_issue_document",
3130
+ args: JSON.stringify(readArguments)
3131
+ } : readArguments;
3132
+ return [
3133
+ `- Required read ${index + 1}: issue ${JSON.stringify(tuple.blockerSelector)}${tuple.blockerId ? ` (id ${JSON.stringify(tuple.blockerId)})` : ""}; document ${JSON.stringify(tuple.documentId)}; key ${JSON.stringify(tuple.key)}; expected latestRevisionId ${JSON.stringify(tuple.expectedLatestRevisionId)}${tuple.expectedLatestRevisionNumber != null ? `; revisionNumber ${tuple.expectedLatestRevisionNumber}` : ""}.`,
3134
+ input.executorKind === "pi" && input.managedMcpToolMode === "proxy_only" ? ` Exact Pi \`mcp\` arguments: ${JSON.stringify(call)}` : ` Call amaster.read_issue_document with these exact arguments: ${JSON.stringify(call)}`
3135
+ ];
3136
+ })
3137
+ ].join("\n") : "";
3138
+ return {
3139
+ required: {
3140
+ content: requiredLines,
3141
+ sourceRef: tuples.map(
3142
+ (tuple) => `issue:${tuple.blockerId ?? tuple.blockerSelector}/document:${tuple.documentId}@${tuple.expectedLatestRevisionId}`
3143
+ ),
3144
+ observedAt: tuples.map((tuple) => tuple.observedAt),
3145
+ freshness: tuples.map(() => snapshotFreshness),
3146
+ scope: tuples.map(() => contextScope),
3147
+ tupleCount: tuples.length
3148
+ },
3149
+ details: {
3150
+ content: detailLines.join("\n"),
3151
+ sourceRef: detailSourceRefs,
3152
+ observedAt: detailObservedAt,
3153
+ freshness: detailSourceRefs.map(() => snapshotFreshness),
3154
+ scope: detailSourceRefs.map(() => contextScope)
3155
+ }
3156
+ };
3157
+ }
2757
3158
  function fixedRules(input, includeIssueLine) {
2758
3159
  return [
2759
3160
  "## AMaster Runtime Connector Task",
@@ -2790,9 +3191,15 @@ function interactionResolutionText(context) {
2790
3191
  const wakeResolution = asRecord(asRecord(context.paperclipWake).interactionResolution);
2791
3192
  const resolution = Object.keys(direct).length > 0 ? direct : wakeResolution;
2792
3193
  if (Object.keys(resolution).length === 0) return "";
3194
+ const target = asRecord(resolution.target);
3195
+ const exactDocumentRevisionDirective = readString(resolution.status) === "changes_requested" && readString(target.type) === "issue_document" && readString(target.issueId) && readString(target.documentId) && readString(target.key) && readString(target.revisionId) ? [
3196
+ "The review target is an exact issue_document revision. Revise that same document with upsert_document_revision: copy target.issueId, target.documentId, and target.key, and use target.revisionId as baseRevisionId.",
3197
+ "Do not copy the reviewed document into the current issue and do not restart its revision lineage at 1."
3198
+ ].join(" ") : "";
2793
3199
  return [
2794
3200
  "Treat this resolved interaction as the authoritative delta for this run.",
2795
3201
  readString(resolution.status) === "changes_requested" ? "Apply every requested change before creating a replacement review." : "",
3202
+ exactDocumentRevisionDirective,
2796
3203
  stringifyBoundedJson(resolution, 8e3)
2797
3204
  ].filter(Boolean).join("\n");
2798
3205
  }
@@ -2928,12 +3335,36 @@ function runtimeDecompositionRequirementText(context) {
2928
3335
  `Requirement source: ${sourceType}:${sourceId}@${sourceRevision}`
2929
3336
  ].join("\n");
2930
3337
  }
3338
+ function piMcpProxyExamplesText(input) {
3339
+ if (!input.hasGovernedMcp || input.executorKind !== "pi" || input.managedMcpToolMode !== "proxy_only" || isRecoveryWakeReason(input.wakeReason)) return "";
3340
+ const proxy = (tool, args) => JSON.stringify({
3341
+ server: "amaster",
3342
+ tool,
3343
+ args: JSON.stringify(args)
3344
+ });
3345
+ return [
3346
+ "The Pi native tool is the outer `mcp` proxy. Emit these as actual tool calls; `args` is the stringified inner canonical object:",
3347
+ "Keep review payload strings short. Reference the exact document key and revision in `target`; do not duplicate the reviewed document body in `prompt` or `detailsMarkdown`.",
3348
+ `- describe: ${proxy("runtime_action.describe", { schemaVersion: "runtime-action-v1", actionType: "update_parent" })}`,
3349
+ `- submit: ${proxy("runtime_action.submit", { schemaVersion: "runtime-action-v1", idempotencyKey: "task-123-progress", action: { type: "update_parent", status: "in_progress", comment: "Continue the remaining work." } })}`,
3350
+ `- submit review interaction: ${proxy("runtime_action.submit", { schemaVersion: "runtime-action-v1", idempotencyKey: "task-123-review", action: { type: "create_interaction", kind: "request_confirmation", continuationPolicy: "wake_assignee_on_accept", payload: { version: 1, resolutionMode: "review", prompt: "Review `plan` revision 1.", target: { type: "issue_document", issueId: "11111111-1111-4111-8111-111111111111", documentId: "33333333-3333-4333-8333-333333333333", key: "plan", revisionId: "22222222-2222-4222-8222-222222222222", revisionNumber: 1 } } } })}`,
3351
+ `- plan: ${proxy("runtime_action.plan", { schemaVersion: "runtime-action-v1", idempotencyKey: "task-123-plan", actions: [{ type: "update_parent", status: "in_progress", comment: "Continue the remaining work." }] })}`,
3352
+ `- commit the returned plan revision: ${proxy("runtime_action.commit", { schemaVersion: "runtime-action-v1", planId: "11111111-1111-4111-8111-111111111111", revision: "plan-revision-1" })}`,
3353
+ `- read document: ${proxy("amaster.read_issue_document", { issueId: "AM-123", key: "plan" })}`
3354
+ ].join("\n");
3355
+ }
2931
3356
  function sectionText(section) {
2932
3357
  if (!section.content) return "";
2933
3358
  return section.title ? `## ${section.title}
2934
3359
  ${section.content}` : section.content;
2935
3360
  }
2936
3361
  function truncateSection(section, targetChars) {
3362
+ const mandatoryContent = section.mandatoryContent ?? "";
3363
+ if (targetChars <= mandatoryContent.length) {
3364
+ section.content = mandatoryContent;
3365
+ section.truncationReason = "unified_context_budget";
3366
+ return;
3367
+ }
2937
3368
  if (targetChars <= 0) {
2938
3369
  section.content = "";
2939
3370
  section.truncationReason = "unified_context_budget";
@@ -3015,12 +3446,33 @@ function compileCommandPromptWithManifest(input, options = {}) {
3015
3446
  issueId: input.issueId ?? null
3016
3447
  };
3017
3448
  const snapshotFreshness = { kind: "run_snapshot" };
3449
+ const resolvedDependencies = resolvedDependencySections(
3450
+ context,
3451
+ input,
3452
+ contextScope,
3453
+ snapshotFreshness
3454
+ );
3455
+ const resolvedDependencyContent = resolvedDependencies.required.content ? [
3456
+ resolvedDependencies.required.content,
3457
+ resolvedDependencies.details.content ? `Auxiliary predecessor context (may be truncated):
3458
+ ${resolvedDependencies.details.content}` : ""
3459
+ ].filter(Boolean).join("\n\n") : "";
3460
+ const piMcpProxyExamples = resolvedDependencies.required.content ? "" : piMcpProxyExamplesText(input);
3018
3461
  const rawSections = [
3019
3462
  { name: "runtime_rules", title: "", priority: 100, sourceRef: `command:${input.commandId}`, content: fixedRules(input, !hasTask) },
3463
+ ...resolvedDependencyContent ? [{
3464
+ name: "resolved_dependencies",
3465
+ title: "Resolved Dependency Outputs",
3466
+ priority: 99,
3467
+ ...resolvedDependencies.required,
3468
+ content: resolvedDependencyContent,
3469
+ mandatoryContent: resolvedDependencies.required.content
3470
+ }] : [],
3020
3471
  { name: "recovery_instruction", title: "Recovery Instruction", priority: 100, sourceRef: `run:${input.runId ?? "unknown"}`, content: completeRecoveryInstruction, truncationReason: completeRecoveryInstruction ? null : "mode_selection" },
3021
3472
  { name: "approval_continuation", title: "Approved Runtime Action Continuation", priority: 99, sourceRef: `run:${input.runId ?? "unknown"}`, content: approvalContinuationText(input), truncationReason: mode === "continuation" ? null : "mode_selection" },
3022
3473
  { name: "runtime_authorization", title: "Runtime Action Contract", priority: 98, sourceRef: `run:${input.runId ?? "unknown"}`, content: runtimeAuthorizationText(context, mode, { suppressOrdinaryCompletionContract }) },
3023
3474
  { name: "runtime_decomposition_requirement", title: "Required Task Decomposition", priority: 98, sourceRef: `issue:${input.issueId ?? "unknown"}`, content: runtimeDecompositionRequirementText(context) },
3475
+ ...piMcpProxyExamples ? [{ name: "pi_mcp_proxy_examples", title: "Pi MCP Proxy Examples", priority: 96, sourceRef: "amaster_governed_mcp_proxy_contract", content: piMcpProxyExamples }] : [],
3024
3476
  { name: "continuation_summary", title: "Continuation Summary", priority: 97, sourceRef: readString(asRecord(context.paperclipContinuationSummary).key) ?? `issue:${input.issueId ?? "unknown"}`, observedAt: readString(asRecord(context.paperclipContinuationSummary).updatedAt), originalContent: continuationSummary, content: mode === "cold" ? "" : continuationSummary, truncationReason: mode === "cold" ? "mode_selection" : null },
3025
3477
  { name: "wake_comments", title: wakeDeltaTitle, priority: interactionResolution ? 99 : 95, sourceRef: wakeDeltaSourceRefs, originalContent: wakeDeltaOriginal, content: wakeDeltaContent, truncationReason: commentsSelected ? null : "duplicate_task_context" },
3026
3478
  { name: "task", title: "Task Context", priority: 90, sourceRef: `issue:${input.issueId ?? "unknown"}`, originalContent: taskText, content: includeTask ? taskText : "", truncationReason: includeTask ? null : "mode_selection" },
@@ -3061,7 +3513,9 @@ function compileCommandPromptWithManifest(input, options = {}) {
3061
3513
  }
3062
3514
  if (prompt.length <= maxChars && manifest.budget.usedChars === prompt.length) break;
3063
3515
  const overflow = Math.max(1, prompt.length - maxChars);
3064
- const candidate = [...sections].filter((section) => section.priority < 100 && section.content.length > 0).sort((left, right) => left.priority - right.priority)[0];
3516
+ const candidate = [...sections].filter(
3517
+ (section) => section.priority < 100 && section.content.length > (section.mandatoryContent?.length ?? 0)
3518
+ ).sort((left, right) => left.priority - right.priority)[0];
3065
3519
  if (!candidate) {
3066
3520
  if (!compactManifest) {
3067
3521
  compactManifest = true;
@@ -3070,6 +3524,11 @@ function compileCommandPromptWithManifest(input, options = {}) {
3070
3524
  }
3071
3525
  const fixedChars = sections.filter((section) => section.priority === 100).map(sectionText).join("\n").length;
3072
3526
  const manifestChars = JSON.stringify(manifest).length;
3527
+ if (resolvedDependencies.required.tupleCount > 0) {
3528
+ throw new Error(
3529
+ `Resolved dependency mandatory read tuples exceed the unified ${maxChars}-character prompt budget: tupleCount=${resolvedDependencies.required.tupleCount} promptChars=${prompt.length} fixedChars=${fixedChars} manifestChars=${manifestChars}`
3530
+ );
3531
+ }
3073
3532
  throw new Error(`Prompt fixed sections exceed the unified ${maxChars}-character budget: promptChars=${prompt.length} fixedChars=${fixedChars} manifestChars=${manifestChars}`);
3074
3533
  }
3075
3534
  truncateSection(candidate, Math.max(0, candidate.content.length - overflow - 32));
@@ -3082,9 +3541,9 @@ function compileCommandPromptWithManifest(input, options = {}) {
3082
3541
  }
3083
3542
 
3084
3543
  // src/amaster-runtime-daemon/config-state.mjs
3085
- import { existsSync as existsSync4, mkdirSync as mkdirSync4, readFileSync as readFileSync4, renameSync as renameSync2, rmSync as rmSync3, writeFileSync as writeFileSync4 } from "node:fs";
3544
+ import { existsSync as existsSync5, mkdirSync as mkdirSync5, readFileSync as readFileSync5, renameSync as renameSync3, rmSync as rmSync3, writeFileSync as writeFileSync5 } from "node:fs";
3086
3545
  import { homedir as homedir2, hostname } from "node:os";
3087
- import { dirname as dirname4, join as join5 } from "node:path";
3546
+ import { dirname as dirname4, join as join6 } from "node:path";
3088
3547
 
3089
3548
  // src/amaster-runtime-daemon/executor-discovery.mjs
3090
3549
  import { spawnSync as spawnSync3 } from "node:child_process";
@@ -3200,26 +3659,26 @@ function defaultMachineId() {
3200
3659
  }
3201
3660
  function runtimeHome(env) {
3202
3661
  return expandHomePath(String(
3203
- env.AMASTER_RUNTIME_STATE_HOME || env.AMASTER_RUNTIME_HOME || join5(homedir2(), ".amaster-employee")
3662
+ env.AMASTER_RUNTIME_STATE_HOME || env.AMASTER_RUNTIME_HOME || join6(homedir2(), ".amaster-employee")
3204
3663
  ));
3205
3664
  }
3206
3665
  function stateFilePath(env) {
3207
- return env.AMASTER_DAEMON_STATE_FILE ? expandHomePath(String(env.AMASTER_DAEMON_STATE_FILE)) : join5(runtimeHome(env), "runtime-connector-state.json");
3666
+ return env.AMASTER_DAEMON_STATE_FILE ? expandHomePath(String(env.AMASTER_DAEMON_STATE_FILE)) : join6(runtimeHome(env), "runtime-connector-state.json");
3208
3667
  }
3209
3668
  function corruptStatePath(path) {
3210
3669
  const timestamp2 = (/* @__PURE__ */ new Date()).toISOString().replace(/\D/g, "").slice(0, 14);
3211
3670
  const base = `${path}.corrupt-${timestamp2}Z`;
3212
3671
  let candidate = base;
3213
- for (let suffix = 1; existsSync4(candidate); suffix += 1) {
3672
+ for (let suffix = 1; existsSync5(candidate); suffix += 1) {
3214
3673
  candidate = `${base}.${suffix}`;
3215
3674
  }
3216
3675
  return candidate;
3217
3676
  }
3218
3677
  function readState(env) {
3219
3678
  const path = stateFilePath(env);
3220
- if (!existsSync4(path)) return {};
3679
+ if (!existsSync5(path)) return {};
3221
3680
  try {
3222
- const state = JSON.parse(readFileSync4(path, "utf8"));
3681
+ const state = JSON.parse(readFileSync5(path, "utf8"));
3223
3682
  if (!state || typeof state !== "object" || Array.isArray(state)) {
3224
3683
  throw new TypeError("runtime connector state must be a JSON object");
3225
3684
  }
@@ -3227,7 +3686,7 @@ function readState(env) {
3227
3686
  } catch {
3228
3687
  const quarantinePath = corruptStatePath(path);
3229
3688
  try {
3230
- renameSync2(path, quarantinePath);
3689
+ renameSync3(path, quarantinePath);
3231
3690
  process.stderr.write(`AMaster runtime state was invalid and quarantined at ${quarantinePath}
3232
3691
  `);
3233
3692
  } catch (error) {
@@ -3241,15 +3700,15 @@ function readState(env) {
3241
3700
  }
3242
3701
  function writeState(env, state) {
3243
3702
  const path = stateFilePath(env);
3244
- mkdirSync4(dirname4(path), { recursive: true });
3703
+ mkdirSync5(dirname4(path), { recursive: true });
3245
3704
  const temporaryPath = `${path}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
3246
3705
  try {
3247
- writeFileSync4(temporaryPath, `${JSON.stringify(state, null, 2)}
3706
+ writeFileSync5(temporaryPath, `${JSON.stringify(state, null, 2)}
3248
3707
  `, {
3249
3708
  flag: "wx",
3250
3709
  mode: 384
3251
3710
  });
3252
- renameSync2(temporaryPath, path);
3711
+ renameSync3(temporaryPath, path);
3253
3712
  } finally {
3254
3713
  rmSync3(temporaryPath, { force: true });
3255
3714
  }
@@ -3263,15 +3722,15 @@ function buildConfig(env = process.env, flags = {}) {
3263
3722
  const authHeader = String(flags.authHeader ?? env.AMASTER_CONNECTOR_AUTH_HEADER ?? "");
3264
3723
  const home = runtimeHome(env);
3265
3724
  const runtimeWorkspacesRoot = expandHomePath(
3266
- String(flags.runtimeWorkspacesRoot ?? env.AMASTER_RUNTIME_WORKSPACES_ROOT ?? join5(home, "workspaces"))
3725
+ String(flags.runtimeWorkspacesRoot ?? env.AMASTER_RUNTIME_WORKSPACES_ROOT ?? join6(home, "workspaces"))
3267
3726
  );
3268
3727
  const browserSessionStateRoot = expandHomePath(String(
3269
- flags.browserSessionStateRoot ?? env.AMASTER_BROWSER_SESSION_STATE_ROOT ?? join5(home, "browser-auth")
3728
+ flags.browserSessionStateRoot ?? env.AMASTER_BROWSER_SESSION_STATE_ROOT ?? join6(home, "browser-auth")
3270
3729
  ));
3271
3730
  const browserExecutablePath = String(
3272
3731
  flags.browserExecutablePath ?? env.AMASTER_BROWSER_EXECUTABLE_PATH ?? ""
3273
3732
  ).trim();
3274
- mkdirSync4(runtimeWorkspacesRoot, { recursive: true });
3733
+ mkdirSync5(runtimeWorkspacesRoot, { recursive: true });
3275
3734
  const workspaceBindings = splitList(
3276
3735
  flags.workspaceAllowlist ?? env.AMASTER_WORKSPACE_ALLOWLIST ?? env.AMASTER_WORKSPACE_BINDINGS ?? runtimeWorkspacesRoot
3277
3736
  ).map(expandHomePath);
@@ -3418,10 +3877,10 @@ function compactExecutorJsonlForTranscript(event) {
3418
3877
  const text = JSON.stringify(compactExecutorJsonValue(event, stringMaxChars));
3419
3878
  if (text.length <= 15e3) return text;
3420
3879
  }
3421
- const record4 = tcAsRecord(event);
3422
- const item = tcAsRecord(record4.item);
3880
+ const record5 = tcAsRecord(event);
3881
+ const item = tcAsRecord(record5.item);
3423
3882
  return JSON.stringify({
3424
- type: tcReadString(record4.type) ?? "executor.event",
3883
+ type: tcReadString(record5.type) ?? "executor.event",
3425
3884
  item: item.type ? {
3426
3885
  id: tcReadString(item.id),
3427
3886
  type: tcReadString(item.type),
@@ -3434,10 +3893,10 @@ function compactExecutorJsonlForTranscript(event) {
3434
3893
  });
3435
3894
  }
3436
3895
  function summarizeTokenUsage(usage) {
3437
- const record4 = tcAsRecord(usage);
3438
- const inputTokens = tcReadNumber(record4.input_tokens ?? record4.inputTokens, 0);
3439
- const cachedInputTokens = tcReadNumber(record4.cached_input_tokens ?? record4.cachedInputTokens, 0);
3440
- const outputTokens = tcReadNumber(record4.output_tokens ?? record4.outputTokens, 0);
3896
+ const record5 = tcAsRecord(usage);
3897
+ const inputTokens = tcReadNumber(record5.input_tokens ?? record5.inputTokens, 0);
3898
+ const cachedInputTokens = tcReadNumber(record5.cached_input_tokens ?? record5.cachedInputTokens, 0);
3899
+ const outputTokens = tcReadNumber(record5.output_tokens ?? record5.outputTokens, 0);
3441
3900
  const parts = [];
3442
3901
  if (inputTokens > 0) parts.push(`\u8F93\u5165 ${inputTokens}`);
3443
3902
  if (cachedInputTokens > 0) parts.push(`\u7F13\u5B58 ${cachedInputTokens}`);
@@ -3692,8 +4151,8 @@ function summarizeClaudeEvent(event) {
3692
4151
  return null;
3693
4152
  }
3694
4153
  function tcPiMessageText(message) {
3695
- const record4 = tcAsRecord(message);
3696
- const content = record4.content;
4154
+ const record5 = tcAsRecord(message);
4155
+ const content = record5.content;
3697
4156
  if (typeof content === "string" && content.trim().length > 0) return content.trim();
3698
4157
  if (!Array.isArray(content)) return "";
3699
4158
  return content.map((entry) => {
@@ -3707,14 +4166,14 @@ function tcPiAssistantMessageEventText(assistantMessageEvent) {
3707
4166
  return tcReadString(event.content) ?? "";
3708
4167
  }
3709
4168
  function tcPiMessageStopReason(message) {
3710
- const record4 = tcAsRecord(message);
3711
- return tcReadString(record4.stopReason ?? record4.stop_reason);
4169
+ const record5 = tcAsRecord(message);
4170
+ return tcReadString(record5.stopReason ?? record5.stop_reason);
3712
4171
  }
3713
4172
  function tcPiMessageErrorText(message) {
3714
- const record4 = tcAsRecord(message);
3715
- const explicitError = tcReadString(record4.errorMessage ?? record4.error_message)?.trim();
4173
+ const record5 = tcAsRecord(message);
4174
+ const explicitError = tcReadString(record5.errorMessage ?? record5.error_message)?.trim();
3716
4175
  if (explicitError) return explicitError;
3717
- const stopReason = tcPiMessageStopReason(record4);
4176
+ const stopReason = tcPiMessageStopReason(record5);
3718
4177
  if (stopReason === "error" || stopReason === "failed" || stopReason === "exception") {
3719
4178
  return `Pi Agent message ended with stopReason=${stopReason}`;
3720
4179
  }
@@ -3927,6 +4386,36 @@ function governedMcpToolResult(structuredContent) {
3927
4386
  ...runtimeAction ? { runtimeAction } : {}
3928
4387
  };
3929
4388
  }
4389
+ function dedupeGovernedMcpToolResults(results) {
4390
+ const unique = [];
4391
+ const indexByInvocationId = /* @__PURE__ */ new Map();
4392
+ for (const rawResult of Array.isArray(results) ? results : []) {
4393
+ const result3 = asRecord(rawResult);
4394
+ const invocationId = readString(result3.invocationId);
4395
+ if (!invocationId) {
4396
+ unique.push(result3);
4397
+ continue;
4398
+ }
4399
+ const existingIndex = indexByInvocationId.get(invocationId);
4400
+ if (existingIndex === void 0) {
4401
+ indexByInvocationId.set(invocationId, unique.length);
4402
+ unique.push(result3);
4403
+ continue;
4404
+ }
4405
+ const existing = asRecord(unique[existingIndex]);
4406
+ const existingRuntimeAction = asRecord(existing.runtimeAction);
4407
+ const runtimeAction = asRecord(result3.runtimeAction);
4408
+ const existingArtifactIntent = asRecord(existing.artifactIntent);
4409
+ const artifactIntent = asRecord(result3.artifactIntent);
4410
+ unique[existingIndex] = {
4411
+ ...existing,
4412
+ ...result3,
4413
+ ...Object.keys(existingRuntimeAction).length > 0 || Object.keys(runtimeAction).length > 0 ? { runtimeAction: { ...existingRuntimeAction, ...runtimeAction } } : {},
4414
+ ...Object.keys(existingArtifactIntent).length > 0 || Object.keys(artifactIntent).length > 0 ? { artifactIntent: { ...existingArtifactIntent, ...artifactIntent } } : {}
4415
+ };
4416
+ }
4417
+ return unique;
4418
+ }
3930
4419
  function durablePiRuntimeActionEvidence(results) {
3931
4420
  const normalizedResults = (Array.isArray(results) ? results : []).map(asRecord);
3932
4421
  const writeCallIds = /* @__PURE__ */ new Set();
@@ -4051,12 +4540,13 @@ function parseCodexJsonl(stdout) {
4051
4540
  errorMessage = readString(error.message) ?? errorMessage;
4052
4541
  }
4053
4542
  }
4543
+ const uniqueMcpToolResults = dedupeGovernedMcpToolResults(mcpToolResults);
4054
4544
  return {
4055
4545
  sessionId,
4056
4546
  summary,
4057
4547
  usage,
4058
4548
  errorMessage: terminalEvent === "completed" ? null : errorMessage,
4059
- ...mcpToolResults.length > 0 ? { mcpToolResults } : {}
4549
+ ...uniqueMcpToolResults.length > 0 ? { mcpToolResults: uniqueMcpToolResults } : {}
4060
4550
  };
4061
4551
  }
4062
4552
  function buildCodexErrorHaystack(input) {
@@ -4257,13 +4747,13 @@ function parseClaudeStreamJson(stdout) {
4257
4747
  }
4258
4748
  function openCodeErrorText(value) {
4259
4749
  if (typeof value === "string") return value;
4260
- const record4 = asRecord(value);
4261
- const message = readString(record4.message);
4750
+ const record5 = asRecord(value);
4751
+ const message = readString(record5.message);
4262
4752
  if (message) return message;
4263
- const data = asRecord(record4.data);
4753
+ const data = asRecord(record5.data);
4264
4754
  const nestedMessage = readString(data.message);
4265
4755
  if (nestedMessage) return nestedMessage;
4266
- return readString(record4.name) ?? readString(record4.code) ?? "";
4756
+ return readString(record5.name) ?? readString(record5.code) ?? "";
4267
4757
  }
4268
4758
  function parseOpenCodeJsonl(stdout) {
4269
4759
  let sessionId = null;
@@ -4301,8 +4791,8 @@ function parseOpenCodeJsonl(stdout) {
4301
4791
  return { sessionId, summary, usage, errorMessage };
4302
4792
  }
4303
4793
  function piMessageText(message) {
4304
- const record4 = asRecord(message);
4305
- const content = record4.content;
4794
+ const record5 = asRecord(message);
4795
+ const content = record5.content;
4306
4796
  if (typeof content === "string") return content.trim();
4307
4797
  if (!Array.isArray(content)) return "";
4308
4798
  return content.map((entry) => {
@@ -4327,10 +4817,10 @@ function piTextValue(value) {
4327
4817
  return typeof value === "string" && value.length > 0 ? value : "";
4328
4818
  }
4329
4819
  function piAssistantEventText(assistantEvent) {
4330
- const record4 = asRecord(assistantEvent);
4331
- const type = readString(record4.type);
4332
- if (type === "text_delta") return piTextValue(record4.delta);
4333
- if (type === "text_end") return piTextValue(record4.content);
4820
+ const record5 = asRecord(assistantEvent);
4821
+ const type = readString(record5.type);
4822
+ if (type === "text_delta") return piTextValue(record5.delta);
4823
+ if (type === "text_end") return piTextValue(record5.content);
4334
4824
  return "";
4335
4825
  }
4336
4826
  function piMessageUsage(message) {
@@ -4351,14 +4841,14 @@ function assignPiUsage(target, source) {
4351
4841
  if (source.costUsd > 0) target.costUsd = source.costUsd;
4352
4842
  }
4353
4843
  function piMessageStopReason(message) {
4354
- const record4 = asRecord(message);
4355
- return readString(record4.stopReason ?? record4.stop_reason);
4844
+ const record5 = asRecord(message);
4845
+ return readString(record5.stopReason ?? record5.stop_reason);
4356
4846
  }
4357
4847
  function piMessageErrorText(message) {
4358
- const record4 = asRecord(message);
4359
- const explicitError = readString(record4.errorMessage ?? record4.error_message)?.trim();
4848
+ const record5 = asRecord(message);
4849
+ const explicitError = readString(record5.errorMessage ?? record5.error_message)?.trim();
4360
4850
  if (explicitError) return explicitError;
4361
- const stopReason = piMessageStopReason(record4);
4851
+ const stopReason = piMessageStopReason(record5);
4362
4852
  if (stopReason === "error" || stopReason === "failed" || stopReason === "exception") {
4363
4853
  return `Pi Agent message ended with stopReason=${stopReason}`;
4364
4854
  }
@@ -4493,6 +4983,7 @@ function parsePiJsonl(stdout) {
4493
4983
  }
4494
4984
  }
4495
4985
  }
4986
+ const uniqueMcpToolResults = dedupeGovernedMcpToolResults(mcpToolResults);
4496
4987
  return {
4497
4988
  sessionId,
4498
4989
  summary: messages.at(-1) ?? "",
@@ -4504,7 +4995,7 @@ function parsePiJsonl(stdout) {
4504
4995
  errorMessage,
4505
4996
  ...nonCleanupErrorCount > 0 ? { nonCleanupErrorCount } : {},
4506
4997
  ...cleanupDiagnostics.length > 0 ? { cleanupDiagnostics } : {},
4507
- ...mcpToolResults.length > 0 ? { mcpToolResults } : {}
4998
+ ...uniqueMcpToolResults.length > 0 ? { mcpToolResults: uniqueMcpToolResults } : {}
4508
4999
  };
4509
5000
  }
4510
5001
  function parseGenericOutput(stdout, stderr) {
@@ -4615,6 +5106,12 @@ function parseRuntimeConnectorResponse(res, method, path, text) {
4615
5106
  const error = new Error(`${method} ${path} returned HTTP ${res.status}: ${responseDescription}`);
4616
5107
  error.httpStatus = res.status;
4617
5108
  error.responseContentType = responseContentType;
5109
+ if (responseContentType?.includes("application/json") && text) {
5110
+ try {
5111
+ error.responseBody = JSON.parse(text);
5112
+ } catch {
5113
+ }
5114
+ }
4618
5115
  throw error;
4619
5116
  }
4620
5117
  if (!text) return null;
@@ -4698,7 +5195,7 @@ var bestEffortPostJson = bestEffortPostRuntimeConnectorJson;
4698
5195
 
4699
5196
  // src/amaster-runtime-daemon/runtime-artifact-upload.mjs
4700
5197
  import { createHash as createHash3 } from "node:crypto";
4701
- import { lstatSync as lstatSync3, readFileSync as readFileSync5, realpathSync as realpathSync2 } from "node:fs";
5198
+ import { lstatSync as lstatSync3, readFileSync as readFileSync6, realpathSync as realpathSync3 } from "node:fs";
4702
5199
  import { isAbsolute as isAbsolute3, relative as relative3, resolve as resolve3 } from "node:path";
4703
5200
  var SHA256_PATTERN = /^[a-f0-9]{64}$/;
4704
5201
  function requiredString(value, name) {
@@ -4715,7 +5212,7 @@ function pathWithin(candidate, root) {
4715
5212
  return rel === "" || !rel.startsWith("..") && !isAbsolute3(rel);
4716
5213
  }
4717
5214
  function prepareRuntimeArtifactUploads(cwd, mcpToolResults) {
4718
- const root = realpathSync2(resolve3(cwd));
5215
+ const root = realpathSync3(resolve3(cwd));
4719
5216
  const uploads = /* @__PURE__ */ new Map();
4720
5217
  for (const result3 of Array.isArray(mcpToolResults) ? mcpToolResults : []) {
4721
5218
  const intent = result3 && typeof result3 === "object" && !Array.isArray(result3) ? result3.artifactIntent : null;
@@ -4736,10 +5233,10 @@ function prepareRuntimeArtifactUploads(cwd, mcpToolResults) {
4736
5233
  }
4737
5234
  const sourcePath = resolve3(root, sourceRelativePath);
4738
5235
  const stat = lstatSync3(sourcePath);
4739
- if (!stat.isFile() || stat.isSymbolicLink() || !pathWithin(realpathSync2(sourcePath), root)) {
5236
+ if (!stat.isFile() || stat.isSymbolicLink() || !pathWithin(realpathSync3(sourcePath), root)) {
4740
5237
  throw new Error(`Runtime Artifact ${intentId} source is not an owned regular file`);
4741
5238
  }
4742
- const body = readFileSync5(sourcePath);
5239
+ const body = readFileSync6(sourcePath);
4743
5240
  const actualSha256 = createHash3("sha256").update(body).digest("hex");
4744
5241
  if (body.length !== expectedByteSize || actualSha256 !== expectedSha256) {
4745
5242
  throw new Error(`Runtime Artifact ${intentId} bytes do not match the governed ownership manifest`);
@@ -4771,21 +5268,39 @@ var RuntimeArtifactIngestAggregateError = class extends AggregateError {
4771
5268
  };
4772
5269
  function createRuntimeArtifactIngestQueue({ ingest, onError }) {
4773
5270
  const handledIntentIds = /* @__PURE__ */ new Set();
5271
+ const artifactIdentityByIntentId = /* @__PURE__ */ new Map();
5272
+ const finalizedArtifactIdentities = /* @__PURE__ */ new Set();
4774
5273
  const artifacts = [];
4775
5274
  const errors = [];
4776
5275
  let queue = Promise.resolve();
5276
+ const artifactIdentity = (intent) => {
5277
+ const sourceRelativePath = readString(asRecord(intent).sourceRelativePath);
5278
+ const sha2563 = readString(asRecord(intent).sha256);
5279
+ const byteSize = asRecord(intent).byteSize;
5280
+ return sourceRelativePath && sha2563 && Number.isSafeInteger(byteSize) && byteSize > 0 ? `${sourceRelativePath}\0${sha2563}\0${byteSize}` : null;
5281
+ };
5282
+ const retainReceipts = (receipts) => {
5283
+ artifacts.push(...receipts);
5284
+ for (const receipt of receipts) {
5285
+ const intentId = readString(asRecord(receipt).intentId);
5286
+ const identity2 = intentId ? artifactIdentityByIntentId.get(intentId) : null;
5287
+ if (identity2) finalizedArtifactIdentities.add(identity2);
5288
+ }
5289
+ };
4777
5290
  return {
4778
5291
  enqueue(results) {
4779
5292
  const pending = results.filter((result3) => {
4780
5293
  const intentId = readString(asRecord(result3).artifactIntent?.intentId);
4781
5294
  if (!intentId || handledIntentIds.has(intentId)) return false;
4782
5295
  handledIntentIds.add(intentId);
5296
+ const identity2 = artifactIdentity(asRecord(result3).artifactIntent);
5297
+ if (identity2) artifactIdentityByIntentId.set(intentId, identity2);
4783
5298
  return true;
4784
5299
  });
4785
5300
  if (pending.length === 0) return;
4786
- queue = queue.then(async () => artifacts.push(...await ingest(pending))).catch((caught) => {
5301
+ queue = queue.then(async () => retainReceipts(await ingest(pending))).catch((caught) => {
4787
5302
  const aggregate = caught instanceof RuntimeArtifactIngestAggregateError ? caught : null;
4788
- artifacts.push(...aggregate?.receipts ?? []);
5303
+ retainReceipts(aggregate?.receipts ?? []);
4789
5304
  for (const error of aggregate?.failures ?? [normalizedError(caught)]) {
4790
5305
  errors.push(error);
4791
5306
  onError?.(error);
@@ -4797,8 +5312,14 @@ function createRuntimeArtifactIngestQueue({ ingest, onError }) {
4797
5312
  },
4798
5313
  async flush() {
4799
5314
  await queue;
4800
- if (errors.length > 0) {
4801
- throw new RuntimeArtifactIngestAggregateError(errors, artifacts);
5315
+ const unresolvedErrors = errors.filter((error) => {
5316
+ if (error.code === "runtime_artifact_rejected") return true;
5317
+ const intentId = readString(error.intentId);
5318
+ const identity2 = intentId ? artifactIdentityByIntentId.get(intentId) : null;
5319
+ return !identity2 || !finalizedArtifactIdentities.has(identity2);
5320
+ });
5321
+ if (unresolvedErrors.length > 0) {
5322
+ throw new RuntimeArtifactIngestAggregateError(unresolvedErrors, artifacts);
4802
5323
  }
4803
5324
  return [...artifacts];
4804
5325
  }
@@ -4807,40 +5328,40 @@ function createRuntimeArtifactIngestQueue({ ingest, onError }) {
4807
5328
 
4808
5329
  // src/amaster-runtime-daemon/workspace-guard.mjs
4809
5330
  import { createHash as createHash4 } from "node:crypto";
4810
- import { existsSync as existsSync6, mkdirSync as mkdirSync5, realpathSync as realpathSync3, statSync as statSync3 } from "node:fs";
4811
- import { basename as basename4, join as join7, isAbsolute as isAbsolute4, relative as relative4, resolve as resolve4 } from "node:path";
5331
+ import { existsSync as existsSync7, mkdirSync as mkdirSync6, realpathSync as realpathSync4, statSync as statSync3 } from "node:fs";
5332
+ import { basename as basename4, join as join8, isAbsolute as isAbsolute4, relative as relative4, resolve as resolve4 } from "node:path";
4812
5333
 
4813
5334
  // src/amaster-runtime-daemon/workspace-manifest.mjs
4814
- import { existsSync as existsSync5, readFileSync as readFileSync6, renameSync as renameSync3, rmSync as rmSync4, writeFileSync as writeFileSync5 } from "node:fs";
4815
- import { basename as basename3, dirname as dirname5, join as join6 } from "node:path";
5335
+ import { existsSync as existsSync6, readFileSync as readFileSync7, renameSync as renameSync4, rmSync as rmSync4, writeFileSync as writeFileSync6 } from "node:fs";
5336
+ import { basename as basename3, dirname as dirname5, join as join7 } from "node:path";
4816
5337
  var WORKSPACE_MANIFEST_FILENAME = ".amaster-runtime.json";
4817
5338
  function nowIso() {
4818
5339
  return (/* @__PURE__ */ new Date()).toISOString();
4819
5340
  }
4820
5341
  function workspaceManifestPath(workspaceOrCwd) {
4821
5342
  if (!workspaceOrCwd) return null;
4822
- if (typeof workspaceOrCwd === "string") return join6(workspaceOrCwd, WORKSPACE_MANIFEST_FILENAME);
4823
- if (typeof workspaceOrCwd.cwd === "string") return join6(workspaceOrCwd.cwd, WORKSPACE_MANIFEST_FILENAME);
5343
+ if (typeof workspaceOrCwd === "string") return join7(workspaceOrCwd, WORKSPACE_MANIFEST_FILENAME);
5344
+ if (typeof workspaceOrCwd.cwd === "string") return join7(workspaceOrCwd.cwd, WORKSPACE_MANIFEST_FILENAME);
4824
5345
  return null;
4825
5346
  }
4826
5347
  function readWorkspaceManifest(manifestPath) {
4827
- if (!manifestPath || !existsSync5(manifestPath)) return null;
5348
+ if (!manifestPath || !existsSync6(manifestPath)) return null;
4828
5349
  try {
4829
- const parsed = JSON.parse(readFileSync6(manifestPath, "utf8"));
5350
+ const parsed = JSON.parse(readFileSync7(manifestPath, "utf8"));
4830
5351
  return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
4831
5352
  } catch {
4832
5353
  return null;
4833
5354
  }
4834
5355
  }
4835
5356
  function writeWorkspaceManifest(manifestPath, manifest) {
4836
- const tempPath = join6(
5357
+ const tempPath = join7(
4837
5358
  dirname5(manifestPath),
4838
5359
  `.${basename3(manifestPath)}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`
4839
5360
  );
4840
5361
  try {
4841
- writeFileSync5(tempPath, `${JSON.stringify(manifest, null, 2)}
5362
+ writeFileSync6(tempPath, `${JSON.stringify(manifest, null, 2)}
4842
5363
  `, { mode: 384 });
4843
- renameSync3(tempPath, manifestPath);
5364
+ renameSync4(tempPath, manifestPath);
4844
5365
  } catch (err) {
4845
5366
  rmSync4(tempPath, { force: true });
4846
5367
  throw err;
@@ -4899,10 +5420,10 @@ function resolveWorkspaceCwd(config, command) {
4899
5420
  const payload = asRecord(command.payload);
4900
5421
  const requested = readString(payload.workspacePath);
4901
5422
  const fallback = config.workspaceBindings[0] ?? process.cwd();
4902
- const cwd = realpathSync3(resolve4(expandHomePath(requested ?? fallback)));
5423
+ const cwd = realpathSync4(resolve4(expandHomePath(requested ?? fallback)));
4903
5424
  const allowlist = config.workspaceBindings.flatMap((entry) => {
4904
5425
  try {
4905
- return [realpathSync3(resolve4(expandHomePath(entry)))];
5426
+ return [realpathSync4(resolve4(expandHomePath(entry)))];
4906
5427
  } catch {
4907
5428
  return [];
4908
5429
  }
@@ -4911,7 +5432,7 @@ function resolveWorkspaceCwd(config, command) {
4911
5432
  if (!allowed) {
4912
5433
  throw new Error(`Workspace path is outside AMASTER_WORKSPACE_ALLOWLIST: ${cwd}`);
4913
5434
  }
4914
- if (!existsSync6(cwd) || !statSync3(cwd).isDirectory()) {
5435
+ if (!existsSync7(cwd) || !statSync3(cwd).isDirectory()) {
4915
5436
  throw new Error(`Workspace path does not exist or is not a directory: ${cwd}`);
4916
5437
  }
4917
5438
  return cwd;
@@ -4942,8 +5463,8 @@ function workspaceLabel(sourceWorkspacePath, payload) {
4942
5463
  }
4943
5464
  function workspacesRoot(config) {
4944
5465
  const root = resolve4(expandHomePath(config.runtimeWorkspacesRoot ?? "~/.amaster-employee/workspaces"));
4945
- mkdirSync5(root, { recursive: true });
4946
- return realpathSync3(root);
5466
+ mkdirSync6(root, { recursive: true });
5467
+ return realpathSync4(root);
4947
5468
  }
4948
5469
  function resolveExecutionWorkspace(config, command, opts = {}) {
4949
5470
  const sourceWorkspacePath = resolveWorkspaceCwd(config, command);
@@ -4955,11 +5476,11 @@ function resolveExecutionWorkspace(config, command, opts = {}) {
4955
5476
  const workspaceKey = `${safeSegment(workspaceLabel(sourceWorkspacePath, payload), "workspace")}-${shortHash(sourceWorkspacePath)}`;
4956
5477
  const issueKey = `${safeSegment(issueLabel(command, payload), "issue")}-${shortHash(issueId, 8)}`;
4957
5478
  const runKey = `${safeSegment(runId, "run")}-${shortHash(runId, 8)}`;
4958
- const runDir = join7(root, workspaceKey, issueKey, runKey);
4959
- const cwd = join7(runDir, "workdir");
4960
- const executorHome = join7(runDir, "executors", safeSegment(executorKind, "executor"));
4961
- mkdirSync5(cwd, { recursive: true });
4962
- mkdirSync5(executorHome, { recursive: true });
5479
+ const runDir = join8(root, workspaceKey, issueKey, runKey);
5480
+ const cwd = join8(runDir, "workdir");
5481
+ const executorHome = join8(runDir, "executors", safeSegment(executorKind, "executor"));
5482
+ mkdirSync6(cwd, { recursive: true });
5483
+ mkdirSync6(executorHome, { recursive: true });
4963
5484
  const workspace = {
4964
5485
  managed: true,
4965
5486
  cwd,
@@ -4981,8 +5502,8 @@ function resolveExecutionWorkspace(config, command, opts = {}) {
4981
5502
  }
4982
5503
 
4983
5504
  // src/amaster-runtime-daemon/workspace-gc.mjs
4984
- import { existsSync as existsSync7, readdirSync as readdirSync3, statSync as statSync4 } from "node:fs";
4985
- import { join as join8, resolve as resolve5 } from "node:path";
5505
+ import { existsSync as existsSync8, readdirSync as readdirSync4, statSync as statSync4 } from "node:fs";
5506
+ import { join as join9, resolve as resolve5 } from "node:path";
4986
5507
  function readIsoTime(value) {
4987
5508
  if (typeof value !== "string" || !value.trim()) return null;
4988
5509
  const time = new Date(value).getTime();
@@ -4999,14 +5520,14 @@ function walkWorkdirs(root) {
4999
5520
  if (!current) continue;
5000
5521
  let entries = [];
5001
5522
  try {
5002
- entries = readdirSync3(current, { withFileTypes: true });
5523
+ entries = readdirSync4(current, { withFileTypes: true });
5003
5524
  } catch {
5004
5525
  continue;
5005
5526
  }
5006
5527
  for (const entry of entries) {
5007
5528
  if (!entry.isDirectory()) continue;
5008
- const fullPath = join8(current, entry.name);
5009
- if (entry.name === "workdir" && existsSync7(workspaceManifestPath(fullPath))) {
5529
+ const fullPath = join9(current, entry.name);
5530
+ if (entry.name === "workdir" && existsSync8(workspaceManifestPath(fullPath))) {
5010
5531
  workdirs.push(fullPath);
5011
5532
  continue;
5012
5533
  }
@@ -5032,12 +5553,12 @@ function directorySizeBytes(path) {
5032
5553
  if (stat.isDirectory()) {
5033
5554
  let entries = [];
5034
5555
  try {
5035
- entries = readdirSync3(current, { withFileTypes: true });
5556
+ entries = readdirSync4(current, { withFileTypes: true });
5036
5557
  } catch {
5037
5558
  continue;
5038
5559
  }
5039
5560
  for (const entry of entries) {
5040
- stack.push(join8(current, entry.name));
5561
+ stack.push(join9(current, entry.name));
5041
5562
  }
5042
5563
  continue;
5043
5564
  }
@@ -5081,7 +5602,7 @@ function planManagedWorkspaceGcDryRun(input) {
5081
5602
  candidates: [],
5082
5603
  protected: []
5083
5604
  };
5084
- if (!root || !existsSync7(root)) return result3;
5605
+ if (!root || !existsSync8(root)) return result3;
5085
5606
  for (const workdir of walkWorkdirs(root)) {
5086
5607
  const manifest = readWorkspaceManifest(workspaceManifestPath(workdir));
5087
5608
  if (!manifest || manifest.managed !== true) continue;
@@ -5109,11 +5630,11 @@ function planManagedWorkspaceGcDryRun(input) {
5109
5630
  }
5110
5631
 
5111
5632
  // src/amaster-runtime-daemon/runtime-status-summary.mjs
5112
- import { existsSync as existsSync8, readdirSync as readdirSync4, statSync as statSync5 } from "node:fs";
5113
- import { dirname as dirname6, join as join9, resolve as resolve6 } from "node:path";
5633
+ import { existsSync as existsSync9, readdirSync as readdirSync5, statSync as statSync5 } from "node:fs";
5634
+ import { dirname as dirname6, join as join10, resolve as resolve6 } from "node:path";
5114
5635
  function runtimeStatusDirectoryEntries(path) {
5115
5636
  try {
5116
- return readdirSync4(path, { withFileTypes: true });
5637
+ return readdirSync5(path, { withFileTypes: true });
5117
5638
  } catch {
5118
5639
  return [];
5119
5640
  }
@@ -5133,7 +5654,7 @@ function runtimeStatusDirectorySizeBytes(path) {
5133
5654
  if (!stat || stat.isSymbolicLink()) continue;
5134
5655
  if (stat.isDirectory()) {
5135
5656
  for (const entry of runtimeStatusDirectoryEntries(current)) {
5136
- stack.push(join9(current, entry.name));
5657
+ stack.push(join10(current, entry.name));
5137
5658
  }
5138
5659
  continue;
5139
5660
  }
@@ -5143,15 +5664,15 @@ function runtimeStatusDirectorySizeBytes(path) {
5143
5664
  }
5144
5665
  function walkRuntimeStatusManagedWorkdirs(root) {
5145
5666
  const workdirs = [];
5146
- if (!root || !existsSync8(root)) return workdirs;
5667
+ if (!root || !existsSync9(root)) return workdirs;
5147
5668
  const stack = [root];
5148
5669
  while (stack.length > 0) {
5149
5670
  const current = stack.pop();
5150
5671
  if (!current) continue;
5151
5672
  for (const entry of runtimeStatusDirectoryEntries(current)) {
5152
5673
  if (!entry.isDirectory()) continue;
5153
- const fullPath = join9(current, entry.name);
5154
- if (entry.name === "workdir" && existsSync8(workspaceManifestPath(fullPath))) {
5674
+ const fullPath = join10(current, entry.name);
5675
+ if (entry.name === "workdir" && existsSync9(workspaceManifestPath(fullPath))) {
5155
5676
  workdirs.push(fullPath);
5156
5677
  continue;
5157
5678
  }
@@ -5192,12 +5713,12 @@ function summarizeRuntimeStatusRecentRun(workdir, manifest) {
5192
5713
  }
5193
5714
  function runtimeStatusOutboxDir(config) {
5194
5715
  const statePath = config.AMASTER_DAEMON_STATE_FILE ?? config.daemonStateFile;
5195
- return join9(dirname6(stateFilePath({
5716
+ return join10(dirname6(stateFilePath({
5196
5717
  AMASTER_DAEMON_STATE_FILE: statePath
5197
5718
  })), "result-outbox");
5198
5719
  }
5199
5720
  function countRuntimeStatusJsonEntries(dir) {
5200
- if (!existsSync8(dir)) return 0;
5721
+ if (!existsSync9(dir)) return 0;
5201
5722
  return runtimeStatusDirectoryEntries(dir).filter((entry) => entry.isFile() && entry.name.endsWith(".json")).length;
5202
5723
  }
5203
5724
  function summarizeRuntimeLocalState(input) {
@@ -5229,7 +5750,7 @@ function summarizeRuntimeLocalState(input) {
5229
5750
  }
5230
5751
  }
5231
5752
  const pendingOutboxDir = runtimeStatusOutboxDir(config);
5232
- const invalidOutboxDir = join9(pendingOutboxDir, "invalid");
5753
+ const invalidOutboxDir = join10(pendingOutboxDir, "invalid");
5233
5754
  return {
5234
5755
  managedWorkspacesRoot: root,
5235
5756
  managedWorkdirCount: workdirs.length,
@@ -5355,10 +5876,10 @@ import {
5355
5876
  chownSync,
5356
5877
  lchownSync,
5357
5878
  lstatSync as lstatSync4,
5358
- readdirSync as readdirSync5
5879
+ readdirSync as readdirSync6
5359
5880
  } from "node:fs";
5360
5881
  import { resolve as resolve7, sep } from "node:path";
5361
- var defaultFs = { chmodSync: chmodSync3, chownSync, lchownSync, lstatSync: lstatSync4, readdirSync: readdirSync5 };
5882
+ var defaultFs = { chmodSync: chmodSync3, chownSync, lchownSync, lstatSync: lstatSync4, readdirSync: readdirSync6 };
5362
5883
  function defaultHashRunId(runId) {
5363
5884
  return Number.parseInt(createHash5("sha256").update(runId).digest("hex").slice(0, 8), 16);
5364
5885
  }
@@ -5488,17 +6009,17 @@ import { createHash as createHash6 } from "node:crypto";
5488
6009
  import {
5489
6010
  chmodSync as chmodSync4,
5490
6011
  chownSync as chownSync2,
5491
- existsSync as existsSync9,
6012
+ existsSync as existsSync10,
5492
6013
  lchownSync as lchownSync2,
5493
6014
  lstatSync as lstatSync5,
5494
- mkdirSync as mkdirSync6,
5495
- readFileSync as readFileSync7,
5496
- renameSync as renameSync4,
6015
+ mkdirSync as mkdirSync7,
6016
+ readFileSync as readFileSync8,
6017
+ renameSync as renameSync5,
5497
6018
  rmSync as rmSync5,
5498
6019
  symlinkSync as symlinkSync2,
5499
- writeFileSync as writeFileSync6
6020
+ writeFileSync as writeFileSync7
5500
6021
  } from "node:fs";
5501
- import { dirname as dirname7, isAbsolute as isAbsolute5, join as join10, relative as relative5, resolve as resolve8 } from "node:path";
6022
+ import { dirname as dirname7, isAbsolute as isAbsolute5, join as join11, relative as relative5, resolve as resolve8 } from "node:path";
5502
6023
  var REGISTRY_FILENAME = ".amaster-company-memory-groups.json";
5503
6024
  var COMPANY_MARKER_FILENAME = ".amaster-company-memory.json";
5504
6025
  var REGISTRY_VERSION = 1;
@@ -5508,15 +6029,15 @@ var DEFAULT_GID_SPAN = 1e6;
5508
6029
  var defaultFs2 = {
5509
6030
  chmodSync: chmodSync4,
5510
6031
  chownSync: chownSync2,
5511
- existsSync: existsSync9,
6032
+ existsSync: existsSync10,
5512
6033
  lchownSync: lchownSync2,
5513
6034
  lstatSync: lstatSync5,
5514
- mkdirSync: mkdirSync6,
5515
- readFileSync: readFileSync7,
5516
- renameSync: renameSync4,
6035
+ mkdirSync: mkdirSync7,
6036
+ readFileSync: readFileSync8,
6037
+ renameSync: renameSync5,
5517
6038
  rmSync: rmSync5,
5518
6039
  symlinkSync: symlinkSync2,
5519
- writeFileSync: writeFileSync6
6040
+ writeFileSync: writeFileSync7
5520
6041
  };
5521
6042
  function requiredString2(value, label) {
5522
6043
  if (typeof value !== "string" || value.trim() === "") {
@@ -5580,7 +6101,7 @@ function ensureMemoryRoot(root, fs) {
5580
6101
  fs.chmodSync(root, 457);
5581
6102
  }
5582
6103
  function readGroupRegistry(root, fs) {
5583
- const path = join10(root, REGISTRY_FILENAME);
6104
+ const path = join11(root, REGISTRY_FILENAME);
5584
6105
  if (!fs.existsSync(path)) {
5585
6106
  return { path, groups: {} };
5586
6107
  }
@@ -5662,11 +6183,11 @@ function prepareCompanyPiMemory(input, fs = defaultFs2) {
5662
6183
  if (input.gid !== void 0 && positiveInteger2(input.gid, "gid") !== gid) {
5663
6184
  throw new Error("pi_company_memory_gid_mismatch");
5664
6185
  }
5665
- const companyDir = join10(root, safeCompanyPiHomeSegment(companyId));
5666
- const companyPiHome = join10(companyDir, ".pi");
5667
- const memoryDir = join10(companyPiHome, "memories");
6186
+ const companyDir = join11(root, safeCompanyPiHomeSegment(companyId));
6187
+ const companyPiHome = join11(companyDir, ".pi");
6188
+ const memoryDir = join11(companyPiHome, "memories");
5668
6189
  ensurePrivateDirectory(companyDir, 456, 0, gid, fs);
5669
- const markerPath = join10(companyDir, COMPANY_MARKER_FILENAME);
6190
+ const markerPath = join11(companyDir, COMPANY_MARKER_FILENAME);
5670
6191
  if (fs.existsSync(markerPath)) {
5671
6192
  const markerStat = fs.lstatSync(markerPath);
5672
6193
  if (!markerStat.isFile() || markerStat.isSymbolicLink()) {
@@ -5691,7 +6212,7 @@ function prepareCompanyPiMemory(input, fs = defaultFs2) {
5691
6212
  assertDirectory(memoryDir, "memories", fs);
5692
6213
  fs.chownSync(memoryDir, 0, gid);
5693
6214
  fs.chmodSync(memoryDir, 1528);
5694
- const memoryLink = join10(profileHome, "memories");
6215
+ const memoryLink = join11(profileHome, "memories");
5695
6216
  if (fs.existsSync(memoryLink)) {
5696
6217
  throw new Error("pi_company_memory_profile_link_exists");
5697
6218
  }
@@ -5715,16 +6236,16 @@ import { createHash as createHash7 } from "node:crypto";
5715
6236
  import {
5716
6237
  chmodSync as chmodSync5,
5717
6238
  copyFileSync as copyFileSync2,
5718
- existsSync as existsSync10,
6239
+ existsSync as existsSync11,
5719
6240
  lstatSync as lstatSync6,
5720
- mkdirSync as mkdirSync7,
5721
- readFileSync as readFileSync8,
5722
- readdirSync as readdirSync6,
6241
+ mkdirSync as mkdirSync8,
6242
+ readFileSync as readFileSync9,
6243
+ readdirSync as readdirSync7,
5723
6244
  rmSync as rmSync6,
5724
6245
  symlinkSync as symlinkSync3,
5725
- writeFileSync as writeFileSync7
6246
+ writeFileSync as writeFileSync8
5726
6247
  } from "node:fs";
5727
- import { dirname as dirname8, isAbsolute as isAbsolute6, join as join11, relative as relative6, resolve as resolve9 } from "node:path";
6248
+ import { dirname as dirname8, isAbsolute as isAbsolute6, join as join12, relative as relative6, resolve as resolve9 } from "node:path";
5728
6249
  var ASSERTION_VERSION = "2026-07-25.v1";
5729
6250
  var SHA256 = /^[a-f0-9]{64}$/;
5730
6251
  var COPY_ENTRIES = ["SYSTEM.md", "policy", "skills", "agents", "bundles", "extensions"];
@@ -5749,7 +6270,7 @@ function sha256File(path, label) {
5749
6270
  if (!stat.isFile() || stat.isSymbolicLink()) {
5750
6271
  throw new Error(`pi_trusted_runtime_source_unsafe:${label}`);
5751
6272
  }
5752
- return createHash7("sha256").update(readFileSync8(path)).digest("hex");
6273
+ return createHash7("sha256").update(readFileSync9(path)).digest("hex");
5753
6274
  }
5754
6275
  function verifyDeclaredFiles(manifest, root, label, ignoredPaths = [], enforceComplete = true) {
5755
6276
  if (!Array.isArray(manifest.files) || manifest.files.length === 0) {
@@ -5771,8 +6292,8 @@ function verifyDeclaredFiles(manifest, root, label, ignoredPaths = [], enforceCo
5771
6292
  if (!enforceComplete) return;
5772
6293
  const ignored = ignoredPaths.map((path) => path.split("\\").join("/"));
5773
6294
  const visit = (directory) => {
5774
- for (const entry of readdirSync6(directory)) {
5775
- const filePath = join11(directory, entry);
6295
+ for (const entry of readdirSync7(directory)) {
6296
+ const filePath = join12(directory, entry);
5776
6297
  const relativePath = relative6(root, filePath).split("\\").join("/");
5777
6298
  const stat = lstatSync6(filePath);
5778
6299
  if (stat.isSymbolicLink()) {
@@ -5790,7 +6311,7 @@ function verifyDeclaredFiles(manifest, root, label, ignoredPaths = [], enforceCo
5790
6311
  };
5791
6312
  visit(root);
5792
6313
  }
5793
- function record3(value) {
6314
+ function record4(value) {
5794
6315
  return value && typeof value === "object" && !Array.isArray(value) ? value : {};
5795
6316
  }
5796
6317
  function within3(candidate, root) {
@@ -5798,13 +6319,13 @@ function within3(candidate, root) {
5798
6319
  return rel === "" || !rel.startsWith("..") && !isAbsolute6(rel);
5799
6320
  }
5800
6321
  function readJsonFile2(path, label, fallback = {}) {
5801
- if (!existsSync10(path)) return fallback;
6322
+ if (!existsSync11(path)) return fallback;
5802
6323
  const stat = lstatSync6(path);
5803
6324
  if (!stat.isFile() || stat.isSymbolicLink()) {
5804
6325
  throw new Error(`pi_trusted_runtime_source_unsafe:${label}`);
5805
6326
  }
5806
6327
  try {
5807
- return JSON.parse(readFileSync8(path, "utf8"));
6328
+ return JSON.parse(readFileSync9(path, "utf8"));
5808
6329
  } catch {
5809
6330
  throw new Error(`pi_trusted_runtime_source_invalid:${label}`);
5810
6331
  }
@@ -5835,29 +6356,29 @@ function copyTreeNoLinks(source, target) {
5835
6356
  const stat = lstatSync6(source);
5836
6357
  if (stat.isSymbolicLink()) throw new Error("pi_trusted_runtime_source_symlink_blocked");
5837
6358
  if (stat.isDirectory()) {
5838
- mkdirSync7(target, { recursive: true, mode: 448 });
6359
+ mkdirSync8(target, { recursive: true, mode: 448 });
5839
6360
  chmodSync5(target, 448);
5840
- for (const entry of readdirSync6(source)) {
5841
- copyTreeNoLinks(join11(source, entry), join11(target, entry));
6361
+ for (const entry of readdirSync7(source)) {
6362
+ copyTreeNoLinks(join12(source, entry), join12(target, entry));
5842
6363
  }
5843
6364
  return;
5844
6365
  }
5845
6366
  if (!stat.isFile()) throw new Error("pi_trusted_runtime_source_type_blocked");
5846
- mkdirSync7(dirname8(target), { recursive: true, mode: 448 });
6367
+ mkdirSync8(dirname8(target), { recursive: true, mode: 448 });
5847
6368
  copyFileSync2(source, target);
5848
6369
  chmodSync5(target, 384 | stat.mode & 73);
5849
6370
  }
5850
6371
  function mergeMcp(seedRoot, overlayRoot, governedConfig) {
5851
- const seed = record3(readJsonFile2(join11(seedRoot, "mcp.json"), "seed_mcp", { mcpServers: {} }));
5852
- const overlay = record3(readJsonFile2(join11(overlayRoot, "mcp.json"), "overlay_mcp", { mcpServers: {} }));
6372
+ const seed = record4(readJsonFile2(join12(seedRoot, "mcp.json"), "seed_mcp", { mcpServers: {} }));
6373
+ const overlay = record4(readJsonFile2(join12(overlayRoot, "mcp.json"), "overlay_mcp", { mcpServers: {} }));
5853
6374
  assertNoPersistentSecrets(seed, ["seed", "mcp.json"]);
5854
6375
  assertNoPersistentSecrets(overlay, ["overlay", "mcp.json"]);
5855
- const seedServers = record3(seed.mcpServers);
5856
- const overlayServers = record3(overlay.mcpServers);
6376
+ const seedServers = record4(seed.mcpServers);
6377
+ const overlayServers = record4(overlay.mcpServers);
5857
6378
  if ("amaster" in seedServers || "amaster" in overlayServers) {
5858
6379
  throw new Error("pi_trusted_runtime_reserved_mcp_override:amaster");
5859
6380
  }
5860
- const governed = record3(record3(governedConfig).mcpServers).amaster;
6381
+ const governed = record4(record4(governedConfig).mcpServers).amaster;
5861
6382
  if (!governed) throw new Error("pi_trusted_runtime_governed_mcp_missing");
5862
6383
  return {
5863
6384
  ...deepMerge(seed, overlay),
@@ -5877,14 +6398,14 @@ function assertEnabledPackagesAvailable(settings, npmRoot) {
5877
6398
  const requiredNames = new Set(
5878
6399
  (Array.isArray(settings.packages) ? settings.packages : []).map(packageName).filter(Boolean)
5879
6400
  );
5880
- for (const plugin of Object.values(record3(settings.plugins))) {
5881
- const config = record3(plugin);
6401
+ for (const plugin of Object.values(record4(settings.plugins))) {
6402
+ const config = record4(plugin);
5882
6403
  if (config.enabled === true && typeof config.package === "string") {
5883
6404
  requiredNames.add(config.package);
5884
6405
  }
5885
6406
  }
5886
6407
  for (const name of requiredNames) {
5887
- const metadataPath = join11(npmRoot, "node_modules", ...name.split("/"), "package.json");
6408
+ const metadataPath = join12(npmRoot, "node_modules", ...name.split("/"), "package.json");
5888
6409
  const metadata = readJsonFile2(metadataPath, `package:${name}`, null);
5889
6410
  if (!metadata || metadata.name !== name) {
5890
6411
  throw new Error(`pi_trusted_runtime_package_unavailable:${name}`);
@@ -5904,44 +6425,44 @@ function materializeTrustedPiRuntimeProfile(input) {
5904
6425
  }
5905
6426
  }
5906
6427
  for (const entry of COPY_ENTRIES) {
5907
- const target = join11(agentDir, entry);
6428
+ const target = join12(agentDir, entry);
5908
6429
  rmSync6(target, { recursive: true, force: true });
5909
6430
  for (const sourceRoot of [seedRoot, overlayRoot]) {
5910
- const source = join11(sourceRoot, entry);
5911
- if (existsSync10(source)) copyTreeNoLinks(source, target);
6431
+ const source = join12(sourceRoot, entry);
6432
+ if (existsSync11(source)) copyTreeNoLinks(source, target);
5912
6433
  }
5913
6434
  }
5914
6435
  const mergedJson = {};
5915
6436
  for (const entry of JSON_ENTRIES) {
5916
- const seed = readJsonFile2(join11(seedRoot, entry), `seed_${entry}`, {});
5917
- const overlay = readJsonFile2(join11(overlayRoot, entry), `overlay_${entry}`, {});
6437
+ const seed = readJsonFile2(join12(seedRoot, entry), `seed_${entry}`, {});
6438
+ const overlay = readJsonFile2(join12(overlayRoot, entry), `overlay_${entry}`, {});
5918
6439
  const merged = deepMerge(seed, overlay);
5919
6440
  if (entry === "settings.json") {
5920
6441
  merged["pi-security"] = {
5921
- ...record3(merged["pi-security"]),
6442
+ ...record4(merged["pi-security"]),
5922
6443
  enabled: true,
5923
6444
  approvals: {
5924
- ...record3(record3(merged["pi-security"]).approvals),
6445
+ ...record4(record4(merged["pi-security"]).approvals),
5925
6446
  allowSessionGrants: false
5926
6447
  }
5927
6448
  };
5928
6449
  }
5929
6450
  assertNoPersistentSecrets(merged, [entry]);
5930
- writeFileSync7(join11(agentDir, entry), `${JSON.stringify(merged, null, 2)}
6451
+ writeFileSync8(join12(agentDir, entry), `${JSON.stringify(merged, null, 2)}
5931
6452
  `, {
5932
6453
  mode: 384
5933
6454
  });
5934
- chmodSync5(join11(agentDir, entry), 384);
6455
+ chmodSync5(join12(agentDir, entry), 384);
5935
6456
  mergedJson[entry] = merged;
5936
6457
  }
5937
6458
  const governedConfig = readJsonFile2(input.governedMcpConfigPath, "governed_mcp");
5938
6459
  const mcp = mergeMcp(seedRoot, overlayRoot, governedConfig);
5939
- writeFileSync7(input.governedMcpConfigPath, `${JSON.stringify(mcp, null, 2)}
6460
+ writeFileSync8(input.governedMcpConfigPath, `${JSON.stringify(mcp, null, 2)}
5940
6461
  `, { mode: 384 });
5941
6462
  chmodSync5(input.governedMcpConfigPath, 384);
5942
- const npmRoot = join11(seedRoot, "npm");
6463
+ const npmRoot = join12(seedRoot, "npm");
5943
6464
  assertEnabledPackagesAvailable(mergedJson["settings.json"], npmRoot);
5944
- const npmTarget = join11(agentDir, "npm");
6465
+ const npmTarget = join12(agentDir, "npm");
5945
6466
  rmSync6(npmTarget, { recursive: true, force: true });
5946
6467
  const npmStat = lstatSync6(npmRoot);
5947
6468
  if (!npmStat.isDirectory() || npmStat.isSymbolicLink()) {
@@ -5986,13 +6507,13 @@ function readTrustedPiRuntimeAudit(input) {
5986
6507
  const profileRoot = resolve9(requiredString3(input.profileRoot, "profileRoot"));
5987
6508
  const auditFile = resolve9(requiredString3(input.auditFile, "auditFile"));
5988
6509
  if (!within3(auditFile, profileRoot)) throw new Error("pi_trusted_runtime_audit_path_escape");
5989
- if (!existsSync10(auditFile)) throw new Error("pi_trusted_runtime_audit_startup_missing");
6510
+ if (!existsSync11(auditFile)) throw new Error("pi_trusted_runtime_audit_startup_missing");
5990
6511
  const stat = lstatSync6(auditFile);
5991
6512
  if (!stat.isFile() || stat.isSymbolicLink()) {
5992
6513
  throw new Error("pi_trusted_runtime_audit_unsafe");
5993
6514
  }
5994
6515
  if (stat.size > MAX_AUDIT_BYTES) throw new Error("pi_trusted_runtime_audit_too_large");
5995
- const lines = readFileSync8(auditFile, "utf8").split("\n").filter(Boolean);
6516
+ const lines = readFileSync9(auditFile, "utf8").split("\n").filter(Boolean);
5996
6517
  if (lines.length === 0 || lines.length > MAX_AUDIT_EVENTS) {
5997
6518
  throw new Error("pi_trusted_runtime_audit_event_count_invalid");
5998
6519
  }
@@ -6049,11 +6570,11 @@ function readTrustedPiRuntimeLocalDigests(input) {
6049
6570
  throw new Error(`pi_trusted_runtime_source_unsafe:${label}`);
6050
6571
  }
6051
6572
  }
6052
- const seedManifestFile = join11(seedRoot, "seed-manifest.json");
6053
- const overlayManifestFile = join11(overlayRoot, "runtime-overlay-manifest.json");
6054
- const seedManifest = JSON.parse(readFileSync8(seedManifestFile, "utf8"));
6055
- const overlayManifest = JSON.parse(readFileSync8(overlayManifestFile, "utf8"));
6056
- const policyManifest = JSON.parse(readFileSync8(policyFile, "utf8"));
6573
+ const seedManifestFile = join12(seedRoot, "seed-manifest.json");
6574
+ const overlayManifestFile = join12(overlayRoot, "runtime-overlay-manifest.json");
6575
+ const seedManifest = JSON.parse(readFileSync9(seedManifestFile, "utf8"));
6576
+ const overlayManifest = JSON.parse(readFileSync9(overlayManifestFile, "utf8"));
6577
+ const policyManifest = JSON.parse(readFileSync9(policyFile, "utf8"));
6057
6578
  verifyDeclaredFiles(seedManifest, seedRoot, "seed", [
6058
6579
  "seed-manifest.json",
6059
6580
  "npm/package-lock.json",
@@ -6157,8 +6678,8 @@ function verifyTrustedPiRuntimeAssertion(input) {
6157
6678
  // src/amaster-runtime-daemon/workspace-status.mjs
6158
6679
  import { spawnSync as spawnSync4 } from "node:child_process";
6159
6680
  import { createHash as createHash8 } from "node:crypto";
6160
- import { existsSync as existsSync11, readdirSync as readdirSync7, readFileSync as readFileSync9, statSync as statSync6 } from "node:fs";
6161
- import { basename as basename5, extname, isAbsolute as isAbsolute7, join as join12, relative as relative7, resolve as resolve10 } from "node:path";
6681
+ import { existsSync as existsSync12, readdirSync as readdirSync8, readFileSync as readFileSync10, statSync as statSync6 } from "node:fs";
6682
+ import { basename as basename5, extname, isAbsolute as isAbsolute7, join as join13, relative as relative7, resolve as resolve10 } from "node:path";
6162
6683
  var WORKSPACE_RUNTIME_SERVICES_FILENAME = ".amaster-runtime-services.json";
6163
6684
  var ARTIFACT_EXTENSIONS = /* @__PURE__ */ new Map([
6164
6685
  [".md", "markdown"],
@@ -6227,7 +6748,7 @@ function sanitizeTrackedChange(line) {
6227
6748
  return isSafeRelativePath(path) ? line : null;
6228
6749
  }
6229
6750
  function sha256File2(filePath) {
6230
- return createHash8("sha256").update(readFileSync9(filePath)).digest("hex");
6751
+ return createHash8("sha256").update(readFileSync10(filePath)).digest("hex");
6231
6752
  }
6232
6753
  function artifactHashCacheKey(relativePath, stat) {
6233
6754
  return `${relativePath}\0${stat.size}\0${stat.mtimeMs}`;
@@ -6265,7 +6786,7 @@ function scanArtifactCandidates(cwd, opts = {}) {
6265
6786
  const current = stack.pop();
6266
6787
  let entries;
6267
6788
  try {
6268
- entries = readdirSync7(current, { withFileTypes: true });
6789
+ entries = readdirSync8(current, { withFileTypes: true });
6269
6790
  } catch {
6270
6791
  continue;
6271
6792
  }
@@ -6276,7 +6797,7 @@ function scanArtifactCandidates(cwd, opts = {}) {
6276
6797
  if (entry.name.startsWith(".") && entry.name !== ".amaster-runtime.json") {
6277
6798
  if (entry.name === ".git") continue;
6278
6799
  }
6279
- const fullPath = join12(current, entry.name);
6800
+ const fullPath = join13(current, entry.name);
6280
6801
  const relativePath = normalizeRelativePath(root, fullPath);
6281
6802
  if (!isSafeRelativePath(relativePath)) continue;
6282
6803
  if (basename5(relativePath) === ".amaster-runtime.json") continue;
@@ -6355,10 +6876,10 @@ function sanitizeRuntimeService(entry) {
6355
6876
  };
6356
6877
  }
6357
6878
  function readRuntimeServicesSnapshot(cwd) {
6358
- const snapshotPath = join12(resolve10(cwd), WORKSPACE_RUNTIME_SERVICES_FILENAME);
6359
- if (!existsSync11(snapshotPath)) return [];
6879
+ const snapshotPath = join13(resolve10(cwd), WORKSPACE_RUNTIME_SERVICES_FILENAME);
6880
+ if (!existsSync12(snapshotPath)) return [];
6360
6881
  try {
6361
- const parsed = JSON.parse(readFileSync9(snapshotPath, "utf8"));
6882
+ const parsed = JSON.parse(readFileSync10(snapshotPath, "utf8"));
6362
6883
  const rawServices = Array.isArray(parsed) ? parsed : Array.isArray(parsed?.services) ? parsed.services : [];
6363
6884
  return rawServices.map((entry) => sanitizeRuntimeService(entry)).filter((entry) => entry !== null).slice(0, 50);
6364
6885
  } catch {
@@ -7199,7 +7720,7 @@ async function executeSourceReadCommand(commandInput, dependencies = {}) {
7199
7720
  // src/amaster-runtime-daemon/browser-session-broker.mjs
7200
7721
  import { createHash as createHash11 } from "node:crypto";
7201
7722
  import { spawnSync as spawnSync5 } from "node:child_process";
7202
- import { existsSync as existsSync12 } from "node:fs";
7723
+ import { existsSync as existsSync13 } from "node:fs";
7203
7724
  import {
7204
7725
  chmod,
7205
7726
  lstat,
@@ -7211,7 +7732,7 @@ import {
7211
7732
  rm,
7212
7733
  writeFile
7213
7734
  } from "node:fs/promises";
7214
- import { join as join13, relative as relative8, resolve as resolve11, sep as sep2 } from "node:path";
7735
+ import { join as join14, relative as relative8, resolve as resolve11, sep as sep2 } from "node:path";
7215
7736
 
7216
7737
  // src/amaster-runtime-daemon/playwright-source-browser.mjs
7217
7738
  var LOGIN_CONTROL_SELECTORS = Object.freeze([
@@ -7403,7 +7924,7 @@ function sha2562(value) {
7403
7924
  return createHash11("sha256").update(value, "utf8").digest("hex");
7404
7925
  }
7405
7926
  function configuredBrowserExecutableReady(executablePath) {
7406
- if (!executablePath || !existsSync12(executablePath)) return false;
7927
+ if (!executablePath || !existsSync13(executablePath)) return false;
7407
7928
  const probe = spawnSync5(executablePath, ["--version"], {
7408
7929
  encoding: "utf8",
7409
7930
  env: { PATH: process.env.PATH ?? "" },
@@ -7462,7 +7983,7 @@ function assertWithinRoot(root, target) {
7462
7983
  }
7463
7984
  }
7464
7985
  async function readMarker(profilePath) {
7465
- const markerPath = join13(profilePath, MARKER_NAME);
7986
+ const markerPath = join14(profilePath, MARKER_NAME);
7466
7987
  const metadata = await pathStat(markerPath, true);
7467
7988
  if (!metadata || !metadata.isFile() || metadata.isSymbolicLink()) {
7468
7989
  fail3("browser_session_profile_owner_mismatch");
@@ -7489,7 +8010,7 @@ async function verifyOwnedProfile(root, profilePath, identity2) {
7489
8010
  return true;
7490
8011
  }
7491
8012
  async function writeMarker(profilePath, identity2) {
7492
- const markerPath = join13(profilePath, MARKER_NAME);
8013
+ const markerPath = join14(profilePath, MARKER_NAME);
7493
8014
  const temporaryPath = `${markerPath}.tmp-${process.pid}-${Date.now()}`;
7494
8015
  try {
7495
8016
  await writeFile(temporaryPath, `${JSON.stringify(expectedMarker(identity2))}
@@ -7503,7 +8024,7 @@ async function writeMarker(profilePath, identity2) {
7503
8024
  }
7504
8025
  }
7505
8026
  async function ensureOwnedProfile(root, identity2) {
7506
- const profilePath = join13(root, profileName(identity2));
8027
+ const profilePath = join14(root, profileName(identity2));
7507
8028
  const exists = await verifyOwnedProfile(root, profilePath, identity2);
7508
8029
  if (exists) return { profilePath, reusedProfile: true };
7509
8030
  await mkdir(profilePath, { mode: 448 });
@@ -7514,13 +8035,13 @@ async function ensureOwnedProfile(root, identity2) {
7514
8035
  }
7515
8036
  async function assertNoSymlinks(path) {
7516
8037
  for (const entry of await readdir(path, { withFileTypes: true })) {
7517
- const entryPath = join13(path, entry.name);
8038
+ const entryPath = join14(path, entry.name);
7518
8039
  if (entry.isSymbolicLink()) fail3("browser_session_profile_symlink_forbidden");
7519
8040
  if (entry.isDirectory()) await assertNoSymlinks(entryPath);
7520
8041
  }
7521
8042
  }
7522
8043
  async function removeOwnedProfile(root, identity2) {
7523
- const profilePath = join13(root, profileName(identity2));
8044
+ const profilePath = join14(root, profileName(identity2));
7524
8045
  if (!await verifyOwnedProfile(root, profilePath, identity2)) return false;
7525
8046
  await assertNoSymlinks(profilePath);
7526
8047
  await rm(profilePath, { recursive: true });
@@ -7569,7 +8090,7 @@ function createBrowserSessionBroker(options) {
7569
8090
  const cancelTimeout = typeof options.clearTimeout === "function" ? options.clearTimeout : clearTimeout;
7570
8091
  const rootPromise = (async () => {
7571
8092
  const stateRoot = await ensureProtectedDirectory(resolve11(options.stateRoot));
7572
- return ensureProtectedDirectory(join13(stateRoot, "browser-sessions"));
8093
+ return ensureProtectedDirectory(join14(stateRoot, "browser-sessions"));
7573
8094
  })();
7574
8095
  const sessions = /* @__PURE__ */ new Map();
7575
8096
  async function closeBinding(bindingId) {
@@ -7793,7 +8314,7 @@ function createBrowserSessionBroker(options) {
7793
8314
  }
7794
8315
  } else {
7795
8316
  const root = await rootPromise;
7796
- const profilePath = join13(root, profileName(input));
8317
+ const profilePath = join14(root, profileName(input));
7797
8318
  if (!await verifyOwnedProfile(root, profilePath, input)) {
7798
8319
  fail3("browser_session_profile_missing");
7799
8320
  }
@@ -7862,7 +8383,7 @@ function createBrowserSessionBroker(options) {
7862
8383
  }
7863
8384
  if (!browserExecutablePath && typeof playwright.chromium.executablePath === "function") {
7864
8385
  const executablePath = playwright.chromium.executablePath();
7865
- if (!executablePath || !existsSync12(executablePath)) {
8386
+ if (!executablePath || !existsSync13(executablePath)) {
7866
8387
  return { ready: false, reason: "chrome_unavailable" };
7867
8388
  }
7868
8389
  }
@@ -8145,7 +8666,7 @@ function createPublicNetworkScope(options = {}) {
8145
8666
  }
8146
8667
 
8147
8668
  // src/amaster-runtime-daemon.mjs
8148
- var CONNECTOR_VERSION = "0.1.0-beta.49";
8669
+ var CONNECTOR_VERSION = "0.1.0-beta.50";
8149
8670
  var CONNECTOR_CONTRACT_VERSION = "2026-06-04.v1";
8150
8671
  var MAX_CHECKPOINT_BYTES = 20 * 1024 * 1024;
8151
8672
  var CHECKPOINT_TTL_MS = 24 * 60 * 60 * 1e3;
@@ -8160,6 +8681,8 @@ var PI_COMPLETION_OUTPUT_TYPES = /* @__PURE__ */ new Set(["agent_end", "approval
8160
8681
  var PROCESS_GROUP_RSS_SAMPLE_MIN_INTERVAL_MS = 5e3;
8161
8682
  var activeRunCommands = /* @__PURE__ */ new Map();
8162
8683
  var pendingResultOutboxRunCommands = /* @__PURE__ */ new Map();
8684
+ var pendingRunCompletionCommands = /* @__PURE__ */ new Map();
8685
+ var runCompletionFlights = /* @__PURE__ */ new Map();
8163
8686
  var localDispatchCommandIds = /* @__PURE__ */ new Set();
8164
8687
  var workspaceStatusHashCache = /* @__PURE__ */ new Map();
8165
8688
  var processGroupRssSampleCache = null;
@@ -8194,9 +8717,9 @@ function configuredBrowserExecutablePath(config) {
8194
8717
  process.platform === "linux" ? "/usr/bin/google-chrome" : null,
8195
8718
  process.platform === "linux" ? "/usr/bin/chromium" : null,
8196
8719
  process.platform === "linux" ? "/usr/bin/chromium-browser" : null,
8197
- process.platform === "win32" && process.env.PROGRAMFILES ? join14(process.env.PROGRAMFILES, "Google", "Chrome", "Application", "chrome.exe") : null
8720
+ process.platform === "win32" && process.env.PROGRAMFILES ? join15(process.env.PROGRAMFILES, "Google", "Chrome", "Application", "chrome.exe") : null
8198
8721
  ].filter(Boolean);
8199
- return candidates.find((candidate) => existsSync13(candidate)) ?? explicit ?? null;
8722
+ return candidates.find((candidate) => existsSync14(candidate)) ?? explicit ?? null;
8200
8723
  }
8201
8724
  function runtimeBrowserSessionBroker(config) {
8202
8725
  const executablePath = configuredBrowserExecutablePath(config);
@@ -8243,11 +8766,11 @@ function updateActiveRunWorkspaceManifest(commandId, manifestPath, patch = {}) {
8243
8766
  }
8244
8767
  function resultOutboxPendingCount(config) {
8245
8768
  const dir = resultOutboxDir(config);
8246
- if (!existsSync13(dir)) return 0;
8769
+ if (!existsSync14(dir)) return 0;
8247
8770
  try {
8248
8771
  let pending = 0;
8249
- for (const file of readdirSync8(dir).filter((name) => name.endsWith(".json"))) {
8250
- if (readValidResultOutboxEntryOrQuarantine(config, file, join14(dir, file))) {
8772
+ for (const file of readdirSync9(dir).filter((name) => name.endsWith(".json"))) {
8773
+ if (readValidResultOutboxEntryOrQuarantine(config, file, join15(dir, file))) {
8251
8774
  pending += 1;
8252
8775
  }
8253
8776
  }
@@ -8256,6 +8779,63 @@ function resultOutboxPendingCount(config) {
8256
8779
  return 0;
8257
8780
  }
8258
8781
  }
8782
+ function runCompletionStateDir(config) {
8783
+ const explicit = readString(process.env.AMASTER_RUN_COMPLETION_STATE_DIR);
8784
+ if (explicit) return resolve12(expandHomePath(explicit));
8785
+ return join15(dirname9(stateFilePath(process.env)), "run-completion-state");
8786
+ }
8787
+ function runCompletionStateInvalidDir(config) {
8788
+ return join15(runCompletionStateDir(config), "invalid");
8789
+ }
8790
+ function quarantineInvalidRunCompletionState(config, filePath, reason) {
8791
+ const invalidDir = runCompletionStateInvalidDir(config);
8792
+ mkdirSync9(invalidDir, { recursive: true, mode: 448 });
8793
+ const destination = join15(invalidDir, basename6(filePath));
8794
+ try {
8795
+ renameSync6(filePath, destination);
8796
+ } catch {
8797
+ copyFileSync3(filePath, destination);
8798
+ unlinkSync2(filePath);
8799
+ }
8800
+ process.stderr.write(`AMaster daemon quarantined invalid run completion state ${basename6(filePath)}: ${reason}
8801
+ `);
8802
+ }
8803
+ function readValidRunCompletionStateOrQuarantine(config, filePath) {
8804
+ try {
8805
+ return readRunCompletionState(filePath);
8806
+ } catch (error) {
8807
+ quarantineInvalidRunCompletionState(
8808
+ config,
8809
+ filePath,
8810
+ error instanceof Error ? error.message : String(error)
8811
+ );
8812
+ return null;
8813
+ }
8814
+ }
8815
+ function runCompletionStateEntries(config) {
8816
+ return listRunCompletionStateFiles(runCompletionStateDir(config)).map((filePath) => ({ filePath, state: readValidRunCompletionStateOrQuarantine(config, filePath) })).filter((entry) => entry.state !== null);
8817
+ }
8818
+ function runCompletionStatePendingCount(config) {
8819
+ return runCompletionStateEntries(config).length;
8820
+ }
8821
+ function runCompletionStateActiveRunCommands(config) {
8822
+ const pending = runCompletionStatePendingCount(config);
8823
+ return runCompletionStateEntries(config).map(({ state }) => {
8824
+ const executor = asRecord(state.executor);
8825
+ const execution = asRecord(executor.closureExecution);
8826
+ const command = asRecord(state.command);
8827
+ return {
8828
+ commandId: state.commandId,
8829
+ ...readString(commandRunId(command)) ? { runId: readString(commandRunId(command)) } : {},
8830
+ ...readString(commandIssueId(command)) ? { issueId: readString(commandIssueId(command)) } : {},
8831
+ ...readString(executor.kind) ? { executorKind: readString(executor.kind) } : {},
8832
+ ...readString(execution.cwd) ? { workspacePath: readString(execution.cwd) } : {},
8833
+ phase: state.phase,
8834
+ outboxPending: pending,
8835
+ ...readString(state.updatedAt) ? { executorCompletedAt: readString(state.updatedAt) } : {}
8836
+ };
8837
+ });
8838
+ }
8259
8839
  function piCompletionOutputType(event) {
8260
8840
  const type = readString(asRecord(event).type);
8261
8841
  if (PI_COMPLETION_OUTPUT_TYPES.has(type ?? "")) return type;
@@ -8263,11 +8843,11 @@ function piCompletionOutputType(event) {
8263
8843
  }
8264
8844
  function resultOutboxActiveRunCommands(config) {
8265
8845
  const dir = resultOutboxDir(config);
8266
- if (!existsSync13(dir)) return [];
8846
+ if (!existsSync14(dir)) return [];
8267
8847
  const outboxPending = resultOutboxPendingCount(config);
8268
8848
  const entries = [];
8269
- for (const file of readdirSync8(dir).filter((name) => name.endsWith(".json")).sort()) {
8270
- const entry = readValidResultOutboxEntryOrQuarantine(config, file, join14(dir, file));
8849
+ for (const file of readdirSync9(dir).filter((name) => name.endsWith(".json")).sort()) {
8850
+ const entry = readValidResultOutboxEntryOrQuarantine(config, file, join15(dir, file));
8271
8851
  if (!entry) continue;
8272
8852
  const activeRun = asRecord(entry.activeRun);
8273
8853
  const commandId = readString(activeRun.commandId) ?? readString(entry.commandId);
@@ -8297,12 +8877,12 @@ function resultOutboxActiveRunCommands(config) {
8297
8877
  }
8298
8878
  function resultOutboxFailedRunCommands(config) {
8299
8879
  const dir = resultOutboxInvalidDir(config);
8300
- if (!existsSync13(dir)) return [];
8880
+ if (!existsSync14(dir)) return [];
8301
8881
  const entries = [];
8302
- for (const file of readdirSync8(dir).filter((name) => name.endsWith(".json")).sort().slice(-100)) {
8882
+ for (const file of readdirSync9(dir).filter((name) => name.endsWith(".json")).sort().slice(-100)) {
8303
8883
  let entry;
8304
8884
  try {
8305
- entry = asRecord(JSON.parse(readFileSync10(join14(dir, file), "utf8")));
8885
+ entry = asRecord(JSON.parse(readFileSync11(join15(dir, file), "utf8")));
8306
8886
  } catch {
8307
8887
  continue;
8308
8888
  }
@@ -8366,7 +8946,7 @@ function safeExpandPath(value) {
8366
8946
  }
8367
8947
  function safeJsonObjectFromFile(filePath) {
8368
8948
  try {
8369
- const parsed = JSON.parse(readFileSync10(filePath, "utf8"));
8949
+ const parsed = JSON.parse(readFileSync11(filePath, "utf8"));
8370
8950
  return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
8371
8951
  } catch {
8372
8952
  return null;
@@ -8383,7 +8963,7 @@ function safeDirectorySummary(pathValue) {
8383
8963
  }
8384
8964
  let entryCount = 0;
8385
8965
  let truncated = false;
8386
- for (const name of readdirSync8(pathValue)) {
8966
+ for (const name of readdirSync9(pathValue)) {
8387
8967
  if (name.startsWith(".")) continue;
8388
8968
  entryCount += 1;
8389
8969
  if (entryCount >= MAX_PI_CAPABILITY_SOURCE_ENTRIES) {
@@ -8407,12 +8987,12 @@ function safeSkillRootSummary(kind, source, pathValue) {
8407
8987
  let truncated = false;
8408
8988
  if (directory.available && pathValue) {
8409
8989
  try {
8410
- for (const name of readdirSync8(pathValue)) {
8990
+ for (const name of readdirSync9(pathValue)) {
8411
8991
  if (name.startsWith(".")) continue;
8412
- const skillDir = join14(pathValue, name);
8992
+ const skillDir = join15(pathValue, name);
8413
8993
  try {
8414
8994
  if (!statSync7(skillDir).isDirectory()) continue;
8415
- if (!existsSync13(join14(skillDir, "SKILL.md"))) continue;
8995
+ if (!existsSync14(join15(skillDir, "SKILL.md"))) continue;
8416
8996
  skillCount += 1;
8417
8997
  if (skillCount >= MAX_PI_CAPABILITY_SOURCE_ENTRIES) {
8418
8998
  truncated = true;
@@ -8463,7 +9043,7 @@ function objectKeyCount(value) {
8463
9043
  return value && typeof value === "object" && !Array.isArray(value) ? Object.keys(value).length : 0;
8464
9044
  }
8465
9045
  function defaultPiCodingAgentDir() {
8466
- return join14(homedir3(), ".pi", "agent");
9046
+ return join15(homedir3(), ".pi", "agent");
8467
9047
  }
8468
9048
  function piCapabilitySourcesDiagnostics() {
8469
9049
  const configuredPiCodingAgentDir = safeExpandPath(process.env.PI_CODING_AGENT_DIR);
@@ -8472,14 +9052,14 @@ function piCapabilitySourcesDiagnostics() {
8472
9052
  const configuredPiAgentHome = safeExpandPath(process.env.PI_AGENT_HOME);
8473
9053
  const piAgentHome = configuredPiAgentHome ?? piCodingAgentDir;
8474
9054
  const piAgentHomeSource = configuredPiAgentHome ? "PI_AGENT_HOME" : piCodingAgentDirSource;
8475
- const userSkillsPath = piAgentHome ? join14(piAgentHome, "skills") : null;
9055
+ const userSkillsPath = piAgentHome ? join15(piAgentHome, "skills") : null;
8476
9056
  const configuredMarketplaceSkillsPath = safeExpandPath(
8477
9057
  process.env.PI_AGENT_MARKETPLACE_SKILLS_DIR
8478
9058
  );
8479
- const marketplaceSkillsPath = configuredMarketplaceSkillsPath ?? (piAgentHome ? join14(piAgentHome, "marketplace", "skills") : null);
9059
+ const marketplaceSkillsPath = configuredMarketplaceSkillsPath ?? (piAgentHome ? join15(piAgentHome, "marketplace", "skills") : null);
8480
9060
  const builtinSkillsPath = safeExpandPath(process.env.PI_AGENT_BUILTIN_SKILLS_DIR) ?? safeExpandPath(process.env.AMASTER_BUILTIN_SKILLS);
8481
- const mcpConfigPath = safeExpandPath(process.env.PI_AGENT_MCP_SERVERS_FILE) ?? (piAgentHome ? join14(piAgentHome, "mcp.json") : null);
8482
- const settingsConfigPath = piCodingAgentDir ? join14(piCodingAgentDir, "settings.json") : null;
9061
+ const mcpConfigPath = safeExpandPath(process.env.PI_AGENT_MCP_SERVERS_FILE) ?? (piAgentHome ? join15(piAgentHome, "mcp.json") : null);
9062
+ const settingsConfigPath = piCodingAgentDir ? join15(piCodingAgentDir, "settings.json") : null;
8483
9063
  const skillRoots = [
8484
9064
  safeSkillRootSummary("user", `${piAgentHomeSource}/skills`, userSkillsPath),
8485
9065
  safeSkillRootSummary(
@@ -8664,6 +9244,8 @@ function buildHeartbeatPayload(config, options = {}) {
8664
9244
  ...Array.from(localDispatchCommandIds, (commandId) => ({ commandId, phase: "preparing" })),
8665
9245
  ...Array.from(activeRunCommands.values()),
8666
9246
  ...Array.from(pendingResultOutboxRunCommands.values()),
9247
+ ...Array.from(pendingRunCompletionCommands.values()),
9248
+ ...runCompletionStateActiveRunCommands(config),
8667
9249
  ...resultOutboxFailedRunCommands(config),
8668
9250
  ...resultOutboxActiveRunCommands(config)
8669
9251
  ]) {
@@ -8725,10 +9307,10 @@ function piAgentSystemDataDir(config) {
8725
9307
  return configured ? resolve12(expandHomePath(configured)) : null;
8726
9308
  }
8727
9309
  function readPiAgentLocalPlatformCredential(credentialsDir) {
8728
- const pointer = readJsonFile3(join14(credentialsDir, "latest.json"));
9310
+ const pointer = readJsonFile3(join15(credentialsDir, "latest.json"));
8729
9311
  const credentialRef = readString(pointer.credentialRef);
8730
9312
  if (!credentialRef || !/^[a-f0-9]{64}$/i.test(credentialRef)) return null;
8731
- const credential = readJsonFile3(join14(credentialsDir, `${credentialRef}.json`));
9313
+ const credential = readJsonFile3(join15(credentialsDir, `${credentialRef}.json`));
8732
9314
  const organizationId = readString(credential.organizationId);
8733
9315
  const apiKey = readString(credential.apiKey);
8734
9316
  if (credential.version !== 1 || !organizationId || !apiKey) return null;
@@ -8744,17 +9326,17 @@ function piAgentLocalPlatformCredentials(config) {
8744
9326
  if (!piAgentLocalPlatformRunnerEnabled(config)) return [];
8745
9327
  const systemDataDir = piAgentSystemDataDir(config);
8746
9328
  if (!systemDataDir) return [];
8747
- const companiesDir = join14(systemDataDir, "companies");
9329
+ const companiesDir = join15(systemDataDir, "companies");
8748
9330
  let entries = [];
8749
9331
  try {
8750
- entries = readdirSync8(companiesDir, { withFileTypes: true });
9332
+ entries = readdirSync9(companiesDir, { withFileTypes: true });
8751
9333
  } catch {
8752
9334
  return [];
8753
9335
  }
8754
9336
  const credentialsByOrganizationId = /* @__PURE__ */ new Map();
8755
9337
  for (const entry of entries) {
8756
9338
  if (!entry.isDirectory()) continue;
8757
- const credential = readPiAgentLocalPlatformCredential(join14(companiesDir, entry.name, "model-credentials"));
9339
+ const credential = readPiAgentLocalPlatformCredential(join15(companiesDir, entry.name, "model-credentials"));
8758
9340
  if (credential) credentialsByOrganizationId.set(credential.organizationId, credential);
8759
9341
  }
8760
9342
  return [...credentialsByOrganizationId.values()];
@@ -8928,7 +9510,7 @@ AMASTER_WORKSPACE_ALLOWLIST=${quoteShell(config.workspaceBindings.join(","))}
8928
9510
  AMASTER_EXECUTORS=${quoteShell(executorEnv)}
8929
9511
  AMASTER_CAPABILITIES=${quoteShell(config.capabilities.join(","))}
8930
9512
  AMASTER_NETWORK_DOMAINS=${quoteShell(config.networkDomains.join(","))}
8931
- AMASTER_DAEMON_STATE_FILE=${quoteShell(join14(homedir3(), ".amaster-employee", "runtime-connector-state.json"))}
9513
+ AMASTER_DAEMON_STATE_FILE=${quoteShell(join15(homedir3(), ".amaster-employee", "runtime-connector-state.json"))}
8932
9514
  EOF
8933
9515
 
8934
9516
  set -a
@@ -8982,17 +9564,19 @@ function maxConcurrentCommands(config) {
8982
9564
  const configured = Number(config.maxConcurrentCommands);
8983
9565
  return Number.isInteger(configured) && configured > 0 ? Math.min(configured, 50) : 1;
8984
9566
  }
8985
- function activeRunCommandCount(options = {}) {
9567
+ function activeRunCommandCount(config, options = {}) {
8986
9568
  const excludeCommandIds = new Set(readStringArray(options.excludeCommandIds));
8987
9569
  const commandIds = new Set([
8988
9570
  ...activeRunCommands.keys(),
8989
9571
  ...pendingResultOutboxRunCommands.keys(),
9572
+ ...pendingRunCompletionCommands.keys(),
9573
+ ...runCompletionStateEntries(config).map(({ state }) => state.commandId),
8990
9574
  ...localDispatchCommandIds
8991
9575
  ].filter((commandId) => !excludeCommandIds.has(commandId)));
8992
9576
  return commandIds.size;
8993
9577
  }
8994
9578
  function availableCommandSlots(config) {
8995
- return Math.max(0, maxConcurrentCommands(config) - activeRunCommandCount());
9579
+ return Math.max(0, maxConcurrentCommands(config) - activeRunCommandCount(config));
8996
9580
  }
8997
9581
  function rememberActiveRunCommand(command, metadata) {
8998
9582
  const commandId = readString(command.commandId) ?? readString(command.id);
@@ -9116,10 +9700,10 @@ function buildActiveRunCommandStatus(config, entry) {
9116
9700
  const base = {
9117
9701
  ...entry,
9118
9702
  phase: readString(entry.phase) ?? "executing",
9119
- managedWorkdirPresent: entry.workspacePath ? existsSync13(entry.workspacePath) : false,
9703
+ managedWorkdirPresent: entry.workspacePath ? existsSync14(entry.workspacePath) : false,
9120
9704
  outboxPending: resultOutboxPendingCount(config)
9121
9705
  };
9122
- if (!entry.workspacePath || !existsSync13(entry.workspacePath)) return base;
9706
+ if (!entry.workspacePath || !existsSync14(entry.workspacePath)) return base;
9123
9707
  const manifestPath = entry.manifestPath ?? workspaceManifestPath(entry.workspacePath);
9124
9708
  const status = readWorkspaceStatus(entry.workspacePath, { hashCache: workspaceStatusHashCache });
9125
9709
  const artifactCandidates = status.artifacts.slice(0, 20);
@@ -9300,7 +9884,7 @@ function trustedPiRuntimeSources(config) {
9300
9884
  }
9301
9885
  function readJsonFile3(filePath) {
9302
9886
  try {
9303
- const parsed = JSON.parse(readFileSync10(filePath, "utf8"));
9887
+ const parsed = JSON.parse(readFileSync11(filePath, "utf8"));
9304
9888
  return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
9305
9889
  } catch {
9306
9890
  return {};
@@ -9387,8 +9971,8 @@ async function materializeAgentInstructionsBundle(config, command, workspace) {
9387
9971
  if (!content) continue;
9388
9972
  const target = safeAgentInstructionMaterializationTarget(workspace, filePath);
9389
9973
  if (!target) continue;
9390
- mkdirSync8(dirname9(target.targetPath), { recursive: true });
9391
- writeFileSync8(target.targetPath, content, "utf8");
9974
+ mkdirSync9(dirname9(target.targetPath), { recursive: true });
9975
+ writeFileSync9(target.targetPath, content, "utf8");
9392
9976
  materialized.push({
9393
9977
  path: target.relativePath,
9394
9978
  byteSize: Buffer.byteLength(content, "utf8")
@@ -9459,14 +10043,14 @@ function companyPiHomeRoot(baseEnv) {
9459
10043
  const explicitRoot = readString(baseEnv.AMASTER_COMPANY_PI_HOME_ROOT);
9460
10044
  if (explicitRoot) return resolve12(expandHomePath(explicitRoot));
9461
10045
  const configuredPiHome = readString(baseEnv.PI_AGENT_HOME) ?? readString(baseEnv.PI_CODING_AGENT_DIR);
9462
- if (configuredPiHome) return join14(dirname9(resolve12(expandHomePath(configuredPiHome))), "companies");
9463
- return join14(homedir3(), ".amaster-employee", "companies");
10046
+ if (configuredPiHome) return join15(dirname9(resolve12(expandHomePath(configuredPiHome))), "companies");
10047
+ return join15(homedir3(), ".amaster-employee", "companies");
9464
10048
  }
9465
10049
  function companyPiAgentHome(baseEnv, companyId) {
9466
10050
  const rawCompanyId = readString(companyId);
9467
10051
  if (!rawCompanyId) return null;
9468
10052
  const segment = safeCompanyPiHomeSegment(rawCompanyId);
9469
- return join14(companyPiHomeRoot(baseEnv), segment, ".pi");
10053
+ return join15(companyPiHomeRoot(baseEnv), segment, ".pi");
9470
10054
  }
9471
10055
  function commandUsesPiExecutor(command) {
9472
10056
  return readString(asRecord(command.payload).executorKind) === "pi";
@@ -9534,7 +10118,7 @@ function resolveNativeSessionRequest(command, workspace) {
9534
10118
  let cwdMatched = false;
9535
10119
  if (requestedCwd && sourceWorkspacePath) {
9536
10120
  try {
9537
- cwdMatched = realpathSync4(requestedCwd) === realpathSync4(sourceWorkspacePath);
10121
+ cwdMatched = realpathSync5(requestedCwd) === realpathSync5(sourceWorkspacePath);
9538
10122
  } catch {
9539
10123
  cwdMatched = resolve12(requestedCwd) === resolve12(sourceWorkspacePath);
9540
10124
  }
@@ -9979,16 +10563,16 @@ function sampleProcessGroupRssBytes(processGroupId) {
9979
10563
  }
9980
10564
  function realOrResolvedPath(value) {
9981
10565
  try {
9982
- return realpathSync4(value);
10566
+ return realpathSync5(value);
9983
10567
  } catch {
9984
10568
  return resolve12(value);
9985
10569
  }
9986
10570
  }
9987
- var LSOF_COMMAND = process.platform === "darwin" && existsSync13("/usr/sbin/lsof") ? "/usr/sbin/lsof" : "lsof";
10571
+ var LSOF_COMMAND = process.platform === "darwin" && existsSync14("/usr/sbin/lsof") ? "/usr/sbin/lsof" : "lsof";
9988
10572
  function processCwdForPid(pid) {
9989
10573
  if (process.platform === "linux") {
9990
10574
  try {
9991
- return realpathSync4(`/proc/${pid}/cwd`);
10575
+ return realpathSync5(`/proc/${pid}/cwd`);
9992
10576
  } catch {
9993
10577
  return null;
9994
10578
  }
@@ -10010,7 +10594,7 @@ function allProcessCwdsByPid() {
10010
10594
  if (process.platform === "linux") {
10011
10595
  const procEntries = (() => {
10012
10596
  try {
10013
- return readdirSync8("/proc", { withFileTypes: true });
10597
+ return readdirSync9("/proc", { withFileTypes: true });
10014
10598
  } catch {
10015
10599
  return [];
10016
10600
  }
@@ -10106,21 +10690,21 @@ function killWorkspaceResidentProcesses(cwd, processGroupId, options = {}) {
10106
10690
  }
10107
10691
  function walkManagedWorkdirs(root) {
10108
10692
  const workdirs = [];
10109
- if (!root || !existsSync13(root)) return workdirs;
10693
+ if (!root || !existsSync14(root)) return workdirs;
10110
10694
  const stack = [root];
10111
10695
  while (stack.length > 0) {
10112
10696
  const current = stack.pop();
10113
10697
  if (!current) continue;
10114
10698
  let entries = [];
10115
10699
  try {
10116
- entries = readdirSync8(current, { withFileTypes: true });
10700
+ entries = readdirSync9(current, { withFileTypes: true });
10117
10701
  } catch {
10118
10702
  continue;
10119
10703
  }
10120
10704
  for (const entry of entries) {
10121
10705
  if (!entry.isDirectory()) continue;
10122
- const fullPath = join14(current, entry.name);
10123
- if (entry.name === "workdir" && existsSync13(workspaceManifestPath(fullPath))) {
10706
+ const fullPath = join15(current, entry.name);
10707
+ if (entry.name === "workdir" && existsSync14(workspaceManifestPath(fullPath))) {
10124
10708
  workdirs.push(fullPath);
10125
10709
  continue;
10126
10710
  }
@@ -10525,6 +11109,874 @@ async function ingestCost(config, command, executor, parsed) {
10525
11109
  costCents: parsedUsageCostCents(parsed.usage)
10526
11110
  });
10527
11111
  }
11112
+ function pendingRunCompletionSnapshot(config, state) {
11113
+ const command = asRecord(state.command);
11114
+ const executor = asRecord(state.executor);
11115
+ const execution = asRecord(executor.closureExecution);
11116
+ return {
11117
+ commandId: state.commandId,
11118
+ ...readString(commandRunId(command)) ? { runId: readString(commandRunId(command)) } : {},
11119
+ ...readString(commandIssueId(command)) ? { issueId: readString(commandIssueId(command)) } : {},
11120
+ ...readString(executor.kind) ? { executorKind: readString(executor.kind) } : {},
11121
+ ...readString(execution.cwd) ? { workspacePath: readString(execution.cwd) } : {},
11122
+ phase: state.phase,
11123
+ outboxPending: runCompletionStatePendingCount(config),
11124
+ ...readString(state.updatedAt) ? { executorCompletedAt: readString(state.updatedAt) } : {}
11125
+ };
11126
+ }
11127
+ function persistPendingRunCompletion(config, state) {
11128
+ writeRunCompletionState(runCompletionStateDir(config), state);
11129
+ pendingRunCompletionCommands.set(state.commandId, pendingRunCompletionSnapshot(config, state));
11130
+ return state;
11131
+ }
11132
+ function clearPendingRunCompletion(config, commandId) {
11133
+ removeRunCompletionState(runCompletionStateDir(config), commandId);
11134
+ pendingRunCompletionCommands.delete(commandId);
11135
+ }
11136
+ function completionCheckRetryable(error) {
11137
+ const status = Number(error?.httpStatus);
11138
+ const code = runtimeConnectorErrorCode(error) ?? readString(error?.code);
11139
+ if (code === "runtime_completion_check_response_invalid") return false;
11140
+ if (!Number.isInteger(status)) return true;
11141
+ if (status === 401 || status === 408 || status === 429 || status >= 500) return true;
11142
+ if (status !== 409) return false;
11143
+ return !code || [
11144
+ "runtime_completion_check_command_race",
11145
+ "runtime_completion_check_command_not_acknowledged"
11146
+ ].includes(code);
11147
+ }
11148
+ function runtimeConnectorErrorCode(error) {
11149
+ const body = asRecord(error?.responseBody);
11150
+ const details = asRecord(body.details);
11151
+ return readString(details.code) ?? readString(body.code);
11152
+ }
11153
+ function terminalCommandStatusFromCompletionCheckError(error) {
11154
+ if (runtimeConnectorErrorCode(error) !== "runtime_completion_check_command_not_acknowledged") {
11155
+ return null;
11156
+ }
11157
+ const details = asRecord(asRecord(error?.responseBody).details);
11158
+ const status = readString(details.status);
11159
+ return ["succeeded", "failed", "cancelled"].includes(status ?? "") ? status : null;
11160
+ }
11161
+ function managedMcpCleanupOwnerMismatch(error) {
11162
+ const message = error instanceof Error ? error.message : String(error);
11163
+ return /^(?:pi|codex)_managed_mcp_cleanup_owner_mismatch:/.test(message);
11164
+ }
11165
+ async function probeTerminalCommandAfterUnsafeCleanup(config, state) {
11166
+ const path = `/api/amaster/runtime-connectors/${state.connectorId}/commands/${state.commandId}/completion-check`;
11167
+ try {
11168
+ await postJson(config, path, runCompletionCheckRequest(state));
11169
+ return null;
11170
+ } catch (error) {
11171
+ const terminalStatus = terminalCommandStatusFromCompletionCheckError(error);
11172
+ if (terminalStatus) return terminalStatus;
11173
+ throw error;
11174
+ }
11175
+ }
11176
+ function runCompletionCheckRequest(state) {
11177
+ const prior = asRecord(state.completionRequest);
11178
+ return {
11179
+ contractVersion: "amaster.runtime-connector.completion-check.v1",
11180
+ ...readString(asRecord(state.command).leaseId) ? { leaseId: readString(asRecord(state.command).leaseId) } : {},
11181
+ proposedStatus: state.candidateStatus,
11182
+ resultSignals: {
11183
+ productiveSuccessfulRun: prior.resultSignals?.productiveSuccessfulRun === true,
11184
+ executorTurnCount: state.closureAttempt === 1 ? 2 : 1,
11185
+ closureAttempt: state.closureAttempt === 1 ? 1 : 0
11186
+ }
11187
+ };
11188
+ }
11189
+ function runCompletionCheckMaxAttempts() {
11190
+ return Math.max(1, Math.min(5, parsePositiveInteger(
11191
+ process.env.AMASTER_COMPLETION_CHECK_MAX_ATTEMPTS,
11192
+ 3
11193
+ )));
11194
+ }
11195
+ function runCompletionCheckRetryDelayMs() {
11196
+ return Math.max(0, Math.min(5e3, parseNonNegativeInteger(
11197
+ process.env.AMASTER_COMPLETION_CHECK_RETRY_DELAY_MS,
11198
+ 100
11199
+ )));
11200
+ }
11201
+ function runCompletionPhaseMaxAttempts() {
11202
+ return Math.max(1, Math.min(100, parsePositiveInteger(
11203
+ process.env.AMASTER_RUN_COMPLETION_PHASE_MAX_ATTEMPTS,
11204
+ 10
11205
+ )));
11206
+ }
11207
+ function runCompletionMaxAgeMs() {
11208
+ return parsePositiveInteger(
11209
+ process.env.AMASTER_RUN_COMPLETION_MAX_AGE_SECONDS,
11210
+ 7 * 24 * 60 * 60
11211
+ ) * 1e3;
11212
+ }
11213
+ function runCompletionStateAgeExceeded(state, nowMs = Date.now()) {
11214
+ const createdAtMs = Date.parse(readString(state.createdAt) ?? "");
11215
+ return Number.isFinite(createdAtMs) && nowMs - createdAtMs > runCompletionMaxAgeMs();
11216
+ }
11217
+ function runCompletionPhaseExhausted(state, nextAttemptCount) {
11218
+ return nextAttemptCount >= runCompletionPhaseMaxAttempts() || runCompletionStateAgeExceeded(state);
11219
+ }
11220
+ function failedRunCompletionCandidate(state, errorCode, message, evidence = {}) {
11221
+ return {
11222
+ candidateStatus: "failed",
11223
+ candidateError: message,
11224
+ candidateResult: {
11225
+ ...asRecord(state.candidateResult),
11226
+ errorCode,
11227
+ completionDeliveryFailure: {
11228
+ phase: state.phase,
11229
+ failedAt: (/* @__PURE__ */ new Date()).toISOString(),
11230
+ ...evidence
11231
+ }
11232
+ }
11233
+ };
11234
+ }
11235
+ async function requestRunCompletionCheck(config, inputState) {
11236
+ let state = inputState;
11237
+ if (state.phase === "usage_snapshot_persisted") {
11238
+ state = persistPendingRunCompletion(config, transitionRunCompletionState(
11239
+ state,
11240
+ "completion_check_requested",
11241
+ { completionRequest: runCompletionCheckRequest(state) }
11242
+ ));
11243
+ } else if (state.phase === "completion_check_outbox" || state.phase === "check_failed_retry") {
11244
+ state = persistPendingRunCompletion(config, transitionRunCompletionState(
11245
+ state,
11246
+ "completion_retry_scheduled",
11247
+ { completionRequest: runCompletionCheckRequest(state) }
11248
+ ));
11249
+ } else if (state.phase === "closure_executing") {
11250
+ state = persistPendingRunCompletion(config, {
11251
+ ...state,
11252
+ completionRequest: runCompletionCheckRequest(state),
11253
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
11254
+ });
11255
+ }
11256
+ if (state.phase !== "completion_check_pending" && state.phase !== "closure_executing") {
11257
+ throw new Error(`run_completion_check_phase_invalid:${state.phase}`);
11258
+ }
11259
+ const path = `/api/amaster/runtime-connectors/${state.connectorId}/commands/${state.commandId}/completion-check`;
11260
+ const maxAttempts = runCompletionCheckMaxAttempts();
11261
+ for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
11262
+ try {
11263
+ const response = asRecord(await postJson(config, path, runCompletionCheckRequest(state)));
11264
+ if (response.contractVersion !== "amaster.runtime-connector.completion-check.v1" || !["ready_to_terminalize", "disposition_required"].includes(response.outcome) || !["observe", "enforce"].includes(response.enforcementMode)) {
11265
+ const error = new Error("runtime_completion_check_response_invalid");
11266
+ error.code = "runtime_completion_check_response_invalid";
11267
+ throw error;
11268
+ }
11269
+ const event = response.outcome === "disposition_required" && response.enforcementMode === "enforce" ? "completion_disposition_required" : "completion_ready";
11270
+ state = transitionRunCompletionState(state, event, {
11271
+ completionResponse: response,
11272
+ candidateResult: {
11273
+ ...asRecord(state.candidateResult),
11274
+ completionObservation: {
11275
+ outcome: response.outcome,
11276
+ enforcementMode: response.enforcementMode,
11277
+ snapshotHash: readString(response.snapshotHash),
11278
+ ...readString(response.reasonCode) ? { reasonCode: readString(response.reasonCode) } : {}
11279
+ }
11280
+ }
11281
+ });
11282
+ return { pending: false, state: persistPendingRunCompletion(config, state) };
11283
+ } catch (error) {
11284
+ const terminalStatus = terminalCommandStatusFromCompletionCheckError(error);
11285
+ if (terminalStatus) {
11286
+ clearPendingRunCompletion(config, state.commandId);
11287
+ return { pending: false, state, serverTerminalStatus: terminalStatus };
11288
+ }
11289
+ if (!completionCheckRetryable(error)) {
11290
+ const message2 = error instanceof Error ? error.message : String(error);
11291
+ state = transitionRunCompletionState(state, "completion_authority_rejected", {
11292
+ candidateStatus: "failed",
11293
+ candidateError: message2,
11294
+ candidateResult: {
11295
+ ...asRecord(state.candidateResult),
11296
+ errorCode: runtimeConnectorErrorCode(error) ?? readString(error?.code) ?? "runtime_completion_check_authority_rejected",
11297
+ completionCheckAbort: {
11298
+ httpStatus: Number(error?.httpStatus) || null,
11299
+ reasonCode: runtimeConnectorErrorCode(error)
11300
+ }
11301
+ }
11302
+ });
11303
+ return { pending: false, state: persistPendingRunCompletion(config, state) };
11304
+ }
11305
+ const message = error instanceof Error ? error.message : String(error);
11306
+ const completionCheckAttemptCount = readNumber(state.completionCheckAttemptCount, 0) + 1;
11307
+ state = persistPendingRunCompletion(config, transitionRunCompletionState(
11308
+ state,
11309
+ "completion_check_failed",
11310
+ {
11311
+ lastCompletionCheckError: truncateText(message, 1e3),
11312
+ completionCheckAttemptCount
11313
+ }
11314
+ ));
11315
+ if (runCompletionPhaseExhausted(state, completionCheckAttemptCount)) {
11316
+ state = persistPendingRunCompletion(config, transitionRunCompletionState(
11317
+ state,
11318
+ "completion_retry_abandoned",
11319
+ {
11320
+ ...failedRunCompletionCandidate(
11321
+ state,
11322
+ "runtime_completion_check_retry_exhausted",
11323
+ `Completion check retry boundary exhausted: ${message}`,
11324
+ { attemptCount: completionCheckAttemptCount }
11325
+ ),
11326
+ completionCheckAbandonedAt: (/* @__PURE__ */ new Date()).toISOString()
11327
+ }
11328
+ ));
11329
+ process.stderr.write(`AMaster daemon abandoned completion check ${state.commandId} after ${completionCheckAttemptCount} durable attempt(s); terminalizing failed.
11330
+ `);
11331
+ return { pending: false, state };
11332
+ }
11333
+ if (attempt >= maxAttempts) {
11334
+ state = persistPendingRunCompletion(config, transitionRunCompletionState(
11335
+ state,
11336
+ "completion_retry_exhausted",
11337
+ { completionCheckOutboxQueuedAt: (/* @__PURE__ */ new Date()).toISOString() }
11338
+ ));
11339
+ process.stderr.write(`AMaster daemon queued completion check ${state.commandId} for durable retry after ${attempt} attempt(s): ${message}
11340
+ `);
11341
+ return { pending: true, state };
11342
+ }
11343
+ state = persistPendingRunCompletion(config, transitionRunCompletionState(
11344
+ state,
11345
+ "completion_retry_scheduled"
11346
+ ));
11347
+ const delayMs = runCompletionCheckRetryDelayMs();
11348
+ if (delayMs > 0) await new Promise((resolveDelay) => setTimeout(resolveDelay, delayMs));
11349
+ }
11350
+ }
11351
+ return { pending: true, state };
11352
+ }
11353
+ function runExitClosurePrompt(state) {
11354
+ const command = asRecord(state.command);
11355
+ const response = asRecord(state.completionResponse);
11356
+ const summary = truncateText(readString(asRecord(state.candidateResult).summary) ?? "", 1200);
11357
+ const issueId = commandIssueId(command) ?? "unknown";
11358
+ return [
11359
+ "# AMaster Run-Exit Disposition Closure",
11360
+ "This is a bounded status-only closure turn for the same command and heartbeat run.",
11361
+ `Issue: ${issueId}`,
11362
+ `Completion reason: ${readString(response.reasonCode) ?? "successful_run_missing_state"}`,
11363
+ summary ? `Primary turn summary: ${summary}` : null,
11364
+ "Do not perform more business work, edit files, create artifacts/documents/children/plans, or mutate company/profile/milestone state.",
11365
+ "Use exactly one runtime_action.submit mutation. Choose update_parent, create_interaction (not suggest_tasks), or add_comment only when a comment is truly the intended exit path.",
11366
+ "A comment alone does not establish completion. Prefer update_parent with the truthful done, blocked, review/input, or todo-continuation state.",
11367
+ `The idempotencyKey must be runtime-command-closure:${state.commandId}.`,
11368
+ "Do not call runtime_action.plan or runtime_action.commit. Stop immediately after the one allowed mutation returns."
11369
+ ].filter(Boolean).join("\n\n");
11370
+ }
11371
+ function parseExecutorTurnOutput(executorKind, execution, liveOutputLogger, hasOutputFlood) {
11372
+ const parsed = hasOutputFlood ? {
11373
+ sessionId: null,
11374
+ summary: "",
11375
+ usage: { inputTokens: 0, cachedInputTokens: 0, outputTokens: 0 },
11376
+ errorMessage: null
11377
+ } : executorKind === "codex" ? parseCodexJsonl(execution.stdout) : executorKind === "claude" ? parseClaudeStreamJson(execution.stdout) : executorKind === "opencode" ? parseOpenCodeJsonl(execution.stdout) : executorKind === "pi" ? parsePiJsonl(execution.stdout) : parseGenericOutput(execution.stdout, execution.stderr);
11378
+ parsed.sessionId ??= liveOutputLogger.sessionId();
11379
+ const liveTerminalOutput = executorKind === "pi" && !hasOutputFlood ? liveOutputLogger.terminalOutput() : null;
11380
+ if (liveTerminalOutput) {
11381
+ const parsedUsage = asRecord(parsed.usage);
11382
+ const liveUsage = asRecord(liveTerminalOutput.usage);
11383
+ parsed.summary = liveTerminalOutput.summary;
11384
+ parsed.hasAssistantOutput = true;
11385
+ parsed.usage = {
11386
+ inputTokens: readNumber(liveUsage.inputTokens, 0) || readNumber(parsedUsage.inputTokens, 0),
11387
+ cachedInputTokens: readNumber(liveUsage.cachedInputTokens, 0) || readNumber(parsedUsage.cachedInputTokens, 0),
11388
+ outputTokens: readNumber(liveUsage.outputTokens, 0) || readNumber(parsedUsage.outputTokens, 0),
11389
+ ...readNumber(liveUsage.costUsd, 0) > 0 || readNumber(parsedUsage.costUsd, 0) > 0 ? { costUsd: readNumber(liveUsage.costUsd, 0) || readNumber(parsedUsage.costUsd, 0) } : {}
11390
+ };
11391
+ }
11392
+ return parsed;
11393
+ }
11394
+ async function executeRunExitClosureTurn(config, inputState, options = {}) {
11395
+ const state = inputState;
11396
+ const command = asRecord(state.command);
11397
+ const executor = asRecord(state.executor);
11398
+ const executionConfig = asRecord(executor.closureExecution);
11399
+ const executorKind = readString(executor.kind);
11400
+ const executable = readString(executionConfig.command);
11401
+ const cwd = readString(executionConfig.cwd);
11402
+ if (!executorKind || !executable || !cwd) {
11403
+ throw new Error("run_exit_closure_execution_context_missing");
11404
+ }
11405
+ const args = Array.isArray(executionConfig.args) ? executionConfig.args.map(String) : [];
11406
+ const env = Object.fromEntries(Object.entries(asRecord(executionConfig.env)).map(([key, value]) => [key, String(value)]));
11407
+ const protectedValues = Array.isArray(executionConfig.protectedValues) ? executionConfig.protectedValues.filter((value) => typeof value === "string" && value) : [];
11408
+ const storedSpawnIdentity = asRecord(executionConfig.spawnIdentity);
11409
+ let reservedPiAssignment = false;
11410
+ const piAllocator = executorKind === "pi" && readNumber(storedSpawnIdentity.uid, 0) > 0 ? configuredPiChildIdentityAllocator(config) : null;
11411
+ if (piAllocator) {
11412
+ const assignment = piAllocator.acquire(commandRunId(command), {
11413
+ ...readNumber(storedSpawnIdentity.gid, 0) > 0 ? { gid: readNumber(storedSpawnIdentity.gid, 0) } : {}
11414
+ });
11415
+ if (assignment.uid !== readNumber(storedSpawnIdentity.uid, 0)) {
11416
+ piAllocator.release(commandRunId(command));
11417
+ throw new Error("run_exit_closure_pi_identity_changed");
11418
+ }
11419
+ reservedPiAssignment = true;
11420
+ }
11421
+ let forgetTrackedRun = () => {
11422
+ };
11423
+ let stopTrackedHeartbeats = () => {
11424
+ };
11425
+ let signal = options.signal;
11426
+ if (!signal) {
11427
+ forgetTrackedRun = rememberActiveRunCommand(command, {
11428
+ executorKind,
11429
+ workspacePath: cwd,
11430
+ sourceWorkspacePath: readString(executionConfig.sourceWorkspacePath),
11431
+ managedWorkdir: executionConfig.managedWorkdir === true,
11432
+ manifestPath: readString(executionConfig.manifestPath)
11433
+ });
11434
+ const controller = new AbortController();
11435
+ signal = controller.signal;
11436
+ stopTrackedHeartbeats = startActiveRunHeartbeats(config, command, controller);
11437
+ }
11438
+ const liveOutputLogger = createLiveOutputLogger(
11439
+ config,
11440
+ command,
11441
+ executorKind,
11442
+ protectedValues
11443
+ );
11444
+ try {
11445
+ await ingestLog(config, command, "system", "info", "Starting bounded run-exit disposition closure turn", {
11446
+ presentationKind: "run_exit_disposition_closure",
11447
+ commandId: state.commandId,
11448
+ closureAttempt: 1
11449
+ });
11450
+ let execution;
11451
+ try {
11452
+ execution = await runExecutor(executable, args, {
11453
+ cwd,
11454
+ env,
11455
+ stdin: runExitClosurePrompt(state),
11456
+ timeoutSeconds: Math.max(1, readNumber(executionConfig.timeoutSeconds, config.executorTimeoutSeconds)),
11457
+ maxOutputBytes: Math.max(1, readNumber(executionConfig.maxOutputBytes, config.executorMaxOutputBytes)),
11458
+ maxRssMb: Math.max(0, readNumber(executionConfig.maxRssMb, config.executorMaxRssMb)),
11459
+ signal,
11460
+ executorKind,
11461
+ ...readNumber(storedSpawnIdentity.uid, 0) > 0 ? { spawnIdentity: storedSpawnIdentity } : {},
11462
+ ...readString(executionConfig.managedInput) ? { managedInput: readString(executionConfig.managedInput) } : {},
11463
+ onOutput: (stream, chunk, rawBytes) => {
11464
+ noteActiveRunOutput(command, stream, chunk, rawBytes);
11465
+ liveOutputLogger.write(stream, chunk);
11466
+ }
11467
+ });
11468
+ } finally {
11469
+ await liveOutputLogger.flush();
11470
+ }
11471
+ execution.stdout = redactProtectedText(execution.stdout, protectedValues);
11472
+ execution.stderr = redactProtectedText(execution.stderr, protectedValues);
11473
+ const outputFlood = asRecord(execution.outputFlood);
11474
+ const hasOutputFlood = Boolean(readString(outputFlood.stream) && readNumber(outputFlood.bytes, 0) > 0);
11475
+ const memoryLimit = asRecord(execution.memoryLimit);
11476
+ const hasMemoryLimit = readNumber(memoryLimit.rssBytes, 0) > 0;
11477
+ const parsed = parseExecutorTurnOutput(executorKind, execution, liveOutputLogger, hasOutputFlood);
11478
+ const outputTelemetry = liveOutputLogger.snapshot({
11479
+ outputBytes: execution.outputBytes,
11480
+ floodLimitBytes: Math.max(1, readNumber(executionConfig.maxOutputBytes, config.executorMaxOutputBytes)),
11481
+ outputTokens: readNumber(parsed.usage?.outputTokens, 0)
11482
+ });
11483
+ const completionOutputStopped = executorKind === "pi" && piCompletionOutputStopped(parsed, execution);
11484
+ const cleanupDisposition = executorKind === "pi" && execution.cancelled !== true && !hasOutputFlood && !hasMemoryLimit && execution.timedOut !== true && !execution.spawnError && execution.signal === null ? classifyPiTerminalCleanupDisposition(parsed, []) : null;
11485
+ const parsedForValidation = cleanupDisposition ? { ...parsed, errorMessage: null } : parsed;
11486
+ const piInvalidOutputError = executorKind === "pi" ? piOutputValidationError(parsedForValidation, {
11487
+ allowMissingTurnEnd: completionOutputStopped || Boolean(cleanupDisposition),
11488
+ allowMissingAssistantOutput: false
11489
+ }) : null;
11490
+ const parsedError = hasOutputFlood ? "Run-exit closure output exceeded the configured limit" : hasMemoryLimit ? "Run-exit closure exceeded the configured memory limit" : execution.timedOut ? "Run-exit closure timed out" : execution.spawnError ?? piInvalidOutputError ?? parsedForValidation.errorMessage ?? ((execution.exitCode ?? 0) === 0 ? null : `Run-exit closure exited with code ${execution.exitCode ?? "unknown"}`);
11491
+ const succeeded = execution.cancelled !== true && !hasOutputFlood && !hasMemoryLimit && (execution.exitCode === 0 || completionOutputStopped || Boolean(cleanupDisposition)) && !execution.timedOut && !execution.spawnError && !parsedError;
11492
+ const mcpToolResults = dedupeGovernedMcpToolResults([
11493
+ ...Array.isArray(parsed.mcpToolResults) ? parsed.mcpToolResults.map(asRecord) : [],
11494
+ ...liveOutputLogger.mcpToolResults().map(asRecord)
11495
+ ]);
11496
+ await ingestLog(config, command, "system", succeeded ? "info" : "error", succeeded ? "Run-exit disposition closure turn completed" : `Run-exit disposition closure turn failed: ${parsedError}`, {
11497
+ presentationKind: "run_exit_disposition_closure",
11498
+ closureAttempt: 1,
11499
+ succeeded,
11500
+ outputTelemetry,
11501
+ toolResultCount: mcpToolResults.length
11502
+ });
11503
+ return {
11504
+ succeeded,
11505
+ error: parsedError,
11506
+ usage: asRecord(parsed.usage),
11507
+ audit: {
11508
+ schemaVersion: "run-exit-disposition-closure-v1",
11509
+ attempt: 1,
11510
+ succeeded,
11511
+ exitCode: execution.exitCode,
11512
+ signal: execution.signal,
11513
+ timedOut: execution.timedOut,
11514
+ summary: truncateText(readString(parsed.summary) ?? "", 2e3),
11515
+ outputTelemetry,
11516
+ toolResults: mcpToolResults.slice(0, 10).map((result3) => ({
11517
+ status: readString(result3.status),
11518
+ toolName: readString(result3.toolName) ?? readString(result3.name) ?? readString(asRecord(result3.runtimeAction).toolName),
11519
+ invocationId: readString(result3.invocationId)
11520
+ })),
11521
+ ...parsedError ? { error: truncateText(parsedError, 1e3) } : {}
11522
+ }
11523
+ };
11524
+ } finally {
11525
+ stopTrackedHeartbeats();
11526
+ forgetTrackedRun();
11527
+ if (reservedPiAssignment) piAllocator.release(commandRunId(command));
11528
+ }
11529
+ }
11530
+ function runCompletionUsageResult(state) {
11531
+ const aggregate = asRecord(asRecord(state.usageRecord).aggregate);
11532
+ const costUsd = readNumber(aggregate.costUsd, 0);
11533
+ return {
11534
+ inputTokens: readNumber(aggregate.inputTokens, 0),
11535
+ cachedInputTokens: readNumber(aggregate.cachedInputTokens, 0),
11536
+ outputTokens: readNumber(aggregate.outputTokens, 0),
11537
+ ...costUsd > 0 ? { costUsd } : {}
11538
+ };
11539
+ }
11540
+ async function ingestRunCompletionAggregateCost(config, state) {
11541
+ const command = asRecord(state.command);
11542
+ const payload = asRecord(command.payload);
11543
+ const companyId = readString(payload.companyId);
11544
+ const agentId = readString(payload.agentId);
11545
+ if (!companyId || !agentId) {
11546
+ return { accepted: true, skipped: true, reason: "cost_attribution_missing" };
11547
+ }
11548
+ const executor = asRecord(state.executor);
11549
+ const aggregate = asRecord(asRecord(state.usageRecord).aggregate);
11550
+ const response = asRecord(await postJson(
11551
+ config,
11552
+ `/api/amaster/runtime-connectors/${state.connectorId}/ingest/cost`,
11553
+ {
11554
+ commandId: state.commandId,
11555
+ idempotencyKey: readString(asRecord(state.usageRecord).idempotencyKey),
11556
+ companyId,
11557
+ agentId,
11558
+ issueId: commandIssueId(command) ?? void 0,
11559
+ runId: commandRunId(command) ?? void 0,
11560
+ provider: readString(executor.kind) ?? "runtime_connector",
11561
+ biller: readString(executor.kind) === "codex" ? "chatgpt" : "runtime_connector",
11562
+ billingType: "unknown",
11563
+ model: readString(executor.model) ?? readString(executor.kind) ?? "runtime_connector",
11564
+ inputTokens: readNumber(aggregate.inputTokens, 0),
11565
+ cachedInputTokens: readNumber(aggregate.cachedInputTokens, 0),
11566
+ outputTokens: readNumber(aggregate.outputTokens, 0),
11567
+ costCents: readNumber(aggregate.costCents, 0),
11568
+ occurredAt: readString(state.createdAt) ?? (/* @__PURE__ */ new Date()).toISOString()
11569
+ }
11570
+ ));
11571
+ if (response.accepted !== true || !readString(response.costEventId)) {
11572
+ throw new Error("runtime_completion_cost_receipt_invalid");
11573
+ }
11574
+ return response;
11575
+ }
11576
+ async function cleanupRunCompletionProfile(config, state) {
11577
+ const command = asRecord(state.command);
11578
+ const executor = asRecord(state.executor);
11579
+ const managedMcp = asRecord(executor.managedMcp);
11580
+ const profileRoot = readString(managedMcp.profileRoot);
11581
+ if (!profileRoot) return { status: "not_configured" };
11582
+ const cleanup = readString(executor.kind) === "pi" ? cleanupManagedPiMcpProfile : cleanupManagedCodexMcpProfile;
11583
+ const result3 = cleanup({ profileRoot }, {
11584
+ commandId: state.commandId,
11585
+ runId: commandRunId(command)
11586
+ });
11587
+ await ingestLog(config, command, "system", "info", "Cleaned managed MCP profile after run completion gate", {
11588
+ presentationKind: "managed_mcp_cleanup",
11589
+ status: readString(result3?.status) ?? "removed"
11590
+ });
11591
+ return result3;
11592
+ }
11593
+ function queueRunCompletionResultOutbox(config, state, payload, error) {
11594
+ const path = `/api/amaster/runtime-connectors/${state.connectorId}/commands/${state.commandId}/result`;
11595
+ writeResultOutboxEntry(config, {
11596
+ connectorId: state.connectorId,
11597
+ commandId: state.commandId,
11598
+ path,
11599
+ payload,
11600
+ activeRun: pendingRunCompletionSnapshot(config, state)
11601
+ });
11602
+ pendingResultOutboxRunCommands.set(state.commandId, {
11603
+ ...pendingRunCompletionSnapshot(config, state),
11604
+ phase: "result_outbox",
11605
+ outboxQueuedAt: (/* @__PURE__ */ new Date()).toISOString()
11606
+ });
11607
+ clearPendingRunCompletion(config, state.commandId);
11608
+ const message = error instanceof Error ? error.message : String(error);
11609
+ process.stderr.write(`AMaster daemon queued terminal result ${state.commandId} after result POST failed: ${message}
11610
+ `);
11611
+ }
11612
+ async function finalizeRunCompletionState(config, inputState) {
11613
+ let state = inputState;
11614
+ if (state.phase === "ready_to_terminalize") {
11615
+ state = persistPendingRunCompletion(config, transitionRunCompletionState(
11616
+ state,
11617
+ "cost_ingest_started"
11618
+ ));
11619
+ }
11620
+ if (state.phase === "cost_ingest_pending") {
11621
+ try {
11622
+ const receipt = await ingestRunCompletionAggregateCost(config, state);
11623
+ const aggregateUsage = runCompletionUsageResult(state);
11624
+ const aggregate = asRecord(asRecord(state.usageRecord).aggregate);
11625
+ state = markRunCompletionCostDelivered({
11626
+ ...state,
11627
+ candidateResult: {
11628
+ ...asRecord(state.candidateResult),
11629
+ usage: aggregateUsage,
11630
+ usageBreakdown: Array.isArray(asRecord(state.usageRecord).turns) ? asRecord(state.usageRecord).turns : [],
11631
+ costUsage: {
11632
+ idempotencyKey: readString(asRecord(state.usageRecord).idempotencyKey),
11633
+ ...readString(receipt.costEventId) ? { costEventId: readString(receipt.costEventId) } : {},
11634
+ ...aggregateUsage,
11635
+ costCents: readNumber(aggregate.costCents, 0)
11636
+ }
11637
+ }
11638
+ }, receipt);
11639
+ state = persistPendingRunCompletion(config, state);
11640
+ } catch (error) {
11641
+ const message = truncateText(error instanceof Error ? error.message : String(error), 1e3);
11642
+ const costIngestAttemptCount = readNumber(state.costIngestAttemptCount, 0) + 1;
11643
+ if (!runCompletionPhaseExhausted(state, costIngestAttemptCount)) {
11644
+ state = persistPendingRunCompletion(config, {
11645
+ ...state,
11646
+ costIngestAttemptCount,
11647
+ lastCostIngestError: message,
11648
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
11649
+ });
11650
+ process.stderr.write(`AMaster daemon retained cost_ingest_pending state for ${state.commandId}: ${state.lastCostIngestError}
11651
+ `);
11652
+ return { pending: true, resultDelivered: false, state };
11653
+ }
11654
+ const usageRecord = asRecord(state.usageRecord);
11655
+ state = persistPendingRunCompletion(config, transitionRunCompletionState(
11656
+ {
11657
+ ...state,
11658
+ usageRecord: {
11659
+ ...usageRecord,
11660
+ ingestStatus: "failed",
11661
+ failedAt: (/* @__PURE__ */ new Date()).toISOString(),
11662
+ failure: { message, attemptCount: costIngestAttemptCount }
11663
+ }
11664
+ },
11665
+ "cost_ingest_abandoned",
11666
+ {
11667
+ ...failedRunCompletionCandidate(
11668
+ state,
11669
+ "runtime_completion_cost_retry_exhausted",
11670
+ `Cost ingestion retry boundary exhausted: ${message}`,
11671
+ { attemptCount: costIngestAttemptCount }
11672
+ ),
11673
+ costIngestAttemptCount,
11674
+ lastCostIngestError: message
11675
+ }
11676
+ ));
11677
+ process.stderr.write(`AMaster daemon abandoned cost ingestion ${state.commandId} after ${costIngestAttemptCount} attempt(s); continuing failed terminalization.
11678
+ `);
11679
+ }
11680
+ }
11681
+ if (state.phase === "profile_cleanup") {
11682
+ try {
11683
+ const cleanup = await cleanupRunCompletionProfile(config, state);
11684
+ state = transitionRunCompletionState(state, "profile_cleaned", {
11685
+ managedMcpCleanup: cleanup,
11686
+ candidateResult: {
11687
+ ...asRecord(state.candidateResult),
11688
+ ...Object.keys(asRecord(asRecord(state.candidateResult).managedMcp)).length > 0 ? {
11689
+ managedMcp: {
11690
+ ...asRecord(asRecord(state.candidateResult).managedMcp),
11691
+ cleanup
11692
+ }
11693
+ } : {}
11694
+ }
11695
+ });
11696
+ state = persistPendingRunCompletion(config, state);
11697
+ } catch (error) {
11698
+ const cleanupError = truncateText(error instanceof Error ? error.message : String(error), 1e3);
11699
+ if (managedMcpCleanupOwnerMismatch(error)) {
11700
+ try {
11701
+ const terminalStatus = await probeTerminalCommandAfterUnsafeCleanup(config, state);
11702
+ if (terminalStatus) {
11703
+ const cleanup2 = {
11704
+ status: "unsafe_residual_preserved",
11705
+ reason: "server_command_already_terminal",
11706
+ serverCommandStatus: terminalStatus
11707
+ };
11708
+ await ingestLog(
11709
+ config,
11710
+ asRecord(state.command),
11711
+ "system",
11712
+ "warn",
11713
+ "Preserved unsafe managed MCP residual after server terminalization",
11714
+ {
11715
+ presentationKind: "managed_mcp_cleanup",
11716
+ status: cleanup2.status,
11717
+ serverCommandStatus: terminalStatus,
11718
+ cleanupError
11719
+ }
11720
+ );
11721
+ process.stderr.write(`AMaster daemon preserved unsafe managed MCP residual after server terminalization for ${state.commandId}; durable completion state was released without deleting the unowned path.
11722
+ `);
11723
+ clearPendingRunCompletion(config, state.commandId);
11724
+ return {
11725
+ pending: false,
11726
+ resultDelivered: true,
11727
+ state: {
11728
+ ...state,
11729
+ lastProfileCleanupError: cleanupError,
11730
+ managedMcpCleanup: cleanup2
11731
+ },
11732
+ managedMcpCleanup: cleanup2
11733
+ };
11734
+ }
11735
+ } catch (probeError) {
11736
+ state = {
11737
+ ...state,
11738
+ lastProfileCleanupProbeError: truncateText(
11739
+ probeError instanceof Error ? probeError.message : String(probeError),
11740
+ 1e3
11741
+ )
11742
+ };
11743
+ }
11744
+ }
11745
+ const profileCleanupAttemptCount = readNumber(state.profileCleanupAttemptCount, 0) + 1;
11746
+ if (!runCompletionPhaseExhausted(state, profileCleanupAttemptCount)) {
11747
+ state = persistPendingRunCompletion(config, {
11748
+ ...state,
11749
+ profileCleanupAttemptCount,
11750
+ lastProfileCleanupError: cleanupError,
11751
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
11752
+ });
11753
+ process.stderr.write(`AMaster daemon retained profile_cleanup state for ${state.commandId}: ${state.lastProfileCleanupError}
11754
+ `);
11755
+ return { pending: true, resultDelivered: false, state };
11756
+ }
11757
+ const cleanup = {
11758
+ status: "unsafe_residual_preserved",
11759
+ reason: "cleanup_retry_exhausted",
11760
+ attemptCount: profileCleanupAttemptCount,
11761
+ error: cleanupError
11762
+ };
11763
+ state = persistPendingRunCompletion(config, transitionRunCompletionState(
11764
+ state,
11765
+ "profile_cleanup_abandoned",
11766
+ {
11767
+ ...failedRunCompletionCandidate(
11768
+ state,
11769
+ "runtime_completion_profile_cleanup_retry_exhausted",
11770
+ `Managed MCP cleanup retry boundary exhausted: ${cleanupError}`,
11771
+ { attemptCount: profileCleanupAttemptCount, residualPreserved: true }
11772
+ ),
11773
+ profileCleanupAttemptCount,
11774
+ lastProfileCleanupError: cleanupError,
11775
+ managedMcpCleanup: cleanup
11776
+ }
11777
+ ));
11778
+ process.stderr.write(`AMaster daemon preserved managed MCP residual for ${state.commandId} after ${profileCleanupAttemptCount} failed cleanup attempt(s); continuing failed terminalization.
11779
+ `);
11780
+ }
11781
+ }
11782
+ if (state.phase !== "result_post_pending") {
11783
+ throw new Error(`run_completion_finalize_phase_invalid:${state.phase}`);
11784
+ }
11785
+ const path = `/api/amaster/runtime-connectors/${state.connectorId}/commands/${state.commandId}/result`;
11786
+ const leaseId = readString(asRecord(state.command).leaseId);
11787
+ let payload = {
11788
+ ...leaseId ? { leaseId } : {},
11789
+ status: state.candidateStatus,
11790
+ result: asRecord(state.candidateResult),
11791
+ ...readString(state.candidateError) ? { error: truncateText(state.candidateError, 4e3) } : {}
11792
+ };
11793
+ try {
11794
+ await postJson(config, path, payload);
11795
+ } catch (error) {
11796
+ if (runtimeConnectorErrorCode(error) === "runtime_completion_disposition_required") {
11797
+ const raceMessage = "Run-exit disposition changed after profile cleanup; command failed closed";
11798
+ payload = {
11799
+ ...payload,
11800
+ status: "failed",
11801
+ error: raceMessage,
11802
+ result: {
11803
+ ...payload.result,
11804
+ errorCode: "runtime_completion_terminalization_race",
11805
+ completionGateRace: {
11806
+ failedClosed: true,
11807
+ detectedAt: (/* @__PURE__ */ new Date()).toISOString()
11808
+ }
11809
+ }
11810
+ };
11811
+ try {
11812
+ await postJson(config, path, payload);
11813
+ } catch (abortError) {
11814
+ queueRunCompletionResultOutbox(config, state, payload, abortError);
11815
+ return { pending: false, resultDelivered: false, outboxed: true, state };
11816
+ }
11817
+ } else {
11818
+ queueRunCompletionResultOutbox(config, state, payload, error);
11819
+ return { pending: false, resultDelivered: false, outboxed: true, state };
11820
+ }
11821
+ }
11822
+ state = transitionRunCompletionState(state, "result_post_delivered");
11823
+ clearPendingRunCompletion(config, state.commandId);
11824
+ return {
11825
+ pending: false,
11826
+ resultDelivered: true,
11827
+ state,
11828
+ managedMcpCleanup: asRecord(state.managedMcpCleanup)
11829
+ };
11830
+ }
11831
+ async function coordinateRunCompletion(config, inputState, options = {}) {
11832
+ let state = inputState;
11833
+ if (["ready_to_terminalize", "cost_ingest_pending", "profile_cleanup", "result_post_pending"].includes(state.phase)) {
11834
+ return finalizeRunCompletionState(config, state);
11835
+ }
11836
+ const recoveringClosure = state.phase === "closure_executing";
11837
+ let checked = state.phase === "disposition_required" ? { pending: false, state } : await requestRunCompletionCheck(config, state);
11838
+ state = checked.state;
11839
+ if (checked.serverTerminalStatus) {
11840
+ return {
11841
+ pending: false,
11842
+ resultDelivered: true,
11843
+ state,
11844
+ serverTerminalStatus: checked.serverTerminalStatus
11845
+ };
11846
+ }
11847
+ if (checked.pending) return { pending: true, resultDelivered: false, state };
11848
+ if (state.phase === "disposition_required") {
11849
+ const closureAlreadyRecorded = state.closureTurnRecorded === true;
11850
+ const recoveryCount = readNumber(state.closureRecoveryCount, 0);
11851
+ const mayResumeUncertainClosure = recoveringClosure && !closureAlreadyRecorded && recoveryCount < 1;
11852
+ if (state.closureAttempt === 0 || mayResumeUncertainClosure) {
11853
+ state = persistPendingRunCompletion(config, transitionRunCompletionState(
11854
+ state,
11855
+ "closure_started",
11856
+ {
11857
+ closureAttempt: 1,
11858
+ ...mayResumeUncertainClosure ? { closureRecoveryCount: recoveryCount + 1 } : {}
11859
+ }
11860
+ ));
11861
+ let closure;
11862
+ try {
11863
+ closure = await executeRunExitClosureTurn(config, state, options);
11864
+ } catch (error) {
11865
+ closure = {
11866
+ succeeded: false,
11867
+ error: error instanceof Error ? error.message : String(error),
11868
+ usage: {},
11869
+ audit: {
11870
+ schemaVersion: "run-exit-disposition-closure-v1",
11871
+ attempt: 1,
11872
+ succeeded: false,
11873
+ error: truncateText(error instanceof Error ? error.message : String(error), 1e3)
11874
+ }
11875
+ };
11876
+ }
11877
+ state = appendRunCompletionUsageTurn({
11878
+ ...state,
11879
+ closureTurnRecorded: true,
11880
+ candidateResult: {
11881
+ ...asRecord(state.candidateResult),
11882
+ closureTurn: closure.audit
11883
+ }
11884
+ }, {
11885
+ turn: "closure",
11886
+ usage: closure.usage,
11887
+ recordedAt: (/* @__PURE__ */ new Date()).toISOString()
11888
+ });
11889
+ state = persistPendingRunCompletion(config, {
11890
+ ...state,
11891
+ completionRequest: {
11892
+ ...asRecord(state.completionRequest),
11893
+ resultSignals: {
11894
+ productiveSuccessfulRun: asRecord(asRecord(state.completionRequest).resultSignals).productiveSuccessfulRun === true,
11895
+ executorTurnCount: 2,
11896
+ closureAttempt: 1
11897
+ }
11898
+ }
11899
+ });
11900
+ checked = await requestRunCompletionCheck(config, state);
11901
+ state = checked.state;
11902
+ if (checked.serverTerminalStatus) {
11903
+ return {
11904
+ pending: false,
11905
+ resultDelivered: true,
11906
+ state,
11907
+ serverTerminalStatus: checked.serverTerminalStatus
11908
+ };
11909
+ }
11910
+ if (checked.pending) return { pending: true, resultDelivered: false, state };
11911
+ }
11912
+ }
11913
+ if (state.phase === "disposition_required") {
11914
+ const command = asRecord(state.command);
11915
+ const candidateResult = asRecord(state.candidateResult);
11916
+ const closureTurn = asRecord(candidateResult.closureTurn);
11917
+ state = persistPendingRunCompletion(config, transitionRunCompletionState(
11918
+ state,
11919
+ "closure_exhausted",
11920
+ {
11921
+ candidateResult: {
11922
+ ...candidateResult,
11923
+ ...Object.keys(closureTurn).length > 0 ? {} : {
11924
+ closureTurn: {
11925
+ schemaVersion: "run-exit-disposition-closure-v1",
11926
+ attempt: 1,
11927
+ succeeded: false,
11928
+ error: "closure_recovery_exhausted"
11929
+ }
11930
+ },
11931
+ closureAttemptExhausted: true,
11932
+ closureFallback: {
11933
+ schemaVersion: "run-exit-disposition-closure-fallback-v1",
11934
+ attempt: 1,
11935
+ reasonCode: readString(asRecord(state.completionResponse).reasonCode) ?? "disposition_still_required",
11936
+ commandId: state.commandId,
11937
+ runId: commandRunId(command)
11938
+ }
11939
+ }
11940
+ }
11941
+ ));
11942
+ }
11943
+ return finalizeRunCompletionState(config, state);
11944
+ }
11945
+ function coordinateRunCompletionSingleFlight(config, inputState, options = {}) {
11946
+ const commandId = readString(inputState?.commandId);
11947
+ if (!commandId) return Promise.reject(new Error("run_completion_command_id_missing"));
11948
+ const activeFlight = runCompletionFlights.get(commandId);
11949
+ if (activeFlight) return activeFlight;
11950
+ const flight = coordinateRunCompletion(config, inputState, options);
11951
+ runCompletionFlights.set(commandId, flight);
11952
+ const release = () => {
11953
+ if (runCompletionFlights.get(commandId) === flight) runCompletionFlights.delete(commandId);
11954
+ };
11955
+ void flight.then(release, release);
11956
+ return flight;
11957
+ }
11958
+ async function flushRunCompletionStates(config) {
11959
+ let completed = 0;
11960
+ for (const { filePath, state: listedState } of runCompletionStateEntries(config)) {
11961
+ try {
11962
+ if (runCompletionFlights.has(listedState.commandId)) continue;
11963
+ if (!existsSync14(filePath)) continue;
11964
+ const state = readValidRunCompletionStateOrQuarantine(config, filePath);
11965
+ if (!state) continue;
11966
+ const outcome = await coordinateRunCompletionSingleFlight(config, state);
11967
+ if (!outcome.pending) completed += 1;
11968
+ } catch (error) {
11969
+ const message = error instanceof Error ? error.message : String(error);
11970
+ process.stderr.write(`AMaster daemon run completion recovery failed for ${listedState.commandId}: ${message}
11971
+ `);
11972
+ }
11973
+ }
11974
+ if (completed > 0) {
11975
+ process.stderr.write(`AMaster daemon resumed ${completed} durable run completion state(s).
11976
+ `);
11977
+ }
11978
+ return completed;
11979
+ }
10528
11980
  async function ingestWorkspaceStatus(config, command, cwd) {
10529
11981
  const connectorId = requireConnectorId(config);
10530
11982
  const status = readWorkspaceStatus(cwd, { hashCache: workspaceStatusHashCache });
@@ -10587,6 +12039,7 @@ async function ingestRuntimeArtifacts(config, command, cwd, mcpToolResults) {
10587
12039
  } catch (err) {
10588
12040
  const message = `Runtime Artifact ${upload.intentId} ingest failed: ${err instanceof Error ? err.message : String(err)}`;
10589
12041
  const failure = new Error(message, err instanceof Error ? { cause: err } : void 0);
12042
+ failure.intentId = upload.intentId;
10590
12043
  if (err instanceof Error && err.code === "runtime_artifact_rejected") {
10591
12044
  failure.code = "runtime_artifact_rejected";
10592
12045
  }
@@ -10659,14 +12112,14 @@ async function completeCommand(config, command, status, result3, error) {
10659
12112
  function resultOutboxDir(config) {
10660
12113
  const explicit = readString(process.env.AMASTER_RESULT_OUTBOX_DIR);
10661
12114
  if (explicit) return resolve12(expandHomePath(explicit));
10662
- return join14(dirname9(stateFilePath(process.env)), "result-outbox");
12115
+ return join15(dirname9(stateFilePath(process.env)), "result-outbox");
10663
12116
  }
10664
12117
  function resultOutboxInvalidDir(config) {
10665
- return join14(resultOutboxDir(config), "invalid");
12118
+ return join15(resultOutboxDir(config), "invalid");
10666
12119
  }
10667
12120
  function writeResultOutboxEntry(config, entry) {
10668
12121
  const dir = resultOutboxDir(config);
10669
- mkdirSync8(dir, { recursive: true });
12122
+ mkdirSync9(dir, { recursive: true });
10670
12123
  const body = {
10671
12124
  version: 1,
10672
12125
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
@@ -10674,19 +12127,19 @@ function writeResultOutboxEntry(config, entry) {
10674
12127
  lastAttemptAt: null,
10675
12128
  ...entry
10676
12129
  };
10677
- writeFileSync8(join14(dir, resultOutboxFileName(entry.commandId)), `${JSON.stringify(body, null, 2)}
12130
+ writeFileSync9(join15(dir, resultOutboxFileName(entry.commandId)), `${JSON.stringify(body, null, 2)}
10678
12131
  `, { mode: 384 });
10679
12132
  }
10680
12133
  function moveResultOutboxEntryToInvalid(config, file, fullPath, reason, detail, original) {
10681
12134
  const invalidDir = resultOutboxInvalidDir(config);
10682
- mkdirSync8(invalidDir, { recursive: true });
10683
- const invalidPath = join14(invalidDir, file);
12135
+ mkdirSync9(invalidDir, { recursive: true });
12136
+ const invalidPath = join15(invalidDir, file);
10684
12137
  if (original === void 0) {
10685
12138
  try {
10686
- renameSync5(fullPath, invalidPath);
12139
+ renameSync6(fullPath, invalidPath);
10687
12140
  } catch {
10688
12141
  copyFileSync3(fullPath, invalidPath);
10689
- unlinkSync(fullPath);
12142
+ unlinkSync2(fullPath);
10690
12143
  }
10691
12144
  return;
10692
12145
  }
@@ -10696,14 +12149,14 @@ function moveResultOutboxEntryToInvalid(config, file, fullPath, reason, detail,
10696
12149
  ...detail ? { detail: truncateText(detail, 1e3) } : {},
10697
12150
  original
10698
12151
  };
10699
- writeFileSync8(invalidPath, `${JSON.stringify(evidence, null, 2)}
12152
+ writeFileSync9(invalidPath, `${JSON.stringify(evidence, null, 2)}
10700
12153
  `, { mode: 384 });
10701
- unlinkSync(fullPath);
12154
+ unlinkSync2(fullPath);
10702
12155
  }
10703
12156
  function readValidResultOutboxEntryOrQuarantine(config, file, fullPath) {
10704
12157
  let entry;
10705
12158
  try {
10706
- entry = JSON.parse(readFileSync10(fullPath, "utf8"));
12159
+ entry = JSON.parse(readFileSync11(fullPath, "utf8"));
10707
12160
  } catch (err) {
10708
12161
  const message = err instanceof Error ? err.message : String(err);
10709
12162
  moveResultOutboxEntryToInvalid(config, file, fullPath, "malformed_result_outbox_json", message);
@@ -10733,13 +12186,13 @@ function updateResultOutboxAttempt(fullPath, entry, err) {
10733
12186
  ...typeof err?.httpStatus === "number" ? { httpStatus: err.httpStatus } : {},
10734
12187
  lastError: truncateText(err instanceof Error ? err.message : String(err), 1e3)
10735
12188
  };
10736
- writeFileSync8(fullPath, `${JSON.stringify(next, null, 2)}
12189
+ writeFileSync9(fullPath, `${JSON.stringify(next, null, 2)}
10737
12190
  `, { mode: 384 });
10738
12191
  return next;
10739
12192
  }
10740
12193
  function quarantineResultOutboxEntry(config, fullPath, file, entry, reason, err) {
10741
12194
  const invalidDir = resultOutboxInvalidDir(config);
10742
- mkdirSync8(invalidDir, { recursive: true });
12195
+ mkdirSync9(invalidDir, { recursive: true });
10743
12196
  const body = {
10744
12197
  ...entry,
10745
12198
  invalidReason: reason,
@@ -10747,30 +12200,31 @@ function quarantineResultOutboxEntry(config, fullPath, file, entry, reason, err)
10747
12200
  ...typeof err?.httpStatus === "number" ? { httpStatus: err.httpStatus } : {},
10748
12201
  lastError: truncateText(err instanceof Error ? err.message : String(err), 1e3)
10749
12202
  };
10750
- const invalidPath = join14(invalidDir, file);
10751
- writeFileSync8(invalidPath, `${JSON.stringify(body, null, 2)}
12203
+ const invalidPath = join15(invalidDir, file);
12204
+ writeFileSync9(invalidPath, `${JSON.stringify(body, null, 2)}
10752
12205
  `, { mode: 384 });
10753
12206
  try {
10754
- unlinkSync(fullPath);
12207
+ unlinkSync2(fullPath);
10755
12208
  } catch (unlinkErr) {
10756
12209
  const message = unlinkErr instanceof Error ? unlinkErr.message : String(unlinkErr);
10757
12210
  process.stderr.write(`AMaster daemon could not remove quarantined result outbox entry ${file}: ${message}
10758
12211
  `);
10759
12212
  }
12213
+ clearDeliveredResultOutboxCommand(config, entry);
10760
12214
  return invalidPath;
10761
12215
  }
10762
12216
  async function flushResultOutbox(config) {
10763
12217
  const dir = resultOutboxDir(config);
10764
- if (!existsSync13(dir)) return { attempted: 0, completed: 0 };
10765
- const files = readdirSync8(dir).filter((name) => name.endsWith(".json")).sort();
12218
+ if (!existsSync14(dir)) return { attempted: 0, completed: 0 };
12219
+ const files = readdirSync9(dir).filter((name) => name.endsWith(".json")).sort();
10766
12220
  let completed = 0;
10767
12221
  for (const file of files) {
10768
- const fullPath = join14(dir, file);
12222
+ const fullPath = join15(dir, file);
10769
12223
  const entry = readValidResultOutboxEntryOrQuarantine(config, file, fullPath);
10770
12224
  if (!entry) continue;
10771
12225
  try {
10772
12226
  await postJson(config, String(entry.path), entry.payload);
10773
- unlinkSync(fullPath);
12227
+ unlinkSync2(fullPath);
10774
12228
  clearDeliveredResultOutboxCommand(config, entry);
10775
12229
  completed += 1;
10776
12230
  } catch (err) {
@@ -10962,8 +12416,8 @@ async function materializeIssueAttachments(config, command, workspace) {
10962
12416
  runtimeAuth,
10963
12417
  issueId
10964
12418
  );
10965
- const targetDir = join14(workspace.cwd, "input-attachments");
10966
- mkdirSync8(targetDir, { recursive: true });
12419
+ const targetDir = join15(workspace.cwd, "input-attachments");
12420
+ mkdirSync9(targetDir, { recursive: true });
10967
12421
  const usedFilenames = /* @__PURE__ */ new Set();
10968
12422
  const materialized = [];
10969
12423
  for (const [index, rawAttachment] of attachments.entries()) {
@@ -10977,9 +12431,9 @@ async function materializeIssueAttachments(config, command, workspace) {
10977
12431
  filename = `${stem}-${index + 1}${ext}`;
10978
12432
  }
10979
12433
  usedFilenames.add(filename);
10980
- const targetPath = join14(targetDir, filename);
12434
+ const targetPath = join15(targetDir, filename);
10981
12435
  const body = await runtimeApiBuffer(runtimeAuth, contentPath);
10982
- writeFileSync8(targetPath, body);
12436
+ writeFileSync9(targetPath, body);
10983
12437
  const attachmentId = readString(attachment.id);
10984
12438
  const actualSha256 = createHash12("sha256").update(body).digest("hex");
10985
12439
  const lineageCandidates = lineageCandidatesByAttachmentId.get(attachmentId) ?? [];
@@ -11053,9 +12507,9 @@ async function materializeRequiredArtifactInputs(config, command, workspace) {
11053
12507
  if (manifest.version !== 1 || !Array.isArray(manifest.entries)) {
11054
12508
  throw new Error("artifact_input_manifest_invalid: expected version 1 entries array");
11055
12509
  }
11056
- const targetRoot = join14(workspace.cwd, "input-artifacts");
12510
+ const targetRoot = join15(workspace.cwd, "input-artifacts");
11057
12511
  rmSync7(targetRoot, { recursive: true, force: true });
11058
- mkdirSync8(targetRoot, { recursive: true });
12512
+ mkdirSync9(targetRoot, { recursive: true });
11059
12513
  const usedPaths = /* @__PURE__ */ new Set();
11060
12514
  const materialized = [];
11061
12515
  for (const [index, rawEntry] of manifest.entries.entries()) {
@@ -11084,17 +12538,17 @@ async function materializeRequiredArtifactInputs(config, command, workspace) {
11084
12538
  id: attachmentId,
11085
12539
  originalFilename: readString(entry.originalFilename)
11086
12540
  }, index);
11087
- let relativePath = join14("input-artifacts", sourceDir, filename).split(/[\\/]+/).join("/");
12541
+ let relativePath = join15("input-artifacts", sourceDir, filename).split(/[\\/]+/).join("/");
11088
12542
  if (usedPaths.has(relativePath)) {
11089
12543
  const ext = extname2(filename);
11090
12544
  const stem = ext ? filename.slice(0, -ext.length) : filename;
11091
12545
  filename = `${stem}-${index + 1}${ext}`;
11092
- relativePath = join14("input-artifacts", sourceDir, filename).split(/[\\/]+/).join("/");
12546
+ relativePath = join15("input-artifacts", sourceDir, filename).split(/[\\/]+/).join("/");
11093
12547
  }
11094
12548
  usedPaths.add(relativePath);
11095
- const targetPath = join14(workspace.cwd, relativePath);
11096
- mkdirSync8(dirname9(targetPath), { recursive: true });
11097
- writeFileSync8(targetPath, body);
12549
+ const targetPath = join15(workspace.cwd, relativePath);
12550
+ mkdirSync9(dirname9(targetPath), { recursive: true });
12551
+ writeFileSync9(targetPath, body);
11098
12552
  chmodSync6(targetPath, 292);
11099
12553
  materialized.push({
11100
12554
  id: attachmentId,
@@ -11114,8 +12568,8 @@ async function materializeRequiredArtifactInputs(config, command, workspace) {
11114
12568
  version: 1,
11115
12569
  entries: materialized.map(({ path: _path, relativePath, ...entry }) => ({ ...entry, path: relativePath }))
11116
12570
  };
11117
- const manifestPath = join14(targetRoot, "artifact-input-manifest.json");
11118
- writeFileSync8(manifestPath, JSON.stringify(localManifest, null, 2) + "\n");
12571
+ const manifestPath = join15(targetRoot, "artifact-input-manifest.json");
12572
+ writeFileSync9(manifestPath, JSON.stringify(localManifest, null, 2) + "\n");
11119
12573
  chmodSync6(manifestPath, 292);
11120
12574
  updateWorkspaceManifest(workspaceManifestPath(workspace), { artifactInputManifest: localManifest });
11121
12575
  await ingestLog(config, command, "system", "info", `Materialized ${materialized.length} required artifact input(s) into the execution workspace`, {
@@ -11125,11 +12579,11 @@ async function materializeRequiredArtifactInputs(config, command, workspace) {
11125
12579
  return materialized;
11126
12580
  }
11127
12581
  function issueCheckpointDir(workspace) {
11128
- return join14(dirname9(workspace.runDir), "checkpoint");
12582
+ return join15(dirname9(workspace.runDir), "checkpoint");
11129
12583
  }
11130
12584
  async function clearIssueCheckpoint(config, command, workspace, reason) {
11131
12585
  const checkpointDir = issueCheckpointDir(workspace);
11132
- if (!existsSync13(checkpointDir)) return false;
12586
+ if (!existsSync14(checkpointDir)) return false;
11133
12587
  rmSync7(checkpointDir, { recursive: true, force: true });
11134
12588
  await ingestLog(config, command, "system", "info", "Cleared issue continuation checkpoint", { reason });
11135
12589
  return true;
@@ -11143,15 +12597,15 @@ function safeCheckpointRelativePath(rawPath) {
11143
12597
  return normalized;
11144
12598
  }
11145
12599
  function hashFileSha256(filePath) {
11146
- return createHash12("sha256").update(readFileSync10(filePath)).digest("hex");
12600
+ return createHash12("sha256").update(readFileSync11(filePath)).digest("hex");
11147
12601
  }
11148
12602
  async function materializeIssueCheckpoint(config, command, workspace) {
11149
12603
  const checkpointDir = issueCheckpointDir(workspace);
11150
- const manifestPath = join14(checkpointDir, "manifest.json");
11151
- if (!existsSync13(manifestPath)) return [];
12604
+ const manifestPath = join15(checkpointDir, "manifest.json");
12605
+ if (!existsSync14(manifestPath)) return [];
11152
12606
  let manifest;
11153
12607
  try {
11154
- manifest = asRecord(JSON.parse(readFileSync10(manifestPath, "utf8")));
12608
+ manifest = asRecord(JSON.parse(readFileSync11(manifestPath, "utf8")));
11155
12609
  } catch (err) {
11156
12610
  rmSync7(checkpointDir, { recursive: true, force: true });
11157
12611
  throw new Error(`invalid issue checkpoint manifest: ${err instanceof Error ? err.message : String(err)}`);
@@ -11164,8 +12618,8 @@ async function materializeIssueCheckpoint(config, command, workspace) {
11164
12618
  try {
11165
12619
  const files = Array.isArray(manifest.files) ? manifest.files : [];
11166
12620
  if (files.length > 20) throw new Error("issue checkpoint manifest exceeds the limit of 20 files");
11167
- const filesRoot = realpathSync4(join14(checkpointDir, "files"));
11168
- const workspaceRoot = realpathSync4(workspace.cwd);
12621
+ const filesRoot = realpathSync5(join15(checkpointDir, "files"));
12622
+ const workspaceRoot = realpathSync5(workspace.cwd);
11169
12623
  const validated = [];
11170
12624
  let totalBytes = 0;
11171
12625
  for (const rawFile of files) {
@@ -11177,8 +12631,8 @@ async function materializeIssueCheckpoint(config, command, workspace) {
11177
12631
  if (!pathWithin2(sourceCandidate, filesRoot) || !pathWithin2(target, workspaceRoot)) {
11178
12632
  throw new Error(`issue checkpoint path escapes its workspace: ${relativePath}`);
11179
12633
  }
11180
- if (!existsSync13(sourceCandidate)) throw new Error(`issue checkpoint file is missing: ${relativePath}`);
11181
- const source = realpathSync4(sourceCandidate);
12634
+ if (!existsSync14(sourceCandidate)) throw new Error(`issue checkpoint file is missing: ${relativePath}`);
12635
+ const source = realpathSync5(sourceCandidate);
11182
12636
  if (!pathWithin2(source, filesRoot) || !statSync7(source).isFile()) {
11183
12637
  throw new Error(`issue checkpoint source escapes its storage root: ${relativePath}`);
11184
12638
  }
@@ -11202,8 +12656,8 @@ async function materializeIssueCheckpoint(config, command, workspace) {
11202
12656
  } catch (err) {
11203
12657
  if (err?.code !== "ENOENT") throw err;
11204
12658
  }
11205
- mkdirSync8(dirname9(target), { recursive: true });
11206
- const targetParent = realpathSync4(dirname9(target));
12659
+ mkdirSync9(dirname9(target), { recursive: true });
12660
+ const targetParent = realpathSync5(dirname9(target));
11207
12661
  if (!pathWithin2(targetParent, workspaceRoot)) {
11208
12662
  throw new Error(`issue checkpoint target escapes its workspace: ${relativePath}`);
11209
12663
  }
@@ -11231,17 +12685,17 @@ async function materializeIssueCheckpoint(config, command, workspace) {
11231
12685
  }
11232
12686
  async function saveIssueCheckpoint(config, command, workspace, candidates) {
11233
12687
  const checkpointDir = issueCheckpointDir(workspace);
11234
- const filesDir = join14(checkpointDir, "files");
12688
+ const filesDir = join15(checkpointDir, "files");
11235
12689
  rmSync7(checkpointDir, { recursive: true, force: true });
11236
- mkdirSync8(filesDir, { recursive: true });
12690
+ mkdirSync9(filesDir, { recursive: true });
11237
12691
  const files = [];
11238
12692
  let totalBytes = 0;
11239
- const workspaceRoot = realpathSync4(workspace.cwd);
12693
+ const workspaceRoot = realpathSync5(workspace.cwd);
11240
12694
  for (const candidate of candidates.slice(0, 20)) {
11241
12695
  const relativePath = safeCheckpointRelativePath(candidate.rawPath);
11242
12696
  const source = readString(candidate.filePath);
11243
- if (!relativePath || !source || !existsSync13(source) || !statSync7(source).isFile()) continue;
11244
- const ownedSource = realpathSync4(source);
12697
+ if (!relativePath || !source || !existsSync14(source) || !statSync7(source).isFile()) continue;
12698
+ const ownedSource = realpathSync5(source);
11245
12699
  if (!pathWithin2(ownedSource, workspaceRoot)) {
11246
12700
  throw new Error(`issue checkpoint source escapes its execution workspace: ${relativePath}`);
11247
12701
  }
@@ -11249,7 +12703,7 @@ async function saveIssueCheckpoint(config, command, workspace, candidates) {
11249
12703
  if (byteSize <= 0 || totalBytes + byteSize > MAX_CHECKPOINT_BYTES) continue;
11250
12704
  const target = resolve12(filesDir, relativePath);
11251
12705
  if (!pathWithin2(target, filesDir)) continue;
11252
- mkdirSync8(dirname9(target), { recursive: true });
12706
+ mkdirSync9(dirname9(target), { recursive: true });
11253
12707
  copyFileSync3(ownedSource, target);
11254
12708
  totalBytes += byteSize;
11255
12709
  files.push({ path: relativePath, byteSize, sha256: hashFileSha256(ownedSource) });
@@ -11267,7 +12721,7 @@ async function saveIssueCheckpoint(config, command, workspace, candidates) {
11267
12721
  totalBytes,
11268
12722
  files
11269
12723
  };
11270
- writeFileSync8(join14(checkpointDir, "manifest.json"), `${JSON.stringify(manifest, null, 2)}
12724
+ writeFileSync9(join15(checkpointDir, "manifest.json"), `${JSON.stringify(manifest, null, 2)}
11271
12725
  `);
11272
12726
  await ingestLog(config, command, "system", "warn", `Saved ${files.length} required deliverable(s) for continuation recovery`, manifest);
11273
12727
  return manifest;
@@ -11353,6 +12807,7 @@ async function executeRunCommand(config, command) {
11353
12807
  };
11354
12808
  let stopActiveRunHeartbeats = () => {
11355
12809
  };
12810
+ let completionOwnsManagedMcpProfile = false;
11356
12811
  try {
11357
12812
  if (executor.kind === "codex" && Object.keys(governedMcp).length > 0) {
11358
12813
  managedMcpProfile = prepareManagedCodexMcpProfile({
@@ -11447,7 +12902,7 @@ async function executeRunCommand(config, command) {
11447
12902
  executorEnv = {
11448
12903
  ...executorEnv,
11449
12904
  AMASTER_MANAGED_RUNTIME_ASSERTION_FD: "3",
11450
- AMASTER_MANAGED_RUNTIME_AUDIT_FILE: join14(
12905
+ AMASTER_MANAGED_RUNTIME_AUDIT_FILE: join15(
11451
12906
  managedMcpProfile.env.HOME,
11452
12907
  ".amaster-managed-runtime-audit.jsonl"
11453
12908
  ),
@@ -11683,16 +13138,15 @@ async function executeRunCommand(config, command) {
11683
13138
  outputTelemetry
11684
13139
  }
11685
13140
  );
11686
- await ingestCost(config, command, executor, parsed);
11687
13141
  const workspaceStatus = await ingestWorkspaceStatus(config, command, cwd);
11688
13142
  let nativeSessionRollout = null;
11689
13143
  let nativeSessionRolloutError = null;
11690
13144
  let nativeSessionRolloutCleanup = null;
11691
13145
  let nativeSessionRolloutCleanupError = null;
11692
- const mcpToolResults = [
13146
+ const mcpToolResults = dedupeGovernedMcpToolResults([
11693
13147
  ...Array.isArray(parsed.mcpToolResults) ? parsed.mcpToolResults.map(asRecord) : [],
11694
13148
  ...liveOutputLogger.mcpToolResults().map(asRecord)
11695
- ];
13149
+ ]);
11696
13150
  runtimeArtifacts.push(...await ingestRuntimeArtifacts(
11697
13151
  config,
11698
13152
  command,
@@ -11795,23 +13249,7 @@ async function executeRunCommand(config, command) {
11795
13249
  const resultStderr = filterExecutionStderrForResult(executor.kind, execution.stderr);
11796
13250
  const error = execution.timedOut ? `Executor timed out after ${config.executorTimeoutSeconds}s` : cancelled ? "Executor cancelled by AMaster control plane" : execution.spawnError ?? parsedErrorMessage ?? (succeeded ? null : `Executor exited with code ${execution.exitCode ?? "unknown"}`);
11797
13251
  const costUsage = parsedCostUsage(parsed.usage);
11798
- if (managedMcpProfile) {
11799
- managedMcpCleanup = cleanupManagedMcpProfile(managedMcpProfile, {
11800
- commandId: command.commandId,
11801
- runId: commandRunId(command)
11802
- });
11803
- patchActiveRunCommand(command, {
11804
- managedMcpCleanup: managedMcpCleanup.status,
11805
- managedMcpCleanedAt: (/* @__PURE__ */ new Date()).toISOString()
11806
- });
11807
- await ingestLog(config, command, "system", "info", `Cleaned isolated ${executor.kind} managed MCP profile`, {
11808
- presentationKind: "managed_mcp_cleanup",
11809
- attestationId: managedMcpProfile.attestation.attestationId,
11810
- sessionId: governedMcp.sessionId,
11811
- status: managedMcpCleanup.status
11812
- });
11813
- }
11814
- const result3 = {
13252
+ let result3 = {
11815
13253
  evidenceContract: { version: 1 },
11816
13254
  executorKind: executor.kind,
11817
13255
  command: invocation.command,
@@ -11900,6 +13338,90 @@ async function executeRunCommand(config, command) {
11900
13338
  }
11901
13339
  } : {}
11902
13340
  };
13341
+ if (succeeded && managedMcpProfile && Array.isArray(command.requiredCapabilities) && command.requiredCapabilities.includes("runtime_actions_v2")) {
13342
+ const productiveSuccessfulRun = outputTelemetry.meaningfulProgressEventCount > 0 || runtimeArtifacts.length > 0 || mcpToolResults.some((toolResult) => ["succeeded", "approval_required"].includes(readString(toolResult.status)));
13343
+ let completionState = createRunCompletionState({
13344
+ connectorId: requireConnectorId(config),
13345
+ command,
13346
+ executor: {
13347
+ kind: executor.kind,
13348
+ model: process.env.AMASTER_CODEX_MODEL || executor.kind,
13349
+ ...managedMcpProfile ? {
13350
+ managedMcp: {
13351
+ profileRoot: managedMcpProfile.profileRoot,
13352
+ attestation: managedMcpProfile.attestation
13353
+ }
13354
+ } : {},
13355
+ closureExecution: {
13356
+ command: invocation.command,
13357
+ args: invocation.args,
13358
+ cwd,
13359
+ sourceWorkspacePath: workspace.sourceWorkspacePath,
13360
+ managedWorkdir: workspace.managed,
13361
+ manifestPath: workspaceManifestPath(workspace),
13362
+ env: executorEnv,
13363
+ protectedValues: protectedExecutorValues,
13364
+ timeoutSeconds: config.executorTimeoutSeconds,
13365
+ maxOutputBytes: config.executorMaxOutputBytes,
13366
+ maxRssMb: config.executorMaxRssMb,
13367
+ ...piChildIsolation ? { spawnIdentity: piChildIsolation.spawn } : {},
13368
+ ...trustedPiRuntime ? { managedInput: `${JSON.stringify(trustedPiRuntimeAssertion)}
13369
+ ` } : {}
13370
+ }
13371
+ },
13372
+ completionRequest: {
13373
+ contractVersion: "amaster.runtime-connector.completion-check.v1",
13374
+ leaseId: command.leaseId,
13375
+ proposedStatus: "succeeded",
13376
+ resultSignals: {
13377
+ productiveSuccessfulRun,
13378
+ executorTurnCount: 1,
13379
+ closureAttempt: 0
13380
+ }
13381
+ },
13382
+ candidateStatus: "succeeded",
13383
+ candidateResult: result3,
13384
+ turn: { usage: parsed.usage }
13385
+ });
13386
+ completionState = persistPendingRunCompletion(config, completionState);
13387
+ completionOwnsManagedMcpProfile = true;
13388
+ const completionOutcome = await coordinateRunCompletionSingleFlight(config, completionState, {
13389
+ signal: abortController.signal
13390
+ });
13391
+ managedMcpCleanup = Object.keys(asRecord(completionOutcome.managedMcpCleanup)).length > 0 ? completionOutcome.managedMcpCleanup : managedMcpCleanup;
13392
+ if (completionOutcome.pending) {
13393
+ await heartbeat(config, { logMode: "compact" }).catch((heartbeatError) => {
13394
+ const message = heartbeatError instanceof Error ? heartbeatError.message : String(heartbeatError);
13395
+ process.stderr.write(`AMaster daemon completion-state heartbeat failed; durable state will retry: ${message}
13396
+ `);
13397
+ });
13398
+ }
13399
+ return { resultDelivered: Boolean(completionOutcome.resultDelivered) };
13400
+ }
13401
+ await ingestCost(config, command, executor, parsed);
13402
+ if (managedMcpProfile) {
13403
+ managedMcpCleanup = cleanupManagedMcpProfile(managedMcpProfile, {
13404
+ commandId: command.commandId,
13405
+ runId: commandRunId(command)
13406
+ });
13407
+ patchActiveRunCommand(command, {
13408
+ managedMcpCleanup: managedMcpCleanup.status,
13409
+ managedMcpCleanedAt: (/* @__PURE__ */ new Date()).toISOString()
13410
+ });
13411
+ await ingestLog(config, command, "system", "info", `Cleaned isolated ${executor.kind} managed MCP profile`, {
13412
+ presentationKind: "managed_mcp_cleanup",
13413
+ attestationId: managedMcpProfile.attestation.attestationId,
13414
+ sessionId: governedMcp.sessionId,
13415
+ status: managedMcpCleanup.status
13416
+ });
13417
+ result3 = {
13418
+ ...result3,
13419
+ managedMcp: {
13420
+ ...asRecord(result3.managedMcp),
13421
+ cleanup: managedMcpCleanup
13422
+ }
13423
+ };
13424
+ }
11903
13425
  const completion = await completeCommand(config, command, cancelled ? "cancelled" : succeeded ? "succeeded" : "failed", result3, error ?? void 0);
11904
13426
  if (!completion) {
11905
13427
  rememberPendingResultOutboxRunCommand(command, {
@@ -11914,7 +13436,7 @@ async function executeRunCommand(config, command) {
11914
13436
  }
11915
13437
  return { resultDelivered: Boolean(completion) };
11916
13438
  } finally {
11917
- if (managedMcpProfile && !managedMcpCleanup) {
13439
+ if (managedMcpProfile && !managedMcpCleanup && !completionOwnsManagedMcpProfile) {
11918
13440
  managedMcpCleanup = cleanupManagedMcpProfile(managedMcpProfile, {
11919
13441
  commandId: command.commandId,
11920
13442
  runId: commandRunId(command)
@@ -12024,13 +13546,15 @@ function isConnectorAuthFailure(err) {
12024
13546
  return err && (err.httpStatus === 401 || err.httpStatus === 403);
12025
13547
  }
12026
13548
  function reconcileStaleManagedMcpProfiles(config) {
13549
+ const protectedCommandIds = runCompletionStateEntries(config).map(({ state }) => state.commandId);
12027
13550
  for (const [executorKind, reconcile] of [
12028
13551
  ["Codex", reconcileManagedCodexMcpProfiles],
12029
13552
  ["Pi", reconcileManagedPiMcpProfiles]
12030
13553
  ]) {
12031
- const result3 = reconcile(config.runtimeWorkspacesRoot);
13554
+ const result3 = reconcile(config.runtimeWorkspacesRoot, { protectedCommandIds });
12032
13555
  if (result3.failed > 0) {
12033
- throw new Error(`${executorKind.toLowerCase()}_managed_mcp_restart_cleanup_failed: ${result3.failed}/${result3.scanned} owned profile(s) could not be reconciled`);
13556
+ const reasons = Array.isArray(result3.failures) ? result3.failures.slice(0, 3).map((failure) => readString(failure?.error) ?? "unknown").join("; ") : "unknown";
13557
+ throw new Error(`${executorKind.toLowerCase()}_managed_mcp_restart_cleanup_failed: ${result3.failed}/${result3.scanned} owned profile(s) could not be reconciled: ${reasons}`);
12034
13558
  }
12035
13559
  if (result3.removed > 0) {
12036
13560
  process.stderr.write(`AMaster daemon removed ${result3.removed} stale marker-owned ${executorKind} managed MCP artifact(s) during startup reconciliation.
@@ -12054,6 +13578,7 @@ async function runOnce(config) {
12054
13578
  }
12055
13579
  }
12056
13580
  await flushResultOutbox(config);
13581
+ await flushRunCompletionStates(config);
12057
13582
  const availableSlots = availableCommandSlots(config);
12058
13583
  if (availableSlots <= 0) return 0;
12059
13584
  const leaseId = `amaster-${Date.now()}`;
@@ -12085,6 +13610,7 @@ async function dispatchAvailableCommands(config, options = {}) {
12085
13610
  }
12086
13611
  }
12087
13612
  await flushResultOutbox(config);
13613
+ await flushRunCompletionStates(config);
12088
13614
  const availableSlots = availableCommandSlots(config);
12089
13615
  if (availableSlots <= 0) return 0;
12090
13616
  const leaseId = `amaster-${Date.now()}`;