@h-rig/runtime 0.0.6-alpha.34 → 0.0.6-alpha.35

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.
@@ -2,15 +2,15 @@
2
2
  // @bun
3
3
 
4
4
  // packages/runtime/src/control-plane/harness-main.ts
5
- import { resolve as resolve33 } from "path";
5
+ import { resolve as resolve34 } from "path";
6
6
 
7
7
  // packages/runtime/src/control-plane/native/harness-cli.ts
8
- import { existsSync as existsSync29 } from "fs";
9
- import { resolve as resolve30 } from "path";
8
+ import { existsSync as existsSync31 } from "fs";
9
+ import { resolve as resolve31 } from "path";
10
10
 
11
11
  // packages/runtime/src/control-plane/native/git-ops.ts
12
- import { existsSync as existsSync22, lstatSync, mkdirSync as mkdirSync11, readFileSync as readFileSync12, writeFileSync as writeFileSync11 } from "fs";
13
- import { dirname as dirname11, isAbsolute as isAbsolute2, resolve as resolve25 } from "path";
12
+ import { existsSync as existsSync24, lstatSync, mkdirSync as mkdirSync12, readFileSync as readFileSync13, writeFileSync as writeFileSync12 } from "fs";
13
+ import { dirname as dirname12, isAbsolute as isAbsolute2, resolve as resolve26 } from "path";
14
14
  import { fileURLToPath as fileURLToPath2 } from "url";
15
15
 
16
16
  // packages/runtime/src/control-plane/runtime/baked-secrets.ts
@@ -279,8 +279,8 @@ function isAgentRuntimeContextPath(path) {
279
279
  }
280
280
 
281
281
  // packages/runtime/src/control-plane/native/task-ops.ts
282
- import { appendFileSync, existsSync as existsSync21, mkdirSync as mkdirSync10, readFileSync as readFileSync11, writeFileSync as writeFileSync10 } from "fs";
283
- import { resolve as resolve24 } from "path";
282
+ import { appendFileSync, existsSync as existsSync23, mkdirSync as mkdirSync11, readFileSync as readFileSync12, writeFileSync as writeFileSync11 } from "fs";
283
+ import { resolve as resolve25 } from "path";
284
284
 
285
285
  // packages/runtime/src/build-time-config.ts
