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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. package/dist/bin/rig-agent-dispatch.js +518 -459
  2. package/dist/bin/rig-agent.js +430 -361
  3. package/dist/src/control-plane/agent-wrapper.js +523 -464
  4. package/dist/src/control-plane/harness-main.js +544 -463
  5. package/dist/src/control-plane/hooks/completion-verification.js +369 -288
  6. package/dist/src/control-plane/hooks/inject-context.js +158 -99
  7. package/dist/src/control-plane/hooks/submodule-branch.js +538 -479
  8. package/dist/src/control-plane/hooks/task-runtime-start.js +538 -479
  9. package/dist/src/control-plane/materialize-task-config.js +68 -8
  10. package/dist/src/control-plane/native/git-ops.js +10 -0
  11. package/dist/src/control-plane/native/harness-cli.js +529 -448
  12. package/dist/src/control-plane/native/task-ops.js +408 -327
  13. package/dist/src/control-plane/native/validator.js +159 -100
  14. package/dist/src/control-plane/native/verifier.js +243 -171
  15. package/dist/src/control-plane/pi-sessiond/bin.js +0 -7
  16. package/dist/src/control-plane/pi-sessiond/server.js +0 -7
  17. package/dist/src/control-plane/pi-sessiond/session-service.js +0 -3
  18. package/dist/src/control-plane/pi-settings-materializer.js +52 -0
  19. package/dist/src/control-plane/plugin-host-context.js +59 -0
  20. package/dist/src/control-plane/runtime/index.js +469 -410
  21. package/dist/src/control-plane/runtime/isolation/index.js +493 -434
  22. package/dist/src/control-plane/runtime/isolation.js +493 -434
  23. package/dist/src/control-plane/runtime/queue.js +411 -352
  24. package/dist/src/control-plane/tasks/source-lifecycle.js +87 -28
  25. package/dist/src/index.js +16 -8
  26. package/dist/src/local-server.js +17 -8
  27. package/package.json +8 -8
@@ -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,19 +6227,31 @@ function loadGithubPullRequestCheckRollup(projectRoot, repoName, prNumber) {
6168
6227
  ]);
6169
6228
  return response.statusCheckRollup || [];
6170
6229
  }
