patchrelay 0.68.6 → 0.68.7

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "service": "patchrelay",
3
- "version": "0.68.6",
4
- "commit": "b47d248df282",
5
- "builtAt": "2026-05-19T20:34:54.989Z"
3
+ "version": "0.68.7",
4
+ "commit": "56a3e7ae8d45",
5
+ "builtAt": "2026-05-21T21:06:57.848Z"
6
6
  }
package/dist/cli/data.js CHANGED
@@ -220,6 +220,7 @@ export class CliDataAccess extends CliOperatorApiClient {
220
220
  prState: dbIssue.prState,
221
221
  prReviewState: dbIssue.prReviewState,
222
222
  prCheckStatus: dbIssue.prCheckStatus,
223
+ factoryState: dbIssue.factoryState,
223
224
  pendingRunType: dbIssue.pendingRunType,
224
225
  lastRunType: issueSession?.lastRunType,
225
226
  lastGitHubFailureSource: issue.latestFailureSource,
@@ -6,6 +6,11 @@ export function resolveRetryTarget(params) {
6
6
  if (hasOpenPr(params.prNumber, params.prState) && params.lastGitHubFailureSource === "queue_eviction") {
7
7
  return { runType: "queue_repair", factoryState: "repairing_queue" };
8
8
  }
9
+ if (hasOpenPr(params.prNumber, params.prState)
10
+ && params.prReviewState === "approved"
11
+ && (params.factoryState === "awaiting_queue" || params.lastRunType === "queue_repair")) {
12
+ return { runType: "queue_repair", factoryState: "repairing_queue" };
13
+ }
9
14
  if (hasOpenPr(params.prNumber, params.prState)
10
15
  && (params.prCheckStatus === "failed" || params.prCheckStatus === "failure" || params.lastGitHubFailureSource === "branch_ci")) {
11
16
  return { runType: "ci_repair", factoryState: "repairing_ci" };
@@ -19,6 +19,13 @@ export function buildOperatorRetryEvent(issue, runType, source = "operator_retry
19
19
  ...(queueIncident ?? {}),
20
20
  ...(failureContext ?? {}),
21
21
  source,
22
+ requiresFreshHead: true,
23
+ promptContext: [
24
+ "Operator retry is recovering a merge queue rejection on an approved PR.",
25
+ "If the previous repair left the same head SHA in place, merge-steward may still consider it terminally evicted.",
26
+ "Preserve the approved diff, but publish a new head SHA on the existing PR branch before finishing.",
27
+ "If rebasing onto the current base produces no content change, create an empty queue-kick commit.",
28
+ ].join(" "),
22
29
  }),
23
30
  dedupeKey: `${source}:queue_repair:${issue.linearIssueId}:${issue.prHeadSha ?? issue.lastGitHubFailureHeadSha ?? "unknown-sha"}`,
24
31
  };
@@ -531,7 +531,7 @@ function buildPrePushSelfReviewSection(target, runType) {
531
531
  }
532
532
  return lines;
533
533
  }
