@h-rig/runtime 0.0.6-alpha.13 → 0.0.6-alpha.15

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.
@@ -1365,6 +1365,30 @@ function sourceTaskConfigCandidates(projectRoot) {
1365
1365
 
1366
1366
  // packages/runtime/src/binary-run.ts
1367
1367
  var runtimeBinaryBuildQueue = Promise.resolve();
1368
+ // packages/runtime/src/control-plane/native/pr-review-gate.ts
1369
+ function strictMergeHeadShaFromGate(result, prUrl) {
1370
+ if (!result.approved) {
1371
+ throw new Error(`Refusing to merge ${prUrl}: strict merge gate is not approved.`);
1372
+ }
1373
+ if (result.evidence.prUrl !== prUrl) {
1374
+ throw new Error(`Refusing to merge ${prUrl}: strict merge gate evidence belongs to ${result.evidence.prUrl}.`);
1375
+ }
1376
+ const headSha = result.evidence.headSha?.trim();
1377
+ if (!headSha) {
1378
+ throw new Error(`Refusing to merge ${prUrl}: strict merge gate did not provide a current head SHA.`);
1379
+ }
1380
+ if (!/^[0-9a-f]{40}$/i.test(headSha)) {
1381
+ throw new Error(`Refusing to merge ${prUrl}: strict merge gate head is not a raw 40-character commit SHA.`);
1382
+ }
1383
+ if (!result.evidence.greptile.fresh || result.evidence.greptile.currentHeadSha !== headSha) {
1384
+ throw new Error(`Refusing to merge ${prUrl}: strict merge gate approval is not tied to head ${headSha}.`);
1385
+ }
1386
+ if (result.evidence.greptile.mapping !== "score-5-of-5" && result.evidence.greptile.mapping !== "explicit-approved") {
1387
+ throw new Error(`Refusing to merge ${prUrl}: strict merge gate mapping is ${result.evidence.greptile.mapping}.`);
1388
+ }
1389
+ return headSha;
1390
+ }
1391
+
1368
1392
  // packages/runtime/src/control-plane/provider/runtime-instructions.ts
1369
1393
  var CLAUDE_ROUTER_TOOL_NAMES = [
1370
1394
  "`mcp__rig_runtime_tools__read`",
@@ -1835,7 +1859,7 @@ function gitOpenPr(options) {
1835
1859
  "",
1836
1860
  "## Review",
1837
1861
  "- Completion verification will run validation, verifier review, and PR policy checks.",
1838
- "- When repository policy allows it, Rig enables GitHub auto-merge after approval."
1862
+ "- When repository policy allows it, Rig attempts an immediate strict-gated, head-locked merge after approval."
1839
1863
  ].join(`
1840
1864
  `);
1841
1865
  const preCheck = runCapture2(withGhRepo([gh, "pr", "list", "--state", "merged", "--head", branch, "--json", "url,mergedAt", "--jq", ".[0]"], repoNameWithOwner), repoRoot);
@@ -2031,15 +2055,12 @@ function gitMergePr(options) {
2031
2055
  return { status: "already-merged", url: options.pr.url };
2032
2056
  }
2033
2057
  if (state !== "OPEN") {
2034
- throw new Error(`Cannot auto-merge PR ${options.pr.url}: state is ${state}.`);
2058
+ throw new Error(`Cannot merge PR ${options.pr.url}: state is ${state}.`);
2035
2059
  }
2036
2060
  if (isDraft) {
2037
- throw new Error(`Cannot auto-merge draft PR ${options.pr.url}.`);
2038
- }
2039
- const strictGateHeadSha = options.strictGateHeadSha?.trim();
2040
- if (!strictGateHeadSha) {
2041
- throw new Error(`Refusing to merge PR ${options.pr.url}: strict merge gate did not provide a current head SHA.`);
2061
+ throw new Error(`Cannot merge draft PR ${options.pr.url}.`);
2042
2062
  }
2063
+ const strictGateHeadSha = strictMergeHeadShaFromGate(options.strictGate, options.pr.url);
2043
2064
  const mergeArgs = withGhRepo([gh, "pr", "merge", options.pr.url], repoNameWithOwner);
2044
2065
  const method = options.method || "squash";
2045
2066
  mergeArgs.push(method === "merge" ? "--merge" : method === "rebase" ? "--rebase" : "--squash");