@h-rig/bundle-default-lifecycle 0.0.6-alpha.157 → 0.0.6-alpha.158

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 (54) hide show
  1. package/dist/src/cli.d.ts +1 -7
  2. package/dist/src/cli.js +5 -2
  3. package/dist/src/control-plane/completion-verification.js +1591 -118
  4. package/dist/src/control-plane/hooks/inject-context.d.ts +2 -0
  5. package/dist/src/control-plane/hooks/inject-context.js +175 -0
  6. package/dist/src/control-plane/hooks/shared.d.ts +11 -0
  7. package/dist/src/control-plane/hooks/shared.js +44 -0
  8. package/dist/src/control-plane/hooks/submodule-branch.d.ts +2 -0
  9. package/dist/src/control-plane/hooks/submodule-branch.js +432 -0
  10. package/dist/src/control-plane/hooks/task-runtime-start.d.ts +2 -0
  11. package/dist/src/control-plane/hooks/task-runtime-start.js +429 -0
  12. package/dist/src/control-plane/materialize-task-config.d.ts +29 -0
  13. package/dist/src/control-plane/materialize-task-config.js +95 -0
  14. package/dist/src/control-plane/native/git-ops.d.ts +67 -0
  15. package/dist/src/control-plane/native/git-ops.js +1390 -0
  16. package/dist/src/control-plane/policy.d.ts +3 -0
  17. package/dist/src/control-plane/policy.js +226 -0
  18. package/dist/src/control-plane/pr-automation.d.ts +2 -0
  19. package/dist/src/control-plane/pr-automation.js +26 -16
  20. package/dist/src/control-plane/pr-merge-gate-cap.d.ts +10 -0
  21. package/dist/src/control-plane/pr-merge-gate-cap.js +13 -0
  22. package/dist/src/control-plane/task-data.d.ts +13 -0
  23. package/dist/src/control-plane/task-data.js +12 -0
  24. package/dist/src/control-plane/task-verify.js +131 -59
  25. package/dist/src/control-plane/verifier.d.ts +1 -3
  26. package/dist/src/control-plane/verifier.js +133 -57
  27. package/dist/src/defaultPipeline.d.ts +1 -1
  28. package/dist/src/defaultPipeline.js +5 -2
  29. package/dist/src/index.d.ts +0 -2
  30. package/dist/src/index.js +1908 -290
  31. package/dist/src/native/closeout-runners.js +22 -2
  32. package/dist/src/native/github-auth-env.d.ts +2 -0
  33. package/dist/src/native/github-auth-env.js +25 -0
  34. package/dist/src/native/host-git.d.ts +6 -0
  35. package/dist/src/native/host-git.js +62 -0
  36. package/dist/src/native/in-process-closeout.d.ts +1 -3
  37. package/dist/src/native/in-process-closeout.js +0 -794
  38. package/dist/src/pipelineCloseout.js +1905 -185
  39. package/dist/src/plugin.js +2843 -145
  40. package/dist/src/stages/auto-merge.js +28 -16
  41. package/dist/src/stages/commit.js +28 -16
  42. package/dist/src/stages/isolation.d.ts +1 -1
  43. package/dist/src/stages/isolation.js +5 -3
  44. package/dist/src/stages/merge-gate.js +35 -3
  45. package/dist/src/stages/open-pr.js +28 -16
  46. package/dist/src/stages/push.js +28 -16
  47. package/dist/src/stages/source-closeout.js +28 -16
  48. package/package.json +29 -16
  49. package/dist/src/branch-naming.d.ts +0 -15
  50. package/dist/src/branch-naming.js +0 -33
  51. package/dist/src/closeoutEquivalence.d.ts +0 -37
  52. package/dist/src/closeoutEquivalence.js +0 -78
  53. package/dist/src/closeoutShadowHarness.d.ts +0 -27
  54. package/dist/src/closeoutShadowHarness.js +0 -29
@@ -1,29 +1,103 @@
1
1
  // @bun
2
2
  // packages/bundle-default-lifecycle/src/control-plane/verifier.ts
