@h-rig/runtime 0.0.6-alpha.27 → 0.0.6-alpha.29

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 (39) hide show
  1. package/dist/bin/rig-agent-dispatch.js +552 -483
  2. package/dist/bin/rig-agent.js +418 -364
  3. package/dist/src/control-plane/agent-wrapper.js +557 -488
  4. package/dist/src/control-plane/harness-main.js +559 -1418
  5. package/dist/src/control-plane/hooks/completion-verification.js +451 -808
  6. package/dist/src/control-plane/hooks/inject-context.js +191 -137
  7. package/dist/src/control-plane/hooks/submodule-branch.js +596 -542
  8. package/dist/src/control-plane/hooks/task-runtime-start.js +596 -542
  9. package/dist/src/control-plane/materialize-task-config.js +64 -8
  10. package/dist/src/control-plane/native/git-ops.js +3 -0
  11. package/dist/src/control-plane/native/harness-cli.js +544 -496
  12. package/dist/src/control-plane/native/repo-ops.js +3 -0
  13. package/dist/src/control-plane/native/run-ops.js +3 -0
  14. package/dist/src/control-plane/native/task-ops.js +418 -370
  15. package/dist/src/control-plane/native/validator.js +161 -107
  16. package/dist/src/control-plane/native/verifier.js +217 -169
  17. package/dist/src/control-plane/pi-sessiond/launcher.js +12 -2
  18. package/dist/src/control-plane/plugin-host-context.js +54 -0
  19. package/dist/src/control-plane/runtime/image/fingerprint-sidecar.js +3 -0
  20. package/dist/src/control-plane/runtime/image/index.js +3 -0
  21. package/dist/src/control-plane/runtime/image-fingerprint-sidecar.js +3 -0
  22. package/dist/src/control-plane/runtime/image.js +3 -0
  23. package/dist/src/control-plane/runtime/index.js +487 -718
  24. package/dist/src/control-plane/runtime/isolation/index.js +511 -457
  25. package/dist/src/control-plane/runtime/isolation.js +511 -457
  26. package/dist/src/control-plane/runtime/plugin-mode.js +3 -27
  27. package/dist/src/control-plane/runtime/queue.js +428 -381
  28. package/dist/src/control-plane/runtime/snapshot/task-run.js +3 -0
  29. package/dist/src/control-plane/runtime/task-run-snapshot.js +3 -0
  30. package/dist/src/control-plane/skill-materializer.js +46 -0
  31. package/dist/src/control-plane/tasks/source-lifecycle.js +84 -30
  32. package/dist/src/index.js +0 -278
  33. package/native/darwin-arm64/rig-shell +0 -0
  34. package/native/darwin-arm64/rig-shell.build-manifest.json +1 -1
  35. package/native/darwin-arm64/rig-tools +0 -0
  36. package/native/darwin-arm64/rig-tools.build-manifest.json +1 -1
  37. package/package.json +8 -7
  38. package/dist/src/control-plane/runtime/plugins.js +0 -1131
  39. package/dist/src/plugins.js +0 -329
@@ -2,8 +2,8 @@
2
2
  // @bun
3
3
 
4
4
  // packages/runtime/src/control-plane/hooks/completion-verification.ts
5
- import { appendFileSync as appendFileSync2, existsSync as existsSync21, mkdirSync as mkdirSync12, readFileSync as readFileSync12, writeFileSync as writeFileSync12 } from "fs";
6
- import { resolve as resolve25 } from "path";
5
+ import { appendFileSync as appendFileSync2, existsSync as existsSync21, mkdirSync as mkdirSync13, readFileSync as readFileSync13, writeFileSync as writeFileSync13 } from "fs";
6
+ import { resolve as resolve24 } from "path";
7
7
  import {
8
8
  escapeRegExp as escapeRegExp2,
9
9
  resolveBunCli,
@@ -13,10 +13,15 @@ import {
13
13
  resolvePolicyContent
14
14
  } from "@rig/hook-kit";
15
15
 
16
- // packages/runtime/src/control-plane/runtime/events.ts
17
- import { appendFile, mkdir } from "fs/promises";
18
- import { randomUUID } from "crypto";
19
- import { dirname as dirname2, resolve as resolve2 } from "path";
16
+ // packages/runtime/src/control-plane/runtime/guard.ts
17
+ import { optimizeNextInvocation } from "bun:jsc";
18
+ import { existsSync as existsSync4, readFileSync as readFileSync2, statSync as statSync2 } from "fs";
19
+ import { resolve as resolve4 } from "path";
20
+
21
+ // packages/runtime/src/control-plane/native/utils.ts
22
+ import { ptr as ptr2 } from "bun:ffi";
23
+ import { existsSync as existsSync3, readFileSync } from "fs";
24
+ import { resolve as resolve3 } from "path";
20
25
 
21
26
  // packages/runtime/src/layout.ts
22
27
  import { existsSync } from "fs";
@@ -127,126 +132,13 @@ function resolveRigLayout(projectRoot) {
127
132
  };
128
133
  }
129
134
 
130
- // packages/runtime/src/control-plane/runtime/events.ts
131
- async function appendEvent(eventsFile, event) {
132
- await mkdir(dirname2(eventsFile), { recursive: true });
133
- await appendFile(eventsFile, `${JSON.stringify(event)}
134
- `, "utf-8");
135
- }
136
- function createEvent(runId, type, payload) {
137
- return {
138
- id: randomUUID(),
139
- runId,
140
- timestamp: new Date().toISOString(),
141
- type,
142
- payload
143
- };
144
- }
145
-
146
- class RuntimeEventBus {
147
- runId;
148
- eventsFile;
149
- memoryEvents = [];
150
- constructor(options) {
151
- this.runId = options.runId || randomUUID();
152
- this.eventsFile = options.eventsFile ?? resolveRigLayout(options.projectRoot).controlPlaneEventsFile;
153
- }
154
- getRunId() {
155
- return this.runId;
156
- }
157
- getEventsFile() {
158
- return this.eventsFile;
159
- }
160
- getMemoryEvents() {
161
- return [...this.memoryEvents];
162
- }
163
- async attachRuntimeBus(runtimeBus) {
164
- if (runtimeBus.getEventsFile() === this.eventsFile) {
165
- return;
166
- }
167
- for (const event of this.memoryEvents) {
168
- await runtimeBus.ingest(event);
169
- }
170
- }
171
- async attachRuntimeWorkspace(projectRoot) {
172
- const runtimeBus = new RuntimeEventBus({ projectRoot, runId: this.runId });
173
- await this.attachRuntimeBus(runtimeBus);
174
- return runtimeBus;
175
- }
176
- async ingest(event) {
177
- this.memoryEvents.push(event);
178
- await appendEvent(this.eventsFile, event);
179
- }
180
- async emit(type, payload) {
181
- const event = createEvent(this.runId, type, payload);
182
- await this.ingest(event);
183
- return event;
184
- }
185
- }
186
-
187
- class GeneralCliEventBus {
188
- runId;
189
- eventsFile;
190
- memoryEvents = [];
191
- runtimeBuses = new Map;
192
- constructor(options) {
193
- this.runId = options.runId || randomUUID();
194
- this.eventsFile = options.eventsFile ?? resolve2(options.projectRoot, ".rig", "logs", "control-plane.events.jsonl");
195
- }
196
- getRunId() {
197
- return this.runId;
198
- }
199
- getEventsFile() {
200
- return this.eventsFile;
201
- }
202
- getMemoryEvents() {
203
- return [...this.memoryEvents];
204
- }
205
- async attachRuntimeBus(runtimeBus) {
206
- const key = runtimeBus.getEventsFile();
207
- if (this.runtimeBuses.has(key)) {
208
- return;
209
- }
210
- this.runtimeBuses.set(key, runtimeBus);
211
- for (const event of this.memoryEvents) {
212
- await runtimeBus.ingest(event);
213
- }
214
- }
215
- async attachRuntimeWorkspace(projectRoot) {
216
- const runtimeBus = new RuntimeEventBus({ projectRoot, runId: this.runId });
217
- await this.attachRuntimeBus(runtimeBus);
218
- return runtimeBus;
219
- }
220
- async emit(type, payload) {
221
- const event = createEvent(this.runId, type, payload);
222
- this.memoryEvents.push(event);
223
- await appendEvent(this.eventsFile, event);
224
- await Promise.all(Array.from(this.runtimeBuses.values()).map((bus) => bus.ingest(event)));
225
- return event;
226
- }
227
- }
228
-
229
- // packages/runtime/src/control-plane/runtime/plugins.ts
230
- import { existsSync as existsSync5, readdirSync } from "fs";
231
- import { resolve as resolve6, basename as basename2 } from "path";
232
-
233
- // packages/runtime/src/control-plane/runtime/guard.ts
234
- import { optimizeNextInvocation } from "bun:jsc";
235
- import { existsSync as existsSync4, readFileSync as readFileSync2, statSync as statSync2 } from "fs";
236
- import { resolve as resolve5 } from "path";
237
-
238
- // packages/runtime/src/control-plane/native/utils.ts
239
- import { ptr as ptr2 } from "bun:ffi";
240
- import { existsSync as existsSync3, readFileSync } from "fs";
241
- import { resolve as resolve4 } from "path";
242
-
243
135
  // packages/runtime/src/control-plane/native/runtime-native.ts
244
136
  import { dlopen, ptr, suffix, toBuffer } from "bun:ffi";
245
137
  import { copyFileSync, existsSync as existsSync2, mkdirSync, renameSync, rmSync, statSync } from "fs";
246
138
  import { tmpdir } from "os";
247
- import { dirname as dirname3, resolve as resolve3 } from "path";
248
- var sharedNativeRuntimeOutputDir = resolve3(tmpdir(), "rig-native");
249
- var sharedNativeRuntimeOutputPath = resolve3(sharedNativeRuntimeOutputDir, `runtime-native-${process.platform}-${process.arch}.${suffix}`);
139
+ import { dirname as dirname2, resolve as resolve2 } from "path";
140
+ var sharedNativeRuntimeOutputDir = resolve2(tmpdir(), "rig-native");
141
+ var sharedNativeRuntimeOutputPath = resolve2(sharedNativeRuntimeOutputDir, `runtime-native-${process.platform}-${process.arch}.${suffix}`);
250
142
  var colocatedNativeRuntimeFileName = `runtime-native.${suffix}`;
251
143
  var nativeRuntimeLibrary = await loadNativeRuntimeLibrary();
