patchrelay 0.52.3 → 0.52.5
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.
package/dist/build-info.json
CHANGED
package/dist/config.js
CHANGED
|
@@ -23,6 +23,8 @@ const DEFAULT_PATCHRELAY_DEVELOPER_INSTRUCTIONS = [
|
|
|
23
23
|
"- A requested-changes repair is only complete after a newer PR head is pushed, unless a genuine external blocker prevents correct publication.",
|
|
24
24
|
"- If you change schema, enums, shared vocabulary, normalization helpers, or compatibility mappings, inspect the main read/write paths that can bypass the new abstraction and fix or cover any mismatch before publishing.",
|
|
25
25
|
"- For CI repair, do not change code or config until you either reproduce the failure on the exact failing head or can point to a concrete log signature that justifies the fix. If you cannot reproduce it, prefer a rerun-only repair over speculative changes.",
|
|
26
|
+
"- For main repair, first verify that the incident still persists on the exact failing main SHA. If a rerun clears transient runner issues such as disk pressure or network lag, treat that as the repair instead of inventing branch changes.",
|
|
27
|
+
"- Do not propose or implement moving CI, deploy, or tests to different nodes or runner pools unless a human explicitly asked for that infrastructure migration.",
|
|
26
28
|
"- If a broader inconsistency is not required to make this task correct, mention it briefly instead of expanding scope.",
|
|
27
29
|
"- Before publishing, do one brief reviewer-minded pass on the current head and fix likely in-scope blockers.",
|
|
28
30
|
].join("\n");
|
|
@@ -37,12 +37,7 @@ export class MainBranchHealthMonitor {
|
|
|
37
37
|
return;
|
|
38
38
|
const baseBranch = project.github.baseBranch ?? "main";
|
|
39
39
|
const branchName = buildMainRepairBranchName(baseBranch);
|
|
40
|
-
const existing = this.
|
|
41
|
-
&& issue.branchName === branchName
|
|
42
|
-
&& isMainRepairIssue(issue)
|
|
43
|
-
&& issue.factoryState !== "done"
|
|
44
|
-
&& issue.factoryState !== "failed"
|
|
45
|
-
&& issue.factoryState !== "escalated"));
|
|
40
|
+
const existing = this.findExistingMainRepair(projectId, branchName);
|
|
46
41
|
const summary = await this.readMainBranchFailure(project.github.repoFullName, baseBranch);
|
|
47
42
|
if (!summary) {
|
|
48
43
|
if (existing) {
|
|
@@ -114,6 +109,33 @@ export class MainBranchHealthMonitor {
|
|
|
114
109
|
detail: summary.failingChecks.map((check) => check.name).join(", "),
|
|
115
110
|
});
|
|
116
111
|
}
|
|
112
|
+
findExistingMainRepair(projectId, branchName) {
|
|
113
|
+
const candidates = this.db.listIssues()
|
|
114
|
+
.filter((issue) => (issue.projectId === projectId
|
|
115
|
+
&& issue.branchName === branchName
|
|
116
|
+
&& isMainRepairIssue(issue)
|
|
117
|
+
&& issue.factoryState !== "done"))
|
|
118
|
+
.sort((left, right) => this.compareMainRepairCandidates(left, right));
|
|
119
|
+
return candidates[0];
|
|
120
|
+
}
|
|
121
|
+
compareMainRepairCandidates(left, right) {
|
|
122
|
+
const leftPriority = this.rankMainRepairCandidate(left);
|
|
123
|
+
const rightPriority = this.rankMainRepairCandidate(right);
|
|
124
|
+
if (leftPriority !== rightPriority)
|
|
125
|
+
return leftPriority - rightPriority;
|
|
126
|
+
return Date.parse(right.updatedAt) - Date.parse(left.updatedAt);
|
|
127
|
+
}
|
|
128
|
+
rankMainRepairCandidate(issue) {
|
|
129
|
+
if (issue.activeRunId !== undefined)
|
|
130
|
+
return 0;
|
|
131
|
+
if (issue.prState === "open" || issue.factoryState === "awaiting_queue" || issue.factoryState === "pr_open")
|
|
132
|
+
return 1;
|
|
133
|
+
if (issue.factoryState === "delegated" || issue.factoryState === "implementing")
|
|
134
|
+
return 2;
|
|
135
|
+
if (issue.factoryState === "failed" || issue.factoryState === "escalated")
|
|
136
|
+
return 3;
|
|
137
|
+
return 4;
|
|
138
|
+
}
|
|
117
139
|
queueExistingMainRepair(issue, summary, priorityLabel) {
|
|
118
140
|
if (issue.activeRunId !== undefined)
|
|
119
141
|
return;
|
|
@@ -121,6 +143,15 @@ export class MainBranchHealthMonitor {
|
|
|
121
143
|
return;
|
|
122
144
|
if (issue.prState === "open" || issue.factoryState === "awaiting_queue" || issue.factoryState === "pr_open")
|
|
123
145
|
return;
|
|
146
|
+
this.db.upsertIssue({
|
|
147
|
+
projectId: issue.projectId,
|
|
148
|
+
linearIssueId: issue.linearIssueId,
|
|
149
|
+
delegatedToPatchRelay: true,
|
|
150
|
+
factoryState: "delegated",
|
|
151
|
+
pendingRunType: null,
|
|
152
|
+
pendingRunContextJson: null,
|
|
153
|
+
activeRunId: null,
|
|
154
|
+
});
|
|
124
155
|
this.db.issueSessions.appendIssueSessionEventRespectingActiveLease(issue.projectId, issue.linearIssueId, {
|
|
125
156
|
projectId: issue.projectId,
|
|
126
157
|
linearIssueId: issue.linearIssueId,
|
|
@@ -131,6 +162,7 @@ export class MainBranchHealthMonitor {
|
|
|
131
162
|
failingChecks: summary.failingChecks,
|
|
132
163
|
pendingChecks: summary.pendingChecks,
|
|
133
164
|
priorityLabel,
|
|
165
|
+
promptContext: buildMainRepairPromptContext(this.config.projects.find((project) => project.id === issue.projectId) ?? { id: issue.projectId }, summary, priorityLabel),
|
|
134
166
|
}),
|
|
135
167
|
dedupeKey: `main_repair:${issue.projectId}:${summary.baseSha}:${summary.failingChecks.map((check) => check.name).join("|")}`,
|
|
136
168
|
});
|
|
@@ -323,6 +323,23 @@ function buildCiRepairContext(context) {
|
|
|
323
323
|
: "",
|
|
324
324
|
].filter(Boolean).join("\n");
|
|
325
325
|
}
|
|
326
|
+
function buildMainRepairContext(context) {
|
|
327
|
+
const failingCheckNames = Array.isArray(context?.failingChecks)
|
|
328
|
+
? context.failingChecks
|
|
329
|
+
.filter((entry) => Boolean(entry) && typeof entry === "object")
|
|
330
|
+
.map((entry) => String(entry.name ?? "").trim())
|
|
331
|
+
.filter((name) => name.length > 0)
|
|
332
|
+
: [];
|
|
333
|
+
return [
|
|
334
|
+
"Base-branch repair on the red mainline.",
|
|
335
|
+
"Goal: restore main by fixing the real persistent failure, not by papering over a transient runner incident.",
|
|
336
|
+
"Before changing code or workflow config, verify that the original incident still persists on the exact failing main SHA or identify a concrete log signature that justifies the fix.",
|
|
337
|
+
"For transient infrastructure symptoms such as disk pressure, runner exhaustion, or network flakiness, prefer a rerun-only repair if the rerun clears the branch.",
|
|
338
|
+
"Do not propose or implement moving CI, deploy, or tests onto different nodes or runner pools unless a human explicitly asked for that infrastructure migration.",
|
|
339
|
+
context?.baseSha ? `Failing main SHA: ${String(context.baseSha)}` : "",
|
|
340
|
+
failingCheckNames.length > 0 ? `Failing checks: ${failingCheckNames.join(", ")}` : "",
|
|
341
|
+
].filter(Boolean).join("\n");
|
|
342
|
+
}
|
|
326
343
|
function appendQueueRepairContext(lines, context) {
|
|
327
344
|
const queueContext = context?.mergeQueueContext;
|
|
328
345
|
if (!queueContext || typeof queueContext !== "object") {
|
|
@@ -433,6 +450,9 @@ function buildCurrentContext(runType, issue, context, followUp = false) {
|
|
|
433
450
|
}
|
|
434
451
|
lines.push(...buildHumanContextLines(context));
|
|
435
452
|
switch (runType) {
|
|
453
|
+
case "main_repair":
|
|
454
|
+
lines.push(buildMainRepairContext(context));
|
|
455
|
+
break;
|
|
436
456
|
case "ci_repair":
|
|
437
457
|
lines.push(buildCiRepairContext(context));
|
|
438
458
|
break;
|