286
286
  function normalizeBuildConfig(value) {
@@ -829,6 +829,8 @@ function buildBrowserGuidanceLines(browser) {
829
829
  }
830
830
 
831
831
  // packages/runtime/src/control-plane/plugin-host-context.ts
832
+ import { existsSync as existsSync8 } from "fs";
833
+ import { resolve as resolvePath } from "path";
832
834
  import { createPluginHost } from "@rig/core";
833
835
  import { loadConfig } from "@rig/core/load-config";
834
836
 
@@ -1176,6 +1178,55 @@ async function materializeSkills(projectRoot, entries) {
1176
1178
  return written;
1177
1179
  }
1178
1180
 
1181
+ // packages/runtime/src/control-plane/pi-settings-materializer.ts
1182
+ import { existsSync as existsSync7, mkdirSync as mkdirSync5, readFileSync as readFileSync6, writeFileSync as writeFileSync5 } from "fs";
1183
+ import { dirname as dirname6, resolve as resolve9 } from "path";
1184
+ var SETTINGS_RELATIVE_PATH = ".pi/settings.json";
1185
+ var MANAGED_RECORD_RELATIVE_PATH = ".rig/state/pi-managed-packages.json";
1186
+ function readJson(path, fallback) {
1187
+ if (!existsSync7(path))
1188
+ return fallback;
1189
+ try {
1190
+ return JSON.parse(readFileSync6(path, "utf-8"));
1191
+ } catch {
1192
+ return fallback;
1193
+ }
1194
+ }
1195
+ function packageKey(entry) {
1196
+ if (typeof entry === "string")
1197
+ return entry;
1198
+ if (entry && typeof entry === "object" && typeof entry.source === "string") {
1199
+ return entry.source;
1200
+ }
1201
+ return JSON.stringify(entry);
1202
+ }
1203
+ function materializePiPackages(projectRoot, declaredPackages) {
1204
+ const settingsPath = resolve9(projectRoot, SETTINGS_RELATIVE_PATH);
1205
+ const managedRecordPath = resolve9(projectRoot, MANAGED_RECORD_RELATIVE_PATH);
1206
+ const settings = readJson(settingsPath, {});
1207
+ const previouslyManaged = new Set(readJson(managedRecordPath, []));
1208
+ const existing = Array.isArray(settings.packages) ? settings.packages : [];
1209
+ const operatorEntries = existing.filter((entry) => !previouslyManaged.has(packageKey(entry)));
1210
+ const operatorKeys = new Set(operatorEntries.map(packageKey));
1211
+ const managedToAdd = declaredPackages.filter((pkg) => !operatorKeys.has(pkg));
1212
+ const nextPackages = [...operatorEntries, ...managedToAdd];
1213
+ if (nextPackages.length > 0 || existsSync7(settingsPath)) {
1214
+ const nextSettings = { ...settings };
1215
+ if (nextPackages.length > 0) {
1216
+ nextSettings.packages = nextPackages;
1217
+ } else {
1218
+ delete nextSettings.packages;
1219
+ }
1220
+ mkdirSync5(dirname6(settingsPath), { recursive: true });
1221
+ writeFileSync5(settingsPath, `${JSON.stringify(nextSettings, null, 2)}
1222
+ `, "utf-8");
1223
+ }
1224
+ mkdirSync5(dirname6(managedRecordPath), { recursive: true });
1225
+ writeFileSync5(managedRecordPath, `${JSON.stringify(managedToAdd, null, 2)}
1226
+ `, "utf-8");
1227
+ return { settingsPath, packages: managedToAdd };
1228
+ }
1229
+
1179
1230
  // packages/runtime/src/control-plane/plugin-host-context.ts
1180
1231
  async function buildPluginHostContext(projectRoot) {
1181
1232
  let config;
@@ -1223,6 +1274,14 @@ async function buildPluginHostContext(projectRoot) {
1223
1274
  } catch (err) {
1224
1275
  console.warn(`[plugin-host] skill materialization failed: ${err instanceof Error ? err.message : err}`);
1225
1276
  }
1277
+ try {
1278
+ const piPackages = config.runtime?.pi?.packages ?? [];
1279
+ if (piPackages.length > 0 || existsSync8(resolvePath(projectRoot, ".rig/state/pi-managed-packages.json"))) {
1280
+ materializePiPackages(projectRoot, piPackages);
1281
+ }
1282
+ } catch (err) {
1283
+ console.warn(`[plugin-host] Pi package materialization failed: ${err instanceof Error ? err.message : err}`);
1284
+ }
1226
1285
  return {
1227
1286
  config,
1228
1287
  pluginHost,
@@ -1236,12 +1295,12 @@ async function buildPluginHostContext(projectRoot) {
1236
1295
 
1237
1296
  // packages/runtime/src/control-plane/tasks/source-aware-task-config-source.ts
1238
1297
  import { spawnSync } from "child_process";
1239
- import { existsSync as existsSync8, readFileSync as readFileSync7, readdirSync as readdirSync2, statSync, writeFileSync as writeFileSync5 } from "fs";
1240
- import { basename as basename3, join as join2, resolve as resolve10 } from "path";
1298
+ import { existsSync as existsSync10, readFileSync as readFileSync8, readdirSync as readdirSync2, statSync, writeFileSync as writeFileSync6 } from "fs";
1299
+ import { basename as basename3, join as join2, resolve as resolve11 } from "path";
1241
1300
 
1242
1301
  // packages/runtime/src/control-plane/tasks/legacy-task-config-source.ts
1243
- import { existsSync as existsSync7, readFileSync as readFileSync6 } from "fs";
1244
- import { resolve as resolve9 } from "path";
1302
+ import { existsSync as existsSync9, readFileSync as readFileSync7 } from "fs";
1303
+ import { resolve as resolve10 } from "path";
1245
1304
 
1246
1305
  // packages/runtime/src/control-plane/tasks/task-record-reader.ts
1247
1306
  async function findTaskById(reader, id) {
@@ -1264,7 +1323,7 @@ class LegacyTaskConfigReadError extends Error {
1264
1323
  }
1265
1324
  }
1266
1325
  function createLegacyTaskConfigRecordReader(projectRoot, options = {}) {
1267
- const configPath = options.configPath ?? resolve9(projectRoot, ".rig", "task-config.json");
1326
+ const configPath = options.configPath ?? resolve10(projectRoot, ".rig", "task-config.json");
1268
1327
  const reader = {
1269
1328
  async listTasks() {
1270
1329
  return readLegacyTaskRecords(projectRoot, configPath);
@@ -1275,8 +1334,8 @@ function createLegacyTaskConfigRecordReader(projectRoot, options = {}) {
1275
1334
  };
1276
1335
  return reader;
1277
1336
  }
1278
- function readLegacyTaskRecords(projectRoot, configPath = resolve9(projectRoot, ".rig", "task-config.json")) {
1279
- if (!existsSync7(configPath)) {
1337
+ function readLegacyTaskRecords(projectRoot, configPath = resolve10(projectRoot, ".rig", "task-config.json")) {
1338
+ if (!existsSync9(configPath)) {
1280
1339
  return [];
1281
1340
  }
1282
1341
  const rawConfig = readLegacyTaskConfigJson(projectRoot, configPath);
@@ -1284,7 +1343,7 @@ function readLegacyTaskRecords(projectRoot, configPath = resolve9(projectRoot, "
1284
1343
  }
1285
1344
  function readLegacyTaskConfigJson(projectRoot, configPath) {
1286
1345
  try {
1287
- const parsed = JSON.parse(readFileSync6(configPath, "utf8"));
1346
+ const parsed = JSON.parse(readFileSync7(configPath, "utf8"));
1288
1347
  if (isPlainRecord(parsed)) {
1289
1348
  return parsed;
1290
1349
  }
@@ -1368,7 +1427,7 @@ function isPlainRecord(candidate) {
1368
1427
  var STATUS_LABELS = new Set(["ready", "blocked", "in-progress", "under-review", "failed", "cancelled"]);
1369
1428
  var FILE_TASK_PATTERN = /\.(task\.)?json$/;
1370
1429
  function createSourceAwareTaskConfigRecordReader(projectRoot, options = {}) {
1371
- const configPath = options.configPath ?? resolve10(projectRoot, ".rig", "task-config.json");
1430
+ const configPath = options.configPath ?? resolve11(projectRoot, ".rig", "task-config.json");
1372
1431
  const legacy = createLegacyTaskConfigRecordReader(projectRoot, { configPath });
1373
1432
  const spawnFn = options.spawn ?? spawnSync;
1374
1433
  const ghBinary = options.ghBinary ?? "gh";
@@ -1451,10 +1510,10 @@ function readMaterializedTaskMetadata(entry) {
1451
1510
  return metadata;
1452
1511
  }
1453
1512
  function readConfiguredFilesTaskSourcePath(projectRoot) {
1454
- const jsonPath = resolve10(projectRoot, "rig.config.json");
1455
- if (existsSync8(jsonPath)) {
1513
+ const jsonPath = resolve11(projectRoot, "rig.config.json");
1514
+ if (existsSync10(jsonPath)) {
1456
1515
  try {
1457
- const parsed = JSON.parse(readFileSync7(jsonPath, "utf8"));
1516
+ const parsed = JSON.parse(readFileSync8(jsonPath, "utf8"));
1458
1517
  if (isPlainRecord2(parsed) && isPlainRecord2(parsed.taskSource)) {
1459
1518
  const source = parsed.taskSource;
1460
1519
  return source.kind === "files" && typeof source.path === "string" ? source.path : null;
@@ -1463,12 +1522,12 @@ function readConfiguredFilesTaskSourcePath(projectRoot) {
1463
1522
  return null;
1464
1523
  }
1465
1524
  }
1466
- const tsPath = resolve10(projectRoot, "rig.config.ts");
1467
- if (!existsSync8(tsPath)) {
1525
+ const tsPath = resolve11(projectRoot, "rig.config.ts");
1526
+ if (!existsSync10(tsPath)) {
1468
1527
  return null;
1469
1528
  }
1470
1529
  try {
1471
- const source = readFileSync7(tsPath, "utf8");
1530
+ const source = readFileSync8(tsPath, "utf8");
1472
1531
  const taskSourceBlock = source.match(/taskSource\s*:\s*\{[\s\S]*?\}/m)?.[0] ?? "";
1473
1532
  const kind = taskSourceBlock.match(/kind\s*:\s*["']([^"']+)["']/)?.[1];
1474
1533
  if (kind !== "files") {
@@ -1488,10 +1547,10 @@ function readRawTaskEntry(configPath, taskId) {
1488
1547
  return isPlainRecord2(entry) ? entry : null;
1489
1548
  }
1490
1549
  function readRawTaskConfig(configPath) {
1491
- if (!existsSync8(configPath)) {
1550
+ if (!existsSync10(configPath)) {
1492
1551
  return null;
1493
1552
  }
1494
- const parsed = JSON.parse(readFileSync7(configPath, "utf8"));
1553
+ const parsed = JSON.parse(readFileSync8(configPath, "utf8"));
1495
1554
  return isPlainRecord2(parsed) ? parsed : null;
1496
1555
  }
1497
1556
  function stripLegacyTaskConfigMetadata2(raw) {
@@ -1499,8 +1558,8 @@ function stripLegacyTaskConfigMetadata2(raw) {
1499
1558
  return tasks;
1500
1559
  }
1501
1560
  function listFileBackedTasks(projectRoot, sourcePath) {
1502
- const directory = resolve10(projectRoot, sourcePath);
1503
- if (!existsSync8(directory)) {
1561
+ const directory = resolve11(projectRoot, sourcePath);
1562
+ if (!existsSync10(directory)) {
1504
1563
  return [];
1505
1564
  }
1506
1565
  const tasks = [];
@@ -1515,11 +1574,11 @@ function listFileBackedTasks(projectRoot, sourcePath) {
1515
1574
  return tasks;
1516
1575
  }
1517
1576
  function readFileBackedTask(projectRoot, sourcePath, taskId, rawEntry) {
1518
- const file = findFileBackedTaskFile(resolve10(projectRoot, sourcePath), taskId);
1577
+ const file = findFileBackedTaskFile(resolve11(projectRoot, sourcePath), taskId);
1519
1578
  if (!file) {
1520
1579
  return null;
1521
1580
  }
1522
- const raw = JSON.parse(readFileSync7(file, "utf8"));
1581
+ const raw = JSON.parse(readFileSync8(file, "utf8"));
1523
1582
  if (!isPlainRecord2(raw)) {
1524
1583
  return null;
1525
1584
  }
@@ -1532,7 +1591,7 @@ function readFileBackedTask(projectRoot, sourcePath, taskId, rawEntry) {
1532
1591
  };
1533
1592
  }
1534
1593
  function findFileBackedTaskFile(directory, taskId) {
1535
- if (!existsSync8(directory)) {
1594
+ if (!existsSync10(directory)) {
1536
1595
  return null;
1537
1596
  }
1538
1597
  for (const name of readdirSync2(directory)) {
@@ -1542,7 +1601,7 @@ function findFileBackedTaskFile(directory, taskId) {
1542
1601
  try {
1543
1602
  if (!statSync(file).isFile())
1544
1603
  continue;
1545
- const raw = JSON.parse(readFileSync7(file, "utf8"));
1604
+ const raw = JSON.parse(readFileSync8(file, "utf8"));
1546
1605
  const inferredId = basename3(file).replace(FILE_TASK_PATTERN, "");
1547
1606
  const id = isPlainRecord2(raw) && typeof raw.id === "string" ? raw.id : inferredId;
1548
1607
  if (id === taskId) {
@@ -1702,8 +1761,8 @@ async function readConfiguredTaskSourceTask(projectRoot, taskId) {
1702
1761
  }
1703
1762
 
1704
1763
  // packages/runtime/src/control-plane/native/task-state.ts
1705
- import { existsSync as existsSync15, readFileSync as readFileSync10, readdirSync as readdirSync3, statSync as statSync3, writeFileSync as writeFileSync6 } from "fs";
1706
- import { basename as basename6, resolve as resolve17 } from "path";
1764
+ import { existsSync as existsSync17, readFileSync as readFileSync11, readdirSync as readdirSync3, statSync as statSync3, writeFileSync as writeFileSync7 } from "fs";
1765
+ import { basename as basename6, resolve as resolve18 } from "path";
1707
1766
 
1708
1767
  // packages/runtime/src/control-plane/state-sync/types.ts
1709
1768
  var SUPPORTED_TASK_STATE_SCHEMA_VERSION = 1;
@@ -1811,51 +1870,51 @@ function readTaskStateMetadataEnvelope(raw) {
1811
1870
  };
1812
1871
  }
1813
1872
  // packages/runtime/src/control-plane/state-sync/read.ts
1814
- import { existsSync as existsSync14, readFileSync as readFileSync9 } from "fs";
1815
- import { resolve as resolve16 } from "path";
1873
+ import { existsSync as existsSync16, readFileSync as readFileSync10 } from "fs";
1874
+ import { resolve as resolve17 } from "path";
1816
1875
 
1817
1876
  // packages/runtime/src/control-plane/native/utils.ts
1818
- import { existsSync as existsSync11, readFileSync as readFileSync8 } from "fs";
1819
- import { resolve as resolve13 } from "path";
1877
+ import { existsSync as existsSync13, readFileSync as readFileSync9 } from "fs";
1878
+ import { resolve as resolve14 } from "path";
1820
1879
 
1821
1880
  // packages/runtime/src/layout.ts
1822
- import { existsSync as existsSync9 } from "fs";
1823
- import { basename as basename4, dirname as dirname6, resolve as resolve11 } from "path";
1881
+ import { existsSync as existsSync11 } from "fs";
1882
+ import { basename as basename4, dirname as dirname7, resolve as resolve12 } from "path";
1824
1883
  var RIG_DEFINITION_DIRNAME = "rig";
1825
1884
  var RIG_STATE_DIRNAME = ".rig";
1826
1885
  var RIG_ARTIFACTS_DIRNAME = "artifacts";
1827
1886
  function resolveMonorepoRoot(projectRoot) {
1828
- const normalizedProjectRoot = resolve11(projectRoot);
1887
+ const normalizedProjectRoot = resolve12(projectRoot);
1829
1888
  const explicit = process.env.MONOREPO_ROOT?.trim();
1830
1889
  if (explicit) {
1831
- const explicitRoot = resolve11(explicit);
1832
- const explicitParent = dirname6(explicitRoot);
1890
+ const explicitRoot = resolve12(explicit);
1891
+ const explicitParent = dirname7(explicitRoot);
1833
1892
  if (basename4(explicitParent) === ".worktrees") {
1834
- const owner = dirname6(explicitParent);
1835
- const ownerHasGit = existsSync9(resolve11(owner, ".git"));
1836
- const ownerHasTaskConfig = existsSync9(resolve11(owner, ".rig", "task-config.json"));
1837
- const ownerHasRigConfig = existsSync9(resolve11(owner, "rig.config.ts"));
1893
+ const owner = dirname7(explicitParent);
1894
+ const ownerHasGit = existsSync11(resolve12(owner, ".git"));
1895
+ const ownerHasTaskConfig = existsSync11(resolve12(owner, ".rig", "task-config.json"));
1896
+ const ownerHasRigConfig = existsSync11(resolve12(owner, "rig.config.ts"));
1838
1897
  if (ownerHasGit && (ownerHasTaskConfig || ownerHasRigConfig)) {
1839
1898
  return owner;
1840
1899
  }
1841
1900
  throw new Error(`MONOREPO_ROOT points to worktree ${explicitRoot}, but the owner checkout is incomplete at ${owner}.`);
1842
1901
  }
1843
- if (!existsSync9(resolve11(explicitRoot, ".git"))) {
1902
+ if (!existsSync11(resolve12(explicitRoot, ".git"))) {
1844
1903
  throw new Error(`MONOREPO_ROOT points to ${explicitRoot}, but no git checkout was found there.`);
1845
1904
  }
1846
- const hasTaskConfig = existsSync9(resolve11(explicitRoot, ".rig", "task-config.json"));
1847
- const hasRigConfig = existsSync9(resolve11(explicitRoot, "rig.config.ts"));
1905
+ const hasTaskConfig = existsSync11(resolve12(explicitRoot, ".rig", "task-config.json"));
1906
+ const hasRigConfig = existsSync11(resolve12(explicitRoot, "rig.config.ts"));
1848
1907
  if (!hasTaskConfig && !hasRigConfig) {
1849
1908
  throw new Error(`MONOREPO_ROOT points to ${explicitRoot}, but neither .rig/task-config.json nor rig.config.ts exists there.`);
1850
1909
  }
1851
1910
  return explicitRoot;
1852
1911
  }
1853
- const projectParent = dirname6(normalizedProjectRoot);
1912
+ const projectParent = dirname7(normalizedProjectRoot);
1854
1913
  if (basename4(projectParent) === ".worktrees") {
1855
- const worktreeOwner = dirname6(projectParent);
1856
- const ownerHasGit = existsSync9(resolve11(worktreeOwner, ".git"));
1857
- const ownerHasTaskConfig = existsSync9(resolve11(worktreeOwner, ".rig", "task-config.json"));
1858
- const ownerHasRigConfig = existsSync9(resolve11(worktreeOwner, "rig.config.ts"));
1914
+ const worktreeOwner = dirname7(projectParent);
1915
+ const ownerHasGit = existsSync11(resolve12(worktreeOwner, ".git"));
1916
+ const ownerHasTaskConfig = existsSync11(resolve12(worktreeOwner, ".rig", "task-config.json"));
1917
+ const ownerHasRigConfig = existsSync11(resolve12(worktreeOwner, "rig.config.ts"));
1859
1918
  if (ownerHasGit && (ownerHasTaskConfig || ownerHasRigConfig)) {
1860
1919
  return worktreeOwner;
1861
1920
  }
@@ -1863,28 +1922,28 @@ function resolveMonorepoRoot(projectRoot) {
1863
1922
  return normalizedProjectRoot;
1864
1923
  }
1865
1924
  function resolveRuntimeWorkspaceLayout(workspaceDir) {
1866
- const root = resolve11(workspaceDir);
1867
- const rigRoot = resolve11(root, ".rig");
1868
- const logsDir = resolve11(rigRoot, "logs");
1869
- const stateDir = resolve11(rigRoot, "state");
1870
- const runtimeDir = resolve11(rigRoot, "runtime");
1871
- const binDir = resolve11(rigRoot, "bin");
1925
+ const root = resolve12(workspaceDir);
1926
+ const rigRoot = resolve12(root, ".rig");
1927
+ const logsDir = resolve12(rigRoot, "logs");
1928
+ const stateDir = resolve12(rigRoot, "state");
1929
+ const runtimeDir = resolve12(rigRoot, "runtime");
1930
+ const binDir = resolve12(rigRoot, "bin");
1872
1931
  return {
1873
1932
  workspaceDir: root,
1874
1933
  rigRoot,
1875
1934
  stateDir,
1876
1935
  logsDir,
1877
- artifactsRoot: resolve11(root, RIG_ARTIFACTS_DIRNAME),
1936
+ artifactsRoot: resolve12(root, RIG_ARTIFACTS_DIRNAME),
1878
1937
  runtimeDir,
1879
- homeDir: resolve11(rigRoot, "home"),
1880
- tmpDir: resolve11(rigRoot, "tmp"),
1881
- cacheDir: resolve11(rigRoot, "cache"),
1882
- sessionDir: resolve11(rigRoot, "session"),
1938
+ homeDir: resolve12(rigRoot, "home"),
1939
+ tmpDir: resolve12(rigRoot, "tmp"),
1940
+ cacheDir: resolve12(rigRoot, "cache"),
1941
+ sessionDir: resolve12(rigRoot, "session"),
1883
1942
  binDir,
1884
- distDir: resolve11(rigRoot, "dist"),
1885
- pluginBinDir: resolve11(binDir, "plugins"),
1886
- contextPath: resolve11(rigRoot, "runtime-context.json"),
1887
- controlPlaneEventsFile: resolve11(logsDir, "control-plane.events.jsonl")
1943
+ distDir: resolve12(rigRoot, "dist"),
1944
+ pluginBinDir: resolve12(binDir, "plugins"),
1945
+ contextPath: resolve12(rigRoot, "runtime-context.json"),
1946
+ controlPlaneEventsFile: resolve12(logsDir, "control-plane.events.jsonl")
1888
1947
  };
1889
1948
  }
1890
1949
  function resolveActiveRuntimeWorkspaceRoot(monorepoRoot) {
@@ -1892,14 +1951,14 @@ function resolveActiveRuntimeWorkspaceRoot(monorepoRoot) {
1892
1951
  if (!explicit) {
1893
1952
  throw new Error("No active runtime workspace. Set RIG_TASK_WORKSPACE or provision a task runtime first.");
1894
1953
  }
1895
- return resolve11(explicit);
1954
+ return resolve12(explicit);
1896
1955
  }
1897
1956
  function resolveRigLayout(projectRoot) {
1898
1957
  const monorepoRoot = resolveMonorepoRoot(projectRoot);
1899
- const definitionRoot = resolve11(projectRoot, RIG_DEFINITION_DIRNAME);
1958
+ const definitionRoot = resolve12(projectRoot, RIG_DEFINITION_DIRNAME);
1900
1959
  const runtimeWorkspaceRoot = resolveActiveRuntimeWorkspaceRoot(monorepoRoot);
1901
1960
  const runtimeLayout = resolveRuntimeWorkspaceLayout(runtimeWorkspaceRoot);
1902
- const policyDir = resolve11(definitionRoot, "policy");
1961
+ const policyDir = resolve12(definitionRoot, "policy");
1903
1962
  return {
1904
1963
  projectRoot,
1905
1964
  monorepoRoot,
@@ -1907,48 +1966,48 @@ function resolveRigLayout(projectRoot) {
1907
1966
  runtimeWorkspaceRoot,
1908
1967
  stateRoot: runtimeLayout.rigRoot,
1909
1968
  artifactsRoot: runtimeLayout.artifactsRoot,
1910
- configPath: resolve11(definitionRoot, "config.sh"),
1911
- taskConfigPath: resolve11(runtimeWorkspaceRoot, ".rig", "task-config.json"),
1969
+ configPath: resolve12(definitionRoot, "config.sh"),
1970
+ taskConfigPath: resolve12(runtimeWorkspaceRoot, ".rig", "task-config.json"),
1912
1971
  policyDir,
1913
- policyFile: resolve11(policyDir, "policy.json"),
1914
- pluginsDir: resolve11(definitionRoot, "plugins"),
1915
- hooksDir: resolve11(definitionRoot, "hooks"),
1916
- toolsDir: resolve11(definitionRoot, "tools"),
1917
- templatesDir: resolve11(definitionRoot, "templates"),
1918
- validationDir: resolve11(definitionRoot, "validation"),
1972
+ policyFile: resolve12(policyDir, "policy.json"),
1973
+ pluginsDir: resolve12(definitionRoot, "plugins"),
1974
+ hooksDir: resolve12(definitionRoot, "hooks"),
1975
+ toolsDir: resolve12(definitionRoot, "tools"),
1976
+ templatesDir: resolve12(definitionRoot, "templates"),
1977
+ validationDir: resolve12(definitionRoot, "validation"),
1919
1978
  stateDir: runtimeLayout.stateDir,
1920
1979
  logsDir: runtimeLayout.logsDir,
1921
- notificationsDir: resolve11(definitionRoot, "notifications"),
1980
+ notificationsDir: resolve12(definitionRoot, "notifications"),
1922
1981
  runtimeDir: runtimeLayout.runtimeDir,
1923
1982
  distDir: runtimeLayout.distDir,
1924
1983
  binDir: runtimeLayout.binDir,
1925
1984
  pluginBinDir: runtimeLayout.pluginBinDir,
1926
- keybindingsPath: resolve11(definitionRoot, "keybindings.json"),
1985
+ keybindingsPath: resolve12(definitionRoot, "keybindings.json"),
1927
1986
  controlPlaneEventsFile: runtimeLayout.controlPlaneEventsFile
1928
1987
  };
1929
1988
  }
1930
1989
 
1931
1990
  // packages/runtime/src/control-plane/native/runtime-native.ts
1932
1991
  import { dlopen, ptr, suffix, toBuffer } from "bun:ffi";
1933
- import { copyFileSync as copyFileSync2, existsSync as existsSync10, mkdirSync as mkdirSync5, renameSync as renameSync2, rmSync as rmSync3, statSync as statSync2 } from "fs";
1992
+ import { copyFileSync as copyFileSync2, existsSync as existsSync12, mkdirSync as mkdirSync6, renameSync as renameSync2, rmSync as rmSync3, statSync as statSync2 } from "fs";
1934
1993
  import { tmpdir as tmpdir4 } from "os";
1935
- import { dirname as dirname7, resolve as resolve12 } from "path";
1936
- var sharedNativeRuntimeOutputDir = resolve12(tmpdir4(), "rig-native");
1937
- var sharedNativeRuntimeOutputPath = resolve12(sharedNativeRuntimeOutputDir, `runtime-native-${process.platform}-${process.arch}.${suffix}`);
1994
+ import { dirname as dirname8, resolve as resolve13 } from "path";
1995
+ var sharedNativeRuntimeOutputDir = resolve13(tmpdir4(), "rig-native");
1996
+ var sharedNativeRuntimeOutputPath = resolve13(sharedNativeRuntimeOutputDir, `runtime-native-${process.platform}-${process.arch}.${suffix}`);
1938
1997
  var colocatedNativeRuntimeFileName = `runtime-native.${suffix}`;
1939
1998
  var nativeRuntimeLibrary = await loadNativeRuntimeLibrary();
1940
1999
  async function ensureNativeRuntimeLibraryPath(outputPath = sharedNativeRuntimeOutputPath, options = {}) {
1941
2000
  if (await buildNativeRuntimeLibrary(outputPath, options)) {
1942
2001
  return outputPath;
1943
2002
  }
1944
- return !options.force && existsSync10(outputPath) ? outputPath : null;
2003
+ return !options.force && existsSync12(outputPath) ? outputPath : null;
1945
2004
  }
1946
2005
  async function loadNativeRuntimeLibrary() {
1947
2006
  if (process.env.RIG_DISABLE_ZIG_NATIVE === "1") {
1948
2007
  return null;
1949
2008
  }
1950
2009
  for (const candidate of nativeRuntimeLibraryCandidates()) {
1951
- if (!candidate || !existsSync10(candidate)) {
2010
+ if (!candidate || !existsSync12(candidate)) {
1952
2011
  continue;
1953
2012
  }
1954
2013
  const loaded = tryDlopenNativeRuntimeLibrary(candidate);
@@ -1964,12 +2023,12 @@ async function loadNativeRuntimeLibrary() {
1964
2023
  }
1965
2024
  function nativePackageLibraryCandidates(fromDir, names) {
1966
2025
  const candidates = [];
1967
- let cursor = resolve12(fromDir);
2026
+ let cursor = resolve13(fromDir);
1968
2027
  for (let index = 0;index < 8; index += 1) {
1969
2028
  for (const name of names) {
1970
- candidates.push(resolve12(cursor, "native", `${process.platform}-${process.arch}`, name), resolve12(cursor, "native", `${process.platform}-${process.arch}`, "lib", name), resolve12(cursor, "native", name), resolve12(cursor, "native", "lib", name));
2029
+ candidates.push(resolve13(cursor, "native", `${process.platform}-${process.arch}`, name), resolve13(cursor, "native", `${process.platform}-${process.arch}`, "lib", name), resolve13(cursor, "native", name), resolve13(cursor, "native", "lib", name));
1971
2030
  }
1972
- const parent = dirname7(cursor);
2031
+ const parent = dirname8(cursor);
1973
2032
  if (parent === cursor)
1974
2033
  break;
1975
2034
  cursor = parent;
@@ -1978,27 +2037,27 @@ function nativePackageLibraryCandidates(fromDir, names) {
1978
2037
  }
1979
2038
  function nativeRuntimeLibraryCandidates() {
1980
2039
  const explicit = process.env.RIG_NATIVE_RUNTIME_LIB?.trim() || "";
1981
- const execDir = process.execPath?.trim() ? dirname7(process.execPath.trim()) : "";
2040
+ const execDir = process.execPath?.trim() ? dirname8(process.execPath.trim()) : "";
1982
2041
  const platformSpecific = `runtime-native-${process.platform}-${process.arch}.${suffix}`;
1983
2042
  return [...new Set([
1984
2043
  explicit,
1985
2044
  ...nativePackageLibraryCandidates(import.meta.dir, [colocatedNativeRuntimeFileName, platformSpecific]),
1986
- execDir ? resolve12(execDir, colocatedNativeRuntimeFileName) : "",
1987
- execDir ? resolve12(execDir, platformSpecific) : "",
1988
- execDir ? resolve12(execDir, "..", colocatedNativeRuntimeFileName) : "",
1989
- execDir ? resolve12(execDir, "..", platformSpecific) : "",
1990
- execDir ? resolve12(execDir, "lib", colocatedNativeRuntimeFileName) : "",
1991
- execDir ? resolve12(execDir, "..", "lib", colocatedNativeRuntimeFileName) : "",
2045
+ execDir ? resolve13(execDir, colocatedNativeRuntimeFileName) : "",
2046
+ execDir ? resolve13(execDir, platformSpecific) : "",
2047
+ execDir ? resolve13(execDir, "..", colocatedNativeRuntimeFileName) : "",
2048
+ execDir ? resolve13(execDir, "..", platformSpecific) : "",
2049
+ execDir ? resolve13(execDir, "lib", colocatedNativeRuntimeFileName) : "",
2050
+ execDir ? resolve13(execDir, "..", "lib", colocatedNativeRuntimeFileName) : "",
1992
2051
  sharedNativeRuntimeOutputPath
1993
2052
  ].filter(Boolean))];
1994
2053
  }
1995
2054
  function resolveNativeRuntimeSourcePath() {
1996
2055
  const explicit = process.env.RIG_NATIVE_RUNTIME_SOURCE?.trim();
1997
- if (explicit && existsSync10(explicit)) {
2056
+ if (explicit && existsSync12(explicit)) {
1998
2057
  return explicit;
1999
2058
  }
2000
- const bundled = resolve12(import.meta.dir, "../../../native/snapshot.zig");
2001
- return existsSync10(bundled) ? bundled : null;
2059
+ const bundled = resolve13(import.meta.dir, "../../../native/snapshot.zig");
2060
+ return existsSync12(bundled) ? bundled : null;
2002
2061
  }
2003
2062
  async function buildNativeRuntimeLibrary(outputPath, options = {}) {
2004
2063
  if (process.env.RIG_DISABLE_ZIG_NATIVE === "1") {
@@ -2011,8 +2070,8 @@ async function buildNativeRuntimeLibrary(outputPath, options = {}) {
2011
2070
  }
2012
2071
  const tempOutputPath = `${outputPath}.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2)}.tmp`;
2013
2072
  try {
2014
- mkdirSync5(dirname7(outputPath), { recursive: true });
2015
- const needsBuild = options.force === true || !existsSync10(outputPath) || statSync2(sourcePath).mtimeMs > statSync2(outputPath).mtimeMs;
2073
+ mkdirSync6(dirname8(outputPath), { recursive: true });
2074
+ const needsBuild = options.force === true || !existsSync12(outputPath) || statSync2(sourcePath).mtimeMs > statSync2(outputPath).mtimeMs;
2016
2075
  if (!needsBuild) {
2017
2076
  return true;
2018
2077
  }
@@ -2030,7 +2089,7 @@ async function buildNativeRuntimeLibrary(outputPath, options = {}) {
2030
2089
  stderr: "pipe"
2031
2090
  });
2032
2091
  const exitCode = await build.exited;
2033
- if (exitCode !== 0 || !existsSync10(tempOutputPath)) {
2092
+ if (exitCode !== 0 || !existsSync12(tempOutputPath)) {
2034
2093
  rmSync3(tempOutputPath, { force: true });
2035
2094
  return false;
2036
2095
  }
@@ -2160,11 +2219,11 @@ async function runCaptureAsync(command, cwd, env, timeoutMs) {
2160
2219
  return { exitCode, stdout, stderr };
2161
2220
  }
2162
2221
  function readJsonFile(path, fallback) {
2163
- if (!existsSync11(path)) {
2222
+ if (!existsSync13(path)) {
2164
2223
  return fallback;
2165
2224
  }
2166
2225
  try {
2167
- return JSON.parse(readFileSync8(path, "utf-8"));
2226
+ return JSON.parse(readFileSync9(path, "utf-8"));
2168
2227
  } catch {
2169
2228
  return fallback;
2170
2229
  }
@@ -2178,31 +2237,31 @@ function unique(values) {
2178
2237
  function resolveHarnessPaths(projectRoot) {
2179
2238
  const hasRuntimeWorkspace = Boolean(process.env.RIG_TASK_WORKSPACE?.trim());
2180
2239
  const monorepoRoot = resolveMonorepoRoot2(projectRoot);
2181
- const harnessRoot = resolve13(projectRoot, "rig");
2182
- const stateRoot = resolve13(projectRoot, ".rig");
2240
+ const harnessRoot = resolve14(projectRoot, "rig");
2241
+ const stateRoot = resolve14(projectRoot, ".rig");
2183
2242
  const layout = hasRuntimeWorkspace ? resolveRigLayout(projectRoot) : null;
2184
- const stateDir = layout?.stateDir ?? resolve13(stateRoot, "state");
2185
- const logsDir = layout?.logsDir ?? resolve13(stateRoot, "logs");
2186
- const artifactsDir = layout?.artifactsRoot ?? resolve13(monorepoRoot, "artifacts");
2187
- const taskConfigPath = layout?.taskConfigPath ?? resolve13(monorepoRoot, ".rig", "task-config.json");
2188
- const binDir = layout?.binDir ?? resolve13(stateRoot, "bin");
2243
+ const stateDir = layout?.stateDir ?? resolve14(stateRoot, "state");
2244
+ const logsDir = layout?.logsDir ?? resolve14(stateRoot, "logs");
2245
+ const artifactsDir = layout?.artifactsRoot ?? resolve14(monorepoRoot, "artifacts");
2246
+ const taskConfigPath = layout?.taskConfigPath ?? resolve14(monorepoRoot, ".rig", "task-config.json");
2247
+ const binDir = layout?.binDir ?? resolve14(stateRoot, "bin");
2189
2248
  return {
2190
2249
  harnessRoot,
2191
2250
  stateDir: process.env.RIG_STATE_DIR || stateDir,
2192
2251
  artifactsDir,
2193
2252
  logsDir: process.env.RIG_LOGS_DIR || logsDir,
2194
2253
  binDir,
2195
- hooksDir: resolve13(harnessRoot, "hooks"),
2196
- validationDir: resolve13(harnessRoot, "validation"),
2254
+ hooksDir: resolve14(harnessRoot, "hooks"),
2255
+ validationDir: resolve14(harnessRoot, "validation"),
2197
2256
  taskConfigPath,
2198
- sessionPath: process.env.RIG_SESSION_FILE || resolve13(stateRoot, "session", "session.json"),
2257
+ sessionPath: process.env.RIG_SESSION_FILE || resolve14(stateRoot, "session", "session.json"),
2199
2258
  monorepoRoot,
2200
- tsApiTestsDir: process.env.TS_API_TESTS_DIR || resolve13(monorepoRoot, "TSAPITests"),
2201
- taskRepoCommitsPath: resolve13(stateDir, "task-repo-commits.json"),
2202
- baseRepoPinsPath: resolve13(stateDir, "base-repo-pins.json"),
2203
- failedApproachesPath: resolve13(stateDir, "failed_approaches.md"),
2204
- agentProfilePath: resolve13(stateDir, "agent-profile.json"),
2205
- reviewProfilePath: resolve13(stateDir, "review-profile.json")
2259
+ tsApiTestsDir: process.env.TS_API_TESTS_DIR || resolve14(monorepoRoot, "TSAPITests"),
2260
+ taskRepoCommitsPath: resolve14(stateDir, "task-repo-commits.json"),
2261
+ baseRepoPinsPath: resolve14(stateDir, "base-repo-pins.json"),
2262
+ failedApproachesPath: resolve14(stateDir, "failed_approaches.md"),
2263
+ agentProfilePath: resolve14(stateDir, "agent-profile.json"),
2264
+ reviewProfilePath: resolve14(stateDir, "review-profile.json")
2206
2265
  };
2207
2266
  }
2208
2267
  function normalizeRelativeScopePath(inputPath) {
@@ -2260,34 +2319,34 @@ function monorepoSearchCandidates(inputPath) {
2260
2319
  }
2261
2320
 
2262
2321
  // packages/runtime/src/control-plane/state-sync/repo.ts
2263
- import { existsSync as existsSync13 } from "fs";
2264
- import { resolve as resolve15 } from "path";
2322
+ import { existsSync as existsSync15 } from "fs";
2323
+ import { resolve as resolve16 } from "path";
2265
2324
 
2266
2325
  // packages/runtime/src/control-plane/repos/layout.ts
2267
- import { existsSync as existsSync12 } from "fs";
2268
- import { basename as basename5, dirname as dirname8, join as join3, resolve as resolve14 } from "path";
2326
+ import { existsSync as existsSync14 } from "fs";
2327
+ import { basename as basename5, dirname as dirname9, join as join3, resolve as resolve15 } from "path";
2269
2328
  function resolveRepoStateDir(projectRoot) {
2270
- const normalizedProjectRoot = resolve14(projectRoot);
2271
- const projectParent = dirname8(normalizedProjectRoot);
2329
+ const normalizedProjectRoot = resolve15(projectRoot);
2330
+ const projectParent = dirname9(normalizedProjectRoot);
2272
2331
  if (basename5(projectParent) === ".worktrees") {
2273
- const ownerRoot = dirname8(projectParent);
2274
- const ownerHasRepoMarkers = existsSync12(resolve14(ownerRoot, ".git")) || existsSync12(resolve14(ownerRoot, ".rig", "state"));
2332
+ const ownerRoot = dirname9(projectParent);
2333
+ const ownerHasRepoMarkers = existsSync14(resolve15(ownerRoot, ".git")) || existsSync14(resolve15(ownerRoot, ".rig", "state"));
2275
2334
  if (ownerHasRepoMarkers) {
2276
- return resolve14(ownerRoot, ".rig", "state");
2335
+ return resolve15(ownerRoot, ".rig", "state");
2277
2336
  }
2278
2337
  }
2279
- return resolve14(projectRoot, ".rig", "state");
2338
+ return resolve15(projectRoot, ".rig", "state");
2280
2339
  }
2281
2340
  function resolveManagedRepoLayout(projectRoot, repoId) {
2282
- const normalizedProjectRoot = resolve14(projectRoot);
2341
+ const normalizedProjectRoot = resolve15(projectRoot);
2283
2342
  const entry = getManagedRepoEntry(repoId);
2284
2343
  const stateDir = resolveRepoStateDir(normalizedProjectRoot);
2285
2344
  const metadataRelativePath = join3("repos", entry.id);
2286
- const metadataRoot = resolve14(stateDir, metadataRelativePath);
2345
+ const metadataRoot = resolve15(stateDir, metadataRelativePath);
2287
2346
  const runtimeWorkspace = process.env.RIG_TASK_WORKSPACE?.trim();
2288
- const runsInsideTaskWorktree = runtimeWorkspace && resolve14(runtimeWorkspace) === normalizedProjectRoot || basename5(dirname8(normalizedProjectRoot)) === ".worktrees";
2347
+ const runsInsideTaskWorktree = runtimeWorkspace && resolve15(runtimeWorkspace) === normalizedProjectRoot || basename5(dirname9(normalizedProjectRoot)) === ".worktrees";
2289
2348
  const isPrimaryManagedRepo = listManagedRepoEntries()[0]?.id === repoId;
2290
- const checkoutRoot = isPrimaryManagedRepo && runsInsideTaskWorktree ? resolveMonorepoRoot(normalizedProjectRoot) : entry.checkoutEnvVar && process.env[entry.checkoutEnvVar]?.trim() ? resolve14(process.env[entry.checkoutEnvVar].trim()) : resolve14(normalizedProjectRoot, entry.alias);
2349
+ const checkoutRoot = isPrimaryManagedRepo && runsInsideTaskWorktree ? resolveMonorepoRoot(normalizedProjectRoot) : entry.checkoutEnvVar && process.env[entry.checkoutEnvVar]?.trim() ? resolve15(process.env[entry.checkoutEnvVar].trim()) : resolve15(normalizedProjectRoot, entry.alias);
2291
2350
  return {
2292
2351
  projectRoot: normalizedProjectRoot,
2293
2352
  repoId: entry.id,
@@ -2295,12 +2354,12 @@ function resolveManagedRepoLayout(projectRoot, repoId) {
2295
2354
  defaultBranch: entry.defaultBranch,
2296
2355
  remoteUrl: entry.remoteEnvVar && process.env[entry.remoteEnvVar]?.trim() ? process.env[entry.remoteEnvVar].trim() : entry.defaultRemoteUrl,
2297
2356
  checkoutRoot,
2298
- worktreesRoot: resolve14(checkoutRoot, ".worktrees"),
2357
+ worktreesRoot: resolve15(checkoutRoot, ".worktrees"),
2299
2358
  stateDir,
2300
2359
  metadataRoot,
2301
2360
  metadataRelativePath,
2302
- mirrorRoot: resolve14(metadataRoot, "mirror.git"),
2303
- mirrorStatePath: resolve14(metadataRoot, "mirror-state.json"),
2361
+ mirrorRoot: resolve15(metadataRoot, "mirror.git"),
2362
+ mirrorStatePath: resolve15(metadataRoot, "mirror-state.json"),
2304
2363
  mirrorStateRelativePath: join3(metadataRelativePath, "mirror-state.json")
2305
2364
  };
2306
2365
  }
@@ -2322,7 +2381,7 @@ function resolveTrackerRepoPath(projectRoot) {
2322
2381
  const monorepoRoot = resolveMonorepoRoot2(projectRoot);
2323
2382
  try {
2324
2383
  const layout = resolveMonorepoRepoLayout(projectRoot);
2325
- if (existsSync13(resolve15(layout.mirrorRoot, "HEAD"))) {
2384
+ if (existsSync15(resolve16(layout.mirrorRoot, "HEAD"))) {
2326
2385
  return layout.mirrorRoot;
2327
2386
  }
2328
2387
  } catch {}
@@ -2333,8 +2392,8 @@ function resolveTrackerRepoPath(projectRoot) {
2333
2392
  var DEFAULT_READ_DEPS = {
2334
2393
  fetchRef: nativeFetchRef,
2335
2394
  readBlobAtRef: nativeReadBlobAtRef,
2336
- exists: existsSync14,
2337
- readFile: (path) => readFileSync9(path, "utf8")
2395
+ exists: existsSync16,
2396
+ readFile: (path) => readFileSync10(path, "utf8")
2338
2397
  };
2339
2398
  function parseIssueStatus(rawStatus) {
2340
2399
  const normalized = normalizeTaskLifecycleStatus(rawStatus);
@@ -2415,12 +2474,12 @@ function shouldPreferLocalTrackerState(options) {
2415
2474
  if (runtimeContextPath) {
2416
2475
  return true;
2417
2476
  }
2418
- return existsSync14(resolve16(runtimeWorkspace, ".rig", "runtime-context.json"));
2477
+ return existsSync16(resolve17(runtimeWorkspace, ".rig", "runtime-context.json"));
2419
2478
  }
2420
2479
  function readLocalTrackerState(projectRoot, deps) {
2421
2480
  const monorepoRoot = resolveMonorepoRoot2(projectRoot);
2422
- const issuesPath = resolve16(monorepoRoot, ".beads", "issues.jsonl");
2423
- const taskStatePath = resolve16(monorepoRoot, ".beads", "task-state.json");
2481
+ const issuesPath = resolve17(monorepoRoot, ".beads", "issues.jsonl");
2482
+ const taskStatePath = resolve17(monorepoRoot, ".beads", "task-state.json");
2424
2483
  return projectSyncedTrackerSnapshot({
2425
2484
  source: "local",
2426
2485
  issuesBaseOid: null,
@@ -2482,7 +2541,7 @@ function readValidationDescriptions(projectRoot) {
2482
2541
  return readValidationDescriptionMap(raw);
2483
2542
  }
2484
2543
  function readSourceValidationDescriptions(projectRoot) {
2485
- const rootRaw = readJsonFile(resolve17(projectRoot, "rig", "task-config.json"), {});
2544
+ const rootRaw = readJsonFile(resolve18(projectRoot, "rig", "task-config.json"), {});
2486
2545
  const sourcePath = findSourceTaskConfigPath(projectRoot);
2487
2546
  const sourceRaw = sourcePath ? readJsonFile(sourcePath, {}) : {};
2488
2547
  const rootDescriptions = readValidationDescriptionMap(rootRaw);
@@ -2558,15 +2617,15 @@ function readValidationDescriptionsFromMeta(meta) {
2558
2617
  return meta.validation_descriptions;
2559
2618
  }
2560
2619
  function readLocalSourceTaskStateEnvelope(projectRoot) {
2561
- const taskStatePath = resolve17(resolveMonorepoRoot2(projectRoot), ".beads", "task-state.json");
2620
+ const taskStatePath = resolve18(resolveMonorepoRoot2(projectRoot), ".beads", "task-state.json");
2562
2621
  return readTaskStateMetadataEnvelope(readJsonFile(taskStatePath, {}));
2563
2622
  }
2564
2623
  function readLocalSourceTaskLifecycleStatus(projectRoot, taskId) {
2565
- const issuesPath = resolve17(resolveMonorepoRoot2(projectRoot), ".beads", "issues.jsonl");
2566
- if (!existsSync15(issuesPath)) {
2624
+ const issuesPath = resolve18(resolveMonorepoRoot2(projectRoot), ".beads", "issues.jsonl");
2625
+ if (!existsSync17(issuesPath)) {
2567
2626
  return null;
2568
2627
  }
2569
- for (const line of readFileSync10(issuesPath, "utf8").split(/\r?\n/)) {
2628
+ for (const line of readFileSync11(issuesPath, "utf8").split(/\r?\n/)) {
2570
2629
  const trimmed = line.trim();
2571
2630
  if (!trimmed) {
2572
2631
  continue;
@@ -2607,25 +2666,25 @@ function lookupTask(projectRoot, input) {
2607
2666
  function artifactDirForId(projectRoot, id) {
2608
2667
  const workspaceDir = process.env.RIG_TASK_WORKSPACE?.trim();
2609
2668
  if (workspaceDir) {
2610
- const worktreeArtifacts = resolve17(workspaceDir, "artifacts", id);
2611
- if (existsSync15(worktreeArtifacts) || existsSync15(resolve17(workspaceDir, "artifacts"))) {
2669
+ const worktreeArtifacts = resolve18(workspaceDir, "artifacts", id);
2670
+ if (existsSync17(worktreeArtifacts) || existsSync17(resolve18(workspaceDir, "artifacts"))) {
2612
2671
  return worktreeArtifacts;
2613
2672
  }
2614
2673
  }
2615
2674
  try {
2616
2675
  const paths = resolveHarnessPaths(projectRoot);
2617
- return resolve17(paths.artifactsDir, id);
2676
+ return resolve18(paths.artifactsDir, id);
2618
2677
  } catch {
2619
- return resolve17(resolveMonorepoRoot2(projectRoot), "artifacts", id);
2678
+ return resolve18(resolveMonorepoRoot2(projectRoot), "artifacts", id);
2620
2679
  }
2621
2680
  }
2622
2681
  function resolveTaskConfigPath(projectRoot) {
2623
2682
  const paths = resolveHarnessPaths(projectRoot);
2624
- if (existsSync15(paths.taskConfigPath)) {
2683
+ if (existsSync17(paths.taskConfigPath)) {
2625
2684
  return paths.taskConfigPath;
2626
2685
  }
2627
2686
  for (const candidate of sourceTaskConfigCandidates(projectRoot)) {
2628
- if (existsSync15(candidate)) {
2687
+ if (existsSync17(candidate)) {
2629
2688
  return candidate;
2630
2689
  }
2631
2690
  }
@@ -2633,7 +2692,7 @@ function resolveTaskConfigPath(projectRoot) {
2633
2692
  }
2634
2693
  function findSourceTaskConfigPath(projectRoot) {
2635
2694
  for (const candidate of sourceTaskConfigCandidates(projectRoot)) {
2636
- if (existsSync15(candidate)) {
2695
+ if (existsSync17(candidate)) {
2637
2696
  return candidate;
2638
2697
  }
2639
2698
  }
@@ -2646,7 +2705,7 @@ function readAndSyncSourceTaskConfig(projectRoot) {
2646
2705
  const synced = synchronizeTaskConfigWithTracker(projectRoot, raw);
2647
2706
  if (sourcePath && synced.updated) {
2648
2707
  try {
2649
- writeFileSync6(sourcePath, `${JSON.stringify(synced.config, null, 2)}
2708
+ writeFileSync7(sourcePath, `${JSON.stringify(synced.config, null, 2)}
2650
2709
  `, "utf-8");
2651
2710
  } catch {}
2652
2711
  }
@@ -2698,12 +2757,12 @@ function shouldRefreshAutoSyncedTaskConfigEntry(entry) {
2698
2757
  return !candidate.role;
2699
2758
  }
2700
2759
  function readSourceIssueRecords(projectRoot) {
2701
- const issuesPath = resolve17(resolveMonorepoRoot2(projectRoot), ".beads", "issues.jsonl");
2702
- if (!existsSync15(issuesPath)) {
2760
+ const issuesPath = resolve18(resolveMonorepoRoot2(projectRoot), ".beads", "issues.jsonl");
2761
+ if (!existsSync17(issuesPath)) {
2703
2762
  return [];
2704
2763
  }
2705
2764
  const records = [];
2706
- for (const line of readFileSync10(issuesPath, "utf-8").split(/\r?\n/)) {
2765
+ for (const line of readFileSync11(issuesPath, "utf-8").split(/\r?\n/)) {
2707
2766
  const trimmed = line.trim();
2708
2767
  if (!trimmed) {
2709
2768
  continue;
@@ -2759,19 +2818,19 @@ function readConfiguredFileTaskConfig(projectRoot) {
2759
2818
  if (!sourcePath) {
2760
2819
  return {};
2761
2820
  }
2762
- const directory = resolve17(projectRoot, sourcePath);
2763
- if (!existsSync15(directory)) {
2821
+ const directory = resolve18(projectRoot, sourcePath);
2822
+ if (!existsSync17(directory)) {
2764
2823
  return {};
2765
2824
  }
2766
2825
  const config = {};
2767
2826
  for (const name of readdirSync3(directory)) {
2768
2827
  if (!FILE_TASK_PATTERN2.test(name))
2769
2828
  continue;
2770
- const file = resolve17(directory, name);
2829
+ const file = resolve18(directory, name);
2771
2830
  try {
2772
2831
  if (!statSync3(file).isFile())
2773
2832
  continue;
2774
- const raw = JSON.parse(readFileSync10(file, "utf8"));
2833
+ const raw = JSON.parse(readFileSync11(file, "utf8"));
2775
2834
  if (!raw || typeof raw !== "object" || Array.isArray(raw))
2776
2835
  continue;
2777
2836
  const record = raw;
@@ -2813,10 +2872,10 @@ function firstStringList2(...candidates) {
2813
2872
  return [];
2814
2873
  }
2815
2874
  function readConfiguredFilesTaskSourcePath2(projectRoot) {
2816
- const jsonPath = resolve17(projectRoot, "rig.config.json");
2817
- if (existsSync15(jsonPath)) {
2875
+ const jsonPath = resolve18(projectRoot, "rig.config.json");
2876
+ if (existsSync17(jsonPath)) {
2818
2877
  try {
2819
- const parsed = JSON.parse(readFileSync10(jsonPath, "utf8"));
2878
+ const parsed = JSON.parse(readFileSync11(jsonPath, "utf8"));
2820
2879
  if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
2821
2880
  const taskSource = parsed.taskSource;
2822
2881
  if (taskSource && typeof taskSource === "object" && !Array.isArray(taskSource)) {
@@ -2828,12 +2887,12 @@ function readConfiguredFilesTaskSourcePath2(projectRoot) {
2828
2887
  return null;
2829
2888
  }
2830
2889
  }
2831
- const tsPath = resolve17(projectRoot, "rig.config.ts");
2832
- if (!existsSync15(tsPath)) {
2890
+ const tsPath = resolve18(projectRoot, "rig.config.ts");
2891
+ if (!existsSync17(tsPath)) {
2833
2892
  return null;
2834
2893
  }
2835
2894
  try {
2836
- const source = readFileSync10(tsPath, "utf8");
2895
+ const source = readFileSync11(tsPath, "utf8");
2837
2896
  const taskSourceBlock = source.match(/taskSource\s*:\s*\{[\s\S]*?\}/m)?.[0] ?? "";
2838
2897
  const kind = taskSourceBlock.match(/kind\s*:\s*["']([^"']+)["']/)?.[1];
2839
2898
  if (kind !== "files") {
@@ -2847,23 +2906,23 @@ function readConfiguredFilesTaskSourcePath2(projectRoot) {
2847
2906
  function sourceTaskConfigCandidates(projectRoot) {
2848
2907
  const runtimeContext = loadRuntimeContextFromEnv();
2849
2908
  return [
2850
- runtimeContext?.monorepoMainRoot ? resolve17(runtimeContext.monorepoMainRoot, ".rig", "task-config.json") : "",
2851
- process.env.MONOREPO_MAIN_ROOT?.trim() ? resolve17(process.env.MONOREPO_MAIN_ROOT.trim(), ".rig", "task-config.json") : "",
2852
- resolve17(resolveMonorepoRoot2(projectRoot), ".rig", "task-config.json")
2909
+ runtimeContext?.monorepoMainRoot ? resolve18(runtimeContext.monorepoMainRoot, ".rig", "task-config.json") : "",
2910
+ process.env.MONOREPO_MAIN_ROOT?.trim() ? resolve18(process.env.MONOREPO_MAIN_ROOT.trim(), ".rig", "task-config.json") : "",
2911
+ resolve18(resolveMonorepoRoot2(projectRoot), ".rig", "task-config.json")
2853
2912
  ].filter(Boolean);
2854
2913
  }
2855
2914
 
2856
2915
  // packages/runtime/src/control-plane/native/validator.ts
2857
- import { existsSync as existsSync19, mkdirSync as mkdirSync8, writeFileSync as writeFileSync8 } from "fs";
2858
- import { resolve as resolve22 } from "path";
2916
+ import { existsSync as existsSync21, mkdirSync as mkdirSync9, writeFileSync as writeFileSync9 } from "fs";
2917
+ import { resolve as resolve23 } from "path";
2859
2918
 
2860
2919
  // packages/runtime/src/control-plane/native/validator-binaries.ts
2861
- import { existsSync as existsSync18, mkdirSync as mkdirSync7, rmSync as rmSync5, statSync as statSync4 } from "fs";
2862
- import { dirname as dirname10, resolve as resolve21 } from "path";
2920
+ import { existsSync as existsSync20, mkdirSync as mkdirSync8, rmSync as rmSync5, statSync as statSync4 } from "fs";
2921
+ import { dirname as dirname11, resolve as resolve22 } from "path";
2863
2922
 
2864
2923
  // packages/runtime/src/binary-run.ts
2865
- import { chmodSync as chmodSync2, cpSync, existsSync as existsSync16, mkdirSync as mkdirSync6, renameSync as renameSync3, rmSync as rmSync4, writeFileSync as writeFileSync7 } from "fs";
2866
- import { basename as basename7, dirname as dirname9, resolve as resolve18 } from "path";
2924
+ import { chmodSync as chmodSync2, cpSync, existsSync as existsSync18, mkdirSync as mkdirSync7, renameSync as renameSync3, rmSync as rmSync4, writeFileSync as writeFileSync8 } from "fs";
2925
+ import { basename as basename7, dirname as dirname10, resolve as resolve19 } from "path";
2867
2926
  import { fileURLToPath } from "url";
2868
2927
  import { drainMicrotasks, gcAndSweep } from "bun:jsc";
2869
2928
  var runtimeBinaryBuildQueue = Promise.resolve();
@@ -2889,9 +2948,9 @@ async function buildRuntimeBinary(options) {
2889
2948
  });
2890
2949
  }
2891
2950
  async function buildRuntimeBinaryInProcess(options, manifest) {
2892
- const tempBuildDir = resolve18(dirname9(options.outputPath), `.bun-build-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`);
2893
- const tempOutputPath = resolve18(tempBuildDir, basename7(options.outputPath));
2894
- mkdirSync6(tempBuildDir, { recursive: true });
2951
+ const tempBuildDir = resolve19(dirname10(options.outputPath), `.bun-build-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`);
2952
+ const tempOutputPath = resolve19(tempBuildDir, basename7(options.outputPath));
2953
+ mkdirSync7(tempBuildDir, { recursive: true });
2895
2954
  await withTemporaryEnv({
2896
2955
  ...options.env,
2897
2956
  ...options.define ? { RIG_BUILD_CONFIG_JSON: JSON.stringify(options.define) } : {}
@@ -2916,7 +2975,7 @@ async function buildRuntimeBinaryInProcess(options, manifest) {
2916
2975
  `);
2917
2976
  throw new Error(`Failed to build ${options.entrypoint}: ${details || "Bun.build() returned errors"}`);
2918
2977
  }
2919
- if (!existsSync16(tempOutputPath)) {
2978
+ if (!existsSync18(tempOutputPath)) {
2920
2979
  const emitted = buildResult.outputs.map((output) => output.path).join(", ") || "(none)";
2921
2980
  throw new Error(`Failed to build ${options.entrypoint}: Bun.build() did not emit ${tempOutputPath}. Emitted: ${emitted}`);
2922
2981
  }
@@ -2948,8 +3007,8 @@ function runtimeBinaryCacheManifestPath(outputPath) {
2948
3007
  function resolveRuntimeBinaryBuildOptions(options) {
2949
3008
  return {
2950
3009
  ...options,
2951
- entrypoint: resolve18(options.cwd, options.sourcePath),
2952
- outputPath: resolve18(options.outputPath)
3010
+ entrypoint: resolve19(options.cwd, options.sourcePath),
3011
+ outputPath: resolve19(options.outputPath)
2953
3012
  };
2954
3013
  }
2955
3014
  function shouldUseRuntimeBinaryBuildWorker() {
@@ -2963,7 +3022,7 @@ function shouldUseRuntimeBinaryBuildWorker() {
2963
3022
  }
2964
3023
  async function buildRuntimeBinaryViaWorker(options) {
2965
3024
  const workerSourcePath = resolveRuntimeBinaryBuildWorkerSourcePath(options);
2966
- if (!workerSourcePath || !existsSync16(workerSourcePath)) {
3025
+ if (!workerSourcePath || !existsSync18(workerSourcePath)) {
2967
3026
  await buildRuntimeBinaryInProcess(options, {
2968
3027
  manifestPath: runtimeBinaryCacheManifestPath(options.outputPath),
2969
3028
  buildKey: createRuntimeBinaryBuildKey({
@@ -3000,7 +3059,7 @@ async function buildRuntimeBinaryViaWorker(options) {
3000
3059
  }
3001
3060
  }
3002
3061
  function createRuntimeBinaryBuildWorkerPayloadPath(outputPath) {
3003
- return resolve18(dirname9(outputPath), `.bun-build-worker-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`);
3062
+ return resolve19(dirname10(outputPath), `.bun-build-worker-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`);
3004
3063
  }
3005
3064
  function resolveRuntimeBinaryBuildWorkerSourcePath(options) {
3006
3065
  const envRoots = [
@@ -3009,13 +3068,13 @@ function resolveRuntimeBinaryBuildWorkerSourcePath(options) {
3009
3068
  process.env.PROJECT_RIG_ROOT?.trim()
3010
3069
  ].filter(Boolean);
3011
3070
  for (const root of envRoots) {
3012
- const candidate = resolve18(root, "packages/runtime/src/binary-build-worker.ts");
3013
- if (existsSync16(candidate)) {
3071
+ const candidate = resolve19(root, "packages/runtime/src/binary-build-worker.ts");
3072
+ if (existsSync18(candidate)) {
3014
3073
  return candidate;
3015
3074
  }
3016
3075
  }
3017
- const localCandidate = resolve18(import.meta.dir, "binary-build-worker.ts");
3018
- return existsSync16(localCandidate) ? localCandidate : null;
3076
+ const localCandidate = resolve19(import.meta.dir, "binary-build-worker.ts");
3077
+ return existsSync18(localCandidate) ? localCandidate : null;
3019
3078
  }
3020
3079
  function resolveRuntimeBinaryBuildWorkerInvocation() {
3021
3080
  const bunPath = Bun.which("bun");
@@ -3051,7 +3110,7 @@ function createRuntimeBinaryBuildKey(input) {
3051
3110
  });
3052
3111
  }
3053
3112
  async function isRuntimeBinaryBuildFresh(input) {
3054
- if (!existsSync16(input.outputPath) || !existsSync16(input.manifestPath)) {
3113
+ if (!existsSync18(input.outputPath) || !existsSync18(input.manifestPath)) {
3055
3114
  return false;
3056
3115
  }
3057
3116
  let manifest = null;
@@ -3064,7 +3123,7 @@ async function isRuntimeBinaryBuildFresh(input) {
3064
3123
  return false;
3065
3124
  }
3066
3125
  for (const [filePath, expectedDigest] of Object.entries(manifest.inputs || {})) {
3067
- if (!existsSync16(filePath)) {
3126
+ if (!existsSync18(filePath)) {
3068
3127
  return false;
3069
3128
  }
3070
3129
  if (await sha256File(filePath) !== expectedDigest) {
@@ -3077,7 +3136,7 @@ async function writeRuntimeBinaryCacheManifest(input) {
3077
3136
  const inputs = {};
3078
3137
  for (const inputPath of Object.keys(input.metafile?.inputs || {}).sort()) {
3079
3138
  const normalized = normalizeBuildInputPath(input.cwd, inputPath);
3080
- if (!normalized || !existsSync16(normalized)) {
3139
+ if (!normalized || !existsSync18(normalized)) {
3081
3140
  continue;
3082
3141
  }
3083
3142
  inputs[normalized] = await sha256File(normalized);
@@ -3100,7 +3159,7 @@ function normalizeBuildInputPath(cwd, inputPath) {
3100
3159
  if (inputPath.startsWith("<")) {
3101
3160
  return null;
3102
3161
  }
3103
- return resolve18(cwd, inputPath);
3162
+ return resolve19(cwd, inputPath);
3104
3163
  }
3105
3164
  async function sha256File(path) {
3106
3165
  const hasher = new Bun.CryptoHasher("sha256");
@@ -3116,8 +3175,8 @@ function sortRecord(value) {
3116
3175
  async function runSerializedRuntimeBinaryBuild(action) {
3117
3176
  const previous = runtimeBinaryBuildQueue;
3118
3177
  let release;
3119
- runtimeBinaryBuildQueue = new Promise((resolve19) => {
3120
- release = resolve19;
3178
+ runtimeBinaryBuildQueue = new Promise((resolve20) => {
3179
+ release = resolve20;
3121
3180
  });
3122
3181
  await previous;
3123
3182
  try {
@@ -3162,11 +3221,11 @@ async function withTemporaryCwd(cwd, action) {
3162
3221
  }
3163
3222
 
3164
3223
  // packages/runtime/src/control-plane/runtime/provisioning-env.ts
3165
- import { delimiter, resolve as resolve20 } from "path";
3224
+ import { delimiter, resolve as resolve21 } from "path";
3166
3225
 
3167
3226
  // packages/runtime/src/control-plane/runtime/runtime-paths.ts
3168
- import { existsSync as existsSync17, readdirSync as readdirSync4, realpathSync } from "fs";
3169
- import { resolve as resolve19 } from "path";
3227
+ import { existsSync as existsSync19, readdirSync as readdirSync4, realpathSync } from "fs";
3228
+ import { resolve as resolve20 } from "path";
3170
3229
 
3171
3230
  // packages/runtime/src/control-plane/runtime/sandbox/utils.ts
3172
3231
  function uniq(values) {
@@ -3184,7 +3243,7 @@ function resolveBunBinaryPath() {
3184
3243
  }
3185
3244
  const home = process.env.HOME?.trim();
3186
3245
  const fallbackCandidates = [
3187
- home ? resolve19(home, ".bun/bin/bun") : "",
3246
+ home ? resolve20(home, ".bun/bin/bun") : "",
3188
3247
  "/opt/homebrew/bin/bun",
3189
3248
  "/usr/local/bin/bun",
3190
3249
  "/usr/bin/bun"
@@ -3212,8 +3271,8 @@ function resolveClaudeBinaryPath() {
3212
3271
  }
3213
3272
  const home = process.env.HOME?.trim();
3214
3273
  const fallbackCandidates = [
3215
- home ? resolve19(home, ".local/bin/claude") : "",
3216
- home ? resolve19(home, ".local/share/claude/local/claude") : "",
3274
+ home ? resolve20(home, ".local/bin/claude") : "",
3275
+ home ? resolve20(home, ".local/share/claude/local/claude") : "",
3217
3276
  "/opt/homebrew/bin/claude",
3218
3277
  "/usr/local/bin/claude",
3219
3278
  "/usr/bin/claude"
@@ -3227,51 +3286,51 @@ function resolveClaudeBinaryPath() {
3227
3286
  throw new Error("claude not found in PATH");
3228
3287
  }
3229
3288
  function resolveBunInstallDir(bunBinaryPath = resolveBunBinaryPath()) {
3230
- return resolve19(bunBinaryPath, "../..");
3289
+ return resolve20(bunBinaryPath, "../..");
3231
3290
  }
3232
3291
  function resolveClaudeInstallDir() {
3233
3292
  const realPath = resolveClaudeBinaryPath();
3234
- return resolve19(realPath, "..");
3293
+ return resolve20(realPath, "..");
3235
3294
  }
3236
3295
  function resolveNodeInstallDir() {
3237
3296
  const preferredNode = resolvePreferredNodeBinary();
3238
3297
  if (!preferredNode)
3239
3298
  return null;
3240
3299
  const explicitNode = process.env.RIG_NODE_BIN?.trim();
3241
- if (explicitNode && resolve19(explicitNode) === resolve19(preferredNode)) {
3242
- return preferredNode.endsWith("/bin/node") ? resolve19(preferredNode, "../..") : resolve19(preferredNode, "..");
3300
+ if (explicitNode && resolve20(explicitNode) === resolve20(preferredNode)) {
3301
+ return preferredNode.endsWith("/bin/node") ? resolve20(preferredNode, "../..") : resolve20(preferredNode, "..");
3243
3302
  }
3244
3303
  try {
3245
3304
  const realPath = realpathSync(preferredNode);
3246
3305
  if (realPath.endsWith("/bin/node")) {
3247
- return resolve19(realPath, "../..");
3306
+ return resolve20(realPath, "../..");
3248
3307
  }
3249
- return resolve19(realPath, "..");
3308
+ return resolve20(realPath, "..");
3250
3309
  } catch {
3251
- return resolve19(preferredNode, "..");
3310
+ return resolve20(preferredNode, "..");
3252
3311
  }
3253
3312
  }
3254
3313
  function resolvePreferredNodeBinary() {
3255
3314
  const candidates = [];
3256
3315
  const envNode = process.env.RIG_NODE_BIN?.trim();
3257
3316
  if (envNode) {
3258
- const explicit = resolve19(envNode);
3259
- if (existsSync17(explicit)) {
3317
+ const explicit = resolve20(envNode);
3318
+ if (existsSync19(explicit)) {
3260
3319
  return explicit;
3261
3320
  }
3262
3321
  }
3263
3322
  const nvmBin = process.env.NVM_BIN?.trim();
3264
3323
  if (nvmBin) {
3265
- candidates.push(resolve19(nvmBin, "node"));
3324
+ candidates.push(resolve20(nvmBin, "node"));
3266
3325
  }
3267
3326
  const home = process.env.HOME?.trim();
3268
3327
  if (home) {
3269
- const nvmVersionsDir = resolve19(home, ".nvm/versions/node");
3270
- if (existsSync17(nvmVersionsDir)) {
3328
+ const nvmVersionsDir = resolve20(home, ".nvm/versions/node");
3329
+ if (existsSync19(nvmVersionsDir)) {
3271
3330
  try {
3272
3331
  const versionDirs = readdirSync4(nvmVersionsDir).map((entry) => entry.trim()).filter((entry) => /^v\d+\.\d+\.\d+$/.test(entry)).sort((a, b) => Bun.semver.order(b.replace(/^v/, ""), a.replace(/^v/, "")));
3273
3332
  for (const versionDir of versionDirs) {
3274
- candidates.push(resolve19(nvmVersionsDir, versionDir, "bin/node"));
3333
+ candidates.push(resolve20(nvmVersionsDir, versionDir, "bin/node"));
3275
3334
  }
3276
3335
  } catch {}
3277
3336
  }
@@ -3280,8 +3339,8 @@ function resolvePreferredNodeBinary() {
3280
3339
  if (whichNode) {
3281
3340
  candidates.push(whichNode);
3282
3341
  }
3283
- const deduped = uniq(candidates.map((candidate) => resolve19(candidate)));
3284
- const existing = deduped.filter((candidate) => existsSync17(candidate));
3342
+ const deduped = uniq(candidates.map((candidate) => resolve20(candidate)));
3343
+ const existing = deduped.filter((candidate) => existsSync19(candidate));
3285
3344
  if (existing.length === 0) {
3286
3345
  return null;
3287
3346
  }
@@ -3295,7 +3354,7 @@ function resolvePreferredNodeBinary() {
3295
3354
  return existing[0] ?? null;
3296
3355
  }
3297
3356
  function inferNodeMajor(nodeBinaryPath) {
3298
- const normalized = resolve19(nodeBinaryPath).replace(/\\/g, "/");
3357
+ const normalized = resolve20(nodeBinaryPath).replace(/\\/g, "/");
3299
3358
  const match = normalized.match(/(?:^|\/)(?:node-)?v?(\d+)\.\d+\.\d+(?:\/|$)/);
3300
3359
  if (!match) {
3301
3360
  return null;
@@ -3307,8 +3366,8 @@ function normalizeExecutablePath(candidate) {
3307
3366
  if (!candidate) {
3308
3367
  return "";
3309
3368
  }
3310
- const normalized = resolve19(candidate);
3311
- if (!existsSync17(normalized)) {
3369
+ const normalized = resolve20(candidate);
3370
+ if (!existsSync19(normalized)) {
3312
3371
  return "";
3313
3372
  }
3314
3373
  try {
@@ -3318,7 +3377,7 @@ function normalizeExecutablePath(candidate) {
3318
3377
  }
3319
3378
  }
3320
3379
  function looksLikeRuntimeGateway(candidate) {
3321
- const normalized = resolve19(candidate).replace(/\\/g, "/");
3380
+ const normalized = resolve20(candidate).replace(/\\/g, "/");
3322
3381
  return normalized.includes("/.rig/bin/") || normalized.endsWith("/rig-shell") || normalized.endsWith("/rig-agent");
3323
3382
  }
3324
3383
 
@@ -3339,7 +3398,7 @@ function runtimeProvisioningEnv(baseEnv = process.env) {
3339
3398
  try {
3340
3399
  return resolveClaudeInstallDir();
3341
3400
  } catch {
3342
- return resolve20(claudeBinary, "..");
3401
+ return resolve21(claudeBinary, "..");
3343
3402
  }
3344
3403
  })() : "";
3345
3404
  const nodeDir = resolveNodeInstallDir();
@@ -3349,8 +3408,8 @@ function runtimeProvisioningEnv(baseEnv = process.env) {
3349
3408
  `${bunDir}/bin`,
3350
3409
  claudeDir,
3351
3410
  nodeDir ? `${nodeDir}/bin` : "",
3352
- realHome ? resolve20(realHome, ".local/bin") : "",
3353
- realHome ? resolve20(realHome, ".cargo/bin") : "",
3411
+ realHome ? resolve21(realHome, ".local/bin") : "",
3412
+ realHome ? resolve21(realHome, ".cargo/bin") : "",
3354
3413
  ...inheritedPath,
3355
3414
  "/usr/local/bin",
3356
3415
  "/usr/local/sbin",
@@ -3381,9 +3440,9 @@ function runtimeProvisioningEnv(baseEnv = process.env) {
3381
3440
  // packages/runtime/src/control-plane/native/validator-binaries.ts
3382
3441
  function resolveValidatorBinaryPath(projectRoot, binaryName, runtimeContext) {
3383
3442
  if (runtimeContext) {
3384
- return resolve21(runtimeContext.binDir, "validators", binaryName);
3443
+ return resolve22(runtimeContext.binDir, "validators", binaryName);
3385
3444
  }
3386
- return resolve21(resolveHarnessPaths(projectRoot).binDir, "validators", binaryName);
3445
+ return resolve22(resolveHarnessPaths(projectRoot).binDir, "validators", binaryName);
3387
3446
  }
3388
3447
  async function ensureValidatorBinary(projectRoot, checkId, runtimeContext) {
3389
3448
  const match = checkId.match(/^([a-z][\w-]*):([a-z][\w-]*)$/);
@@ -3398,19 +3457,19 @@ async function ensureValidatorBinary(projectRoot, checkId, runtimeContext) {
3398
3457
  const binaryName = `${category}-${check}`;
3399
3458
  const binaryPath = resolveValidatorBinaryPath(projectRoot, binaryName, runtimeContext);
3400
3459
  const hostProjectRoot = runtimeContext?.hostProjectRoot?.trim() || projectRoot;
3401
- const sourcePath = resolve21(hostProjectRoot, "packages/runtime/src/control-plane/validators", category, `${check}.ts`);
3402
- if (!existsSync18(sourcePath)) {
3460
+ const sourcePath = resolve22(hostProjectRoot, "packages/runtime/src/control-plane/validators", category, `${check}.ts`);
3461
+ if (!existsSync20(sourcePath)) {
3403
3462
  return null;
3404
3463
  }
3405
3464
  const sourceMtime = statSync4(sourcePath).mtimeMs;
3406
- const binaryExists = existsSync18(binaryPath);
3465
+ const binaryExists = existsSync20(binaryPath);
3407
3466
  const binaryMtime = binaryExists ? statSync4(binaryPath).mtimeMs : 0;
3408
3467
  if (!binaryExists || sourceMtime > binaryMtime) {
3409
3468
  if (binaryExists) {
3410
3469
  rmSync5(binaryPath, { force: true });
3411
3470
  rmSync5(`${binaryPath}.build-manifest.json`, { force: true });
3412
3471
  }
3413
- mkdirSync7(dirname10(binaryPath), { recursive: true });
3472
+ mkdirSync8(dirname11(binaryPath), { recursive: true });
3414
3473
  await buildRuntimeBinary({
3415
3474
  sourcePath: `packages/runtime/src/control-plane/validators/${category}/${check}.ts`,
3416
3475
  outputPath: binaryPath,
@@ -3419,7 +3478,7 @@ async function ensureValidatorBinary(projectRoot, checkId, runtimeContext) {
3419
3478
  env: runtimeProvisioningEnv()
3420
3479
  });
3421
3480
  }
3422
- return existsSync18(binaryPath) ? binaryPath : null;
3481
+ return existsSync20(binaryPath) ? binaryPath : null;
3423
3482
  }
3424
3483
 
3425
3484
  // packages/runtime/src/control-plane/native/validator.ts
@@ -3456,20 +3515,20 @@ async function readTaskSourceValidation(projectRoot, taskId) {
3456
3515
  function resolveValidationPaths(projectRoot, taskId, runtimeContext) {
3457
3516
  if (runtimeContext) {
3458
3517
  return {
3459
- taskLogDir: resolve22(runtimeContext.logsDir, taskId),
3460
- artifactDir: resolve22(runtimeContext.workspaceDir, "artifacts", taskId)
3518
+ taskLogDir: resolve23(runtimeContext.logsDir, taskId),
3519
+ artifactDir: resolve23(runtimeContext.workspaceDir, "artifacts", taskId)
3461
3520
  };
3462
3521
  }
3463
3522
  const paths = resolveHarnessPaths(projectRoot);
3464
3523
  return {
3465
- taskLogDir: resolve22(paths.logsDir, taskId),
3466
- artifactDir: resolve22(paths.artifactsDir, taskId)
3524
+ taskLogDir: resolve23(paths.logsDir, taskId),
3525
+ artifactDir: resolve23(paths.artifactsDir, taskId)
3467
3526
  };
3468
3527
  }
3469
3528
  async function runValidatorBinary(projectRoot, taskId, checkId, runtimeContext) {
3470
3529
  const binaryName = checkId.replace(":", "-");
3471
3530
  const binaryPath = await ensureValidatorBinary(projectRoot, checkId, runtimeContext) ?? resolveValidatorBinaryPath(projectRoot, binaryName, runtimeContext);
3472
- if (!existsSync19(binaryPath)) {
3531
+ if (!existsSync21(binaryPath)) {
3473
3532
  return {
3474
3533
  result: {
3475
3534
  id: checkId,
@@ -3480,7 +3539,7 @@ async function runValidatorBinary(projectRoot, taskId, checkId, runtimeContext)
3480
3539
  };
3481
3540
  }
3482
3541
  const validatorCwd = runtimeContext?.workspaceDir || resolveMonorepoRoot(projectRoot);
3483
- const runtimeShellPath = runtimeContext ? resolve22(runtimeContext.binDir, "rig-shell") : "";
3542
+ const runtimeShellPath = runtimeContext ? resolve23(runtimeContext.binDir, "rig-shell") : "";
3484
3543
  const monorepoMainRoot = runtimeContext?.monorepoMainRoot || process.env.MONOREPO_MAIN_ROOT?.trim() || resolveMonorepoRoot(projectRoot);
3485
3544
  const validatorEnv = {
3486
3545
  PROJECT_RIG_ROOT: runtimeContext?.hostProjectRoot || projectRoot,
@@ -3495,7 +3554,7 @@ async function runValidatorBinary(projectRoot, taskId, checkId, runtimeContext)
3495
3554
  validatorEnv.RIG_LOGS_DIR = runtimeContext.logsDir;
3496
3555
  validatorEnv.RIG_RUNTIME_BIN_DIR = runtimeContext.binDir;
3497
3556
  }
3498
- const { exitCode, stdout, stderr } = await runCaptureAsync(runtimeShellPath && existsSync19(runtimeShellPath) ? [runtimeShellPath, "run-binary", binaryPath] : [binaryPath], validatorCwd, validatorEnv);
3557
+ const { exitCode, stdout, stderr } = await runCaptureAsync(runtimeShellPath && existsSync21(runtimeShellPath) ? [runtimeShellPath, "run-binary", binaryPath] : [binaryPath], validatorCwd, validatorEnv);
3499
3558
  try {
3500
3559
  const result = JSON.parse(stdout.trim());
3501
3560
  return { result, exitCode };
@@ -3535,8 +3594,8 @@ async function validateTask(projectRoot, taskId, runtimeContext, registry, optio
3535
3594
  const configuredValidation = stringArray(taskConfig[taskId]?.validation);
3536
3595
  const commands = resolvedContext?.validation?.length ? resolvedContext.validation : configuredValidation.length > 0 ? configuredValidation : sourceValidation.validation;
3537
3596
  const { taskLogDir, artifactDir } = resolveValidationPaths(projectRoot, taskId, resolvedContext);
3538
- mkdirSync8(taskLogDir, { recursive: true });
3539
- mkdirSync8(artifactDir, { recursive: true });
3597
+ mkdirSync9(taskLogDir, { recursive: true });
3598
+ mkdirSync9(artifactDir, { recursive: true });
3540
3599
  if (commands.length === 0) {
3541
3600
  const skipped = {
3542
3601
  status: "skipped",
@@ -3545,7 +3604,7 @@ async function validateTask(projectRoot, taskId, runtimeContext, registry, optio
3545
3604
  failed: 0,
3546
3605
  categories: []
3547
3606
  };
3548
- writeFileSync8(resolve22(artifactDir, "validation-summary.json"), `${JSON.stringify(skipped, null, 2)}
3607
+ writeFileSync9(resolve23(artifactDir, "validation-summary.json"), `${JSON.stringify(skipped, null, 2)}
3549
3608
  `, "utf-8");
3550
3609
  return skipped;
3551
3610
  }
@@ -3580,18 +3639,18 @@ async function validateTask(projectRoot, taskId, runtimeContext, registry, optio
3580
3639
  exit_code: 2,
3581
3640
  duration_seconds: 0
3582
3641
  });
3583
- const logFile2 = resolve22(taskLogDir, `invalid-entry-validation.log`);
3584
- mkdirSync8(taskLogDir, { recursive: true });
3585
- writeFileSync8(logFile2, `=== ${nowIso()} :: ${cmd} ===
3642
+ const logFile2 = resolve23(taskLogDir, `invalid-entry-validation.log`);
3643
+ mkdirSync9(taskLogDir, { recursive: true });
3644
+ writeFileSync9(logFile2, `=== ${nowIso()} :: ${cmd} ===
3586
3645
  Invalid validation entry: not a check-ID. All entries must use format "category:check-name".
3587
3646
  `, "utf-8");
3588
3647
  continue;
3589
3648
  }
3590
3649
  const { result, exitCode } = await dispatchValidator(cmd, effectiveRegistry, validatorCtx, (id) => runValidatorBinary(projectRoot, taskId, id, resolvedContext));
3591
3650
  const durationSeconds = Math.max(0, Math.round((Date.now() - startedAt) / 1000));
3592
- const logFile = resolve22(taskLogDir, `${cmd.replace(":", "-")}-validation.log`);
3593
- mkdirSync8(taskLogDir, { recursive: true });
3594
- writeFileSync8(logFile, `=== ${nowIso()} :: ${cmd} ===
3651
+ const logFile = resolve23(taskLogDir, `${cmd.replace(":", "-")}-validation.log`);
3652
+ mkdirSync9(taskLogDir, { recursive: true });
3653
+ writeFileSync9(logFile, `=== ${nowIso()} :: ${cmd} ===
3595
3654
  ${JSON.stringify(result, null, 2)}
3596
3655
  `, "utf-8");
3597
3656
  if (result.passed) {
@@ -3613,15 +3672,15 @@ ${JSON.stringify(result, null, 2)}
3613
3672
  failed,
3614
3673
  categories
3615
3674
  };
3616
- mkdirSync8(artifactDir, { recursive: true });
3617
- writeFileSync8(resolve22(artifactDir, "validation-summary.json"), `${JSON.stringify(summary, null, 2)}
3675
+ mkdirSync9(artifactDir, { recursive: true });
3676
+ writeFileSync9(resolve23(artifactDir, "validation-summary.json"), `${JSON.stringify(summary, null, 2)}
3618
3677
  `, "utf-8");
3619
3678
  return summary;
3620
3679
  }
3621
3680
 
3622
3681
  // packages/runtime/src/control-plane/native/verifier.ts
3623
- import { existsSync as existsSync20, mkdirSync as mkdirSync9, writeFileSync as writeFileSync9 } from "fs";
3624
- import { resolve as resolve23 } from "path";
3682
+ import { existsSync as existsSync22, mkdirSync as mkdirSync10, writeFileSync as writeFileSync10 } from "fs";
3683
+ import { resolve as resolve24 } from "path";
3625
3684
 
3626
3685
  // packages/runtime/src/control-plane/native/pr-review-gate.ts
3627
3686
  function parseJsonObject(value) {
@@ -4872,11 +4931,11 @@ async function verifyTask(options) {
4872
4931
  const taskId = options.taskId;
4873
4932
  const normalizedTaskId = lookupTask(options.projectRoot, taskId);
4874
4933
  const artifactDir = artifactDirForId(options.projectRoot, taskId);
4875
- mkdirSync9(artifactDir, { recursive: true });
4876
- const validationSummaryPath = resolve23(artifactDir, "validation-summary.json");
4877
- const reviewFeedbackPath = resolve23(artifactDir, "review-feedback.md");
4878
- const reviewStatePath = resolve23(artifactDir, "review-state.json");
4879
- const greptileRawPath = resolve23(artifactDir, "review-greptile-raw.json");
4934
+ mkdirSync10(artifactDir, { recursive: true });
4935
+ const validationSummaryPath = resolve24(artifactDir, "validation-summary.json");
4936
+ const reviewFeedbackPath = resolve24(artifactDir, "review-feedback.md");
4937
+ const reviewStatePath = resolve24(artifactDir, "review-state.json");
4938
+ const greptileRawPath = resolve24(artifactDir, "review-greptile-raw.json");
4880
4939
  const prStates = readPrMetadata(options.projectRoot, taskId);
4881
4940
  const prState = prStates[0] || null;
4882
4941
  const localReasons = [];
@@ -4888,7 +4947,7 @@ async function verifyTask(options) {
4888
4947
  if (!normalizedTaskId && !await hasConfiguredSourceTask(options.projectRoot, taskId)) {
4889
4948
  localReasons.push(`[Task Config] Unknown task id '${taskId}' in task-config or configured task source.`);
4890
4949
  }
4891
- if (!existsSync20(validationSummaryPath)) {
4950
+ if (!existsSync22(validationSummaryPath)) {
4892
4951
  localReasons.push(`[Artifact Quality] validation-summary.json not found at ${validationSummaryPath}.`);
4893
4952
  } else {
4894
4953
  const summary = await parseValidationSummary(validationSummaryPath);
@@ -4897,13 +4956,13 @@ async function verifyTask(options) {
4897
4956
  }
4898
4957
  }
4899
4958
  for (const file of ["task-result.json", "decision-log.md", "next-actions.md", "changed-files.txt"]) {
4900
- const requiredPath = resolve23(artifactDir, file);
4901
- if (!existsSync20(requiredPath)) {
4959
+ const requiredPath = resolve24(artifactDir, file);
4960
+ if (!existsSync22(requiredPath)) {
4902
4961
  localReasons.push(`[Artifact Quality] Missing required artifact file: ${requiredPath}`);
4903
4962
  }
4904
4963
  }
4905
- const taskResultPath = resolve23(artifactDir, "task-result.json");
4906
- if (existsSync20(taskResultPath)) {
4964
+ const taskResultPath = resolve24(artifactDir, "task-result.json");
4965
+ if (existsSync22(taskResultPath)) {
4907
4966
  const taskResult = await readJsonFile2(taskResultPath);
4908
4967
  const artifactStatus = typeof taskResult?.status === "string" ? taskResult.status.trim().toLowerCase() : "";
4909
4968
  if (artifactStatus === "partial") {
@@ -4916,8 +4975,8 @@ async function verifyTask(options) {
4916
4975
  localReasons.push("[Artifact Quality] task-result.json next actions indicate remaining implementation scope.");
4917
4976
  }
4918
4977
  }
4919
- const nextActionsPath = resolve23(artifactDir, "next-actions.md");
4920
- if (existsSync20(nextActionsPath)) {
4978
+ const nextActionsPath = resolve24(artifactDir, "next-actions.md");
4979
+ if (existsSync22(nextActionsPath)) {
4921
4980
  const nextActionsContent = await Bun.file(nextActionsPath).text();
4922
4981
  if (nextActionsContent.includes("TODO: Replace this scaffold") || nextActionsContent.includes("bd-<downstream-task-id>")) {
4923
4982
  localReasons.push("[Artifact Quality] next-actions.md still contains scaffold placeholder text. Replace with real recommendations.");
@@ -4948,7 +5007,7 @@ async function verifyTask(options) {
4948
5007
  aiReasons.push(`[AI Review] Required mode needs a completed Greptile approval; current verdict is ${ai.verdict}.`);
4949
5008
  }
4950
5009
  if (persistArtifacts && ai.rawResponse) {
4951
- writeFileSync9(greptileRawPath, `${ai.rawResponse}
5010
+ writeFileSync10(greptileRawPath, `${ai.rawResponse}
4952
5011
  `, "utf-8");
4953
5012
  }
4954
5013
  } else if (!options.skipAiReview && reviewMode === "off") {
@@ -5191,7 +5250,7 @@ function evaluateSourceCloseoutChecks(prState, prLabel) {
5191
5250
  if (!Array.isArray(checks) || checks.length === 0) {
5192
5251
  return [`[Source Issue] PR ${prLabel} must have green check evidence before completion.`];
5193
5252
  }
5194
- const ciGate = evaluatePullRequestCiChecks(checks, "PR", 0);
5253
+ const ciGate = evaluatePullRequestCiChecks(checks, "PR", 0, { mergeStateStatus: prState.mergeStateStatus });
5195
5254
  if (ciGate.verdict === "APPROVE") {
5196
5255
  return [];
5197
5256
  }
@@ -5287,7 +5346,7 @@ function isAcceptedValidationSummary(summary) {
5287
5346
  return summary.status === "skipped" && summary.total === 0 && summary.failed === 0;
5288
5347
  }
5289
5348
  async function loadReviewMode(reviewProfilePath, fallback) {
5290
- const parsed = existsSync20(reviewProfilePath) ? await readJsonFile2(reviewProfilePath) : null;
5349
+ const parsed = existsSync22(reviewProfilePath) ? await readJsonFile2(reviewProfilePath) : null;
5291
5350
  const mode = parsed?.mode;
5292
5351
  if (mode === "off" || mode === "advisory" || mode === "required") {
5293
5352
  return mode;
@@ -5298,7 +5357,7 @@ async function loadReviewMode(reviewProfilePath, fallback) {
5298
5357
  return "advisory";
5299
5358
  }
5300
5359
  async function loadReviewProvider(reviewProfilePath, fallback) {
5301
- const parsed = existsSync20(reviewProfilePath) ? await readJsonFile2(reviewProfilePath) : null;
5360
+ const parsed = existsSync22(reviewProfilePath) ? await readJsonFile2(reviewProfilePath) : null;
5302
5361
  const provider = parsed?.provider;
5303
5362
  if (typeof provider === "string" && provider.trim().length > 0) {
5304
5363
  return provider;
@@ -5457,7 +5516,7 @@ function writeFeedbackFile(options) {
5457
5516
  if (options.aiRawFeedback) {
5458
5517
  lines.push("## Raw Reviewer Feedback", "", "```text", options.aiRawFeedback, "```", "");
5459
5518
  }
5460
- writeFileSync9(options.output, `${lines.join(`
5519
+ writeFileSync10(options.output, `${lines.join(`
5461
5520
  `)}
5462
5521
  `, "utf-8");
5463
5522
  }
@@ -5474,7 +5533,7 @@ function writeReviewStateFile(options) {
5474
5533
  ai_warnings: options.aiWarnings,
5475
5534
  updated_at: nowIso()
5476
5535
  };
5477
- writeFileSync9(options.output, `${JSON.stringify(payload, null, 2)}
5536
+ writeFileSync10(options.output, `${JSON.stringify(payload, null, 2)}
5478
5537
  `, "utf-8");
5479
5538
  }
5480
5539
  async function runGreptileReviewForPr(options) {
@@ -5555,7 +5614,7 @@ async function runGreptileReviewForPr(options) {
5555
5614
  }
5556
5615
  await Bun.sleep(options.pollIntervalMs);
5557
5616
  }
5558
- const ciGate = evaluatePullRequestCiChecks(githubCheckRollup, repoName, prNumber);
5617
+ const ciGate = evaluatePullRequestCiChecks(githubCheckRollup, repoName, prNumber, { mergeStateStatus: options.prState.mergeStateStatus });
5559
5618
  if (ciGate.verdict !== "APPROVE") {
5560
5619
  return {
5561
5620
  verdict: ciGate.verdict,
@@ -5813,7 +5872,7 @@ async function runGithubGreptileFallbackReviewForPr(options) {
5813
5872
  }
5814
5873
  await Bun.sleep(options.pollIntervalMs);
5815
5874
  }
5816
- const ciGate = evaluatePullRequestCiChecks(checkRollup, repoName, prNumber);
5875
+ const ciGate = evaluatePullRequestCiChecks(checkRollup, repoName, prNumber, { mergeStateStatus: options.prState.mergeStateStatus });
5817
5876
  if (ciGate.verdict !== "APPROVE") {
5818
5877
  return {
5819
5878
  verdict: ciGate.verdict,
@@ -6168,7 +6227,7 @@ function loadGithubPullRequestCheckRollup(projectRoot, repoName, prNumber) {
6168
6227
  ]);
6169
6228
  return response.statusCheckRollup || [];
6170
6229
  }
6171
- function evaluatePullRequestCiChecks(checks, repoName, prNumber) {
6230
+ function evaluatePullRequestCiChecks(checks, repoName, prNumber, options = {}) {
6172
6231
  const nonGreptileChecks = checks.filter((check) => {
6173
6232
  const label = (check.name || check.context || "").toLowerCase();
6174
6233
  return label.length > 0 && !label.includes("greptile");
@@ -6180,7 +6239,8 @@ function evaluatePullRequestCiChecks(checks, repoName, prNumber) {
6180
6239
  const state = (check.state || check.status || "").toUpperCase();
6181
6240
  return state === "PENDING" || state === "EXPECTED" || state === "QUEUED" || state === "IN_PROGRESS";
6182
6241
  });
6183
- if (pending.length > 0) {
6242
+ const mergeClean = (options.mergeStateStatus || "").toUpperCase() === "CLEAN";
6243
+ if (pending.length > 0 && !mergeClean) {
6184
6244
  return {
6185
6245
  verdict: "SKIP",
6186
6246
  reasons: pending.map((check) => `[CI] ${repoName}#${prNumber} check is still pending: ${check.name || check.context || "unknown"}.`)
@@ -6261,7 +6321,7 @@ function filterActionableGithubGreptileThreads(threads) {
6261
6321
  }
6262
6322
  function resolvePrRepoRoot(projectRoot, prState) {
6263
6323
  const runtimeWorkspace = process.env.RIG_TASK_WORKSPACE?.trim();
6264
- if (prState.target === "monorepo" && runtimeWorkspace && existsSync20(resolve23(runtimeWorkspace, ".git"))) {
6324
+ if (prState.target === "monorepo" && runtimeWorkspace && existsSync22(resolve24(runtimeWorkspace, ".git"))) {
6265
6325
  return runtimeWorkspace;
6266
6326
  }
6267
6327
  const paths = resolveHarnessPaths(projectRoot);
@@ -6633,16 +6693,16 @@ async function taskDeps(projectRoot, taskId) {
6633
6693
  for (const dep of deps) {
6634
6694
  const artifactDir = artifactDirForId(projectRoot, dep);
6635
6695
  console.log(`=== ${dep} ===`);
6636
- if (!existsSync21(artifactDir)) {
6696
+ if (!existsSync23(artifactDir)) {
6637
6697
  console.log(` (no artifacts yet)
6638
6698
  `);
6639
6699
  continue;
6640
6700
  }
6641
- printArtifactSection(resolve24(artifactDir, "decision-log.md"), "--- Decisions ---");
6642
- printArtifactSection(resolve24(artifactDir, "next-actions.md"), "--- Next Actions (for you) ---");
6643
- const changedFiles = resolve24(artifactDir, "changed-files.txt");
6644
- if (existsSync21(changedFiles)) {
6645
- const lines = readFileSync11(changedFiles, "utf-8").split(/\r?\n/).filter(Boolean);
6701
+ printArtifactSection(resolve25(artifactDir, "decision-log.md"), "--- Decisions ---");
6702
+ printArtifactSection(resolve25(artifactDir, "next-actions.md"), "--- Next Actions (for you) ---");
6703
+ const changedFiles = resolve25(artifactDir, "changed-files.txt");
6704
+ if (existsSync23(changedFiles)) {
6705
+ const lines = readFileSync12(changedFiles, "utf-8").split(/\r?\n/).filter(Boolean);
6646
6706
  console.log(`--- Changed Files (${lines.length}) ---`);
6647
6707
  for (const line of lines) {
6648
6708
  console.log(line);
@@ -6687,12 +6747,12 @@ function taskRecord(projectRoot, type, text, taskId) {
6687
6747
  throw new Error("No active task.");
6688
6748
  }
6689
6749
  const paths = resolveHarnessPaths(projectRoot);
6690
- mkdirSync10(paths.stateDir, { recursive: true });
6750
+ mkdirSync11(paths.stateDir, { recursive: true });
6691
6751
  if (type === "decision") {
6692
- const artifactDir = resolve24(paths.artifactsDir, activeTask);
6693
- mkdirSync10(artifactDir, { recursive: true });
6752
+ const artifactDir = resolve25(paths.artifactsDir, activeTask);
6753
+ mkdirSync11(artifactDir, { recursive: true });
6694
6754
  const timestamp = nowIso();
6695
- appendFileSync(resolve24(artifactDir, "decision-log.md"), `
6755
+ appendFileSync(resolve25(artifactDir, "decision-log.md"), `
6696
6756
  ### ${timestamp}
6697
6757
 
6698
6758
  ${text}
@@ -6702,14 +6762,14 @@ ${text}
6702
6762
  return;
6703
6763
  }
6704
6764
  const failedPath = paths.failedApproachesPath;
6705
- if (!existsSync21(failedPath)) {
6706
- writeFileSync10(failedPath, `# Failed Approaches Log
6765
+ if (!existsSync23(failedPath)) {
6766
+ writeFileSync11(failedPath, `# Failed Approaches Log
6707
6767
 
6708
6768
  This file records approaches that did not work.
6709
6769
 
6710
6770
  `, "utf-8");
6711
6771
  }
6712
- const content = readFileSync11(failedPath, "utf-8");
6772
+ const content = readFileSync12(failedPath, "utf-8");
6713
6773
  const attempts = (content.match(new RegExp(`^## ${escapeRegExp(activeTask)}\\b`, "gm")) || []).length + 1;
6714
6774
  appendFileSync(failedPath, `
6715
6775
  ## ${activeTask} - Attempt ${attempts} (${nowIso()})
@@ -6726,40 +6786,40 @@ function taskArtifacts(projectRoot, taskId) {
6726
6786
  throw new Error("No active task.");
6727
6787
  }
6728
6788
  const paths = resolveHarnessPaths(projectRoot);
6729
- const artifactDir = resolve24(paths.artifactsDir, activeTask);
6730
- mkdirSync10(artifactDir, { recursive: true });
6789
+ const artifactDir = resolve25(paths.artifactsDir, activeTask);
6790
+ mkdirSync11(artifactDir, { recursive: true });
6731
6791
  const changed = changedFilesForTask(projectRoot, activeTask, true);
6732
- writeFileSync10(resolve24(artifactDir, "changed-files.txt"), `${changed.join(`
6792
+ writeFileSync11(resolve25(artifactDir, "changed-files.txt"), `${changed.join(`
6733
6793
  `)}
6734
6794
  `, "utf-8");
6735
6795
  console.log(`changed-files.txt: ${changed.length} files`);
6736
- const taskResultPath = resolve24(artifactDir, "task-result.json");
6737
- if (!existsSync21(taskResultPath)) {
6796
+ const taskResultPath = resolve25(artifactDir, "task-result.json");
6797
+ if (!existsSync23(taskResultPath)) {
6738
6798
  const template = {
6739
6799
  task_id: activeTask,
6740
6800
  status: "completed",
6741
6801
  summary: "TODO: Write a one-line summary of what you did",
6742
6802
  completed_at: nowIso()
6743
6803
  };
6744
- writeFileSync10(taskResultPath, `${JSON.stringify(template, null, 2)}
6804
+ writeFileSync11(taskResultPath, `${JSON.stringify(template, null, 2)}
6745
6805
  `, "utf-8");
6746
6806
  console.log("task-result.json: created (update the summary!)");
6747
6807
  } else {
6748
6808
  console.log("task-result.json: already exists");
6749
6809
  }
6750
- const decisionLogPath = resolve24(artifactDir, "decision-log.md");
6751
- if (!existsSync21(decisionLogPath)) {
6810
+ const decisionLogPath = resolve25(artifactDir, "decision-log.md");
6811
+ if (!existsSync23(decisionLogPath)) {
6752
6812
  const content = `# Decision Log: ${activeTask}
6753
6813
 
6754
6814
  Record key decisions here using: rig-agent record decision "..."
6755
6815
  `;
6756
- writeFileSync10(decisionLogPath, content, "utf-8");
6816
+ writeFileSync11(decisionLogPath, content, "utf-8");
6757
6817
  console.log("decision-log.md: created (record your decisions!)");
6758
6818
  } else {
6759
6819
  console.log("decision-log.md: already exists");
6760
6820
  }
6761
- const nextActionsPath = resolve24(artifactDir, "next-actions.md");
6762
- if (!existsSync21(nextActionsPath)) {
6821
+ const nextActionsPath = resolve25(artifactDir, "next-actions.md");
6822
+ if (!existsSync23(nextActionsPath)) {
6763
6823
  const content = [
6764
6824
  `# Next Actions: ${activeTask}`,
6765
6825
  "",
@@ -6776,13 +6836,13 @@ Record key decisions here using: rig-agent record decision "..."
6776
6836
  ""
6777
6837
  ].join(`
6778
6838
  `);
6779
- writeFileSync10(nextActionsPath, content, "utf-8");
6839
+ writeFileSync11(nextActionsPath, content, "utf-8");
6780
6840
  console.log("next-actions.md: created (add recommendations for downstream tasks!)");
6781
6841
  } else {
6782
6842
  console.log("next-actions.md: already exists");
6783
6843
  }
6784
- const validationSummaryPath = resolve24(artifactDir, "validation-summary.json");
6785
- if (existsSync21(validationSummaryPath)) {
6844
+ const validationSummaryPath = resolve25(artifactDir, "validation-summary.json");
6845
+ if (existsSync23(validationSummaryPath)) {
6786
6846
  console.log("validation-summary.json: already exists");
6787
6847
  } else {
6788
6848
  console.log("validation-summary.json: not yet created (run: rig-agent validate)");
@@ -6873,7 +6933,7 @@ function collectTaskChangedFiles(projectRoot, taskId, includeCommitted) {
6873
6933
  [projectRoot, ""],
6874
6934
  [monorepoRepoRoot, ""]
6875
6935
  ]) {
6876
- if (!existsSync21(resolve24(repo, ".git"))) {
6936
+ if (!existsSync23(resolve25(repo, ".git"))) {
6877
6937
  continue;
6878
6938
  }
6879
6939
  if (includeCommitted && repo === monorepoRepoRoot) {
@@ -6898,12 +6958,22 @@ function filterTaskChangedFiles(projectRoot, taskId, files, scoped) {
6898
6958
  }
6899
6959
  function resolveTaskMonorepoRoot(projectRoot) {
6900
6960
  const runtimeWorkspace = loadRuntimeContextFromEnv()?.workspaceDir || process.env.RIG_TASK_WORKSPACE?.trim();
6901
- if (runtimeWorkspace && existsSync21(resolve24(runtimeWorkspace, ".git"))) {
6902
- return resolve24(runtimeWorkspace);
6961
+ if (runtimeWorkspace && existsSync23(resolve25(runtimeWorkspace, ".git"))) {
6962
+ return resolve25(runtimeWorkspace);
6903
6963
  }
6904
6964
  return resolveHarnessPaths(projectRoot).monorepoRoot;
6905
6965
  }
6906
6966
  function collectCommittedMonorepoFiles(projectRoot, repo) {
6967
+ const defaultRef = runCapture(["git", "-C", repo, "rev-parse", "--abbrev-ref", "origin/HEAD"], projectRoot);
6968
+ if (defaultRef.exitCode === 0 && defaultRef.stdout.trim()) {
6969
+ const mergeBase = runCapture(["git", "-C", repo, "merge-base", "HEAD", defaultRef.stdout.trim()], projectRoot);
6970
+ if (mergeBase.exitCode === 0 && mergeBase.stdout.trim()) {
6971
+ const result = runCapture(["git", "-C", repo, "diff", "--name-only", `${mergeBase.stdout.trim()}..HEAD`], projectRoot);
6972
+ if (result.exitCode === 0) {
6973
+ return result.stdout.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
6974
+ }
6975
+ }
6976
+ }
6907
6977
  const initialHeadCommit = resolveRuntimeInitialHeadCommit(projectRoot, repo);
6908
6978
  if (initialHeadCommit) {
6909
6979
  const result = runCapture(["git", "-C", repo, "diff", "--name-only", `${initialHeadCommit}..HEAD`], projectRoot);
@@ -6927,7 +6997,7 @@ function resolveRuntimeInitialHeadCommit(projectRoot, repo) {
6927
6997
  const runtimeContext = loadRuntimeContextFromEnv();
6928
6998
  if (runtimeContext?.initialHeadCommits?.monorepo?.trim()) {
6929
6999
  const monorepoRoot = resolveTaskMonorepoRoot(projectRoot);
6930
- if (resolve24(monorepoRoot) === resolve24(repo)) {
7000
+ if (resolve25(monorepoRoot) === resolve25(repo)) {
6931
7001
  return runtimeContext.initialHeadCommits.monorepo.trim();
6932
7002
  }
6933
7003
  }
@@ -6937,7 +7007,7 @@ function resolveMonorepoBaseCommit(projectRoot, repo) {
6937
7007
  const runtimeContext = loadRuntimeContextFromEnv();
6938
7008
  if (runtimeContext?.monorepoBaseCommit?.trim()) {
6939
7009
  const monorepoRoot = resolveTaskMonorepoRoot(projectRoot);
6940
- if (resolve24(monorepoRoot) === resolve24(repo)) {
7010
+ if (resolve25(monorepoRoot) === resolve25(repo)) {
6941
7011
  return runtimeContext.monorepoBaseCommit.trim();
6942
7012
  }
6943
7013
  }
@@ -6982,7 +7052,7 @@ function resolveRuntimeDirtyBaseline(projectRoot, repo) {
6982
7052
  return new Set;
6983
7053
  }
6984
7054
  const monorepoRoot = resolveTaskMonorepoRoot(projectRoot);
6985
- const selected = resolve24(repo) === resolve24(monorepoRoot) ? dirtyFiles.monorepo : resolve24(repo) === resolve24(projectRoot) ? dirtyFiles.project : undefined;
7055
+ const selected = resolve25(repo) === resolve25(monorepoRoot) ? dirtyFiles.monorepo : resolve25(repo) === resolve25(projectRoot) ? dirtyFiles.project : undefined;
6986
7056
  return new Set((selected || []).map((file) => normalizeChangedFilePath(file)).filter(Boolean));
6987
7057
  }
6988
7058
  function normalizeChangedFilePath(file) {
@@ -7082,12 +7152,12 @@ function printIndented(text) {
7082
7152
  }
7083
7153
  }
7084
7154
  function readLocalBeadsTasks(projectRoot) {
7085
- const issuesPath = resolve24(resolveMonorepoRoot2(projectRoot), ".beads/issues.jsonl");
7086
- if (!existsSync21(issuesPath)) {
7155
+ const issuesPath = resolve25(resolveMonorepoRoot2(projectRoot), ".beads/issues.jsonl");
7156
+ if (!existsSync23(issuesPath)) {
7087
7157
  return [];
7088
7158
  }
7089
7159
  const tasks = [];
7090
- for (const line of readFileSync11(issuesPath, "utf-8").split(/\r?\n/)) {
7160
+ for (const line of readFileSync12(issuesPath, "utf-8").split(/\r?\n/)) {
7091
7161
  const trimmed = line.trim();
7092
7162
  if (!trimmed) {
7093
7163
  continue;
@@ -7200,11 +7270,11 @@ function taskDependencies(projectRoot, taskId, tracker) {
7200
7270
  return [...ids].sort();
7201
7271
  }
7202
7272
  function printArtifactSection(path, header) {
7203
- if (!existsSync21(path)) {
7273
+ if (!existsSync23(path)) {
7204
7274
  return;
7205
7275
  }
7206
7276
  console.log(header);
7207
- process.stdout.write(readFileSync11(path, "utf-8"));
7277
+ process.stdout.write(readFileSync12(path, "utf-8"));
7208
7278
  console.log("");
7209
7279
  }
7210
7280
  function escapeRegExp(value) {
@@ -7244,8 +7314,8 @@ function isRuntimeGatewayGhPath(candidate) {
7244
7314
  }
7245
7315
  function resolveOptionalMonorepoRoot(projectRoot) {
7246
7316
  const runtimeWorkspace = process.env.RIG_TASK_WORKSPACE?.trim();
7247
- if (runtimeWorkspace && existsSync22(resolve25(runtimeWorkspace, ".git"))) {
7248
- return resolve25(runtimeWorkspace);
7317
+ if (runtimeWorkspace && existsSync24(resolve26(runtimeWorkspace, ".git"))) {
7318
+ return resolve26(runtimeWorkspace);
7249
7319
  }
7250
7320
  try {
7251
7321
  return resolveMonorepoRoot2(projectRoot);
@@ -7270,7 +7340,7 @@ function resolveGitBinary(projectRoot) {
7270
7340
  if (!candidate || isRuntimeGatewayGitPath(candidate)) {
7271
7341
  continue;
7272
7342
  }
7273
- if (existsSync22(candidate)) {
7343
+ if (existsSync24(candidate)) {
7274
7344
  return candidate;
7275
7345
  }
7276
7346
  }
@@ -7330,11 +7400,11 @@ function gitPreflight(projectRoot, taskId, strict) {
7330
7400
  const expected = resolvedTask ? `rig/${resolveTaskBranchId(projectRoot, resolvedTask)}` : "";
7331
7401
  console.log("=== Git Flow Preflight ===");
7332
7402
  let issues = 0;
7333
- if (!existsSync22(resolve25(projectRoot, ".git"))) {
7403
+ if (!existsSync24(resolve26(projectRoot, ".git"))) {
7334
7404
  console.log(`ERROR: project root is not a git repo (${projectRoot})`);
7335
7405
  issues += 1;
7336
7406
  }
7337
- if (monorepoRoot && existsSync22(resolve25(monorepoRoot, ".git"))) {
7407
+ if (monorepoRoot && existsSync24(resolve26(monorepoRoot, ".git"))) {
7338
7408
  const monoBranch = branchName(projectRoot, monorepoRoot);
7339
7409
  if (expected && monoBranch !== expected) {
7340
7410
  console.log(`WARN: monorepo branch is ${monoBranch}, expected ${expected} for task ${resolvedTask}`);
@@ -7368,7 +7438,7 @@ function gitSyncBranch(projectRoot, taskId, targetRepo = "monorepo") {
7368
7438
  }
7369
7439
  const repoRoot = targetRepo === "monorepo" ? resolveOptionalMonorepoRoot(projectRoot) || resolveMonorepoRoot2(projectRoot) : projectRoot;
7370
7440
  const repoLabel = targetRepo === "monorepo" ? "Monorepo" : "Project";
7371
- if (!existsSync22(resolve25(repoRoot, ".git"))) {
7441
+ if (!existsSync24(resolve26(repoRoot, ".git"))) {
7372
7442
  throw new Error(`${repoLabel} repo not found at ${repoRoot}`);
7373
7443
  }
7374
7444
  const branchId = resolveTaskBranchId(projectRoot, resolvedTask);
@@ -7412,8 +7482,8 @@ function gitCommit(options) {
7412
7482
  function gitSnapshot(projectRoot, taskId, outputPath) {
7413
7483
  const monorepoRoot = resolveOptionalMonorepoRoot(projectRoot);
7414
7484
  const resolvedTask = taskId || safeCurrentTaskId(projectRoot);
7415
- const output = outputPath || (resolvedTask ? resolveArtifactSnapshot(projectRoot, resolvedTask) : resolve25(resolve25(projectRoot, ".rig", "state"), "git-state.txt"));
7416
- mkdirSync11(dirname11(output), { recursive: true });
7485
+ const output = outputPath || (resolvedTask ? resolveArtifactSnapshot(projectRoot, resolvedTask) : resolve26(resolve26(projectRoot, ".rig", "state"), "git-state.txt"));
7486
+ mkdirSync12(dirname12(output), { recursive: true });
7417
7487
  const lines = ["# Git Snapshot", `timestamp: ${nowIso()}`];
7418
7488
  if (resolvedTask) {
7419
7489
  lines.push(`task: ${resolvedTask}`);
@@ -7423,7 +7493,7 @@ function gitSnapshot(projectRoot, taskId, outputPath) {
7423
7493
  if (monorepoRoot && monorepoRoot !== projectRoot) {
7424
7494
  lines.push(...snapshotRepo(projectRoot, "monorepo", monorepoRoot));
7425
7495
  }
7426
- writeFileSync11(output, `${lines.join(`
7496
+ writeFileSync12(output, `${lines.join(`
7427
7497
  `)}
7428
7498
  `, "utf-8");
7429
7499
  return output;
@@ -7447,7 +7517,7 @@ function gitOpenPr(options) {
7447
7517
  } else if (taskId) {
7448
7518
  gitSyncBranch(options.projectRoot, taskId, "project");
7449
7519
  }
7450
- if (!existsSync22(resolve25(repoRoot, ".git"))) {
7520
+ if (!existsSync24(resolve26(repoRoot, ".git"))) {
7451
7521
  throw new Error(`Repository not available for open-pr target ${target}: ${repoRoot}`);
7452
7522
  }
7453
7523
  const branch = branchName(options.projectRoot, repoRoot);
@@ -7660,12 +7730,12 @@ function assertPrHasNoGitConflicts(prState, repoLabel, baseRef) {
7660
7730
  }
7661
7731
  function writePrMetadata(projectRoot, taskId, result) {
7662
7732
  const dir = artifactDirForId(projectRoot, taskId);
7663
- mkdirSync11(dir, { recursive: true });
7664
- const path = resolve25(dir, "pr-state.json");
7733
+ mkdirSync12(dir, { recursive: true });
7734
+ const path = resolve26(dir, "pr-state.json");
7665
7735
  let prs = {};
7666
- if (existsSync22(path)) {
7736
+ if (existsSync24(path)) {
7667
7737
  try {
7668
- const parsed = JSON.parse(readFileSync12(path, "utf-8"));
7738
+ const parsed = JSON.parse(readFileSync13(path, "utf-8"));
7669
7739
  if (parsed && typeof parsed === "object" && parsed.prs && typeof parsed.prs === "object") {
7670
7740
  prs = parsed.prs;
7671
7741
  }
@@ -7681,16 +7751,16 @@ function writePrMetadata(projectRoot, taskId, result) {
7681
7751
  ...primary || {},
7682
7752
  updated_at: nowIso()
7683
7753
  };
7684
- writeFileSync11(path, `${JSON.stringify(artifact, null, 2)}
7754
+ writeFileSync12(path, `${JSON.stringify(artifact, null, 2)}
7685
7755
  `, "utf-8");
7686
7756
  }
7687
7757
  function readPrMetadata(projectRoot, taskId) {
7688
- const path = resolve25(artifactDirForId(projectRoot, taskId), "pr-state.json");
7689
- if (!existsSync22(path)) {
7758
+ const path = resolve26(artifactDirForId(projectRoot, taskId), "pr-state.json");
7759
+ if (!existsSync24(path)) {
7690
7760
  return [];
7691
7761
  }
7692
7762
  try {
7693
- const parsed = JSON.parse(readFileSync12(path, "utf-8"));
7763
+ const parsed = JSON.parse(readFileSync13(path, "utf-8"));
7694
7764
  if (!parsed || typeof parsed !== "object") {
7695
7765
  return [];
7696
7766
  }
@@ -7703,8 +7773,8 @@ function readPrMetadata(projectRoot, taskId) {
7703
7773
  }
7704
7774
  }
7705
7775
  function resolveArtifactSnapshot(projectRoot, taskId) {
7706
- const artifactDir = resolve25(resolveHarnessPaths(projectRoot).artifactsDir, taskId);
7707
- return resolve25(artifactDir, "git-state.txt");
7776
+ const artifactDir = resolve26(resolveHarnessPaths(projectRoot).artifactsDir, taskId);
7777
+ return resolve26(artifactDir, "git-state.txt");
7708
7778
  }
7709
7779
  function isGitOpenPrResult(value) {
7710
7780
  if (!value || typeof value !== "object" || Array.isArray(value)) {
@@ -7763,14 +7833,14 @@ function resolveGithubCliBinary(projectRoot) {
7763
7833
  }
7764
7834
  const explicitPathEntries = (process.env.PATH || "").split(":").map((entry) => entry.trim()).filter(Boolean);
7765
7835
  for (const entry of explicitPathEntries) {
7766
- candidates.add(resolve25(entry, "gh"));
7836
+ candidates.add(resolve26(entry, "gh"));
7767
7837
  }
7768
7838
  const bunResolved = Bun.which("gh");
7769
7839
  if (bunResolved) {
7770
7840
  candidates.add(bunResolved);
7771
7841
  }
7772
7842
  for (const candidate of candidates) {
7773
- if (candidate && existsSync22(candidate) && !isRuntimeGatewayGhPath(candidate)) {
7843
+ if (candidate && existsSync24(candidate) && !isRuntimeGatewayGhPath(candidate)) {
7774
7844
  return candidate;
7775
7845
  }
7776
7846
  }
@@ -7800,7 +7870,7 @@ function resolveRepoNameWithOwner(projectRoot, repoRoot) {
7800
7870
  return resolveGithubRepoNameWithOwnerFromGitRoot(projectRoot, repoRoot, repoRoot, visited);
7801
7871
  }
7802
7872
  function resolveGithubRepoNameWithOwnerFromGitRoot(projectRoot, gitRoot, cwd, visited) {
7803
- const normalizedGitRoot = resolve25(gitRoot);
7873
+ const normalizedGitRoot = resolve26(gitRoot);
7804
7874
  if (visited.has(normalizedGitRoot)) {
7805
7875
  return "";
7806
7876
  }
@@ -7872,7 +7942,7 @@ function resolveNetworkRemoteName(projectRoot, repoRoot, repoNameWithOwner) {
7872
7942
  return remotes.includes("origin") ? "origin" : remotes[0];
7873
7943
  }
7874
7944
  function gitQuery(projectRoot, gitRoot, cwd, ...args) {
7875
- const gitArgs = existsSync22(resolve25(gitRoot, ".git")) ? gitCmd(projectRoot, gitRoot, ...args) : [resolveGitBinary(projectRoot), "--git-dir", gitRoot, ...args];
7945
+ const gitArgs = existsSync24(resolve26(gitRoot, ".git")) ? gitCmd(projectRoot, gitRoot, ...args) : [resolveGitBinary(projectRoot), "--git-dir", gitRoot, ...args];
7876
7946
  return runCapture2(gitArgs, cwd, projectRoot);
7877
7947
  }
7878
7948
  function resolveLocalGitRemoteRoot(remoteUrl, gitRoot) {
@@ -7890,9 +7960,9 @@ function resolveLocalGitRemoteRoot(remoteUrl, gitRoot) {
7890
7960
  } else if (/^[a-z][a-z0-9+.-]*:\/\//i.test(normalized) || /^[^@]+@[^:]+:.+$/.test(normalized)) {
7891
7961
  return "";
7892
7962
  } else if (!isAbsolute2(normalized)) {
7893
- candidate = resolve25(gitRoot, normalized);
7963
+ candidate = resolve26(gitRoot, normalized);
7894
7964
  }
7895
- return existsSync22(candidate) ? candidate : "";
7965
+ return existsSync24(candidate) ? candidate : "";
7896
7966
  }
7897
7967
  function normalizeGithubRepoNameWithOwner(value) {
7898
7968
  const normalized = value.trim();
@@ -8019,7 +8089,7 @@ function inferReviewerFromChangedFiles(projectRoot, repoRoot, baseRef, branchRef
8019
8089
  return best;
8020
8090
  }
8021
8091
  function snapshotRepo(projectRoot, label, repo) {
8022
- if (!existsSync22(resolve25(repo, ".git"))) {
8092
+ if (!existsSync24(resolve26(repo, ".git"))) {
8023
8093
  return [`## ${label}`, `repo: ${repo}`, "status: unavailable", ""];
8024
8094
  }
8025
8095
  const status = runCapture2(gitCmd(projectRoot, repo, "status", "--short"), projectRoot).stdout.trim();
@@ -8042,7 +8112,7 @@ function snapshotRepo(projectRoot, label, repo) {
8042
8112
  ];
8043
8113
  }
8044
8114
  function commitRepo(projectRoot, repo, label, message, allowEmpty, scoped, files, changedFilesManifest) {
8045
- if (!existsSync22(resolve25(repo, ".git"))) {
8115
+ if (!existsSync24(resolve26(repo, ".git"))) {
8046
8116
  console.log(`Skipping ${label}: repo not available (${repo})`);
8047
8117
  return;
8048
8118
  }
@@ -8074,18 +8144,18 @@ function commitRepo(projectRoot, repo, label, message, allowEmpty, scoped, files
8074
8144
  console.log(`Committed ${label}: ${message}`);
8075
8145
  }
8076
8146
  function readChangedFilesManifest(projectRoot, taskId) {
8077
- const manifestPath = resolve25(artifactDirForId(projectRoot, taskId), "changed-files.txt");
8078
- if (!existsSync22(manifestPath)) {
8147
+ const manifestPath = resolve26(artifactDirForId(projectRoot, taskId), "changed-files.txt");
8148
+ if (!existsSync24(manifestPath)) {
8079
8149
  return [];
8080
8150
  }
8081
- const files = readFileSync12(manifestPath, "utf-8").split(/\r?\n/).map((line) => normalizeChangedFilePath2(line)).filter(Boolean);
8151
+ const files = readFileSync13(manifestPath, "utf-8").split(/\r?\n/).map((line) => normalizeChangedFilePath2(line)).filter(Boolean);
8082
8152
  return [...new Set(files)];
8083
8153
  }
8084
8154
  function refreshChangedFilesManifest(projectRoot, taskId) {
8085
- const manifestPath = resolve25(artifactDirForId(projectRoot, taskId), "changed-files.txt");
8086
- mkdirSync11(dirname11(manifestPath), { recursive: true });
8155
+ const manifestPath = resolve26(artifactDirForId(projectRoot, taskId), "changed-files.txt");
8156
+ mkdirSync12(dirname12(manifestPath), { recursive: true });
8087
8157
  const changedFiles = changedFilesForTask(projectRoot, taskId, true);
8088
- writeFileSync11(manifestPath, `${changedFiles.join(`
8158
+ writeFileSync12(manifestPath, `${changedFiles.join(`
8089
8159
  `)}
8090
8160
  `, "utf-8");
8091
8161
  return manifestPath;
@@ -8198,7 +8268,7 @@ function repoHasPathChange(projectRoot, repoRoot, relativePath) {
8198
8268
  return result.exitCode === 0 && result.stdout.trim().length > 0;
8199
8269
  }
8200
8270
  function stageExcludePathspecs(repoRoot) {
8201
- const patterns = existsSync22(resolve25(repoRoot, ".rig", "task-config.json")) ? [...TASK_RUNTIME_STAGE_EXCLUDES, ...GENERATED_STAGE_EXCLUDES] : [".rig/**", ...GENERATED_STAGE_EXCLUDES];
8271
+ const patterns = existsSync24(resolve26(repoRoot, ".rig", "task-config.json")) ? [...TASK_RUNTIME_STAGE_EXCLUDES, ...GENERATED_STAGE_EXCLUDES] : [".rig/**", ...GENERATED_STAGE_EXCLUDES];
8202
8272
  return patterns.map((pattern) => `:(glob,exclude)${pattern}`);
8203
8273
  }
8204
8274
  function pathResolvesBeyondSymlink(repoRoot, relativePath) {
@@ -8208,7 +8278,7 @@ function pathResolvesBeyondSymlink(repoRoot, relativePath) {
8208
8278
  }
8209
8279
  let current = repoRoot;
8210
8280
  for (let index = 0;index < parts.length - 1; index += 1) {
8211
- current = resolve25(current, parts[index]);
8281
+ current = resolve26(current, parts[index]);
8212
8282
  try {
8213
8283
  if (lstatSync(current).isSymbolicLink()) {
8214
8284
  return true;
@@ -8220,7 +8290,7 @@ function pathResolvesBeyondSymlink(repoRoot, relativePath) {
8220
8290
  return false;
8221
8291
  }
8222
8292
  function printRepoStatus(projectRoot, label, repo, expectedBranch) {
8223
- if (!existsSync22(resolve25(repo, ".git"))) {
8293
+ if (!existsSync24(resolve26(repo, ".git"))) {
8224
8294
  console.log(`${label}: unavailable (${repo})`);
8225
8295
  return;
8226
8296
  }
@@ -8256,7 +8326,7 @@ function resolveTaskBranchId(projectRoot, taskId) {
8256
8326
  }
8257
8327
  } catch {}
8258
8328
  const artifactDir = artifactDirForId(projectRoot, taskId);
8259
- if (existsSync22(artifactDir)) {
8329
+ if (existsSync24(artifactDir)) {
8260
8330
  return taskId;
8261
8331
  }
8262
8332
  throw new Error(`Unknown task id: ${taskId}`);
@@ -8292,11 +8362,11 @@ function runCapture2(command, cwd, projectRoot = cwd) {
8292
8362
  }
8293
8363
  function runtimeGitEnv(projectRoot) {
8294
8364
  const { ctx, runtimeRoot } = resolveRuntimeMetadata(projectRoot);
8295
- const runtimeHome = runtimeRoot ? resolve25(runtimeRoot, "home") : "";
8296
- const runtimeTmp = runtimeRoot ? resolve25(runtimeRoot, "tmp") : "";
8297
- const runtimeCache = runtimeRoot ? resolve25(runtimeRoot, "cache") : "";
8298
- const runtimeKnownHosts = runtimeHome ? resolve25(runtimeHome, ".ssh", "known_hosts") : "";
8299
- const runtimeKey = runtimeHome ? resolve25(runtimeHome, ".ssh", "rig-agent-key") : "";
8365
+ const runtimeHome = runtimeRoot ? resolve26(runtimeRoot, "home") : "";
8366
+ const runtimeTmp = runtimeRoot ? resolve26(runtimeRoot, "tmp") : "";
8367
+ const runtimeCache = runtimeRoot ? resolve26(runtimeRoot, "cache") : "";
8368
+ const runtimeKnownHosts = runtimeHome ? resolve26(runtimeHome, ".ssh", "known_hosts") : "";
8369
+ const runtimeKey = runtimeHome ? resolve26(runtimeHome, ".ssh", "rig-agent-key") : "";
8300
8370
  const env = {};
8301
8371
  if (ctx?.workspaceDir) {
8302
8372
  env.PROJECT_RIG_ROOT = projectRoot;
@@ -8309,14 +8379,14 @@ function runtimeGitEnv(projectRoot) {
8309
8379
  if (runtimeRoot) {
8310
8380
  env.RIG_RUNTIME_HOME = runtimeRoot;
8311
8381
  }
8312
- if (runtimeHome && existsSync22(runtimeHome)) {
8382
+ if (runtimeHome && existsSync24(runtimeHome)) {
8313
8383
  env.HOME = runtimeHome;
8314
8384
  env.OPENSSL_CONF = ensureRuntimeOpenSslConfig(runtimeHome);
8315
8385
  }
8316
- if (runtimeTmp && existsSync22(runtimeTmp)) {
8386
+ if (runtimeTmp && existsSync24(runtimeTmp)) {
8317
8387
  env.TMPDIR = runtimeTmp;
8318
8388
  }
8319
- if (runtimeCache && existsSync22(runtimeCache)) {
8389
+ if (runtimeCache && existsSync24(runtimeCache)) {
8320
8390
  env.XDG_CACHE_HOME = runtimeCache;
8321
8391
  }
8322
8392
  const workspaceSecrets = loadDotEnvSecrets(ctx?.workspaceDir || projectRoot, process.env);
@@ -8360,14 +8430,14 @@ function runtimeGitEnv(projectRoot) {
8360
8430
  env.GH_TOKEN = env.GH_TOKEN || gitHubToken;
8361
8431
  applyGitHubCredentialHelperEnv(env);
8362
8432
  }
8363
- if (runtimeKnownHosts && existsSync22(runtimeKnownHosts)) {
8433
+ if (runtimeKnownHosts && existsSync24(runtimeKnownHosts)) {
8364
8434
  const sshParts = [
8365
8435
  "ssh",
8366
8436
  `-o UserKnownHostsFile="${runtimeKnownHosts}"`,
8367
8437
  "-o StrictHostKeyChecking=yes",
8368
8438
  "-F /dev/null"
8369
8439
  ];
8370
- if (runtimeKey && existsSync22(runtimeKey)) {
8440
+ if (runtimeKey && existsSync24(runtimeKey)) {
8371
8441
  sshParts.splice(1, 0, `-i "${runtimeKey}"`, "-o IdentitiesOnly=yes");
8372
8442
  }
8373
8443
  env.GIT_SSH_COMMAND = sshParts.join(" ");
@@ -8388,12 +8458,12 @@ function loadPersistedRuntimeSecrets(runtimeRoot) {
8388
8458
  if (!runtimeRoot) {
8389
8459
  return {};
8390
8460
  }
8391
- const path = resolve25(runtimeRoot, "runtime-secrets.json");
8392
- if (!existsSync22(path)) {
8461
+ const path = resolve26(runtimeRoot, "runtime-secrets.json");
8462
+ if (!existsSync24(path)) {
8393
8463
  return {};
8394
8464
  }
8395
8465
  try {
8396
- const parsed = JSON.parse(readFileSync12(path, "utf-8"));
8466
+ const parsed = JSON.parse(readFileSync13(path, "utf-8"));
8397
8467
  const entries = Object.entries(parsed).filter((entry) => typeof entry[1] === "string");
8398
8468
  return Object.fromEntries(entries);
8399
8469
  } catch {
@@ -8401,13 +8471,13 @@ function loadPersistedRuntimeSecrets(runtimeRoot) {
8401
8471
  }
8402
8472
  }
8403
8473
  function ensureRuntimeOpenSslConfig(runtimeHome) {
8404
- const sslDir = resolve25(runtimeHome, ".ssl");
8405
- const sslConfig = resolve25(sslDir, "openssl.cnf");
8406
- if (!existsSync22(sslDir)) {
8407
- mkdirSync11(sslDir, { recursive: true });
8474
+ const sslDir = resolve26(runtimeHome, ".ssl");
8475
+ const sslConfig = resolve26(sslDir, "openssl.cnf");
8476
+ if (!existsSync24(sslDir)) {
8477
+ mkdirSync12(sslDir, { recursive: true });
8408
8478
  }
8409
- if (!existsSync22(sslConfig)) {
8410
- writeFileSync11(sslConfig, `# Rig runtime OpenSSL config placeholder
8479
+ if (!existsSync24(sslConfig)) {
8480
+ writeFileSync12(sslConfig, `# Rig runtime OpenSSL config placeholder
8411
8481
  `);
8412
8482
  }
8413
8483
  return sslConfig;
@@ -8425,29 +8495,29 @@ function resolveRuntimeMetadata(projectRoot) {
8425
8495
  if (contextFile) {
8426
8496
  return {
8427
8497
  ctx,
8428
- runtimeRoot: dirname11(resolve25(contextFile))
8498
+ runtimeRoot: dirname12(resolve26(contextFile))
8429
8499
  };
8430
8500
  }
8431
8501
  const inferredContextFile = findRuntimeContextFile2(projectRoot);
8432
- if (existsSync22(inferredContextFile)) {
8502
+ if (existsSync24(inferredContextFile)) {
8433
8503
  try {
8434
8504
  ctx = loadRuntimeContext(inferredContextFile);
8435
8505
  } catch {}
8436
8506
  return {
8437
8507
  ctx,
8438
- runtimeRoot: dirname11(inferredContextFile)
8508
+ runtimeRoot: dirname12(inferredContextFile)
8439
8509
  };
8440
8510
  }
8441
8511
  return { ctx, runtimeRoot: "" };
8442
8512
  }
8443
8513
  function findRuntimeContextFile2(startPath) {
8444
- let current = resolve25(startPath);
8514
+ let current = resolve26(startPath);
8445
8515
  while (true) {
8446
- const candidate = resolve25(current, "runtime-context.json");
8447
- if (existsSync22(candidate)) {
8516
+ const candidate = resolve26(current, "runtime-context.json");
8517
+ if (existsSync24(candidate)) {
8448
8518
  return candidate;
8449
8519
  }
8450
- const parent = dirname11(current);
8520
+ const parent = dirname12(current);
8451
8521
  if (parent === current) {
8452
8522
  return "";
8453
8523
  }
@@ -8456,7 +8526,7 @@ function findRuntimeContextFile2(startPath) {
8456
8526
  }
8457
8527
 
8458
8528
  // packages/runtime/src/control-plane/native/profile-ops.ts
8459
- import { existsSync as existsSync23, mkdirSync as mkdirSync12, writeFileSync as writeFileSync12 } from "fs";
8529
+ import { existsSync as existsSync25, mkdirSync as mkdirSync13, writeFileSync as writeFileSync13 } from "fs";
8460
8530
  var DEFAULTS = {
8461
8531
  model: parseEnvOrDefault(process.env.DEFAULT_AGENT_MODEL, ["claude", "gpt-codex", "pi"], "pi"),
8462
8532
  runtime: parseEnvOrDefault(process.env.DEFAULT_AGENT_RUNTIME, ["claude-code", "codex-app-server", "pi"], "pi"),
@@ -8471,7 +8541,7 @@ function parseEnvOrDefault(value, allowed, fallback) {
8471
8541
  return allowed.includes(value) ? value : fallback;
8472
8542
  }
8473
8543
  async function readProfileFile(path) {
8474
- if (!existsSync23(path)) {
8544
+ if (!existsSync25(path)) {
8475
8545
  return null;
8476
8546
  }
8477
8547
  try {
@@ -8524,14 +8594,14 @@ async function setProfile(projectRoot, options) {
8524
8594
  plugin = model === "gpt-codex" ? "codex" : model === "pi" ? "pi" : "claude";
8525
8595
  }
8526
8596
  const paths = resolveHarnessPaths(projectRoot);
8527
- mkdirSync12(paths.stateDir, { recursive: true });
8597
+ mkdirSync13(paths.stateDir, { recursive: true });
8528
8598
  const next = {
8529
8599
  model,
8530
8600
  runtime,
8531
8601
  agent_plugin: plugin,
8532
8602
  updated_at: new Date().toISOString()
8533
8603
  };
8534
- writeFileSync12(paths.agentProfilePath, `${JSON.stringify(next, null, 2)}
8604
+ writeFileSync13(paths.agentProfilePath, `${JSON.stringify(next, null, 2)}
8535
8605
  `, "utf-8");
8536
8606
  await showProfile(projectRoot, false);
8537
8607
  }
@@ -8567,13 +8637,13 @@ async function setReviewProfile(projectRoot, mode, provider) {
8567
8637
  throw new Error(`Invalid provider: ${resolvedProvider}. Supported: greptile.`);
8568
8638
  }
8569
8639
  const paths = resolveHarnessPaths(projectRoot);
8570
- mkdirSync12(paths.stateDir, { recursive: true });
8640
+ mkdirSync13(paths.stateDir, { recursive: true });
8571
8641
  const next = {
8572
8642
  mode,
8573
8643
  provider: resolvedProvider,
8574
8644
  updated_at: new Date().toISOString()
8575
8645
  };
8576
- writeFileSync12(paths.reviewProfilePath, `${JSON.stringify(next, null, 2)}
8646
+ writeFileSync13(paths.reviewProfilePath, `${JSON.stringify(next, null, 2)}
8577
8647
  `, "utf-8");
8578
8648
  await showReviewProfile(projectRoot);
8579
8649
  }
@@ -8611,44 +8681,44 @@ async function loadReviewProfile(path) {
8611
8681
  }
8612
8682
 
8613
8683
  // packages/runtime/src/control-plane/native/repo-ops.ts
8614
- import { existsSync as existsSync27, mkdirSync as mkdirSync16, readFileSync as readFileSync14, readdirSync as readdirSync6, rmSync as rmSync7, writeFileSync as writeFileSync14 } from "fs";
8615
- import { basename as basename8, dirname as dirname13, resolve as resolve29 } from "path";
8684
+ import { existsSync as existsSync29, mkdirSync as mkdirSync17, readFileSync as readFileSync15, readdirSync as readdirSync6, rmSync as rmSync7, writeFileSync as writeFileSync15 } from "fs";
8685
+ import { basename as basename8, dirname as dirname14, resolve as resolve30 } from "path";
8616
8686
  // packages/runtime/src/control-plane/repos/mirror/bootstrap.ts
8617
- import { existsSync as existsSync25, mkdirSync as mkdirSync14, realpathSync as realpathSync2 } from "fs";
8618
- import { resolve as resolve27 } from "path";
8687
+ import { existsSync as existsSync27, mkdirSync as mkdirSync15, realpathSync as realpathSync2 } from "fs";
8688
+ import { resolve as resolve28 } from "path";
8619
8689
 
8620
8690
  // packages/runtime/src/control-plane/authority-files.ts
8621
- import { existsSync as existsSync24, mkdirSync as mkdirSync13, readFileSync as readFileSync13, writeFileSync as writeFileSync13, appendFileSync as appendFileSync2, copyFileSync as copyFileSync3, statSync as statSync5, readdirSync as readdirSync5, chmodSync as chmodSync3 } from "fs";
8622
- import { dirname as dirname12, join as join4, relative, resolve as resolve26 } from "path";
8691
+ import { existsSync as existsSync26, mkdirSync as mkdirSync14, readFileSync as readFileSync14, writeFileSync as writeFileSync14, appendFileSync as appendFileSync2, copyFileSync as copyFileSync3, statSync as statSync5, readdirSync as readdirSync5, chmodSync as chmodSync3 } from "fs";
8692
+ import { dirname as dirname13, join as join4, relative, resolve as resolve27 } from "path";
8623
8693
  import { parse as parseToml, stringify as stringifyToml } from "smol-toml";
8624
8694
  function resolveAuthorityProjectStateDir(projectRoot) {
8625
8695
  const explicit = process.env.RIG_STATE_DIR?.trim();
8626
8696
  if (explicit) {
8627
- return resolve26(explicit);
8697
+ return resolve27(explicit);
8628
8698
  }
8629
- return resolve26(resolve26(projectRoot), ".rig", "state");
8699
+ return resolve27(resolve27(projectRoot), ".rig", "state");
8630
8700
  }
8631
8701
  function readJsonAtPath(path, fallback) {
8632
- if (!existsSync24(path)) {
8702
+ if (!existsSync26(path)) {
8633
8703
  return fallback;
8634
8704
  }
8635
8705
  try {
8636
- return JSON.parse(readFileSync13(path, "utf-8"));
8706
+ return JSON.parse(readFileSync14(path, "utf-8"));
8637
8707
  } catch {
8638
8708
  return fallback;
8639
8709
  }
8640
8710
  }
8641
8711
  function writeJsonAtPath(path, value) {
8642
- mkdirSync13(dirname12(path), { recursive: true });
8643
- writeFileSync13(path, `${JSON.stringify(value, null, 2)}
8712
+ mkdirSync14(dirname13(path), { recursive: true });
8713
+ writeFileSync14(path, `${JSON.stringify(value, null, 2)}
8644
8714
  `, "utf8");
8645
8715
  return path;
8646
8716
  }
8647
8717
  function readAuthorityProjectStateJson(projectRoot, relativePath, fallback) {
8648
- return readJsonAtPath(resolve26(resolveAuthorityProjectStateDir(projectRoot), relativePath), fallback);
8718
+ return readJsonAtPath(resolve27(resolveAuthorityProjectStateDir(projectRoot), relativePath), fallback);
8649
8719
  }
8650
8720
  function writeAuthorityProjectStateJson(projectRoot, relativePath, value) {
8651
- return writeJsonAtPath(resolve26(resolveAuthorityProjectStateDir(projectRoot), relativePath), value);
8721
+ return writeJsonAtPath(resolve27(resolveAuthorityProjectStateDir(projectRoot), relativePath), value);
8652
8722
  }
8653
8723
 
8654
8724
  // packages/runtime/src/control-plane/repos/mirror/state.ts
@@ -8708,7 +8778,7 @@ function sameExistingPath(left, right) {
8708
8778
  try {
8709
8779
  return realpathSync2(left) === realpathSync2(right);
8710
8780
  } catch {
8711
- return resolve27(left) === resolve27(right);
8781
+ return resolve28(left) === resolve28(right);
8712
8782
  }
8713
8783
  }
8714
8784
  function repoLooksUsable(repoRoot, projectRoot) {
@@ -8744,7 +8814,7 @@ function resolveMirrorRemoteUrl(layout) {
8744
8814
  }
8745
8815
  }
8746
8816
  }
8747
- if (existsSync25(resolve27(layout.checkoutRoot, ".git")) && checkoutLooksUsable(layout)) {
8817
+ if (existsSync27(resolve28(layout.checkoutRoot, ".git")) && checkoutLooksUsable(layout)) {
8748
8818
  const checkoutOrigin = runGit(["git", "-C", layout.checkoutRoot, "remote", "get-url", "origin"], layout.projectRoot);
8749
8819
  if (checkoutOrigin.exitCode === 0) {
8750
8820
  const currentOrigin = checkoutOrigin.stdout.trim();
@@ -8757,9 +8827,9 @@ function resolveMirrorRemoteUrl(layout) {
8757
8827
  }
8758
8828
  function ensureManagedRepoMirror(projectRoot, repoId) {
8759
8829
  const layout = resolveManagedRepoLayout(projectRoot, repoId);
8760
- mkdirSync14(layout.metadataRoot, { recursive: true });
8830
+ mkdirSync15(layout.metadataRoot, { recursive: true });
8761
8831
  const remoteUrl = resolveMirrorRemoteUrl(layout);
8762
- if (!existsSync25(resolve27(layout.mirrorRoot, "HEAD"))) {
8832
+ if (!existsSync27(resolve28(layout.mirrorRoot, "HEAD"))) {
8763
8833
  ensureGitSuccess(runGit(["git", "init", "--bare", layout.mirrorRoot], layout.projectRoot), ["git", "init", "--bare", layout.mirrorRoot]);
8764
8834
  }
8765
8835
  const getOrigin = runGit(["git", "--git-dir", layout.mirrorRoot, "remote", "get-url", "origin"], layout.projectRoot);
@@ -8779,8 +8849,8 @@ function ensureManagedRepoMirror(projectRoot, repoId) {
8779
8849
  return layout;
8780
8850
  }
8781
8851
  // packages/runtime/src/control-plane/repos/mirror/refresh.ts
8782
- import { existsSync as existsSync26, mkdirSync as mkdirSync15, realpathSync as realpathSync3, rmSync as rmSync6 } from "fs";
8783
- import { resolve as resolve28 } from "path";
8852
+ import { existsSync as existsSync28, mkdirSync as mkdirSync16, realpathSync as realpathSync3, rmSync as rmSync6 } from "fs";
8853
+ import { resolve as resolve29 } from "path";
8784
8854
  function nowIso3() {
8785
8855
  return new Date().toISOString();
8786
8856
  }
@@ -8807,7 +8877,7 @@ function sameExistingPath2(left, right) {
8807
8877
  try {
8808
8878
  return realpathSync3(left) === realpathSync3(right);
8809
8879
  } catch {
8810
- return resolve28(left) === resolve28(right);
8880
+ return resolve29(left) === resolve29(right);
8811
8881
  }
8812
8882
  }
8813
8883
  function ensureMirrorHead(layout) {
@@ -8853,12 +8923,12 @@ function checkoutLooksUsable2(layout) {
8853
8923
  return probe.exitCode === 0 && sameExistingPath2(probe.stdout.trim(), layout.checkoutRoot);
8854
8924
  }
8855
8925
  function ensureCheckoutFromMirror(layout) {
8856
- mkdirSync15(resolve28(layout.checkoutRoot, ".."), { recursive: true });
8857
- const gitPath = resolve28(layout.checkoutRoot, ".git");
8858
- if (existsSync26(layout.checkoutRoot) && (!existsSync26(gitPath) || !checkoutLooksUsable2(layout))) {
8926
+ mkdirSync16(resolve29(layout.checkoutRoot, ".."), { recursive: true });
8927
+ const gitPath = resolve29(layout.checkoutRoot, ".git");
8928
+ if (existsSync28(layout.checkoutRoot) && (!existsSync28(gitPath) || !checkoutLooksUsable2(layout))) {
8859
8929
  rmSync6(layout.checkoutRoot, { recursive: true, force: true });
8860
8930
  }
8861
- if (!existsSync26(gitPath)) {
8931
+ if (!existsSync28(gitPath)) {
8862
8932
  ensureGitSuccess2(runGit2(["git", "clone", layout.mirrorRoot, layout.checkoutRoot], layout.projectRoot), ["git", "clone", layout.mirrorRoot, layout.checkoutRoot]);
8863
8933
  }
8864
8934
  const getOrigin = runGit2(["git", "-C", layout.checkoutRoot, "remote", "get-url", "origin"], layout.projectRoot);
@@ -8959,7 +9029,7 @@ function repoDiscover(projectRoot, taskId) {
8959
9029
  }
8960
9030
  function repoBaseline(projectRoot, refresh = false) {
8961
9031
  const paths = resolveRepoDiscoveryPaths(projectRoot);
8962
- if (!refresh && existsSync27(paths.baseRepoPinsPath)) {
9032
+ if (!refresh && existsSync29(paths.baseRepoPinsPath)) {
8963
9033
  const baseline = readJsonFile(paths.baseRepoPinsPath, { recorded_at: nowIso(), repos: {} });
8964
9034
  return baseline.repos || {};
8965
9035
  }
@@ -8983,8 +9053,8 @@ function ensureMonorepoReady(projectRoot) {
8983
9053
  }
8984
9054
  function persistBaselinePins(projectRoot, repos) {
8985
9055
  const paths = resolveRepoDiscoveryPaths(projectRoot);
8986
- mkdirSync16(resolve29(paths.baseRepoPinsPath, ".."), { recursive: true });
8987
- writeFileSync14(paths.baseRepoPinsPath, `${JSON.stringify({ recorded_at: nowIso(), repos }, null, 2)}
9056
+ mkdirSync17(resolve30(paths.baseRepoPinsPath, ".."), { recursive: true });
9057
+ writeFileSync15(paths.baseRepoPinsPath, `${JSON.stringify({ recorded_at: nowIso(), repos }, null, 2)}
8988
9058
  `, "utf-8");
8989
9059
  return repos;
8990
9060
  }
@@ -9063,28 +9133,28 @@ function readRepoDiscoveryTaskConfig(projectRoot) {
9063
9133
  function resolveRepoDiscoveryPaths(projectRoot) {
9064
9134
  const monorepoRoot = resolveMonorepoRepoLayout(projectRoot).checkoutRoot;
9065
9135
  const explicitHostProjectRoot = (process.env.RIG_HOST_PROJECT_ROOT || "").trim();
9066
- const normalizedProjectRoot = resolve29(projectRoot);
9136
+ const normalizedProjectRoot = resolve30(projectRoot);
9067
9137
  const hostProjectRoot = explicitHostProjectRoot && shouldUseHostProjectStateRoot(normalizedProjectRoot) ? explicitHostProjectRoot : normalizedProjectRoot;
9068
- const stateDir = resolve29(hostProjectRoot, ".rig", "state");
9138
+ const stateDir = resolve30(hostProjectRoot, ".rig", "state");
9069
9139
  return {
9070
9140
  monorepoRoot,
9071
- taskRepoCommitsPath: resolve29(stateDir, "task-repo-commits.json"),
9072
- baseRepoPinsPath: resolve29(stateDir, "base-repo-pins.json")
9141
+ taskRepoCommitsPath: resolve30(stateDir, "task-repo-commits.json"),
9142
+ baseRepoPinsPath: resolve30(stateDir, "base-repo-pins.json")
9073
9143
  };
9074
9144
  }
9075
9145
  function shouldUseHostProjectStateRoot(projectRoot) {
9076
9146
  const runtimeWorkspace = process.env.RIG_TASK_WORKSPACE?.trim();
9077
- if (runtimeWorkspace && resolve29(runtimeWorkspace) === projectRoot) {
9147
+ if (runtimeWorkspace && resolve30(runtimeWorkspace) === projectRoot) {
9078
9148
  return true;
9079
9149
  }
9080
- return basename8(dirname13(projectRoot)) === ".worktrees";
9150
+ return basename8(dirname14(projectRoot)) === ".worktrees";
9081
9151
  }
9082
9152
  function readPinFromArtifact(projectRoot, depTask, repoKey) {
9083
- const snapshot = resolve29(artifactDirForId(projectRoot, depTask), "git-state.txt");
9084
- if (!existsSync27(snapshot)) {
9153
+ const snapshot = resolve30(artifactDirForId(projectRoot, depTask), "git-state.txt");
9154
+ if (!existsSync29(snapshot)) {
9085
9155
  return "";
9086
9156
  }
9087
- const content = readFileSync14(snapshot, "utf-8");
9157
+ const content = readFileSync15(snapshot, "utf-8");
9088
9158
  const chunk = content.split(/\r?\n/);
9089
9159
  let inSection = false;
9090
9160
  for (const line of chunk) {
@@ -9106,12 +9176,12 @@ function repoPath(projectRoot, key) {
9106
9176
  if (managed) {
9107
9177
  return managed.checkoutRoot;
9108
9178
  }
9109
- return key.startsWith("/") ? key : resolve29(projectRoot, key);
9179
+ return key.startsWith("/") ? key : resolve30(projectRoot, key);
9110
9180
  }
9111
9181
  function applyPins(projectRoot, pins) {
9112
9182
  for (const [key, commit] of Object.entries(pins)) {
9113
9183
  const path = repoPath(projectRoot, key);
9114
- if (!existsSync27(resolve29(path, ".git"))) {
9184
+ if (!existsSync29(resolve30(path, ".git"))) {
9115
9185
  throw new Error(`Repo for pin not available: ${key} (${path})`);
9116
9186
  }
9117
9187
  let hasCommit = runGitCapture(["git", "-C", path, "cat-file", "-e", `${commit}^{commit}`], projectRoot).exitCode === 0;
@@ -9140,7 +9210,7 @@ function verifyPins(projectRoot, pins) {
9140
9210
  let ok = true;
9141
9211
  for (const [key, expected] of Object.entries(pins)) {
9142
9212
  const path = repoPath(projectRoot, key);
9143
- if (!existsSync27(resolve29(path, ".git"))) {
9213
+ if (!existsSync29(resolve30(path, ".git"))) {
9144
9214
  console.error(`ERROR: repo missing during pin verification: ${key}`);
9145
9215
  ok = false;
9146
9216
  continue;
@@ -9165,23 +9235,23 @@ function resolveRuntimeGitEnv() {
9165
9235
  GIT_SSH_COMMAND: process.env.GIT_SSH_COMMAND
9166
9236
  };
9167
9237
  }
9168
- const runtimeRoot = process.env.RIG_RUNTIME_HOME?.trim() || (process.env.RIG_RUNTIME_CONTEXT_FILE?.trim() ? resolve29(process.env.RIG_RUNTIME_CONTEXT_FILE, "..") : inferRuntimeRootFromWorkspace(process.cwd()));
9169
- const runtimeHome = runtimeRoot ? resolve29(runtimeRoot, "home") : process.env.HOME?.trim() || "";
9238
+ const runtimeRoot = process.env.RIG_RUNTIME_HOME?.trim() || (process.env.RIG_RUNTIME_CONTEXT_FILE?.trim() ? resolve30(process.env.RIG_RUNTIME_CONTEXT_FILE, "..") : inferRuntimeRootFromWorkspace(process.cwd()));
9239
+ const runtimeHome = runtimeRoot ? resolve30(runtimeRoot, "home") : process.env.HOME?.trim() || "";
9170
9240
  if (!runtimeHome) {
9171
9241
  return;
9172
9242
  }
9173
- const knownHostsPath = resolve29(runtimeHome, ".ssh", "known_hosts");
9174
- if (!existsSync27(knownHostsPath)) {
9243
+ const knownHostsPath = resolve30(runtimeHome, ".ssh", "known_hosts");
9244
+ if (!existsSync29(knownHostsPath)) {
9175
9245
  return { HOME: runtimeHome };
9176
9246
  }
9177
- const agentSshKey = resolve29(runtimeHome, ".ssh", "rig-agent-key");
9247
+ const agentSshKey = resolve30(runtimeHome, ".ssh", "rig-agent-key");
9178
9248
  const sshParts = [
9179
9249
  "ssh",
9180
9250
  `-o UserKnownHostsFile="${knownHostsPath}"`,
9181
9251
  "-o StrictHostKeyChecking=yes",
9182
9252
  "-F /dev/null"
9183
9253
  ];
9184
- if (existsSync27(agentSshKey)) {
9254
+ if (existsSync29(agentSshKey)) {
9185
9255
  sshParts.splice(1, 0, `-i "${agentSshKey}"`, "-o IdentitiesOnly=yes");
9186
9256
  }
9187
9257
  return {
@@ -9191,24 +9261,24 @@ function resolveRuntimeGitEnv() {
9191
9261
  }
9192
9262
  function inferRuntimeRootFromWorkspace(cwd) {
9193
9263
  const contextPath = findRuntimeContextFile3(cwd);
9194
- if (!contextPath || !existsSync27(contextPath)) {
9264
+ if (!contextPath || !existsSync29(contextPath)) {
9195
9265
  return "";
9196
9266
  }
9197
9267
  try {
9198
9268
  loadRuntimeContext(contextPath);
9199
- return resolve29(contextPath, "..");
9269
+ return resolve30(contextPath, "..");
9200
9270
  } catch {
9201
9271
  return "";
9202
9272
  }
9203
9273
  }
9204
9274
  function findRuntimeContextFile3(startPath) {
9205
- let current = resolve29(startPath);
9275
+ let current = resolve30(startPath);
9206
9276
  while (true) {
9207
- const candidate = resolve29(current, "runtime-context.json");
9208
- if (existsSync27(candidate)) {
9277
+ const candidate = resolve30(current, "runtime-context.json");
9278
+ if (existsSync29(candidate)) {
9209
9279
  return candidate;
9210
9280
  }
9211
- const parent = resolve29(current, "..");
9281
+ const parent = resolve30(current, "..");
9212
9282
  if (parent === current) {
9213
9283
  return "";
9214
9284
  }
@@ -9217,13 +9287,13 @@ function findRuntimeContextFile3(startPath) {
9217
9287
  }
9218
9288
 
9219
9289
  // packages/runtime/src/control-plane/memory-sync/cli.ts
9220
- import { existsSync as existsSync28 } from "fs";
9290
+ import { existsSync as existsSync30 } from "fs";
9221
9291
  import { randomUUID } from "crypto";
9222
9292
 
9223
9293
  // packages/runtime/src/control-plane/memory-sync/db.ts
9224
9294
  import { Database } from "bun:sqlite";
9225
- import { mkdirSync as mkdirSync17 } from "fs";
9226
- import { dirname as dirname14 } from "path";
9295
+ import { mkdirSync as mkdirSync18 } from "fs";
9296
+ import { dirname as dirname15 } from "path";
9227
9297
 
9228
9298
  // packages/runtime/src/control-plane/memory-sync/types.ts
9229
9299
  var NO_MATCH_RETRIEVAL_CANONICAL_KEY = "__memory_recall__:none";
@@ -9819,7 +9889,7 @@ async function validateEventTargets(executor, event) {
9819
9889
  }
9820
9890
  }
9821
9891
  async function openMemoryDb(dbPath) {
9822
- mkdirSync17(dirname14(dbPath), { recursive: true });
9892
+ mkdirSync18(dirname15(dbPath), { recursive: true });
9823
9893
  const sqlite = new Database(dbPath, { create: true, strict: true });
9824
9894
  const client = createMemoryDbClient(sqlite);
9825
9895
  const db = {
@@ -10238,7 +10308,7 @@ function formatMemoryQueryResults(results) {
10238
10308
  }
10239
10309
 
10240
10310
  // packages/runtime/src/control-plane/memory-sync/read.ts
10241
- import { mkdtempSync, rmSync as rmSync8, writeFileSync as writeFileSync15 } from "fs";
10311
+ import { mkdtempSync, rmSync as rmSync8, writeFileSync as writeFileSync16 } from "fs";
10242
10312
  import { tmpdir as tmpdir5 } from "os";
10243
10313
  import { join as join5 } from "path";
10244
10314
  var CANONICAL_MEMORY_DB_PATH = "rig/memory/project-memory.db";
@@ -10267,7 +10337,7 @@ async function readCanonicalMemoryDb(projectRoot, deps = {}) {
10267
10337
  try {
10268
10338
  try {
10269
10339
  const bytes = readDeps.readBlobBytesAtRef(repoPath2, baseOid, CANONICAL_MEMORY_DB_PATH);
10270
- writeFileSync15(dbPath, bytes);
10340
+ writeFileSync16(dbPath, bytes);
10271
10341
  } catch (error) {
10272
10342
  if (!isMissingCanonicalMemoryBlobError(error)) {
10273
10343
  throw error;
@@ -10425,7 +10495,7 @@ function requireRuntimeMemoryContext(runtimeContext) {
10425
10495
  }
10426
10496
  async function ensureRuntimeMemoryUsable(runtimeContext) {
10427
10497
  const memory = requireRuntimeMemoryContext(runtimeContext);
10428
- if (!existsSync28(memory.hydratedPath)) {
10498
+ if (!existsSync30(memory.hydratedPath)) {
10429
10499
  throw new Error(`Shared memory database is missing: ${memory.hydratedPath}`);
10430
10500
  }
10431
10501
  const db = await openMemoryDb(memory.hydratedPath);
@@ -10726,8 +10796,8 @@ async function executeHarnessCommand(projectRoot, args, eventBus, pluginHostCtx)
10726
10796
  }
10727
10797
  case "completion-verification":
10728
10798
  case "completition-verification": {
10729
- const hookPath = resolve30(projectRoot, ".rig/bin/hooks/completion-verification");
10730
- if (!existsSync29(hookPath)) {
10799
+ const hookPath = resolve31(projectRoot, ".rig/bin/hooks/completion-verification");
10800
+ if (!existsSync31(hookPath)) {
10731
10801
  throw new Error(`completion-verification hook binary not found: ${hookPath}`);
10732
10802
  }
10733
10803
  const proc = Bun.spawn([hookPath], {
@@ -11029,10 +11099,10 @@ function printHelp() {
11029
11099
  }
11030
11100
 
11031
11101
  // packages/runtime/src/control-plane/native/root-resolver.ts
11032
- import { existsSync as existsSync30, readFileSync as readFileSync15 } from "fs";
11033
- import { dirname as dirname15, parse, resolve as resolve31 } from "path";
11102
+ import { existsSync as existsSync32, readFileSync as readFileSync16 } from "fs";
11103
+ import { dirname as dirname16, parse, resolve as resolve32 } from "path";
11034
11104
  function hasProjectMarker(candidate) {
11035
- return existsSync30(resolve31(candidate, RIG_DEFINITION_DIRNAME)) || existsSync30(resolve31(candidate, RIG_STATE_DIRNAME));
11105
+ return existsSync32(resolve32(candidate, RIG_DEFINITION_DIRNAME)) || existsSync32(resolve32(candidate, RIG_STATE_DIRNAME));
11036
11106
  }
11037
11107
  function resolveProjectRoot(options) {
11038
11108
  const cwd = options?.cwd || process.cwd();
@@ -11049,23 +11119,23 @@ function resolveProjectRoot(options) {
11049
11119
  if (configRoot && hasProjectMarker(configRoot)) {
11050
11120
  return configRoot;
11051
11121
  }
11052
- let fileDir = resolve31(fallbackFromDir);
11122
+ let fileDir = resolve32(fallbackFromDir);
11053
11123
  for (let i = 0;i < 5; i += 1) {
11054
11124
  if (hasProjectMarker(fileDir)) {
11055
11125
  return fileDir;
11056
11126
  }
11057
- fileDir = dirname15(fileDir);
11127
+ fileDir = dirname16(fileDir);
11058
11128
  }
11059
11129
  return cwd;
11060
11130
  }
11061
11131
  function walkUpForRoot(start) {
11062
- let searchDir = resolve31(start);
11132
+ let searchDir = resolve32(start);
11063
11133
  const root = parse(searchDir).root || "/";
11064
11134
  while (searchDir !== root) {
11065
11135
  if (hasProjectMarker(searchDir)) {
11066
11136
  return searchDir;
11067
11137
  }
11068
- searchDir = dirname15(searchDir);
11138
+ searchDir = dirname16(searchDir);
11069
11139
  }
11070
11140
  if (hasProjectMarker(root)) {
11071
11141
  return root;
@@ -11073,12 +11143,12 @@ function walkUpForRoot(start) {
11073
11143
  return "";
11074
11144
  }
11075
11145
  function readConfiguredRoot() {
11076
- const configPath = resolve31(process.env.HOME || "~", ".config", "project-rig", "root");
11077
- if (!existsSync30(configPath)) {
11146
+ const configPath = resolve32(process.env.HOME || "~", ".config", "project-rig", "root");
11147
+ if (!existsSync32(configPath)) {
11078
11148
  return "";
11079
11149
  }
11080
11150
  try {
11081
- const value = readFileSync15(configPath, "utf-8").split(/\r?\n/)[0]?.trim() || "";
11151
+ const value = readFileSync16(configPath, "utf-8").split(/\r?\n/)[0]?.trim() || "";
11082
11152
  return value;
11083
11153
  } catch {
11084
11154
  return "";
@@ -11088,9 +11158,9 @@ function readConfiguredRoot() {
11088
11158
  // packages/runtime/src/control-plane/runtime/events.ts
11089
11159
  import { appendFile, mkdir } from "fs/promises";
11090
11160
  import { randomUUID as randomUUID2 } from "crypto";
11091
- import { dirname as dirname16, resolve as resolve32 } from "path";
11161
+ import { dirname as dirname17, resolve as resolve33 } from "path";
11092
11162
  async function appendEvent(eventsFile, event) {
11093
- await mkdir(dirname16(eventsFile), { recursive: true });
11163
+ await mkdir(dirname17(eventsFile), { recursive: true });
11094
11164
  await appendFile(eventsFile, `${JSON.stringify(event)}
11095
11165
  `, "utf-8");
11096
11166
  }
@@ -11152,7 +11222,7 @@ class GeneralCliEventBus {
11152
11222
  runtimeBuses = new Map;
11153
11223
  constructor(options) {
11154
11224
  this.runId = options.runId || randomUUID2();
11155
- this.eventsFile = options.eventsFile ?? resolve32(options.projectRoot, ".rig", "logs", "control-plane.events.jsonl");
11225
+ this.eventsFile = options.eventsFile ?? resolve33(options.projectRoot, ".rig", "logs", "control-plane.events.jsonl");
11156
11226
  }
11157
11227
  getRunId() {
11158
11228
  return this.runId;
@@ -11205,7 +11275,7 @@ function resolveHarnessPluginMode(options) {
11205
11275
  async function main() {
11206
11276
  const projectRoot = resolveProjectRoot({
11207
11277
  cwd: process.cwd(),
11208
- fallbackFromDir: resolve33(import.meta.dir, "../..")
11278
+ fallbackFromDir: resolve34(import.meta.dir, "../..")
11209
11279
  });
11210
11280
  process.env.PROJECT_RIG_ROOT = projectRoot;
11211
11281
  process.chdir(projectRoot);