252
144
  function requireNativeRuntimeLibrary(feature) {
@@ -282,12 +174,12 @@ async function loadNativeRuntimeLibrary() {
282
174
  }
283
175
  function nativePackageLibraryCandidates(fromDir, names) {
284
176
  const candidates = [];
285
- let cursor = resolve3(fromDir);
177
+ let cursor = resolve2(fromDir);
286
178
  for (let index = 0;index < 8; index += 1) {
287
179
  for (const name of names) {
288
- candidates.push(resolve3(cursor, "native", `${process.platform}-${process.arch}`, name), resolve3(cursor, "native", `${process.platform}-${process.arch}`, "lib", name), resolve3(cursor, "native", name), resolve3(cursor, "native", "lib", name));
180
+ candidates.push(resolve2(cursor, "native", `${process.platform}-${process.arch}`, name), resolve2(cursor, "native", `${process.platform}-${process.arch}`, "lib", name), resolve2(cursor, "native", name), resolve2(cursor, "native", "lib", name));
289
181
  }
290
- const parent = dirname3(cursor);
182
+ const parent = dirname2(cursor);
291
183
  if (parent === cursor)
292
184
  break;
293
185
  cursor = parent;
@@ -296,17 +188,17 @@ function nativePackageLibraryCandidates(fromDir, names) {
296
188
  }
297
189
  function nativeRuntimeLibraryCandidates() {
298
190
  const explicit = process.env.RIG_NATIVE_RUNTIME_LIB?.trim() || "";
299
- const execDir = process.execPath?.trim() ? dirname3(process.execPath.trim()) : "";
191
+ const execDir = process.execPath?.trim() ? dirname2(process.execPath.trim()) : "";
300
192
  const platformSpecific = `runtime-native-${process.platform}-${process.arch}.${suffix}`;
301
193
  return [...new Set([
302
194
  explicit,
303
195
  ...nativePackageLibraryCandidates(import.meta.dir, [colocatedNativeRuntimeFileName, platformSpecific]),
304
- execDir ? resolve3(execDir, colocatedNativeRuntimeFileName) : "",
305
- execDir ? resolve3(execDir, platformSpecific) : "",
306
- execDir ? resolve3(execDir, "..", colocatedNativeRuntimeFileName) : "",
307
- execDir ? resolve3(execDir, "..", platformSpecific) : "",
308
- execDir ? resolve3(execDir, "lib", colocatedNativeRuntimeFileName) : "",
309
- execDir ? resolve3(execDir, "..", "lib", colocatedNativeRuntimeFileName) : "",
196
+ execDir ? resolve2(execDir, colocatedNativeRuntimeFileName) : "",
197
+ execDir ? resolve2(execDir, platformSpecific) : "",
198
+ execDir ? resolve2(execDir, "..", colocatedNativeRuntimeFileName) : "",
199
+ execDir ? resolve2(execDir, "..", platformSpecific) : "",
200
+ execDir ? resolve2(execDir, "lib", colocatedNativeRuntimeFileName) : "",
201
+ execDir ? resolve2(execDir, "..", "lib", colocatedNativeRuntimeFileName) : "",
310
202
  sharedNativeRuntimeOutputPath
311
203
  ].filter(Boolean))];
312
204
  }
@@ -315,7 +207,7 @@ function resolveNativeRuntimeSourcePath() {
315
207
  if (explicit && existsSync2(explicit)) {
316
208
  return explicit;
317
209
  }
318
- const bundled = resolve3(import.meta.dir, "../../../native/snapshot.zig");
210
+ const bundled = resolve2(import.meta.dir, "../../../native/snapshot.zig");
319
211
  return existsSync2(bundled) ? bundled : null;
320
212
  }
321
213
  async function buildNativeRuntimeLibrary(outputPath, options = {}) {
@@ -329,7 +221,7 @@ async function buildNativeRuntimeLibrary(outputPath, options = {}) {
329
221
  }
330
222
  const tempOutputPath = `${outputPath}.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2)}.tmp`;
331
223
  try {
332
- mkdirSync(dirname3(outputPath), { recursive: true });
224
+ mkdirSync(dirname2(outputPath), { recursive: true });
333
225
  const needsBuild = options.force === true || !existsSync2(outputPath) || statSync(sourcePath).mtimeMs > statSync(outputPath).mtimeMs;
334
226
  if (!needsBuild) {
335
227
  return true;
@@ -506,31 +398,31 @@ function unique(values) {
506
398
  function resolveHarnessPaths(projectRoot) {
507
399
  const hasRuntimeWorkspace = Boolean(process.env.RIG_TASK_WORKSPACE?.trim());
508
400
  const monorepoRoot = resolveMonorepoRoot2(projectRoot);
509
- const harnessRoot = resolve4(projectRoot, "rig");
510
- const stateRoot = resolve4(projectRoot, ".rig");
401
+ const harnessRoot = resolve3(projectRoot, "rig");
402
+ const stateRoot = resolve3(projectRoot, ".rig");
511
403
  const layout = hasRuntimeWorkspace ? resolveRigLayout(projectRoot) : null;
512
- const stateDir = layout?.stateDir ?? resolve4(stateRoot, "state");
513
- const logsDir = layout?.logsDir ?? resolve4(stateRoot, "logs");
514
- const artifactsDir = layout?.artifactsRoot ?? resolve4(monorepoRoot, "artifacts");
515
- const taskConfigPath = layout?.taskConfigPath ?? resolve4(monorepoRoot, ".rig", "task-config.json");
516
- const binDir = layout?.binDir ?? resolve4(stateRoot, "bin");
404
+ const stateDir = layout?.stateDir ?? resolve3(stateRoot, "state");
405
+ const logsDir = layout?.logsDir ?? resolve3(stateRoot, "logs");
406
+ const artifactsDir = layout?.artifactsRoot ?? resolve3(monorepoRoot, "artifacts");
407
+ const taskConfigPath = layout?.taskConfigPath ?? resolve3(monorepoRoot, ".rig", "task-config.json");
408
+ const binDir = layout?.binDir ?? resolve3(stateRoot, "bin");
517
409
  return {
518
410
  harnessRoot,
519
411
  stateDir: process.env.RIG_STATE_DIR || stateDir,
520
412
  artifactsDir,
521
413
  logsDir: process.env.RIG_LOGS_DIR || logsDir,
522
414
  binDir,
523
- hooksDir: resolve4(harnessRoot, "hooks"),
524
- validationDir: resolve4(harnessRoot, "validation"),
415
+ hooksDir: resolve3(harnessRoot, "hooks"),
416
+ validationDir: resolve3(harnessRoot, "validation"),
525
417
  taskConfigPath,
526
- sessionPath: process.env.RIG_SESSION_FILE || resolve4(stateRoot, "session", "session.json"),
418
+ sessionPath: process.env.RIG_SESSION_FILE || resolve3(stateRoot, "session", "session.json"),
527
419
  monorepoRoot,
528
- tsApiTestsDir: process.env.TS_API_TESTS_DIR || resolve4(monorepoRoot, "TSAPITests"),
529
- taskRepoCommitsPath: resolve4(stateDir, "task-repo-commits.json"),
530
- baseRepoPinsPath: resolve4(stateDir, "base-repo-pins.json"),
531
- failedApproachesPath: resolve4(stateDir, "failed_approaches.md"),
532
- agentProfilePath: resolve4(stateDir, "agent-profile.json"),
533
- reviewProfilePath: resolve4(stateDir, "review-profile.json")
420
+ tsApiTestsDir: process.env.TS_API_TESTS_DIR || resolve3(monorepoRoot, "TSAPITests"),
421
+ taskRepoCommitsPath: resolve3(stateDir, "task-repo-commits.json"),
422
+ baseRepoPinsPath: resolve3(stateDir, "base-repo-pins.json"),
423
+ failedApproachesPath: resolve3(stateDir, "failed_approaches.md"),
424
+ agentProfilePath: resolve3(stateDir, "agent-profile.json"),
425
+ reviewProfilePath: resolve3(stateDir, "review-profile.json")
534
426
  };
535
427
  }
536
428
  function normalizeRelativeScopePath(inputPath) {
@@ -658,7 +550,7 @@ function loadPolicy(projectRoot) {
658
550
  if (seededPolicyConfig) {
659
551
  return seededPolicyConfig;
660
552
  }
661
- const configPath = resolve5(projectRoot, "rig/policy/policy.json");
553
+ const configPath = resolve4(projectRoot, "rig/policy/policy.json");
662
554
  if (!existsSync4(configPath)) {
663
555
  return defaultPolicy();
664
556
  }
@@ -889,28 +781,28 @@ function resolveAction(mode, matched) {
889
781
  }
890
782
  function resolveAbsolutePath(projectRoot, rawPath) {
891
783
  if (rawPath.startsWith("/"))
892
- return resolve5(rawPath);
893
- return resolve5(projectRoot, rawPath);
784
+ return resolve4(rawPath);
785
+ return resolve4(projectRoot, rawPath);
894
786
  }
895
787
  function isHarnessPath(projectRoot, rawPath) {
896
788
  const absPath = resolveAbsolutePath(projectRoot, rawPath);
897
789
  const managedRoots = [
898
- resolve5(projectRoot, "rig"),
899
- resolve5(projectRoot, ".rig"),
900
- resolve5(projectRoot, "artifacts")
790
+ resolve4(projectRoot, "rig"),
791
+ resolve4(projectRoot, ".rig"),
792
+ resolve4(projectRoot, "artifacts")
901
793
  ];
902
794
  return managedRoots.some((root) => absPath === root || absPath.startsWith(root + "/"));
903
795
  }
904
796
  function isRuntimePath(projectRoot, rawPath, taskWorkspace) {
905
797
  const absPath = resolveAbsolutePath(projectRoot, rawPath);
906
798
  if (taskWorkspace) {
907
- const workspaceRigRoot = resolve5(taskWorkspace, ".rig");
908
- const workspaceArtifactsRoot = resolve5(taskWorkspace, "artifacts");
799
+ const workspaceRigRoot = resolve4(taskWorkspace, ".rig");
800
+ const workspaceArtifactsRoot = resolve4(taskWorkspace, "artifacts");
909
801
  if (absPath === workspaceRigRoot || absPath.startsWith(workspaceRigRoot + "/") || absPath === workspaceArtifactsRoot || absPath.startsWith(workspaceArtifactsRoot + "/")) {
910
802
  return true;
911
803
  }
912
804
  }
913
- const runtimeRoot = resolve5(projectRoot, ".rig/runtime/agents");
805
+ const runtimeRoot = resolve4(projectRoot, ".rig/runtime/agents");
914
806
  return absPath === runtimeRoot || absPath.startsWith(runtimeRoot + "/");
915
807
  }
916
808
  function isTestFile(path) {
@@ -958,7 +850,7 @@ function evaluateScope(policy, context, filePath, access) {
958
850
  return allowed();
959
851
  }
960
852
  if (context.taskWorkspace && context.taskWorkspace !== context.projectRoot && filePath.startsWith("/")) {
961
- const absPath = resolve5(filePath);
853
+ const absPath = resolve4(filePath);
962
854
  if (!absPath.startsWith(context.taskWorkspace + "/") && !isHarnessPath(context.projectRoot, filePath)) {
963
855
  const reason2 = `Absolute path '${filePath}' is outside task runtime boundary. Allowed root: ${context.taskWorkspace}`;
964
856
  const matched2 = [{ id: "scope:workspace-boundary", category: "command", reason: reason2 }];
@@ -1167,12 +1059,6 @@ function extractContentFromToolInput(input) {
1167
1059
  return input.new_string;
1168
1060
  return "";
1169
1061
  }
1170
- function loadRuntimeImageConfig(projectRoot) {
1171
- return loadPolicy(projectRoot).runtime_image ?? {
1172
- deps: { ...DEFAULT_RUNTIME_IMAGE.deps },
1173
- plugins_require_binaries: DEFAULT_RUNTIME_IMAGE.plugins_require_binaries
1174
- };
1175
- }
1176
1062
  var guardHotPathPrimed = false;
1177
1063
  function primeGuardHotPaths() {
1178
1064
  if (guardHotPathPrimed) {
@@ -1186,290 +1072,99 @@ function primeGuardHotPaths() {
1186
1072
  }
1187
1073
  primeGuardHotPaths();
1188
1074
 
1189
- // packages/runtime/src/control-plane/runtime/plugin-mode.ts
1190
- var LEGACY_PLUGIN_SCAN_ENV = "RIG_LEGACY_PLUGIN_SCAN";
1191
- function isLegacyPluginScanEnabled(env = process.env) {
1192
- const value = env[LEGACY_PLUGIN_SCAN_ENV]?.trim().toLowerCase();
1193
- return value === "1" || value === "true" || value === "yes" || value === "on";
1194
- }
1075
+ // packages/runtime/src/control-plane/native/git-ops.ts
1076
+ import { existsSync as existsSync20, lstatSync, mkdirSync as mkdirSync12, readFileSync as readFileSync12, writeFileSync as writeFileSync12 } from "fs";
1077
+ import { dirname as dirname10, isAbsolute as isAbsolute2, resolve as resolve23 } from "path";
1078
+ import { fileURLToPath as fileURLToPath2 } from "url";
1195
1079
 
1196
- // packages/runtime/src/control-plane/runtime/plugins.ts
1197
- class PluginManager {
1198
- eventBus;
1199
- context;
1200
- pluginDir;
1201
- pluginFiles;
1202
- pluginNames;
1203
- localBinDir;
1204
- pluginsRequireBinaries;
1205
- plugins;
1206
- loadPromise;
1207
- constructor(options) {
1208
- this.eventBus = options.eventBus;
1209
- this.context = options.context;
1210
- this.pluginDir = options.pluginDir;
1211
- this.pluginFiles = options.pluginFiles;
1212
- this.pluginNames = options.pluginNames;
1213
- this.localBinDir = options.localBinDir;
1214
- this.pluginsRequireBinaries = options.pluginsRequireBinaries;
1215
- this.plugins = options.preloadedPlugins ?? null;
1216
- this.loadPromise = null;
1217
- }
1218
- static disabled(options) {
1219
- const validatorProjectRoot = options.runtimeContext?.workspaceDir || options.projectRoot;
1220
- return new PluginManager({
1221
- eventBus: options.eventBus,
1222
- context: {
1223
- projectRoot: validatorProjectRoot,
1224
- runId: options.runId,
1225
- eventBus: options.eventBus
1226
- },
1227
- pluginDir: resolve6(options.projectRoot, "rig/plugins"),
1228
- pluginFiles: [],
1229
- pluginNames: [],
1230
- localBinDir: options.runtimeContext ? resolve6(options.runtimeContext.binDir, "plugins") : resolve6(options.projectRoot, "rig/plugins"),
1231
- pluginsRequireBinaries: false,
1232
- preloadedPlugins: []
1233
- });
1234
- }
1235
- static async load(options) {
1236
- const pluginDir = resolve6(options.projectRoot, "rig/plugins");
1237
- const runtimeImageConfig = loadRuntimeImageConfig(options.projectRoot);
1238
- const localBinDir = options.runtimeContext ? resolve6(options.runtimeContext.binDir, "plugins") : resolve6(options.projectRoot, "rig/plugins");
1239
- const legacyPluginScan = options.legacyPluginScan ?? isLegacyPluginScanEnabled(options.env);
1240
- const files = legacyPluginScan ? safeReadDir(pluginDir).filter((entry) => /\.(ts|js|mjs|cjs)$/.test(entry)) : [];
1241
- const pluginNames = files.map((file) => basename2(file).replace(/\.plugin\.(ts|js|mjs|cjs)$/, ""));
1242
- const validatorProjectRoot = options.runtimeContext?.workspaceDir || options.projectRoot;
1243
- const context = {
1244
- projectRoot: validatorProjectRoot,
1245
- runId: options.runId,
1246
- eventBus: options.eventBus
1247
- };
1248
- return new PluginManager({
1249
- eventBus: options.eventBus,
1250
- context,
1251
- pluginDir,
1252
- pluginFiles: files,
1253
- pluginNames,
1254
- localBinDir,
1255
- pluginsRequireBinaries: options.pluginsRequireBinaries ?? (runtimeImageConfig.plugins_require_binaries && Boolean(options.runtimeContext))
1256
- });
1257
- }
1258
- list() {
1259
- if (this.plugins) {
1260
- return this.plugins.map((plugin) => ({
1261
- name: plugin.name,
1262
- validators: plugin.validators?.map((validator) => validator.id) ?? []
1263
- }));
1264
- }
1265
- return this.pluginNames.map((name) => ({
1266
- name,
1267
- validators: []
1268
- }));
1269
- }
1270
- async beforeCommand(ctx) {
1271
- const plugins = await this.ensureLoaded();
1272
- for (const plugin of plugins) {
1273
- if (!plugin.beforeCommand) {
1274
- continue;
1275
- }
1276
- await this.safeInvoke(plugin.name, "beforeCommand", () => plugin.beforeCommand?.(ctx, this.context));
1277
- }
1278
- }
1279
- async afterCommand(result) {
1280
- const plugins = await this.ensureLoaded();
1281
- for (const plugin of plugins) {
1282
- if (!plugin.afterCommand) {
1283
- continue;
1284
- }
1285
- await this.safeInvoke(plugin.name, "afterCommand", () => plugin.afterCommand?.(result, this.context));
1080
+ // packages/runtime/src/control-plane/runtime/baked-secrets.ts
1081
+ import { existsSync as existsSync5, readFileSync as readFileSync3 } from "fs";
1082
+ import { resolve as resolve5 } from "path";
1083
+ var BAKED_RUNTIME_SECRETS = {
1084
+ ANTHROPIC_API_KEY: typeof RIG_BAKED_ANTHROPIC_API_KEY !== "undefined" ? RIG_BAKED_ANTHROPIC_API_KEY : "",
1085
+ OPENAI_API_KEY: typeof RIG_BAKED_OPENAI_API_KEY !== "undefined" ? RIG_BAKED_OPENAI_API_KEY : "",
1086
+ OPENROUTER_API_KEY: typeof RIG_BAKED_OPENROUTER_API_KEY !== "undefined" ? RIG_BAKED_OPENROUTER_API_KEY : "",
1087
+ AI_REVIEW_MODE: typeof RIG_BAKED_AI_REVIEW_MODE !== "undefined" ? RIG_BAKED_AI_REVIEW_MODE : "",
1088
+ AI_REVIEW_PROVIDER: typeof RIG_BAKED_AI_REVIEW_PROVIDER !== "undefined" ? RIG_BAKED_AI_REVIEW_PROVIDER : "",
1089
+ GREPTILE_API_BASE: typeof RIG_BAKED_GREPTILE_API_BASE !== "undefined" ? RIG_BAKED_GREPTILE_API_BASE : "",
1090
+ GREPTILE_REMOTE: typeof RIG_BAKED_GREPTILE_REMOTE !== "undefined" ? RIG_BAKED_GREPTILE_REMOTE : "",
1091
+ GREPTILE_REPOSITORY: typeof RIG_BAKED_GREPTILE_REPOSITORY !== "undefined" ? RIG_BAKED_GREPTILE_REPOSITORY : "",
1092
+ GREPTILE_CONTEXT_BRANCH: typeof RIG_BAKED_GREPTILE_CONTEXT_BRANCH !== "undefined" ? RIG_BAKED_GREPTILE_CONTEXT_BRANCH : "",
1093
+ GREPTILE_DEFAULT_BRANCH: typeof RIG_BAKED_GREPTILE_DEFAULT_BRANCH !== "undefined" ? RIG_BAKED_GREPTILE_DEFAULT_BRANCH : "",
1094
+ GREPTILE_API_KEY: typeof RIG_BAKED_GREPTILE_API_KEY !== "undefined" ? RIG_BAKED_GREPTILE_API_KEY : "",
1095
+ GREPTILE_GITHUB_TOKEN: typeof RIG_BAKED_GREPTILE_GITHUB_TOKEN !== "undefined" ? RIG_BAKED_GREPTILE_GITHUB_TOKEN : "",
1096
+ GREPTILE_POLL_ATTEMPTS: typeof RIG_BAKED_GREPTILE_POLL_ATTEMPTS !== "undefined" ? RIG_BAKED_GREPTILE_POLL_ATTEMPTS : "",
1097
+ GREPTILE_POLL_INTERVAL_MS: typeof RIG_BAKED_GREPTILE_POLL_INTERVAL_MS !== "undefined" ? RIG_BAKED_GREPTILE_POLL_INTERVAL_MS : "",
1098
+ GH_TOKEN: typeof RIG_BAKED_GITHUB_TOKEN !== "undefined" ? RIG_BAKED_GITHUB_TOKEN : "",
1099
+ GITHUB_TOKEN: typeof RIG_BAKED_GITHUB_TOKEN !== "undefined" ? RIG_BAKED_GITHUB_TOKEN : "",
1100
+ GITHUB_SSH_KEY: typeof RIG_BAKED_GITHUB_SSH_KEY !== "undefined" ? RIG_BAKED_GITHUB_SSH_KEY : "",
1101
+ AWS_ACCESS_KEY_ID: typeof RIG_BAKED_AWS_ACCESS_KEY_ID !== "undefined" ? RIG_BAKED_AWS_ACCESS_KEY_ID : "",
1102
+ AWS_SECRET_ACCESS_KEY: typeof RIG_BAKED_AWS_SECRET_ACCESS_KEY !== "undefined" ? RIG_BAKED_AWS_SECRET_ACCESS_KEY : "",
1103
+ AWS_REGION: typeof RIG_BAKED_AWS_REGION !== "undefined" ? RIG_BAKED_AWS_REGION : "",
1104
+ LINEAR_API_KEY: typeof RIG_BAKED_LINEAR_API_KEY !== "undefined" ? RIG_BAKED_LINEAR_API_KEY : "",
1105
+ LINEAR_WEBHOOK_SECRET: typeof RIG_BAKED_LINEAR_WEBHOOK_SECRET !== "undefined" ? RIG_BAKED_LINEAR_WEBHOOK_SECRET : ""
1106
+ };
1107
+ function resolveRuntimeSecrets(env, baked = BAKED_RUNTIME_SECRETS) {
1108
+ const resolved = {};
1109
+ const keys = new Set([
1110
+ ...Object.keys(BAKED_RUNTIME_SECRETS),
1111
+ ...Object.keys(baked)
1112
+ ]);
1113
+ for (const key of keys) {
1114
+ const envValue = env[key]?.trim();
1115
+ const bakedValue = baked[key]?.trim();
1116
+ if (envValue) {
1117
+ resolved[key] = envValue;
1118
+ } else if (bakedValue) {
1119
+ resolved[key] = bakedValue;
1286
1120
  }
1287
1121
  }
1288
- async onEvent(event) {
1289
- const plugins = this.plugins;
1290
- if (!plugins) {
1291
- return;
1292
- }
1293
- for (const plugin of plugins) {
1294
- if (!plugin.onEvent) {
1295
- continue;
1296
- }
1297
- await this.safeInvoke(plugin.name, "onEvent", () => plugin.onEvent?.(event, this.context));
1298
- }
1299
- }
1300
- async runValidators(taskId) {
1301
- const plugins = await this.ensureLoaded();
1302
- const results = [];
1303
- for (const plugin of plugins) {
1304
- for (const validator of plugin.validators ?? []) {
1305
- await this.eventBus.emit("validator.started", {
1306
- plugin: plugin.name,
1307
- validator: validator.id,
1308
- taskId
1309
- });
1310
- try {
1311
- const result = await validator.run({ taskId, projectRoot: this.context.projectRoot }, this.context);
1312
- results.push(result);
1313
- await this.eventBus.emit("validator.finished", {
1314
- plugin: plugin.name,
1315
- validator: validator.id,
1316
- taskId,
1317
- passed: result.passed,
1318
- summary: result.summary
1319
- });
1320
- } catch (error) {
1321
- const failed = {
1322
- id: validator.id,
1323
- passed: false,
1324
- summary: `${plugin.name}/${validator.id} failed unexpectedly`,
1325
- details: `${error}`
1326
- };
1327
- results.push(failed);
1328
- await this.eventBus.emit("validator.finished", {
1329
- plugin: plugin.name,
1330
- validator: validator.id,
1331
- taskId,
1332
- passed: false,
1333
- summary: failed.summary,
1334
- details: failed.details
1335
- });
1336
- }
1337
- }
1338
- }
1339
- return results;
1122
+ return resolved;
1123
+ }
1124
+ function loadDotEnvSecrets(projectRoot, env = process.env) {
1125
+ const dotenvPath = resolve5(projectRoot, ".env");
1126
+ if (!existsSync5(dotenvPath)) {
1127
+ return {};
1340
1128
  }
1341
- async safeInvoke(pluginName, hook, call) {
1342
- try {
1343
- await call();
1344
- } catch (error) {
1345
- await this.eventBus.emit("plugin.error", {
1346
- plugin: pluginName,
1347
- phase: hook,
1348
- error: `${error}`
1349
- });
1129
+ const parsed = {};
1130
+ const lines = readFileSync3(dotenvPath, "utf-8").split(/\r?\n/);
1131
+ for (const rawLine of lines) {
1132
+ const line = rawLine.trim();
1133
+ if (!line || line.startsWith("#")) {
1134
+ continue;
1350
1135
  }
1351
- }
1352
- async ensureLoaded() {
1353
- if (this.plugins) {
1354
- return this.plugins;
1136
+ const exportMatch = line.match(/^(?:export\s+)?([A-Z0-9_]+)\s*=\s*(.*)$/);
1137
+ if (!exportMatch) {
1138
+ continue;
1355
1139
  }
1356
- if (this.loadPromise) {
1357
- return this.loadPromise;
1140
+ const key = exportMatch[1];
1141
+ if (!(key in BAKED_RUNTIME_SECRETS)) {
1142
+ continue;
1358
1143
  }
1359
- this.loadPromise = this.loadCompiledPlugins();
1360
- try {
1361
- this.plugins = await this.loadPromise;
1362
- return this.plugins;
1363
- } finally {
1364
- this.loadPromise = null;
1365
- }
1366
- }
1367
- resolveBinPath(binName) {
1368
- const candidates = [this.localBinDir].filter(Boolean).map((dir) => resolve6(dir, binName));
1369
- return candidates.find((candidate) => existsSync5(candidate));
1370
- }
1371
- async loadCompiledPlugins() {
1372
- const plugins = [];
1373
- for (const file of this.pluginFiles) {
1374
- const binName = basename2(file).replace(/\.plugin\.(ts|js|mjs|cjs)$/, "");
1375
- let binPath = this.resolveBinPath(binName);
1376
- if (!binPath) {
1377
- const triedPaths = [this.localBinDir].filter(Boolean).map((dir) => resolve6(dir, binName));
1378
- const missingError = `Compiled plugin binary not found for '${binName}'. Tried: ${triedPaths.join(", ")}`;
1379
- await this.eventBus.emit("plugin.error", {
1380
- file: resolve6(this.pluginDir, file),
1381
- phase: "load",
1382
- error: missingError
1383
- });
1384
- if (this.pluginsRequireBinaries) {
1385
- throw new Error(missingError);
1386
- }
1387
- plugins.push({
1388
- name: binName,
1389
- validators: []
1390
- });
1391
- await this.eventBus.emit("plugin.loaded", {
1392
- plugin: binName,
1393
- file: resolve6(this.pluginDir, file),
1394
- source: "metadata-only"
1395
- });
1396
- continue;
1397
- }
1398
- const wrapper = createBinaryPluginWrapper(binName, binPath, this.context.projectRoot);
1399
- plugins.push(wrapper);
1400
- await this.eventBus.emit("plugin.loaded", {
1401
- plugin: wrapper.name,
1402
- file: binPath,
1403
- source: "compiled-binary"
1404
- });
1144
+ const value = expandShellValue(exportMatch[2] ?? "", { ...env, ...parsed });
1145
+ if (value) {
1146
+ parsed[key] = value;
1405
1147
  }
1406
- return plugins;
1407
1148
  }
1149
+ return parsed;
1408
1150
  }
1409
- function createBinaryPluginWrapper(name, binPath, projectRoot) {
1410
- return {
1411
- name,
1412
- validators: [
1413
- {
1414
- id: `${name}:compiled`,
1415
- async run(ctx) {
1416
- const proc = Bun.spawn([binPath, "--validate", ctx.taskId, ctx.projectRoot], {
1417
- cwd: projectRoot,
1418
- stdout: "pipe",
1419
- stderr: "pipe"
1420
- });
1421
- const exitCode = await proc.exited;
1422
- const stdout = await new Response(proc.stdout).text();
1423
- const stderr = await new Response(proc.stderr).text();
1424
- if (exitCode !== 0) {
1425
- return {
1426
- id: `${name}:compiled`,
1427
- passed: false,
1428
- summary: `Plugin binary ${name} exited with code ${exitCode}`,
1429
- details: stderr || stdout
1430
- };
1431
- }
1432
- try {
1433
- const results = JSON.parse(stdout.trim());
1434
- const failed = results.filter((r) => !r.passed);
1435
- if (failed.length > 0) {
1436
- return {
1437
- id: `${name}:compiled`,
1438
- passed: false,
1439
- summary: `${failed.length} of ${results.length} validator(s) failed`,
1440
- details: failed.map((f) => `${f.id}: ${f.summary}`).join(`
1441
- `)
1442
- };
1443
- }
1444
- return {
1445
- id: `${name}:compiled`,
1446
- passed: true,
1447
- summary: `All ${results.length} validator(s) passed`
1448
- };
1449
- } catch {
1450
- return {
1451
- id: `${name}:compiled`,
1452
- passed: false,
1453
- summary: `Failed to parse output from compiled plugin ${name}`,
1454
- details: stdout.slice(0, 500)
1455
- };
1456
- }
1457
- }
1458
- }
1459
- ]
1460
- };
1461
- }
1462
- function safeReadDir(path) {
1463
- try {
1464
- return readdirSync(path, { withFileTypes: true }).filter((entry) => entry.isFile()).map((entry) => entry.name).sort();
1465
- } catch {
1466
- return [];
1151
+ function expandShellValue(rawValue, env) {
1152
+ let value = rawValue.trim();
1153
+ if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
1154
+ value = value.slice(1, -1);
1467
1155
  }
1156
+ return value.replace(/\$\{([A-Z0-9_]+)(:-([^}]*))?\}/g, (_match, name, _defaultGroup, fallback) => {
1157
+ const envValue = env[name]?.trim();
1158
+ if (envValue) {
1159
+ return envValue;
1160
+ }
1161
+ return fallback ?? "";
1162
+ });
1468
1163
  }
1469
1164
 
1470
1165
  // packages/runtime/src/control-plane/runtime/context.ts
1471
- import { existsSync as existsSync6, mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync } from "fs";
1472
- import { dirname as dirname4, resolve as resolve7 } from "path";
1166
+ import { existsSync as existsSync6, mkdirSync as mkdirSync2, readFileSync as readFileSync4, writeFileSync } from "fs";
1167
+ import { dirname as dirname3, resolve as resolve6 } from "path";
1473
1168
  var RUNTIME_CONTEXT_ENV = "RIG_RUNTIME_CONTEXT_FILE";
1474
1169
  var runtimeContextStringFields = [
1475
1170
  "runtimeId",
@@ -1493,13 +1188,13 @@ var runtimeContextOptionalStringFields = [
1493
1188
  "monorepoBaseCommit"
1494
1189
  ];
1495
1190
  function loadRuntimeContext(path) {
1496
- const absPath = resolve7(path);
1191
+ const absPath = resolve6(path);
1497
1192
  if (!existsSync6(absPath)) {
1498
1193
  throw new Error(`RuntimeTaskContext file not found: ${absPath}`);
1499
1194
  }
1500
1195
  let raw;
1501
1196
  try {
1502
- raw = JSON.parse(readFileSync3(absPath, "utf8"));
1197
+ raw = JSON.parse(readFileSync4(absPath, "utf8"));
1503
1198
  } catch (err) {
1504
1199
  throw new Error(`Failed to parse RuntimeTaskContext at ${absPath}: ${String(err)}`);
1505
1200
  }
@@ -1622,13 +1317,13 @@ function loadRuntimeContextFromEnv(env = process.env) {
1622
1317
  return loadRuntimeContext(inferred);
1623
1318
  }
1624
1319
  function findRuntimeContextFile(startPath) {
1625
- let current = resolve7(startPath);
1320
+ let current = resolve6(startPath);
1626
1321
  while (true) {
1627
- const candidate = resolve7(current, "runtime-context.json");
1322
+ const candidate = resolve6(current, "runtime-context.json");
1628
1323
  if (existsSync6(candidate) && isAgentRuntimeContextPath(candidate)) {
1629
1324
  return candidate;
1630
1325
  }
1631
- const parent = dirname4(current);
1326
+ const parent = dirname3(current);
1632
1327
  if (parent === current) {
1633
1328
  return "";
1634
1329
  }
@@ -1640,99 +1335,9 @@ function isAgentRuntimeContextPath(path) {
1640
1335
  return /\/\.rig\/runtime-context\.json$/.test(normalized);
1641
1336
  }
1642
1337
 
1643
- // packages/runtime/src/control-plane/native/git-ops.ts
1644
- import { existsSync as existsSync20, lstatSync, mkdirSync as mkdirSync11, readFileSync as readFileSync11, writeFileSync as writeFileSync11 } from "fs";
1645
- import { dirname as dirname11, isAbsolute as isAbsolute2, resolve as resolve24 } from "path";
1646
- import { fileURLToPath as fileURLToPath2 } from "url";
1647
-
1648
- // packages/runtime/src/control-plane/runtime/baked-secrets.ts
1649
- import { existsSync as existsSync7, readFileSync as readFileSync4 } from "fs";
1650
- import { resolve as resolve8 } from "path";
1651
- var BAKED_RUNTIME_SECRETS = {
1652
- ANTHROPIC_API_KEY: typeof RIG_BAKED_ANTHROPIC_API_KEY !== "undefined" ? RIG_BAKED_ANTHROPIC_API_KEY : "",
1653
- OPENAI_API_KEY: typeof RIG_BAKED_OPENAI_API_KEY !== "undefined" ? RIG_BAKED_OPENAI_API_KEY : "",
1654
- OPENROUTER_API_KEY: typeof RIG_BAKED_OPENROUTER_API_KEY !== "undefined" ? RIG_BAKED_OPENROUTER_API_KEY : "",
1655
- AI_REVIEW_MODE: typeof RIG_BAKED_AI_REVIEW_MODE !== "undefined" ? RIG_BAKED_AI_REVIEW_MODE : "",
1656
- AI_REVIEW_PROVIDER: typeof RIG_BAKED_AI_REVIEW_PROVIDER !== "undefined" ? RIG_BAKED_AI_REVIEW_PROVIDER : "",
1657
- GREPTILE_API_BASE: typeof RIG_BAKED_GREPTILE_API_BASE !== "undefined" ? RIG_BAKED_GREPTILE_API_BASE : "",
1658
- GREPTILE_REMOTE: typeof RIG_BAKED_GREPTILE_REMOTE !== "undefined" ? RIG_BAKED_GREPTILE_REMOTE : "",
1659
- GREPTILE_REPOSITORY: typeof RIG_BAKED_GREPTILE_REPOSITORY !== "undefined" ? RIG_BAKED_GREPTILE_REPOSITORY : "",
1660
- GREPTILE_CONTEXT_BRANCH: typeof RIG_BAKED_GREPTILE_CONTEXT_BRANCH !== "undefined" ? RIG_BAKED_GREPTILE_CONTEXT_BRANCH : "",
1661
- GREPTILE_DEFAULT_BRANCH: typeof RIG_BAKED_GREPTILE_DEFAULT_BRANCH !== "undefined" ? RIG_BAKED_GREPTILE_DEFAULT_BRANCH : "",
1662
- GREPTILE_API_KEY: typeof RIG_BAKED_GREPTILE_API_KEY !== "undefined" ? RIG_BAKED_GREPTILE_API_KEY : "",
1663
- GREPTILE_GITHUB_TOKEN: typeof RIG_BAKED_GREPTILE_GITHUB_TOKEN !== "undefined" ? RIG_BAKED_GREPTILE_GITHUB_TOKEN : "",
1664
- GREPTILE_POLL_ATTEMPTS: typeof RIG_BAKED_GREPTILE_POLL_ATTEMPTS !== "undefined" ? RIG_BAKED_GREPTILE_POLL_ATTEMPTS : "",
1665
- GREPTILE_POLL_INTERVAL_MS: typeof RIG_BAKED_GREPTILE_POLL_INTERVAL_MS !== "undefined" ? RIG_BAKED_GREPTILE_POLL_INTERVAL_MS : "",
1666
- GH_TOKEN: typeof RIG_BAKED_GITHUB_TOKEN !== "undefined" ? RIG_BAKED_GITHUB_TOKEN : "",
1667
- GITHUB_TOKEN: typeof RIG_BAKED_GITHUB_TOKEN !== "undefined" ? RIG_BAKED_GITHUB_TOKEN : "",
1668
- GITHUB_SSH_KEY: typeof RIG_BAKED_GITHUB_SSH_KEY !== "undefined" ? RIG_BAKED_GITHUB_SSH_KEY : "",
1669
- AWS_ACCESS_KEY_ID: typeof RIG_BAKED_AWS_ACCESS_KEY_ID !== "undefined" ? RIG_BAKED_AWS_ACCESS_KEY_ID : "",
1670
- AWS_SECRET_ACCESS_KEY: typeof RIG_BAKED_AWS_SECRET_ACCESS_KEY !== "undefined" ? RIG_BAKED_AWS_SECRET_ACCESS_KEY : "",
1671
- AWS_REGION: typeof RIG_BAKED_AWS_REGION !== "undefined" ? RIG_BAKED_AWS_REGION : "",
1672
- LINEAR_API_KEY: typeof RIG_BAKED_LINEAR_API_KEY !== "undefined" ? RIG_BAKED_LINEAR_API_KEY : "",
1673
- LINEAR_WEBHOOK_SECRET: typeof RIG_BAKED_LINEAR_WEBHOOK_SECRET !== "undefined" ? RIG_BAKED_LINEAR_WEBHOOK_SECRET : ""
1674
- };
1675
- function resolveRuntimeSecrets(env, baked = BAKED_RUNTIME_SECRETS) {
1676
- const resolved = {};
1677
- const keys = new Set([
1678
- ...Object.keys(BAKED_RUNTIME_SECRETS),
1679
- ...Object.keys(baked)
1680
- ]);
1681
- for (const key of keys) {
1682
- const envValue = env[key]?.trim();
1683
- const bakedValue = baked[key]?.trim();
1684
- if (envValue) {
1685
- resolved[key] = envValue;
1686
- } else if (bakedValue) {
1687
- resolved[key] = bakedValue;
1688
- }
1689
- }
1690
- return resolved;
1691
- }
1692
- function loadDotEnvSecrets(projectRoot, env = process.env) {
1693
- const dotenvPath = resolve8(projectRoot, ".env");
1694
- if (!existsSync7(dotenvPath)) {
1695
- return {};
1696
- }
1697
- const parsed = {};
1698
- const lines = readFileSync4(dotenvPath, "utf-8").split(/\r?\n/);
1699
- for (const rawLine of lines) {
1700
- const line = rawLine.trim();
1701
- if (!line || line.startsWith("#")) {
1702
- continue;
1703
- }
1704
- const exportMatch = line.match(/^(?:export\s+)?([A-Z0-9_]+)\s*=\s*(.*)$/);
1705
- if (!exportMatch) {
1706
- continue;
1707
- }
1708
- const key = exportMatch[1];
1709
- if (!(key in BAKED_RUNTIME_SECRETS)) {
1710
- continue;
1711
- }
1712
- const value = expandShellValue(exportMatch[2] ?? "", { ...env, ...parsed });
1713
- if (value) {
1714
- parsed[key] = value;
1715
- }
1716
- }
1717
- return parsed;
1718
- }
1719
- function expandShellValue(rawValue, env) {
1720
- let value = rawValue.trim();
1721
- if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
1722
- value = value.slice(1, -1);
1723
- }
1724
- return value.replace(/\$\{([A-Z0-9_]+)(:-([^}]*))?\}/g, (_match, name, _defaultGroup, fallback) => {
1725
- const envValue = env[name]?.trim();
1726
- if (envValue) {
1727
- return envValue;
1728
- }
1729
- return fallback ?? "";
1730
- });
1731
- }
1732
-
1733
1338
  // packages/runtime/src/control-plane/native/task-ops.ts
1734
- import { appendFileSync, existsSync as existsSync19, mkdirSync as mkdirSync10, readFileSync as readFileSync10, writeFileSync as writeFileSync10 } from "fs";
1735
- import { resolve as resolve23 } from "path";
1339
+ import { appendFileSync, existsSync as existsSync19, mkdirSync as mkdirSync11, readFileSync as readFileSync11, writeFileSync as writeFileSync11 } from "fs";
1340
+ import { resolve as resolve22 } from "path";
1736
1341
 
1737
1342
  // packages/runtime/src/build-time-config.ts
1738
1343
  function normalizeBuildConfig(value) {
@@ -1758,14 +1363,14 @@ function readBuildConfig() {
1758
1363
 
1759
1364
  // packages/runtime/src/control-plane/runtime/tooling/shell.ts
1760
1365
  import { tmpdir as tmpdir2 } from "os";
1761
- import { basename as basename3, dirname as dirname5, resolve as resolve9 } from "path";
1762
- var sharedNativeShellOutputDir = resolve9(tmpdir2(), "rig-native");
1763
- var sharedNativeShellOutputPath = resolve9(sharedNativeShellOutputDir, `rig-shell-${process.platform}-${process.arch}${process.platform === "win32" ? ".exe" : ""}`);
1366
+ import { basename as basename2, dirname as dirname4, resolve as resolve7 } from "path";
1367
+ var sharedNativeShellOutputDir = resolve7(tmpdir2(), "rig-native");
1368
+ var sharedNativeShellOutputPath = resolve7(sharedNativeShellOutputDir, `rig-shell-${process.platform}-${process.arch}${process.platform === "win32" ? ".exe" : ""}`);
1764
1369
  // packages/runtime/src/control-plane/runtime/tooling/file-tools.ts
1765
1370
  import { tmpdir as tmpdir3 } from "os";
1766
- import { basename as basename4, dirname as dirname6, resolve as resolve10 } from "path";
1767
- var sharedNativeToolsOutputDir = resolve10(tmpdir3(), "rig-native");
1768
- var sharedNativeToolsOutputPath = resolve10(sharedNativeToolsOutputDir, `rig-tools-${process.platform}-${process.arch}${process.platform === "win32" ? ".exe" : ""}`);
1371
+ import { basename as basename3, dirname as dirname5, resolve as resolve8 } from "path";
1372
+ var sharedNativeToolsOutputDir = resolve8(tmpdir3(), "rig-native");
1373
+ var sharedNativeToolsOutputPath = resolve8(sharedNativeToolsOutputDir, `rig-tools-${process.platform}-${process.arch}${process.platform === "win32" ? ".exe" : ""}`);
1769
1374
  // packages/runtime/src/control-plane/plugin-host-context.ts
1770
1375
  import { createPluginHost } from "@rig/core";
1771
1376
  import { loadConfig } from "@rig/core/load-config";
@@ -1912,7 +1517,7 @@ function createTaskFieldRegistry(extensions) {
1912
1517
  }
1913
1518
 
1914
1519
  // packages/runtime/src/control-plane/validators/runtime-registration.ts
1915
- import { existsSync as existsSync8 } from "fs";
1520
+ import { existsSync as existsSync7 } from "fs";
1916
1521
  import { join } from "path";
1917
1522
  function createValidatorRegistry() {
1918
1523
  const map = new Map;
@@ -1945,7 +1550,7 @@ function registerBuiltInValidators(registry) {
1945
1550
  }
1946
1551
  async function runStdTypecheck(ctx) {
1947
1552
  const packageJsonPath = join(ctx.workspaceRoot, "package.json");
1948
- if (!existsSync8(packageJsonPath)) {
1553
+ if (!existsSync7(packageJsonPath)) {
1949
1554
  return {
1950
1555
  id: "std:typecheck",
1951
1556
  passed: false,
@@ -1973,8 +1578,8 @@ async function runStdTypecheck(ctx) {
1973
1578
  }
1974
1579
 
1975
1580
  // packages/runtime/src/control-plane/hook-materializer.ts
1976
- import { existsSync as existsSync9, mkdirSync as mkdirSync3, readFileSync as readFileSync5, writeFileSync as writeFileSync2 } from "fs";
1977
- import { dirname as dirname7, resolve as resolve11 } from "path";
1581
+ import { existsSync as existsSync8, mkdirSync as mkdirSync3, readFileSync as readFileSync5, writeFileSync as writeFileSync2 } from "fs";
1582
+ import { dirname as dirname6, resolve as resolve9 } from "path";
1978
1583
  var MARKER_PLUGIN = "_rigPlugin";
1979
1584
  var MARKER_HOOK_ID = "_rigHookId";
1980
1585
  function matcherToString(matcher) {
@@ -1988,8 +1593,8 @@ function isPluginOwned(cmd) {
1988
1593
  return typeof cmd[MARKER_PLUGIN] === "string";
1989
1594
  }
1990
1595
  function materializeHooks(projectRoot, entries) {
1991
- const settingsPath = resolve11(projectRoot, ".claude", "settings.json");
1992
- const existing = existsSync9(settingsPath) ? safeReadJson(settingsPath) : {};
1596
+ const settingsPath = resolve9(projectRoot, ".claude", "settings.json");
1597
+ const existing = existsSync8(settingsPath) ? safeReadJson(settingsPath) : {};
1993
1598
  const hooks = existing.hooks ?? {};
1994
1599
  for (const event of Object.keys(hooks)) {
1995
1600
  const groups = hooks[event] ?? [];
@@ -2031,7 +1636,7 @@ function materializeHooks(projectRoot, entries) {
2031
1636
  } else {
2032
1637
  delete next.hooks;
2033
1638
  }
2034
- mkdirSync3(dirname7(settingsPath), { recursive: true });
1639
+ mkdirSync3(dirname6(settingsPath), { recursive: true });
2035
1640
  writeFileSync2(settingsPath, `${JSON.stringify(next, null, 2)}
2036
1641
  `, "utf-8");
2037
1642
  return settingsPath;
@@ -2044,6 +1649,49 @@ function safeReadJson(path) {
2044
1649
  }
2045
1650
  }
2046
1651
 
1652
+ // packages/runtime/src/control-plane/skill-materializer.ts
1653
+ import { existsSync as existsSync9, mkdirSync as mkdirSync4, readFileSync as readFileSync6, readdirSync, rmSync as rmSync2, writeFileSync as writeFileSync3 } from "fs";
1654
+ import { resolve as resolve10 } from "path";
1655
+ import { loadSkill } from "@rig/skill-loader";
1656
+ var MARKER_FILENAME = ".rig-plugin";
1657
+ function skillDirName(id) {
1658
+ return id.replace(/[^a-zA-Z0-9._-]+/g, "-");
1659
+ }
1660
+ async function materializeSkills(projectRoot, entries) {
1661
+ const skillsRoot = resolve10(projectRoot, ".pi", "skills");
1662
+ if (existsSync9(skillsRoot)) {
1663
+ for (const name of readdirSync(skillsRoot)) {
1664
+ const dir = resolve10(skillsRoot, name);
1665
+ if (existsSync9(resolve10(dir, MARKER_FILENAME))) {
1666
+ rmSync2(dir, { recursive: true, force: true });
1667
+ }
1668
+ }
1669
+ }
1670
+ const written = [];
1671
+ for (const { pluginName, skill } of entries) {
1672
+ const sourcePath = resolve10(projectRoot, skill.path);
1673
+ if (!existsSync9(sourcePath)) {
1674
+ console.warn(`[plugin-host] skill "${skill.id}" from plugin "${pluginName}" not materialized: ${sourcePath} does not exist`);
1675
+ continue;
1676
+ }
1677
+ let body;
1678
+ try {
1679
+ await loadSkill(sourcePath);
1680
+ body = readFileSync6(sourcePath, "utf-8");
1681
+ } catch (err) {
1682
+ console.warn(`[plugin-host] skill "${skill.id}" from plugin "${pluginName}" not materialized: ${err instanceof Error ? err.message : err}`);
1683
+ continue;
1684
+ }
1685
+ const dir = resolve10(skillsRoot, skillDirName(skill.id));
1686
+ mkdirSync4(dir, { recursive: true });
1687
+ writeFileSync3(resolve10(dir, "SKILL.md"), body, "utf-8");
1688
+ writeFileSync3(resolve10(dir, MARKER_FILENAME), `${JSON.stringify({ plugin: pluginName, skillId: skill.id }, null, 2)}
1689
+ `, "utf-8");
1690
+ written.push({ id: skill.id, pluginName, directory: dir });
1691
+ }
1692
+ return written;
1693
+ }
1694
+
2047
1695
  // packages/runtime/src/control-plane/plugin-host-context.ts
2048
1696
  async function buildPluginHostContext(projectRoot) {
2049
1697
  let config;
@@ -2080,6 +1728,17 @@ async function buildPluginHostContext(projectRoot) {
2080
1728
  } catch (err) {
2081
1729
  console.warn(`[plugin-host] hook materialization failed: ${err instanceof Error ? err.message : err}`);
2082
1730
  }
1731
+ try {
1732
+ const skillEntries = config.plugins.flatMap((plugin) => (plugin.contributes?.skills ?? []).map((skill) => ({
1733
+ pluginName: plugin.name,
1734
+ skill
1735
+ })));
1736
+ if (skillEntries.length > 0) {
1737
+ await materializeSkills(projectRoot, skillEntries);
1738
+ }
1739
+ } catch (err) {
1740
+ console.warn(`[plugin-host] skill materialization failed: ${err instanceof Error ? err.message : err}`);
1741
+ }
2083
1742
  return {
2084
1743
  config,
2085
1744
  pluginHost,
@@ -2093,12 +1752,12 @@ async function buildPluginHostContext(projectRoot) {
2093
1752
 
2094
1753
  // packages/runtime/src/control-plane/tasks/source-aware-task-config-source.ts
2095
1754
  import { spawnSync } from "child_process";
2096
- import { existsSync as existsSync11, readFileSync as readFileSync7, readdirSync as readdirSync2, statSync as statSync3, writeFileSync as writeFileSync3 } from "fs";
2097
- import { basename as basename5, join as join2, resolve as resolve13 } from "path";
1755
+ import { existsSync as existsSync11, readFileSync as readFileSync8, readdirSync as readdirSync2, statSync as statSync3, writeFileSync as writeFileSync4 } from "fs";
1756
+ import { basename as basename4, join as join2, resolve as resolve12 } from "path";
2098
1757
 
2099
1758
  // packages/runtime/src/control-plane/tasks/legacy-task-config-source.ts
2100
- import { existsSync as existsSync10, readFileSync as readFileSync6 } from "fs";
2101
- import { resolve as resolve12 } from "path";
1759
+ import { existsSync as existsSync10, readFileSync as readFileSync7 } from "fs";
1760
+ import { resolve as resolve11 } from "path";
2102
1761
 
2103
1762
  // packages/runtime/src/control-plane/tasks/task-record-reader.ts
2104
1763
  async function findTaskById(reader, id) {
@@ -2121,7 +1780,7 @@ class LegacyTaskConfigReadError extends Error {
2121
1780
  }
2122
1781
  }
2123
1782
  function createLegacyTaskConfigRecordReader(projectRoot, options = {}) {
2124
- const configPath = options.configPath ?? resolve12(projectRoot, ".rig", "task-config.json");
1783
+ const configPath = options.configPath ?? resolve11(projectRoot, ".rig", "task-config.json");
2125
1784
  const reader = {
2126
1785
  async listTasks() {
2127
1786
  return readLegacyTaskRecords(projectRoot, configPath);
@@ -2132,7 +1791,7 @@ function createLegacyTaskConfigRecordReader(projectRoot, options = {}) {
2132
1791
  };
2133
1792
  return reader;
2134
1793
  }
2135
- function readLegacyTaskRecords(projectRoot, configPath = resolve12(projectRoot, ".rig", "task-config.json")) {
1794
+ function readLegacyTaskRecords(projectRoot, configPath = resolve11(projectRoot, ".rig", "task-config.json")) {
2136
1795
  if (!existsSync10(configPath)) {
2137
1796
  return [];
2138
1797
  }
@@ -2141,7 +1800,7 @@ function readLegacyTaskRecords(projectRoot, configPath = resolve12(projectRoot,
2141
1800
  }
2142
1801
  function readLegacyTaskConfigJson(projectRoot, configPath) {
2143
1802
  try {
2144
- const parsed = JSON.parse(readFileSync6(configPath, "utf8"));
1803
+ const parsed = JSON.parse(readFileSync7(configPath, "utf8"));
2145
1804
  if (isPlainRecord(parsed)) {
2146
1805
  return parsed;
2147
1806
  }
@@ -2225,7 +1884,7 @@ function isPlainRecord(candidate) {
2225
1884
  var STATUS_LABELS = new Set(["ready", "blocked", "in-progress", "under-review", "failed", "cancelled"]);
2226
1885
  var FILE_TASK_PATTERN = /\.(task\.)?json$/;
2227
1886
  function createSourceAwareTaskConfigRecordReader(projectRoot, options = {}) {
2228
- const configPath = options.configPath ?? resolve13(projectRoot, ".rig", "task-config.json");
1887
+ const configPath = options.configPath ?? resolve12(projectRoot, ".rig", "task-config.json");
2229
1888
  const legacy = createLegacyTaskConfigRecordReader(projectRoot, { configPath });
2230
1889
  const spawnFn = options.spawn ?? spawnSync;
2231
1890
  const ghBinary = options.ghBinary ?? "gh";
@@ -2291,7 +1950,7 @@ async function readSourceAwareTaskStatus(projectRoot, taskId, options = {}) {
2291
1950
  }
2292
1951
  }
2293
1952
  function updateSourceAwareTaskConfigTask(projectRoot, taskId, update, options = {}) {
2294
- const configPath = options.configPath ?? resolve13(projectRoot, ".rig", "task-config.json");
1953
+ const configPath = options.configPath ?? resolve12(projectRoot, ".rig", "task-config.json");
2295
1954
  const rawEntry = readRawTaskEntry(configPath, taskId);
2296
1955
  if (!rawEntry) {
2297
1956
  const configuredFilesPath = readConfiguredFilesTaskSourcePath(projectRoot);
@@ -2344,10 +2003,10 @@ function readMaterializedTaskMetadata(entry) {
2344
2003
  return metadata;
2345
2004
  }
2346
2005
  function readConfiguredFilesTaskSourcePath(projectRoot) {
2347
- const jsonPath = resolve13(projectRoot, "rig.config.json");
2006
+ const jsonPath = resolve12(projectRoot, "rig.config.json");
2348
2007
  if (existsSync11(jsonPath)) {
2349
2008
  try {
2350
- const parsed = JSON.parse(readFileSync7(jsonPath, "utf8"));
2009
+ const parsed = JSON.parse(readFileSync8(jsonPath, "utf8"));
2351
2010
  if (isPlainRecord2(parsed) && isPlainRecord2(parsed.taskSource)) {
2352
2011
  const source = parsed.taskSource;
2353
2012
  return source.kind === "files" && typeof source.path === "string" ? source.path : null;
@@ -2356,12 +2015,12 @@ function readConfiguredFilesTaskSourcePath(projectRoot) {
2356
2015
  return null;
2357
2016
  }
2358
2017
  }
2359
- const tsPath = resolve13(projectRoot, "rig.config.ts");
2018
+ const tsPath = resolve12(projectRoot, "rig.config.ts");
2360
2019
  if (!existsSync11(tsPath)) {
2361
2020
  return null;
2362
2021
  }
2363
2022
  try {
2364
- const source = readFileSync7(tsPath, "utf8");
2023
+ const source = readFileSync8(tsPath, "utf8");
2365
2024
  const taskSourceBlock = source.match(/taskSource\s*:\s*\{[\s\S]*?\}/m)?.[0] ?? "";
2366
2025
  const kind = taskSourceBlock.match(/kind\s*:\s*["']([^"']+)["']/)?.[1];
2367
2026
  if (kind !== "files") {
@@ -2384,7 +2043,7 @@ function readRawTaskConfig(configPath) {
2384
2043
  if (!existsSync11(configPath)) {
2385
2044
  return null;
2386
2045
  }
2387
- const parsed = JSON.parse(readFileSync7(configPath, "utf8"));
2046
+ const parsed = JSON.parse(readFileSync8(configPath, "utf8"));
2388
2047
  return isPlainRecord2(parsed) ? parsed : null;
2389
2048
  }
2390
2049
  function stripLegacyTaskConfigMetadata2(raw) {
@@ -2401,16 +2060,16 @@ function writeLegacyTaskStatus(configPath, taskId, status) {
2401
2060
  return;
2402
2061
  }
2403
2062
  entry.status = status;
2404
- writeFileSync3(configPath, `${JSON.stringify(rawConfig, null, 2)}
2063
+ writeFileSync4(configPath, `${JSON.stringify(rawConfig, null, 2)}
2405
2064
  `, "utf8");
2406
2065
  }
2407
2066
  function updateFileBackedTask(projectRoot, sourcePath, taskId, update) {
2408
- const directory = resolve13(projectRoot, sourcePath);
2067
+ const directory = resolve12(projectRoot, sourcePath);
2409
2068
  const file = findFileBackedTaskFile(directory, taskId);
2410
2069
  if (!file) {
2411
2070
  return false;
2412
2071
  }
2413
- const raw = JSON.parse(readFileSync7(file, "utf8"));
2072
+ const raw = JSON.parse(readFileSync8(file, "utf8"));
2414
2073
  if (!isPlainRecord2(raw)) {
2415
2074
  return false;
2416
2075
  }
@@ -2427,12 +2086,12 @@ function updateFileBackedTask(projectRoot, sourcePath, taskId, update) {
2427
2086
  { body: update.comment, createdAt: new Date().toISOString(), source: "rig" }
2428
2087
  ];
2429
2088
  }
2430
- writeFileSync3(file, `${JSON.stringify(raw, null, 2)}
2089
+ writeFileSync4(file, `${JSON.stringify(raw, null, 2)}
2431
2090
  `, "utf8");
2432
2091
  return true;
2433
2092
  }
2434
2093
  function listFileBackedTasks(projectRoot, sourcePath) {
2435
- const directory = resolve13(projectRoot, sourcePath);
2094
+ const directory = resolve12(projectRoot, sourcePath);
2436
2095
  if (!existsSync11(directory)) {
2437
2096
  return [];
2438
2097
  }
@@ -2440,7 +2099,7 @@ function listFileBackedTasks(projectRoot, sourcePath) {
2440
2099
  for (const name of readdirSync2(directory)) {
2441
2100
  if (!FILE_TASK_PATTERN.test(name))
2442
2101
  continue;
2443
- const inferredId = basename5(name).replace(FILE_TASK_PATTERN, "");
2102
+ const inferredId = basename4(name).replace(FILE_TASK_PATTERN, "");
2444
2103
  const task = readFileBackedTask(projectRoot, sourcePath, inferredId, {});
2445
2104
  if (task)
2446
2105
  tasks.push(task);
@@ -2448,11 +2107,11 @@ function listFileBackedTasks(projectRoot, sourcePath) {
2448
2107
  return tasks;
2449
2108
  }
2450
2109
  function readFileBackedTask(projectRoot, sourcePath, taskId, rawEntry) {
2451
- const file = findFileBackedTaskFile(resolve13(projectRoot, sourcePath), taskId);
2110
+ const file = findFileBackedTaskFile(resolve12(projectRoot, sourcePath), taskId);
2452
2111
  if (!file) {
2453
2112
  return null;
2454
2113
  }
2455
- const raw = JSON.parse(readFileSync7(file, "utf8"));
2114
+ const raw = JSON.parse(readFileSync8(file, "utf8"));
2456
2115
  if (!isPlainRecord2(raw)) {
2457
2116
  return null;
2458
2117
  }
@@ -2475,8 +2134,8 @@ function findFileBackedTaskFile(directory, taskId) {
2475
2134
  try {
2476
2135
  if (!statSync3(file).isFile())
2477
2136
  continue;
2478
- const raw = JSON.parse(readFileSync7(file, "utf8"));
2479
- const inferredId = basename5(file).replace(FILE_TASK_PATTERN, "");
2137
+ const raw = JSON.parse(readFileSync8(file, "utf8"));
2138
+ const inferredId = basename4(file).replace(FILE_TASK_PATTERN, "");
2480
2139
  const id = isPlainRecord2(raw) && typeof raw.id === "string" ? raw.id : inferredId;
2481
2140
  if (id === taskId) {
2482
2141
  return file;
@@ -2824,8 +2483,8 @@ function buildTaskRunLifecycleComment(input) {
2824
2483
  }
2825
2484
 
2826
2485
  // packages/runtime/src/control-plane/native/task-state.ts
2827
- import { existsSync as existsSync13, readFileSync as readFileSync9, readdirSync as readdirSync3, statSync as statSync4, writeFileSync as writeFileSync5 } from "fs";
2828
- import { basename as basename6, resolve as resolve15 } from "path";
2486
+ import { existsSync as existsSync13, readFileSync as readFileSync10, readdirSync as readdirSync3, statSync as statSync4, writeFileSync as writeFileSync6 } from "fs";
2487
+ import { basename as basename5, resolve as resolve14 } from "path";
2829
2488
 
2830
2489
  // packages/runtime/src/control-plane/state-sync/types.ts
2831
2490
  var CANONICAL_TASK_LIFECYCLE_STATUSES = new Set([
@@ -2840,23 +2499,23 @@ var CANONICAL_TASK_LIFECYCLE_STATUSES = new Set([
2840
2499
  "cancelled"
2841
2500
  ]);
2842
2501
  // packages/runtime/src/control-plane/native/git-native.ts
2843
- import { chmodSync, copyFileSync as copyFileSync2, existsSync as existsSync12, mkdirSync as mkdirSync4, readFileSync as readFileSync8, renameSync as renameSync2, rmSync as rmSync2, writeFileSync as writeFileSync4 } from "fs";
2502
+ import { chmodSync, copyFileSync as copyFileSync2, existsSync as existsSync12, mkdirSync as mkdirSync5, readFileSync as readFileSync9, renameSync as renameSync2, rmSync as rmSync3, writeFileSync as writeFileSync5 } from "fs";
2844
2503
  import { tmpdir as tmpdir4 } from "os";
2845
- import { dirname as dirname8, isAbsolute, resolve as resolve14 } from "path";
2504
+ import { dirname as dirname7, isAbsolute, resolve as resolve13 } from "path";
2846
2505
  import { createHash } from "crypto";
2847
- var sharedGitNativeOutputDir = resolve14(tmpdir4(), "rig-native");
2848
- var sharedGitNativeOutputPath = resolve14(sharedGitNativeOutputDir, `rig-git-${process.platform}-${process.arch}${process.platform === "win32" ? ".exe" : ""}`);
2506
+ var sharedGitNativeOutputDir = resolve13(tmpdir4(), "rig-native");
2507
+ var sharedGitNativeOutputPath = resolve13(sharedGitNativeOutputDir, `rig-git-${process.platform}-${process.arch}${process.platform === "win32" ? ".exe" : ""}`);
2849
2508
  var trackerCommandUsageProbe = "usage: rig-git fetch-ref <repo-path> <remote> <branch>";
2850
2509
  function temporaryGitBinaryOutputPath(outputPath) {
2851
2510
  const suffix2 = process.platform === "win32" ? ".exe" : "";
2852
- return resolve14(dirname8(outputPath), `.rig-git-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}${suffix2}`);
2511
+ return resolve13(dirname7(outputPath), `.rig-git-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}${suffix2}`);
2853
2512
  }
2854
2513
  function publishGitBinary(tempOutputPath, outputPath) {
2855
2514
  try {
2856
2515
  renameSync2(tempOutputPath, outputPath);
2857
2516
  } catch (error) {
2858
2517
  if (process.platform === "win32" && existsSync12(outputPath)) {
2859
- rmSync2(outputPath, { force: true });
2518
+ rmSync3(outputPath, { force: true });
2860
2519
  renameSync2(tempOutputPath, outputPath);
2861
2520
  return;
2862
2521
  }
@@ -2867,27 +2526,27 @@ function runtimeRigGitFileName() {
2867
2526
  return `rig-git${process.platform === "win32" ? ".exe" : ""}`;
2868
2527
  }
2869
2528
  function rigGitSourceCandidates() {
2870
- const execDir = process.execPath?.trim() ? dirname8(process.execPath.trim()) : "";
2529
+ const execDir = process.execPath?.trim() ? dirname7(process.execPath.trim()) : "";
2871
2530
  const cwd = process.cwd()?.trim() || "";
2872
2531
  const projectRoot = process.env.PROJECT_RIG_ROOT?.trim() || "";
2873
2532
  const hostProjectRoot = process.env.RIG_HOST_PROJECT_ROOT?.trim() || "";
2874
- const moduleRelativeSource = resolve14(import.meta.dir, "../../../native/rig-git.zig");
2533
+ const moduleRelativeSource = resolve13(import.meta.dir, "../../../native/rig-git.zig");
2875
2534
  return [...new Set([
2876
2535
  process.env.RIG_NATIVE_GIT_SOURCE?.trim() || "",
2877
2536
  moduleRelativeSource,
2878
- projectRoot ? resolve14(projectRoot, "packages/runtime/native/rig-git.zig") : "",
2879
- hostProjectRoot ? resolve14(hostProjectRoot, "packages/runtime/native/rig-git.zig") : "",
2880
- cwd ? resolve14(cwd, "packages/runtime/native/rig-git.zig") : "",
2881
- execDir ? resolve14(execDir, "..", "..", "packages/runtime/native/rig-git.zig") : "",
2882
- execDir ? resolve14(execDir, "..", "native", "rig-git.zig") : ""
2537
+ projectRoot ? resolve13(projectRoot, "packages/runtime/native/rig-git.zig") : "",
2538
+ hostProjectRoot ? resolve13(hostProjectRoot, "packages/runtime/native/rig-git.zig") : "",
2539
+ cwd ? resolve13(cwd, "packages/runtime/native/rig-git.zig") : "",
2540
+ execDir ? resolve13(execDir, "..", "..", "packages/runtime/native/rig-git.zig") : "",
2541
+ execDir ? resolve13(execDir, "..", "native", "rig-git.zig") : ""
2883
2542
  ].filter(Boolean))];
2884
2543
  }
2885
2544
  function nativePackageBinaryCandidates(fromDir, fileName) {
2886
2545
  const candidates = [];
2887
- let cursor = resolve14(fromDir);
2546
+ let cursor = resolve13(fromDir);
2888
2547
  for (let index = 0;index < 8; index += 1) {
2889
- candidates.push(resolve14(cursor, "native", `${process.platform}-${process.arch}`, fileName), resolve14(cursor, "native", `${process.platform}-${process.arch}`, "bin", fileName), resolve14(cursor, "native", fileName), resolve14(cursor, "native", "bin", fileName));
2890
- const parent = dirname8(cursor);
2548
+ candidates.push(resolve13(cursor, "native", `${process.platform}-${process.arch}`, fileName), resolve13(cursor, "native", `${process.platform}-${process.arch}`, "bin", fileName), resolve13(cursor, "native", fileName), resolve13(cursor, "native", "bin", fileName));
2549
+ const parent = dirname7(cursor);
2891
2550
  if (parent === cursor)
2892
2551
  break;
2893
2552
  cursor = parent;
@@ -2895,15 +2554,15 @@ function nativePackageBinaryCandidates(fromDir, fileName) {
2895
2554
  return candidates;
2896
2555
  }
2897
2556
  function rigGitBinaryCandidates() {
2898
- const execDir = process.execPath?.trim() ? dirname8(process.execPath.trim()) : "";
2557
+ const execDir = process.execPath?.trim() ? dirname7(process.execPath.trim()) : "";
2899
2558
  const fileName = runtimeRigGitFileName();
2900
2559
  const explicit = process.env.RIG_NATIVE_GIT_BIN?.trim() || "";
2901
2560
  return [...new Set([
2902
2561
  explicit,
2903
2562
  ...nativePackageBinaryCandidates(import.meta.dir, fileName),
2904
- execDir ? resolve14(execDir, fileName) : "",
2905
- execDir ? resolve14(execDir, "..", fileName) : "",
2906
- execDir ? resolve14(execDir, "..", "bin", fileName) : "",
2563
+ execDir ? resolve13(execDir, fileName) : "",
2564
+ execDir ? resolve13(execDir, "..", fileName) : "",
2565
+ execDir ? resolve13(execDir, "..", "bin", fileName) : "",
2907
2566
  sharedGitNativeOutputPath
2908
2567
  ].filter(Boolean))];
2909
2568
  }
@@ -2954,14 +2613,14 @@ function hasMatchingNativeBuildManifestSync(manifestPath, buildKey) {
2954
2613
  return false;
2955
2614
  }
2956
2615
  try {
2957
- const manifest = JSON.parse(readFileSync8(manifestPath, "utf8"));
2616
+ const manifest = JSON.parse(readFileSync9(manifestPath, "utf8"));
2958
2617
  return manifest.version === 1 && manifest.buildKey === buildKey;
2959
2618
  } catch {
2960
2619
  return false;
2961
2620
  }
2962
2621
  }
2963
2622
  function sha256FileSync(path) {
2964
- return createHash("sha256").update(readFileSync8(path)).digest("hex");
2623
+ return createHash("sha256").update(readFileSync9(path)).digest("hex");
2965
2624
  }
2966
2625
  function ensureRigGitBinaryPathSync(outputPath = preferredGitBinaryOutputPath()) {
2967
2626
  if (process.env.RIG_DISABLE_ZIG_NATIVE === "1") {
@@ -2979,7 +2638,7 @@ function ensureRigGitBinaryPathSync(outputPath = preferredGitBinaryOutputPath())
2979
2638
  if (!zigBinary) {
2980
2639
  throw new Error("zig is required to build native Rig git tools.");
2981
2640
  }
2982
- mkdirSync4(dirname8(outputPath), { recursive: true });
2641
+ mkdirSync5(dirname7(outputPath), { recursive: true });
2983
2642
  const sourceDigest = sha256FileSync(sourcePath);
2984
2643
  const buildKey = JSON.stringify({
2985
2644
  version: 1,
@@ -3004,7 +2663,7 @@ function ensureRigGitBinaryPathSync(outputPath = preferredGitBinaryOutputPath())
3004
2663
  "ReleaseFast",
3005
2664
  `-femit-bin=${tempOutputPath}`
3006
2665
  ], {
3007
- cwd: dirname8(sourcePath),
2666
+ cwd: dirname7(sourcePath),
3008
2667
  stdout: "pipe",
3009
2668
  stderr: "pipe"
3010
2669
  });
@@ -3017,16 +2676,16 @@ function ensureRigGitBinaryPathSync(outputPath = preferredGitBinaryOutputPath())
3017
2676
  }
3018
2677
  chmodSync(tempOutputPath, 493);
3019
2678
  if (existsSync12(outputPath) && hasMatchingNativeBuildManifestSync(manifestPath, buildKey)) {
3020
- rmSync2(tempOutputPath, { force: true });
2679
+ rmSync3(tempOutputPath, { force: true });
3021
2680
  chmodSync(outputPath, 493);
3022
2681
  return outputPath;
3023
2682
  }
3024
2683
  publishGitBinary(tempOutputPath, outputPath);
3025
2684
  if (!binarySupportsTrackerCommandsSync(outputPath)) {
3026
- rmSync2(outputPath, { force: true });
2685
+ rmSync3(outputPath, { force: true });
3027
2686
  throw new Error("Failed to build native Rig git tools: tracker command probe failed");
3028
2687
  }
3029
- writeFileSync4(manifestPath, `${JSON.stringify({ version: 1, buildKey }, null, 2)}
2688
+ writeFileSync5(manifestPath, `${JSON.stringify({ version: 1, buildKey }, null, 2)}
3030
2689
  `, "utf8");
3031
2690
  return outputPath;
3032
2691
  }
@@ -3135,7 +2794,7 @@ function readValidationDescriptions(projectRoot) {
3135
2794
  return readValidationDescriptionMap(raw);
3136
2795
  }
3137
2796
  function readSourceValidationDescriptions(projectRoot) {
3138
- const rootRaw = readJsonFile(resolve15(projectRoot, "rig", "task-config.json"), {});
2797
+ const rootRaw = readJsonFile(resolve14(projectRoot, "rig", "task-config.json"), {});
3139
2798
  const sourcePath = findSourceTaskConfigPath(projectRoot);
3140
2799
  const sourceRaw = sourcePath ? readJsonFile(sourcePath, {}) : {};
3141
2800
  const rootDescriptions = readValidationDescriptionMap(rootRaw);
@@ -3226,16 +2885,16 @@ function lookupTask(projectRoot, input) {
3226
2885
  function artifactDirForId(projectRoot, id) {
3227
2886
  const workspaceDir = process.env.RIG_TASK_WORKSPACE?.trim();
3228
2887
  if (workspaceDir) {
3229
- const worktreeArtifacts = resolve15(workspaceDir, "artifacts", id);
3230
- if (existsSync13(worktreeArtifacts) || existsSync13(resolve15(workspaceDir, "artifacts"))) {
2888
+ const worktreeArtifacts = resolve14(workspaceDir, "artifacts", id);
2889
+ if (existsSync13(worktreeArtifacts) || existsSync13(resolve14(workspaceDir, "artifacts"))) {
3231
2890
  return worktreeArtifacts;
3232
2891
  }
3233
2892
  }
3234
2893
  try {
3235
2894
  const paths = resolveHarnessPaths(projectRoot);
3236
- return resolve15(paths.artifactsDir, id);
2895
+ return resolve14(paths.artifactsDir, id);
3237
2896
  } catch {
3238
- return resolve15(resolveMonorepoRoot2(projectRoot), "artifacts", id);
2897
+ return resolve14(resolveMonorepoRoot2(projectRoot), "artifacts", id);
3239
2898
  }
3240
2899
  }
3241
2900
  function resolveTaskConfigPath(projectRoot) {
@@ -3265,7 +2924,7 @@ function readAndSyncSourceTaskConfig(projectRoot) {
3265
2924
  const synced = synchronizeTaskConfigWithTracker(projectRoot, raw);
3266
2925
  if (sourcePath && synced.updated) {
3267
2926
  try {
3268
- writeFileSync5(sourcePath, `${JSON.stringify(synced.config, null, 2)}
2927
+ writeFileSync6(sourcePath, `${JSON.stringify(synced.config, null, 2)}
3269
2928
  `, "utf-8");
3270
2929
  } catch {}
3271
2930
  }
@@ -3317,12 +2976,12 @@ function shouldRefreshAutoSyncedTaskConfigEntry(entry) {
3317
2976
  return !candidate.role;
3318
2977
  }
3319
2978
  function readSourceIssueRecords(projectRoot) {
3320
- const issuesPath = resolve15(resolveMonorepoRoot2(projectRoot), ".beads", "issues.jsonl");
2979
+ const issuesPath = resolve14(resolveMonorepoRoot2(projectRoot), ".beads", "issues.jsonl");
3321
2980
  if (!existsSync13(issuesPath)) {
3322
2981
  return [];
3323
2982
  }
3324
2983
  const records = [];
3325
- for (const line of readFileSync9(issuesPath, "utf-8").split(/\r?\n/)) {
2984
+ for (const line of readFileSync10(issuesPath, "utf-8").split(/\r?\n/)) {
3326
2985
  const trimmed = line.trim();
3327
2986
  if (!trimmed) {
3328
2987
  continue;
@@ -3378,7 +3037,7 @@ function readConfiguredFileTaskConfig(projectRoot) {
3378
3037
  if (!sourcePath) {
3379
3038
  return {};
3380
3039
  }
3381
- const directory = resolve15(projectRoot, sourcePath);
3040
+ const directory = resolve14(projectRoot, sourcePath);
3382
3041
  if (!existsSync13(directory)) {
3383
3042
  return {};
3384
3043
  }
@@ -3386,15 +3045,15 @@ function readConfiguredFileTaskConfig(projectRoot) {
3386
3045
  for (const name of readdirSync3(directory)) {
3387
3046
  if (!FILE_TASK_PATTERN2.test(name))
3388
3047
  continue;
3389
- const file = resolve15(directory, name);
3048
+ const file = resolve14(directory, name);
3390
3049
  try {
3391
3050
  if (!statSync4(file).isFile())
3392
3051
  continue;
3393
- const raw = JSON.parse(readFileSync9(file, "utf8"));
3052
+ const raw = JSON.parse(readFileSync10(file, "utf8"));
3394
3053
  if (!raw || typeof raw !== "object" || Array.isArray(raw))
3395
3054
  continue;
3396
3055
  const record = raw;
3397
- const inferredId = basename6(name).replace(FILE_TASK_PATTERN2, "");
3056
+ const inferredId = basename5(name).replace(FILE_TASK_PATTERN2, "");
3398
3057
  const id = typeof record.id === "string" && record.id.trim().length > 0 ? record.id.trim() : inferredId;
3399
3058
  config[id] = fileTaskToConfigEntry(record, { kind: "files", path: sourcePath });
3400
3059
  } catch {}
@@ -3432,10 +3091,10 @@ function firstStringList2(...candidates) {
3432
3091
  return [];
3433
3092
  }
3434
3093
  function readConfiguredFilesTaskSourcePath2(projectRoot) {
3435
- const jsonPath = resolve15(projectRoot, "rig.config.json");
3094
+ const jsonPath = resolve14(projectRoot, "rig.config.json");
3436
3095
  if (existsSync13(jsonPath)) {
3437
3096
  try {
3438
- const parsed = JSON.parse(readFileSync9(jsonPath, "utf8"));
3097
+ const parsed = JSON.parse(readFileSync10(jsonPath, "utf8"));
3439
3098
  if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
3440
3099
  const taskSource = parsed.taskSource;
3441
3100
  if (taskSource && typeof taskSource === "object" && !Array.isArray(taskSource)) {
@@ -3447,12 +3106,12 @@ function readConfiguredFilesTaskSourcePath2(projectRoot) {
3447
3106
  return null;
3448
3107
  }
3449
3108
  }
3450
- const tsPath = resolve15(projectRoot, "rig.config.ts");
3109
+ const tsPath = resolve14(projectRoot, "rig.config.ts");
3451
3110
  if (!existsSync13(tsPath)) {
3452
3111
  return null;
3453
3112
  }
3454
3113
  try {
3455
- const source = readFileSync9(tsPath, "utf8");
3114
+ const source = readFileSync10(tsPath, "utf8");
3456
3115
  const taskSourceBlock = source.match(/taskSource\s*:\s*\{[\s\S]*?\}/m)?.[0] ?? "";
3457
3116
  const kind = taskSourceBlock.match(/kind\s*:\s*["']([^"']+)["']/)?.[1];
3458
3117
  if (kind !== "files") {
@@ -3466,23 +3125,23 @@ function readConfiguredFilesTaskSourcePath2(projectRoot) {
3466
3125
  function sourceTaskConfigCandidates(projectRoot) {
3467
3126
  const runtimeContext = loadRuntimeContextFromEnv();
3468
3127
  return [
3469
- runtimeContext?.monorepoMainRoot ? resolve15(runtimeContext.monorepoMainRoot, ".rig", "task-config.json") : "",
3470
- process.env.MONOREPO_MAIN_ROOT?.trim() ? resolve15(process.env.MONOREPO_MAIN_ROOT.trim(), ".rig", "task-config.json") : "",
3471
- resolve15(resolveMonorepoRoot2(projectRoot), ".rig", "task-config.json")
3128
+ runtimeContext?.monorepoMainRoot ? resolve14(runtimeContext.monorepoMainRoot, ".rig", "task-config.json") : "",
3129
+ process.env.MONOREPO_MAIN_ROOT?.trim() ? resolve14(process.env.MONOREPO_MAIN_ROOT.trim(), ".rig", "task-config.json") : "",
3130
+ resolve14(resolveMonorepoRoot2(projectRoot), ".rig", "task-config.json")
3472
3131
  ].filter(Boolean);
3473
3132
  }
3474
3133
 
3475
3134
  // packages/runtime/src/control-plane/native/validator.ts
3476
- import { existsSync as existsSync17, mkdirSync as mkdirSync7, writeFileSync as writeFileSync7 } from "fs";
3477
- import { resolve as resolve20 } from "path";
3135
+ import { existsSync as existsSync17, mkdirSync as mkdirSync8, writeFileSync as writeFileSync8 } from "fs";
3136
+ import { resolve as resolve19 } from "path";
3478
3137
 
3479
3138
  // packages/runtime/src/control-plane/native/validator-binaries.ts
3480
- import { existsSync as existsSync16, mkdirSync as mkdirSync6, rmSync as rmSync4, statSync as statSync5 } from "fs";
3481
- import { dirname as dirname10, resolve as resolve19 } from "path";
3139
+ import { existsSync as existsSync16, mkdirSync as mkdirSync7, rmSync as rmSync5, statSync as statSync5 } from "fs";
3140
+ import { dirname as dirname9, resolve as resolve18 } from "path";
3482
3141
 
3483
3142
  // packages/runtime/src/binary-run.ts
3484
- import { chmodSync as chmodSync2, cpSync, existsSync as existsSync14, mkdirSync as mkdirSync5, renameSync as renameSync3, rmSync as rmSync3, writeFileSync as writeFileSync6 } from "fs";
3485
- import { basename as basename7, dirname as dirname9, resolve as resolve16 } from "path";
3143
+ import { chmodSync as chmodSync2, cpSync, existsSync as existsSync14, mkdirSync as mkdirSync6, renameSync as renameSync3, rmSync as rmSync4, writeFileSync as writeFileSync7 } from "fs";
3144
+ import { basename as basename6, dirname as dirname8, resolve as resolve15 } from "path";
3486
3145
  import { fileURLToPath } from "url";
3487
3146
  import { drainMicrotasks, gcAndSweep } from "bun:jsc";
3488
3147
  var runtimeBinaryBuildQueue = Promise.resolve();
@@ -3508,9 +3167,9 @@ async function buildRuntimeBinary(options) {
3508
3167
  });
3509
3168
  }
3510
3169
  async function buildRuntimeBinaryInProcess(options, manifest) {
3511
- const tempBuildDir = resolve16(dirname9(options.outputPath), `.bun-build-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`);
3512
- const tempOutputPath = resolve16(tempBuildDir, basename7(options.outputPath));
3513
- mkdirSync5(tempBuildDir, { recursive: true });
3170
+ const tempBuildDir = resolve15(dirname8(options.outputPath), `.bun-build-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`);
3171
+ const tempOutputPath = resolve15(tempBuildDir, basename6(options.outputPath));
3172
+ mkdirSync6(tempBuildDir, { recursive: true });
3514
3173
  await withTemporaryEnv({
3515
3174
  ...options.env,
3516
3175
  ...options.define ? { RIG_BUILD_CONFIG_JSON: JSON.stringify(options.define) } : {}
@@ -3550,7 +3209,7 @@ async function buildRuntimeBinaryInProcess(options, manifest) {
3550
3209
  });
3551
3210
  }
3552
3211
  })).finally(() => {
3553
- rmSync3(tempBuildDir, { recursive: true, force: true });
3212
+ rmSync4(tempBuildDir, { recursive: true, force: true });
3554
3213
  });
3555
3214
  }
3556
3215
  function runBestEffortBuildGc() {
@@ -3567,8 +3226,8 @@ function runtimeBinaryCacheManifestPath(outputPath) {
3567
3226
  function resolveRuntimeBinaryBuildOptions(options) {
3568
3227
  return {
3569
3228
  ...options,
3570
- entrypoint: resolve16(options.cwd, options.sourcePath),
3571
- outputPath: resolve16(options.outputPath)
3229
+ entrypoint: resolve15(options.cwd, options.sourcePath),
3230
+ outputPath: resolve15(options.outputPath)
3572
3231
  };
3573
3232
  }
3574
3233
  function shouldUseRuntimeBinaryBuildWorker() {
@@ -3613,13 +3272,13 @@ async function buildRuntimeBinaryViaWorker(options) {
3613
3272
  new Response(build.stdout).text(),
3614
3273
  new Response(build.stderr).text()
3615
3274
  ]);
3616
- rmSync3(payloadPath, { force: true });
3275
+ rmSync4(payloadPath, { force: true });
3617
3276
  if (exitCode !== 0) {
3618
3277
  throw new Error(`Failed to build ${options.entrypoint}: ${(stderr || stdout || `worker exited ${exitCode}`).trim()}`);
3619
3278
  }
3620
3279
  }
3621
3280
  function createRuntimeBinaryBuildWorkerPayloadPath(outputPath) {
3622
- return resolve16(dirname9(outputPath), `.bun-build-worker-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`);
3281
+ return resolve15(dirname8(outputPath), `.bun-build-worker-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`);
3623
3282
  }
3624
3283
  function resolveRuntimeBinaryBuildWorkerSourcePath(options) {
3625
3284
  const envRoots = [
@@ -3628,12 +3287,12 @@ function resolveRuntimeBinaryBuildWorkerSourcePath(options) {
3628
3287
  process.env.PROJECT_RIG_ROOT?.trim()
3629
3288
  ].filter(Boolean);
3630
3289
  for (const root of envRoots) {
3631
- const candidate = resolve16(root, "packages/runtime/src/binary-build-worker.ts");
3290
+ const candidate = resolve15(root, "packages/runtime/src/binary-build-worker.ts");
3632
3291
  if (existsSync14(candidate)) {
3633
3292
  return candidate;
3634
3293
  }
3635
3294
  }
3636
- const localCandidate = resolve16(import.meta.dir, "binary-build-worker.ts");
3295
+ const localCandidate = resolve15(import.meta.dir, "binary-build-worker.ts");
3637
3296
  return existsSync14(localCandidate) ? localCandidate : null;
3638
3297
  }
3639
3298
  function resolveRuntimeBinaryBuildWorkerInvocation() {
@@ -3719,7 +3378,7 @@ function normalizeBuildInputPath(cwd, inputPath) {
3719
3378
  if (inputPath.startsWith("<")) {
3720
3379
  return null;
3721
3380
  }
3722
- return resolve16(cwd, inputPath);
3381
+ return resolve15(cwd, inputPath);
3723
3382
  }
3724
3383
  async function sha256File(path) {
3725
3384
  const hasher = new Bun.CryptoHasher("sha256");
@@ -3735,8 +3394,8 @@ function sortRecord(value) {
3735
3394
  async function runSerializedRuntimeBinaryBuild(action) {
3736
3395
  const previous = runtimeBinaryBuildQueue;
3737
3396
  let release;
3738
- runtimeBinaryBuildQueue = new Promise((resolve17) => {
3739
- release = resolve17;
3397
+ runtimeBinaryBuildQueue = new Promise((resolve16) => {
3398
+ release = resolve16;
3740
3399
  });
3741
3400
  await previous;
3742
3401
  try {
@@ -3781,11 +3440,11 @@ async function withTemporaryCwd(cwd, action) {
3781
3440
  }
3782
3441
 
3783
3442
  // packages/runtime/src/control-plane/runtime/provisioning-env.ts
3784
- import { delimiter, resolve as resolve18 } from "path";
3443
+ import { delimiter, resolve as resolve17 } from "path";
3785
3444
 
3786
3445
  // packages/runtime/src/control-plane/runtime/runtime-paths.ts
3787
3446
  import { existsSync as existsSync15, readdirSync as readdirSync4, realpathSync } from "fs";
3788
- import { resolve as resolve17 } from "path";
3447
+ import { resolve as resolve16 } from "path";
3789
3448
 
3790
3449
  // packages/runtime/src/control-plane/runtime/sandbox/utils.ts
3791
3450
  function uniq(values) {
@@ -3803,7 +3462,7 @@ function resolveBunBinaryPath() {
3803
3462
  }
3804
3463
  const home = process.env.HOME?.trim();
3805
3464
  const fallbackCandidates = [
3806
- home ? resolve17(home, ".bun/bin/bun") : "",
3465
+ home ? resolve16(home, ".bun/bin/bun") : "",
3807
3466
  "/opt/homebrew/bin/bun",
3808
3467
  "/usr/local/bin/bun",
3809
3468
  "/usr/bin/bun"
@@ -3831,8 +3490,8 @@ function resolveClaudeBinaryPath() {
3831
3490
  }
3832
3491
  const home = process.env.HOME?.trim();
3833
3492
  const fallbackCandidates = [
3834
- home ? resolve17(home, ".local/bin/claude") : "",
3835
- home ? resolve17(home, ".local/share/claude/local/claude") : "",
3493
+ home ? resolve16(home, ".local/bin/claude") : "",
3494
+ home ? resolve16(home, ".local/share/claude/local/claude") : "",
3836
3495
  "/opt/homebrew/bin/claude",
3837
3496
  "/usr/local/bin/claude",
3838
3497
  "/usr/bin/claude"
@@ -3846,51 +3505,51 @@ function resolveClaudeBinaryPath() {
3846
3505
  throw new Error("claude not found in PATH");
3847
3506
  }
3848
3507
  function resolveBunInstallDir(bunBinaryPath = resolveBunBinaryPath()) {
3849
- return resolve17(bunBinaryPath, "../..");
3508
+ return resolve16(bunBinaryPath, "../..");
3850
3509
  }
3851
3510
  function resolveClaudeInstallDir() {
3852
3511
  const realPath = resolveClaudeBinaryPath();
3853
- return resolve17(realPath, "..");
3512
+ return resolve16(realPath, "..");
3854
3513
  }
3855
3514
  function resolveNodeInstallDir() {
3856
3515
  const preferredNode = resolvePreferredNodeBinary();
3857
3516
  if (!preferredNode)
3858
3517
  return null;
3859
3518
  const explicitNode = process.env.RIG_NODE_BIN?.trim();
3860
- if (explicitNode && resolve17(explicitNode) === resolve17(preferredNode)) {
3861
- return preferredNode.endsWith("/bin/node") ? resolve17(preferredNode, "../..") : resolve17(preferredNode, "..");
3519
+ if (explicitNode && resolve16(explicitNode) === resolve16(preferredNode)) {
3520
+ return preferredNode.endsWith("/bin/node") ? resolve16(preferredNode, "../..") : resolve16(preferredNode, "..");
3862
3521
  }
3863
3522
  try {
3864
3523
  const realPath = realpathSync(preferredNode);
3865
3524
  if (realPath.endsWith("/bin/node")) {
3866
- return resolve17(realPath, "../..");
3525
+ return resolve16(realPath, "../..");
3867
3526
  }
3868
- return resolve17(realPath, "..");
3527
+ return resolve16(realPath, "..");
3869
3528
  } catch {
3870
- return resolve17(preferredNode, "..");
3529
+ return resolve16(preferredNode, "..");
3871
3530
  }
3872
3531
  }
3873
3532
  function resolvePreferredNodeBinary() {
3874
3533
  const candidates = [];
3875
3534
  const envNode = process.env.RIG_NODE_BIN?.trim();
3876
3535
  if (envNode) {
3877
- const explicit = resolve17(envNode);
3536
+ const explicit = resolve16(envNode);
3878
3537
  if (existsSync15(explicit)) {
3879
3538
  return explicit;
3880
3539
  }
3881
3540
  }
3882
3541
  const nvmBin = process.env.NVM_BIN?.trim();
3883
3542
  if (nvmBin) {
3884
- candidates.push(resolve17(nvmBin, "node"));
3543
+ candidates.push(resolve16(nvmBin, "node"));
3885
3544
  }
3886
3545
  const home = process.env.HOME?.trim();
3887
3546
  if (home) {
3888
- const nvmVersionsDir = resolve17(home, ".nvm/versions/node");
3547
+ const nvmVersionsDir = resolve16(home, ".nvm/versions/node");
3889
3548
  if (existsSync15(nvmVersionsDir)) {
3890
3549
  try {
3891
3550
  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/, "")));
3892
3551
  for (const versionDir of versionDirs) {
3893
- candidates.push(resolve17(nvmVersionsDir, versionDir, "bin/node"));
3552
+ candidates.push(resolve16(nvmVersionsDir, versionDir, "bin/node"));
3894
3553
  }
3895
3554
  } catch {}
3896
3555
  }
@@ -3899,7 +3558,7 @@ function resolvePreferredNodeBinary() {
3899
3558
  if (whichNode) {
3900
3559
  candidates.push(whichNode);
3901
3560
  }
3902
- const deduped = uniq(candidates.map((candidate) => resolve17(candidate)));
3561
+ const deduped = uniq(candidates.map((candidate) => resolve16(candidate)));
3903
3562
  const existing = deduped.filter((candidate) => existsSync15(candidate));
3904
3563
  if (existing.length === 0) {
3905
3564
  return null;
@@ -3914,7 +3573,7 @@ function resolvePreferredNodeBinary() {
3914
3573
  return existing[0] ?? null;
3915
3574
  }
3916
3575
  function inferNodeMajor(nodeBinaryPath) {
3917
- const normalized = resolve17(nodeBinaryPath).replace(/\\/g, "/");
3576
+ const normalized = resolve16(nodeBinaryPath).replace(/\\/g, "/");
3918
3577
  const match = normalized.match(/(?:^|\/)(?:node-)?v?(\d+)\.\d+\.\d+(?:\/|$)/);
3919
3578
  if (!match) {
3920
3579
  return null;
@@ -3926,7 +3585,7 @@ function normalizeExecutablePath(candidate) {
3926
3585
  if (!candidate) {
3927
3586
  return "";
3928
3587
  }
3929
- const normalized = resolve17(candidate);
3588
+ const normalized = resolve16(candidate);
3930
3589
  if (!existsSync15(normalized)) {
3931
3590
  return "";
3932
3591
  }
@@ -3937,7 +3596,7 @@ function normalizeExecutablePath(candidate) {
3937
3596
  }
3938
3597
  }
3939
3598
  function looksLikeRuntimeGateway(candidate) {
3940
- const normalized = resolve17(candidate).replace(/\\/g, "/");
3599
+ const normalized = resolve16(candidate).replace(/\\/g, "/");
3941
3600
  return normalized.includes("/.rig/bin/") || normalized.endsWith("/rig-shell") || normalized.endsWith("/rig-agent");
3942
3601
  }
3943
3602
 
@@ -3958,7 +3617,7 @@ function runtimeProvisioningEnv(baseEnv = process.env) {
3958
3617
  try {
3959
3618
  return resolveClaudeInstallDir();
3960
3619
  } catch {
3961
- return resolve18(claudeBinary, "..");
3620
+ return resolve17(claudeBinary, "..");
3962
3621
  }
3963
3622
  })() : "";
3964
3623
  const nodeDir = resolveNodeInstallDir();
@@ -3968,8 +3627,8 @@ function runtimeProvisioningEnv(baseEnv = process.env) {
3968
3627
  `${bunDir}/bin`,
3969
3628
  claudeDir,
3970
3629
  nodeDir ? `${nodeDir}/bin` : "",
3971
- realHome ? resolve18(realHome, ".local/bin") : "",
3972
- realHome ? resolve18(realHome, ".cargo/bin") : "",
3630
+ realHome ? resolve17(realHome, ".local/bin") : "",
3631
+ realHome ? resolve17(realHome, ".cargo/bin") : "",
3973
3632
  ...inheritedPath,
3974
3633
  "/usr/local/bin",
3975
3634
  "/usr/local/sbin",
@@ -4000,9 +3659,9 @@ function runtimeProvisioningEnv(baseEnv = process.env) {
4000
3659
  // packages/runtime/src/control-plane/native/validator-binaries.ts
4001
3660
  function resolveValidatorBinaryPath(projectRoot, binaryName, runtimeContext) {
4002
3661
  if (runtimeContext) {
4003
- return resolve19(runtimeContext.binDir, "validators", binaryName);
3662
+ return resolve18(runtimeContext.binDir, "validators", binaryName);
4004
3663
  }
4005
- return resolve19(resolveHarnessPaths(projectRoot).binDir, "validators", binaryName);
3664
+ return resolve18(resolveHarnessPaths(projectRoot).binDir, "validators", binaryName);
4006
3665
  }
4007
3666
  async function ensureValidatorBinary(projectRoot, checkId, runtimeContext) {
4008
3667
  const match = checkId.match(/^([a-z][\w-]*):([a-z][\w-]*)$/);
@@ -4017,7 +3676,7 @@ async function ensureValidatorBinary(projectRoot, checkId, runtimeContext) {
4017
3676
  const binaryName = `${category}-${check}`;
4018
3677
  const binaryPath = resolveValidatorBinaryPath(projectRoot, binaryName, runtimeContext);
4019
3678
  const hostProjectRoot = runtimeContext?.hostProjectRoot?.trim() || projectRoot;
4020
- const sourcePath = resolve19(hostProjectRoot, "packages/runtime/src/control-plane/validators", category, `${check}.ts`);
3679
+ const sourcePath = resolve18(hostProjectRoot, "packages/runtime/src/control-plane/validators", category, `${check}.ts`);
4021
3680
  if (!existsSync16(sourcePath)) {
4022
3681
  return null;
4023
3682
  }
@@ -4026,10 +3685,10 @@ async function ensureValidatorBinary(projectRoot, checkId, runtimeContext) {
4026
3685
  const binaryMtime = binaryExists ? statSync5(binaryPath).mtimeMs : 0;
4027
3686
  if (!binaryExists || sourceMtime > binaryMtime) {
4028
3687
  if (binaryExists) {
4029
- rmSync4(binaryPath, { force: true });
4030
- rmSync4(`${binaryPath}.build-manifest.json`, { force: true });
3688
+ rmSync5(binaryPath, { force: true });
3689
+ rmSync5(`${binaryPath}.build-manifest.json`, { force: true });
4031
3690
  }
4032
- mkdirSync6(dirname10(binaryPath), { recursive: true });
3691
+ mkdirSync7(dirname9(binaryPath), { recursive: true });
4033
3692
  await buildRuntimeBinary({
4034
3693
  sourcePath: `packages/runtime/src/control-plane/validators/${category}/${check}.ts`,
4035
3694
  outputPath: binaryPath,
@@ -4075,14 +3734,14 @@ async function readTaskSourceValidation(projectRoot, taskId) {
4075
3734
  function resolveValidationPaths(projectRoot, taskId, runtimeContext) {
4076
3735
  if (runtimeContext) {
4077
3736
  return {
4078
- taskLogDir: resolve20(runtimeContext.logsDir, taskId),
4079
- artifactDir: resolve20(runtimeContext.workspaceDir, "artifacts", taskId)
3737
+ taskLogDir: resolve19(runtimeContext.logsDir, taskId),
3738
+ artifactDir: resolve19(runtimeContext.workspaceDir, "artifacts", taskId)
4080
3739
  };
4081
3740
  }
4082
3741
  const paths = resolveHarnessPaths(projectRoot);
4083
3742
  return {
4084
- taskLogDir: resolve20(paths.logsDir, taskId),
4085
- artifactDir: resolve20(paths.artifactsDir, taskId)
3743
+ taskLogDir: resolve19(paths.logsDir, taskId),
3744
+ artifactDir: resolve19(paths.artifactsDir, taskId)
4086
3745
  };
4087
3746
  }
4088
3747
  async function runValidatorBinary(projectRoot, taskId, checkId, runtimeContext) {
@@ -4099,7 +3758,7 @@ async function runValidatorBinary(projectRoot, taskId, checkId, runtimeContext)
4099
3758
  };
4100
3759
  }
4101
3760
  const validatorCwd = runtimeContext?.workspaceDir || resolveMonorepoRoot(projectRoot);
4102
- const runtimeShellPath = runtimeContext ? resolve20(runtimeContext.binDir, "rig-shell") : "";
3761
+ const runtimeShellPath = runtimeContext ? resolve19(runtimeContext.binDir, "rig-shell") : "";
4103
3762
  const monorepoMainRoot = runtimeContext?.monorepoMainRoot || process.env.MONOREPO_MAIN_ROOT?.trim() || resolveMonorepoRoot(projectRoot);
4104
3763
  const validatorEnv = {
4105
3764
  PROJECT_RIG_ROOT: runtimeContext?.hostProjectRoot || projectRoot,
@@ -4154,8 +3813,8 @@ async function validateTask(projectRoot, taskId, runtimeContext, registry, optio
4154
3813
  const configuredValidation = stringArray(taskConfig[taskId]?.validation);
4155
3814
  const commands = resolvedContext?.validation?.length ? resolvedContext.validation : configuredValidation.length > 0 ? configuredValidation : sourceValidation.validation;
4156
3815
  const { taskLogDir, artifactDir } = resolveValidationPaths(projectRoot, taskId, resolvedContext);
4157
- mkdirSync7(taskLogDir, { recursive: true });
4158
- mkdirSync7(artifactDir, { recursive: true });
3816
+ mkdirSync8(taskLogDir, { recursive: true });
3817
+ mkdirSync8(artifactDir, { recursive: true });
4159
3818
  if (commands.length === 0) {
4160
3819
  const skipped = {
4161
3820
  status: "skipped",
@@ -4164,7 +3823,7 @@ async function validateTask(projectRoot, taskId, runtimeContext, registry, optio
4164
3823
  failed: 0,
4165
3824
  categories: []
4166
3825
  };
4167
- writeFileSync7(resolve20(artifactDir, "validation-summary.json"), `${JSON.stringify(skipped, null, 2)}
3826
+ writeFileSync8(resolve19(artifactDir, "validation-summary.json"), `${JSON.stringify(skipped, null, 2)}
4168
3827
  `, "utf-8");
4169
3828
  return skipped;
4170
3829
  }
@@ -4199,18 +3858,18 @@ async function validateTask(projectRoot, taskId, runtimeContext, registry, optio
4199
3858
  exit_code: 2,
4200
3859
  duration_seconds: 0
4201
3860
  });
4202
- const logFile2 = resolve20(taskLogDir, `invalid-entry-validation.log`);
4203
- mkdirSync7(taskLogDir, { recursive: true });
4204
- writeFileSync7(logFile2, `=== ${nowIso()} :: ${cmd} ===
3861
+ const logFile2 = resolve19(taskLogDir, `invalid-entry-validation.log`);
3862
+ mkdirSync8(taskLogDir, { recursive: true });
3863
+ writeFileSync8(logFile2, `=== ${nowIso()} :: ${cmd} ===
4205
3864
  Invalid validation entry: not a check-ID. All entries must use format "category:check-name".
4206
3865
  `, "utf-8");
4207
3866
  continue;
4208
3867
  }
4209
3868
  const { result, exitCode } = await dispatchValidator(cmd, effectiveRegistry, validatorCtx, (id) => runValidatorBinary(projectRoot, taskId, id, resolvedContext));
4210
3869
  const durationSeconds = Math.max(0, Math.round((Date.now() - startedAt) / 1000));
4211
- const logFile = resolve20(taskLogDir, `${cmd.replace(":", "-")}-validation.log`);
4212
- mkdirSync7(taskLogDir, { recursive: true });
4213
- writeFileSync7(logFile, `=== ${nowIso()} :: ${cmd} ===
3870
+ const logFile = resolve19(taskLogDir, `${cmd.replace(":", "-")}-validation.log`);
3871
+ mkdirSync8(taskLogDir, { recursive: true });
3872
+ writeFileSync8(logFile, `=== ${nowIso()} :: ${cmd} ===
4214
3873
  ${JSON.stringify(result, null, 2)}
4215
3874
  `, "utf-8");
4216
3875
  if (result.passed) {
@@ -4232,19 +3891,19 @@ ${JSON.stringify(result, null, 2)}
4232
3891
  failed,
4233
3892
  categories
4234
3893
  };
4235
- mkdirSync7(artifactDir, { recursive: true });
4236
- writeFileSync7(resolve20(artifactDir, "validation-summary.json"), `${JSON.stringify(summary, null, 2)}
3894
+ mkdirSync8(artifactDir, { recursive: true });
3895
+ writeFileSync8(resolve19(artifactDir, "validation-summary.json"), `${JSON.stringify(summary, null, 2)}
4237
3896
  `, "utf-8");
4238
3897
  return summary;
4239
3898
  }
4240
3899
 
4241
3900
  // packages/runtime/src/control-plane/native/verifier.ts
4242
- import { existsSync as existsSync18, mkdirSync as mkdirSync9, writeFileSync as writeFileSync9 } from "fs";
4243
- import { resolve as resolve22 } from "path";
3901
+ import { existsSync as existsSync18, mkdirSync as mkdirSync10, writeFileSync as writeFileSync10 } from "fs";
3902
+ import { resolve as resolve21 } from "path";
4244
3903
 
4245
3904
  // packages/runtime/src/control-plane/native/pr-review-gate.ts
4246
- import { mkdirSync as mkdirSync8, writeFileSync as writeFileSync8 } from "fs";
4247
- import { resolve as resolve21 } from "path";
3905
+ import { mkdirSync as mkdirSync9, writeFileSync as writeFileSync9 } from "fs";
3906
+ import { resolve as resolve20 } from "path";
4248
3907
  function parseJsonObject(value) {
4249
3908
  if (!value?.trim())
4250
3909
  return { value: {}, error: "empty JSON output" };
@@ -5568,34 +5227,34 @@ function buildStrictPrGateSteeringPrompt(result) {
5568
5227
  }
5569
5228
  function persistPrReviewCycleArtifacts(input) {
5570
5229
  const cycleName = input.final ? `${input.cycle}-final` : String(input.cycle);
5571
- const taskArtifactRoot = input.artifactRoot?.trim() ? input.artifactRoot : resolve21(input.projectRoot, "artifacts", input.taskId);
5572
- const root = resolve21(taskArtifactRoot, "pr-review-cycles", cycleName);
5573
- mkdirSync8(root, { recursive: true });
5574
- const finalMergeGateResultPath = input.final ? resolve21(taskArtifactRoot, "merge-gate-final.json") : undefined;
5230
+ const taskArtifactRoot = input.artifactRoot?.trim() ? input.artifactRoot : resolve20(input.projectRoot, "artifacts", input.taskId);
5231
+ const root = resolve20(taskArtifactRoot, "pr-review-cycles", cycleName);
5232
+ mkdirSync9(root, { recursive: true });
5233
+ const finalMergeGateResultPath = input.final ? resolve20(taskArtifactRoot, "merge-gate-final.json") : undefined;
5575
5234
  const paths = {
5576
5235
  root,
5577
- prTitlePath: resolve21(root, "pr-title.md"),
5578
- prBodyPath: resolve21(root, "pr-body.md"),
5579
- prCommentsPath: resolve21(root, "pr-comments.json"),
5580
- reviewThreadsPath: resolve21(root, "review-threads.json"),
5581
- reviewCommentsPath: resolve21(root, "review-comments.json"),
5582
- checkRollupPath: resolve21(root, "check-rollup.json"),
5583
- greptileEvidencePath: resolve21(root, "greptile-evidence.json"),
5584
- mergeGateResultPath: resolve21(root, "merge-gate-result.json"),
5585
- steeringPromptPath: resolve21(root, "agent-steering-prompt.md"),
5236
+ prTitlePath: resolve20(root, "pr-title.md"),
5237
+ prBodyPath: resolve20(root, "pr-body.md"),
5238
+ prCommentsPath: resolve20(root, "pr-comments.json"),
5239
+ reviewThreadsPath: resolve20(root, "review-threads.json"),
5240
+ reviewCommentsPath: resolve20(root, "review-comments.json"),
5241
+ checkRollupPath: resolve20(root, "check-rollup.json"),
5242
+ greptileEvidencePath: resolve20(root, "greptile-evidence.json"),
5243
+ mergeGateResultPath: resolve20(root, "merge-gate-result.json"),
5244
+ steeringPromptPath: resolve20(root, "agent-steering-prompt.md"),
5586
5245
  ...finalMergeGateResultPath ? { finalMergeGateResultPath } : {}
5587
5246
  };
5588
- writeFileSync8(paths.prTitlePath, input.result.evidence.title || "", "utf8");
5589
- writeFileSync8(paths.prBodyPath, input.result.evidence.body || "", "utf8");
5590
- writeFileSync8(paths.prCommentsPath, `${JSON.stringify(input.result.evidence.relevantIssueComments, null, 2)}
5247
+ writeFileSync9(paths.prTitlePath, input.result.evidence.title || "", "utf8");
5248
+ writeFileSync9(paths.prBodyPath, input.result.evidence.body || "", "utf8");
5249
+ writeFileSync9(paths.prCommentsPath, `${JSON.stringify(input.result.evidence.relevantIssueComments, null, 2)}
5591
5250
  `, "utf8");
5592
- writeFileSync8(paths.reviewThreadsPath, `${JSON.stringify(input.result.evidence.reviewThreads, null, 2)}
5251
+ writeFileSync9(paths.reviewThreadsPath, `${JSON.stringify(input.result.evidence.reviewThreads, null, 2)}
5593
5252
  `, "utf8");
5594
- writeFileSync8(paths.reviewCommentsPath, `${JSON.stringify(input.result.evidence.changedFileReviewComments, null, 2)}
5253
+ writeFileSync9(paths.reviewCommentsPath, `${JSON.stringify(input.result.evidence.changedFileReviewComments, null, 2)}
5595
5254
  `, "utf8");
5596
- writeFileSync8(paths.checkRollupPath, `${JSON.stringify(input.result.evidence.statusCheckRollup, null, 2)}
5255
+ writeFileSync9(paths.checkRollupPath, `${JSON.stringify(input.result.evidence.statusCheckRollup, null, 2)}
5597
5256
  `, "utf8");
5598
- writeFileSync8(paths.greptileEvidencePath, `${JSON.stringify(input.result.evidence.greptile, null, 2)}
5257
+ writeFileSync9(paths.greptileEvidencePath, `${JSON.stringify(input.result.evidence.greptile, null, 2)}
5599
5258
  `, "utf8");
5600
5259
  const mergeGatePayload = {
5601
5260
  approved: input.result.approved,
@@ -5612,13 +5271,13 @@ function persistPrReviewCycleArtifacts(input) {
5612
5271
  evidence: input.result.evidence,
5613
5272
  cycleArtifactRoot: root
5614
5273
  };
5615
- writeFileSync8(paths.mergeGateResultPath, `${JSON.stringify(mergeGatePayload, null, 2)}
5274
+ writeFileSync9(paths.mergeGateResultPath, `${JSON.stringify(mergeGatePayload, null, 2)}
5616
5275
  `, "utf8");
5617
5276
  if (paths.finalMergeGateResultPath) {
5618
- writeFileSync8(paths.finalMergeGateResultPath, `${JSON.stringify(mergeGatePayload, null, 2)}
5277
+ writeFileSync9(paths.finalMergeGateResultPath, `${JSON.stringify(mergeGatePayload, null, 2)}
5619
5278
  `, "utf8");
5620
5279
  }
5621
- writeFileSync8(paths.steeringPromptPath, input.steeringPrompt, "utf8");
5280
+ writeFileSync9(paths.steeringPromptPath, input.steeringPrompt, "utf8");
5622
5281
  return paths;
5623
5282
  }
5624
5283
  async function runStrictPrMergeGate(input) {
@@ -5635,7 +5294,7 @@ async function runStrictPrMergeGate(input) {
5635
5294
  final: input.final
5636
5295
  });
5637
5296
  const steeringPrompt = buildStrictPrGateSteeringPrompt({ ...base, artifacts });
5638
- writeFileSync8(artifacts.steeringPromptPath, steeringPrompt, "utf8");
5297
+ writeFileSync9(artifacts.steeringPromptPath, steeringPrompt, "utf8");
5639
5298
  return { ...base, artifacts, steeringPrompt };
5640
5299
  }
5641
5300
 
@@ -5645,11 +5304,11 @@ async function verifyTask(options) {
5645
5304
  const taskId = options.taskId;
5646
5305
  const normalizedTaskId = lookupTask(options.projectRoot, taskId);
5647
5306
  const artifactDir = artifactDirForId(options.projectRoot, taskId);
5648
- mkdirSync9(artifactDir, { recursive: true });
5649
- const validationSummaryPath = resolve22(artifactDir, "validation-summary.json");
5650
- const reviewFeedbackPath = resolve22(artifactDir, "review-feedback.md");
5651
- const reviewStatePath = resolve22(artifactDir, "review-state.json");
5652
- const greptileRawPath = resolve22(artifactDir, "review-greptile-raw.json");
5307
+ mkdirSync10(artifactDir, { recursive: true });
5308
+ const validationSummaryPath = resolve21(artifactDir, "validation-summary.json");
5309
+ const reviewFeedbackPath = resolve21(artifactDir, "review-feedback.md");
5310
+ const reviewStatePath = resolve21(artifactDir, "review-state.json");
5311
+ const greptileRawPath = resolve21(artifactDir, "review-greptile-raw.json");
5653
5312
  const prStates = readPrMetadata(options.projectRoot, taskId);
5654
5313
  const prState = prStates[0] || null;
5655
5314
  const localReasons = [];
@@ -5670,12 +5329,12 @@ async function verifyTask(options) {
5670
5329
  }
5671
5330
  }
5672
5331
  for (const file of ["task-result.json", "decision-log.md", "next-actions.md", "changed-files.txt"]) {
5673
- const requiredPath = resolve22(artifactDir, file);
5332
+ const requiredPath = resolve21(artifactDir, file);
5674
5333
  if (!existsSync18(requiredPath)) {
5675
5334
  localReasons.push(`[Artifact Quality] Missing required artifact file: ${requiredPath}`);
5676
5335
  }
5677
5336
  }
5678
- const taskResultPath = resolve22(artifactDir, "task-result.json");
5337
+ const taskResultPath = resolve21(artifactDir, "task-result.json");
5679
5338
  if (existsSync18(taskResultPath)) {
5680
5339
  const taskResult = await readJsonFile2(taskResultPath);
5681
5340
  const artifactStatus = typeof taskResult?.status === "string" ? taskResult.status.trim().toLowerCase() : "";
@@ -5689,7 +5348,7 @@ async function verifyTask(options) {
5689
5348
  localReasons.push("[Artifact Quality] task-result.json next actions indicate remaining implementation scope.");
5690
5349
  }
5691
5350
  }
5692
- const nextActionsPath = resolve22(artifactDir, "next-actions.md");
5351
+ const nextActionsPath = resolve21(artifactDir, "next-actions.md");
5693
5352
  if (existsSync18(nextActionsPath)) {
5694
5353
  const nextActionsContent = await Bun.file(nextActionsPath).text();
5695
5354
  if (nextActionsContent.includes("TODO: Replace this scaffold") || nextActionsContent.includes("bd-<downstream-task-id>")) {
@@ -5703,12 +5362,6 @@ async function verifyTask(options) {
5703
5362
  if (sourceCloseoutIssueId) {
5704
5363
  localReasons.push(...evaluateGithubSourceIssuePrCloseout(options.projectRoot, prStates, sourceCloseoutIssueId));
5705
5364
  }
5706
- const pluginResults = await options.plugins.runValidators(taskId);
5707
- for (const result of pluginResults) {
5708
- if (!result.passed) {
5709
- localReasons.push(`[Plugin Validator] ${result.id}: ${result.summary}`);
5710
- }
5711
- }
5712
5365
  const reviewMode = await loadReviewMode(paths.reviewProfilePath, process.env.AI_REVIEW_MODE || "advisory");
5713
5366
  const reviewProvider = await loadReviewProvider(paths.reviewProfilePath, process.env.AI_REVIEW_PROVIDER || "greptile");
5714
5367
  if (!options.skipAiReview && localReasons.length === 0 && reviewProvider === "greptile" && reviewMode !== "off") {
@@ -5727,7 +5380,7 @@ async function verifyTask(options) {
5727
5380
  aiReasons.push(`[AI Review] Required mode needs a completed Greptile approval; current verdict is ${ai.verdict}.`);
5728
5381
  }
5729
5382
  if (persistArtifacts && ai.rawResponse) {
5730
- writeFileSync9(greptileRawPath, `${ai.rawResponse}
5383
+ writeFileSync10(greptileRawPath, `${ai.rawResponse}
5731
5384
  `, "utf-8");
5732
5385
  }
5733
5386
  } else if (!options.skipAiReview && reviewMode === "off") {
@@ -6236,7 +5889,7 @@ function writeFeedbackFile(options) {
6236
5889
  if (options.aiRawFeedback) {
6237
5890
  lines.push("## Raw Reviewer Feedback", "", "```text", options.aiRawFeedback, "```", "");
6238
5891
  }
6239
- writeFileSync9(options.output, `${lines.join(`
5892
+ writeFileSync10(options.output, `${lines.join(`
6240
5893
  `)}
6241
5894
  `, "utf-8");
6242
5895
  }
@@ -6253,7 +5906,7 @@ function writeReviewStateFile(options) {
6253
5906
  ai_warnings: options.aiWarnings,
6254
5907
  updated_at: nowIso()
6255
5908
  };
6256
- writeFileSync9(options.output, `${JSON.stringify(payload, null, 2)}
5909
+ writeFileSync10(options.output, `${JSON.stringify(payload, null, 2)}
6257
5910
  `, "utf-8");
6258
5911
  }
6259
5912
  async function runGreptileReviewForPr(options) {
@@ -7040,7 +6693,7 @@ function filterActionableGithubGreptileThreads(threads) {
7040
6693
  }
7041
6694
  function resolvePrRepoRoot(projectRoot, prState) {
7042
6695
  const runtimeWorkspace = process.env.RIG_TASK_WORKSPACE?.trim();
7043
- if (prState.target === "monorepo" && runtimeWorkspace && existsSync18(resolve22(runtimeWorkspace, ".git"))) {
6696
+ if (prState.target === "monorepo" && runtimeWorkspace && existsSync18(resolve21(runtimeWorkspace, ".git"))) {
7044
6697
  return runtimeWorkspace;
7045
6698
  }
7046
6699
  const paths = resolveHarnessPaths(projectRoot);
@@ -7108,14 +6761,14 @@ function taskArtifacts(projectRoot, taskId) {
7108
6761
  throw new Error("No active task.");
7109
6762
  }
7110
6763
  const paths = resolveHarnessPaths(projectRoot);
7111
- const artifactDir = resolve23(paths.artifactsDir, activeTask);
7112
- mkdirSync10(artifactDir, { recursive: true });
6764
+ const artifactDir = resolve22(paths.artifactsDir, activeTask);
6765
+ mkdirSync11(artifactDir, { recursive: true });
7113
6766
  const changed = changedFilesForTask(projectRoot, activeTask, true);
7114
- writeFileSync10(resolve23(artifactDir, "changed-files.txt"), `${changed.join(`
6767
+ writeFileSync11(resolve22(artifactDir, "changed-files.txt"), `${changed.join(`
7115
6768
  `)}
7116
6769
  `, "utf-8");
7117
6770
  console.log(`changed-files.txt: ${changed.length} files`);
7118
- const taskResultPath = resolve23(artifactDir, "task-result.json");
6771
+ const taskResultPath = resolve22(artifactDir, "task-result.json");
7119
6772
  if (!existsSync19(taskResultPath)) {
7120
6773
  const template = {
7121
6774
  task_id: activeTask,
@@ -7123,24 +6776,24 @@ function taskArtifacts(projectRoot, taskId) {
7123
6776
  summary: "TODO: Write a one-line summary of what you did",
7124
6777
  completed_at: nowIso()
7125
6778
  };
7126
- writeFileSync10(taskResultPath, `${JSON.stringify(template, null, 2)}
6779
+ writeFileSync11(taskResultPath, `${JSON.stringify(template, null, 2)}
7127
6780
  `, "utf-8");
7128
6781
  console.log("task-result.json: created (update the summary!)");
7129
6782
  } else {
7130
6783
  console.log("task-result.json: already exists");
7131
6784
  }
7132
- const decisionLogPath = resolve23(artifactDir, "decision-log.md");
6785
+ const decisionLogPath = resolve22(artifactDir, "decision-log.md");
7133
6786
  if (!existsSync19(decisionLogPath)) {
7134
6787
  const content = `# Decision Log: ${activeTask}
7135
6788
 
7136
6789
  Record key decisions here using: rig-agent record decision "..."
7137
6790
  `;
7138
- writeFileSync10(decisionLogPath, content, "utf-8");
6791
+ writeFileSync11(decisionLogPath, content, "utf-8");
7139
6792
  console.log("decision-log.md: created (record your decisions!)");
7140
6793
  } else {
7141
6794
  console.log("decision-log.md: already exists");
7142
6795
  }
7143
- const nextActionsPath = resolve23(artifactDir, "next-actions.md");
6796
+ const nextActionsPath = resolve22(artifactDir, "next-actions.md");
7144
6797
  if (!existsSync19(nextActionsPath)) {
7145
6798
  const content = [
7146
6799
  `# Next Actions: ${activeTask}`,
@@ -7158,12 +6811,12 @@ Record key decisions here using: rig-agent record decision "..."
7158
6811
  ""
7159
6812
  ].join(`
7160
6813
  `);
7161
- writeFileSync10(nextActionsPath, content, "utf-8");
6814
+ writeFileSync11(nextActionsPath, content, "utf-8");
7162
6815
  console.log("next-actions.md: created (add recommendations for downstream tasks!)");
7163
6816
  } else {
7164
6817
  console.log("next-actions.md: already exists");
7165
6818
  }
7166
- const validationSummaryPath = resolve23(artifactDir, "validation-summary.json");
6819
+ const validationSummaryPath = resolve22(artifactDir, "validation-summary.json");
7167
6820
  if (existsSync19(validationSummaryPath)) {
7168
6821
  console.log("validation-summary.json: already exists");
7169
6822
  } else {
@@ -7230,7 +6883,7 @@ function collectTaskChangedFiles(projectRoot, taskId, includeCommitted) {
7230
6883
  [projectRoot, ""],
7231
6884
  [monorepoRepoRoot, ""]
7232
6885
  ]) {
7233
- if (!existsSync19(resolve23(repo, ".git"))) {
6886
+ if (!existsSync19(resolve22(repo, ".git"))) {
7234
6887
  continue;
7235
6888
  }
7236
6889
  if (includeCommitted && repo === monorepoRepoRoot) {
@@ -7268,8 +6921,8 @@ function filterTaskChangedFiles(projectRoot, taskId, files, scoped) {
7268
6921
  }
7269
6922
  function resolveTaskMonorepoRoot(projectRoot) {
7270
6923
  const runtimeWorkspace = loadRuntimeContextFromEnv()?.workspaceDir || process.env.RIG_TASK_WORKSPACE?.trim();
7271
- if (runtimeWorkspace && existsSync19(resolve23(runtimeWorkspace, ".git"))) {
7272
- return resolve23(runtimeWorkspace);
6924
+ if (runtimeWorkspace && existsSync19(resolve22(runtimeWorkspace, ".git"))) {
6925
+ return resolve22(runtimeWorkspace);
7273
6926
  }
7274
6927
  return resolveHarnessPaths(projectRoot).monorepoRoot;
7275
6928
  }
@@ -7297,7 +6950,7 @@ function resolveRuntimeInitialHeadCommit(projectRoot, repo) {
7297
6950
  const runtimeContext = loadRuntimeContextFromEnv();
7298
6951
  if (runtimeContext?.initialHeadCommits?.monorepo?.trim()) {
7299
6952
  const monorepoRoot = resolveTaskMonorepoRoot(projectRoot);
7300
- if (resolve23(monorepoRoot) === resolve23(repo)) {
6953
+ if (resolve22(monorepoRoot) === resolve22(repo)) {
7301
6954
  return runtimeContext.initialHeadCommits.monorepo.trim();
7302
6955
  }
7303
6956
  }
@@ -7307,7 +6960,7 @@ function resolveMonorepoBaseCommit(projectRoot, repo) {
7307
6960
  const runtimeContext = loadRuntimeContextFromEnv();
7308
6961
  if (runtimeContext?.monorepoBaseCommit?.trim()) {
7309
6962
  const monorepoRoot = resolveTaskMonorepoRoot(projectRoot);
7310
- if (resolve23(monorepoRoot) === resolve23(repo)) {
6963
+ if (resolve22(monorepoRoot) === resolve22(repo)) {
7311
6964
  return runtimeContext.monorepoBaseCommit.trim();
7312
6965
  }
7313
6966
  }
@@ -7341,7 +6994,7 @@ function resolveRuntimeDirtyBaseline(projectRoot, repo) {
7341
6994
  return new Set;
7342
6995
  }
7343
6996
  const monorepoRoot = resolveTaskMonorepoRoot(projectRoot);
7344
- const selected = resolve23(repo) === resolve23(monorepoRoot) ? dirtyFiles.monorepo : resolve23(repo) === resolve23(projectRoot) ? dirtyFiles.project : undefined;
6997
+ const selected = resolve22(repo) === resolve22(monorepoRoot) ? dirtyFiles.monorepo : resolve22(repo) === resolve22(projectRoot) ? dirtyFiles.project : undefined;
7345
6998
  return new Set((selected || []).map((file) => normalizeChangedFilePath(file)).filter(Boolean));
7346
6999
  }
7347
7000
  function normalizeChangedFilePath(file) {
@@ -7399,8 +7052,8 @@ function isRuntimeGatewayGhPath(candidate) {
7399
7052
  }
7400
7053
  function resolveOptionalMonorepoRoot(projectRoot) {
7401
7054
  const runtimeWorkspace = process.env.RIG_TASK_WORKSPACE?.trim();
7402
- if (runtimeWorkspace && existsSync20(resolve24(runtimeWorkspace, ".git"))) {
7403
- return resolve24(runtimeWorkspace);
7055
+ if (runtimeWorkspace && existsSync20(resolve23(runtimeWorkspace, ".git"))) {
7056
+ return resolve23(runtimeWorkspace);
7404
7057
  }
7405
7058
  try {
7406
7059
  return resolveMonorepoRoot2(projectRoot);
@@ -7452,7 +7105,7 @@ function gitSyncBranch(projectRoot, taskId, targetRepo = "monorepo") {
7452
7105
  }
7453
7106
  const repoRoot = targetRepo === "monorepo" ? resolveOptionalMonorepoRoot(projectRoot) || resolveMonorepoRoot2(projectRoot) : projectRoot;
7454
7107
  const repoLabel = targetRepo === "monorepo" ? "Monorepo" : "Project";
7455
- if (!existsSync20(resolve24(repoRoot, ".git"))) {
7108
+ if (!existsSync20(resolve23(repoRoot, ".git"))) {
7456
7109
  throw new Error(`${repoLabel} repo not found at ${repoRoot}`);
7457
7110
  }
7458
7111
  const branchId = resolveTaskBranchId(projectRoot, resolvedTask);
@@ -7512,7 +7165,7 @@ function gitOpenPr(options) {
7512
7165
  } else if (taskId) {
7513
7166
  gitSyncBranch(options.projectRoot, taskId, "project");
7514
7167
  }
7515
- if (!existsSync20(resolve24(repoRoot, ".git"))) {
7168
+ if (!existsSync20(resolve23(repoRoot, ".git"))) {
7516
7169
  throw new Error(`Repository not available for open-pr target ${target}: ${repoRoot}`);
7517
7170
  }
7518
7171
  const branch = branchName(options.projectRoot, repoRoot);
@@ -7745,7 +7398,7 @@ function gitMergePr(options) {
7745
7398
  }
7746
7399
  const repoRoot = resolveRepoRoot(options.projectRoot, options.pr.target);
7747
7400
  const repoNameWithOwner = resolveRepoNameWithOwner(options.projectRoot, repoRoot);
7748
- if (!existsSync20(resolve24(repoRoot, ".git"))) {
7401
+ if (!existsSync20(resolve23(repoRoot, ".git"))) {
7749
7402
  throw new Error(`Repository not available for merge-pr target ${options.pr.target}: ${repoRoot}`);
7750
7403
  }
7751
7404
  const prState = readPrViewState(gh, repoRoot, repoNameWithOwner, options.pr.url);
@@ -7806,12 +7459,12 @@ function assertPrHasNoGitConflicts(prState, repoLabel, baseRef) {
7806
7459
  }
7807
7460
  function writePrMetadata(projectRoot, taskId, result) {
7808
7461
  const dir = artifactDirForId(projectRoot, taskId);
7809
- mkdirSync11(dir, { recursive: true });
7810
- const path = resolve24(dir, "pr-state.json");
7462
+ mkdirSync12(dir, { recursive: true });
7463
+ const path = resolve23(dir, "pr-state.json");
7811
7464
  let prs = {};
7812
7465
  if (existsSync20(path)) {
7813
7466
  try {
7814
- const parsed = JSON.parse(readFileSync11(path, "utf-8"));
7467
+ const parsed = JSON.parse(readFileSync12(path, "utf-8"));
7815
7468
  if (parsed && typeof parsed === "object" && parsed.prs && typeof parsed.prs === "object") {
7816
7469
  prs = parsed.prs;
7817
7470
  }
@@ -7827,16 +7480,16 @@ function writePrMetadata(projectRoot, taskId, result) {
7827
7480
  ...primary || {},
7828
7481
  updated_at: nowIso()
7829
7482
  };
7830
- writeFileSync11(path, `${JSON.stringify(artifact, null, 2)}
7483
+ writeFileSync12(path, `${JSON.stringify(artifact, null, 2)}
7831
7484
  `, "utf-8");
7832
7485
  }
7833
7486
  function readPrMetadata(projectRoot, taskId) {
7834
- const path = resolve24(artifactDirForId(projectRoot, taskId), "pr-state.json");
7487
+ const path = resolve23(artifactDirForId(projectRoot, taskId), "pr-state.json");
7835
7488
  if (!existsSync20(path)) {
7836
7489
  return [];
7837
7490
  }
7838
7491
  try {
7839
- const parsed = JSON.parse(readFileSync11(path, "utf-8"));
7492
+ const parsed = JSON.parse(readFileSync12(path, "utf-8"));
7840
7493
  if (!parsed || typeof parsed !== "object") {
7841
7494
  return [];
7842
7495
  }
@@ -7908,7 +7561,7 @@ function resolveGithubCliBinary(projectRoot) {
7908
7561
  }
7909
7562
  const explicitPathEntries = (process.env.PATH || "").split(":").map((entry) => entry.trim()).filter(Boolean);
7910
7563
  for (const entry of explicitPathEntries) {
7911
- candidates.add(resolve24(entry, "gh"));
7564
+ candidates.add(resolve23(entry, "gh"));
7912
7565
  }
7913
7566
  const bunResolved = Bun.which("gh");
7914
7567
  if (bunResolved) {
@@ -7945,7 +7598,7 @@ function resolveRepoNameWithOwner(projectRoot, repoRoot) {
7945
7598
  return resolveGithubRepoNameWithOwnerFromGitRoot(projectRoot, repoRoot, repoRoot, visited);
7946
7599
  }
7947
7600
  function resolveGithubRepoNameWithOwnerFromGitRoot(projectRoot, gitRoot, cwd, visited) {
7948
- const normalizedGitRoot = resolve24(gitRoot);
7601
+ const normalizedGitRoot = resolve23(gitRoot);
7949
7602
  if (visited.has(normalizedGitRoot)) {
7950
7603
  return "";
7951
7604
  }
@@ -8017,7 +7670,7 @@ function resolveNetworkRemoteName(projectRoot, repoRoot, repoNameWithOwner) {
8017
7670
  return remotes.includes("origin") ? "origin" : remotes[0];
8018
7671
  }
8019
7672
  function gitQuery(projectRoot, gitRoot, cwd, ...args) {
8020
- const gitArgs = existsSync20(resolve24(gitRoot, ".git")) ? gitCmd(projectRoot, gitRoot, ...args) : [resolveGitBinary(projectRoot), "--git-dir", gitRoot, ...args];
7673
+ const gitArgs = existsSync20(resolve23(gitRoot, ".git")) ? gitCmd(projectRoot, gitRoot, ...args) : [resolveGitBinary(projectRoot), "--git-dir", gitRoot, ...args];
8021
7674
  return runCapture2(gitArgs, cwd, projectRoot);
8022
7675
  }
8023
7676
  function resolveLocalGitRemoteRoot(remoteUrl, gitRoot) {
@@ -8035,7 +7688,7 @@ function resolveLocalGitRemoteRoot(remoteUrl, gitRoot) {
8035
7688
  } else if (/^[a-z][a-z0-9+.-]*:\/\//i.test(normalized) || /^[^@]+@[^:]+:.+$/.test(normalized)) {
8036
7689
  return "";
8037
7690
  } else if (!isAbsolute2(normalized)) {
8038
- candidate = resolve24(gitRoot, normalized);
7691
+ candidate = resolve23(gitRoot, normalized);
8039
7692
  }
8040
7693
  return existsSync20(candidate) ? candidate : "";
8041
7694
  }
@@ -8164,7 +7817,7 @@ function inferReviewerFromChangedFiles(projectRoot, repoRoot, baseRef, branchRef
8164
7817
  return best;
8165
7818
  }
8166
7819
  function commitRepo(projectRoot, repo, label, message, allowEmpty, scoped, files, changedFilesManifest) {
8167
- if (!existsSync20(resolve24(repo, ".git"))) {
7820
+ if (!existsSync20(resolve23(repo, ".git"))) {
8168
7821
  console.log(`Skipping ${label}: repo not available (${repo})`);
8169
7822
  return;
8170
7823
  }
@@ -8196,18 +7849,18 @@ function commitRepo(projectRoot, repo, label, message, allowEmpty, scoped, files
8196
7849
  console.log(`Committed ${label}: ${message}`);
8197
7850
  }
8198
7851
  function readChangedFilesManifest(projectRoot, taskId) {
8199
- const manifestPath = resolve24(artifactDirForId(projectRoot, taskId), "changed-files.txt");
7852
+ const manifestPath = resolve23(artifactDirForId(projectRoot, taskId), "changed-files.txt");
8200
7853
  if (!existsSync20(manifestPath)) {
8201
7854
  return [];
8202
7855
  }
8203
- const files = readFileSync11(manifestPath, "utf-8").split(/\r?\n/).map((line) => normalizeChangedFilePath2(line)).filter(Boolean);
7856
+ const files = readFileSync12(manifestPath, "utf-8").split(/\r?\n/).map((line) => normalizeChangedFilePath2(line)).filter(Boolean);
8204
7857
  return [...new Set(files)];
8205
7858
  }
8206
7859
  function refreshChangedFilesManifest(projectRoot, taskId) {
8207
- const manifestPath = resolve24(artifactDirForId(projectRoot, taskId), "changed-files.txt");
8208
- mkdirSync11(dirname11(manifestPath), { recursive: true });
7860
+ const manifestPath = resolve23(artifactDirForId(projectRoot, taskId), "changed-files.txt");
7861
+ mkdirSync12(dirname10(manifestPath), { recursive: true });
8209
7862
  const changedFiles = changedFilesForTask(projectRoot, taskId, true);
8210
- writeFileSync11(manifestPath, `${changedFiles.join(`
7863
+ writeFileSync12(manifestPath, `${changedFiles.join(`
8211
7864
  `)}
8212
7865
  `, "utf-8");
8213
7866
  return manifestPath;
@@ -8320,7 +7973,7 @@ function repoHasPathChange(projectRoot, repoRoot, relativePath) {
8320
7973
  return result.exitCode === 0 && result.stdout.trim().length > 0;
8321
7974
  }
8322
7975
  function stageExcludePathspecs(repoRoot) {
8323
- const patterns = existsSync20(resolve24(repoRoot, ".rig", "task-config.json")) ? [...TASK_RUNTIME_STAGE_EXCLUDES, ...GENERATED_STAGE_EXCLUDES] : [".rig/**", ...GENERATED_STAGE_EXCLUDES];
7976
+ const patterns = existsSync20(resolve23(repoRoot, ".rig", "task-config.json")) ? [...TASK_RUNTIME_STAGE_EXCLUDES, ...GENERATED_STAGE_EXCLUDES] : [".rig/**", ...GENERATED_STAGE_EXCLUDES];
8324
7977
  return patterns.map((pattern) => `:(glob,exclude)${pattern}`);
8325
7978
  }
8326
7979
  function pathResolvesBeyondSymlink(repoRoot, relativePath) {
@@ -8330,7 +7983,7 @@ function pathResolvesBeyondSymlink(repoRoot, relativePath) {
8330
7983
  }
8331
7984
  let current = repoRoot;
8332
7985
  for (let index = 0;index < parts.length - 1; index += 1) {
8333
- current = resolve24(current, parts[index]);
7986
+ current = resolve23(current, parts[index]);
8334
7987
  try {
8335
7988
  if (lstatSync(current).isSymbolicLink()) {
8336
7989
  return true;
@@ -8400,11 +8053,11 @@ function runCapture2(command, cwd, projectRoot = cwd) {
8400
8053
  }
8401
8054
  function runtimeGitEnv(projectRoot) {
8402
8055
  const { ctx, runtimeRoot } = resolveRuntimeMetadata(projectRoot);
8403
- const runtimeHome = runtimeRoot ? resolve24(runtimeRoot, "home") : "";
8404
- const runtimeTmp = runtimeRoot ? resolve24(runtimeRoot, "tmp") : "";
8405
- const runtimeCache = runtimeRoot ? resolve24(runtimeRoot, "cache") : "";
8406
- const runtimeKnownHosts = runtimeHome ? resolve24(runtimeHome, ".ssh", "known_hosts") : "";
8407
- const runtimeKey = runtimeHome ? resolve24(runtimeHome, ".ssh", "rig-agent-key") : "";
8056
+ const runtimeHome = runtimeRoot ? resolve23(runtimeRoot, "home") : "";
8057
+ const runtimeTmp = runtimeRoot ? resolve23(runtimeRoot, "tmp") : "";
8058
+ const runtimeCache = runtimeRoot ? resolve23(runtimeRoot, "cache") : "";
8059
+ const runtimeKnownHosts = runtimeHome ? resolve23(runtimeHome, ".ssh", "known_hosts") : "";
8060
+ const runtimeKey = runtimeHome ? resolve23(runtimeHome, ".ssh", "rig-agent-key") : "";
8408
8061
  const env = {};
8409
8062
  if (ctx?.workspaceDir) {
8410
8063
  env.PROJECT_RIG_ROOT = projectRoot;
@@ -8496,12 +8149,12 @@ function loadPersistedRuntimeSecrets(runtimeRoot) {
8496
8149
  if (!runtimeRoot) {
8497
8150
  return {};
8498
8151
  }
8499
- const path = resolve24(runtimeRoot, "runtime-secrets.json");
8152
+ const path = resolve23(runtimeRoot, "runtime-secrets.json");
8500
8153
  if (!existsSync20(path)) {
8501
8154
  return {};
8502
8155
  }
8503
8156
  try {
8504
- const parsed = JSON.parse(readFileSync11(path, "utf-8"));
8157
+ const parsed = JSON.parse(readFileSync12(path, "utf-8"));
8505
8158
  const entries = Object.entries(parsed).filter((entry) => typeof entry[1] === "string");
8506
8159
  return Object.fromEntries(entries);
8507
8160
  } catch {
@@ -8509,13 +8162,13 @@ function loadPersistedRuntimeSecrets(runtimeRoot) {
8509
8162
  }
8510
8163
  }
8511
8164
  function ensureRuntimeOpenSslConfig(runtimeHome) {
8512
- const sslDir = resolve24(runtimeHome, ".ssl");
8513
- const sslConfig = resolve24(sslDir, "openssl.cnf");
8165
+ const sslDir = resolve23(runtimeHome, ".ssl");
8166
+ const sslConfig = resolve23(sslDir, "openssl.cnf");
8514
8167
  if (!existsSync20(sslDir)) {
8515
- mkdirSync11(sslDir, { recursive: true });
8168
+ mkdirSync12(sslDir, { recursive: true });
8516
8169
  }
8517
8170
  if (!existsSync20(sslConfig)) {
8518
- writeFileSync11(sslConfig, `# Rig runtime OpenSSL config placeholder
8171
+ writeFileSync12(sslConfig, `# Rig runtime OpenSSL config placeholder
8519
8172
  `);
8520
8173
  }
8521
8174
  return sslConfig;
@@ -8533,7 +8186,7 @@ function resolveRuntimeMetadata(projectRoot) {
8533
8186
  if (contextFile) {
8534
8187
  return {
8535
8188
  ctx,
8536
- runtimeRoot: dirname11(resolve24(contextFile))
8189
+ runtimeRoot: dirname10(resolve23(contextFile))
8537
8190
  };
8538
8191
  }
8539
8192
  const inferredContextFile = findRuntimeContextFile2(projectRoot);
@@ -8543,19 +8196,19 @@ function resolveRuntimeMetadata(projectRoot) {
8543
8196
  } catch {}
8544
8197
  return {
8545
8198
  ctx,
8546
- runtimeRoot: dirname11(inferredContextFile)
8199
+ runtimeRoot: dirname10(inferredContextFile)
8547
8200
  };
8548
8201
  }
8549
8202
  return { ctx, runtimeRoot: "" };
8550
8203
  }
8551
8204
  function findRuntimeContextFile2(startPath) {
8552
- let current = resolve24(startPath);
8205
+ let current = resolve23(startPath);
8553
8206
  while (true) {
8554
- const candidate = resolve24(current, "runtime-context.json");
8207
+ const candidate = resolve23(current, "runtime-context.json");
8555
8208
  if (existsSync20(candidate)) {
8556
8209
  return candidate;
8557
8210
  }
8558
- const parent = dirname11(current);
8211
+ const parent = dirname10(current);
8559
8212
  if (parent === current) {
8560
8213
  return "";
8561
8214
  }
@@ -8643,21 +8296,12 @@ async function main() {
8643
8296
  const policy = loadPolicy(projectRoot);
8644
8297
  const openPrEnabled = policy.completion.checks.includes("open-pr");
8645
8298
  const autoMergeEnabled = policy.completion.checks.includes("auto-merge");
8646
- const eventBus = new RuntimeEventBus({ projectRoot });
8647
- const runtimeContext = loadRuntimeContextFromEnv() ?? undefined;
8648
- const plugins = await PluginManager.load({
8649
- projectRoot,
8650
- runId: eventBus.getRunId(),
8651
- eventBus,
8652
- runtimeContext
8653
- });
8654
8299
  console.log(`
8655
8300
  [2/3] Verifier preflight...`);
8656
8301
  if (!failed) {
8657
8302
  const localVerifyOutcome = await verifyTask({
8658
8303
  projectRoot,
8659
8304
  taskId,
8660
- plugins,
8661
8305
  skipAiReview: true,
8662
8306
  persistArtifacts: false
8663
8307
  });
@@ -8728,8 +8372,7 @@ async function main() {
8728
8372
  [3/3] Verifier review...`);
8729
8373
  const verifyOutcome = await verifyTask({
8730
8374
  projectRoot,
8731
- taskId,
8732
- plugins
8375
+ taskId
8733
8376
  });
8734
8377
  if (!verifyOutcome.approved) {
8735
8378
  console.log("REJECT:");
@@ -8801,9 +8444,9 @@ async function main() {
8801
8444
  console.log(`
8802
8445
  [post] Auto-merge: skipped (not in policy completion.checks)`);
8803
8446
  }
8804
- const artifactDir = resolve25(paths.artifactsDir, taskId);
8805
- mkdirSync12(artifactDir, { recursive: true });
8806
- writeFileSync12(resolve25(artifactDir, "review-status.txt"), failed ? `REJECTED
8447
+ const artifactDir = resolve24(paths.artifactsDir, taskId);
8448
+ mkdirSync13(artifactDir, { recursive: true });
8449
+ writeFileSync13(resolve24(artifactDir, "review-status.txt"), failed ? `REJECTED
8807
8450
  ` : `APPROVED
8808
8451
  `, "utf-8");
8809
8452
  if (!failed) {
@@ -8850,7 +8493,7 @@ async function runBunTool(args, cwd) {
8850
8493
  };
8851
8494
  }
8852
8495
  async function runProtoQualityGate(monorepoRoot) {
8853
- const protosDir = resolve25(monorepoRoot, "packages", "protos");
8496
+ const protosDir = resolve24(monorepoRoot, "packages", "protos");
8854
8497
  if (!existsSync21(protosDir)) {
8855
8498
  console.log(`FAIL: Proto workspace not found at ${protosDir}`);
8856
8499
  return false;
@@ -8899,12 +8542,12 @@ async function runProtoQualityGate(monorepoRoot) {
8899
8542
  } else {
8900
8543
  console.log("OK: Generated TypeScript compiles");
8901
8544
  }
8902
- const workflowPath = resolve25(monorepoRoot, ".github", "workflows", "pull-request-gate.yml");
8545
+ const workflowPath = resolve24(monorepoRoot, ".github", "workflows", "pull-request-gate.yml");
8903
8546
  if (!existsSync21(workflowPath)) {
8904
8547
  console.log(`FAIL: Missing workflow gate file at ${workflowPath}`);
8905
8548
  ok = false;
8906
8549
  } else {
8907
- const workflow = readFileSync12(workflowPath, "utf-8");
8550
+ const workflow = readFileSync13(workflowPath, "utf-8");
8908
8551
  if (workflow.includes("if: false && needs.detect.outputs.protos_changed == 'true'")) {
8909
8552
  console.log("FAIL: Proto quality CI gate is disabled in pull-request-gate.yml");
8910
8553
  ok = false;
@@ -8944,9 +8587,9 @@ async function readJsonFileIfPresent(path) {
8944
8587
  }
8945
8588
  async function recordVerifierFailure(projectRoot, taskId, paths) {
8946
8589
  const failedApproachesPath = paths.failedApproachesPath;
8947
- const artifactDir = resolve25(paths.artifactsDir, taskId);
8948
- const reviewStatePath = resolve25(artifactDir, "review-state.json");
8949
- const reviewFeedbackPath = resolve25(artifactDir, "review-feedback.md");
8590
+ const artifactDir = resolve24(paths.artifactsDir, taskId);
8591
+ const reviewStatePath = resolve24(artifactDir, "review-state.json");
8592
+ const reviewFeedbackPath = resolve24(artifactDir, "review-feedback.md");
8950
8593
  let summary = "Verifier rejected completion. Read review-feedback.md for required fixes.";
8951
8594
  const parsedReviewState = await readJsonFileIfPresent(reviewStatePath);
8952
8595
  if (parsedReviewState) {
@@ -8957,11 +8600,11 @@ async function recordVerifierFailure(projectRoot, taskId, paths) {
8957
8600
  }
8958
8601
  let attempts = 1;
8959
8602
  if (existsSync21(failedApproachesPath)) {
8960
- const content = readFileSync12(failedApproachesPath, "utf-8");
8603
+ const content = readFileSync13(failedApproachesPath, "utf-8");
8961
8604
  attempts = (content.match(new RegExp(`^## ${escapeRegExp2(taskId)}\\b`, "gm")) || []).length + 1;
8962
8605
  } else {
8963
- mkdirSync12(resolve25(failedApproachesPath, ".."), { recursive: true });
8964
- writeFileSync12(failedApproachesPath, `# Failed Approaches
8606
+ mkdirSync13(resolve24(failedApproachesPath, ".."), { recursive: true });
8607
+ writeFileSync13(failedApproachesPath, `# Failed Approaches
8965
8608
 
8966
8609
  `, "utf-8");
8967
8610
  }
@@ -8999,8 +8642,8 @@ async function recordTaskRepoCommits(projectRoot, taskId, paths) {
8999
8642
  recorded_at: new Date().toISOString(),
9000
8643
  repos
9001
8644
  };
9002
- mkdirSync12(resolve25(statePath, ".."), { recursive: true });
9003
- writeFileSync12(statePath, `${JSON.stringify(state, null, 2)}
8645
+ mkdirSync13(resolve24(statePath, ".."), { recursive: true });
8646
+ writeFileSync13(statePath, `${JSON.stringify(state, null, 2)}
9004
8647
  `, "utf-8");
9005
8648
  }
9006
8649
  }