@urateam/core 0.1.55 → 0.1.56
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/__tests__/auth-monitor.test.js +119 -20
- package/dist/__tests__/auth-monitor.test.js.map +1 -1
- package/dist/__tests__/bec-238-repro.test.d.ts +2 -0
- package/dist/__tests__/bec-238-repro.test.d.ts.map +1 -0
- package/dist/__tests__/bec-238-repro.test.js +116 -0
- package/dist/__tests__/bec-238-repro.test.js.map +1 -0
- package/dist/__tests__/bec146-repro.test.d.ts +2 -0
- package/dist/__tests__/bec146-repro.test.d.ts.map +1 -0
- package/dist/__tests__/bec146-repro.test.js +153 -0
- package/dist/__tests__/bec146-repro.test.js.map +1 -0
- package/dist/__tests__/db-migrations.test.js +7 -3
- package/dist/__tests__/db-migrations.test.js.map +1 -1
- package/dist/__tests__/decision-artifact-schema.test.d.ts +2 -0
- package/dist/__tests__/decision-artifact-schema.test.d.ts.map +1 -0
- package/dist/__tests__/decision-artifact-schema.test.js +45 -0
- package/dist/__tests__/decision-artifact-schema.test.js.map +1 -0
- package/dist/__tests__/decisions-parser.test.d.ts +2 -0
- package/dist/__tests__/decisions-parser.test.d.ts.map +1 -0
- package/dist/__tests__/decisions-parser.test.js +59 -0
- package/dist/__tests__/decisions-parser.test.js.map +1 -0
- package/dist/__tests__/decisions-store.test.d.ts +2 -0
- package/dist/__tests__/decisions-store.test.d.ts.map +1 -0
- package/dist/__tests__/decisions-store.test.js +68 -0
- package/dist/__tests__/decisions-store.test.js.map +1 -0
- package/dist/__tests__/decisions-table-migration.test.d.ts +2 -0
- package/dist/__tests__/decisions-table-migration.test.d.ts.map +1 -0
- package/dist/__tests__/decisions-table-migration.test.js +56 -0
- package/dist/__tests__/decisions-table-migration.test.js.map +1 -0
- package/dist/__tests__/execute-stage-session-opts.test.js +1 -0
- package/dist/__tests__/execute-stage-session-opts.test.js.map +1 -1
- package/dist/__tests__/executor-issue-id.test.js +1 -0
- package/dist/__tests__/executor-issue-id.test.js.map +1 -1
- package/dist/__tests__/extract-handoff-decisions.test.d.ts +2 -0
- package/dist/__tests__/extract-handoff-decisions.test.d.ts.map +1 -0
- package/dist/__tests__/extract-handoff-decisions.test.js +26 -0
- package/dist/__tests__/extract-handoff-decisions.test.js.map +1 -0
- package/dist/__tests__/force-push-agent-branches.test.js +38 -15
- package/dist/__tests__/force-push-agent-branches.test.js.map +1 -1
- package/dist/__tests__/github-webhook.test.js +117 -0
- package/dist/__tests__/github-webhook.test.js.map +1 -1
- package/dist/__tests__/implement-template-decisions.test.d.ts +2 -0
- package/dist/__tests__/implement-template-decisions.test.d.ts.map +1 -0
- package/dist/__tests__/implement-template-decisions.test.js +41 -0
- package/dist/__tests__/implement-template-decisions.test.js.map +1 -0
- package/dist/__tests__/migrator.test.js +137 -39
- package/dist/__tests__/migrator.test.js.map +1 -1
- package/dist/__tests__/pipeline-runner.test.js +118 -0
- package/dist/__tests__/pipeline-runner.test.js.map +1 -1
- package/dist/__tests__/pm-conflict.test.js +145 -5
- package/dist/__tests__/pm-conflict.test.js.map +1 -1
- package/dist/__tests__/preflight-claude-auth.test.js +3 -2
- package/dist/__tests__/preflight-claude-auth.test.js.map +1 -1
- package/dist/__tests__/ralph-review-fix-regression.test.js +1 -0
- package/dist/__tests__/ralph-review-fix-regression.test.js.map +1 -1
- package/dist/__tests__/ralph.test.js +1 -0
- package/dist/__tests__/ralph.test.js.map +1 -1
- package/dist/__tests__/release-manager-qarun-query.test.d.ts +2 -0
- package/dist/__tests__/release-manager-qarun-query.test.d.ts.map +1 -0
- package/dist/__tests__/release-manager-qarun-query.test.js +233 -0
- package/dist/__tests__/release-manager-qarun-query.test.js.map +1 -0
- package/dist/__tests__/release-manager-scheduler.test.js +62 -0
- package/dist/__tests__/release-manager-scheduler.test.js.map +1 -1
- package/dist/__tests__/session-lazy-creation.test.js +1 -0
- package/dist/__tests__/session-lazy-creation.test.js.map +1 -1
- package/dist/__tests__/session-resolver.test.d.ts +13 -0
- package/dist/__tests__/session-resolver.test.d.ts.map +1 -0
- package/dist/__tests__/session-resolver.test.js +152 -0
- package/dist/__tests__/session-resolver.test.js.map +1 -0
- package/dist/__tests__/session-resume-fallback.test.js +1 -0
- package/dist/__tests__/session-resume-fallback.test.js.map +1 -1
- package/dist/__tests__/stage-models.test.js +1 -0
- package/dist/__tests__/stage-models.test.js.map +1 -1
- package/dist/__tests__/surgical-review-fix-prompt.test.d.ts +2 -0
- package/dist/__tests__/surgical-review-fix-prompt.test.d.ts.map +1 -0
- package/dist/__tests__/surgical-review-fix-prompt.test.js +71 -0
- package/dist/__tests__/surgical-review-fix-prompt.test.js.map +1 -0
- package/dist/__tests__/surgical-review-fix-runner.test.d.ts +2 -0
- package/dist/__tests__/surgical-review-fix-runner.test.d.ts.map +1 -0
- package/dist/__tests__/surgical-review-fix-runner.test.js +171 -0
- package/dist/__tests__/surgical-review-fix-runner.test.js.map +1 -0
- package/dist/__tests__/validate-run-mode.test.js +1 -0
- package/dist/__tests__/validate-run-mode.test.js.map +1 -1
- package/dist/__tests__/validate.test.js +1 -0
- package/dist/__tests__/validate.test.js.map +1 -1
- package/dist/audit/auth-error-messages.d.ts +6 -0
- package/dist/audit/auth-error-messages.d.ts.map +1 -0
- package/dist/audit/auth-error-messages.js +18 -0
- package/dist/audit/auth-error-messages.js.map +1 -0
- package/dist/audit/events.d.ts +22 -4
- package/dist/audit/events.d.ts.map +1 -1
- package/dist/audit/events.js +34 -5
- package/dist/audit/events.js.map +1 -1
- package/dist/audit/index.d.ts +1 -0
- package/dist/audit/index.d.ts.map +1 -1
- package/dist/audit/index.js +1 -0
- package/dist/audit/index.js.map +1 -1
- package/dist/db/client.d.ts.map +1 -1
- package/dist/db/client.js +10 -0
- package/dist/db/client.js.map +1 -1
- package/dist/db/decisions-store.d.ts +25 -0
- package/dist/db/decisions-store.d.ts.map +1 -0
- package/dist/db/decisions-store.js +56 -0
- package/dist/db/decisions-store.js.map +1 -0
- package/dist/db/index.d.ts +1 -1
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/index.js +1 -1
- package/dist/db/index.js.map +1 -1
- package/dist/db/migrations/postgres/008_sso.sql +9 -20
- package/dist/db/migrations/postgres/009_review_model_runs.sql +9 -18
- package/dist/db/migrations/postgres/009_sso.sql +20 -0
- package/dist/db/migrations/postgres/010_release_manager.sql +9 -38
- package/dist/db/migrations/postgres/010_review_model_runs.sql +18 -0
- package/dist/db/migrations/postgres/011_qa_run_columns.sql +9 -8
- package/dist/db/migrations/postgres/011_release_manager.sql +38 -0
- package/dist/db/migrations/postgres/012_qa_gap_issues.sql +9 -18
- package/dist/db/migrations/postgres/012_qa_run_columns.sql +8 -0
- package/dist/db/migrations/postgres/013_qa_gap_issues.sql +18 -0
- package/dist/db/migrations/postgres/013_stage_runs_cache_tokens.sql +11 -6
- package/dist/db/migrations/postgres/014_missing_indexes.sql +9 -28
- package/dist/db/migrations/postgres/014_stage_runs_cache_tokens.sql +6 -0
- package/dist/db/migrations/postgres/015_missing_indexes.sql +28 -0
- package/dist/db/migrations/postgres/015_triage_results.sql +9 -11
- package/dist/db/migrations/postgres/016_triage_results.sql +11 -0
- package/dist/db/migrations/sqlite/007_sso.sql +9 -20
- package/dist/db/migrations/sqlite/008_review_model_runs.sql +9 -18
- package/dist/db/migrations/sqlite/008_sso.sql +20 -0
- package/dist/db/migrations/sqlite/009_release_manager.sql +9 -43
- package/dist/db/migrations/sqlite/009_review_model_runs.sql +18 -0
- package/dist/db/migrations/sqlite/010_qa_run_columns.sql +9 -9
- package/dist/db/migrations/sqlite/010_release_manager.sql +43 -0
- package/dist/db/migrations/sqlite/011_qa_gap_issues.sql +9 -22
- package/dist/db/migrations/sqlite/011_qa_run_columns.sql +9 -0
- package/dist/db/migrations/sqlite/012_qa_gap_issues.sql +22 -0
- package/dist/db/migrations/sqlite/012_stage_runs_cache_tokens.sql +11 -6
- package/dist/db/migrations/sqlite/013_missing_indexes.sql +10 -28
- package/dist/db/migrations/sqlite/013_stage_runs_cache_tokens.sql +6 -0
- package/dist/db/migrations/sqlite/013_triage_results.sql +10 -11
- package/dist/db/migrations/sqlite/014_missing_indexes.sql +28 -0
- package/dist/db/migrations/sqlite/015_triage_results.sql +11 -0
- package/dist/db/migrator.d.ts +45 -2
- package/dist/db/migrator.d.ts.map +1 -1
- package/dist/db/migrator.js +113 -29
- package/dist/db/migrator.js.map +1 -1
- package/dist/db/schema.d.ts +125 -0
- package/dist/db/schema.d.ts.map +1 -1
- package/dist/db/schema.js +13 -0
- package/dist/db/schema.js.map +1 -1
- package/dist/executor/auth-monitor.d.ts.map +1 -1
- package/dist/executor/auth-monitor.js +39 -30
- package/dist/executor/auth-monitor.js.map +1 -1
- package/dist/executor/deep-review.d.ts.map +1 -1
- package/dist/executor/deep-review.js +14 -79
- package/dist/executor/deep-review.js.map +1 -1
- package/dist/executor/executor.d.ts +21 -0
- package/dist/executor/executor.d.ts.map +1 -1
- package/dist/executor/executor.js +41 -90
- package/dist/executor/executor.js.map +1 -1
- package/dist/executor/extract-handoff.d.ts +9 -0
- package/dist/executor/extract-handoff.d.ts.map +1 -1
- package/dist/executor/extract-handoff.js +48 -0
- package/dist/executor/extract-handoff.js.map +1 -1
- package/dist/executor/handoff.d.ts +10 -1
- package/dist/executor/handoff.d.ts.map +1 -1
- package/dist/executor/handoff.js +7 -1
- package/dist/executor/handoff.js.map +1 -1
- package/dist/executor/index.d.ts +1 -0
- package/dist/executor/index.d.ts.map +1 -1
- package/dist/executor/index.js +1 -0
- package/dist/executor/index.js.map +1 -1
- package/dist/executor/prompt/templates.d.ts +12 -1
- package/dist/executor/prompt/templates.d.ts.map +1 -1
- package/dist/executor/prompt/templates.js +64 -0
- package/dist/executor/prompt/templates.js.map +1 -1
- package/dist/executor/session-resolver.d.ts +51 -0
- package/dist/executor/session-resolver.d.ts.map +1 -0
- package/dist/executor/session-resolver.js +83 -0
- package/dist/executor/session-resolver.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/notifier/composite.js +1 -1
- package/dist/notifier/composite.js.map +1 -1
- package/dist/notifier/linear.d.ts +1 -1
- package/dist/notifier/linear.d.ts.map +1 -1
- package/dist/notifier/linear.js +49 -9
- package/dist/notifier/linear.js.map +1 -1
- package/dist/pipeline/run-surgical-review-fix.d.ts +29 -0
- package/dist/pipeline/run-surgical-review-fix.d.ts.map +1 -0
- package/dist/pipeline/run-surgical-review-fix.js +48 -0
- package/dist/pipeline/run-surgical-review-fix.js.map +1 -0
- package/dist/pipeline/runner.d.ts.map +1 -1
- package/dist/pipeline/runner.js +132 -36
- package/dist/pipeline/runner.js.map +1 -1
- package/dist/pm/conflict.d.ts +2 -0
- package/dist/pm/conflict.d.ts.map +1 -1
- package/dist/pm/conflict.js +59 -9
- package/dist/pm/conflict.js.map +1 -1
- package/dist/pm/scheduler.d.ts +2 -0
- package/dist/pm/scheduler.d.ts.map +1 -1
- package/dist/pm/scheduler.js +51 -43
- package/dist/pm/scheduler.js.map +1 -1
- package/dist/pm/slack.d.ts +11 -0
- package/dist/pm/slack.d.ts.map +1 -1
- package/dist/pm/slack.js +48 -5
- package/dist/pm/slack.js.map +1 -1
- package/dist/release-manager/release-helpers.d.ts +19 -2
- package/dist/release-manager/release-helpers.d.ts.map +1 -1
- package/dist/release-manager/release-helpers.js +22 -3
- package/dist/release-manager/release-helpers.js.map +1 -1
- package/dist/release-manager/release-tick.d.ts.map +1 -1
- package/dist/release-manager/release-tick.js +20 -8
- package/dist/release-manager/release-tick.js.map +1 -1
- package/dist/release-manager/state.d.ts.map +1 -1
- package/dist/release-manager/state.js +25 -18
- package/dist/release-manager/state.js.map +1 -1
- package/dist/types.d.ts +232 -13
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +52 -0
- package/dist/types.js.map +1 -1
- package/dist/webhook/github-handler.d.ts +2 -2
- package/dist/webhook/github-handler.d.ts.map +1 -1
- package/dist/webhook/github-handler.js +18 -6
- package/dist/webhook/github-handler.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/pipeline/runner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,UAAU,EAEV,QAAQ,EACR,WAAW,EAEX,cAAc,
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/pipeline/runner.ts"],"names":[],"mappings":"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"}
|
package/dist/pipeline/runner.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ResumePayloadSchema } from "../types.js"; // value import — cannot be `import type`
|
|
1
2
|
import { pipelineRuns, stageRuns, reviewModelRuns } from "../db/schema.js";
|
|
2
3
|
import { formatPRCostSummary, } from "./cost-summary.js";
|
|
3
4
|
import { executeStage } from "../executor/executor.js";
|
|
@@ -16,7 +17,7 @@ import { DEFAULT_AGENT_CLAUDE_MD } from "../executor/agent-config.js";
|
|
|
16
17
|
import { generatePRDescription } from "./pr-description.js";
|
|
17
18
|
import { maybePostChangeSummary } from "./pr-change-summary.js";
|
|
18
19
|
import { access, writeFile, appendFile } from "node:fs/promises";
|
|
19
|
-
import { join, resolve } from "node:path";
|
|
20
|
+
import { join, resolve, sep } from "node:path";
|
|
20
21
|
import { homedir } from "node:os";
|
|
21
22
|
import { execFile as execFileCb } from "node:child_process";
|
|
22
23
|
import { promisify } from "node:util";
|
|
@@ -48,12 +49,30 @@ import { runTypecheck } from "./typecheck-gate.js";
|
|
|
48
49
|
import { checkSpecVsImpl } from "./spec-vs-impl-gate.js";
|
|
49
50
|
import { countNewPublicExports, shouldAutoDeepReview, DEFAULT_AUTO_DEEP_REVIEW_THRESHOLDS, } from "./auto-deep-review.js";
|
|
50
51
|
import { startFeedbackPipeline, } from "./feedback-pipeline.js";
|
|
52
|
+
import { runSurgicalReviewFix } from "./run-surgical-review-fix.js";
|
|
51
53
|
// Re-export from extracted module so existing callers (including tests) still
|
|
52
54
|
// find buildReviewFeedbackContext at pipeline/runner.js without changing their
|
|
53
55
|
// import paths.
|
|
54
56
|
export { buildReviewFeedbackContext } from "./feedback-pipeline.js";
|
|
55
57
|
// Module-level logger (no runId yet — used for pre-run messages)
|
|
56
58
|
const log = createLogger({ component: "PipelineRunner" });
|
|
59
|
+
/**
|
|
60
|
+
* Serialise a resume payload to the JSON string stored in
|
|
61
|
+
* `pipeline_runs.resume_payload`. Both the await-approval pause path and the
|
|
62
|
+
* transient-failure retry path use this helper so their serialization stays in
|
|
63
|
+
* sync with `ResumePayloadSchema` — a single place to update if the schema
|
|
64
|
+
* evolves.
|
|
65
|
+
*/
|
|
66
|
+
function buildResumePayload(handoff, pipelineConfig, repoConfig, sanitizedIssue, worktreePath, currentStageIndex) {
|
|
67
|
+
return JSON.stringify({
|
|
68
|
+
handoff,
|
|
69
|
+
pipelineConfig,
|
|
70
|
+
repoConfig,
|
|
71
|
+
sanitizedIssue,
|
|
72
|
+
worktreePath,
|
|
73
|
+
currentStageIndex,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
57
76
|
export class PipelineRunner {
|
|
58
77
|
queue;
|
|
59
78
|
/** Push queue: concurrency=1 serialises push+PR creation within this process.
|
|
@@ -181,15 +200,16 @@ export class PipelineRunner {
|
|
|
181
200
|
.where(eq(pipelineRuns.id, existingRunId));
|
|
182
201
|
return;
|
|
183
202
|
}
|
|
184
|
-
// Look up a paused run in the DB for this issue
|
|
203
|
+
// Look up a paused or retriable run in the DB for this issue.
|
|
204
|
+
// "paused" = awaiting approval; "retriable" = transient failure awaiting manual retry.
|
|
185
205
|
const db = this.db;
|
|
186
206
|
const rows = await db
|
|
187
207
|
.select()
|
|
188
208
|
.from(pipelineRuns)
|
|
189
|
-
.where(and(eq(pipelineRuns.issueId, issueId),
|
|
209
|
+
.where(and(eq(pipelineRuns.issueId, issueId), inArray(pipelineRuns.status, ["paused", "retriable"])))
|
|
190
210
|
.limit(1);
|
|
191
211
|
if (rows.length === 0) {
|
|
192
|
-
resumeLog.info("resume() called but no paused run found in DB — no-op");
|
|
212
|
+
resumeLog.info("resume() called but no paused or retriable run found in DB — no-op");
|
|
193
213
|
return;
|
|
194
214
|
}
|
|
195
215
|
const pausedRun = rows[0];
|
|
@@ -197,6 +217,15 @@ export class PipelineRunner {
|
|
|
197
217
|
const runLog = createLogger({ component: "PipelineRunner", runId, issueId });
|
|
198
218
|
// Claim the slot immediately to prevent concurrent resume() calls
|
|
199
219
|
this.activeRuns.set(issueId, runId);
|
|
220
|
+
// For retriable runs: flip status to "paused" so the PM tick's
|
|
221
|
+
// recoverRetriableRuns() won't find and double-recover this run while
|
|
222
|
+
// execution is queued. The paused-run execution path is identical.
|
|
223
|
+
if (pausedRun.status === "retriable") {
|
|
224
|
+
await db
|
|
225
|
+
.update(pipelineRuns)
|
|
226
|
+
.set({ status: "paused" })
|
|
227
|
+
.where(eq(pipelineRuns.id, runId));
|
|
228
|
+
}
|
|
200
229
|
// Validate that the run has a full resume payload (saved at await-approval)
|
|
201
230
|
if (pausedRun.currentStageIndex == null || !pausedRun.resumePayload) {
|
|
202
231
|
runLog.error("resume payload missing — cannot resume pipeline; marking as failed");
|
|
@@ -211,9 +240,22 @@ export class PipelineRunner {
|
|
|
211
240
|
this.activeRuns.delete(issueId);
|
|
212
241
|
return;
|
|
213
242
|
}
|
|
214
|
-
|
|
243
|
+
// Parse and validate the resume payload using the Zod schema.
|
|
244
|
+
// This replaces the former hand-rolled property-existence checks and catches
|
|
245
|
+
// schema mismatches from older DB rows (e.g. missing handoff, wrong types)
|
|
246
|
+
// before any git or executor operations run.
|
|
247
|
+
//
|
|
248
|
+
// BC: paused runs created before currentStageIndex was added to the payload
|
|
249
|
+
// schema (BEC-192) only have it on the DB row. Inject it from the DB column
|
|
250
|
+
// so those existing in-flight runs don't get falsely failed on first resume
|
|
251
|
+
// after deploy.
|
|
252
|
+
let parsed;
|
|
215
253
|
try {
|
|
216
|
-
|
|
254
|
+
const raw = JSON.parse(pausedRun.resumePayload);
|
|
255
|
+
if (raw.currentStageIndex === undefined && pausedRun.currentStageIndex != null) {
|
|
256
|
+
raw.currentStageIndex = pausedRun.currentStageIndex;
|
|
257
|
+
}
|
|
258
|
+
parsed = ResumePayloadSchema.safeParse(raw);
|
|
217
259
|
}
|
|
218
260
|
catch {
|
|
219
261
|
runLog.error("resume payload is invalid JSON — failing run");
|
|
@@ -228,26 +270,33 @@ export class PipelineRunner {
|
|
|
228
270
|
this.activeRuns.delete(issueId);
|
|
229
271
|
return;
|
|
230
272
|
}
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
runLog.error("resume payload has invalid structure — failing run");
|
|
273
|
+
if (!parsed.success) {
|
|
274
|
+
const zodErrors = parsed.error.issues
|
|
275
|
+
.map((e) => `${e.path.join(".") || "(root)"}: ${e.message}`)
|
|
276
|
+
.join("; ");
|
|
277
|
+
runLog.error({ zodErrors }, "resume payload failed schema validation — failing run");
|
|
237
278
|
await db
|
|
238
279
|
.update(pipelineRuns)
|
|
239
280
|
.set({
|
|
240
281
|
status: "failed",
|
|
241
282
|
completedAt: new Date(),
|
|
242
|
-
errorMessage:
|
|
283
|
+
errorMessage: `Invalid resume payload structure — cannot resume: ${zodErrors}`,
|
|
243
284
|
})
|
|
244
285
|
.where(eq(pipelineRuns.id, runId));
|
|
245
286
|
this.activeRuns.delete(issueId);
|
|
246
287
|
return;
|
|
247
288
|
}
|
|
248
|
-
|
|
289
|
+
const { handoff, pipelineConfig, repoConfig, sanitizedIssue, worktreePath, currentStageIndex } = parsed.data;
|
|
290
|
+
// Path containment check — worktreePath must be within agentRunDir.
|
|
291
|
+
// We append sep to agentRunDir before the startsWith check so that a
|
|
292
|
+
// crafted path like /home/ura/data/runs-evil cannot slip past as a prefix match
|
|
293
|
+
// of /home/ura/data/runs. An exact match (resolvedPath === this.agentRunDir)
|
|
294
|
+
// is also accepted for symmetry, even though real worktrees are always subdirs.
|
|
249
295
|
const resolvedPath = resolve(worktreePath); // canonicalize — collapses .. segments
|
|
250
|
-
|
|
296
|
+
const normalizedBase = this.agentRunDir.endsWith(sep)
|
|
297
|
+
? this.agentRunDir
|
|
298
|
+
: this.agentRunDir + sep;
|
|
299
|
+
if (!resolvedPath.startsWith(normalizedBase) && resolvedPath !== this.agentRunDir) {
|
|
251
300
|
runLog.error({ worktreePath, agentRunDir: this.agentRunDir }, "resume: worktreePath outside agentRunDir — failing run");
|
|
252
301
|
await db
|
|
253
302
|
.update(pipelineRuns)
|
|
@@ -306,13 +355,13 @@ export class PipelineRunner {
|
|
|
306
355
|
this.activeRuns.delete(issueId);
|
|
307
356
|
return;
|
|
308
357
|
}
|
|
309
|
-
runLog.info({ stageIndex:
|
|
358
|
+
runLog.info({ stageIndex: currentStageIndex, worktreePath }, "resuming pipeline — re-queuing execution from stage after await-approval");
|
|
310
359
|
this.queue.enqueue(async () => {
|
|
311
360
|
if (!this.activeRuns.has(issueId))
|
|
312
361
|
return;
|
|
313
362
|
try {
|
|
314
363
|
await runWithLogContext({ runId, issueId }, () => this.executePipeline(runId, run, pipelineConfig, repoConfig, sanitizedIssue, pausedRun.branch, {
|
|
315
|
-
startStageIndex:
|
|
364
|
+
startStageIndex: currentStageIndex,
|
|
316
365
|
worktreePath,
|
|
317
366
|
initialHandoff: handoff ?? undefined,
|
|
318
367
|
// BEC-227 — carry the per-run SDK session id across the
|
|
@@ -672,13 +721,7 @@ export class PipelineRunner {
|
|
|
672
721
|
// Save the full resume context so resume() can re-attach the worktree
|
|
673
722
|
// and continue from the next stage with the correct handoff artifact.
|
|
674
723
|
const stageIndex = config.stages.indexOf(stage);
|
|
675
|
-
const resumePayload =
|
|
676
|
-
handoff: handoff ?? null,
|
|
677
|
-
pipelineConfig: config,
|
|
678
|
-
repoConfig,
|
|
679
|
-
sanitizedIssue,
|
|
680
|
-
worktreePath: worktreePath,
|
|
681
|
-
});
|
|
724
|
+
const resumePayload = buildResumePayload(handoff ?? null, config, repoConfig, sanitizedIssue, worktreePath, stageIndex);
|
|
682
725
|
await db
|
|
683
726
|
.update(pipelineRuns)
|
|
684
727
|
.set({
|
|
@@ -820,6 +863,11 @@ export class PipelineRunner {
|
|
|
820
863
|
agentSessionId: runAgentSessionId,
|
|
821
864
|
isFirstResumableStage: isFirstResumableStageForRalph,
|
|
822
865
|
suppressHandoff: suppressRalphHandoff,
|
|
866
|
+
// BEC-227 Phase 4 / Track D — RALPH iteration counter (1..N)
|
|
867
|
+
// surfaces in pipeline_run_decisions.iteration so operators
|
|
868
|
+
// can correlate persisted decisions with the RALPH loop pass
|
|
869
|
+
// that produced them.
|
|
870
|
+
iteration,
|
|
823
871
|
});
|
|
824
872
|
// Accumulate each RALPH iteration's tokens
|
|
825
873
|
run.totalInputTokens += result.inputTokens;
|
|
@@ -933,6 +981,11 @@ export class PipelineRunner {
|
|
|
933
981
|
const validation = await validateHandoff(stage, {
|
|
934
982
|
artifact: result.handoffArtifact,
|
|
935
983
|
structured: result.handoffIsStructured ?? false,
|
|
984
|
+
// BEC-227 Phase 4 / Track D — validator doesn't consume the
|
|
985
|
+
// decisions artifact (Track B's review-fix loop does). The
|
|
986
|
+
// executor already persisted it before returning; we don't
|
|
987
|
+
// need to thread it through validateHandoff.
|
|
988
|
+
decisions: null,
|
|
936
989
|
}, sanitizedIssue, repoConfig, worktreePath, mainStageRunMode);
|
|
937
990
|
validationPassed = validation.valid;
|
|
938
991
|
let lastValidationIssues = validation.issues;
|
|
@@ -971,6 +1024,8 @@ export class PipelineRunner {
|
|
|
971
1024
|
const retryValidation = await validateHandoff(stage, {
|
|
972
1025
|
artifact: result.handoffArtifact,
|
|
973
1026
|
structured: result.handoffIsStructured ?? false,
|
|
1027
|
+
// BEC-227 Phase 4 / Track D — see main-stage call above.
|
|
1028
|
+
decisions: null,
|
|
974
1029
|
}, sanitizedIssue, repoConfig, worktreePath, valRetryRunMode);
|
|
975
1030
|
if (retryValidation.valid) {
|
|
976
1031
|
validationPassed = true;
|
|
@@ -1070,6 +1125,32 @@ export class PipelineRunner {
|
|
|
1070
1125
|
runLog.info({ rfIteration, maxIterations: reviewFixIterations, blockingFindings: blockingCount }, "review-fix loop: re-running stages to address blocking findings");
|
|
1071
1126
|
for (const fixStage of fixStages) {
|
|
1072
1127
|
runLog.info({ stage: fixStage, rfIteration }, "review-fix: executing stage");
|
|
1128
|
+
// BEC-227 Phase 4 / Track B — for the implement fixStage, decide
|
|
1129
|
+
// surgical vs legacy review-fix. Surgical = the per-run SDK session
|
|
1130
|
+
// is intact (JSONL on disk) so we can send a focused
|
|
1131
|
+
// findings-plus-prior-decisions prompt instead of re-running the
|
|
1132
|
+
// full implement template. The audit event fires inside
|
|
1133
|
+
// runSurgicalReviewFix for BOTH paths so operators can monitor
|
|
1134
|
+
// fallback rates.
|
|
1135
|
+
let surgicalPrompt;
|
|
1136
|
+
let surgicalSuppressHandoff = false;
|
|
1137
|
+
if (fixStage === "implement") {
|
|
1138
|
+
const blocking = (handoff?.context?.reviewFindings ?? []).filter((f) => f.severity === "blocking");
|
|
1139
|
+
if (blocking.length > 0) {
|
|
1140
|
+
const decision = await runSurgicalReviewFix({
|
|
1141
|
+
db: this.db,
|
|
1142
|
+
runId,
|
|
1143
|
+
issueId: sanitizedIssue.id,
|
|
1144
|
+
agentSessionId: runAgentSessionId,
|
|
1145
|
+
worktreePath,
|
|
1146
|
+
blockingFindings: blocking,
|
|
1147
|
+
});
|
|
1148
|
+
if (decision.path === "surgical") {
|
|
1149
|
+
surgicalPrompt = decision.prompt;
|
|
1150
|
+
surgicalSuppressHandoff = true;
|
|
1151
|
+
}
|
|
1152
|
+
}
|
|
1153
|
+
}
|
|
1073
1154
|
const isFirstResumableStageForFix = claimFirstResumableStage(fixStage);
|
|
1074
1155
|
const fixResult = await executeStage({
|
|
1075
1156
|
runId,
|
|
@@ -1085,6 +1166,16 @@ export class PipelineRunner {
|
|
|
1085
1166
|
stageModels: config.stageModels,
|
|
1086
1167
|
agentSessionId: runAgentSessionId,
|
|
1087
1168
|
isFirstResumableStage: isFirstResumableStageForFix,
|
|
1169
|
+
// BEC-227 Phase 4 / Track D — review-fix iteration counter
|
|
1170
|
+
// (1..N) for the implement fixStage's decision artifact. Other
|
|
1171
|
+
// fixStages (test/review) don't emit decisions, so the value
|
|
1172
|
+
// is harmless when unused.
|
|
1173
|
+
iteration: rfIteration,
|
|
1174
|
+
// BEC-227 Phase 4 / Track B — undefined when the surgical
|
|
1175
|
+
// decision returned `legacy` (or fixStage !== "implement"),
|
|
1176
|
+
// which preserves the legacy assembled-prompt path.
|
|
1177
|
+
promptOverride: surgicalPrompt,
|
|
1178
|
+
suppressHandoff: surgicalSuppressHandoff,
|
|
1088
1179
|
});
|
|
1089
1180
|
// BEC-134: track latest review stage_run id for fanout persistence.
|
|
1090
1181
|
if (fixStage === "review") {
|
|
@@ -1118,7 +1209,12 @@ export class PipelineRunner {
|
|
|
1118
1209
|
: isFirstResumableStageForFix
|
|
1119
1210
|
? "first-resumed"
|
|
1120
1211
|
: "resumed";
|
|
1121
|
-
const validation = await validateHandoff(fixStage, {
|
|
1212
|
+
const validation = await validateHandoff(fixStage, {
|
|
1213
|
+
artifact: fixResult.handoffArtifact,
|
|
1214
|
+
structured: fixResult.handoffIsStructured ?? false,
|
|
1215
|
+
// BEC-227 Phase 4 / Track D — see main-stage call above.
|
|
1216
|
+
decisions: null,
|
|
1217
|
+
}, sanitizedIssue, repoConfig, worktreePath, fixStageRunMode);
|
|
1122
1218
|
if (!validation.valid) {
|
|
1123
1219
|
runLog.warn({ stage: fixStage, rfIteration, issues: validation.issues }, "review-fix: handoff validation failed");
|
|
1124
1220
|
}
|
|
@@ -1716,6 +1812,11 @@ export class PipelineRunner {
|
|
|
1716
1812
|
}
|
|
1717
1813
|
else {
|
|
1718
1814
|
runLog.warn("push queue: rebase conflicts detected, running implement pass to resolve");
|
|
1815
|
+
// Abort the in-progress rebase so the worktree HEAD returns to the
|
|
1816
|
+
// named branch ref before the agent starts writing new commits.
|
|
1817
|
+
// Without this, HEAD stays detached on the tentative rebase commit
|
|
1818
|
+
// and verifyBranchMatch() (BEC-99 guard) will reject the push.
|
|
1819
|
+
await abortRebase(wtPath);
|
|
1719
1820
|
const isFirstResumableStageForResolve = claimFirstResumableStage("implement");
|
|
1720
1821
|
const resolveResult = await executeStage({
|
|
1721
1822
|
runId,
|
|
@@ -1736,8 +1837,7 @@ export class PipelineRunner {
|
|
|
1736
1837
|
run.totalInputTokens += resolveResult.inputTokens;
|
|
1737
1838
|
run.totalOutputTokens += resolveResult.outputTokens;
|
|
1738
1839
|
if (resolveResult.status !== "completed") {
|
|
1739
|
-
runLog.warn("push queue: conflict resolution failed —
|
|
1740
|
-
await abortRebase(wtPath);
|
|
1840
|
+
runLog.warn("push queue: conflict resolution failed — force-pushing for human review");
|
|
1741
1841
|
rebaseConflict = true;
|
|
1742
1842
|
}
|
|
1743
1843
|
else {
|
|
@@ -1769,9 +1869,11 @@ export class PipelineRunner {
|
|
|
1769
1869
|
const [qualityResult, agentCommits] = await Promise.all([
|
|
1770
1870
|
(async () => {
|
|
1771
1871
|
try {
|
|
1772
|
-
const stored = await
|
|
1872
|
+
const [stored, actualFiles] = await Promise.all([
|
|
1873
|
+
getTriageResult(this.db, sanitizedIssue.id),
|
|
1874
|
+
getChangedFiles(wtPath, repoConfig.defaultBranch),
|
|
1875
|
+
]);
|
|
1773
1876
|
const predicted = stored?.affectedFiles;
|
|
1774
|
-
const actualFiles = await getChangedFiles(wtPath, repoConfig.defaultBranch);
|
|
1775
1877
|
const quality = computeAffectedFilesPredictionQuality(predicted, actualFiles);
|
|
1776
1878
|
await logAuditEvent(this.db, pmTriageQualityScoreEvent({
|
|
1777
1879
|
runId,
|
|
@@ -2437,13 +2539,6 @@ export class PipelineRunner {
|
|
|
2437
2539
|
context.pipelineConfig &&
|
|
2438
2540
|
context.repoConfig &&
|
|
2439
2541
|
context.sanitizedIssue) {
|
|
2440
|
-
const resumePayload = JSON.stringify({
|
|
2441
|
-
handoff: context.handoff ?? null,
|
|
2442
|
-
pipelineConfig: context.pipelineConfig,
|
|
2443
|
-
repoConfig: context.repoConfig,
|
|
2444
|
-
sanitizedIssue: context.sanitizedIssue,
|
|
2445
|
-
worktreePath: context.worktreePath,
|
|
2446
|
-
});
|
|
2447
2542
|
// Store currentStageIndex - 1 so the existing resume path's
|
|
2448
2543
|
// `slice(startStageIndex + 1)` lands back on the failed stage.
|
|
2449
2544
|
// (await-approval stores the completed stage index; we need to re-run the failed one.)
|
|
@@ -2451,6 +2546,7 @@ export class PipelineRunner {
|
|
|
2451
2546
|
// re-runs the full stage list. The await-approval path stores the completed
|
|
2452
2547
|
// stage index; we store failedIndex - 1 so the same +1 offset re-runs the failed stage.
|
|
2453
2548
|
const resumeStageIndex = (context.currentStageIndex ?? 0) - 1;
|
|
2549
|
+
const resumePayload = buildResumePayload(context.handoff ?? null, context.pipelineConfig, context.repoConfig, context.sanitizedIssue, context.worktreePath, resumeStageIndex);
|
|
2454
2550
|
await db
|
|
2455
2551
|
.update(pipelineRuns)
|
|
2456
2552
|
.set({
|