@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
@@ -1,11 +1,11 @@
1
1
  // @bun
2
2
  // packages/runtime/src/control-plane/native/harness-cli.ts
3
- import { existsSync as existsSync29 } from "fs";
4
- import { resolve as resolve30 } from "path";
3
+ import { existsSync as existsSync31 } from "fs";
4
+ import { resolve as resolve31 } from "path";
5
5
 
6
6
  // packages/runtime/src/control-plane/native/git-ops.ts
7
- import { existsSync as existsSync22, lstatSync, mkdirSync as mkdirSync11, readFileSync as readFileSync12, writeFileSync as writeFileSync11 } from "fs";
8
- import { dirname as dirname11, isAbsolute as isAbsolute2, resolve as resolve25 } from "path";
7
+ import { existsSync as existsSync24, lstatSync, mkdirSync as mkdirSync12, readFileSync as readFileSync13, writeFileSync as writeFileSync12 } from "fs";
8
+ import { dirname as dirname12, isAbsolute as isAbsolute2, resolve as resolve26 } from "path";
9
9
  import { fileURLToPath as fileURLToPath2 } from "url";
10
10
 
11
11
  // packages/runtime/src/control-plane/runtime/baked-secrets.ts
@@ -274,8 +274,8 @@ function isAgentRuntimeContextPath(path) {
274
274
  }
275
275
 
276
276
  // packages/runtime/src/control-plane/native/task-ops.ts
277
- import { appendFileSync, existsSync as existsSync21, mkdirSync as mkdirSync10, readFileSync as readFileSync11, writeFileSync as writeFileSync10 } from "fs";
278
- import { resolve as resolve24 } from "path";
277
+ import { appendFileSync, existsSync as existsSync23, mkdirSync as mkdirSync11, readFileSync as readFileSync12, writeFileSync as writeFileSync11 } from "fs";
278
+ import { resolve as resolve25 } from "path";
279
279
 
280
280
  // packages/runtime/src/build-time-config.ts