3
- import { existsSync, mkdirSync, writeFileSync } from "fs";
4
- import { resolve } from "path";
5
- import { resolveRuntimeSecrets } from "@rig/runtime/control-plane/runtime/baked-secrets";
6
- import { readPrMetadata } from "@rig/runtime/control-plane/native/git-ops";
7
- import { loadRuntimeContextFromEnv } from "@rig/runtime/control-plane/runtime/context";
8
- import { readConfiguredTaskSourceTask } from "@rig/runtime/control-plane/tasks/source-lifecycle";
9
- import { artifactDirForId, lookupTask, readTaskConfig } from "@rig/runtime/control-plane/native/task-state";
10
- import { nowIso, resolveHarnessPaths, runCapture } from "@rig/runtime/control-plane/native/utils";
11
- import {
12
- collectPrReviewEvidence,
13
- evaluateStrictPrMergeGate,
14
- parseGreptileScore,
15
- stripHtml
16
- } from "@rig/pr-review-plugin";
3
+ import { existsSync as existsSync2, mkdirSync as mkdirSync2, writeFileSync as writeFileSync2 } from "fs";
4
+ import { resolve as resolve2 } from "path";
5
+ import { resolveRuntimeSecrets as resolveRuntimeSecrets2 } from "@rig/core/baked-secrets";
6
+
7
+ // packages/bundle-default-lifecycle/src/control-plane/native/git-ops.ts
8
+ import { existsSync, lstatSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from "fs";
9
+ import { dirname, isAbsolute, resolve } from "path";
10
+ import { loadDotEnvSecrets, resolveRuntimeSecrets } from "@rig/core/baked-secrets";
11
+ import { loadRuntimeContext, loadRuntimeContextFromEnv } from "@rig/core/runtime-context";
12
+
13
+ // packages/bundle-default-lifecycle/src/control-plane/task-data.ts
14
+ import { TASK_DATA_SERVICE_CAPABILITY } from "@rig/contracts";
15
+ import { defineCapability } from "@rig/core/capability";
16
+ import { requireInstalledCapability } from "@rig/core/capability-loaders";
17
+ var TaskDataCap = defineCapability(TASK_DATA_SERVICE_CAPABILITY);
18
+ function taskData() {
19
+ return requireInstalledCapability(TaskDataCap, "task-data capability unavailable: load @rig/task-sources-plugin (default bundle) before running the lifecycle.");
20
+ }
21
+
22
+ // packages/bundle-default-lifecycle/src/control-plane/native/git-ops.ts
23
+ import { nowIso, runCapture as baseRunCapture } from "@rig/core/exec";
24
+ import { resolveCheckoutRoot as resolveMonorepoRoot } from "@rig/core/checkout-root";
25
+ import { getScopeRules } from "@rig/core/scope-rules";
26
+ import { safePathSegment } from "@rig/core/safe-identifiers";
27
+ var TASK_ARTIFACT_STAGE_FALLBACK = new Set([
28
+ "changed-files.txt",
29
+ "contract-changes.md",
30
+ "decision-log.md",
31
+ "git-state.txt",
32
+ "next-actions.md",
33
+ "pr-state.json",
34
+ "task-result.json",
35
+ "validation-summary.json"
36
+ ]);
37
+ function readPrMetadata(projectRoot, taskId) {
38
+ const path = resolve(taskData().artifactDirForId(projectRoot, taskId), "pr-state.json");
39
+ if (!existsSync(path)) {
40
+ return [];
41
+ }
42
+ try {
43
+ const parsed = JSON.parse(readFileSync(path, "utf-8"));
44
+ if (!parsed || typeof parsed !== "object") {
45
+ return [];
46
+ }
47
+ if (parsed.prs && typeof parsed.prs === "object") {
48
+ return Object.values(parsed.prs).filter(isGitOpenPrResult);
49
+ }
50
+ return isGitOpenPrResult(parsed) ? [parsed] : [];
51
+ } catch {
52
+ return [];
53
+ }
54
+ }
55
+ function isGitOpenPrResult(value) {
56
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
57
+ return false;
58
+ }
59
+ const record = value;
60
+ return typeof record.url === "string" && typeof record.branch === "string" && typeof record.base === "string" && (record.target === "project" || record.target === "monorepo") && typeof record.repoLabel === "string";
61
+ }
62
+
63
+ // packages/bundle-default-lifecycle/src/control-plane/verifier.ts
64
+ import { loadRuntimeContextFromEnv as loadRuntimeContextFromEnv2 } from "@rig/core/runtime-context";
65
+ import { nowIso as nowIso2, runCapture } from "@rig/core/exec";
66
+ import { resolveHarnessPaths } from "@rig/core/harness-paths";
67
+
68
+ // packages/bundle-default-lifecycle/src/control-plane/pr-merge-gate-cap.ts
69
+ import { PR_MERGE_GATE } from "@rig/contracts";
70
+ import { defineCapability as defineCapability2 } from "@rig/core/capability";
71
+ import { resolvePluginHost } from "@rig/core/project-plugins";
72
+ var PrMergeGateCap = defineCapability2(PR_MERGE_GATE);
73
+ async function resolvePrMergeGateService(projectRoot) {
74
+ const { host } = await resolvePluginHost(projectRoot);
75
+ return PrMergeGateCap.require(host);
76
+ }
77
+
78
+ // packages/bundle-default-lifecycle/src/control-plane/verifier.ts
79
+ var mergeGateHolder = null;
80
+ async function ensureMergeGate(projectRoot) {
81
+ mergeGateHolder = await resolvePrMergeGateService(projectRoot);
82
+ return mergeGateHolder;
83
+ }
84
+ function mg() {
85
+ if (!mergeGateHolder) {
86
+ throw new Error("PR merge-gate capability not resolved (verifyTask must run first).");
87
+ }
88
+ return mergeGateHolder;
89
+ }
17
90
  async function verifyTask(options) {
91
+ await ensureMergeGate(options.projectRoot);
18
92
  const paths = resolveHarnessPaths(options.projectRoot);
19
93
  const taskId = options.taskId;
20
- const normalizedTaskId = lookupTask(options.projectRoot, taskId);
21
- const artifactDir = artifactDirForId(options.projectRoot, taskId);
22
- mkdirSync(artifactDir, { recursive: true });
23
- const validationSummaryPath = resolve(artifactDir, "validation-summary.json");
24
- const reviewFeedbackPath = resolve(artifactDir, "review-feedback.md");
25
- const reviewStatePath = resolve(artifactDir, "review-state.json");
26
- const greptileRawPath = resolve(artifactDir, "review-greptile-raw.json");
94
+ const normalizedTaskId = taskData().lookupTask(options.projectRoot, taskId);
95
+ const artifactDir = taskData().artifactDirForId(options.projectRoot, taskId);
96
+ mkdirSync2(artifactDir, { recursive: true });
97
+ const validationSummaryPath = resolve2(artifactDir, "validation-summary.json");
98
+ const reviewFeedbackPath = resolve2(artifactDir, "review-feedback.md");
99
+ const reviewStatePath = resolve2(artifactDir, "review-state.json");
100
+ const greptileRawPath = resolve2(artifactDir, "review-greptile-raw.json");
27
101
  const prStates = readPrMetadata(options.projectRoot, taskId);
28
102
  const prState = prStates[0] || null;
29
103
  const localReasons = [];
@@ -35,7 +109,7 @@ async function verifyTask(options) {
35
109
  if (!normalizedTaskId && !await hasConfiguredSourceTask(options.projectRoot, taskId)) {
36
110
  localReasons.push(`[Task Config] Unknown task id '${taskId}' in task-config or configured task source.`);
37
111
  }
38
- if (!existsSync(validationSummaryPath)) {
112
+ if (!existsSync2(validationSummaryPath)) {
39
113
  localReasons.push(`[Artifact Quality] validation-summary.json not found at ${validationSummaryPath}.`);
40
114
  } else {
41
115
  const summary = await parseValidationSummary(validationSummaryPath);
@@ -44,13 +118,13 @@ async function verifyTask(options) {
44
118
  }
45
119
  }
46
120
  for (const file of ["task-result.json", "decision-log.md", "next-actions.md", "changed-files.txt"]) {
47
- const requiredPath = resolve(artifactDir, file);
48
- if (!existsSync(requiredPath)) {
121
+ const requiredPath = resolve2(artifactDir, file);
122
+ if (!existsSync2(requiredPath)) {
49
123
  localReasons.push(`[Artifact Quality] Missing required artifact file: ${requiredPath}`);
50
124
  }
51
125
  }
52
- const taskResultPath = resolve(artifactDir, "task-result.json");
53
- if (existsSync(taskResultPath)) {
126
+ const taskResultPath = resolve2(artifactDir, "task-result.json");
127
+ if (existsSync2(taskResultPath)) {
54
128
  const taskResult = await readJsonFile(taskResultPath);
55
129
  const artifactStatus = typeof taskResult?.status === "string" ? taskResult.status.trim().toLowerCase() : "";
56
130
  if (artifactStatus === "partial") {
@@ -63,8 +137,8 @@ async function verifyTask(options) {
63
137
  localReasons.push("[Artifact Quality] task-result.json next actions indicate remaining implementation scope.");
64
138
  }
65
139
  }
66
- const nextActionsPath = resolve(artifactDir, "next-actions.md");
67
- if (existsSync(nextActionsPath)) {
140
+ const nextActionsPath = resolve2(artifactDir, "next-actions.md");
141
+ if (existsSync2(nextActionsPath)) {
68
142
  const nextActionsContent = await Bun.file(nextActionsPath).text();
69
143
  if (nextActionsContent.includes("TODO: Replace this scaffold") || nextActionsContent.includes("bd-<downstream-task-id>")) {
70
144
  localReasons.push("[Artifact Quality] next-actions.md still contains scaffold placeholder text. Replace with real recommendations.");
@@ -95,7 +169,7 @@ async function verifyTask(options) {
95
169
  aiReasons.push(`[AI Review] Required mode needs a completed Greptile approval; current verdict is ${ai.verdict}.`);
96
170
  }
97
171
  if (persistArtifacts && ai.rawResponse) {
98
- writeFileSync(greptileRawPath, `${ai.rawResponse}
172
+ writeFileSync2(greptileRawPath, `${ai.rawResponse}
99
173
  `, "utf-8");
100
174
  }
101
175
  } else if (!options.skipAiReview && reviewMode === "off") {
@@ -217,15 +291,15 @@ function nextActionsIndicateRemainingScope(content) {
217
291
  return /^\s*- \[ \]/m.test(normalized) || /\b(remaining scope|still need|needs? to be implemented|not yet implemented|not implemented|follow[- ]?up required|blocked by|blocker:)\b/i.test(lower);
218
292
  }
219
293
  async function hasConfiguredSourceTask(projectRoot, taskId) {
220
- return readConfiguredTaskSourceTask(projectRoot, taskId).then((result) => result.task !== null).catch(() => false);
294
+ return taskData().readConfiguredTaskSourceTask(projectRoot, taskId).then((result) => result.task !== null).catch(() => false);
221
295
  }
222
296
  function resolveGithubSourceIssueId(projectRoot, taskId) {
223
- const fromRuntime = loadRuntimeContextFromEnv()?.sourceTask?.sourceIssueId;
297
+ const fromRuntime = loadRuntimeContextFromEnv2()?.sourceTask?.sourceIssueId;
224
298
  if (typeof fromRuntime === "string" && isGithubSourceIssueId(fromRuntime)) {
225
299
  return fromRuntime;
226
300
  }
227
301
  try {
228
- const taskConfig = readTaskConfig(projectRoot);
302
+ const taskConfig = taskData().readTaskConfig(projectRoot);
229
303
  const entry = taskConfig[taskId];
230
304
  const sourceIssueId = typeof entry?.sourceIssueId === "string" ? entry.sourceIssueId : typeof entry?.source_issue_id === "string" ? entry.source_issue_id : null;
231
305
  if (sourceIssueId && isGithubSourceIssueId(sourceIssueId)) {
@@ -296,14 +370,15 @@ function loadGithubPullRequestCloseoutSnapshot(projectRoot, prState) {
296
370
  "--json",
297
371
  "state,isDraft,mergeable,mergeStateStatus,reviewDecision,title,body,statusCheckRollup"
298
372
  ]);
373
+ const isDraft = booleanField(view, "isDraft");
299
374
  return {
300
- state: stringField(view, "state"),
301
- isDraft: booleanField(view, "isDraft"),
302
- mergeable: stringField(view, "mergeable"),
303
- mergeStateStatus: stringField(view, "mergeStateStatus"),
304
- reviewDecision: stringField(view, "reviewDecision"),
305
- title: stringField(view, "title"),
306
- body: stringField(view, "body"),
375
+ ...objectField("state", stringField(view, "state")),
376
+ ...isDraft !== undefined ? { isDraft } : {},
377
+ ...objectField("mergeable", stringField(view, "mergeable")),
378
+ ...objectField("mergeStateStatus", stringField(view, "mergeStateStatus")),
379
+ ...objectField("reviewDecision", stringField(view, "reviewDecision")),
380
+ ...objectField("title", stringField(view, "title")),
381
+ ...objectField("body", stringField(view, "body")),
307
382
  statusCheckRollup: statusCheckRollupField(view, "statusCheckRollup"),
308
383
  reviewThreads: loadGithubReviewThreads(projectRoot, repoName, prNumber)
309
384
  };
@@ -378,6 +453,9 @@ function stringField(record, key) {
378
453
  const value = record[key];
379
454
  return typeof value === "string" ? value : undefined;
380
455
  }
456
+ function objectField(key, value) {
457
+ return value === undefined ? {} : { [key]: value };
458
+ }
381
459
  function booleanField(record, key) {
382
460
  const value = record[key];
383
461
  return typeof value === "boolean" ? value : undefined;
@@ -434,7 +512,7 @@ function isAcceptedValidationSummary(summary) {
434
512
  return summary.status === "skipped" && summary.total === 0 && summary.failed === 0;
435
513
  }
436
514
  async function loadReviewMode(reviewProfilePath, fallback) {
437
- const parsed = existsSync(reviewProfilePath) ? await readJsonFile(reviewProfilePath) : null;
515
+ const parsed = existsSync2(reviewProfilePath) ? await readJsonFile(reviewProfilePath) : null;
438
516
  const mode = parsed?.mode;
439
517
  if (mode === "off" || mode === "advisory" || mode === "required") {
440
518
  return mode;
@@ -445,7 +523,7 @@ async function loadReviewMode(reviewProfilePath, fallback) {
445
523
  return "advisory";
446
524
  }
447
525
  async function loadReviewProvider(reviewProfilePath, fallback) {
448
- const parsed = existsSync(reviewProfilePath) ? await readJsonFile(reviewProfilePath) : null;
526
+ const parsed = existsSync2(reviewProfilePath) ? await readJsonFile(reviewProfilePath) : null;
449
527
  const provider = parsed?.provider;
450
528
  if (typeof provider === "string" && provider.trim().length > 0) {
451
529
  return provider;
@@ -468,7 +546,7 @@ function resolveRepoSlug(projectRoot) {
468
546
  async function runGreptileReview(options) {
469
547
  const reasons = [];
470
548
  const warnings = [];
471
- const secrets = resolveRuntimeSecrets(process.env);
549
+ const secrets = resolveRuntimeSecrets2(process.env);
472
550
  const apiKey = secrets.GREPTILE_API_KEY || "";
473
551
  const apiBase = secrets.GREPTILE_API_BASE || "https://api.greptile.com/mcp";
474
552
  const remote = secrets.GREPTILE_REMOTE || "github";
@@ -604,7 +682,7 @@ function writeFeedbackFile(options) {
604
682
  if (options.aiRawFeedback) {
605
683
  lines.push("## Raw Reviewer Feedback", "", "```text", options.aiRawFeedback, "```", "");
606
684
  }
607
- writeFileSync(options.output, `${lines.join(`
685
+ writeFileSync2(options.output, `${lines.join(`
608
686
  `)}
609
687
  `, "utf-8");
610
688
  }
@@ -619,9 +697,9 @@ function writeReviewStateFile(options) {
619
697
  local_reasons: options.localReasons,
620
698
  ai_reasons: options.aiReasons,
621
699
  ai_warnings: options.aiWarnings,
622
- updated_at: nowIso()
700
+ updated_at: nowIso2()
623
701
  };
624
- writeFileSync(options.output, `${JSON.stringify(payload, null, 2)}
702
+ writeFileSync2(options.output, `${JSON.stringify(payload, null, 2)}
625
703
  `, "utf-8");
626
704
  }
627
705
  async function runGreptileReviewForPr(options) {
@@ -646,7 +724,6 @@ async function runGreptileReviewForPr(options) {
646
724
  taskId: options.taskId,
647
725
  prState: options.prState,
648
726
  reviewMode: options.reviewMode,
649
- infrastructureError: undefined,
650
727
  pollAttempts: options.pollAttempts,
651
728
  pollIntervalMs: options.pollIntervalMs
652
729
  });
@@ -774,7 +851,7 @@ async function runGreptileReviewForPr(options) {
774
851
  });
775
852
  const actionableComments = filterActionableGreptileComments(commentsPayload.comments || []);
776
853
  const reviewBody = reviewDetails.codeReview?.body || "";
777
- const score = parseGreptileScore(reviewBody);
854
+ const score = mg().parseGreptileScore(reviewBody);
778
855
  const feedback = [
779
856
  `## ${options.prState.repoLabel || repoName} PR Review`,
780
857
  "",
@@ -782,7 +859,7 @@ async function runGreptileReviewForPr(options) {
782
859
  `- Review ID: ${selectedReview.id}`,
783
860
  `- Status: ${selectedReview.status}`,
784
861
  "",
785
- reviewBody ? stripHtml(reviewBody).trim() : "Greptile completed without summary body."
862
+ reviewBody ? mg().stripHtml(reviewBody).trim() : "Greptile completed without summary body."
786
863
  ].filter(Boolean).join(`
787
864
  `);
788
865
  if (actionableComments.length > 0) {
@@ -803,7 +880,7 @@ async function runGreptileReviewForPr(options) {
803
880
  }
804
881
  };
805
882
  }
806
- const blockerScanBody = stripHtml(reviewBody).replace(/\b(?:no|without|zero)\s+blockers?\b/gi, " ").replace(/\bno\s+changes\s+requested\b/gi, " ");
883
+ const blockerScanBody = mg().stripHtml(reviewBody).replace(/\b(?:no|without|zero)\s+blockers?\b/gi, " ").replace(/\bno\s+changes\s+requested\b/gi, " ");
807
884
  if (/not safe(?: to merge)?|unsafe(?: to merge)?|do not merge|cannot merge|blockers?|must fix|changes requested|please fix|needs? fix|fix this|address this|\breject(?:ed|ion)?\b|\bskip(?:ped)?\b|status\s*:\s*(?:reject(?:ed)?|skip(?:ped)?|failed)/i.test(blockerScanBody)) {
808
885
  reasons.push(`[AI Review] ${repoName}#${prNumber} summary indicates the PR is not safe to merge.`);
809
886
  return {
@@ -851,7 +928,7 @@ async function runGreptileReviewForPr(options) {
851
928
  status: selectedReview.status
852
929
  }]
853
930
  });
854
- strictGate = evaluateStrictPrMergeGate(strictEvidence);
931
+ strictGate = mg().evaluateGate(strictEvidence);
855
932
  } catch (error) {
856
933
  reasons.push(`[AI Review] Strict Greptile evidence collection failed for ${repoName}#${prNumber}: ${error instanceof Error ? error.message : String(error)}`);
857
934
  return {
@@ -978,7 +1055,7 @@ async function runGithubGreptileFallbackReviewForPr(options) {
978
1055
  fallbackReview?.html_url ? `- Review: ${fallbackReview.html_url}` : "",
979
1056
  fallbackReview?.state ? `- Status: ${fallbackReview.state}` : "",
980
1057
  "",
981
- fallbackReview?.body?.trim() ? stripHtml(fallbackReview.body).trim() : "Greptile MCP was unavailable, so verification used GitHub review threads instead."
1058
+ fallbackReview?.body?.trim() ? mg().stripHtml(fallbackReview.body).trim() : "Greptile MCP was unavailable, so verification used GitHub review threads instead."
982
1059
  ].filter(Boolean).join(`
983
1060
  `);
984
1061
  const warnings = buildGithubGreptileFallbackWarnings(options);
@@ -1001,7 +1078,7 @@ async function runGithubGreptileFallbackReviewForPr(options) {
1001
1078
  taskId: options.taskId,
1002
1079
  prUrl
1003
1080
  });
1004
- strictGate = evaluateStrictPrMergeGate(strictEvidence);
1081
+ strictGate = mg().evaluateGate(strictEvidence);
1005
1082
  } catch (error) {
1006
1083
  return {
1007
1084
  verdict: "REJECT",
@@ -1226,7 +1303,7 @@ function loadGithubPullRequestState(projectRoot, repoName, prNumber) {
1226
1303
  ]);
1227
1304
  return {
1228
1305
  state: response.state || "",
1229
- merged: response.merged,
1306
+ ...response.merged !== undefined ? { merged: response.merged } : {},
1230
1307
  merged_at: response.merged_at ?? null
1231
1308
  };
1232
1309
  }
@@ -1255,7 +1332,7 @@ function runGhJson(projectRoot, args) {
1255
1332
  }
1256
1333
  }
1257
1334
  async function collectStrictPrEvidenceForVerifier(input) {
1258
- return collectPrReviewEvidence({
1335
+ return mg().collectEvidence({
1259
1336
  projectRoot: input.projectRoot,
1260
1337
  prUrl: input.prUrl,
1261
1338
  taskId: input.taskId,
@@ -1423,7 +1500,7 @@ function filterActionableGithubGreptileThreads(threads) {
1423
1500
  }
1424
1501
  function resolvePrRepoRoot(projectRoot, prState) {
1425
1502
  const runtimeWorkspace = process.env.RIG_TASK_WORKSPACE?.trim();
1426
- if (prState.target === "monorepo" && runtimeWorkspace && existsSync(resolve(runtimeWorkspace, ".git"))) {
1503
+ if (prState.target === "monorepo" && runtimeWorkspace && existsSync2(resolve2(runtimeWorkspace, ".git"))) {
1427
1504
  return runtimeWorkspace;
1428
1505
  }
1429
1506
  const paths = resolveHarnessPaths(projectRoot);
@@ -1437,7 +1514,7 @@ function isCommitAncestorOfPrHead(projectRoot, prState, reviewedCommit, headComm
1437
1514
  return runCapture(["git", "-C", repoRoot, "merge-base", "--is-ancestor", reviewedCommit, headCommit], projectRoot).exitCode === 0;
1438
1515
  }
1439
1516
  function summarizeComment(input) {
1440
- const text = stripHtml(input).replace(/\s+/g, " ").trim();
1517
+ const text = mg().stripHtml(input).replace(/\s+/g, " ").trim();
1441
1518
  return text.length > 160 ? `${text.slice(0, 157)}...` : text;
1442
1519
  }
1443
1520
  function asGreptileInfrastructureWarning(reason) {
@@ -1459,7 +1536,6 @@ var __testOnly = {
1459
1536
  filterActionableGithubGreptileThreads,
1460
1537
  isGithubGreptileCheckApproved,
1461
1538
  isAiReviewApproved,
1462
- parseGreptileScore,
1463
1539
  pickLatestGithubGreptileReview,
1464
1540
  pickRelevantGithubGreptileReview,
1465
1541
  resolveGreptileRequestTimeoutMs,
@@ -1,5 +1,5 @@
1
1
  import type { StageMutation } from "@rig/contracts";
2
- import { type KernelStageResolverResult } from "@rig/kernel/resolver";
2
+ import { type KernelStageResolverResult } from "@rig/kernel-seed/resolver";
3
3
  import type { DefaultLifecycleStageDescriptor, DefaultLifecycleStageId } from "./stages/types";
4
4
  export declare const DEFAULT_LIFECYCLE_STAGE_IDS: readonly ["validate", "verify", "commit", "push", "open-pr", "merge-gate", "auto-merge", "source-closeout", "isolation", "journal-append"];
5
5
  export declare const defaultLifecycleStages: readonly DefaultLifecycleStageDescriptor[];
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  // packages/bundle-default-lifecycle/src/defaultPipeline.ts
3
- import { resolveKernelStages } from "@rig/kernel/resolver";
4
- import { createDefaultKernelPlugin } from "@rig/kernel/default-kernel";
3
+ import { createDefaultKernelPlugin } from "@rig/kernel-seed/default-kernel";
4
+ import { resolveKernelStages } from "@rig/kernel-seed/resolver";
5
5
 
6
6
  // packages/bundle-default-lifecycle/src/stages/types.ts
7
7
  function defineDefaultLifecycleStage(input) {
@@ -29,6 +29,9 @@ var commitStage = defineDefaultLifecycleStage({
29
29
  });
30
30
 
31
31
  // packages/bundle-default-lifecycle/src/stages/isolation.ts
32
+ import { ISOLATION_BACKEND } from "@rig/contracts";
33
+ import { defineCapability } from "@rig/core/capability";
34
+ import { requireCapabilityForRoot } from "@rig/core/capability-loaders";
32
35
  var isolationStage = defineDefaultLifecycleStage({
33
36
  id: "isolation",
34
37
  kind: "transform",
@@ -1,5 +1,3 @@
1
- export * from "./closeoutEquivalence";
2
- export * from "./closeoutShadowHarness";
3
1
  export * from "./defaultPipeline";
4
2
  export * from "./pipelineCloseout";
5
3
  export * from "./cli";