6171
- function evaluatePullRequestCiChecks(checks, repoName, prNumber) {
6172
- const nonGreptileChecks = checks.filter((check) => {
6173
- const label = (check.name || check.context || "").toLowerCase();
6174
- return label.length > 0 && !label.includes("greptile");
6175
- });
6176
- const pending = nonGreptileChecks.filter((check) => {
6230
+ function evaluatePullRequestCiChecks(checks, repoName, prNumber, options = {}) {
6231
+ const isPendingCheck2 = (check) => {
6177
6232
  if ((check.__typename || "") === "CheckRun") {
6178
6233
  return (check.status || "").toUpperCase() !== "COMPLETED";
6179
6234
  }
6180
6235
  const state = (check.state || check.status || "").toUpperCase();
6181
6236
  return state === "PENDING" || state === "EXPECTED" || state === "QUEUED" || state === "IN_PROGRESS";
6237
+ };
6238
+ const pendingGreptile = checks.filter((check) => {
6239
+ const label = (check.name || check.context || "").toLowerCase();
6240
+ return label.includes("greptile") && isPendingCheck2(check);
6182
6241
  });
6183
- if (pending.length > 0) {
6242
+ if (pendingGreptile.length > 0) {
6243
+ return {
6244
+ verdict: "SKIP",
6245
+ reasons: pendingGreptile.map((check) => `[CI] ${repoName}#${prNumber} mandatory Greptile check is still pending: ${check.name || check.context || "unknown"}.`)
6246
+ };
6247
+ }
6248
+ const nonGreptileChecks = checks.filter((check) => {
6249
+ const label = (check.name || check.context || "").toLowerCase();
6250
+ return label.length > 0 && !label.includes("greptile");
6251
+ });
6252
+ const pending = nonGreptileChecks.filter(isPendingCheck2);
6253
+ const mergeClean = (options.mergeStateStatus || "").toUpperCase() === "CLEAN";
6254
+ if (pending.length > 0 && !mergeClean) {
6184
6255
  return {
6185
6256
  verdict: "SKIP",
6186
6257
  reasons: pending.map((check) => `[CI] ${repoName}#${prNumber} check is still pending: ${check.name || check.context || "unknown"}.`)
@@ -6261,7 +6332,7 @@ function filterActionableGithubGreptileThreads(threads) {
6261
6332
  }
6262
6333
  function resolvePrRepoRoot(projectRoot, prState) {
6263
6334
  const runtimeWorkspace = process.env.RIG_TASK_WORKSPACE?.trim();
6264
- if (prState.target === "monorepo" && runtimeWorkspace && existsSync20(resolve23(runtimeWorkspace, ".git"))) {
6335
+ if (prState.target === "monorepo" && runtimeWorkspace && existsSync22(resolve24(runtimeWorkspace, ".git"))) {
6265
6336
  return runtimeWorkspace;
6266
6337
  }
6267
6338
  const paths = resolveHarnessPaths(projectRoot);
@@ -6633,16 +6704,16 @@ async function taskDeps(projectRoot, taskId) {
6633
6704
  for (const dep of deps) {
6634
6705
  const artifactDir = artifactDirForId(projectRoot, dep);
6635
6706
  console.log(`=== ${dep} ===`);
6636
- if (!existsSync21(artifactDir)) {
6707
+ if (!existsSync23(artifactDir)) {
6637
6708
  console.log(` (no artifacts yet)
6638
6709
  `);
6639
6710
  continue;
6640
6711
  }
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);
6712
+ printArtifactSection(resolve25(artifactDir, "decision-log.md"), "--- Decisions ---");
6713
+ printArtifactSection(resolve25(artifactDir, "next-actions.md"), "--- Next Actions (for you) ---");
6714
+ const changedFiles = resolve25(artifactDir, "changed-files.txt");
6715
+ if (existsSync23(changedFiles)) {
6716
+ const lines = readFileSync12(changedFiles, "utf-8").split(/\r?\n/).filter(Boolean);
6646
6717
  console.log(`--- Changed Files (${lines.length}) ---`);
6647
6718
  for (const line of lines) {
6648
6719
  console.log(line);
@@ -6687,12 +6758,12 @@ function taskRecord(projectRoot, type, text, taskId) {
6687
6758
  throw new Error("No active task.");
6688
6759
  }
6689
6760
  const paths = resolveHarnessPaths(projectRoot);
6690
- mkdirSync10(paths.stateDir, { recursive: true });
6761
+ mkdirSync11(paths.stateDir, { recursive: true });
6691
6762
  if (type === "decision") {
6692
- const artifactDir = resolve24(paths.artifactsDir, activeTask);
6693
- mkdirSync10(artifactDir, { recursive: true });
6763
+ const artifactDir = resolve25(paths.artifactsDir, activeTask);
6764
+ mkdirSync11(artifactDir, { recursive: true });
6694
6765
  const timestamp = nowIso();
6695
- appendFileSync(resolve24(artifactDir, "decision-log.md"), `
6766
+ appendFileSync(resolve25(artifactDir, "decision-log.md"), `
6696
6767
  ### ${timestamp}
6697
6768
 
6698
6769
  ${text}
@@ -6702,14 +6773,14 @@ ${text}
6702
6773
  return;
6703
6774
  }
6704
6775
  const failedPath = paths.failedApproachesPath;
6705
- if (!existsSync21(failedPath)) {
6706
- writeFileSync10(failedPath, `# Failed Approaches Log
6776
+ if (!existsSync23(failedPath)) {
6777
+ writeFileSync11(failedPath, `# Failed Approaches Log
6707
6778
 
6708
6779
  This file records approaches that did not work.
6709
6780
 
6710
6781
  `, "utf-8");
6711
6782
  }
6712
- const content = readFileSync11(failedPath, "utf-8");
6783
+ const content = readFileSync12(failedPath, "utf-8");
6713
6784
  const attempts = (content.match(new RegExp(`^## ${escapeRegExp(activeTask)}\\b`, "gm")) || []).length + 1;
6714
6785
  appendFileSync(failedPath, `
6715
6786
  ## ${activeTask} - Attempt ${attempts} (${nowIso()})
@@ -6726,40 +6797,40 @@ function taskArtifacts(projectRoot, taskId) {
6726
6797
  throw new Error("No active task.");
6727
6798
  }
6728
6799
  const paths = resolveHarnessPaths(projectRoot);
6729
- const artifactDir = resolve24(paths.artifactsDir, activeTask);
6730
- mkdirSync10(artifactDir, { recursive: true });
6800
+ const artifactDir = resolve25(paths.artifactsDir, activeTask);
6801
+ mkdirSync11(artifactDir, { recursive: true });
6731
6802
  const changed = changedFilesForTask(projectRoot, activeTask, true);
6732
- writeFileSync10(resolve24(artifactDir, "changed-files.txt"), `${changed.join(`
6803
+ writeFileSync11(resolve25(artifactDir, "changed-files.txt"), `${changed.join(`
6733
6804
  `)}
6734
6805
  `, "utf-8");
6735
6806
  console.log(`changed-files.txt: ${changed.length} files`);
6736
- const taskResultPath = resolve24(artifactDir, "task-result.json");
6737
- if (!existsSync21(taskResultPath)) {
6807
+ const taskResultPath = resolve25(artifactDir, "task-result.json");
6808
+ if (!existsSync23(taskResultPath)) {
6738
6809
  const template = {
6739
6810
  task_id: activeTask,
6740
6811
  status: "completed",
6741
6812
  summary: "TODO: Write a one-line summary of what you did",
6742
6813
  completed_at: nowIso()
6743
6814
  };
6744
- writeFileSync10(taskResultPath, `${JSON.stringify(template, null, 2)}
6815
+ writeFileSync11(taskResultPath, `${JSON.stringify(template, null, 2)}
6745
6816
  `, "utf-8");
6746
6817
  console.log("task-result.json: created (update the summary!)");
6747
6818
  } else {
6748
6819
  console.log("task-result.json: already exists");
6749
6820
  }
6750
- const decisionLogPath = resolve24(artifactDir, "decision-log.md");
6751
- if (!existsSync21(decisionLogPath)) {
6821
+ const decisionLogPath = resolve25(artifactDir, "decision-log.md");
6822
+ if (!existsSync23(decisionLogPath)) {
6752
6823
  const content = `# Decision Log: ${activeTask}
6753
6824
 
6754
6825
  Record key decisions here using: rig-agent record decision "..."
6755
6826
  `;
6756
- writeFileSync10(decisionLogPath, content, "utf-8");
6827
+ writeFileSync11(decisionLogPath, content, "utf-8");
6757
6828
  console.log("decision-log.md: created (record your decisions!)");
6758
6829
  } else {
6759
6830
  console.log("decision-log.md: already exists");
6760
6831
  }
6761
- const nextActionsPath = resolve24(artifactDir, "next-actions.md");
6762
- if (!existsSync21(nextActionsPath)) {
6832
+ const nextActionsPath = resolve25(artifactDir, "next-actions.md");
6833
+ if (!existsSync23(nextActionsPath)) {
6763
6834
  const content = [
6764
6835
  `# Next Actions: ${activeTask}`,
6765
6836
  "",
@@ -6776,13 +6847,13 @@ Record key decisions here using: rig-agent record decision "..."
6776
6847
  ""
6777
6848
  ].join(`
6778
6849
  `);
6779
- writeFileSync10(nextActionsPath, content, "utf-8");
6850
+ writeFileSync11(nextActionsPath, content, "utf-8");
6780
6851
  console.log("next-actions.md: created (add recommendations for downstream tasks!)");
6781
6852
  } else {
6782
6853
  console.log("next-actions.md: already exists");
6783
6854
  }
6784
- const validationSummaryPath = resolve24(artifactDir, "validation-summary.json");
6785
- if (existsSync21(validationSummaryPath)) {
6855
+ const validationSummaryPath = resolve25(artifactDir, "validation-summary.json");
6856
+ if (existsSync23(validationSummaryPath)) {
6786
6857
  console.log("validation-summary.json: already exists");
6787
6858
  } else {
6788
6859
  console.log("validation-summary.json: not yet created (run: rig-agent validate)");
@@ -6873,7 +6944,7 @@ function collectTaskChangedFiles(projectRoot, taskId, includeCommitted) {
6873
6944
  [projectRoot, ""],
6874
6945
  [monorepoRepoRoot, ""]
6875
6946
  ]) {
6876
- if (!existsSync21(resolve24(repo, ".git"))) {
6947
+ if (!existsSync23(resolve25(repo, ".git"))) {
6877
6948
  continue;
6878
6949
  }
6879
6950
  if (includeCommitted && repo === monorepoRepoRoot) {
@@ -6898,12 +6969,22 @@ function filterTaskChangedFiles(projectRoot, taskId, files, scoped) {
6898
6969
  }
6899
6970
  function resolveTaskMonorepoRoot(projectRoot) {
6900
6971
  const runtimeWorkspace = loadRuntimeContextFromEnv()?.workspaceDir || process.env.RIG_TASK_WORKSPACE?.trim();
6901
- if (runtimeWorkspace && existsSync21(resolve24(runtimeWorkspace, ".git"))) {
6902
- return resolve24(runtimeWorkspace);
6972
+ if (runtimeWorkspace && existsSync23(resolve25(runtimeWorkspace, ".git"))) {
6973
+ return resolve25(runtimeWorkspace);
6903
6974
  }
6904
6975
  return resolveHarnessPaths(projectRoot).monorepoRoot;
6905
6976
  }
6906
6977
  function collectCommittedMonorepoFiles(projectRoot, repo) {
6978
+ const defaultRef = runCapture(["git", "-C", repo, "rev-parse", "--abbrev-ref", "origin/HEAD"], projectRoot);
6979
+ if (defaultRef.exitCode === 0 && defaultRef.stdout.trim()) {
6980
+ const mergeBase = runCapture(["git", "-C", repo, "merge-base", "HEAD", defaultRef.stdout.trim()], projectRoot);
6981
+ if (mergeBase.exitCode === 0 && mergeBase.stdout.trim()) {
6982
+ const result = runCapture(["git", "-C", repo, "diff", "--name-only", `${mergeBase.stdout.trim()}..HEAD`], projectRoot);
6983
+ if (result.exitCode === 0) {
6984
+ return result.stdout.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
6985
+ }
6986
+ }
6987
+ }
6907
6988
  const initialHeadCommit = resolveRuntimeInitialHeadCommit(projectRoot, repo);
6908
6989
  if (initialHeadCommit) {
6909
6990
  const result = runCapture(["git", "-C", repo, "diff", "--name-only", `${initialHeadCommit}..HEAD`], projectRoot);
@@ -6927,7 +7008,7 @@ function resolveRuntimeInitialHeadCommit(projectRoot, repo) {
6927
7008
  const runtimeContext = loadRuntimeContextFromEnv();
6928
7009
  if (runtimeContext?.initialHeadCommits?.monorepo?.trim()) {
6929
7010
  const monorepoRoot = resolveTaskMonorepoRoot(projectRoot);
6930
- if (resolve24(monorepoRoot) === resolve24(repo)) {
7011
+ if (resolve25(monorepoRoot) === resolve25(repo)) {
6931
7012
  return runtimeContext.initialHeadCommits.monorepo.trim();
6932
7013
  }
6933
7014
  }
@@ -6937,7 +7018,7 @@ function resolveMonorepoBaseCommit(projectRoot, repo) {
6937
7018
  const runtimeContext = loadRuntimeContextFromEnv();
6938
7019
  if (runtimeContext?.monorepoBaseCommit?.trim()) {
6939
7020
  const monorepoRoot = resolveTaskMonorepoRoot(projectRoot);
6940
- if (resolve24(monorepoRoot) === resolve24(repo)) {
7021
+ if (resolve25(monorepoRoot) === resolve25(repo)) {
6941
7022
  return runtimeContext.monorepoBaseCommit.trim();
6942
7023
  }
6943
7024
  }
@@ -6982,7 +7063,7 @@ function resolveRuntimeDirtyBaseline(projectRoot, repo) {
6982
7063
  return new Set;
6983
7064
  }
6984
7065
  const monorepoRoot = resolveTaskMonorepoRoot(projectRoot);
6985
- const selected = resolve24(repo) === resolve24(monorepoRoot) ? dirtyFiles.monorepo : resolve24(repo) === resolve24(projectRoot) ? dirtyFiles.project : undefined;
7066
+ const selected = resolve25(repo) === resolve25(monorepoRoot) ? dirtyFiles.monorepo : resolve25(repo) === resolve25(projectRoot) ? dirtyFiles.project : undefined;
6986
7067
  return new Set((selected || []).map((file) => normalizeChangedFilePath(file)).filter(Boolean));
6987
7068
  }
6988
7069
  function normalizeChangedFilePath(file) {
@@ -7082,12 +7163,12 @@ function printIndented(text) {
7082
7163
  }
7083
7164
  }
7084
7165
  function readLocalBeadsTasks(projectRoot) {
7085
- const issuesPath = resolve24(resolveMonorepoRoot2(projectRoot), ".beads/issues.jsonl");
7086
- if (!existsSync21(issuesPath)) {
7166
+ const issuesPath = resolve25(resolveMonorepoRoot2(projectRoot), ".beads/issues.jsonl");
7167
+ if (!existsSync23(issuesPath)) {
7087
7168
  return [];
7088
7169
  }
7089
7170
  const tasks = [];
7090
- for (const line of readFileSync11(issuesPath, "utf-8").split(/\r?\n/)) {
7171
+ for (const line of readFileSync12(issuesPath, "utf-8").split(/\r?\n/)) {
7091
7172
  const trimmed = line.trim();
7092
7173
  if (!trimmed) {
7093
7174
  continue;
@@ -7200,11 +7281,11 @@ function taskDependencies(projectRoot, taskId, tracker) {
7200
7281
  return [...ids].sort();
7201
7282
  }
7202
7283
  function printArtifactSection(path, header) {
7203
- if (!existsSync21(path)) {
7284
+ if (!existsSync23(path)) {
7204
7285
  return;
7205
7286
  }
7206
7287
  console.log(header);
7207
- process.stdout.write(readFileSync11(path, "utf-8"));
7288
+ process.stdout.write(readFileSync12(path, "utf-8"));
7208
7289
  console.log("");
7209
7290
  }
7210
7291
  function escapeRegExp(value) {
@@ -7244,8 +7325,8 @@ function isRuntimeGatewayGhPath(candidate) {
7244
7325
  }
7245
7326
  function resolveOptionalMonorepoRoot(projectRoot) {
7246
7327
  const runtimeWorkspace = process.env.RIG_TASK_WORKSPACE?.trim();
7247
- if (runtimeWorkspace && existsSync22(resolve25(runtimeWorkspace, ".git"))) {
7248
- return resolve25(runtimeWorkspace);
7328
+ if (runtimeWorkspace && existsSync24(resolve26(runtimeWorkspace, ".git"))) {
7329
+ return resolve26(runtimeWorkspace);
7249
7330
  }
7250
7331
  try {
7251
7332
  return resolveMonorepoRoot2(projectRoot);
@@ -7270,7 +7351,7 @@ function resolveGitBinary(projectRoot) {
7270
7351
  if (!candidate || isRuntimeGatewayGitPath(candidate)) {
7271
7352
  continue;
7272
7353
  }
7273
- if (existsSync22(candidate)) {
7354
+ if (existsSync24(candidate)) {
7274
7355
  return candidate;
7275
7356
  }
7276
7357
  }
@@ -7330,11 +7411,11 @@ function gitPreflight(projectRoot, taskId, strict) {
7330
7411
  const expected = resolvedTask ? `rig/${resolveTaskBranchId(projectRoot, resolvedTask)}` : "";
7331
7412
  console.log("=== Git Flow Preflight ===");
7332
7413
  let issues = 0;
7333
- if (!existsSync22(resolve25(projectRoot, ".git"))) {
7414
+ if (!existsSync24(resolve26(projectRoot, ".git"))) {
7334
7415
  console.log(`ERROR: project root is not a git repo (${projectRoot})`);
7335
7416
  issues += 1;
7336
7417
  }
7337
- if (monorepoRoot && existsSync22(resolve25(monorepoRoot, ".git"))) {
7418
+ if (monorepoRoot && existsSync24(resolve26(monorepoRoot, ".git"))) {
7338
7419
  const monoBranch = branchName(projectRoot, monorepoRoot);
7339
7420
  if (expected && monoBranch !== expected) {
7340
7421
  console.log(`WARN: monorepo branch is ${monoBranch}, expected ${expected} for task ${resolvedTask}`);
@@ -7368,7 +7449,7 @@ function gitSyncBranch(projectRoot, taskId, targetRepo = "monorepo") {
7368
7449
  }
7369
7450
  const repoRoot = targetRepo === "monorepo" ? resolveOptionalMonorepoRoot(projectRoot) || resolveMonorepoRoot2(projectRoot) : projectRoot;
7370
7451
  const repoLabel = targetRepo === "monorepo" ? "Monorepo" : "Project";
7371
- if (!existsSync22(resolve25(repoRoot, ".git"))) {
7452
+ if (!existsSync24(resolve26(repoRoot, ".git"))) {
7372
7453
  throw new Error(`${repoLabel} repo not found at ${repoRoot}`);
7373
7454
  }
7374
7455
  const branchId = resolveTaskBranchId(projectRoot, resolvedTask);
@@ -7412,8 +7493,8 @@ function gitCommit(options) {
7412
7493
  function gitSnapshot(projectRoot, taskId, outputPath) {
7413
7494
  const monorepoRoot = resolveOptionalMonorepoRoot(projectRoot);
7414
7495
  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 });
7496
+ const output = outputPath || (resolvedTask ? resolveArtifactSnapshot(projectRoot, resolvedTask) : resolve26(resolve26(projectRoot, ".rig", "state"), "git-state.txt"));
7497
+ mkdirSync12(dirname12(output), { recursive: true });
7417
7498
  const lines = ["# Git Snapshot", `timestamp: ${nowIso()}`];
7418
7499
  if (resolvedTask) {
7419
7500
  lines.push(`task: ${resolvedTask}`);
@@ -7423,7 +7504,7 @@ function gitSnapshot(projectRoot, taskId, outputPath) {
7423
7504
  if (monorepoRoot && monorepoRoot !== projectRoot) {
7424
7505
  lines.push(...snapshotRepo(projectRoot, "monorepo", monorepoRoot));
7425
7506
  }
7426
- writeFileSync11(output, `${lines.join(`
7507
+ writeFileSync12(output, `${lines.join(`
7427
7508
  `)}
7428
7509
  `, "utf-8");
7429
7510
  return output;
@@ -7447,7 +7528,7 @@ function gitOpenPr(options) {
7447
7528
  } else if (taskId) {
7448
7529
  gitSyncBranch(options.projectRoot, taskId, "project");
7449
7530
  }
7450
- if (!existsSync22(resolve25(repoRoot, ".git"))) {
7531
+ if (!existsSync24(resolve26(repoRoot, ".git"))) {
7451
7532
  throw new Error(`Repository not available for open-pr target ${target}: ${repoRoot}`);
7452
7533
  }
7453
7534
  const branch = branchName(options.projectRoot, repoRoot);
@@ -7660,12 +7741,12 @@ function assertPrHasNoGitConflicts(prState, repoLabel, baseRef) {
7660
7741
  }
7661
7742
  function writePrMetadata(projectRoot, taskId, result) {
7662
7743
  const dir = artifactDirForId(projectRoot, taskId);
7663
- mkdirSync11(dir, { recursive: true });
7664
- const path = resolve25(dir, "pr-state.json");
7744
+ mkdirSync12(dir, { recursive: true });
7745
+ const path = resolve26(dir, "pr-state.json");
7665
7746
  let prs = {};
7666
- if (existsSync22(path)) {
7747
+ if (existsSync24(path)) {
7667
7748
  try {
7668
- const parsed = JSON.parse(readFileSync12(path, "utf-8"));
7749
+ const parsed = JSON.parse(readFileSync13(path, "utf-8"));
7669
7750
  if (parsed && typeof parsed === "object" && parsed.prs && typeof parsed.prs === "object") {
7670
7751
  prs = parsed.prs;
7671
7752
  }
@@ -7681,16 +7762,16 @@ function writePrMetadata(projectRoot, taskId, result) {
7681
7762
  ...primary || {},
7682
7763
  updated_at: nowIso()
7683
7764
  };
7684
- writeFileSync11(path, `${JSON.stringify(artifact, null, 2)}
7765
+ writeFileSync12(path, `${JSON.stringify(artifact, null, 2)}
7685
7766
  `, "utf-8");
7686
7767
  }
7687
7768
  function readPrMetadata(projectRoot, taskId) {
7688
- const path = resolve25(artifactDirForId(projectRoot, taskId), "pr-state.json");
7689
- if (!existsSync22(path)) {
7769
+ const path = resolve26(artifactDirForId(projectRoot, taskId), "pr-state.json");
7770
+ if (!existsSync24(path)) {
7690
7771
  return [];
7691
7772
  }
7692
7773
  try {
7693
- const parsed = JSON.parse(readFileSync12(path, "utf-8"));
7774
+ const parsed = JSON.parse(readFileSync13(path, "utf-8"));
7694
7775
  if (!parsed || typeof parsed !== "object") {
7695
7776
  return [];
7696
7777
  }
@@ -7703,8 +7784,8 @@ function readPrMetadata(projectRoot, taskId) {
7703
7784
  }
7704
7785
  }
7705
7786
  function resolveArtifactSnapshot(projectRoot, taskId) {
7706
- const artifactDir = resolve25(resolveHarnessPaths(projectRoot).artifactsDir, taskId);
7707
- return resolve25(artifactDir, "git-state.txt");
7787
+ const artifactDir = resolve26(resolveHarnessPaths(projectRoot).artifactsDir, taskId);
7788
+ return resolve26(artifactDir, "git-state.txt");
7708
7789
  }
7709
7790
  function isGitOpenPrResult(value) {
7710
7791
  if (!value || typeof value !== "object" || Array.isArray(value)) {
@@ -7763,14 +7844,14 @@ function resolveGithubCliBinary(projectRoot) {
7763
7844
  }
7764
7845
  const explicitPathEntries = (process.env.PATH || "").split(":").map((entry) => entry.trim()).filter(Boolean);
7765
7846
  for (const entry of explicitPathEntries) {
7766
- candidates.add(resolve25(entry, "gh"));
7847
+ candidates.add(resolve26(entry, "gh"));
7767
7848
  }
7768
7849
  const bunResolved = Bun.which("gh");
7769
7850
  if (bunResolved) {
7770
7851
  candidates.add(bunResolved);
7771
7852
  }
7772
7853
  for (const candidate of candidates) {
7773
- if (candidate && existsSync22(candidate) && !isRuntimeGatewayGhPath(candidate)) {
7854
+ if (candidate && existsSync24(candidate) && !isRuntimeGatewayGhPath(candidate)) {
7774
7855
  return candidate;
7775
7856
  }
7776
7857
  }
@@ -7800,7 +7881,7 @@ function resolveRepoNameWithOwner(projectRoot, repoRoot) {
7800
7881
  return resolveGithubRepoNameWithOwnerFromGitRoot(projectRoot, repoRoot, repoRoot, visited);
7801
7882
  }
7802
7883
  function resolveGithubRepoNameWithOwnerFromGitRoot(projectRoot, gitRoot, cwd, visited) {
7803
- const normalizedGitRoot = resolve25(gitRoot);
7884
+ const normalizedGitRoot = resolve26(gitRoot);
7804
7885
  if (visited.has(normalizedGitRoot)) {
7805
7886
  return "";
7806
7887
  }
@@ -7872,7 +7953,7 @@ function resolveNetworkRemoteName(projectRoot, repoRoot, repoNameWithOwner) {
7872
7953
  return remotes.includes("origin") ? "origin" : remotes[0];
7873
7954
  }
7874
7955
  function gitQuery(projectRoot, gitRoot, cwd, ...args) {
7875
- const gitArgs = existsSync22(resolve25(gitRoot, ".git")) ? gitCmd(projectRoot, gitRoot, ...args) : [resolveGitBinary(projectRoot), "--git-dir", gitRoot, ...args];
7956
+ const gitArgs = existsSync24(resolve26(gitRoot, ".git")) ? gitCmd(projectRoot, gitRoot, ...args) : [resolveGitBinary(projectRoot), "--git-dir", gitRoot, ...args];
7876
7957
  return runCapture2(gitArgs, cwd, projectRoot);
7877
7958
  }
7878
7959
  function resolveLocalGitRemoteRoot(remoteUrl, gitRoot) {
@@ -7890,9 +7971,9 @@ function resolveLocalGitRemoteRoot(remoteUrl, gitRoot) {
7890
7971
  } else if (/^[a-z][a-z0-9+.-]*:\/\//i.test(normalized) || /^[^@]+@[^:]+:.+$/.test(normalized)) {
7891
7972
  return "";
7892
7973
  } else if (!isAbsolute2(normalized)) {
7893
- candidate = resolve25(gitRoot, normalized);
7974
+ candidate = resolve26(gitRoot, normalized);
7894
7975
  }
7895
- return existsSync22(candidate) ? candidate : "";
7976
+ return existsSync24(candidate) ? candidate : "";
7896
7977
  }
7897
7978
  function normalizeGithubRepoNameWithOwner(value) {
7898
7979
  const normalized = value.trim();
@@ -8019,7 +8100,7 @@ function inferReviewerFromChangedFiles(projectRoot, repoRoot, baseRef, branchRef
8019
8100
  return best;
8020
8101
  }
8021
8102
  function snapshotRepo(projectRoot, label, repo) {
8022
- if (!existsSync22(resolve25(repo, ".git"))) {
8103
+ if (!existsSync24(resolve26(repo, ".git"))) {
8023
8104
  return [`## ${label}`, `repo: ${repo}`, "status: unavailable", ""];
8024
8105
  }
8025
8106
  const status = runCapture2(gitCmd(projectRoot, repo, "status", "--short"), projectRoot).stdout.trim();
@@ -8042,7 +8123,7 @@ function snapshotRepo(projectRoot, label, repo) {
8042
8123
  ];
8043
8124
  }
8044
8125
  function commitRepo(projectRoot, repo, label, message, allowEmpty, scoped, files, changedFilesManifest) {
8045
- if (!existsSync22(resolve25(repo, ".git"))) {
8126
+ if (!existsSync24(resolve26(repo, ".git"))) {
8046
8127
  console.log(`Skipping ${label}: repo not available (${repo})`);
8047
8128
  return;
8048
8129
  }
@@ -8074,18 +8155,18 @@ function commitRepo(projectRoot, repo, label, message, allowEmpty, scoped, files
8074
8155
  console.log(`Committed ${label}: ${message}`);
8075
8156
  }
8076
8157
  function readChangedFilesManifest(projectRoot, taskId) {
8077
- const manifestPath = resolve25(artifactDirForId(projectRoot, taskId), "changed-files.txt");
8078
- if (!existsSync22(manifestPath)) {
8158
+ const manifestPath = resolve26(artifactDirForId(projectRoot, taskId), "changed-files.txt");
8159
+ if (!existsSync24(manifestPath)) {
8079
8160
  return [];
8080
8161
  }
8081
- const files = readFileSync12(manifestPath, "utf-8").split(/\r?\n/).map((line) => normalizeChangedFilePath2(line)).filter(Boolean);
8162
+ const files = readFileSync13(manifestPath, "utf-8").split(/\r?\n/).map((line) => normalizeChangedFilePath2(line)).filter(Boolean);
8082
8163
  return [...new Set(files)];
8083
8164
  }
8084
8165
  function refreshChangedFilesManifest(projectRoot, taskId) {
8085
- const manifestPath = resolve25(artifactDirForId(projectRoot, taskId), "changed-files.txt");
8086
- mkdirSync11(dirname11(manifestPath), { recursive: true });
8166
+ const manifestPath = resolve26(artifactDirForId(projectRoot, taskId), "changed-files.txt");
8167
+ mkdirSync12(dirname12(manifestPath), { recursive: true });
8087
8168
  const changedFiles = changedFilesForTask(projectRoot, taskId, true);
8088
- writeFileSync11(manifestPath, `${changedFiles.join(`
8169
+ writeFileSync12(manifestPath, `${changedFiles.join(`
8089
8170
  `)}
8090
8171
  `, "utf-8");
8091
8172
  return manifestPath;
@@ -8198,7 +8279,7 @@ function repoHasPathChange(projectRoot, repoRoot, relativePath) {
8198
8279
  return result.exitCode === 0 && result.stdout.trim().length > 0;
8199
8280
  }
8200
8281
  function stageExcludePathspecs(repoRoot) {
8201
- const patterns = existsSync22(resolve25(repoRoot, ".rig", "task-config.json")) ? [...TASK_RUNTIME_STAGE_EXCLUDES, ...GENERATED_STAGE_EXCLUDES] : [".rig/**", ...GENERATED_STAGE_EXCLUDES];
8282
+ const patterns = existsSync24(resolve26(repoRoot, ".rig", "task-config.json")) ? [...TASK_RUNTIME_STAGE_EXCLUDES, ...GENERATED_STAGE_EXCLUDES] : [".rig/**", ...GENERATED_STAGE_EXCLUDES];
8202
8283
  return patterns.map((pattern) => `:(glob,exclude)${pattern}`);
8203
8284
  }
8204
8285
  function pathResolvesBeyondSymlink(repoRoot, relativePath) {
@@ -8208,7 +8289,7 @@ function pathResolvesBeyondSymlink(repoRoot, relativePath) {
8208
8289
  }
8209
8290
  let current = repoRoot;
8210
8291
  for (let index = 0;index < parts.length - 1; index += 1) {
8211
- current = resolve25(current, parts[index]);
8292
+ current = resolve26(current, parts[index]);
8212
8293
  try {
8213
8294
  if (lstatSync(current).isSymbolicLink()) {
8214
8295
  return true;
@@ -8220,7 +8301,7 @@ function pathResolvesBeyondSymlink(repoRoot, relativePath) {
8220
8301
  return false;
8221
8302
  }
8222
8303
  function printRepoStatus(projectRoot, label, repo, expectedBranch) {
8223
- if (!existsSync22(resolve25(repo, ".git"))) {
8304
+ if (!existsSync24(resolve26(repo, ".git"))) {
8224
8305
  console.log(`${label}: unavailable (${repo})`);
8225
8306
  return;
8226
8307
  }
@@ -8256,7 +8337,7 @@ function resolveTaskBranchId(projectRoot, taskId) {
8256
8337
  }
8257
8338
  } catch {}
8258
8339
  const artifactDir = artifactDirForId(projectRoot, taskId);
8259
- if (existsSync22(artifactDir)) {
8340
+ if (existsSync24(artifactDir)) {
8260
8341
  return taskId;
8261
8342
  }
8262
8343
  throw new Error(`Unknown task id: ${taskId}`);
@@ -8292,11 +8373,11 @@ function runCapture2(command, cwd, projectRoot = cwd) {
8292
8373
  }
8293
8374
  function runtimeGitEnv(projectRoot) {
8294
8375
  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") : "";
8376
+ const runtimeHome = runtimeRoot ? resolve26(runtimeRoot, "home") : "";
8377
+ const runtimeTmp = runtimeRoot ? resolve26(runtimeRoot, "tmp") : "";
8378
+ const runtimeCache = runtimeRoot ? resolve26(runtimeRoot, "cache") : "";
8379
+ const runtimeKnownHosts = runtimeHome ? resolve26(runtimeHome, ".ssh", "known_hosts") : "";
8380
+ const runtimeKey = runtimeHome ? resolve26(runtimeHome, ".ssh", "rig-agent-key") : "";
8300
8381
  const env = {};
8301
8382
  if (ctx?.workspaceDir) {
8302
8383
  env.PROJECT_RIG_ROOT = projectRoot;
@@ -8309,14 +8390,14 @@ function runtimeGitEnv(projectRoot) {
8309
8390
  if (runtimeRoot) {
8310
8391
  env.RIG_RUNTIME_HOME = runtimeRoot;
8311
8392
  }
8312
- if (runtimeHome && existsSync22(runtimeHome)) {
8393
+ if (runtimeHome && existsSync24(runtimeHome)) {
8313
8394
  env.HOME = runtimeHome;
8314
8395
  env.OPENSSL_CONF = ensureRuntimeOpenSslConfig(runtimeHome);
8315
8396
  }
8316
- if (runtimeTmp && existsSync22(runtimeTmp)) {
8397
+ if (runtimeTmp && existsSync24(runtimeTmp)) {
8317
8398
  env.TMPDIR = runtimeTmp;
8318
8399
  }
8319
- if (runtimeCache && existsSync22(runtimeCache)) {
8400
+ if (runtimeCache && existsSync24(runtimeCache)) {
8320
8401
  env.XDG_CACHE_HOME = runtimeCache;
8321
8402
  }
8322
8403
  const workspaceSecrets = loadDotEnvSecrets(ctx?.workspaceDir || projectRoot, process.env);
@@ -8360,14 +8441,14 @@ function runtimeGitEnv(projectRoot) {
8360
8441
  env.GH_TOKEN = env.GH_TOKEN || gitHubToken;
8361
8442
  applyGitHubCredentialHelperEnv(env);
8362
8443
  }
8363
- if (runtimeKnownHosts && existsSync22(runtimeKnownHosts)) {
8444
+ if (runtimeKnownHosts && existsSync24(runtimeKnownHosts)) {
8364
8445
  const sshParts = [
8365
8446
  "ssh",
8366
8447
  `-o UserKnownHostsFile="${runtimeKnownHosts}"`,
8367
8448
  "-o StrictHostKeyChecking=yes",
8368
8449
  "-F /dev/null"
8369
8450
  ];
8370
- if (runtimeKey && existsSync22(runtimeKey)) {
8451
+ if (runtimeKey && existsSync24(runtimeKey)) {
8371
8452
  sshParts.splice(1, 0, `-i "${runtimeKey}"`, "-o IdentitiesOnly=yes");
8372
8453
  }
8373
8454
  env.GIT_SSH_COMMAND = sshParts.join(" ");
@@ -8388,12 +8469,12 @@ function loadPersistedRuntimeSecrets(runtimeRoot) {
8388
8469
  if (!runtimeRoot) {
8389
8470
  return {};
8390
8471
  }
8391
- const path = resolve25(runtimeRoot, "runtime-secrets.json");
8392
- if (!existsSync22(path)) {
8472
+ const path = resolve26(runtimeRoot, "runtime-secrets.json");
8473
+ if (!existsSync24(path)) {
8393
8474
  return {};
8394
8475
  }
8395
8476
  try {
8396
- const parsed = JSON.parse(readFileSync12(path, "utf-8"));
8477
+ const parsed = JSON.parse(readFileSync13(path, "utf-8"));
8397
8478
  const entries = Object.entries(parsed).filter((entry) => typeof entry[1] === "string");
8398
8479
  return Object.fromEntries(entries);
8399
8480
  } catch {
@@ -8401,13 +8482,13 @@ function loadPersistedRuntimeSecrets(runtimeRoot) {
8401
8482
  }
8402
8483
  }
8403
8484
  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 });
8485
+ const sslDir = resolve26(runtimeHome, ".ssl");
8486
+ const sslConfig = resolve26(sslDir, "openssl.cnf");
8487
+ if (!existsSync24(sslDir)) {
8488
+ mkdirSync12(sslDir, { recursive: true });
8408
8489
  }
8409
- if (!existsSync22(sslConfig)) {
8410
- writeFileSync11(sslConfig, `# Rig runtime OpenSSL config placeholder
8490
+ if (!existsSync24(sslConfig)) {
8491
+ writeFileSync12(sslConfig, `# Rig runtime OpenSSL config placeholder
8411
8492
  `);
8412
8493
  }
8413
8494
  return sslConfig;
@@ -8425,29 +8506,29 @@ function resolveRuntimeMetadata(projectRoot) {
8425
8506
  if (contextFile) {
8426
8507
  return {
8427
8508
  ctx,
8428
- runtimeRoot: dirname11(resolve25(contextFile))
8509
+ runtimeRoot: dirname12(resolve26(contextFile))
8429
8510
  };
8430
8511
  }
8431
8512
  const inferredContextFile = findRuntimeContextFile2(projectRoot);
8432
- if (existsSync22(inferredContextFile)) {
8513
+ if (existsSync24(inferredContextFile)) {
8433
8514
  try {
8434
8515
  ctx = loadRuntimeContext(inferredContextFile);
8435
8516
  } catch {}
8436
8517
  return {
8437
8518
  ctx,
8438
- runtimeRoot: dirname11(inferredContextFile)
8519
+ runtimeRoot: dirname12(inferredContextFile)
8439
8520
  };
8440
8521
  }
8441
8522
  return { ctx, runtimeRoot: "" };
8442
8523
  }
8443
8524
  function findRuntimeContextFile2(startPath) {
8444
- let current = resolve25(startPath);
8525
+ let current = resolve26(startPath);
8445
8526
  while (true) {
8446
- const candidate = resolve25(current, "runtime-context.json");
8447
- if (existsSync22(candidate)) {
8527
+ const candidate = resolve26(current, "runtime-context.json");
8528
+ if (existsSync24(candidate)) {
8448
8529
  return candidate;
8449
8530
  }
8450
- const parent = dirname11(current);
8531
+ const parent = dirname12(current);
8451
8532
  if (parent === current) {
8452
8533
  return "";
8453
8534
  }
@@ -8456,7 +8537,7 @@ function findRuntimeContextFile2(startPath) {
8456
8537
  }
8457
8538
 
8458
8539
  // packages/runtime/src/control-plane/native/profile-ops.ts
8459
- import { existsSync as existsSync23, mkdirSync as mkdirSync12, writeFileSync as writeFileSync12 } from "fs";
8540
+ import { existsSync as existsSync25, mkdirSync as mkdirSync13, writeFileSync as writeFileSync13 } from "fs";
8460
8541
  var DEFAULTS = {
8461
8542
  model: parseEnvOrDefault(process.env.DEFAULT_AGENT_MODEL, ["claude", "gpt-codex", "pi"], "pi"),
8462
8543
  runtime: parseEnvOrDefault(process.env.DEFAULT_AGENT_RUNTIME, ["claude-code", "codex-app-server", "pi"], "pi"),
@@ -8471,7 +8552,7 @@ function parseEnvOrDefault(value, allowed, fallback) {
8471
8552
  return allowed.includes(value) ? value : fallback;
8472
8553
  }
8473
8554
  async function readProfileFile(path) {
8474
- if (!existsSync23(path)) {
8555
+ if (!existsSync25(path)) {
8475
8556
  return null;
8476
8557
  }
8477
8558
  try {
@@ -8524,14 +8605,14 @@ async function setProfile(projectRoot, options) {
8524
8605
  plugin = model === "gpt-codex" ? "codex" : model === "pi" ? "pi" : "claude";
8525
8606
  }
8526
8607
  const paths = resolveHarnessPaths(projectRoot);
8527
- mkdirSync12(paths.stateDir, { recursive: true });
8608
+ mkdirSync13(paths.stateDir, { recursive: true });
8528
8609
  const next = {
8529
8610
  model,
8530
8611
  runtime,
8531
8612
  agent_plugin: plugin,
8532
8613
  updated_at: new Date().toISOString()
8533
8614
  };
8534
- writeFileSync12(paths.agentProfilePath, `${JSON.stringify(next, null, 2)}
8615
+ writeFileSync13(paths.agentProfilePath, `${JSON.stringify(next, null, 2)}
8535
8616
  `, "utf-8");
8536
8617
  await showProfile(projectRoot, false);
8537
8618
  }
@@ -8567,13 +8648,13 @@ async function setReviewProfile(projectRoot, mode, provider) {
8567
8648
  throw new Error(`Invalid provider: ${resolvedProvider}. Supported: greptile.`);
8568
8649
  }
8569
8650
  const paths = resolveHarnessPaths(projectRoot);
8570
- mkdirSync12(paths.stateDir, { recursive: true });
8651
+ mkdirSync13(paths.stateDir, { recursive: true });
8571
8652
  const next = {
8572
8653
  mode,
8573
8654
  provider: resolvedProvider,
8574
8655
  updated_at: new Date().toISOString()
8575
8656
  };
8576
- writeFileSync12(paths.reviewProfilePath, `${JSON.stringify(next, null, 2)}
8657
+ writeFileSync13(paths.reviewProfilePath, `${JSON.stringify(next, null, 2)}
8577
8658
  `, "utf-8");
8578
8659
  await showReviewProfile(projectRoot);
8579
8660
  }
@@ -8611,44 +8692,44 @@ async function loadReviewProfile(path) {
8611
8692
  }
8612
8693
 
8613
8694
  // 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";
8695
+ import { existsSync as existsSync29, mkdirSync as mkdirSync17, readFileSync as readFileSync15, readdirSync as readdirSync6, rmSync as rmSync7, writeFileSync as writeFileSync15 } from "fs";
8696
+ import { basename as basename8, dirname as dirname14, resolve as resolve30 } from "path";
8616
8697
  // 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";
8698
+ import { existsSync as existsSync27, mkdirSync as mkdirSync15, realpathSync as realpathSync2 } from "fs";
8699
+ import { resolve as resolve28 } from "path";
8619
8700
 
8620
8701
  // 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";
8702
+ 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";
8703
+ import { dirname as dirname13, join as join4, relative, resolve as resolve27 } from "path";
8623
8704
  import { parse as parseToml, stringify as stringifyToml } from "smol-toml";
8624
8705
  function resolveAuthorityProjectStateDir(projectRoot) {
8625
8706
  const explicit = process.env.RIG_STATE_DIR?.trim();
8626
8707
  if (explicit) {
8627
- return resolve26(explicit);
8708
+ return resolve27(explicit);
8628
8709
  }
8629
- return resolve26(resolve26(projectRoot), ".rig", "state");
8710
+ return resolve27(resolve27(projectRoot), ".rig", "state");
8630
8711
  }
8631
8712
  function readJsonAtPath(path, fallback) {
8632
- if (!existsSync24(path)) {
8713
+ if (!existsSync26(path)) {
8633
8714
  return fallback;
8634
8715
  }
8635
8716
  try {
8636
- return JSON.parse(readFileSync13(path, "utf-8"));
8717
+ return JSON.parse(readFileSync14(path, "utf-8"));
8637
8718
  } catch {
8638
8719
  return fallback;
8639
8720
  }
8640
8721
  }
8641
8722
  function writeJsonAtPath(path, value) {
8642
- mkdirSync13(dirname12(path), { recursive: true });
8643
- writeFileSync13(path, `${JSON.stringify(value, null, 2)}
8723
+ mkdirSync14(dirname13(path), { recursive: true });
8724
+ writeFileSync14(path, `${JSON.stringify(value, null, 2)}
8644
8725
  `, "utf8");
8645
8726
  return path;
8646
8727
  }
8647
8728
  function readAuthorityProjectStateJson(projectRoot, relativePath, fallback) {
8648
- return readJsonAtPath(resolve26(resolveAuthorityProjectStateDir(projectRoot), relativePath), fallback);
8729
+ return readJsonAtPath(resolve27(resolveAuthorityProjectStateDir(projectRoot), relativePath), fallback);
8649
8730
  }
8650
8731
  function writeAuthorityProjectStateJson(projectRoot, relativePath, value) {
8651
- return writeJsonAtPath(resolve26(resolveAuthorityProjectStateDir(projectRoot), relativePath), value);
8732
+ return writeJsonAtPath(resolve27(resolveAuthorityProjectStateDir(projectRoot), relativePath), value);
8652
8733
  }
8653
8734
 
8654
8735
  // packages/runtime/src/control-plane/repos/mirror/state.ts
@@ -8708,7 +8789,7 @@ function sameExistingPath(left, right) {
8708
8789
  try {
8709
8790
  return realpathSync2(left) === realpathSync2(right);
8710
8791
  } catch {
8711
- return resolve27(left) === resolve27(right);
8792
+ return resolve28(left) === resolve28(right);
8712
8793
  }
8713
8794
  }
8714
8795
  function repoLooksUsable(repoRoot, projectRoot) {
@@ -8744,7 +8825,7 @@ function resolveMirrorRemoteUrl(layout) {
8744
8825
  }
8745
8826
  }
8746
8827
  }
8747
- if (existsSync25(resolve27(layout.checkoutRoot, ".git")) && checkoutLooksUsable(layout)) {
8828
+ if (existsSync27(resolve28(layout.checkoutRoot, ".git")) && checkoutLooksUsable(layout)) {
8748
8829
  const checkoutOrigin = runGit(["git", "-C", layout.checkoutRoot, "remote", "get-url", "origin"], layout.projectRoot);
8749
8830
  if (checkoutOrigin.exitCode === 0) {
8750
8831
  const currentOrigin = checkoutOrigin.stdout.trim();
@@ -8757,9 +8838,9 @@ function resolveMirrorRemoteUrl(layout) {
8757
8838
  }
8758
8839
  function ensureManagedRepoMirror(projectRoot, repoId) {
8759
8840
  const layout = resolveManagedRepoLayout(projectRoot, repoId);
8760
- mkdirSync14(layout.metadataRoot, { recursive: true });
8841
+ mkdirSync15(layout.metadataRoot, { recursive: true });
8761
8842
  const remoteUrl = resolveMirrorRemoteUrl(layout);
8762
- if (!existsSync25(resolve27(layout.mirrorRoot, "HEAD"))) {
8843
+ if (!existsSync27(resolve28(layout.mirrorRoot, "HEAD"))) {
8763
8844
  ensureGitSuccess(runGit(["git", "init", "--bare", layout.mirrorRoot], layout.projectRoot), ["git", "init", "--bare", layout.mirrorRoot]);
8764
8845
  }
8765
8846
  const getOrigin = runGit(["git", "--git-dir", layout.mirrorRoot, "remote", "get-url", "origin"], layout.projectRoot);
@@ -8779,8 +8860,8 @@ function ensureManagedRepoMirror(projectRoot, repoId) {
8779
8860
  return layout;
8780
8861
  }
8781
8862
  // 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";
8863
+ import { existsSync as existsSync28, mkdirSync as mkdirSync16, realpathSync as realpathSync3, rmSync as rmSync6 } from "fs";
8864
+ import { resolve as resolve29 } from "path";
8784
8865
  function nowIso3() {
8785
8866
  return new Date().toISOString();
8786
8867
  }
@@ -8807,7 +8888,7 @@ function sameExistingPath2(left, right) {
8807
8888
  try {
8808
8889
  return realpathSync3(left) === realpathSync3(right);
8809
8890
  } catch {
8810
- return resolve28(left) === resolve28(right);
8891
+ return resolve29(left) === resolve29(right);
8811
8892
  }
8812
8893
  }
8813
8894
  function ensureMirrorHead(layout) {
@@ -8853,12 +8934,12 @@ function checkoutLooksUsable2(layout) {
8853
8934
  return probe.exitCode === 0 && sameExistingPath2(probe.stdout.trim(), layout.checkoutRoot);
8854
8935
  }
8855
8936
  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))) {
8937
+ mkdirSync16(resolve29(layout.checkoutRoot, ".."), { recursive: true });
8938
+ const gitPath = resolve29(layout.checkoutRoot, ".git");
8939
+ if (existsSync28(layout.checkoutRoot) && (!existsSync28(gitPath) || !checkoutLooksUsable2(layout))) {
8859
8940
  rmSync6(layout.checkoutRoot, { recursive: true, force: true });
8860
8941
  }
8861
- if (!existsSync26(gitPath)) {
8942
+ if (!existsSync28(gitPath)) {
8862
8943
  ensureGitSuccess2(runGit2(["git", "clone", layout.mirrorRoot, layout.checkoutRoot], layout.projectRoot), ["git", "clone", layout.mirrorRoot, layout.checkoutRoot]);
8863
8944
  }
8864
8945
  const getOrigin = runGit2(["git", "-C", layout.checkoutRoot, "remote", "get-url", "origin"], layout.projectRoot);
@@ -8959,7 +9040,7 @@ function repoDiscover(projectRoot, taskId) {
8959
9040
  }
8960
9041
  function repoBaseline(projectRoot, refresh = false) {
8961
9042
  const paths = resolveRepoDiscoveryPaths(projectRoot);
8962
- if (!refresh && existsSync27(paths.baseRepoPinsPath)) {
9043
+ if (!refresh && existsSync29(paths.baseRepoPinsPath)) {
8963
9044
  const baseline = readJsonFile(paths.baseRepoPinsPath, { recorded_at: nowIso(), repos: {} });
8964
9045
  return baseline.repos || {};
8965
9046
  }
@@ -8983,8 +9064,8 @@ function ensureMonorepoReady(projectRoot) {
8983
9064
  }
8984
9065
  function persistBaselinePins(projectRoot, repos) {
8985
9066
  const paths = resolveRepoDiscoveryPaths(projectRoot);
8986
- mkdirSync16(resolve29(paths.baseRepoPinsPath, ".."), { recursive: true });
8987
- writeFileSync14(paths.baseRepoPinsPath, `${JSON.stringify({ recorded_at: nowIso(), repos }, null, 2)}
9067
+ mkdirSync17(resolve30(paths.baseRepoPinsPath, ".."), { recursive: true });
9068
+ writeFileSync15(paths.baseRepoPinsPath, `${JSON.stringify({ recorded_at: nowIso(), repos }, null, 2)}
8988
9069
  `, "utf-8");
8989
9070
  return repos;
8990
9071
  }
@@ -9063,28 +9144,28 @@ function readRepoDiscoveryTaskConfig(projectRoot) {
9063
9144
  function resolveRepoDiscoveryPaths(projectRoot) {
9064
9145
  const monorepoRoot = resolveMonorepoRepoLayout(projectRoot).checkoutRoot;
9065
9146
  const explicitHostProjectRoot = (process.env.RIG_HOST_PROJECT_ROOT || "").trim();
9066
- const normalizedProjectRoot = resolve29(projectRoot);
9147
+ const normalizedProjectRoot = resolve30(projectRoot);
9067
9148
  const hostProjectRoot = explicitHostProjectRoot && shouldUseHostProjectStateRoot(normalizedProjectRoot) ? explicitHostProjectRoot : normalizedProjectRoot;
9068
- const stateDir = resolve29(hostProjectRoot, ".rig", "state");
9149
+ const stateDir = resolve30(hostProjectRoot, ".rig", "state");
9069
9150
  return {
9070
9151
  monorepoRoot,
9071
- taskRepoCommitsPath: resolve29(stateDir, "task-repo-commits.json"),
9072
- baseRepoPinsPath: resolve29(stateDir, "base-repo-pins.json")
9152
+ taskRepoCommitsPath: resolve30(stateDir, "task-repo-commits.json"),
9153
+ baseRepoPinsPath: resolve30(stateDir, "base-repo-pins.json")
9073
9154
  };
9074
9155
  }
9075
9156
  function shouldUseHostProjectStateRoot(projectRoot) {
9076
9157
  const runtimeWorkspace = process.env.RIG_TASK_WORKSPACE?.trim();
9077
- if (runtimeWorkspace && resolve29(runtimeWorkspace) === projectRoot) {
9158
+ if (runtimeWorkspace && resolve30(runtimeWorkspace) === projectRoot) {
9078
9159
  return true;
9079
9160
  }
9080
- return basename8(dirname13(projectRoot)) === ".worktrees";
9161
+ return basename8(dirname14(projectRoot)) === ".worktrees";
9081
9162
  }
9082
9163
  function readPinFromArtifact(projectRoot, depTask, repoKey) {
9083
- const snapshot = resolve29(artifactDirForId(projectRoot, depTask), "git-state.txt");
9084
- if (!existsSync27(snapshot)) {
9164
+ const snapshot = resolve30(artifactDirForId(projectRoot, depTask), "git-state.txt");
9165
+ if (!existsSync29(snapshot)) {
9085
9166
  return "";
9086
9167
  }
9087
- const content = readFileSync14(snapshot, "utf-8");
9168
+ const content = readFileSync15(snapshot, "utf-8");
9088
9169
  const chunk = content.split(/\r?\n/);
9089
9170
  let inSection = false;
9090
9171
  for (const line of chunk) {
@@ -9106,12 +9187,12 @@ function repoPath(projectRoot, key) {
9106
9187
  if (managed) {
9107
9188
  return managed.checkoutRoot;
9108
9189
  }
9109
- return key.startsWith("/") ? key : resolve29(projectRoot, key);
9190
+ return key.startsWith("/") ? key : resolve30(projectRoot, key);
9110
9191
  }
9111
9192
  function applyPins(projectRoot, pins) {
9112
9193
  for (const [key, commit] of Object.entries(pins)) {
9113
9194
  const path = repoPath(projectRoot, key);
9114
- if (!existsSync27(resolve29(path, ".git"))) {
9195
+ if (!existsSync29(resolve30(path, ".git"))) {
9115
9196
  throw new Error(`Repo for pin not available: ${key} (${path})`);
9116
9197
  }
9117
9198
  let hasCommit = runGitCapture(["git", "-C", path, "cat-file", "-e", `${commit}^{commit}`], projectRoot).exitCode === 0;
@@ -9140,7 +9221,7 @@ function verifyPins(projectRoot, pins) {
9140
9221
  let ok = true;
9141
9222
  for (const [key, expected] of Object.entries(pins)) {
9142
9223
  const path = repoPath(projectRoot, key);
9143
- if (!existsSync27(resolve29(path, ".git"))) {
9224
+ if (!existsSync29(resolve30(path, ".git"))) {
9144
9225
  console.error(`ERROR: repo missing during pin verification: ${key}`);
9145
9226
  ok = false;
9146
9227
  continue;
@@ -9165,23 +9246,23 @@ function resolveRuntimeGitEnv() {
9165
9246
  GIT_SSH_COMMAND: process.env.GIT_SSH_COMMAND
9166
9247
  };
9167
9248
  }
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() || "";
9249
+ 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()));
9250
+ const runtimeHome = runtimeRoot ? resolve30(runtimeRoot, "home") : process.env.HOME?.trim() || "";
9170
9251
  if (!runtimeHome) {
9171
9252
  return;
9172
9253
  }
9173
- const knownHostsPath = resolve29(runtimeHome, ".ssh", "known_hosts");
9174
- if (!existsSync27(knownHostsPath)) {
9254
+ const knownHostsPath = resolve30(runtimeHome, ".ssh", "known_hosts");
9255
+ if (!existsSync29(knownHostsPath)) {
9175
9256
  return { HOME: runtimeHome };
9176
9257
  }
9177
- const agentSshKey = resolve29(runtimeHome, ".ssh", "rig-agent-key");
9258
+ const agentSshKey = resolve30(runtimeHome, ".ssh", "rig-agent-key");
9178
9259
  const sshParts = [
9179
9260
  "ssh",
9180
9261
  `-o UserKnownHostsFile="${knownHostsPath}"`,
9181
9262
  "-o StrictHostKeyChecking=yes",
9182
9263
  "-F /dev/null"
9183
9264
  ];
9184
- if (existsSync27(agentSshKey)) {
9265
+ if (existsSync29(agentSshKey)) {
9185
9266
  sshParts.splice(1, 0, `-i "${agentSshKey}"`, "-o IdentitiesOnly=yes");
9186
9267
  }
9187
9268
  return {
@@ -9191,24 +9272,24 @@ function resolveRuntimeGitEnv() {
9191
9272
  }
9192
9273
  function inferRuntimeRootFromWorkspace(cwd) {
9193
9274
  const contextPath = findRuntimeContextFile3(cwd);
9194
- if (!contextPath || !existsSync27(contextPath)) {
9275
+ if (!contextPath || !existsSync29(contextPath)) {
9195
9276
  return "";
9196
9277
  }
9197
9278
  try {
9198
9279
  loadRuntimeContext(contextPath);
9199
- return resolve29(contextPath, "..");
9280
+ return resolve30(contextPath, "..");
9200
9281
  } catch {
9201
9282
  return "";
9202
9283
  }
9203
9284
  }
9204
9285
  function findRuntimeContextFile3(startPath) {
9205
- let current = resolve29(startPath);
9286
+ let current = resolve30(startPath);
9206
9287
  while (true) {
9207
- const candidate = resolve29(current, "runtime-context.json");
9208
- if (existsSync27(candidate)) {
9288
+ const candidate = resolve30(current, "runtime-context.json");
9289
+ if (existsSync29(candidate)) {
9209
9290
  return candidate;
9210
9291
  }
9211
- const parent = resolve29(current, "..");
9292
+ const parent = resolve30(current, "..");
9212
9293
  if (parent === current) {
9213
9294
  return "";
9214
9295
  }
@@ -9217,13 +9298,13 @@ function findRuntimeContextFile3(startPath) {
9217
9298
  }
9218
9299
 
9219
9300
  // packages/runtime/src/control-plane/memory-sync/cli.ts
9220
- import { existsSync as existsSync28 } from "fs";
9301
+ import { existsSync as existsSync30 } from "fs";
9221
9302
  import { randomUUID } from "crypto";
9222
9303
 
9223
9304
  // packages/runtime/src/control-plane/memory-sync/db.ts
9224
9305
  import { Database } from "bun:sqlite";
9225
- import { mkdirSync as mkdirSync17 } from "fs";
9226
- import { dirname as dirname14 } from "path";
9306
+ import { mkdirSync as mkdirSync18 } from "fs";
9307
+ import { dirname as dirname15 } from "path";
9227
9308
 
9228
9309
  // packages/runtime/src/control-plane/memory-sync/types.ts
9229
9310
  var NO_MATCH_RETRIEVAL_CANONICAL_KEY = "__memory_recall__:none";
@@ -9819,7 +9900,7 @@ async function validateEventTargets(executor, event) {
9819
9900
  }
9820
9901
  }
9821
9902
  async function openMemoryDb(dbPath) {
9822
- mkdirSync17(dirname14(dbPath), { recursive: true });
9903
+ mkdirSync18(dirname15(dbPath), { recursive: true });
9823
9904
  const sqlite = new Database(dbPath, { create: true, strict: true });
9824
9905
  const client = createMemoryDbClient(sqlite);
9825
9906
  const db = {
@@ -10238,7 +10319,7 @@ function formatMemoryQueryResults(results) {
10238
10319
  }
10239
10320
 
10240
10321
  // packages/runtime/src/control-plane/memory-sync/read.ts
10241
- import { mkdtempSync, rmSync as rmSync8, writeFileSync as writeFileSync15 } from "fs";
10322
+ import { mkdtempSync, rmSync as rmSync8, writeFileSync as writeFileSync16 } from "fs";
10242
10323
  import { tmpdir as tmpdir5 } from "os";
10243
10324
  import { join as join5 } from "path";
10244
10325
  var CANONICAL_MEMORY_DB_PATH = "rig/memory/project-memory.db";
@@ -10267,7 +10348,7 @@ async function readCanonicalMemoryDb(projectRoot, deps = {}) {
10267
10348
  try {
10268
10349
  try {
10269
10350
  const bytes = readDeps.readBlobBytesAtRef(repoPath2, baseOid, CANONICAL_MEMORY_DB_PATH);
10270
- writeFileSync15(dbPath, bytes);
10351
+ writeFileSync16(dbPath, bytes);
10271
10352
  } catch (error) {
10272
10353
  if (!isMissingCanonicalMemoryBlobError(error)) {
10273
10354
  throw error;
@@ -10425,7 +10506,7 @@ function requireRuntimeMemoryContext(runtimeContext) {
10425
10506
  }
10426
10507
  async function ensureRuntimeMemoryUsable(runtimeContext) {
10427
10508
  const memory = requireRuntimeMemoryContext(runtimeContext);
10428
- if (!existsSync28(memory.hydratedPath)) {
10509
+ if (!existsSync30(memory.hydratedPath)) {
10429
10510
  throw new Error(`Shared memory database is missing: ${memory.hydratedPath}`);
10430
10511
  }
10431
10512
  const db = await openMemoryDb(memory.hydratedPath);
@@ -10726,8 +10807,8 @@ async function executeHarnessCommand(projectRoot, args, eventBus, pluginHostCtx)
10726
10807
  }
10727
10808
  case "completion-verification":
10728
10809
  case "completition-verification": {
10729
- const hookPath = resolve30(projectRoot, ".rig/bin/hooks/completion-verification");
10730
- if (!existsSync29(hookPath)) {
10810
+ const hookPath = resolve31(projectRoot, ".rig/bin/hooks/completion-verification");
10811
+ if (!existsSync31(hookPath)) {
10731
10812
  throw new Error(`completion-verification hook binary not found: ${hookPath}`);
10732
10813
  }
10733
10814
  const proc = Bun.spawn([hookPath], {
@@ -11029,10 +11110,10 @@ function printHelp() {
11029
11110
  }
11030
11111
 
11031
11112
  // 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";
11113
+ import { existsSync as existsSync32, readFileSync as readFileSync16 } from "fs";
11114
+ import { dirname as dirname16, parse, resolve as resolve32 } from "path";
11034
11115
  function hasProjectMarker(candidate) {
11035
- return existsSync30(resolve31(candidate, RIG_DEFINITION_DIRNAME)) || existsSync30(resolve31(candidate, RIG_STATE_DIRNAME));
11116
+ return existsSync32(resolve32(candidate, RIG_DEFINITION_DIRNAME)) || existsSync32(resolve32(candidate, RIG_STATE_DIRNAME));
11036
11117
  }
11037
11118
  function resolveProjectRoot(options) {
11038
11119
  const cwd = options?.cwd || process.cwd();
@@ -11049,23 +11130,23 @@ function resolveProjectRoot(options) {
11049
11130
  if (configRoot && hasProjectMarker(configRoot)) {
11050
11131
  return configRoot;
11051
11132
  }
11052
- let fileDir = resolve31(fallbackFromDir);
11133
+ let fileDir = resolve32(fallbackFromDir);
11053
11134
  for (let i = 0;i < 5; i += 1) {
11054
11135
  if (hasProjectMarker(fileDir)) {
11055
11136
  return fileDir;
11056
11137
  }
11057
- fileDir = dirname15(fileDir);
11138
+ fileDir = dirname16(fileDir);
11058
11139
  }
11059
11140
  return cwd;
11060
11141
  }
11061
11142
  function walkUpForRoot(start) {
11062
- let searchDir = resolve31(start);
11143
+ let searchDir = resolve32(start);
11063
11144
  const root = parse(searchDir).root || "/";
11064
11145
  while (searchDir !== root) {
11065
11146
  if (hasProjectMarker(searchDir)) {
11066
11147
  return searchDir;
11067
11148
  }
11068
- searchDir = dirname15(searchDir);
11149
+ searchDir = dirname16(searchDir);
11069
11150
  }
11070
11151
  if (hasProjectMarker(root)) {
11071
11152
  return root;
@@ -11073,12 +11154,12 @@ function walkUpForRoot(start) {
11073
11154
  return "";
11074
11155
  }
11075
11156
  function readConfiguredRoot() {
11076
- const configPath = resolve31(process.env.HOME || "~", ".config", "project-rig", "root");
11077
- if (!existsSync30(configPath)) {
11157
+ const configPath = resolve32(process.env.HOME || "~", ".config", "project-rig", "root");
11158
+ if (!existsSync32(configPath)) {
11078
11159
  return "";
11079
11160
  }
11080
11161
  try {
11081
- const value = readFileSync15(configPath, "utf-8").split(/\r?\n/)[0]?.trim() || "";
11162
+ const value = readFileSync16(configPath, "utf-8").split(/\r?\n/)[0]?.trim() || "";
11082
11163
  return value;
11083
11164
  } catch {
11084
11165
  return "";
@@ -11088,9 +11169,9 @@ function readConfiguredRoot() {
11088
11169
  // packages/runtime/src/control-plane/runtime/events.ts
11089
11170
  import { appendFile, mkdir } from "fs/promises";
11090
11171
  import { randomUUID as randomUUID2 } from "crypto";
11091
- import { dirname as dirname16, resolve as resolve32 } from "path";
11172
+ import { dirname as dirname17, resolve as resolve33 } from "path";
11092
11173
  async function appendEvent(eventsFile, event) {
11093
- await mkdir(dirname16(eventsFile), { recursive: true });
11174
+ await mkdir(dirname17(eventsFile), { recursive: true });
11094
11175
  await appendFile(eventsFile, `${JSON.stringify(event)}
11095
11176
  `, "utf-8");
11096
11177
  }
@@ -11152,7 +11233,7 @@ class GeneralCliEventBus {
11152
11233
  runtimeBuses = new Map;
11153
11234
  constructor(options) {
11154
11235
  this.runId = options.runId || randomUUID2();
11155
- this.eventsFile = options.eventsFile ?? resolve32(options.projectRoot, ".rig", "logs", "control-plane.events.jsonl");
11236
+ this.eventsFile = options.eventsFile ?? resolve33(options.projectRoot, ".rig", "logs", "control-plane.events.jsonl");
11156
11237
  }
11157
11238
  getRunId() {
11158
11239
  return this.runId;
@@ -11205,7 +11286,7 @@ function resolveHarnessPluginMode(options) {
11205
11286
  async function main() {
11206
11287
  const projectRoot = resolveProjectRoot({
11207
11288
  cwd: process.cwd(),
11208
- fallbackFromDir: resolve33(import.meta.dir, "../..")
11289
+ fallbackFromDir: resolve34(import.meta.dir, "../..")
11209
11290
  });
11210
11291
  process.env.PROJECT_RIG_ROOT = projectRoot;
11211
11292
  process.chdir(projectRoot);