281
281
  function normalizeBuildConfig(value) {
@@ -824,6 +824,8 @@ function buildBrowserGuidanceLines(browser) {
824
824
  }
825
825
 
826
826
  // packages/runtime/src/control-plane/plugin-host-context.ts
827
+ import { existsSync as existsSync8 } from "fs";
828
+ import { resolve as resolvePath } from "path";
827
829
  import { createPluginHost } from "@rig/core";
828
830
  import { loadConfig } from "@rig/core/load-config";
829
831
 
@@ -1171,6 +1173,55 @@ async function materializeSkills(projectRoot, entries) {
1171
1173
  return written;
1172
1174
  }
1173
1175
 
1176
+ // packages/runtime/src/control-plane/pi-settings-materializer.ts
1177
+ import { existsSync as existsSync7, mkdirSync as mkdirSync5, readFileSync as readFileSync6, writeFileSync as writeFileSync5 } from "fs";
1178
+ import { dirname as dirname6, resolve as resolve9 } from "path";
1179
+ var SETTINGS_RELATIVE_PATH = ".pi/settings.json";
1180
+ var MANAGED_RECORD_RELATIVE_PATH = ".rig/state/pi-managed-packages.json";
1181
+ function readJson(path, fallback) {
1182
+ if (!existsSync7(path))
1183
+ return fallback;
1184
+ try {
1185
+ return JSON.parse(readFileSync6(path, "utf-8"));
1186
+ } catch {
1187
+ return fallback;
1188
+ }
1189
+ }
1190
+ function packageKey(entry) {
1191
+ if (typeof entry === "string")
1192
+ return entry;
1193
+ if (entry && typeof entry === "object" && typeof entry.source === "string") {
1194
+ return entry.source;
1195
+ }
1196
+ return JSON.stringify(entry);
1197
+ }
1198
+ function materializePiPackages(projectRoot, declaredPackages) {
1199
+ const settingsPath = resolve9(projectRoot, SETTINGS_RELATIVE_PATH);
1200
+ const managedRecordPath = resolve9(projectRoot, MANAGED_RECORD_RELATIVE_PATH);
1201
+ const settings = readJson(settingsPath, {});
1202
+ const previouslyManaged = new Set(readJson(managedRecordPath, []));
1203
+ const existing = Array.isArray(settings.packages) ? settings.packages : [];
1204
+ const operatorEntries = existing.filter((entry) => !previouslyManaged.has(packageKey(entry)));
1205
+ const operatorKeys = new Set(operatorEntries.map(packageKey));
1206
+ const managedToAdd = declaredPackages.filter((pkg) => !operatorKeys.has(pkg));
1207
+ const nextPackages = [...operatorEntries, ...managedToAdd];
1208
+ if (nextPackages.length > 0 || existsSync7(settingsPath)) {
1209
+ const nextSettings = { ...settings };
1210
+ if (nextPackages.length > 0) {
1211
+ nextSettings.packages = nextPackages;
1212
+ } else {
1213
+ delete nextSettings.packages;
1214
+ }
1215
+ mkdirSync5(dirname6(settingsPath), { recursive: true });
1216
+ writeFileSync5(settingsPath, `${JSON.stringify(nextSettings, null, 2)}
1217
+ `, "utf-8");
1218
+ }
1219
+ mkdirSync5(dirname6(managedRecordPath), { recursive: true });
1220
+ writeFileSync5(managedRecordPath, `${JSON.stringify(managedToAdd, null, 2)}
1221
+ `, "utf-8");
1222
+ return { settingsPath, packages: managedToAdd };
1223
+ }
1224
+
1174
1225
  // packages/runtime/src/control-plane/plugin-host-context.ts
1175
1226
  async function buildPluginHostContext(projectRoot) {
1176
1227
  let config;
@@ -1218,6 +1269,14 @@ async function buildPluginHostContext(projectRoot) {
1218
1269
  } catch (err) {
1219
1270
  console.warn(`[plugin-host] skill materialization failed: ${err instanceof Error ? err.message : err}`);
1220
1271
  }
1272
+ try {
1273
+ const piPackages = config.runtime?.pi?.packages ?? [];
1274
+ if (piPackages.length > 0 || existsSync8(resolvePath(projectRoot, ".rig/state/pi-managed-packages.json"))) {
1275
+ materializePiPackages(projectRoot, piPackages);
1276
+ }
1277
+ } catch (err) {
1278
+ console.warn(`[plugin-host] Pi package materialization failed: ${err instanceof Error ? err.message : err}`);
1279
+ }
1221
1280
  return {
1222
1281
  config,
1223
1282
  pluginHost,
@@ -1231,12 +1290,12 @@ async function buildPluginHostContext(projectRoot) {
1231
1290
 
1232
1291
  // packages/runtime/src/control-plane/tasks/source-aware-task-config-source.ts
1233
1292
  import { spawnSync } from "child_process";
1234
- import { existsSync as existsSync8, readFileSync as readFileSync7, readdirSync as readdirSync2, statSync, writeFileSync as writeFileSync5 } from "fs";
1235
- import { basename as basename3, join as join2, resolve as resolve10 } from "path";
1293
+ import { existsSync as existsSync10, readFileSync as readFileSync8, readdirSync as readdirSync2, statSync, writeFileSync as writeFileSync6 } from "fs";
1294
+ import { basename as basename3, join as join2, resolve as resolve11 } from "path";
1236
1295
 
1237
1296
  // packages/runtime/src/control-plane/tasks/legacy-task-config-source.ts
1238
- import { existsSync as existsSync7, readFileSync as readFileSync6 } from "fs";
1239
- import { resolve as resolve9 } from "path";
1297
+ import { existsSync as existsSync9, readFileSync as readFileSync7 } from "fs";
1298
+ import { resolve as resolve10 } from "path";
1240
1299
 
1241
1300
  // packages/runtime/src/control-plane/tasks/task-record-reader.ts
1242
1301
  async function findTaskById(reader, id) {
@@ -1259,7 +1318,7 @@ class LegacyTaskConfigReadError extends Error {
1259
1318
  }
1260
1319
  }
1261
1320
  function createLegacyTaskConfigRecordReader(projectRoot, options = {}) {
1262
- const configPath = options.configPath ?? resolve9(projectRoot, ".rig", "task-config.json");
1321
+ const configPath = options.configPath ?? resolve10(projectRoot, ".rig", "task-config.json");
1263
1322
  const reader = {
1264
1323
  async listTasks() {
1265
1324
  return readLegacyTaskRecords(projectRoot, configPath);
@@ -1270,8 +1329,8 @@ function createLegacyTaskConfigRecordReader(projectRoot, options = {}) {
1270
1329
  };
1271
1330
  return reader;
1272
1331
  }
1273
- function readLegacyTaskRecords(projectRoot, configPath = resolve9(projectRoot, ".rig", "task-config.json")) {
1274
- if (!existsSync7(configPath)) {
1332
+ function readLegacyTaskRecords(projectRoot, configPath = resolve10(projectRoot, ".rig", "task-config.json")) {
1333
+ if (!existsSync9(configPath)) {
1275
1334
  return [];
1276
1335
  }
1277
1336
  const rawConfig = readLegacyTaskConfigJson(projectRoot, configPath);
@@ -1279,7 +1338,7 @@ function readLegacyTaskRecords(projectRoot, configPath = resolve9(projectRoot, "
1279
1338
  }
1280
1339
  function readLegacyTaskConfigJson(projectRoot, configPath) {
1281
1340
  try {
1282
- const parsed = JSON.parse(readFileSync6(configPath, "utf8"));
1341
+ const parsed = JSON.parse(readFileSync7(configPath, "utf8"));
1283
1342
  if (isPlainRecord(parsed)) {
1284
1343
  return parsed;
1285
1344
  }
@@ -1363,7 +1422,7 @@ function isPlainRecord(candidate) {
1363
1422
  var STATUS_LABELS = new Set(["ready", "blocked", "in-progress", "under-review", "failed", "cancelled"]);
1364
1423
  var FILE_TASK_PATTERN = /\.(task\.)?json$/;
1365
1424
  function createSourceAwareTaskConfigRecordReader(projectRoot, options = {}) {
1366
- const configPath = options.configPath ?? resolve10(projectRoot, ".rig", "task-config.json");
1425
+ const configPath = options.configPath ?? resolve11(projectRoot, ".rig", "task-config.json");
1367
1426
  const legacy = createLegacyTaskConfigRecordReader(projectRoot, { configPath });
1368
1427
  const spawnFn = options.spawn ?? spawnSync;
1369
1428
  const ghBinary = options.ghBinary ?? "gh";
@@ -1446,10 +1505,10 @@ function readMaterializedTaskMetadata(entry) {
1446
1505
  return metadata;
1447
1506
  }
1448
1507
  function readConfiguredFilesTaskSourcePath(projectRoot) {
1449
- const jsonPath = resolve10(projectRoot, "rig.config.json");
1450
- if (existsSync8(jsonPath)) {
1508
+ const jsonPath = resolve11(projectRoot, "rig.config.json");
1509
+ if (existsSync10(jsonPath)) {
1451
1510
  try {
1452
- const parsed = JSON.parse(readFileSync7(jsonPath, "utf8"));
1511
+ const parsed = JSON.parse(readFileSync8(jsonPath, "utf8"));
1453
1512
  if (isPlainRecord2(parsed) && isPlainRecord2(parsed.taskSource)) {
1454
1513
  const source = parsed.taskSource;
1455
1514
  return source.kind === "files" && typeof source.path === "string" ? source.path : null;
@@ -1458,12 +1517,12 @@ function readConfiguredFilesTaskSourcePath(projectRoot) {
1458
1517
  return null;
1459
1518
  }
1460
1519
  }
1461
- const tsPath = resolve10(projectRoot, "rig.config.ts");
1462
- if (!existsSync8(tsPath)) {
1520
+ const tsPath = resolve11(projectRoot, "rig.config.ts");
1521
+ if (!existsSync10(tsPath)) {
1463
1522
  return null;
1464
1523
  }
1465
1524
  try {
1466
- const source = readFileSync7(tsPath, "utf8");
1525
+ const source = readFileSync8(tsPath, "utf8");
1467
1526
  const taskSourceBlock = source.match(/taskSource\s*:\s*\{[\s\S]*?\}/m)?.[0] ?? "";
1468
1527
  const kind = taskSourceBlock.match(/kind\s*:\s*["']([^"']+)["']/)?.[1];
1469
1528
  if (kind !== "files") {
@@ -1483,10 +1542,10 @@ function readRawTaskEntry(configPath, taskId) {
1483
1542
  return isPlainRecord2(entry) ? entry : null;
1484
1543
  }
1485
1544
  function readRawTaskConfig(configPath) {
1486
- if (!existsSync8(configPath)) {
1545
+ if (!existsSync10(configPath)) {
1487
1546
  return null;
1488
1547
  }
1489
- const parsed = JSON.parse(readFileSync7(configPath, "utf8"));
1548
+ const parsed = JSON.parse(readFileSync8(configPath, "utf8"));
1490
1549
  return isPlainRecord2(parsed) ? parsed : null;
1491
1550
  }
1492
1551
  function stripLegacyTaskConfigMetadata2(raw) {
@@ -1494,8 +1553,8 @@ function stripLegacyTaskConfigMetadata2(raw) {
1494
1553
  return tasks;
1495
1554
  }
1496
1555
  function listFileBackedTasks(projectRoot, sourcePath) {
1497
- const directory = resolve10(projectRoot, sourcePath);
1498
- if (!existsSync8(directory)) {
1556
+ const directory = resolve11(projectRoot, sourcePath);
1557
+ if (!existsSync10(directory)) {
1499
1558
  return [];
1500
1559
  }
1501
1560
  const tasks = [];
@@ -1510,11 +1569,11 @@ function listFileBackedTasks(projectRoot, sourcePath) {
1510
1569
  return tasks;
1511
1570
  }
1512
1571
  function readFileBackedTask(projectRoot, sourcePath, taskId, rawEntry) {
1513
- const file = findFileBackedTaskFile(resolve10(projectRoot, sourcePath), taskId);
1572
+ const file = findFileBackedTaskFile(resolve11(projectRoot, sourcePath), taskId);
1514
1573
  if (!file) {
1515
1574
  return null;
1516
1575
  }
1517
- const raw = JSON.parse(readFileSync7(file, "utf8"));
1576
+ const raw = JSON.parse(readFileSync8(file, "utf8"));
1518
1577
  if (!isPlainRecord2(raw)) {
1519
1578
  return null;
1520
1579
  }
@@ -1527,7 +1586,7 @@ function readFileBackedTask(projectRoot, sourcePath, taskId, rawEntry) {
1527
1586
  };
1528
1587
  }
1529
1588
  function findFileBackedTaskFile(directory, taskId) {
1530
- if (!existsSync8(directory)) {
1589
+ if (!existsSync10(directory)) {
1531
1590
  return null;
1532
1591
  }
1533
1592
  for (const name of readdirSync2(directory)) {
@@ -1537,7 +1596,7 @@ function findFileBackedTaskFile(directory, taskId) {
1537
1596
  try {
1538
1597
  if (!statSync(file).isFile())
1539
1598
  continue;
1540
- const raw = JSON.parse(readFileSync7(file, "utf8"));
1599
+ const raw = JSON.parse(readFileSync8(file, "utf8"));
1541
1600
  const inferredId = basename3(file).replace(FILE_TASK_PATTERN, "");
1542
1601
  const id = isPlainRecord2(raw) && typeof raw.id === "string" ? raw.id : inferredId;
1543
1602
  if (id === taskId) {
@@ -1697,8 +1756,8 @@ async function readConfiguredTaskSourceTask(projectRoot, taskId) {
1697
1756
  }
1698
1757
 
1699
1758
  // packages/runtime/src/control-plane/native/task-state.ts
1700
- import { existsSync as existsSync15, readFileSync as readFileSync10, readdirSync as readdirSync3, statSync as statSync3, writeFileSync as writeFileSync6 } from "fs";
1701
- import { basename as basename6, resolve as resolve17 } from "path";
1759
+ import { existsSync as existsSync17, readFileSync as readFileSync11, readdirSync as readdirSync3, statSync as statSync3, writeFileSync as writeFileSync7 } from "fs";
1760
+ import { basename as basename6, resolve as resolve18 } from "path";
1702
1761
 
1703
1762
  // packages/runtime/src/control-plane/state-sync/types.ts
1704
1763
  var SUPPORTED_TASK_STATE_SCHEMA_VERSION = 1;
@@ -1806,50 +1865,50 @@ function readTaskStateMetadataEnvelope(raw) {
1806
1865
  };
1807
1866
  }
1808
1867
  // packages/runtime/src/control-plane/state-sync/read.ts
1809
- import { existsSync as existsSync14, readFileSync as readFileSync9 } from "fs";
1810
- import { resolve as resolve16 } from "path";
1868
+ import { existsSync as existsSync16, readFileSync as readFileSync10 } from "fs";
1869
+ import { resolve as resolve17 } from "path";
1811
1870
 
1812
1871
  // packages/runtime/src/control-plane/native/utils.ts
1813
- import { existsSync as existsSync11, readFileSync as readFileSync8 } from "fs";
1814
- import { resolve as resolve13 } from "path";
1872
+ import { existsSync as existsSync13, readFileSync as readFileSync9 } from "fs";
1873
+ import { resolve as resolve14 } from "path";
1815
1874
 
1816
1875
  // packages/runtime/src/layout.ts
1817
- import { existsSync as existsSync9 } from "fs";
1818
- import { basename as basename4, dirname as dirname6, resolve as resolve11 } from "path";
1876
+ import { existsSync as existsSync11 } from "fs";
1877
+ import { basename as basename4, dirname as dirname7, resolve as resolve12 } from "path";
1819
1878
  var RIG_DEFINITION_DIRNAME = "rig";
1820
1879
  var RIG_ARTIFACTS_DIRNAME = "artifacts";
1821
1880
  function resolveMonorepoRoot(projectRoot) {
1822
- const normalizedProjectRoot = resolve11(projectRoot);
1881
+ const normalizedProjectRoot = resolve12(projectRoot);
1823
1882
  const explicit = process.env.MONOREPO_ROOT?.trim();
1824
1883
  if (explicit) {
1825
- const explicitRoot = resolve11(explicit);
1826
- const explicitParent = dirname6(explicitRoot);
1884
+ const explicitRoot = resolve12(explicit);
1885
+ const explicitParent = dirname7(explicitRoot);
1827
1886
  if (basename4(explicitParent) === ".worktrees") {
1828
- const owner = dirname6(explicitParent);
1829
- const ownerHasGit = existsSync9(resolve11(owner, ".git"));
1830
- const ownerHasTaskConfig = existsSync9(resolve11(owner, ".rig", "task-config.json"));
1831
- const ownerHasRigConfig = existsSync9(resolve11(owner, "rig.config.ts"));
1887
+ const owner = dirname7(explicitParent);
1888
+ const ownerHasGit = existsSync11(resolve12(owner, ".git"));
1889
+ const ownerHasTaskConfig = existsSync11(resolve12(owner, ".rig", "task-config.json"));
1890
+ const ownerHasRigConfig = existsSync11(resolve12(owner, "rig.config.ts"));
1832
1891
  if (ownerHasGit && (ownerHasTaskConfig || ownerHasRigConfig)) {
1833
1892
  return owner;
1834
1893
  }
1835
1894
  throw new Error(`MONOREPO_ROOT points to worktree ${explicitRoot}, but the owner checkout is incomplete at ${owner}.`);
1836
1895
  }
1837
- if (!existsSync9(resolve11(explicitRoot, ".git"))) {
1896
+ if (!existsSync11(resolve12(explicitRoot, ".git"))) {
1838
1897
  throw new Error(`MONOREPO_ROOT points to ${explicitRoot}, but no git checkout was found there.`);
1839
1898
  }
1840
- const hasTaskConfig = existsSync9(resolve11(explicitRoot, ".rig", "task-config.json"));
1841
- const hasRigConfig = existsSync9(resolve11(explicitRoot, "rig.config.ts"));
1899
+ const hasTaskConfig = existsSync11(resolve12(explicitRoot, ".rig", "task-config.json"));
1900
+ const hasRigConfig = existsSync11(resolve12(explicitRoot, "rig.config.ts"));
1842
1901
  if (!hasTaskConfig && !hasRigConfig) {
1843
1902
  throw new Error(`MONOREPO_ROOT points to ${explicitRoot}, but neither .rig/task-config.json nor rig.config.ts exists there.`);
1844
1903
  }
1845
1904
  return explicitRoot;
1846
1905
  }
1847
- const projectParent = dirname6(normalizedProjectRoot);
1906
+ const projectParent = dirname7(normalizedProjectRoot);
1848
1907
  if (basename4(projectParent) === ".worktrees") {
1849
- const worktreeOwner = dirname6(projectParent);
1850
- const ownerHasGit = existsSync9(resolve11(worktreeOwner, ".git"));
1851
- const ownerHasTaskConfig = existsSync9(resolve11(worktreeOwner, ".rig", "task-config.json"));
1852
- const ownerHasRigConfig = existsSync9(resolve11(worktreeOwner, "rig.config.ts"));
1908
+ const worktreeOwner = dirname7(projectParent);
1909
+ const ownerHasGit = existsSync11(resolve12(worktreeOwner, ".git"));
1910
+ const ownerHasTaskConfig = existsSync11(resolve12(worktreeOwner, ".rig", "task-config.json"));
1911
+ const ownerHasRigConfig = existsSync11(resolve12(worktreeOwner, "rig.config.ts"));
1853
1912
  if (ownerHasGit && (ownerHasTaskConfig || ownerHasRigConfig)) {
1854
1913
  return worktreeOwner;
1855
1914
  }
@@ -1857,28 +1916,28 @@ function resolveMonorepoRoot(projectRoot) {
1857
1916
  return normalizedProjectRoot;
1858
1917
  }
1859
1918
  function resolveRuntimeWorkspaceLayout(workspaceDir) {
1860
- const root = resolve11(workspaceDir);
1861
- const rigRoot = resolve11(root, ".rig");
1862
- const logsDir = resolve11(rigRoot, "logs");
1863
- const stateDir = resolve11(rigRoot, "state");
1864
- const runtimeDir = resolve11(rigRoot, "runtime");
1865
- const binDir = resolve11(rigRoot, "bin");
1919
+ const root = resolve12(workspaceDir);
1920
+ const rigRoot = resolve12(root, ".rig");
1921
+ const logsDir = resolve12(rigRoot, "logs");
1922
+ const stateDir = resolve12(rigRoot, "state");
1923
+ const runtimeDir = resolve12(rigRoot, "runtime");
1924
+ const binDir = resolve12(rigRoot, "bin");
1866
1925
  return {
1867
1926
  workspaceDir: root,
1868
1927
  rigRoot,
1869
1928
  stateDir,
1870
1929
  logsDir,
1871
- artifactsRoot: resolve11(root, RIG_ARTIFACTS_DIRNAME),
1930
+ artifactsRoot: resolve12(root, RIG_ARTIFACTS_DIRNAME),
1872
1931
  runtimeDir,
1873
- homeDir: resolve11(rigRoot, "home"),
1874
- tmpDir: resolve11(rigRoot, "tmp"),
1875
- cacheDir: resolve11(rigRoot, "cache"),
1876
- sessionDir: resolve11(rigRoot, "session"),
1932
+ homeDir: resolve12(rigRoot, "home"),
1933
+ tmpDir: resolve12(rigRoot, "tmp"),
1934
+ cacheDir: resolve12(rigRoot, "cache"),
1935
+ sessionDir: resolve12(rigRoot, "session"),
1877
1936
  binDir,
1878
- distDir: resolve11(rigRoot, "dist"),
1879
- pluginBinDir: resolve11(binDir, "plugins"),
1880
- contextPath: resolve11(rigRoot, "runtime-context.json"),
1881
- controlPlaneEventsFile: resolve11(logsDir, "control-plane.events.jsonl")
1937
+ distDir: resolve12(rigRoot, "dist"),
1938
+ pluginBinDir: resolve12(binDir, "plugins"),
1939
+ contextPath: resolve12(rigRoot, "runtime-context.json"),
1940
+ controlPlaneEventsFile: resolve12(logsDir, "control-plane.events.jsonl")
1882
1941
  };
1883
1942
  }
1884
1943
  function resolveActiveRuntimeWorkspaceRoot(monorepoRoot) {
@@ -1886,14 +1945,14 @@ function resolveActiveRuntimeWorkspaceRoot(monorepoRoot) {
1886
1945
  if (!explicit) {
1887
1946
  throw new Error("No active runtime workspace. Set RIG_TASK_WORKSPACE or provision a task runtime first.");
1888
1947
  }
1889
- return resolve11(explicit);
1948
+ return resolve12(explicit);
1890
1949
  }
1891
1950
  function resolveRigLayout(projectRoot) {
1892
1951
  const monorepoRoot = resolveMonorepoRoot(projectRoot);
1893
- const definitionRoot = resolve11(projectRoot, RIG_DEFINITION_DIRNAME);
1952
+ const definitionRoot = resolve12(projectRoot, RIG_DEFINITION_DIRNAME);
1894
1953
  const runtimeWorkspaceRoot = resolveActiveRuntimeWorkspaceRoot(monorepoRoot);
1895
1954
  const runtimeLayout = resolveRuntimeWorkspaceLayout(runtimeWorkspaceRoot);
1896
- const policyDir = resolve11(definitionRoot, "policy");
1955
+ const policyDir = resolve12(definitionRoot, "policy");
1897
1956
  return {
1898
1957
  projectRoot,
1899
1958
  monorepoRoot,
@@ -1901,48 +1960,48 @@ function resolveRigLayout(projectRoot) {
1901
1960
  runtimeWorkspaceRoot,
1902
1961
  stateRoot: runtimeLayout.rigRoot,
1903
1962
  artifactsRoot: runtimeLayout.artifactsRoot,
1904
- configPath: resolve11(definitionRoot, "config.sh"),
1905
- taskConfigPath: resolve11(runtimeWorkspaceRoot, ".rig", "task-config.json"),
1963
+ configPath: resolve12(definitionRoot, "config.sh"),
1964
+ taskConfigPath: resolve12(runtimeWorkspaceRoot, ".rig", "task-config.json"),
1906
1965
  policyDir,
1907
- policyFile: resolve11(policyDir, "policy.json"),
1908
- pluginsDir: resolve11(definitionRoot, "plugins"),
1909
- hooksDir: resolve11(definitionRoot, "hooks"),
1910
- toolsDir: resolve11(definitionRoot, "tools"),
1911
- templatesDir: resolve11(definitionRoot, "templates"),
1912
- validationDir: resolve11(definitionRoot, "validation"),
1966
+ policyFile: resolve12(policyDir, "policy.json"),
1967
+ pluginsDir: resolve12(definitionRoot, "plugins"),
1968
+ hooksDir: resolve12(definitionRoot, "hooks"),
1969
+ toolsDir: resolve12(definitionRoot, "tools"),
1970
+ templatesDir: resolve12(definitionRoot, "templates"),
1971
+ validationDir: resolve12(definitionRoot, "validation"),
1913
1972
  stateDir: runtimeLayout.stateDir,
1914
1973
  logsDir: runtimeLayout.logsDir,
1915
- notificationsDir: resolve11(definitionRoot, "notifications"),
1974
+ notificationsDir: resolve12(definitionRoot, "notifications"),
1916
1975
  runtimeDir: runtimeLayout.runtimeDir,
1917
1976
  distDir: runtimeLayout.distDir,
1918
1977
  binDir: runtimeLayout.binDir,
1919
1978
  pluginBinDir: runtimeLayout.pluginBinDir,
1920
- keybindingsPath: resolve11(definitionRoot, "keybindings.json"),
1979
+ keybindingsPath: resolve12(definitionRoot, "keybindings.json"),
1921
1980
  controlPlaneEventsFile: runtimeLayout.controlPlaneEventsFile
1922
1981
  };
1923
1982
  }
1924
1983
 
1925
1984
  // packages/runtime/src/control-plane/native/runtime-native.ts
1926
1985
  import { dlopen, ptr, suffix, toBuffer } from "bun:ffi";
1927
- import { copyFileSync as copyFileSync2, existsSync as existsSync10, mkdirSync as mkdirSync5, renameSync as renameSync2, rmSync as rmSync3, statSync as statSync2 } from "fs";
1986
+ import { copyFileSync as copyFileSync2, existsSync as existsSync12, mkdirSync as mkdirSync6, renameSync as renameSync2, rmSync as rmSync3, statSync as statSync2 } from "fs";
1928
1987
  import { tmpdir as tmpdir4 } from "os";
1929
- import { dirname as dirname7, resolve as resolve12 } from "path";
1930
- var sharedNativeRuntimeOutputDir = resolve12(tmpdir4(), "rig-native");
1931
- var sharedNativeRuntimeOutputPath = resolve12(sharedNativeRuntimeOutputDir, `runtime-native-${process.platform}-${process.arch}.${suffix}`);
1988
+ import { dirname as dirname8, resolve as resolve13 } from "path";
1989
+ var sharedNativeRuntimeOutputDir = resolve13(tmpdir4(), "rig-native");
1990
+ var sharedNativeRuntimeOutputPath = resolve13(sharedNativeRuntimeOutputDir, `runtime-native-${process.platform}-${process.arch}.${suffix}`);
1932
1991
  var colocatedNativeRuntimeFileName = `runtime-native.${suffix}`;
1933
1992
  var nativeRuntimeLibrary = await loadNativeRuntimeLibrary();
1934
1993
  async function ensureNativeRuntimeLibraryPath(outputPath = sharedNativeRuntimeOutputPath, options = {}) {
1935
1994
  if (await buildNativeRuntimeLibrary(outputPath, options)) {
1936
1995
  return outputPath;
1937
1996
  }
1938
- return !options.force && existsSync10(outputPath) ? outputPath : null;
1997
+ return !options.force && existsSync12(outputPath) ? outputPath : null;
1939
1998
  }
1940
1999
  async function loadNativeRuntimeLibrary() {
1941
2000
  if (process.env.RIG_DISABLE_ZIG_NATIVE === "1") {
1942
2001
  return null;
1943
2002
  }
1944
2003
  for (const candidate of nativeRuntimeLibraryCandidates()) {
1945
- if (!candidate || !existsSync10(candidate)) {
2004
+ if (!candidate || !existsSync12(candidate)) {
1946
2005
  continue;
1947
2006
  }
1948
2007
  const loaded = tryDlopenNativeRuntimeLibrary(candidate);
@@ -1958,12 +2017,12 @@ async function loadNativeRuntimeLibrary() {
1958
2017
  }
1959
2018
  function nativePackageLibraryCandidates(fromDir, names) {
1960
2019
  const candidates = [];
1961
- let cursor = resolve12(fromDir);
2020
+ let cursor = resolve13(fromDir);
1962
2021
  for (let index = 0;index < 8; index += 1) {
1963
2022
  for (const name of names) {
1964
- 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));
2023
+ 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));
1965
2024
  }
1966
- const parent = dirname7(cursor);
2025
+ const parent = dirname8(cursor);
1967
2026
  if (parent === cursor)
1968
2027
  break;
1969
2028
  cursor = parent;
@@ -1972,27 +2031,27 @@ function nativePackageLibraryCandidates(fromDir, names) {
1972
2031
  }
1973
2032
  function nativeRuntimeLibraryCandidates() {
1974
2033
  const explicit = process.env.RIG_NATIVE_RUNTIME_LIB?.trim() || "";
1975
- const execDir = process.execPath?.trim() ? dirname7(process.execPath.trim()) : "";
2034
+ const execDir = process.execPath?.trim() ? dirname8(process.execPath.trim()) : "";
1976
2035
  const platformSpecific = `runtime-native-${process.platform}-${process.arch}.${suffix}`;
1977
2036
  return [...new Set([
1978
2037
  explicit,
1979
2038
  ...nativePackageLibraryCandidates(import.meta.dir, [colocatedNativeRuntimeFileName, platformSpecific]),
1980
- execDir ? resolve12(execDir, colocatedNativeRuntimeFileName) : "",
1981
- execDir ? resolve12(execDir, platformSpecific) : "",
1982
- execDir ? resolve12(execDir, "..", colocatedNativeRuntimeFileName) : "",
1983
- execDir ? resolve12(execDir, "..", platformSpecific) : "",
1984
- execDir ? resolve12(execDir, "lib", colocatedNativeRuntimeFileName) : "",
1985
- execDir ? resolve12(execDir, "..", "lib", colocatedNativeRuntimeFileName) : "",
2039
+ execDir ? resolve13(execDir, colocatedNativeRuntimeFileName) : "",
2040
+ execDir ? resolve13(execDir, platformSpecific) : "",
2041
+ execDir ? resolve13(execDir, "..", colocatedNativeRuntimeFileName) : "",
2042
+ execDir ? resolve13(execDir, "..", platformSpecific) : "",
2043
+ execDir ? resolve13(execDir, "lib", colocatedNativeRuntimeFileName) : "",
2044
+ execDir ? resolve13(execDir, "..", "lib", colocatedNativeRuntimeFileName) : "",
1986
2045
  sharedNativeRuntimeOutputPath
1987
2046
  ].filter(Boolean))];
1988
2047
  }
1989
2048
  function resolveNativeRuntimeSourcePath() {
1990
2049
  const explicit = process.env.RIG_NATIVE_RUNTIME_SOURCE?.trim();
1991
- if (explicit && existsSync10(explicit)) {
2050
+ if (explicit && existsSync12(explicit)) {
1992
2051
  return explicit;
1993
2052
  }
1994
- const bundled = resolve12(import.meta.dir, "../../../native/snapshot.zig");
1995
- return existsSync10(bundled) ? bundled : null;
2053
+ const bundled = resolve13(import.meta.dir, "../../../native/snapshot.zig");
2054
+ return existsSync12(bundled) ? bundled : null;
1996
2055
  }
1997
2056
  async function buildNativeRuntimeLibrary(outputPath, options = {}) {
1998
2057
  if (process.env.RIG_DISABLE_ZIG_NATIVE === "1") {
@@ -2005,8 +2064,8 @@ async function buildNativeRuntimeLibrary(outputPath, options = {}) {
2005
2064
  }
2006
2065
  const tempOutputPath = `${outputPath}.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2)}.tmp`;
2007
2066
  try {
2008
- mkdirSync5(dirname7(outputPath), { recursive: true });
2009
- const needsBuild = options.force === true || !existsSync10(outputPath) || statSync2(sourcePath).mtimeMs > statSync2(outputPath).mtimeMs;
2067
+ mkdirSync6(dirname8(outputPath), { recursive: true });
2068
+ const needsBuild = options.force === true || !existsSync12(outputPath) || statSync2(sourcePath).mtimeMs > statSync2(outputPath).mtimeMs;
2010
2069
  if (!needsBuild) {
2011
2070
  return true;
2012
2071
  }
@@ -2024,7 +2083,7 @@ async function buildNativeRuntimeLibrary(outputPath, options = {}) {
2024
2083
  stderr: "pipe"
2025
2084
  });
2026
2085
  const exitCode = await build.exited;
2027
- if (exitCode !== 0 || !existsSync10(tempOutputPath)) {
2086
+ if (exitCode !== 0 || !existsSync12(tempOutputPath)) {
2028
2087
  rmSync3(tempOutputPath, { force: true });
2029
2088
  return false;
2030
2089
  }
@@ -2154,11 +2213,11 @@ async function runCaptureAsync(command, cwd, env, timeoutMs) {
2154
2213
  return { exitCode, stdout, stderr };
2155
2214
  }
2156
2215
  function readJsonFile(path, fallback) {
2157
- if (!existsSync11(path)) {
2216
+ if (!existsSync13(path)) {
2158
2217
  return fallback;
2159
2218
  }
2160
2219
  try {
2161
- return JSON.parse(readFileSync8(path, "utf-8"));
2220
+ return JSON.parse(readFileSync9(path, "utf-8"));
2162
2221
  } catch {
2163
2222
  return fallback;
2164
2223
  }
@@ -2172,31 +2231,31 @@ function unique(values) {
2172
2231
  function resolveHarnessPaths(projectRoot) {
2173
2232
  const hasRuntimeWorkspace = Boolean(process.env.RIG_TASK_WORKSPACE?.trim());
2174
2233
  const monorepoRoot = resolveMonorepoRoot2(projectRoot);
2175
- const harnessRoot = resolve13(projectRoot, "rig");
2176
- const stateRoot = resolve13(projectRoot, ".rig");
2234
+ const harnessRoot = resolve14(projectRoot, "rig");
2235
+ const stateRoot = resolve14(projectRoot, ".rig");
2177
2236
  const layout = hasRuntimeWorkspace ? resolveRigLayout(projectRoot) : null;
2178
- const stateDir = layout?.stateDir ?? resolve13(stateRoot, "state");
2179
- const logsDir = layout?.logsDir ?? resolve13(stateRoot, "logs");
2180
- const artifactsDir = layout?.artifactsRoot ?? resolve13(monorepoRoot, "artifacts");
2181
- const taskConfigPath = layout?.taskConfigPath ?? resolve13(monorepoRoot, ".rig", "task-config.json");
2182
- const binDir = layout?.binDir ?? resolve13(stateRoot, "bin");
2237
+ const stateDir = layout?.stateDir ?? resolve14(stateRoot, "state");
2238
+ const logsDir = layout?.logsDir ?? resolve14(stateRoot, "logs");
2239
+ const artifactsDir = layout?.artifactsRoot ?? resolve14(monorepoRoot, "artifacts");
2240
+ const taskConfigPath = layout?.taskConfigPath ?? resolve14(monorepoRoot, ".rig", "task-config.json");
2241
+ const binDir = layout?.binDir ?? resolve14(stateRoot, "bin");
2183
2242
  return {
2184
2243
  harnessRoot,
2185
2244
  stateDir: process.env.RIG_STATE_DIR || stateDir,
2186
2245
  artifactsDir,
2187
2246
  logsDir: process.env.RIG_LOGS_DIR || logsDir,
2188
2247
  binDir,
2189
- hooksDir: resolve13(harnessRoot, "hooks"),
2190
- validationDir: resolve13(harnessRoot, "validation"),
2248
+ hooksDir: resolve14(harnessRoot, "hooks"),
2249
+ validationDir: resolve14(harnessRoot, "validation"),
2191
2250
  taskConfigPath,
2192
- sessionPath: process.env.RIG_SESSION_FILE || resolve13(stateRoot, "session", "session.json"),
2251
+ sessionPath: process.env.RIG_SESSION_FILE || resolve14(stateRoot, "session", "session.json"),
2193
2252
  monorepoRoot,
2194
- tsApiTestsDir: process.env.TS_API_TESTS_DIR || resolve13(monorepoRoot, "TSAPITests"),
2195
- taskRepoCommitsPath: resolve13(stateDir, "task-repo-commits.json"),
2196
- baseRepoPinsPath: resolve13(stateDir, "base-repo-pins.json"),
2197
- failedApproachesPath: resolve13(stateDir, "failed_approaches.md"),
2198
- agentProfilePath: resolve13(stateDir, "agent-profile.json"),
2199
- reviewProfilePath: resolve13(stateDir, "review-profile.json")
2253
+ tsApiTestsDir: process.env.TS_API_TESTS_DIR || resolve14(monorepoRoot, "TSAPITests"),
2254
+ taskRepoCommitsPath: resolve14(stateDir, "task-repo-commits.json"),
2255
+ baseRepoPinsPath: resolve14(stateDir, "base-repo-pins.json"),
2256
+ failedApproachesPath: resolve14(stateDir, "failed_approaches.md"),
2257
+ agentProfilePath: resolve14(stateDir, "agent-profile.json"),
2258
+ reviewProfilePath: resolve14(stateDir, "review-profile.json")
2200
2259
  };
2201
2260
  }
2202
2261
  function normalizeRelativeScopePath(inputPath) {
@@ -2254,34 +2313,34 @@ function monorepoSearchCandidates(inputPath) {
2254
2313
  }
2255
2314
 
2256
2315
  // packages/runtime/src/control-plane/state-sync/repo.ts
2257
- import { existsSync as existsSync13 } from "fs";
2258
- import { resolve as resolve15 } from "path";
2316
+ import { existsSync as existsSync15 } from "fs";
2317
+ import { resolve as resolve16 } from "path";
2259
2318
 
2260
2319
  // packages/runtime/src/control-plane/repos/layout.ts
2261
- import { existsSync as existsSync12 } from "fs";
2262
- import { basename as basename5, dirname as dirname8, join as join3, resolve as resolve14 } from "path";
2320
+ import { existsSync as existsSync14 } from "fs";
2321
+ import { basename as basename5, dirname as dirname9, join as join3, resolve as resolve15 } from "path";
2263
2322
  function resolveRepoStateDir(projectRoot) {
2264
- const normalizedProjectRoot = resolve14(projectRoot);
2265
- const projectParent = dirname8(normalizedProjectRoot);
2323
+ const normalizedProjectRoot = resolve15(projectRoot);
2324
+ const projectParent = dirname9(normalizedProjectRoot);
2266
2325
  if (basename5(projectParent) === ".worktrees") {
2267
- const ownerRoot = dirname8(projectParent);
2268
- const ownerHasRepoMarkers = existsSync12(resolve14(ownerRoot, ".git")) || existsSync12(resolve14(ownerRoot, ".rig", "state"));
2326
+ const ownerRoot = dirname9(projectParent);
2327
+ const ownerHasRepoMarkers = existsSync14(resolve15(ownerRoot, ".git")) || existsSync14(resolve15(ownerRoot, ".rig", "state"));
2269
2328
  if (ownerHasRepoMarkers) {
2270
- return resolve14(ownerRoot, ".rig", "state");
2329
+ return resolve15(ownerRoot, ".rig", "state");
2271
2330
  }
2272
2331
  }
2273
- return resolve14(projectRoot, ".rig", "state");
2332
+ return resolve15(projectRoot, ".rig", "state");
2274
2333
  }
2275
2334
  function resolveManagedRepoLayout(projectRoot, repoId) {
2276
- const normalizedProjectRoot = resolve14(projectRoot);
2335
+ const normalizedProjectRoot = resolve15(projectRoot);
2277
2336
  const entry = getManagedRepoEntry(repoId);
2278
2337
  const stateDir = resolveRepoStateDir(normalizedProjectRoot);
2279
2338
  const metadataRelativePath = join3("repos", entry.id);
2280
- const metadataRoot = resolve14(stateDir, metadataRelativePath);
2339
+ const metadataRoot = resolve15(stateDir, metadataRelativePath);
2281
2340
  const runtimeWorkspace = process.env.RIG_TASK_WORKSPACE?.trim();
2282
- const runsInsideTaskWorktree = runtimeWorkspace && resolve14(runtimeWorkspace) === normalizedProjectRoot || basename5(dirname8(normalizedProjectRoot)) === ".worktrees";
2341
+ const runsInsideTaskWorktree = runtimeWorkspace && resolve15(runtimeWorkspace) === normalizedProjectRoot || basename5(dirname9(normalizedProjectRoot)) === ".worktrees";
2283
2342
  const isPrimaryManagedRepo = listManagedRepoEntries()[0]?.id === repoId;
2284
- const checkoutRoot = isPrimaryManagedRepo && runsInsideTaskWorktree ? resolveMonorepoRoot(normalizedProjectRoot) : entry.checkoutEnvVar && process.env[entry.checkoutEnvVar]?.trim() ? resolve14(process.env[entry.checkoutEnvVar].trim()) : resolve14(normalizedProjectRoot, entry.alias);
2343
+ const checkoutRoot = isPrimaryManagedRepo && runsInsideTaskWorktree ? resolveMonorepoRoot(normalizedProjectRoot) : entry.checkoutEnvVar && process.env[entry.checkoutEnvVar]?.trim() ? resolve15(process.env[entry.checkoutEnvVar].trim()) : resolve15(normalizedProjectRoot, entry.alias);
2285
2344
  return {
2286
2345
  projectRoot: normalizedProjectRoot,
2287
2346
  repoId: entry.id,
@@ -2289,12 +2348,12 @@ function resolveManagedRepoLayout(projectRoot, repoId) {
2289
2348
  defaultBranch: entry.defaultBranch,
2290
2349
  remoteUrl: entry.remoteEnvVar && process.env[entry.remoteEnvVar]?.trim() ? process.env[entry.remoteEnvVar].trim() : entry.defaultRemoteUrl,
2291
2350
  checkoutRoot,
2292
- worktreesRoot: resolve14(checkoutRoot, ".worktrees"),
2351
+ worktreesRoot: resolve15(checkoutRoot, ".worktrees"),
2293
2352
  stateDir,
2294
2353
  metadataRoot,
2295
2354
  metadataRelativePath,
2296
- mirrorRoot: resolve14(metadataRoot, "mirror.git"),
2297
- mirrorStatePath: resolve14(metadataRoot, "mirror-state.json"),
2355
+ mirrorRoot: resolve15(metadataRoot, "mirror.git"),
2356
+ mirrorStatePath: resolve15(metadataRoot, "mirror-state.json"),
2298
2357
  mirrorStateRelativePath: join3(metadataRelativePath, "mirror-state.json")
2299
2358
  };
2300
2359
  }
@@ -2316,7 +2375,7 @@ function resolveTrackerRepoPath(projectRoot) {
2316
2375
  const monorepoRoot = resolveMonorepoRoot2(projectRoot);
2317
2376
  try {
2318
2377
  const layout = resolveMonorepoRepoLayout(projectRoot);
2319
- if (existsSync13(resolve15(layout.mirrorRoot, "HEAD"))) {
2378
+ if (existsSync15(resolve16(layout.mirrorRoot, "HEAD"))) {
2320
2379
  return layout.mirrorRoot;
2321
2380
  }
2322
2381
  } catch {}
@@ -2327,8 +2386,8 @@ function resolveTrackerRepoPath(projectRoot) {
2327
2386
  var DEFAULT_READ_DEPS = {
2328
2387
  fetchRef: nativeFetchRef,
2329
2388
  readBlobAtRef: nativeReadBlobAtRef,
2330
- exists: existsSync14,
2331
- readFile: (path) => readFileSync9(path, "utf8")
2389
+ exists: existsSync16,
2390
+ readFile: (path) => readFileSync10(path, "utf8")
2332
2391
  };
2333
2392
  function parseIssueStatus(rawStatus) {
2334
2393
  const normalized = normalizeTaskLifecycleStatus(rawStatus);
@@ -2409,12 +2468,12 @@ function shouldPreferLocalTrackerState(options) {
2409
2468
  if (runtimeContextPath) {
2410
2469
  return true;
2411
2470
  }
2412
- return existsSync14(resolve16(runtimeWorkspace, ".rig", "runtime-context.json"));
2471
+ return existsSync16(resolve17(runtimeWorkspace, ".rig", "runtime-context.json"));
2413
2472
  }
2414
2473
  function readLocalTrackerState(projectRoot, deps) {
2415
2474
  const monorepoRoot = resolveMonorepoRoot2(projectRoot);
2416
- const issuesPath = resolve16(monorepoRoot, ".beads", "issues.jsonl");
2417
- const taskStatePath = resolve16(monorepoRoot, ".beads", "task-state.json");
2475
+ const issuesPath = resolve17(monorepoRoot, ".beads", "issues.jsonl");
2476
+ const taskStatePath = resolve17(monorepoRoot, ".beads", "task-state.json");
2418
2477
  return projectSyncedTrackerSnapshot({
2419
2478
  source: "local",
2420
2479
  issuesBaseOid: null,
@@ -2476,7 +2535,7 @@ function readValidationDescriptions(projectRoot) {
2476
2535
  return readValidationDescriptionMap(raw);
2477
2536
  }
2478
2537
  function readSourceValidationDescriptions(projectRoot) {
2479
- const rootRaw = readJsonFile(resolve17(projectRoot, "rig", "task-config.json"), {});
2538
+ const rootRaw = readJsonFile(resolve18(projectRoot, "rig", "task-config.json"), {});
2480
2539
  const sourcePath = findSourceTaskConfigPath(projectRoot);
2481
2540
  const sourceRaw = sourcePath ? readJsonFile(sourcePath, {}) : {};
2482
2541
  const rootDescriptions = readValidationDescriptionMap(rootRaw);
@@ -2552,15 +2611,15 @@ function readValidationDescriptionsFromMeta(meta) {
2552
2611
  return meta.validation_descriptions;
2553
2612
  }
2554
2613
  function readLocalSourceTaskStateEnvelope(projectRoot) {
2555
- const taskStatePath = resolve17(resolveMonorepoRoot2(projectRoot), ".beads", "task-state.json");
2614
+ const taskStatePath = resolve18(resolveMonorepoRoot2(projectRoot), ".beads", "task-state.json");
2556
2615
  return readTaskStateMetadataEnvelope(readJsonFile(taskStatePath, {}));
2557
2616
  }
2558
2617
  function readLocalSourceTaskLifecycleStatus(projectRoot, taskId) {
2559
- const issuesPath = resolve17(resolveMonorepoRoot2(projectRoot), ".beads", "issues.jsonl");
2560
- if (!existsSync15(issuesPath)) {
2618
+ const issuesPath = resolve18(resolveMonorepoRoot2(projectRoot), ".beads", "issues.jsonl");
2619
+ if (!existsSync17(issuesPath)) {
2561
2620
  return null;
2562
2621
  }
2563
- for (const line of readFileSync10(issuesPath, "utf8").split(/\r?\n/)) {
2622
+ for (const line of readFileSync11(issuesPath, "utf8").split(/\r?\n/)) {
2564
2623
  const trimmed = line.trim();
2565
2624
  if (!trimmed) {
2566
2625
  continue;
@@ -2601,25 +2660,25 @@ function lookupTask(projectRoot, input) {
2601
2660
  function artifactDirForId(projectRoot, id) {
2602
2661
  const workspaceDir = process.env.RIG_TASK_WORKSPACE?.trim();
2603
2662
  if (workspaceDir) {
2604
- const worktreeArtifacts = resolve17(workspaceDir, "artifacts", id);
2605
- if (existsSync15(worktreeArtifacts) || existsSync15(resolve17(workspaceDir, "artifacts"))) {
2663
+ const worktreeArtifacts = resolve18(workspaceDir, "artifacts", id);
2664
+ if (existsSync17(worktreeArtifacts) || existsSync17(resolve18(workspaceDir, "artifacts"))) {
2606
2665
  return worktreeArtifacts;
2607
2666
  }
2608
2667
  }
2609
2668
  try {
2610
2669
  const paths = resolveHarnessPaths(projectRoot);
2611
- return resolve17(paths.artifactsDir, id);
2670
+ return resolve18(paths.artifactsDir, id);
2612
2671
  } catch {
2613
- return resolve17(resolveMonorepoRoot2(projectRoot), "artifacts", id);
2672
+ return resolve18(resolveMonorepoRoot2(projectRoot), "artifacts", id);
2614
2673
  }
2615
2674
  }
2616
2675
  function resolveTaskConfigPath(projectRoot) {
2617
2676
  const paths = resolveHarnessPaths(projectRoot);
2618
- if (existsSync15(paths.taskConfigPath)) {
2677
+ if (existsSync17(paths.taskConfigPath)) {
2619
2678
  return paths.taskConfigPath;
2620
2679
  }
2621
2680
  for (const candidate of sourceTaskConfigCandidates(projectRoot)) {
2622
- if (existsSync15(candidate)) {
2681
+ if (existsSync17(candidate)) {
2623
2682
  return candidate;
2624
2683
  }
2625
2684
  }
@@ -2627,7 +2686,7 @@ function resolveTaskConfigPath(projectRoot) {
2627
2686
  }
2628
2687
  function findSourceTaskConfigPath(projectRoot) {
2629
2688
  for (const candidate of sourceTaskConfigCandidates(projectRoot)) {
2630
- if (existsSync15(candidate)) {
2689
+ if (existsSync17(candidate)) {
2631
2690
  return candidate;
2632
2691
  }
2633
2692
  }
@@ -2640,7 +2699,7 @@ function readAndSyncSourceTaskConfig(projectRoot) {
2640
2699
  const synced = synchronizeTaskConfigWithTracker(projectRoot, raw);
2641
2700
  if (sourcePath && synced.updated) {
2642
2701
  try {
2643
- writeFileSync6(sourcePath, `${JSON.stringify(synced.config, null, 2)}
2702
+ writeFileSync7(sourcePath, `${JSON.stringify(synced.config, null, 2)}
2644
2703
  `, "utf-8");
2645
2704
  } catch {}
2646
2705
  }
@@ -2692,12 +2751,12 @@ function shouldRefreshAutoSyncedTaskConfigEntry(entry) {
2692
2751
  return !candidate.role;
2693
2752
  }
2694
2753
  function readSourceIssueRecords(projectRoot) {
2695
- const issuesPath = resolve17(resolveMonorepoRoot2(projectRoot), ".beads", "issues.jsonl");
2696
- if (!existsSync15(issuesPath)) {
2754
+ const issuesPath = resolve18(resolveMonorepoRoot2(projectRoot), ".beads", "issues.jsonl");
2755
+ if (!existsSync17(issuesPath)) {
2697
2756
  return [];
2698
2757
  }
2699
2758
  const records = [];
2700
- for (const line of readFileSync10(issuesPath, "utf-8").split(/\r?\n/)) {
2759
+ for (const line of readFileSync11(issuesPath, "utf-8").split(/\r?\n/)) {
2701
2760
  const trimmed = line.trim();
2702
2761
  if (!trimmed) {
2703
2762
  continue;
@@ -2753,19 +2812,19 @@ function readConfiguredFileTaskConfig(projectRoot) {
2753
2812
  if (!sourcePath) {
2754
2813
  return {};
2755
2814
  }
2756
- const directory = resolve17(projectRoot, sourcePath);
2757
- if (!existsSync15(directory)) {
2815
+ const directory = resolve18(projectRoot, sourcePath);
2816
+ if (!existsSync17(directory)) {
2758
2817
  return {};
2759
2818
  }
2760
2819
  const config = {};
2761
2820
  for (const name of readdirSync3(directory)) {
2762
2821
  if (!FILE_TASK_PATTERN2.test(name))
2763
2822
  continue;
2764
- const file = resolve17(directory, name);
2823
+ const file = resolve18(directory, name);
2765
2824
  try {
2766
2825
  if (!statSync3(file).isFile())
2767
2826
  continue;
2768
- const raw = JSON.parse(readFileSync10(file, "utf8"));
2827
+ const raw = JSON.parse(readFileSync11(file, "utf8"));
2769
2828
  if (!raw || typeof raw !== "object" || Array.isArray(raw))
2770
2829
  continue;
2771
2830
  const record = raw;
@@ -2807,10 +2866,10 @@ function firstStringList2(...candidates) {
2807
2866
  return [];
2808
2867
  }
2809
2868
  function readConfiguredFilesTaskSourcePath2(projectRoot) {
2810
- const jsonPath = resolve17(projectRoot, "rig.config.json");
2811
- if (existsSync15(jsonPath)) {
2869
+ const jsonPath = resolve18(projectRoot, "rig.config.json");
2870
+ if (existsSync17(jsonPath)) {
2812
2871
  try {
2813
- const parsed = JSON.parse(readFileSync10(jsonPath, "utf8"));
2872
+ const parsed = JSON.parse(readFileSync11(jsonPath, "utf8"));
2814
2873
  if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
2815
2874
  const taskSource = parsed.taskSource;
2816
2875
  if (taskSource && typeof taskSource === "object" && !Array.isArray(taskSource)) {
@@ -2822,12 +2881,12 @@ function readConfiguredFilesTaskSourcePath2(projectRoot) {
2822
2881
  return null;
2823
2882
  }
2824
2883
  }
2825
- const tsPath = resolve17(projectRoot, "rig.config.ts");
2826
- if (!existsSync15(tsPath)) {
2884
+ const tsPath = resolve18(projectRoot, "rig.config.ts");
2885
+ if (!existsSync17(tsPath)) {
2827
2886
  return null;
2828
2887
  }
2829
2888
  try {
2830
- const source = readFileSync10(tsPath, "utf8");
2889
+ const source = readFileSync11(tsPath, "utf8");
2831
2890
  const taskSourceBlock = source.match(/taskSource\s*:\s*\{[\s\S]*?\}/m)?.[0] ?? "";
2832
2891
  const kind = taskSourceBlock.match(/kind\s*:\s*["']([^"']+)["']/)?.[1];
2833
2892
  if (kind !== "files") {
@@ -2841,23 +2900,23 @@ function readConfiguredFilesTaskSourcePath2(projectRoot) {
2841
2900
  function sourceTaskConfigCandidates(projectRoot) {
2842
2901
  const runtimeContext = loadRuntimeContextFromEnv();
2843
2902
  return [
2844
- runtimeContext?.monorepoMainRoot ? resolve17(runtimeContext.monorepoMainRoot, ".rig", "task-config.json") : "",
2845
- process.env.MONOREPO_MAIN_ROOT?.trim() ? resolve17(process.env.MONOREPO_MAIN_ROOT.trim(), ".rig", "task-config.json") : "",
2846
- resolve17(resolveMonorepoRoot2(projectRoot), ".rig", "task-config.json")
2903
+ runtimeContext?.monorepoMainRoot ? resolve18(runtimeContext.monorepoMainRoot, ".rig", "task-config.json") : "",
2904
+ process.env.MONOREPO_MAIN_ROOT?.trim() ? resolve18(process.env.MONOREPO_MAIN_ROOT.trim(), ".rig", "task-config.json") : "",
2905
+ resolve18(resolveMonorepoRoot2(projectRoot), ".rig", "task-config.json")
2847
2906
  ].filter(Boolean);
2848
2907
  }
2849
2908
 
2850
2909
  // packages/runtime/src/control-plane/native/validator.ts
2851
- import { existsSync as existsSync19, mkdirSync as mkdirSync8, writeFileSync as writeFileSync8 } from "fs";
2852
- import { resolve as resolve22 } from "path";
2910
+ import { existsSync as existsSync21, mkdirSync as mkdirSync9, writeFileSync as writeFileSync9 } from "fs";
2911
+ import { resolve as resolve23 } from "path";
2853
2912
 
2854
2913
  // packages/runtime/src/control-plane/native/validator-binaries.ts
2855
- import { existsSync as existsSync18, mkdirSync as mkdirSync7, rmSync as rmSync5, statSync as statSync4 } from "fs";
2856
- import { dirname as dirname10, resolve as resolve21 } from "path";
2914
+ import { existsSync as existsSync20, mkdirSync as mkdirSync8, rmSync as rmSync5, statSync as statSync4 } from "fs";
2915
+ import { dirname as dirname11, resolve as resolve22 } from "path";
2857
2916
 
2858
2917
  // packages/runtime/src/binary-run.ts
2859
- import { chmodSync as chmodSync2, cpSync, existsSync as existsSync16, mkdirSync as mkdirSync6, renameSync as renameSync3, rmSync as rmSync4, writeFileSync as writeFileSync7 } from "fs";
2860
- import { basename as basename7, dirname as dirname9, resolve as resolve18 } from "path";
2918
+ import { chmodSync as chmodSync2, cpSync, existsSync as existsSync18, mkdirSync as mkdirSync7, renameSync as renameSync3, rmSync as rmSync4, writeFileSync as writeFileSync8 } from "fs";
2919
+ import { basename as basename7, dirname as dirname10, resolve as resolve19 } from "path";
2861
2920
  import { fileURLToPath } from "url";
2862
2921
  import { drainMicrotasks, gcAndSweep } from "bun:jsc";
2863
2922
  var runtimeBinaryBuildQueue = Promise.resolve();
@@ -2883,9 +2942,9 @@ async function buildRuntimeBinary(options) {
2883
2942
  });
2884
2943
  }
2885
2944
  async function buildRuntimeBinaryInProcess(options, manifest) {
2886
- const tempBuildDir = resolve18(dirname9(options.outputPath), `.bun-build-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`);
2887
- const tempOutputPath = resolve18(tempBuildDir, basename7(options.outputPath));
2888
- mkdirSync6(tempBuildDir, { recursive: true });
2945
+ const tempBuildDir = resolve19(dirname10(options.outputPath), `.bun-build-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`);
2946
+ const tempOutputPath = resolve19(tempBuildDir, basename7(options.outputPath));
2947
+ mkdirSync7(tempBuildDir, { recursive: true });
2889
2948
  await withTemporaryEnv({
2890
2949
  ...options.env,
2891
2950
  ...options.define ? { RIG_BUILD_CONFIG_JSON: JSON.stringify(options.define) } : {}
@@ -2910,7 +2969,7 @@ async function buildRuntimeBinaryInProcess(options, manifest) {
2910
2969
  `);
2911
2970
  throw new Error(`Failed to build ${options.entrypoint}: ${details || "Bun.build() returned errors"}`);
2912
2971
  }
2913
- if (!existsSync16(tempOutputPath)) {
2972
+ if (!existsSync18(tempOutputPath)) {
2914
2973
  const emitted = buildResult.outputs.map((output) => output.path).join(", ") || "(none)";
2915
2974
  throw new Error(`Failed to build ${options.entrypoint}: Bun.build() did not emit ${tempOutputPath}. Emitted: ${emitted}`);
2916
2975
  }
@@ -2942,8 +3001,8 @@ function runtimeBinaryCacheManifestPath(outputPath) {
2942
3001
  function resolveRuntimeBinaryBuildOptions(options) {
2943
3002
  return {
2944
3003
  ...options,
2945
- entrypoint: resolve18(options.cwd, options.sourcePath),
2946
- outputPath: resolve18(options.outputPath)
3004
+ entrypoint: resolve19(options.cwd, options.sourcePath),
3005
+ outputPath: resolve19(options.outputPath)
2947
3006
  };
2948
3007
  }
2949
3008
  function shouldUseRuntimeBinaryBuildWorker() {
@@ -2957,7 +3016,7 @@ function shouldUseRuntimeBinaryBuildWorker() {
2957
3016
  }
2958
3017
  async function buildRuntimeBinaryViaWorker(options) {
2959
3018
  const workerSourcePath = resolveRuntimeBinaryBuildWorkerSourcePath(options);
2960
- if (!workerSourcePath || !existsSync16(workerSourcePath)) {
3019
+ if (!workerSourcePath || !existsSync18(workerSourcePath)) {
2961
3020
  await buildRuntimeBinaryInProcess(options, {
2962
3021
  manifestPath: runtimeBinaryCacheManifestPath(options.outputPath),
2963
3022
  buildKey: createRuntimeBinaryBuildKey({
@@ -2994,7 +3053,7 @@ async function buildRuntimeBinaryViaWorker(options) {
2994
3053
  }
2995
3054
  }
2996
3055
  function createRuntimeBinaryBuildWorkerPayloadPath(outputPath) {
2997
- return resolve18(dirname9(outputPath), `.bun-build-worker-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`);
3056
+ return resolve19(dirname10(outputPath), `.bun-build-worker-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`);
2998
3057
  }
2999
3058
  function resolveRuntimeBinaryBuildWorkerSourcePath(options) {
3000
3059
  const envRoots = [
@@ -3003,13 +3062,13 @@ function resolveRuntimeBinaryBuildWorkerSourcePath(options) {
3003
3062
  process.env.PROJECT_RIG_ROOT?.trim()
3004
3063
  ].filter(Boolean);
3005
3064
  for (const root of envRoots) {
3006
- const candidate = resolve18(root, "packages/runtime/src/binary-build-worker.ts");
3007
- if (existsSync16(candidate)) {
3065
+ const candidate = resolve19(root, "packages/runtime/src/binary-build-worker.ts");
3066
+ if (existsSync18(candidate)) {
3008
3067
  return candidate;
3009
3068
  }
3010
3069
  }
3011
- const localCandidate = resolve18(import.meta.dir, "binary-build-worker.ts");
3012
- return existsSync16(localCandidate) ? localCandidate : null;
3070
+ const localCandidate = resolve19(import.meta.dir, "binary-build-worker.ts");
3071
+ return existsSync18(localCandidate) ? localCandidate : null;
3013
3072
  }
3014
3073
  function resolveRuntimeBinaryBuildWorkerInvocation() {
3015
3074
  const bunPath = Bun.which("bun");
@@ -3045,7 +3104,7 @@ function createRuntimeBinaryBuildKey(input) {
3045
3104
  });
3046
3105
  }
3047
3106
  async function isRuntimeBinaryBuildFresh(input) {
3048
- if (!existsSync16(input.outputPath) || !existsSync16(input.manifestPath)) {
3107
+ if (!existsSync18(input.outputPath) || !existsSync18(input.manifestPath)) {
3049
3108
  return false;
3050
3109
  }
3051
3110
  let manifest = null;
@@ -3058,7 +3117,7 @@ async function isRuntimeBinaryBuildFresh(input) {
3058
3117
  return false;
3059
3118
  }
3060
3119
  for (const [filePath, expectedDigest] of Object.entries(manifest.inputs || {})) {
3061
- if (!existsSync16(filePath)) {
3120
+ if (!existsSync18(filePath)) {
3062
3121
  return false;
3063
3122
  }
3064
3123
  if (await sha256File(filePath) !== expectedDigest) {
@@ -3071,7 +3130,7 @@ async function writeRuntimeBinaryCacheManifest(input) {
3071
3130
  const inputs = {};
3072
3131
  for (const inputPath of Object.keys(input.metafile?.inputs || {}).sort()) {
3073
3132
  const normalized = normalizeBuildInputPath(input.cwd, inputPath);
3074
- if (!normalized || !existsSync16(normalized)) {
3133
+ if (!normalized || !existsSync18(normalized)) {
3075
3134
  continue;
3076
3135
  }
3077
3136
  inputs[normalized] = await sha256File(normalized);
@@ -3094,7 +3153,7 @@ function normalizeBuildInputPath(cwd, inputPath) {
3094
3153
  if (inputPath.startsWith("<")) {
3095
3154
  return null;
3096
3155
  }
3097
- return resolve18(cwd, inputPath);
3156
+ return resolve19(cwd, inputPath);
3098
3157
  }
3099
3158
  async function sha256File(path) {
3100
3159
  const hasher = new Bun.CryptoHasher("sha256");
@@ -3110,8 +3169,8 @@ function sortRecord(value) {
3110
3169
  async function runSerializedRuntimeBinaryBuild(action) {
3111
3170
  const previous = runtimeBinaryBuildQueue;
3112
3171
  let release;
3113
- runtimeBinaryBuildQueue = new Promise((resolve19) => {
3114
- release = resolve19;
3172
+ runtimeBinaryBuildQueue = new Promise((resolve20) => {
3173
+ release = resolve20;
3115
3174
  });
3116
3175
  await previous;
3117
3176
  try {
@@ -3156,11 +3215,11 @@ async function withTemporaryCwd(cwd, action) {
3156
3215
  }
3157
3216
 
3158
3217
  // packages/runtime/src/control-plane/runtime/provisioning-env.ts
3159
- import { delimiter, resolve as resolve20 } from "path";
3218
+ import { delimiter, resolve as resolve21 } from "path";
3160
3219
 
3161
3220
  // packages/runtime/src/control-plane/runtime/runtime-paths.ts
3162
- import { existsSync as existsSync17, readdirSync as readdirSync4, realpathSync } from "fs";
3163
- import { resolve as resolve19 } from "path";
3221
+ import { existsSync as existsSync19, readdirSync as readdirSync4, realpathSync } from "fs";
3222
+ import { resolve as resolve20 } from "path";
3164
3223
 
3165
3224
  // packages/runtime/src/control-plane/runtime/sandbox/utils.ts
3166
3225
  function uniq(values) {
@@ -3178,7 +3237,7 @@ function resolveBunBinaryPath() {
3178
3237
  }
3179
3238
  const home = process.env.HOME?.trim();
3180
3239
  const fallbackCandidates = [
3181
- home ? resolve19(home, ".bun/bin/bun") : "",
3240
+ home ? resolve20(home, ".bun/bin/bun") : "",
3182
3241
  "/opt/homebrew/bin/bun",
3183
3242
  "/usr/local/bin/bun",
3184
3243
  "/usr/bin/bun"
@@ -3206,8 +3265,8 @@ function resolveClaudeBinaryPath() {
3206
3265
  }
3207
3266
  const home = process.env.HOME?.trim();
3208
3267
  const fallbackCandidates = [
3209
- home ? resolve19(home, ".local/bin/claude") : "",
3210
- home ? resolve19(home, ".local/share/claude/local/claude") : "",
3268
+ home ? resolve20(home, ".local/bin/claude") : "",
3269
+ home ? resolve20(home, ".local/share/claude/local/claude") : "",
3211
3270
  "/opt/homebrew/bin/claude",
3212
3271
  "/usr/local/bin/claude",
3213
3272
  "/usr/bin/claude"
@@ -3221,51 +3280,51 @@ function resolveClaudeBinaryPath() {
3221
3280
  throw new Error("claude not found in PATH");
3222
3281
  }
3223
3282
  function resolveBunInstallDir(bunBinaryPath = resolveBunBinaryPath()) {
3224
- return resolve19(bunBinaryPath, "../..");
3283
+ return resolve20(bunBinaryPath, "../..");
3225
3284
  }
3226
3285
  function resolveClaudeInstallDir() {
3227
3286
  const realPath = resolveClaudeBinaryPath();
3228
- return resolve19(realPath, "..");
3287
+ return resolve20(realPath, "..");
3229
3288
  }
3230
3289
  function resolveNodeInstallDir() {
3231
3290
  const preferredNode = resolvePreferredNodeBinary();
3232
3291
  if (!preferredNode)
3233
3292
  return null;
3234
3293
  const explicitNode = process.env.RIG_NODE_BIN?.trim();
3235
- if (explicitNode && resolve19(explicitNode) === resolve19(preferredNode)) {
3236
- return preferredNode.endsWith("/bin/node") ? resolve19(preferredNode, "../..") : resolve19(preferredNode, "..");
3294
+ if (explicitNode && resolve20(explicitNode) === resolve20(preferredNode)) {
3295
+ return preferredNode.endsWith("/bin/node") ? resolve20(preferredNode, "../..") : resolve20(preferredNode, "..");
3237
3296
  }
3238
3297
  try {
3239
3298
  const realPath = realpathSync(preferredNode);
3240
3299
  if (realPath.endsWith("/bin/node")) {
3241
- return resolve19(realPath, "../..");
3300
+ return resolve20(realPath, "../..");
3242
3301
  }
3243
- return resolve19(realPath, "..");
3302
+ return resolve20(realPath, "..");
3244
3303
  } catch {
3245
- return resolve19(preferredNode, "..");
3304
+ return resolve20(preferredNode, "..");
3246
3305
  }
3247
3306
  }
3248
3307
  function resolvePreferredNodeBinary() {
3249
3308
  const candidates = [];
3250
3309
  const envNode = process.env.RIG_NODE_BIN?.trim();
3251
3310
  if (envNode) {
3252
- const explicit = resolve19(envNode);
3253
- if (existsSync17(explicit)) {
3311
+ const explicit = resolve20(envNode);
3312
+ if (existsSync19(explicit)) {
3254
3313
  return explicit;
3255
3314
  }
3256
3315
  }
3257
3316
  const nvmBin = process.env.NVM_BIN?.trim();
3258
3317
  if (nvmBin) {
3259
- candidates.push(resolve19(nvmBin, "node"));
3318
+ candidates.push(resolve20(nvmBin, "node"));
3260
3319
  }
3261
3320
  const home = process.env.HOME?.trim();
3262
3321
  if (home) {
3263
- const nvmVersionsDir = resolve19(home, ".nvm/versions/node");
3264
- if (existsSync17(nvmVersionsDir)) {
3322
+ const nvmVersionsDir = resolve20(home, ".nvm/versions/node");
3323
+ if (existsSync19(nvmVersionsDir)) {
3265
3324
  try {
3266
3325
  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/, "")));
3267
3326
  for (const versionDir of versionDirs) {
3268
- candidates.push(resolve19(nvmVersionsDir, versionDir, "bin/node"));
3327
+ candidates.push(resolve20(nvmVersionsDir, versionDir, "bin/node"));
3269
3328
  }
3270
3329
  } catch {}
3271
3330
  }
@@ -3274,8 +3333,8 @@ function resolvePreferredNodeBinary() {
3274
3333
  if (whichNode) {
3275
3334
  candidates.push(whichNode);
3276
3335
  }
3277
- const deduped = uniq(candidates.map((candidate) => resolve19(candidate)));
3278
- const existing = deduped.filter((candidate) => existsSync17(candidate));
3336
+ const deduped = uniq(candidates.map((candidate) => resolve20(candidate)));
3337
+ const existing = deduped.filter((candidate) => existsSync19(candidate));
3279
3338
  if (existing.length === 0) {
3280
3339
  return null;
3281
3340
  }
@@ -3289,7 +3348,7 @@ function resolvePreferredNodeBinary() {
3289
3348
  return existing[0] ?? null;
3290
3349
  }
3291
3350
  function inferNodeMajor(nodeBinaryPath) {
3292
- const normalized = resolve19(nodeBinaryPath).replace(/\\/g, "/");
3351
+ const normalized = resolve20(nodeBinaryPath).replace(/\\/g, "/");
3293
3352
  const match = normalized.match(/(?:^|\/)(?:node-)?v?(\d+)\.\d+\.\d+(?:\/|$)/);
3294
3353
  if (!match) {
3295
3354
  return null;
@@ -3301,8 +3360,8 @@ function normalizeExecutablePath(candidate) {
3301
3360
  if (!candidate) {
3302
3361
  return "";
3303
3362
  }
3304
- const normalized = resolve19(candidate);
3305
- if (!existsSync17(normalized)) {
3363
+ const normalized = resolve20(candidate);
3364
+ if (!existsSync19(normalized)) {
3306
3365
  return "";
3307
3366
  }
3308
3367
  try {
@@ -3312,7 +3371,7 @@ function normalizeExecutablePath(candidate) {
3312
3371
  }
3313
3372
  }
3314
3373
  function looksLikeRuntimeGateway(candidate) {
3315
- const normalized = resolve19(candidate).replace(/\\/g, "/");
3374
+ const normalized = resolve20(candidate).replace(/\\/g, "/");
3316
3375
  return normalized.includes("/.rig/bin/") || normalized.endsWith("/rig-shell") || normalized.endsWith("/rig-agent");
3317
3376
  }
3318
3377
 
@@ -3333,7 +3392,7 @@ function runtimeProvisioningEnv(baseEnv = process.env) {
3333
3392
  try {
3334
3393
  return resolveClaudeInstallDir();
3335
3394
  } catch {
3336
- return resolve20(claudeBinary, "..");
3395
+ return resolve21(claudeBinary, "..");
3337
3396
  }
3338
3397
  })() : "";
3339
3398
  const nodeDir = resolveNodeInstallDir();
@@ -3343,8 +3402,8 @@ function runtimeProvisioningEnv(baseEnv = process.env) {
3343
3402
  `${bunDir}/bin`,
3344
3403
  claudeDir,
3345
3404
  nodeDir ? `${nodeDir}/bin` : "",
3346
- realHome ? resolve20(realHome, ".local/bin") : "",
3347
- realHome ? resolve20(realHome, ".cargo/bin") : "",
3405
+ realHome ? resolve21(realHome, ".local/bin") : "",
3406
+ realHome ? resolve21(realHome, ".cargo/bin") : "",
3348
3407
  ...inheritedPath,
3349
3408
  "/usr/local/bin",
3350
3409
  "/usr/local/sbin",
@@ -3375,9 +3434,9 @@ function runtimeProvisioningEnv(baseEnv = process.env) {
3375
3434
  // packages/runtime/src/control-plane/native/validator-binaries.ts
3376
3435
  function resolveValidatorBinaryPath(projectRoot, binaryName, runtimeContext) {
3377
3436
  if (runtimeContext) {
3378
- return resolve21(runtimeContext.binDir, "validators", binaryName);
3437
+ return resolve22(runtimeContext.binDir, "validators", binaryName);
3379
3438
  }
3380
- return resolve21(resolveHarnessPaths(projectRoot).binDir, "validators", binaryName);
3439
+ return resolve22(resolveHarnessPaths(projectRoot).binDir, "validators", binaryName);
3381
3440
  }
3382
3441
  async function ensureValidatorBinary(projectRoot, checkId, runtimeContext) {
3383
3442
  const match = checkId.match(/^([a-z][\w-]*):([a-z][\w-]*)$/);
@@ -3392,19 +3451,19 @@ async function ensureValidatorBinary(projectRoot, checkId, runtimeContext) {
3392
3451
  const binaryName = `${category}-${check}`;
3393
3452
  const binaryPath = resolveValidatorBinaryPath(projectRoot, binaryName, runtimeContext);
3394
3453
  const hostProjectRoot = runtimeContext?.hostProjectRoot?.trim() || projectRoot;
3395
- const sourcePath = resolve21(hostProjectRoot, "packages/runtime/src/control-plane/validators", category, `${check}.ts`);
3396
- if (!existsSync18(sourcePath)) {
3454
+ const sourcePath = resolve22(hostProjectRoot, "packages/runtime/src/control-plane/validators", category, `${check}.ts`);
3455
+ if (!existsSync20(sourcePath)) {
3397
3456
  return null;
3398
3457
  }
3399
3458
  const sourceMtime = statSync4(sourcePath).mtimeMs;
3400
- const binaryExists = existsSync18(binaryPath);
3459
+ const binaryExists = existsSync20(binaryPath);
3401
3460
  const binaryMtime = binaryExists ? statSync4(binaryPath).mtimeMs : 0;
3402
3461
  if (!binaryExists || sourceMtime > binaryMtime) {
3403
3462
  if (binaryExists) {
3404
3463
  rmSync5(binaryPath, { force: true });
3405
3464
  rmSync5(`${binaryPath}.build-manifest.json`, { force: true });
3406
3465
  }
3407
- mkdirSync7(dirname10(binaryPath), { recursive: true });
3466
+ mkdirSync8(dirname11(binaryPath), { recursive: true });
3408
3467
  await buildRuntimeBinary({
3409
3468
  sourcePath: `packages/runtime/src/control-plane/validators/${category}/${check}.ts`,
3410
3469
  outputPath: binaryPath,
@@ -3413,7 +3472,7 @@ async function ensureValidatorBinary(projectRoot, checkId, runtimeContext) {
3413
3472
  env: runtimeProvisioningEnv()
3414
3473
  });
3415
3474
  }
3416
- return existsSync18(binaryPath) ? binaryPath : null;
3475
+ return existsSync20(binaryPath) ? binaryPath : null;
3417
3476
  }
3418
3477
 
3419
3478
  // packages/runtime/src/control-plane/native/validator.ts
@@ -3450,20 +3509,20 @@ async function readTaskSourceValidation(projectRoot, taskId) {
3450
3509
  function resolveValidationPaths(projectRoot, taskId, runtimeContext) {
3451
3510
  if (runtimeContext) {
3452
3511
  return {
3453
- taskLogDir: resolve22(runtimeContext.logsDir, taskId),
3454
- artifactDir: resolve22(runtimeContext.workspaceDir, "artifacts", taskId)
3512
+ taskLogDir: resolve23(runtimeContext.logsDir, taskId),
3513
+ artifactDir: resolve23(runtimeContext.workspaceDir, "artifacts", taskId)
3455
3514
  };
3456
3515
  }
3457
3516
  const paths = resolveHarnessPaths(projectRoot);
3458
3517
  return {
3459
- taskLogDir: resolve22(paths.logsDir, taskId),
3460
- artifactDir: resolve22(paths.artifactsDir, taskId)
3518
+ taskLogDir: resolve23(paths.logsDir, taskId),
3519
+ artifactDir: resolve23(paths.artifactsDir, taskId)
3461
3520
  };
3462
3521
  }
3463
3522
  async function runValidatorBinary(projectRoot, taskId, checkId, runtimeContext) {
3464
3523
  const binaryName = checkId.replace(":", "-");
3465
3524
  const binaryPath = await ensureValidatorBinary(projectRoot, checkId, runtimeContext) ?? resolveValidatorBinaryPath(projectRoot, binaryName, runtimeContext);
3466
- if (!existsSync19(binaryPath)) {
3525
+ if (!existsSync21(binaryPath)) {
3467
3526
  return {
3468
3527
  result: {
3469
3528
  id: checkId,
@@ -3474,7 +3533,7 @@ async function runValidatorBinary(projectRoot, taskId, checkId, runtimeContext)
3474
3533
  };
3475
3534
  }
3476
3535
  const validatorCwd = runtimeContext?.workspaceDir || resolveMonorepoRoot(projectRoot);
3477
- const runtimeShellPath = runtimeContext ? resolve22(runtimeContext.binDir, "rig-shell") : "";
3536
+ const runtimeShellPath = runtimeContext ? resolve23(runtimeContext.binDir, "rig-shell") : "";
3478
3537
  const monorepoMainRoot = runtimeContext?.monorepoMainRoot || process.env.MONOREPO_MAIN_ROOT?.trim() || resolveMonorepoRoot(projectRoot);
3479
3538
  const validatorEnv = {
3480
3539
  PROJECT_RIG_ROOT: runtimeContext?.hostProjectRoot || projectRoot,
@@ -3489,7 +3548,7 @@ async function runValidatorBinary(projectRoot, taskId, checkId, runtimeContext)
3489
3548
  validatorEnv.RIG_LOGS_DIR = runtimeContext.logsDir;
3490
3549
  validatorEnv.RIG_RUNTIME_BIN_DIR = runtimeContext.binDir;
3491
3550
  }
3492
- const { exitCode, stdout, stderr } = await runCaptureAsync(runtimeShellPath && existsSync19(runtimeShellPath) ? [runtimeShellPath, "run-binary", binaryPath] : [binaryPath], validatorCwd, validatorEnv);
3551
+ const { exitCode, stdout, stderr } = await runCaptureAsync(runtimeShellPath && existsSync21(runtimeShellPath) ? [runtimeShellPath, "run-binary", binaryPath] : [binaryPath], validatorCwd, validatorEnv);
3493
3552
  try {
3494
3553
  const result = JSON.parse(stdout.trim());
3495
3554
  return { result, exitCode };
@@ -3529,8 +3588,8 @@ async function validateTask(projectRoot, taskId, runtimeContext, registry, optio
3529
3588
  const configuredValidation = stringArray(taskConfig[taskId]?.validation);
3530
3589
  const commands = resolvedContext?.validation?.length ? resolvedContext.validation : configuredValidation.length > 0 ? configuredValidation : sourceValidation.validation;
3531
3590
  const { taskLogDir, artifactDir } = resolveValidationPaths(projectRoot, taskId, resolvedContext);
3532
- mkdirSync8(taskLogDir, { recursive: true });
3533
- mkdirSync8(artifactDir, { recursive: true });
3591
+ mkdirSync9(taskLogDir, { recursive: true });
3592
+ mkdirSync9(artifactDir, { recursive: true });
3534
3593
  if (commands.length === 0) {
3535
3594
  const skipped = {
3536
3595
  status: "skipped",
@@ -3539,7 +3598,7 @@ async function validateTask(projectRoot, taskId, runtimeContext, registry, optio
3539
3598
  failed: 0,
3540
3599
  categories: []
3541
3600
  };
3542
- writeFileSync8(resolve22(artifactDir, "validation-summary.json"), `${JSON.stringify(skipped, null, 2)}
3601
+ writeFileSync9(resolve23(artifactDir, "validation-summary.json"), `${JSON.stringify(skipped, null, 2)}
3543
3602
  `, "utf-8");
3544
3603
  return skipped;
3545
3604
  }
@@ -3574,18 +3633,18 @@ async function validateTask(projectRoot, taskId, runtimeContext, registry, optio
3574
3633
  exit_code: 2,
3575
3634
  duration_seconds: 0
3576
3635
  });
3577
- const logFile2 = resolve22(taskLogDir, `invalid-entry-validation.log`);
3578
- mkdirSync8(taskLogDir, { recursive: true });
3579
- writeFileSync8(logFile2, `=== ${nowIso()} :: ${cmd} ===
3636
+ const logFile2 = resolve23(taskLogDir, `invalid-entry-validation.log`);
3637
+ mkdirSync9(taskLogDir, { recursive: true });
3638
+ writeFileSync9(logFile2, `=== ${nowIso()} :: ${cmd} ===
3580
3639
  Invalid validation entry: not a check-ID. All entries must use format "category:check-name".
3581
3640
  `, "utf-8");
3582
3641
  continue;
3583
3642
  }
3584
3643
  const { result, exitCode } = await dispatchValidator(cmd, effectiveRegistry, validatorCtx, (id) => runValidatorBinary(projectRoot, taskId, id, resolvedContext));
3585
3644
  const durationSeconds = Math.max(0, Math.round((Date.now() - startedAt) / 1000));
3586
- const logFile = resolve22(taskLogDir, `${cmd.replace(":", "-")}-validation.log`);
3587
- mkdirSync8(taskLogDir, { recursive: true });
3588
- writeFileSync8(logFile, `=== ${nowIso()} :: ${cmd} ===
3645
+ const logFile = resolve23(taskLogDir, `${cmd.replace(":", "-")}-validation.log`);
3646
+ mkdirSync9(taskLogDir, { recursive: true });
3647
+ writeFileSync9(logFile, `=== ${nowIso()} :: ${cmd} ===
3589
3648
  ${JSON.stringify(result, null, 2)}
3590
3649
  `, "utf-8");
3591
3650
  if (result.passed) {
@@ -3607,15 +3666,15 @@ ${JSON.stringify(result, null, 2)}
3607
3666
  failed,
3608
3667
  categories
3609
3668
  };
3610
- mkdirSync8(artifactDir, { recursive: true });
3611
- writeFileSync8(resolve22(artifactDir, "validation-summary.json"), `${JSON.stringify(summary, null, 2)}
3669
+ mkdirSync9(artifactDir, { recursive: true });
3670
+ writeFileSync9(resolve23(artifactDir, "validation-summary.json"), `${JSON.stringify(summary, null, 2)}
3612
3671
  `, "utf-8");
3613
3672
  return summary;
3614
3673
  }
3615
3674
 
3616
3675
  // packages/runtime/src/control-plane/native/verifier.ts
3617
- import { existsSync as existsSync20, mkdirSync as mkdirSync9, writeFileSync as writeFileSync9 } from "fs";
3618
- import { resolve as resolve23 } from "path";
3676
+ import { existsSync as existsSync22, mkdirSync as mkdirSync10, writeFileSync as writeFileSync10 } from "fs";
3677
+ import { resolve as resolve24 } from "path";
3619
3678
 
3620
3679
  // packages/runtime/src/control-plane/native/pr-review-gate.ts
3621
3680
  function parseJsonObject(value) {
@@ -4866,11 +4925,11 @@ async function verifyTask(options) {
4866
4925
  const taskId = options.taskId;
4867
4926
  const normalizedTaskId = lookupTask(options.projectRoot, taskId);
4868
4927
  const artifactDir = artifactDirForId(options.projectRoot, taskId);
4869
- mkdirSync9(artifactDir, { recursive: true });
4870
- const validationSummaryPath = resolve23(artifactDir, "validation-summary.json");
4871
- const reviewFeedbackPath = resolve23(artifactDir, "review-feedback.md");
4872
- const reviewStatePath = resolve23(artifactDir, "review-state.json");
4873
- const greptileRawPath = resolve23(artifactDir, "review-greptile-raw.json");
4928
+ mkdirSync10(artifactDir, { recursive: true });
4929
+ const validationSummaryPath = resolve24(artifactDir, "validation-summary.json");
4930
+ const reviewFeedbackPath = resolve24(artifactDir, "review-feedback.md");
4931
+ const reviewStatePath = resolve24(artifactDir, "review-state.json");
4932
+ const greptileRawPath = resolve24(artifactDir, "review-greptile-raw.json");
4874
4933
  const prStates = readPrMetadata(options.projectRoot, taskId);
4875
4934
  const prState = prStates[0] || null;
4876
4935
  const localReasons = [];
@@ -4882,7 +4941,7 @@ async function verifyTask(options) {
4882
4941
  if (!normalizedTaskId && !await hasConfiguredSourceTask(options.projectRoot, taskId)) {
4883
4942
  localReasons.push(`[Task Config] Unknown task id '${taskId}' in task-config or configured task source.`);
4884
4943
  }
4885
- if (!existsSync20(validationSummaryPath)) {
4944
+ if (!existsSync22(validationSummaryPath)) {
4886
4945
  localReasons.push(`[Artifact Quality] validation-summary.json not found at ${validationSummaryPath}.`);
4887
4946
  } else {
4888
4947
  const summary = await parseValidationSummary(validationSummaryPath);
@@ -4891,13 +4950,13 @@ async function verifyTask(options) {
4891
4950
  }
4892
4951
  }
4893
4952
  for (const file of ["task-result.json", "decision-log.md", "next-actions.md", "changed-files.txt"]) {
4894
- const requiredPath = resolve23(artifactDir, file);
4895
- if (!existsSync20(requiredPath)) {
4953
+ const requiredPath = resolve24(artifactDir, file);
4954
+ if (!existsSync22(requiredPath)) {
4896
4955
  localReasons.push(`[Artifact Quality] Missing required artifact file: ${requiredPath}`);
4897
4956
  }
4898
4957
  }
4899
- const taskResultPath = resolve23(artifactDir, "task-result.json");
4900
- if (existsSync20(taskResultPath)) {
4958
+ const taskResultPath = resolve24(artifactDir, "task-result.json");
4959
+ if (existsSync22(taskResultPath)) {
4901
4960
  const taskResult = await readJsonFile2(taskResultPath);
4902
4961
  const artifactStatus = typeof taskResult?.status === "string" ? taskResult.status.trim().toLowerCase() : "";
4903
4962
  if (artifactStatus === "partial") {
@@ -4910,8 +4969,8 @@ async function verifyTask(options) {
4910
4969
  localReasons.push("[Artifact Quality] task-result.json next actions indicate remaining implementation scope.");
4911
4970
  }
4912
4971
  }
4913
- const nextActionsPath = resolve23(artifactDir, "next-actions.md");
4914
- if (existsSync20(nextActionsPath)) {
4972
+ const nextActionsPath = resolve24(artifactDir, "next-actions.md");
4973
+ if (existsSync22(nextActionsPath)) {
4915
4974
  const nextActionsContent = await Bun.file(nextActionsPath).text();
4916
4975
  if (nextActionsContent.includes("TODO: Replace this scaffold") || nextActionsContent.includes("bd-<downstream-task-id>")) {
4917
4976
  localReasons.push("[Artifact Quality] next-actions.md still contains scaffold placeholder text. Replace with real recommendations.");
@@ -4942,7 +5001,7 @@ async function verifyTask(options) {
4942
5001
  aiReasons.push(`[AI Review] Required mode needs a completed Greptile approval; current verdict is ${ai.verdict}.`);
4943
5002
  }
4944
5003
  if (persistArtifacts && ai.rawResponse) {
4945
- writeFileSync9(greptileRawPath, `${ai.rawResponse}
5004
+ writeFileSync10(greptileRawPath, `${ai.rawResponse}
4946
5005
  `, "utf-8");
4947
5006
  }
4948
5007
  } else if (!options.skipAiReview && reviewMode === "off") {
@@ -5185,7 +5244,7 @@ function evaluateSourceCloseoutChecks(prState, prLabel) {
5185
5244
  if (!Array.isArray(checks) || checks.length === 0) {
5186
5245
  return [`[Source Issue] PR ${prLabel} must have green check evidence before completion.`];
5187
5246
  }
5188
- const ciGate = evaluatePullRequestCiChecks(checks, "PR", 0);
5247
+ const ciGate = evaluatePullRequestCiChecks(checks, "PR", 0, { mergeStateStatus: prState.mergeStateStatus });
5189
5248
  if (ciGate.verdict === "APPROVE") {
5190
5249
  return [];
5191
5250
  }
@@ -5281,7 +5340,7 @@ function isAcceptedValidationSummary(summary) {
5281
5340
  return summary.status === "skipped" && summary.total === 0 && summary.failed === 0;
5282
5341
  }
5283
5342
  async function loadReviewMode(reviewProfilePath, fallback) {
5284
- const parsed = existsSync20(reviewProfilePath) ? await readJsonFile2(reviewProfilePath) : null;
5343
+ const parsed = existsSync22(reviewProfilePath) ? await readJsonFile2(reviewProfilePath) : null;
5285
5344
  const mode = parsed?.mode;
5286
5345
  if (mode === "off" || mode === "advisory" || mode === "required") {
5287
5346
  return mode;
@@ -5292,7 +5351,7 @@ async function loadReviewMode(reviewProfilePath, fallback) {
5292
5351
  return "advisory";
5293
5352
  }
5294
5353
  async function loadReviewProvider(reviewProfilePath, fallback) {
5295
- const parsed = existsSync20(reviewProfilePath) ? await readJsonFile2(reviewProfilePath) : null;
5354
+ const parsed = existsSync22(reviewProfilePath) ? await readJsonFile2(reviewProfilePath) : null;
5296
5355
  const provider = parsed?.provider;
5297
5356
  if (typeof provider === "string" && provider.trim().length > 0) {
5298
5357
  return provider;
@@ -5451,7 +5510,7 @@ function writeFeedbackFile(options) {
5451
5510
  if (options.aiRawFeedback) {
5452
5511
  lines.push("## Raw Reviewer Feedback", "", "```text", options.aiRawFeedback, "```", "");
5453
5512
  }
5454
- writeFileSync9(options.output, `${lines.join(`
5513
+ writeFileSync10(options.output, `${lines.join(`
5455
5514
  `)}
5456
5515
  `, "utf-8");
5457
5516
  }
@@ -5468,7 +5527,7 @@ function writeReviewStateFile(options) {
5468
5527
  ai_warnings: options.aiWarnings,
5469
5528
  updated_at: nowIso()
5470
5529
  };
5471
- writeFileSync9(options.output, `${JSON.stringify(payload, null, 2)}
5530
+ writeFileSync10(options.output, `${JSON.stringify(payload, null, 2)}
5472
5531
  `, "utf-8");
5473
5532
  }
5474
5533
  async function runGreptileReviewForPr(options) {
@@ -5549,7 +5608,7 @@ async function runGreptileReviewForPr(options) {
5549
5608
  }
5550
5609
  await Bun.sleep(options.pollIntervalMs);
5551
5610
  }
5552
- const ciGate = evaluatePullRequestCiChecks(githubCheckRollup, repoName, prNumber);
5611
+ const ciGate = evaluatePullRequestCiChecks(githubCheckRollup, repoName, prNumber, { mergeStateStatus: options.prState.mergeStateStatus });
5553
5612
  if (ciGate.verdict !== "APPROVE") {
5554
5613
  return {
5555
5614
  verdict: ciGate.verdict,
@@ -5807,7 +5866,7 @@ async function runGithubGreptileFallbackReviewForPr(options) {
5807
5866
  }
5808
5867
  await Bun.sleep(options.pollIntervalMs);
5809
5868
  }
5810
- const ciGate = evaluatePullRequestCiChecks(checkRollup, repoName, prNumber);
5869
+ const ciGate = evaluatePullRequestCiChecks(checkRollup, repoName, prNumber, { mergeStateStatus: options.prState.mergeStateStatus });
5811
5870
  if (ciGate.verdict !== "APPROVE") {
5812
5871
  return {
5813
5872
  verdict: ciGate.verdict,
@@ -6162,19 +6221,31 @@ function loadGithubPullRequestCheckRollup(projectRoot, repoName, prNumber) {
6162
6221
  ]);
6163
6222
  return response.statusCheckRollup || [];
6164
6223
  }
6165
- function evaluatePullRequestCiChecks(checks, repoName, prNumber) {
6166
- const nonGreptileChecks = checks.filter((check) => {
6167
- const label = (check.name || check.context || "").toLowerCase();
6168
- return label.length > 0 && !label.includes("greptile");
6169
- });
6170
- const pending = nonGreptileChecks.filter((check) => {
6224
+ function evaluatePullRequestCiChecks(checks, repoName, prNumber, options = {}) {
6225
+ const isPendingCheck2 = (check) => {
6171
6226
  if ((check.__typename || "") === "CheckRun") {
6172
6227
  return (check.status || "").toUpperCase() !== "COMPLETED";
6173
6228
  }
6174
6229
  const state = (check.state || check.status || "").toUpperCase();
6175
6230
  return state === "PENDING" || state === "EXPECTED" || state === "QUEUED" || state === "IN_PROGRESS";
6231
+ };
6232
+ const pendingGreptile = checks.filter((check) => {
6233
+ const label = (check.name || check.context || "").toLowerCase();
6234
+ return label.includes("greptile") && isPendingCheck2(check);
6176
6235
  });
6177
- if (pending.length > 0) {
6236
+ if (pendingGreptile.length > 0) {
6237
+ return {
6238
+ verdict: "SKIP",
6239
+ reasons: pendingGreptile.map((check) => `[CI] ${repoName}#${prNumber} mandatory Greptile check is still pending: ${check.name || check.context || "unknown"}.`)
6240
+ };
6241
+ }
6242
+ const nonGreptileChecks = checks.filter((check) => {
6243
+ const label = (check.name || check.context || "").toLowerCase();
6244
+ return label.length > 0 && !label.includes("greptile");
6245
+ });
6246
+ const pending = nonGreptileChecks.filter(isPendingCheck2);
6247
+ const mergeClean = (options.mergeStateStatus || "").toUpperCase() === "CLEAN";
6248
+ if (pending.length > 0 && !mergeClean) {
6178
6249
  return {
6179
6250
  verdict: "SKIP",
6180
6251
  reasons: pending.map((check) => `[CI] ${repoName}#${prNumber} check is still pending: ${check.name || check.context || "unknown"}.`)
@@ -6255,7 +6326,7 @@ function filterActionableGithubGreptileThreads(threads) {
6255
6326
  }
6256
6327
  function resolvePrRepoRoot(projectRoot, prState) {
6257
6328
  const runtimeWorkspace = process.env.RIG_TASK_WORKSPACE?.trim();
6258
- if (prState.target === "monorepo" && runtimeWorkspace && existsSync20(resolve23(runtimeWorkspace, ".git"))) {
6329
+ if (prState.target === "monorepo" && runtimeWorkspace && existsSync22(resolve24(runtimeWorkspace, ".git"))) {
6259
6330
  return runtimeWorkspace;
6260
6331
  }
6261
6332
  const paths = resolveHarnessPaths(projectRoot);
@@ -6627,16 +6698,16 @@ async function taskDeps(projectRoot, taskId) {
6627
6698
  for (const dep of deps) {
6628
6699
  const artifactDir = artifactDirForId(projectRoot, dep);
6629
6700
  console.log(`=== ${dep} ===`);
6630
- if (!existsSync21(artifactDir)) {
6701
+ if (!existsSync23(artifactDir)) {
6631
6702
  console.log(` (no artifacts yet)
6632
6703
  `);
6633
6704
  continue;
6634
6705
  }
6635
- printArtifactSection(resolve24(artifactDir, "decision-log.md"), "--- Decisions ---");
6636
- printArtifactSection(resolve24(artifactDir, "next-actions.md"), "--- Next Actions (for you) ---");
6637
- const changedFiles = resolve24(artifactDir, "changed-files.txt");
6638
- if (existsSync21(changedFiles)) {
6639
- const lines = readFileSync11(changedFiles, "utf-8").split(/\r?\n/).filter(Boolean);
6706
+ printArtifactSection(resolve25(artifactDir, "decision-log.md"), "--- Decisions ---");
6707
+ printArtifactSection(resolve25(artifactDir, "next-actions.md"), "--- Next Actions (for you) ---");
6708
+ const changedFiles = resolve25(artifactDir, "changed-files.txt");
6709
+ if (existsSync23(changedFiles)) {
6710
+ const lines = readFileSync12(changedFiles, "utf-8").split(/\r?\n/).filter(Boolean);
6640
6711
  console.log(`--- Changed Files (${lines.length}) ---`);
6641
6712
  for (const line of lines) {
6642
6713
  console.log(line);
@@ -6681,12 +6752,12 @@ function taskRecord(projectRoot, type, text, taskId) {
6681
6752
  throw new Error("No active task.");
6682
6753
  }
6683
6754
  const paths = resolveHarnessPaths(projectRoot);
6684
- mkdirSync10(paths.stateDir, { recursive: true });
6755
+ mkdirSync11(paths.stateDir, { recursive: true });
6685
6756
  if (type === "decision") {
6686
- const artifactDir = resolve24(paths.artifactsDir, activeTask);
6687
- mkdirSync10(artifactDir, { recursive: true });
6757
+ const artifactDir = resolve25(paths.artifactsDir, activeTask);
6758
+ mkdirSync11(artifactDir, { recursive: true });
6688
6759
  const timestamp = nowIso();
6689
- appendFileSync(resolve24(artifactDir, "decision-log.md"), `
6760
+ appendFileSync(resolve25(artifactDir, "decision-log.md"), `
6690
6761
  ### ${timestamp}
6691
6762
 
6692
6763
  ${text}
@@ -6696,14 +6767,14 @@ ${text}
6696
6767
  return;
6697
6768
  }
6698
6769
  const failedPath = paths.failedApproachesPath;
6699
- if (!existsSync21(failedPath)) {
6700
- writeFileSync10(failedPath, `# Failed Approaches Log
6770
+ if (!existsSync23(failedPath)) {
6771
+ writeFileSync11(failedPath, `# Failed Approaches Log
6701
6772
 
6702
6773
  This file records approaches that did not work.
6703
6774
 
6704
6775
  `, "utf-8");
6705
6776
  }
6706
- const content = readFileSync11(failedPath, "utf-8");
6777
+ const content = readFileSync12(failedPath, "utf-8");
6707
6778
  const attempts = (content.match(new RegExp(`^## ${escapeRegExp(activeTask)}\\b`, "gm")) || []).length + 1;
6708
6779
  appendFileSync(failedPath, `
6709
6780
  ## ${activeTask} - Attempt ${attempts} (${nowIso()})
@@ -6720,40 +6791,40 @@ function taskArtifacts(projectRoot, taskId) {
6720
6791
  throw new Error("No active task.");
6721
6792
  }
6722
6793
  const paths = resolveHarnessPaths(projectRoot);
6723
- const artifactDir = resolve24(paths.artifactsDir, activeTask);
6724
- mkdirSync10(artifactDir, { recursive: true });
6794
+ const artifactDir = resolve25(paths.artifactsDir, activeTask);
6795
+ mkdirSync11(artifactDir, { recursive: true });
6725
6796
  const changed = changedFilesForTask(projectRoot, activeTask, true);
6726
- writeFileSync10(resolve24(artifactDir, "changed-files.txt"), `${changed.join(`
6797
+ writeFileSync11(resolve25(artifactDir, "changed-files.txt"), `${changed.join(`
6727
6798
  `)}
6728
6799
  `, "utf-8");
6729
6800
  console.log(`changed-files.txt: ${changed.length} files`);
6730
- const taskResultPath = resolve24(artifactDir, "task-result.json");
6731
- if (!existsSync21(taskResultPath)) {
6801
+ const taskResultPath = resolve25(artifactDir, "task-result.json");
6802
+ if (!existsSync23(taskResultPath)) {
6732
6803
  const template = {
6733
6804
  task_id: activeTask,
6734
6805
  status: "completed",
6735
6806
  summary: "TODO: Write a one-line summary of what you did",
6736
6807
  completed_at: nowIso()
6737
6808
  };
6738
- writeFileSync10(taskResultPath, `${JSON.stringify(template, null, 2)}
6809
+ writeFileSync11(taskResultPath, `${JSON.stringify(template, null, 2)}
6739
6810
  `, "utf-8");
6740
6811
  console.log("task-result.json: created (update the summary!)");
6741
6812
  } else {
6742
6813
  console.log("task-result.json: already exists");
6743
6814
  }
6744
- const decisionLogPath = resolve24(artifactDir, "decision-log.md");
6745
- if (!existsSync21(decisionLogPath)) {
6815
+ const decisionLogPath = resolve25(artifactDir, "decision-log.md");
6816
+ if (!existsSync23(decisionLogPath)) {
6746
6817
  const content = `# Decision Log: ${activeTask}
6747
6818
 
6748
6819
  Record key decisions here using: rig-agent record decision "..."
6749
6820
  `;
6750
- writeFileSync10(decisionLogPath, content, "utf-8");
6821
+ writeFileSync11(decisionLogPath, content, "utf-8");
6751
6822
  console.log("decision-log.md: created (record your decisions!)");
6752
6823
  } else {
6753
6824
  console.log("decision-log.md: already exists");
6754
6825
  }
6755
- const nextActionsPath = resolve24(artifactDir, "next-actions.md");
6756
- if (!existsSync21(nextActionsPath)) {
6826
+ const nextActionsPath = resolve25(artifactDir, "next-actions.md");
6827
+ if (!existsSync23(nextActionsPath)) {
6757
6828
  const content = [
6758
6829
  `# Next Actions: ${activeTask}`,
6759
6830
  "",
@@ -6770,13 +6841,13 @@ Record key decisions here using: rig-agent record decision "..."
6770
6841
  ""
6771
6842
  ].join(`
6772
6843
  `);
6773
- writeFileSync10(nextActionsPath, content, "utf-8");
6844
+ writeFileSync11(nextActionsPath, content, "utf-8");
6774
6845
  console.log("next-actions.md: created (add recommendations for downstream tasks!)");
6775
6846
  } else {
6776
6847
  console.log("next-actions.md: already exists");
6777
6848
  }
6778
- const validationSummaryPath = resolve24(artifactDir, "validation-summary.json");
6779
- if (existsSync21(validationSummaryPath)) {
6849
+ const validationSummaryPath = resolve25(artifactDir, "validation-summary.json");
6850
+ if (existsSync23(validationSummaryPath)) {
6780
6851
  console.log("validation-summary.json: already exists");
6781
6852
  } else {
6782
6853
  console.log("validation-summary.json: not yet created (run: rig-agent validate)");
@@ -6867,7 +6938,7 @@ function collectTaskChangedFiles(projectRoot, taskId, includeCommitted) {
6867
6938
  [projectRoot, ""],
6868
6939
  [monorepoRepoRoot, ""]
6869
6940
  ]) {
6870
- if (!existsSync21(resolve24(repo, ".git"))) {
6941
+ if (!existsSync23(resolve25(repo, ".git"))) {
6871
6942
  continue;
6872
6943
  }
6873
6944
  if (includeCommitted && repo === monorepoRepoRoot) {
@@ -6892,12 +6963,22 @@ function filterTaskChangedFiles(projectRoot, taskId, files, scoped) {
6892
6963
  }
6893
6964
  function resolveTaskMonorepoRoot(projectRoot) {
6894
6965
  const runtimeWorkspace = loadRuntimeContextFromEnv()?.workspaceDir || process.env.RIG_TASK_WORKSPACE?.trim();
6895
- if (runtimeWorkspace && existsSync21(resolve24(runtimeWorkspace, ".git"))) {
6896
- return resolve24(runtimeWorkspace);
6966
+ if (runtimeWorkspace && existsSync23(resolve25(runtimeWorkspace, ".git"))) {
6967
+ return resolve25(runtimeWorkspace);
6897
6968
  }
6898
6969
  return resolveHarnessPaths(projectRoot).monorepoRoot;
6899
6970
  }
6900
6971
  function collectCommittedMonorepoFiles(projectRoot, repo) {
6972
+ const defaultRef = runCapture(["git", "-C", repo, "rev-parse", "--abbrev-ref", "origin/HEAD"], projectRoot);
6973
+ if (defaultRef.exitCode === 0 && defaultRef.stdout.trim()) {
6974
+ const mergeBase = runCapture(["git", "-C", repo, "merge-base", "HEAD", defaultRef.stdout.trim()], projectRoot);
6975
+ if (mergeBase.exitCode === 0 && mergeBase.stdout.trim()) {
6976
+ const result = runCapture(["git", "-C", repo, "diff", "--name-only", `${mergeBase.stdout.trim()}..HEAD`], projectRoot);
6977
+ if (result.exitCode === 0) {
6978
+ return result.stdout.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
6979
+ }
6980
+ }
6981
+ }
6901
6982
  const initialHeadCommit = resolveRuntimeInitialHeadCommit(projectRoot, repo);
6902
6983
  if (initialHeadCommit) {
6903
6984
  const result = runCapture(["git", "-C", repo, "diff", "--name-only", `${initialHeadCommit}..HEAD`], projectRoot);
@@ -6921,7 +7002,7 @@ function resolveRuntimeInitialHeadCommit(projectRoot, repo) {
6921
7002
  const runtimeContext = loadRuntimeContextFromEnv();
6922
7003
  if (runtimeContext?.initialHeadCommits?.monorepo?.trim()) {
6923
7004
  const monorepoRoot = resolveTaskMonorepoRoot(projectRoot);
6924
- if (resolve24(monorepoRoot) === resolve24(repo)) {
7005
+ if (resolve25(monorepoRoot) === resolve25(repo)) {
6925
7006
  return runtimeContext.initialHeadCommits.monorepo.trim();
6926
7007
  }
6927
7008
  }
@@ -6931,7 +7012,7 @@ function resolveMonorepoBaseCommit(projectRoot, repo) {
6931
7012
  const runtimeContext = loadRuntimeContextFromEnv();
6932
7013
  if (runtimeContext?.monorepoBaseCommit?.trim()) {
6933
7014
  const monorepoRoot = resolveTaskMonorepoRoot(projectRoot);
6934
- if (resolve24(monorepoRoot) === resolve24(repo)) {
7015
+ if (resolve25(monorepoRoot) === resolve25(repo)) {
6935
7016
  return runtimeContext.monorepoBaseCommit.trim();
6936
7017
  }
6937
7018
  }
@@ -6976,7 +7057,7 @@ function resolveRuntimeDirtyBaseline(projectRoot, repo) {
6976
7057
  return new Set;
6977
7058
  }
6978
7059
  const monorepoRoot = resolveTaskMonorepoRoot(projectRoot);
6979
- const selected = resolve24(repo) === resolve24(monorepoRoot) ? dirtyFiles.monorepo : resolve24(repo) === resolve24(projectRoot) ? dirtyFiles.project : undefined;
7060
+ const selected = resolve25(repo) === resolve25(monorepoRoot) ? dirtyFiles.monorepo : resolve25(repo) === resolve25(projectRoot) ? dirtyFiles.project : undefined;
6980
7061
  return new Set((selected || []).map((file) => normalizeChangedFilePath(file)).filter(Boolean));
6981
7062
  }
6982
7063
  function normalizeChangedFilePath(file) {
@@ -7076,12 +7157,12 @@ function printIndented(text) {
7076
7157
  }
7077
7158
  }
7078
7159
  function readLocalBeadsTasks(projectRoot) {
7079
- const issuesPath = resolve24(resolveMonorepoRoot2(projectRoot), ".beads/issues.jsonl");
7080
- if (!existsSync21(issuesPath)) {
7160
+ const issuesPath = resolve25(resolveMonorepoRoot2(projectRoot), ".beads/issues.jsonl");
7161
+ if (!existsSync23(issuesPath)) {
7081
7162
  return [];
7082
7163
  }
7083
7164
  const tasks = [];
7084
- for (const line of readFileSync11(issuesPath, "utf-8").split(/\r?\n/)) {
7165
+ for (const line of readFileSync12(issuesPath, "utf-8").split(/\r?\n/)) {
7085
7166
  const trimmed = line.trim();
7086
7167
  if (!trimmed) {
7087
7168
  continue;
@@ -7194,11 +7275,11 @@ function taskDependencies(projectRoot, taskId, tracker) {
7194
7275
  return [...ids].sort();
7195
7276
  }
7196
7277
  function printArtifactSection(path, header) {
7197
- if (!existsSync21(path)) {
7278
+ if (!existsSync23(path)) {
7198
7279
  return;
7199
7280
  }
7200
7281
  console.log(header);
7201
- process.stdout.write(readFileSync11(path, "utf-8"));
7282
+ process.stdout.write(readFileSync12(path, "utf-8"));
7202
7283
  console.log("");
7203
7284
  }
7204
7285
  function escapeRegExp(value) {
@@ -7238,8 +7319,8 @@ function isRuntimeGatewayGhPath(candidate) {
7238
7319
  }
7239
7320
  function resolveOptionalMonorepoRoot(projectRoot) {
7240
7321
  const runtimeWorkspace = process.env.RIG_TASK_WORKSPACE?.trim();
7241
- if (runtimeWorkspace && existsSync22(resolve25(runtimeWorkspace, ".git"))) {
7242
- return resolve25(runtimeWorkspace);
7322
+ if (runtimeWorkspace && existsSync24(resolve26(runtimeWorkspace, ".git"))) {
7323
+ return resolve26(runtimeWorkspace);
7243
7324
  }
7244
7325
  try {
7245
7326
  return resolveMonorepoRoot2(projectRoot);
@@ -7264,7 +7345,7 @@ function resolveGitBinary(projectRoot) {
7264
7345
  if (!candidate || isRuntimeGatewayGitPath(candidate)) {
7265
7346
  continue;
7266
7347
  }
7267
- if (existsSync22(candidate)) {
7348
+ if (existsSync24(candidate)) {
7268
7349
  return candidate;
7269
7350
  }
7270
7351
  }
@@ -7324,11 +7405,11 @@ function gitPreflight(projectRoot, taskId, strict) {
7324
7405
  const expected = resolvedTask ? `rig/${resolveTaskBranchId(projectRoot, resolvedTask)}` : "";
7325
7406
  console.log("=== Git Flow Preflight ===");
7326
7407
  let issues = 0;
7327
- if (!existsSync22(resolve25(projectRoot, ".git"))) {
7408
+ if (!existsSync24(resolve26(projectRoot, ".git"))) {
7328
7409
  console.log(`ERROR: project root is not a git repo (${projectRoot})`);
7329
7410
  issues += 1;
7330
7411
  }
7331
- if (monorepoRoot && existsSync22(resolve25(monorepoRoot, ".git"))) {
7412
+ if (monorepoRoot && existsSync24(resolve26(monorepoRoot, ".git"))) {
7332
7413
  const monoBranch = branchName(projectRoot, monorepoRoot);
7333
7414
  if (expected && monoBranch !== expected) {
7334
7415
  console.log(`WARN: monorepo branch is ${monoBranch}, expected ${expected} for task ${resolvedTask}`);
@@ -7362,7 +7443,7 @@ function gitSyncBranch(projectRoot, taskId, targetRepo = "monorepo") {
7362
7443
  }
7363
7444
  const repoRoot = targetRepo === "monorepo" ? resolveOptionalMonorepoRoot(projectRoot) || resolveMonorepoRoot2(projectRoot) : projectRoot;
7364
7445
  const repoLabel = targetRepo === "monorepo" ? "Monorepo" : "Project";
7365
- if (!existsSync22(resolve25(repoRoot, ".git"))) {
7446
+ if (!existsSync24(resolve26(repoRoot, ".git"))) {
7366
7447
  throw new Error(`${repoLabel} repo not found at ${repoRoot}`);
7367
7448
  }
7368
7449
  const branchId = resolveTaskBranchId(projectRoot, resolvedTask);
@@ -7406,8 +7487,8 @@ function gitCommit(options) {
7406
7487
  function gitSnapshot(projectRoot, taskId, outputPath) {
7407
7488
  const monorepoRoot = resolveOptionalMonorepoRoot(projectRoot);
7408
7489
  const resolvedTask = taskId || safeCurrentTaskId(projectRoot);
7409
- const output = outputPath || (resolvedTask ? resolveArtifactSnapshot(projectRoot, resolvedTask) : resolve25(resolve25(projectRoot, ".rig", "state"), "git-state.txt"));
7410
- mkdirSync11(dirname11(output), { recursive: true });
7490
+ const output = outputPath || (resolvedTask ? resolveArtifactSnapshot(projectRoot, resolvedTask) : resolve26(resolve26(projectRoot, ".rig", "state"), "git-state.txt"));
7491
+ mkdirSync12(dirname12(output), { recursive: true });
7411
7492
  const lines = ["# Git Snapshot", `timestamp: ${nowIso()}`];
7412
7493
  if (resolvedTask) {
7413
7494
  lines.push(`task: ${resolvedTask}`);
@@ -7417,7 +7498,7 @@ function gitSnapshot(projectRoot, taskId, outputPath) {
7417
7498
  if (monorepoRoot && monorepoRoot !== projectRoot) {
7418
7499
  lines.push(...snapshotRepo(projectRoot, "monorepo", monorepoRoot));
7419
7500
  }
7420
- writeFileSync11(output, `${lines.join(`
7501
+ writeFileSync12(output, `${lines.join(`
7421
7502
  `)}
7422
7503
  `, "utf-8");
7423
7504
  return output;
@@ -7441,7 +7522,7 @@ function gitOpenPr(options) {
7441
7522
  } else if (taskId) {
7442
7523
  gitSyncBranch(options.projectRoot, taskId, "project");
7443
7524
  }
7444
- if (!existsSync22(resolve25(repoRoot, ".git"))) {
7525
+ if (!existsSync24(resolve26(repoRoot, ".git"))) {
7445
7526
  throw new Error(`Repository not available for open-pr target ${target}: ${repoRoot}`);
7446
7527
  }
7447
7528
  const branch = branchName(options.projectRoot, repoRoot);
@@ -7654,12 +7735,12 @@ function assertPrHasNoGitConflicts(prState, repoLabel, baseRef) {
7654
7735
  }
7655
7736
  function writePrMetadata(projectRoot, taskId, result) {
7656
7737
  const dir = artifactDirForId(projectRoot, taskId);
7657
- mkdirSync11(dir, { recursive: true });
7658
- const path = resolve25(dir, "pr-state.json");
7738
+ mkdirSync12(dir, { recursive: true });
7739
+ const path = resolve26(dir, "pr-state.json");
7659
7740
  let prs = {};
7660
- if (existsSync22(path)) {
7741
+ if (existsSync24(path)) {
7661
7742
  try {
7662
- const parsed = JSON.parse(readFileSync12(path, "utf-8"));
7743
+ const parsed = JSON.parse(readFileSync13(path, "utf-8"));
7663
7744
  if (parsed && typeof parsed === "object" && parsed.prs && typeof parsed.prs === "object") {
7664
7745
  prs = parsed.prs;
7665
7746
  }
@@ -7675,16 +7756,16 @@ function writePrMetadata(projectRoot, taskId, result) {
7675
7756
  ...primary || {},
7676
7757
  updated_at: nowIso()
7677
7758
  };
7678
- writeFileSync11(path, `${JSON.stringify(artifact, null, 2)}
7759
+ writeFileSync12(path, `${JSON.stringify(artifact, null, 2)}
7679
7760
  `, "utf-8");
7680
7761
  }
7681
7762
  function readPrMetadata(projectRoot, taskId) {
7682
- const path = resolve25(artifactDirForId(projectRoot, taskId), "pr-state.json");
7683
- if (!existsSync22(path)) {
7763
+ const path = resolve26(artifactDirForId(projectRoot, taskId), "pr-state.json");
7764
+ if (!existsSync24(path)) {
7684
7765
  return [];
7685
7766
  }
7686
7767
  try {
7687
- const parsed = JSON.parse(readFileSync12(path, "utf-8"));
7768
+ const parsed = JSON.parse(readFileSync13(path, "utf-8"));
7688
7769
  if (!parsed || typeof parsed !== "object") {
7689
7770
  return [];
7690
7771
  }
@@ -7697,8 +7778,8 @@ function readPrMetadata(projectRoot, taskId) {
7697
7778
  }
7698
7779
  }
7699
7780
  function resolveArtifactSnapshot(projectRoot, taskId) {
7700
- const artifactDir = resolve25(resolveHarnessPaths(projectRoot).artifactsDir, taskId);
7701
- return resolve25(artifactDir, "git-state.txt");
7781
+ const artifactDir = resolve26(resolveHarnessPaths(projectRoot).artifactsDir, taskId);
7782
+ return resolve26(artifactDir, "git-state.txt");
7702
7783
  }
7703
7784
  function isGitOpenPrResult(value) {
7704
7785
  if (!value || typeof value !== "object" || Array.isArray(value)) {
@@ -7757,14 +7838,14 @@ function resolveGithubCliBinary(projectRoot) {
7757
7838
  }
7758
7839
  const explicitPathEntries = (process.env.PATH || "").split(":").map((entry) => entry.trim()).filter(Boolean);
7759
7840
  for (const entry of explicitPathEntries) {
7760
- candidates.add(resolve25(entry, "gh"));
7841
+ candidates.add(resolve26(entry, "gh"));
7761
7842
  }
7762
7843
  const bunResolved = Bun.which("gh");
7763
7844
  if (bunResolved) {
7764
7845
  candidates.add(bunResolved);
7765
7846
  }
7766
7847
  for (const candidate of candidates) {
7767
- if (candidate && existsSync22(candidate) && !isRuntimeGatewayGhPath(candidate)) {
7848
+ if (candidate && existsSync24(candidate) && !isRuntimeGatewayGhPath(candidate)) {
7768
7849
  return candidate;
7769
7850
  }
7770
7851
  }
@@ -7794,7 +7875,7 @@ function resolveRepoNameWithOwner(projectRoot, repoRoot) {
7794
7875
  return resolveGithubRepoNameWithOwnerFromGitRoot(projectRoot, repoRoot, repoRoot, visited);
7795
7876
  }
7796
7877
  function resolveGithubRepoNameWithOwnerFromGitRoot(projectRoot, gitRoot, cwd, visited) {
7797
- const normalizedGitRoot = resolve25(gitRoot);
7878
+ const normalizedGitRoot = resolve26(gitRoot);
7798
7879
  if (visited.has(normalizedGitRoot)) {
7799
7880
  return "";
7800
7881
  }
@@ -7866,7 +7947,7 @@ function resolveNetworkRemoteName(projectRoot, repoRoot, repoNameWithOwner) {
7866
7947
  return remotes.includes("origin") ? "origin" : remotes[0];
7867
7948
  }
7868
7949
  function gitQuery(projectRoot, gitRoot, cwd, ...args) {
7869
- const gitArgs = existsSync22(resolve25(gitRoot, ".git")) ? gitCmd(projectRoot, gitRoot, ...args) : [resolveGitBinary(projectRoot), "--git-dir", gitRoot, ...args];
7950
+ const gitArgs = existsSync24(resolve26(gitRoot, ".git")) ? gitCmd(projectRoot, gitRoot, ...args) : [resolveGitBinary(projectRoot), "--git-dir", gitRoot, ...args];
7870
7951
  return runCapture2(gitArgs, cwd, projectRoot);
7871
7952
  }
7872
7953
  function resolveLocalGitRemoteRoot(remoteUrl, gitRoot) {
@@ -7884,9 +7965,9 @@ function resolveLocalGitRemoteRoot(remoteUrl, gitRoot) {
7884
7965
  } else if (/^[a-z][a-z0-9+.-]*:\/\//i.test(normalized) || /^[^@]+@[^:]+:.+$/.test(normalized)) {
7885
7966
  return "";
7886
7967
  } else if (!isAbsolute2(normalized)) {
7887
- candidate = resolve25(gitRoot, normalized);
7968
+ candidate = resolve26(gitRoot, normalized);
7888
7969
  }
7889
- return existsSync22(candidate) ? candidate : "";
7970
+ return existsSync24(candidate) ? candidate : "";
7890
7971
  }
7891
7972
  function normalizeGithubRepoNameWithOwner(value) {
7892
7973
  const normalized = value.trim();
@@ -8013,7 +8094,7 @@ function inferReviewerFromChangedFiles(projectRoot, repoRoot, baseRef, branchRef
8013
8094
  return best;
8014
8095
  }
8015
8096
  function snapshotRepo(projectRoot, label, repo) {
8016
- if (!existsSync22(resolve25(repo, ".git"))) {
8097
+ if (!existsSync24(resolve26(repo, ".git"))) {
8017
8098
  return [`## ${label}`, `repo: ${repo}`, "status: unavailable", ""];
8018
8099
  }
8019
8100
  const status = runCapture2(gitCmd(projectRoot, repo, "status", "--short"), projectRoot).stdout.trim();
@@ -8036,7 +8117,7 @@ function snapshotRepo(projectRoot, label, repo) {
8036
8117
  ];
8037
8118
  }
8038
8119
  function commitRepo(projectRoot, repo, label, message, allowEmpty, scoped, files, changedFilesManifest) {
8039
- if (!existsSync22(resolve25(repo, ".git"))) {
8120
+ if (!existsSync24(resolve26(repo, ".git"))) {
8040
8121
  console.log(`Skipping ${label}: repo not available (${repo})`);
8041
8122
  return;
8042
8123
  }
@@ -8068,18 +8149,18 @@ function commitRepo(projectRoot, repo, label, message, allowEmpty, scoped, files
8068
8149
  console.log(`Committed ${label}: ${message}`);
8069
8150
  }
8070
8151
  function readChangedFilesManifest(projectRoot, taskId) {
8071
- const manifestPath = resolve25(artifactDirForId(projectRoot, taskId), "changed-files.txt");
8072
- if (!existsSync22(manifestPath)) {
8152
+ const manifestPath = resolve26(artifactDirForId(projectRoot, taskId), "changed-files.txt");
8153
+ if (!existsSync24(manifestPath)) {
8073
8154
  return [];
8074
8155
  }
8075
- const files = readFileSync12(manifestPath, "utf-8").split(/\r?\n/).map((line) => normalizeChangedFilePath2(line)).filter(Boolean);
8156
+ const files = readFileSync13(manifestPath, "utf-8").split(/\r?\n/).map((line) => normalizeChangedFilePath2(line)).filter(Boolean);
8076
8157
  return [...new Set(files)];
8077
8158
  }
8078
8159
  function refreshChangedFilesManifest(projectRoot, taskId) {
8079
- const manifestPath = resolve25(artifactDirForId(projectRoot, taskId), "changed-files.txt");
8080
- mkdirSync11(dirname11(manifestPath), { recursive: true });
8160
+ const manifestPath = resolve26(artifactDirForId(projectRoot, taskId), "changed-files.txt");
8161
+ mkdirSync12(dirname12(manifestPath), { recursive: true });
8081
8162
  const changedFiles = changedFilesForTask(projectRoot, taskId, true);
8082
- writeFileSync11(manifestPath, `${changedFiles.join(`
8163
+ writeFileSync12(manifestPath, `${changedFiles.join(`
8083
8164
  `)}
8084
8165
  `, "utf-8");
8085
8166
  return manifestPath;
@@ -8192,7 +8273,7 @@ function repoHasPathChange(projectRoot, repoRoot, relativePath) {
8192
8273
  return result.exitCode === 0 && result.stdout.trim().length > 0;
8193
8274
  }
8194
8275
  function stageExcludePathspecs(repoRoot) {
8195
- const patterns = existsSync22(resolve25(repoRoot, ".rig", "task-config.json")) ? [...TASK_RUNTIME_STAGE_EXCLUDES, ...GENERATED_STAGE_EXCLUDES] : [".rig/**", ...GENERATED_STAGE_EXCLUDES];
8276
+ const patterns = existsSync24(resolve26(repoRoot, ".rig", "task-config.json")) ? [...TASK_RUNTIME_STAGE_EXCLUDES, ...GENERATED_STAGE_EXCLUDES] : [".rig/**", ...GENERATED_STAGE_EXCLUDES];
8196
8277
  return patterns.map((pattern) => `:(glob,exclude)${pattern}`);
8197
8278
  }
8198
8279
  function pathResolvesBeyondSymlink(repoRoot, relativePath) {
@@ -8202,7 +8283,7 @@ function pathResolvesBeyondSymlink(repoRoot, relativePath) {
8202
8283
  }
8203
8284
  let current = repoRoot;
8204
8285
  for (let index = 0;index < parts.length - 1; index += 1) {
8205
- current = resolve25(current, parts[index]);
8286
+ current = resolve26(current, parts[index]);
8206
8287
  try {
8207
8288
  if (lstatSync(current).isSymbolicLink()) {
8208
8289
  return true;
@@ -8214,7 +8295,7 @@ function pathResolvesBeyondSymlink(repoRoot, relativePath) {
8214
8295
  return false;
8215
8296
  }
8216
8297
  function printRepoStatus(projectRoot, label, repo, expectedBranch) {
8217
- if (!existsSync22(resolve25(repo, ".git"))) {
8298
+ if (!existsSync24(resolve26(repo, ".git"))) {
8218
8299
  console.log(`${label}: unavailable (${repo})`);
8219
8300
  return;
8220
8301
  }
@@ -8250,7 +8331,7 @@ function resolveTaskBranchId(projectRoot, taskId) {
8250
8331
  }
8251
8332
  } catch {}
8252
8333
  const artifactDir = artifactDirForId(projectRoot, taskId);
8253
- if (existsSync22(artifactDir)) {
8334
+ if (existsSync24(artifactDir)) {
8254
8335
  return taskId;
8255
8336
  }
8256
8337
  throw new Error(`Unknown task id: ${taskId}`);
@@ -8286,11 +8367,11 @@ function runCapture2(command, cwd, projectRoot = cwd) {
8286
8367
  }
8287
8368
  function runtimeGitEnv(projectRoot) {
8288
8369
  const { ctx, runtimeRoot } = resolveRuntimeMetadata(projectRoot);
8289
- const runtimeHome = runtimeRoot ? resolve25(runtimeRoot, "home") : "";
8290
- const runtimeTmp = runtimeRoot ? resolve25(runtimeRoot, "tmp") : "";
8291
- const runtimeCache = runtimeRoot ? resolve25(runtimeRoot, "cache") : "";
8292
- const runtimeKnownHosts = runtimeHome ? resolve25(runtimeHome, ".ssh", "known_hosts") : "";
8293
- const runtimeKey = runtimeHome ? resolve25(runtimeHome, ".ssh", "rig-agent-key") : "";
8370
+ const runtimeHome = runtimeRoot ? resolve26(runtimeRoot, "home") : "";
8371
+ const runtimeTmp = runtimeRoot ? resolve26(runtimeRoot, "tmp") : "";
8372
+ const runtimeCache = runtimeRoot ? resolve26(runtimeRoot, "cache") : "";
8373
+ const runtimeKnownHosts = runtimeHome ? resolve26(runtimeHome, ".ssh", "known_hosts") : "";
8374
+ const runtimeKey = runtimeHome ? resolve26(runtimeHome, ".ssh", "rig-agent-key") : "";
8294
8375
  const env = {};
8295
8376
  if (ctx?.workspaceDir) {
8296
8377
  env.PROJECT_RIG_ROOT = projectRoot;
@@ -8303,14 +8384,14 @@ function runtimeGitEnv(projectRoot) {
8303
8384
  if (runtimeRoot) {
8304
8385
  env.RIG_RUNTIME_HOME = runtimeRoot;
8305
8386
  }
8306
- if (runtimeHome && existsSync22(runtimeHome)) {
8387
+ if (runtimeHome && existsSync24(runtimeHome)) {
8307
8388
  env.HOME = runtimeHome;
8308
8389
  env.OPENSSL_CONF = ensureRuntimeOpenSslConfig(runtimeHome);
8309
8390
  }
8310
- if (runtimeTmp && existsSync22(runtimeTmp)) {
8391
+ if (runtimeTmp && existsSync24(runtimeTmp)) {
8311
8392
  env.TMPDIR = runtimeTmp;
8312
8393
  }
8313
- if (runtimeCache && existsSync22(runtimeCache)) {
8394
+ if (runtimeCache && existsSync24(runtimeCache)) {
8314
8395
  env.XDG_CACHE_HOME = runtimeCache;
8315
8396
  }
8316
8397
  const workspaceSecrets = loadDotEnvSecrets(ctx?.workspaceDir || projectRoot, process.env);
@@ -8354,14 +8435,14 @@ function runtimeGitEnv(projectRoot) {
8354
8435
  env.GH_TOKEN = env.GH_TOKEN || gitHubToken;
8355
8436
  applyGitHubCredentialHelperEnv(env);
8356
8437
  }
8357
- if (runtimeKnownHosts && existsSync22(runtimeKnownHosts)) {
8438
+ if (runtimeKnownHosts && existsSync24(runtimeKnownHosts)) {
8358
8439
  const sshParts = [
8359
8440
  "ssh",
8360
8441
  `-o UserKnownHostsFile="${runtimeKnownHosts}"`,
8361
8442
  "-o StrictHostKeyChecking=yes",
8362
8443
  "-F /dev/null"
8363
8444
  ];
8364
- if (runtimeKey && existsSync22(runtimeKey)) {
8445
+ if (runtimeKey && existsSync24(runtimeKey)) {
8365
8446
  sshParts.splice(1, 0, `-i "${runtimeKey}"`, "-o IdentitiesOnly=yes");
8366
8447
  }
8367
8448
  env.GIT_SSH_COMMAND = sshParts.join(" ");
@@ -8382,12 +8463,12 @@ function loadPersistedRuntimeSecrets(runtimeRoot) {
8382
8463
  if (!runtimeRoot) {
8383
8464
  return {};
8384
8465
  }
8385
- const path = resolve25(runtimeRoot, "runtime-secrets.json");
8386
- if (!existsSync22(path)) {
8466
+ const path = resolve26(runtimeRoot, "runtime-secrets.json");
8467
+ if (!existsSync24(path)) {
8387
8468
  return {};
8388
8469
  }
8389
8470
  try {
8390
- const parsed = JSON.parse(readFileSync12(path, "utf-8"));
8471
+ const parsed = JSON.parse(readFileSync13(path, "utf-8"));
8391
8472
  const entries = Object.entries(parsed).filter((entry) => typeof entry[1] === "string");
8392
8473
  return Object.fromEntries(entries);
8393
8474
  } catch {
@@ -8395,13 +8476,13 @@ function loadPersistedRuntimeSecrets(runtimeRoot) {
8395
8476
  }
8396
8477
  }
8397
8478
  function ensureRuntimeOpenSslConfig(runtimeHome) {
8398
- const sslDir = resolve25(runtimeHome, ".ssl");
8399
- const sslConfig = resolve25(sslDir, "openssl.cnf");
8400
- if (!existsSync22(sslDir)) {
8401
- mkdirSync11(sslDir, { recursive: true });
8479
+ const sslDir = resolve26(runtimeHome, ".ssl");
8480
+ const sslConfig = resolve26(sslDir, "openssl.cnf");
8481
+ if (!existsSync24(sslDir)) {
8482
+ mkdirSync12(sslDir, { recursive: true });
8402
8483
  }
8403
- if (!existsSync22(sslConfig)) {
8404
- writeFileSync11(sslConfig, `# Rig runtime OpenSSL config placeholder
8484
+ if (!existsSync24(sslConfig)) {
8485
+ writeFileSync12(sslConfig, `# Rig runtime OpenSSL config placeholder
8405
8486
  `);
8406
8487
  }
8407
8488
  return sslConfig;
@@ -8419,29 +8500,29 @@ function resolveRuntimeMetadata(projectRoot) {
8419
8500
  if (contextFile) {
8420
8501
  return {
8421
8502
  ctx,
8422
- runtimeRoot: dirname11(resolve25(contextFile))
8503
+ runtimeRoot: dirname12(resolve26(contextFile))
8423
8504
  };
8424
8505
  }
8425
8506
  const inferredContextFile = findRuntimeContextFile2(projectRoot);
8426
- if (existsSync22(inferredContextFile)) {
8507
+ if (existsSync24(inferredContextFile)) {
8427
8508
  try {
8428
8509
  ctx = loadRuntimeContext(inferredContextFile);
8429
8510
  } catch {}
8430
8511
  return {
8431
8512
  ctx,
8432
- runtimeRoot: dirname11(inferredContextFile)
8513
+ runtimeRoot: dirname12(inferredContextFile)
8433
8514
  };
8434
8515
  }
8435
8516
  return { ctx, runtimeRoot: "" };
8436
8517
  }
8437
8518
  function findRuntimeContextFile2(startPath) {
8438
- let current = resolve25(startPath);
8519
+ let current = resolve26(startPath);
8439
8520
  while (true) {
8440
- const candidate = resolve25(current, "runtime-context.json");
8441
- if (existsSync22(candidate)) {
8521
+ const candidate = resolve26(current, "runtime-context.json");
8522
+ if (existsSync24(candidate)) {
8442
8523
  return candidate;
8443
8524
  }
8444
- const parent = dirname11(current);
8525
+ const parent = dirname12(current);
8445
8526
  if (parent === current) {
8446
8527
  return "";
8447
8528
  }
@@ -8450,7 +8531,7 @@ function findRuntimeContextFile2(startPath) {
8450
8531
  }
8451
8532
 
8452
8533
  // packages/runtime/src/control-plane/native/profile-ops.ts
8453
- import { existsSync as existsSync23, mkdirSync as mkdirSync12, writeFileSync as writeFileSync12 } from "fs";
8534
+ import { existsSync as existsSync25, mkdirSync as mkdirSync13, writeFileSync as writeFileSync13 } from "fs";
8454
8535
  var DEFAULTS = {
8455
8536
  model: parseEnvOrDefault(process.env.DEFAULT_AGENT_MODEL, ["claude", "gpt-codex", "pi"], "pi"),
8456
8537
  runtime: parseEnvOrDefault(process.env.DEFAULT_AGENT_RUNTIME, ["claude-code", "codex-app-server", "pi"], "pi"),
@@ -8465,7 +8546,7 @@ function parseEnvOrDefault(value, allowed, fallback) {
8465
8546
  return allowed.includes(value) ? value : fallback;
8466
8547
  }
8467
8548
  async function readProfileFile(path) {
8468
- if (!existsSync23(path)) {
8549
+ if (!existsSync25(path)) {
8469
8550
  return null;
8470
8551
  }
8471
8552
  try {
@@ -8518,14 +8599,14 @@ async function setProfile(projectRoot, options) {
8518
8599
  plugin = model === "gpt-codex" ? "codex" : model === "pi" ? "pi" : "claude";
8519
8600
  }
8520
8601
  const paths = resolveHarnessPaths(projectRoot);
8521
- mkdirSync12(paths.stateDir, { recursive: true });
8602
+ mkdirSync13(paths.stateDir, { recursive: true });
8522
8603
  const next = {
8523
8604
  model,
8524
8605
  runtime,
8525
8606
  agent_plugin: plugin,
8526
8607
  updated_at: new Date().toISOString()
8527
8608
  };
8528
- writeFileSync12(paths.agentProfilePath, `${JSON.stringify(next, null, 2)}
8609
+ writeFileSync13(paths.agentProfilePath, `${JSON.stringify(next, null, 2)}
8529
8610
  `, "utf-8");
8530
8611
  await showProfile(projectRoot, false);
8531
8612
  }
@@ -8561,13 +8642,13 @@ async function setReviewProfile(projectRoot, mode, provider) {
8561
8642
  throw new Error(`Invalid provider: ${resolvedProvider}. Supported: greptile.`);
8562
8643
  }
8563
8644
  const paths = resolveHarnessPaths(projectRoot);
8564
- mkdirSync12(paths.stateDir, { recursive: true });
8645
+ mkdirSync13(paths.stateDir, { recursive: true });
8565
8646
  const next = {
8566
8647
  mode,
8567
8648
  provider: resolvedProvider,
8568
8649
  updated_at: new Date().toISOString()
8569
8650
  };
8570
- writeFileSync12(paths.reviewProfilePath, `${JSON.stringify(next, null, 2)}
8651
+ writeFileSync13(paths.reviewProfilePath, `${JSON.stringify(next, null, 2)}
8571
8652
  `, "utf-8");
8572
8653
  await showReviewProfile(projectRoot);
8573
8654
  }
@@ -8605,44 +8686,44 @@ async function loadReviewProfile(path) {
8605
8686
  }
8606
8687
 
8607
8688
  // packages/runtime/src/control-plane/native/repo-ops.ts
8608
- import { existsSync as existsSync27, mkdirSync as mkdirSync16, readFileSync as readFileSync14, readdirSync as readdirSync6, rmSync as rmSync7, writeFileSync as writeFileSync14 } from "fs";
8609
- import { basename as basename8, dirname as dirname13, resolve as resolve29 } from "path";
8689
+ import { existsSync as existsSync29, mkdirSync as mkdirSync17, readFileSync as readFileSync15, readdirSync as readdirSync6, rmSync as rmSync7, writeFileSync as writeFileSync15 } from "fs";
8690
+ import { basename as basename8, dirname as dirname14, resolve as resolve30 } from "path";
8610
8691
  // packages/runtime/src/control-plane/repos/mirror/bootstrap.ts
8611
- import { existsSync as existsSync25, mkdirSync as mkdirSync14, realpathSync as realpathSync2 } from "fs";
8612
- import { resolve as resolve27 } from "path";
8692
+ import { existsSync as existsSync27, mkdirSync as mkdirSync15, realpathSync as realpathSync2 } from "fs";
8693
+ import { resolve as resolve28 } from "path";
8613
8694
 
8614
8695
  // packages/runtime/src/control-plane/authority-files.ts
8615
- 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";
8616
- import { dirname as dirname12, join as join4, relative, resolve as resolve26 } from "path";
8696
+ 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";
8697
+ import { dirname as dirname13, join as join4, relative, resolve as resolve27 } from "path";
8617
8698
  import { parse as parseToml, stringify as stringifyToml } from "smol-toml";
8618
8699
  function resolveAuthorityProjectStateDir(projectRoot) {
8619
8700
  const explicit = process.env.RIG_STATE_DIR?.trim();
8620
8701
  if (explicit) {
8621
- return resolve26(explicit);
8702
+ return resolve27(explicit);
8622
8703
  }
8623
- return resolve26(resolve26(projectRoot), ".rig", "state");
8704
+ return resolve27(resolve27(projectRoot), ".rig", "state");
8624
8705
  }
8625
8706
  function readJsonAtPath(path, fallback) {
8626
- if (!existsSync24(path)) {
8707
+ if (!existsSync26(path)) {
8627
8708
  return fallback;
8628
8709
  }
8629
8710
  try {
8630
- return JSON.parse(readFileSync13(path, "utf-8"));
8711
+ return JSON.parse(readFileSync14(path, "utf-8"));
8631
8712
  } catch {
8632
8713
  return fallback;
8633
8714
  }
8634
8715
  }
8635
8716
  function writeJsonAtPath(path, value) {
8636
- mkdirSync13(dirname12(path), { recursive: true });
8637
- writeFileSync13(path, `${JSON.stringify(value, null, 2)}
8717
+ mkdirSync14(dirname13(path), { recursive: true });
8718
+ writeFileSync14(path, `${JSON.stringify(value, null, 2)}
8638
8719
  `, "utf8");
8639
8720
  return path;
8640
8721
  }
8641
8722
  function readAuthorityProjectStateJson(projectRoot, relativePath, fallback) {
8642
- return readJsonAtPath(resolve26(resolveAuthorityProjectStateDir(projectRoot), relativePath), fallback);
8723
+ return readJsonAtPath(resolve27(resolveAuthorityProjectStateDir(projectRoot), relativePath), fallback);
8643
8724
  }
8644
8725
  function writeAuthorityProjectStateJson(projectRoot, relativePath, value) {
8645
- return writeJsonAtPath(resolve26(resolveAuthorityProjectStateDir(projectRoot), relativePath), value);
8726
+ return writeJsonAtPath(resolve27(resolveAuthorityProjectStateDir(projectRoot), relativePath), value);
8646
8727
  }
8647
8728
 
8648
8729
  // packages/runtime/src/control-plane/repos/mirror/state.ts
@@ -8702,7 +8783,7 @@ function sameExistingPath(left, right) {
8702
8783
  try {
8703
8784
  return realpathSync2(left) === realpathSync2(right);
8704
8785
  } catch {
8705
- return resolve27(left) === resolve27(right);
8786
+ return resolve28(left) === resolve28(right);
8706
8787
  }
8707
8788
  }
8708
8789
  function repoLooksUsable(repoRoot, projectRoot) {
@@ -8738,7 +8819,7 @@ function resolveMirrorRemoteUrl(layout) {
8738
8819
  }
8739
8820
  }
8740
8821
  }
8741
- if (existsSync25(resolve27(layout.checkoutRoot, ".git")) && checkoutLooksUsable(layout)) {
8822
+ if (existsSync27(resolve28(layout.checkoutRoot, ".git")) && checkoutLooksUsable(layout)) {
8742
8823
  const checkoutOrigin = runGit(["git", "-C", layout.checkoutRoot, "remote", "get-url", "origin"], layout.projectRoot);
8743
8824
  if (checkoutOrigin.exitCode === 0) {
8744
8825
  const currentOrigin = checkoutOrigin.stdout.trim();
@@ -8751,9 +8832,9 @@ function resolveMirrorRemoteUrl(layout) {
8751
8832
  }
8752
8833
  function ensureManagedRepoMirror(projectRoot, repoId) {
8753
8834
  const layout = resolveManagedRepoLayout(projectRoot, repoId);
8754
- mkdirSync14(layout.metadataRoot, { recursive: true });
8835
+ mkdirSync15(layout.metadataRoot, { recursive: true });
8755
8836
  const remoteUrl = resolveMirrorRemoteUrl(layout);
8756
- if (!existsSync25(resolve27(layout.mirrorRoot, "HEAD"))) {
8837
+ if (!existsSync27(resolve28(layout.mirrorRoot, "HEAD"))) {
8757
8838
  ensureGitSuccess(runGit(["git", "init", "--bare", layout.mirrorRoot], layout.projectRoot), ["git", "init", "--bare", layout.mirrorRoot]);
8758
8839
  }
8759
8840
  const getOrigin = runGit(["git", "--git-dir", layout.mirrorRoot, "remote", "get-url", "origin"], layout.projectRoot);
@@ -8773,8 +8854,8 @@ function ensureManagedRepoMirror(projectRoot, repoId) {
8773
8854
  return layout;
8774
8855
  }
8775
8856
  // packages/runtime/src/control-plane/repos/mirror/refresh.ts
8776
- import { existsSync as existsSync26, mkdirSync as mkdirSync15, realpathSync as realpathSync3, rmSync as rmSync6 } from "fs";
8777
- import { resolve as resolve28 } from "path";
8857
+ import { existsSync as existsSync28, mkdirSync as mkdirSync16, realpathSync as realpathSync3, rmSync as rmSync6 } from "fs";
8858
+ import { resolve as resolve29 } from "path";
8778
8859
  function nowIso3() {
8779
8860
  return new Date().toISOString();
8780
8861
  }
@@ -8801,7 +8882,7 @@ function sameExistingPath2(left, right) {
8801
8882
  try {
8802
8883
  return realpathSync3(left) === realpathSync3(right);
8803
8884
  } catch {
8804
- return resolve28(left) === resolve28(right);
8885
+ return resolve29(left) === resolve29(right);
8805
8886
  }
8806
8887
  }
8807
8888
  function ensureMirrorHead(layout) {
@@ -8847,12 +8928,12 @@ function checkoutLooksUsable2(layout) {
8847
8928
  return probe.exitCode === 0 && sameExistingPath2(probe.stdout.trim(), layout.checkoutRoot);
8848
8929
  }
8849
8930
  function ensureCheckoutFromMirror(layout) {
8850
- mkdirSync15(resolve28(layout.checkoutRoot, ".."), { recursive: true });
8851
- const gitPath = resolve28(layout.checkoutRoot, ".git");
8852
- if (existsSync26(layout.checkoutRoot) && (!existsSync26(gitPath) || !checkoutLooksUsable2(layout))) {
8931
+ mkdirSync16(resolve29(layout.checkoutRoot, ".."), { recursive: true });
8932
+ const gitPath = resolve29(layout.checkoutRoot, ".git");
8933
+ if (existsSync28(layout.checkoutRoot) && (!existsSync28(gitPath) || !checkoutLooksUsable2(layout))) {
8853
8934
  rmSync6(layout.checkoutRoot, { recursive: true, force: true });
8854
8935
  }
8855
- if (!existsSync26(gitPath)) {
8936
+ if (!existsSync28(gitPath)) {
8856
8937
  ensureGitSuccess2(runGit2(["git", "clone", layout.mirrorRoot, layout.checkoutRoot], layout.projectRoot), ["git", "clone", layout.mirrorRoot, layout.checkoutRoot]);
8857
8938
  }
8858
8939
  const getOrigin = runGit2(["git", "-C", layout.checkoutRoot, "remote", "get-url", "origin"], layout.projectRoot);
@@ -8953,7 +9034,7 @@ function repoDiscover(projectRoot, taskId) {
8953
9034
  }
8954
9035
  function repoBaseline(projectRoot, refresh = false) {
8955
9036
  const paths = resolveRepoDiscoveryPaths(projectRoot);
8956
- if (!refresh && existsSync27(paths.baseRepoPinsPath)) {
9037
+ if (!refresh && existsSync29(paths.baseRepoPinsPath)) {
8957
9038
  const baseline = readJsonFile(paths.baseRepoPinsPath, { recorded_at: nowIso(), repos: {} });
8958
9039
  return baseline.repos || {};
8959
9040
  }
@@ -8977,8 +9058,8 @@ function ensureMonorepoReady(projectRoot) {
8977
9058
  }
8978
9059
  function persistBaselinePins(projectRoot, repos) {
8979
9060
  const paths = resolveRepoDiscoveryPaths(projectRoot);
8980
- mkdirSync16(resolve29(paths.baseRepoPinsPath, ".."), { recursive: true });
8981
- writeFileSync14(paths.baseRepoPinsPath, `${JSON.stringify({ recorded_at: nowIso(), repos }, null, 2)}
9061
+ mkdirSync17(resolve30(paths.baseRepoPinsPath, ".."), { recursive: true });
9062
+ writeFileSync15(paths.baseRepoPinsPath, `${JSON.stringify({ recorded_at: nowIso(), repos }, null, 2)}
8982
9063
  `, "utf-8");
8983
9064
  return repos;
8984
9065
  }
@@ -9057,28 +9138,28 @@ function readRepoDiscoveryTaskConfig(projectRoot) {
9057
9138
  function resolveRepoDiscoveryPaths(projectRoot) {
9058
9139
  const monorepoRoot = resolveMonorepoRepoLayout(projectRoot).checkoutRoot;
9059
9140
  const explicitHostProjectRoot = (process.env.RIG_HOST_PROJECT_ROOT || "").trim();
9060
- const normalizedProjectRoot = resolve29(projectRoot);
9141
+ const normalizedProjectRoot = resolve30(projectRoot);
9061
9142
  const hostProjectRoot = explicitHostProjectRoot && shouldUseHostProjectStateRoot(normalizedProjectRoot) ? explicitHostProjectRoot : normalizedProjectRoot;
9062
- const stateDir = resolve29(hostProjectRoot, ".rig", "state");
9143
+ const stateDir = resolve30(hostProjectRoot, ".rig", "state");
9063
9144
  return {
9064
9145
  monorepoRoot,
9065
- taskRepoCommitsPath: resolve29(stateDir, "task-repo-commits.json"),
9066
- baseRepoPinsPath: resolve29(stateDir, "base-repo-pins.json")
9146
+ taskRepoCommitsPath: resolve30(stateDir, "task-repo-commits.json"),
9147
+ baseRepoPinsPath: resolve30(stateDir, "base-repo-pins.json")
9067
9148
  };
9068
9149
  }
9069
9150
  function shouldUseHostProjectStateRoot(projectRoot) {
9070
9151
  const runtimeWorkspace = process.env.RIG_TASK_WORKSPACE?.trim();
9071
- if (runtimeWorkspace && resolve29(runtimeWorkspace) === projectRoot) {
9152
+ if (runtimeWorkspace && resolve30(runtimeWorkspace) === projectRoot) {
9072
9153
  return true;
9073
9154
  }
9074
- return basename8(dirname13(projectRoot)) === ".worktrees";
9155
+ return basename8(dirname14(projectRoot)) === ".worktrees";
9075
9156
  }
9076
9157
  function readPinFromArtifact(projectRoot, depTask, repoKey) {
9077
- const snapshot = resolve29(artifactDirForId(projectRoot, depTask), "git-state.txt");
9078
- if (!existsSync27(snapshot)) {
9158
+ const snapshot = resolve30(artifactDirForId(projectRoot, depTask), "git-state.txt");
9159
+ if (!existsSync29(snapshot)) {
9079
9160
  return "";
9080
9161
  }
9081
- const content = readFileSync14(snapshot, "utf-8");
9162
+ const content = readFileSync15(snapshot, "utf-8");
9082
9163
  const chunk = content.split(/\r?\n/);
9083
9164
  let inSection = false;
9084
9165
  for (const line of chunk) {
@@ -9100,12 +9181,12 @@ function repoPath(projectRoot, key) {
9100
9181
  if (managed) {
9101
9182
  return managed.checkoutRoot;
9102
9183
  }
9103
- return key.startsWith("/") ? key : resolve29(projectRoot, key);
9184
+ return key.startsWith("/") ? key : resolve30(projectRoot, key);
9104
9185
  }
9105
9186
  function applyPins(projectRoot, pins) {
9106
9187
  for (const [key, commit] of Object.entries(pins)) {
9107
9188
  const path = repoPath(projectRoot, key);
9108
- if (!existsSync27(resolve29(path, ".git"))) {
9189
+ if (!existsSync29(resolve30(path, ".git"))) {
9109
9190
  throw new Error(`Repo for pin not available: ${key} (${path})`);
9110
9191
  }
9111
9192
  let hasCommit = runGitCapture(["git", "-C", path, "cat-file", "-e", `${commit}^{commit}`], projectRoot).exitCode === 0;
@@ -9134,7 +9215,7 @@ function verifyPins(projectRoot, pins) {
9134
9215
  let ok = true;
9135
9216
  for (const [key, expected] of Object.entries(pins)) {
9136
9217
  const path = repoPath(projectRoot, key);
9137
- if (!existsSync27(resolve29(path, ".git"))) {
9218
+ if (!existsSync29(resolve30(path, ".git"))) {
9138
9219
  console.error(`ERROR: repo missing during pin verification: ${key}`);
9139
9220
  ok = false;
9140
9221
  continue;
@@ -9159,23 +9240,23 @@ function resolveRuntimeGitEnv() {
9159
9240
  GIT_SSH_COMMAND: process.env.GIT_SSH_COMMAND
9160
9241
  };
9161
9242
  }
9162
- 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()));
9163
- const runtimeHome = runtimeRoot ? resolve29(runtimeRoot, "home") : process.env.HOME?.trim() || "";
9243
+ 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()));
9244
+ const runtimeHome = runtimeRoot ? resolve30(runtimeRoot, "home") : process.env.HOME?.trim() || "";
9164
9245
  if (!runtimeHome) {
9165
9246
  return;
9166
9247
  }
9167
- const knownHostsPath = resolve29(runtimeHome, ".ssh", "known_hosts");
9168
- if (!existsSync27(knownHostsPath)) {
9248
+ const knownHostsPath = resolve30(runtimeHome, ".ssh", "known_hosts");
9249
+ if (!existsSync29(knownHostsPath)) {
9169
9250
  return { HOME: runtimeHome };
9170
9251
  }
9171
- const agentSshKey = resolve29(runtimeHome, ".ssh", "rig-agent-key");
9252
+ const agentSshKey = resolve30(runtimeHome, ".ssh", "rig-agent-key");
9172
9253
  const sshParts = [
9173
9254
  "ssh",
9174
9255
  `-o UserKnownHostsFile="${knownHostsPath}"`,
9175
9256
  "-o StrictHostKeyChecking=yes",
9176
9257
  "-F /dev/null"
9177
9258
  ];
9178
- if (existsSync27(agentSshKey)) {
9259
+ if (existsSync29(agentSshKey)) {
9179
9260
  sshParts.splice(1, 0, `-i "${agentSshKey}"`, "-o IdentitiesOnly=yes");
9180
9261
  }
9181
9262
  return {
@@ -9185,24 +9266,24 @@ function resolveRuntimeGitEnv() {
9185
9266
  }
9186
9267
  function inferRuntimeRootFromWorkspace(cwd) {
9187
9268
  const contextPath = findRuntimeContextFile3(cwd);
9188
- if (!contextPath || !existsSync27(contextPath)) {
9269
+ if (!contextPath || !existsSync29(contextPath)) {
9189
9270
  return "";
9190
9271
  }
9191
9272
  try {
9192
9273
  loadRuntimeContext(contextPath);
9193
- return resolve29(contextPath, "..");
9274
+ return resolve30(contextPath, "..");
9194
9275
  } catch {
9195
9276
  return "";
9196
9277
  }
9197
9278
  }
9198
9279
  function findRuntimeContextFile3(startPath) {
9199
- let current = resolve29(startPath);
9280
+ let current = resolve30(startPath);
9200
9281
  while (true) {
9201
- const candidate = resolve29(current, "runtime-context.json");
9202
- if (existsSync27(candidate)) {
9282
+ const candidate = resolve30(current, "runtime-context.json");
9283
+ if (existsSync29(candidate)) {
9203
9284
  return candidate;
9204
9285
  }
9205
- const parent = resolve29(current, "..");
9286
+ const parent = resolve30(current, "..");
9206
9287
  if (parent === current) {
9207
9288
  return "";
9208
9289
  }
@@ -9211,13 +9292,13 @@ function findRuntimeContextFile3(startPath) {
9211
9292
  }
9212
9293
 
9213
9294
  // packages/runtime/src/control-plane/memory-sync/cli.ts
9214
- import { existsSync as existsSync28 } from "fs";
9295
+ import { existsSync as existsSync30 } from "fs";
9215
9296
  import { randomUUID } from "crypto";
9216
9297
 
9217
9298
  // packages/runtime/src/control-plane/memory-sync/db.ts
9218
9299
  import { Database } from "bun:sqlite";
9219
- import { mkdirSync as mkdirSync17 } from "fs";
9220
- import { dirname as dirname14 } from "path";
9300
+ import { mkdirSync as mkdirSync18 } from "fs";
9301
+ import { dirname as dirname15 } from "path";
9221
9302
 
9222
9303
  // packages/runtime/src/control-plane/memory-sync/types.ts
9223
9304
  var NO_MATCH_RETRIEVAL_CANONICAL_KEY = "__memory_recall__:none";
@@ -9813,7 +9894,7 @@ async function validateEventTargets(executor, event) {
9813
9894
  }
9814
9895
  }
9815
9896
  async function openMemoryDb(dbPath) {
9816
- mkdirSync17(dirname14(dbPath), { recursive: true });
9897
+ mkdirSync18(dirname15(dbPath), { recursive: true });
9817
9898
  const sqlite = new Database(dbPath, { create: true, strict: true });
9818
9899
  const client = createMemoryDbClient(sqlite);
9819
9900
  const db = {
@@ -10232,7 +10313,7 @@ function formatMemoryQueryResults(results) {
10232
10313
  }
10233
10314
 
10234
10315
  // packages/runtime/src/control-plane/memory-sync/read.ts
10235
- import { mkdtempSync, rmSync as rmSync8, writeFileSync as writeFileSync15 } from "fs";
10316
+ import { mkdtempSync, rmSync as rmSync8, writeFileSync as writeFileSync16 } from "fs";
10236
10317
  import { tmpdir as tmpdir5 } from "os";
10237
10318
  import { join as join5 } from "path";
10238
10319
  var CANONICAL_MEMORY_DB_PATH = "rig/memory/project-memory.db";
@@ -10261,7 +10342,7 @@ async function readCanonicalMemoryDb(projectRoot, deps = {}) {
10261
10342
  try {
10262
10343
  try {
10263
10344
  const bytes = readDeps.readBlobBytesAtRef(repoPath2, baseOid, CANONICAL_MEMORY_DB_PATH);
10264
- writeFileSync15(dbPath, bytes);
10345
+ writeFileSync16(dbPath, bytes);
10265
10346
  } catch (error) {
10266
10347
  if (!isMissingCanonicalMemoryBlobError(error)) {
10267
10348
  throw error;
@@ -10419,7 +10500,7 @@ function requireRuntimeMemoryContext(runtimeContext) {
10419
10500
  }
10420
10501
  async function ensureRuntimeMemoryUsable(runtimeContext) {
10421
10502
  const memory = requireRuntimeMemoryContext(runtimeContext);
10422
- if (!existsSync28(memory.hydratedPath)) {
10503
+ if (!existsSync30(memory.hydratedPath)) {
10423
10504
  throw new Error(`Shared memory database is missing: ${memory.hydratedPath}`);
10424
10505
  }
10425
10506
  const db = await openMemoryDb(memory.hydratedPath);
@@ -10720,8 +10801,8 @@ async function executeHarnessCommand(projectRoot, args, eventBus, pluginHostCtx)
10720
10801
  }
10721
10802
  case "completion-verification":
10722
10803
  case "completition-verification": {
10723
- const hookPath = resolve30(projectRoot, ".rig/bin/hooks/completion-verification");
10724
- if (!existsSync29(hookPath)) {
10804
+ const hookPath = resolve31(projectRoot, ".rig/bin/hooks/completion-verification");
10805
+ if (!existsSync31(hookPath)) {
10725
10806
  throw new Error(`completion-verification hook binary not found: ${hookPath}`);
10726
10807
  }
10727
10808
  const proc = Bun.spawn([hookPath], {