534
- function buildPublicationContract(runType, issueClass) {
534
+ function buildPublicationContract(runType, issueClass, context) {
535
535
  if (issueClass === "orchestration") {
536
536
  return [
537
537
  "## Publish",
@@ -554,6 +554,7 @@ function buildPublicationContract(runType, issueClass) {
554
554
  ...buildPrePushSelfReviewSection("new_pr", runType),
555
555
  ].join("\n");
556
556
  }
557
+ const requiresFreshQueueHead = runType === "queue_repair" && context?.requiresFreshHead === true;
557
558
  return [
558
559
  "## Publish",
559
560
  "",
@@ -561,8 +562,16 @@ function buildPublicationContract(runType, issueClass) {
561
562
  "Do not open a new PR.",
562
563
  "A PR-less stop is not a successful outcome for a repair run unless a genuine external blocker prevents any correct push.",
563
564
  "",
564
- "Before pushing, compute `git diff $(git merge-base origin/main HEAD)..HEAD | git patch-id --stable` and compare its first field to the `Last published patch-id` shown in the prompt header (if any).",
565
- "If they match, do not push — finish the run as a no-op. Edit the PR body via `gh pr edit` instead if a textual update is needed.",
565
+ ...(requiresFreshQueueHead
566
+ ? [
567
+ "This queue repair requires a fresh PR head SHA because the previous head was terminally evicted by merge-steward.",
568
+ "Before pushing, compute `git diff $(git merge-base origin/main HEAD)..HEAD | git patch-id --stable` and compare its first field to the `Last published patch-id` shown in the prompt header (if any).",
569
+ "If the patch-id matches, preserve the approved diff and still push a new head SHA on the existing PR branch. Prefer a real rebase onto current `origin/main`; if that produces no content change, create an empty queue-kick commit.",
570
+ ]
571
+ : [
572
+ "Before pushing, compute `git diff $(git merge-base origin/main HEAD)..HEAD | git patch-id --stable` and compare its first field to the `Last published patch-id` shown in the prompt header (if any).",
573
+ "If they match, do not push — finish the run as a no-op. Edit the PR body via `gh pr edit` instead if a textual update is needed.",
574
+ ]),
566
575
  "",
567
576
  ...buildPrePushSelfReviewSection("existing_pr", runType),
568
577
  ].join("\n");
@@ -586,7 +595,7 @@ function buildSections(issue, runType, repoPath, context, followUp = false) {
586
595
  if (workflow) {
587
596
  sections.push({ id: "workflow-guidance", content: workflow });
588
597
  }
589
- sections.push({ id: "publication-contract", content: buildPublicationContract(runType, issueClass) });
598
+ sections.push({ id: "publication-contract", content: buildPublicationContract(runType, issueClass, context) });
590
599
  return sections;
591
600
  }
592
601
  function filterAllowedReplacements(promptLayer) {
@@ -12,6 +12,8 @@ function isDuplicateProbe(issue, context) {
12
12
  const headSha = typeof context?.failureHeadSha === "string" ? context.failureHeadSha : undefined;
13
13
  if (!signature)
14
14
  return false;
15
+ if (context?.requiresFreshHead === true)
16
+ return false;
15
17
  return issue.lastAttemptedFailureSignature === signature
16
18
  && (headSha === undefined || issue.lastAttemptedFailureHeadSha === headSha);
17
19
  }
@@ -133,12 +135,25 @@ export class QueueHealthMonitor {
133
135
  if (isDirty || hasEvictionCheckRun) {
134
136
  const headRefOid = pr.headRefOid ?? "unknown";
135
137
  const reason = hasEvictionCheckRun ? "queue_eviction_missed" : "preemptive_conflict";
136
- const signature = `preemptive_queue_conflict:${headRefOid}`;
138
+ const signature = hasEvictionCheckRun
139
+ ? `same_head_queue_eviction:${headRefOid}`
140
+ : `preemptive_queue_conflict:${headRefOid}`;
137
141
  const pendingRunContext = {
138
142
  source: "queue_health_monitor",
139
143
  failureReason: reason,
140
144
  failureHeadSha: headRefOid,
141
145
  failureSignature: signature,
146
+ ...(hasEvictionCheckRun
147
+ ? {
148
+ requiresFreshHead: true,
149
+ promptContext: [
150
+ `merge-steward/queue is already failed on PR #${issue.prNumber} at head ${headRefOid}.`,
151
+ "merge-steward will not re-admit the same evicted head SHA.",
152
+ "Preserve the approved diff, but publish a new head SHA on the existing PR branch before finishing.",
153
+ "If rebasing onto the current base produces no content change, create an empty queue-kick commit.",
154
+ ].join(" "),
155
+ }
156
+ : {}),
142
157
  };
143
158
  if (isDuplicateProbe(issue, pendingRunContext)) {
144
159
  return;
@@ -108,6 +108,7 @@ export class ServiceIssueActions {
108
108
  prState: issue.prState,
109
109
  prReviewState: issue.prReviewState,
110
110
  prCheckStatus: issue.prCheckStatus,
111
+ factoryState: issue.factoryState,
111
112
  pendingRunType: issue.pendingRunType,
112
113
  lastRunType: issueSession?.lastRunType,
113
114
  lastGitHubFailureSource: issue.lastGitHubFailureSource,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "patchrelay",
3
- "version": "0.68.6",
3
+ "version": "0.68.7",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "repository": {