@pourkit/cli 0.0.0-next-20260623021955 → 0.0.0-next-20260624074234

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/cli.js CHANGED
@@ -5082,7 +5082,7 @@ Before handoff, run: pourkit validate-artifact finalizer ${artifactPathInWorktre
5082
5082
 
5083
5083
  // issues/issue-final-review.ts
5084
5084
  import { existsSync as existsSync11, readFileSync as readFileSync12 } from "fs";
5085
- import { isAbsolute as isAbsolute3, join as join11 } from "path";
5085
+ import { isAbsolute as isAbsolute3, join as join11, relative as relative2, sep as sep2 } from "path";
5086
5086
  init_common();
5087
5087
  var ISSUE_FINAL_REVIEW_ARTIFACT_PATH = join11(
5088
5088
  ".pourkit",
@@ -5138,6 +5138,7 @@ async function runIssueFinalReview(options) {
5138
5138
  repoRoot: repoRoot2,
5139
5139
  promptTemplate: agent.promptTemplate,
5140
5140
  validationCommand: `pourkit validate-artifact issue-final-review ${artifactPathInWorktree} --issue-number ${issue.number} --branch-name ${builderBranch} --base-ref origin/${target.baseBranch}`,
5141
+ worktreePath,
5141
5142
  reviewArtifactPath: options.reviewArtifactPath,
5142
5143
  reviewVerdict: options.reviewVerdict
5143
5144
  });
@@ -5347,6 +5348,7 @@ function loadIssueFinalReviewPrompt(options) {
5347
5348
  repoRoot: repoRoot2,
5348
5349
  promptTemplate,
5349
5350
  validationCommand,
5351
+ worktreePath,
5350
5352
  reviewArtifactPath,
5351
5353
  reviewVerdict
5352
5354
  } = options;
@@ -5385,11 +5387,12 @@ Read the selected issue requirements, planning context (including plan and PRD c
5385
5387
  - If validation fails, fix the artifact or safely retouch the worktree as needed, then rerun the same command.
5386
5388
  - Do not finish until the validation command passes.`);
5387
5389
  if (reviewVerdict) {
5390
+ const reviewArtifactPathForPrompt = reviewArtifactPath ? formatReviewArtifactPathForPrompt(worktreePath, reviewArtifactPath) : reviewArtifactPath;
5388
5391
  prompt += `
5389
5392
 
5390
5393
  ## Prior Review Context
5391
5394
 
5392
- - Reviewer Artifact Path: ${reviewArtifactPath}
5395
+ - Reviewer Artifact Path: ${reviewArtifactPathForPrompt}
5393
5396
  - Prior Review Verdict: ${reviewVerdict}`;
5394
5397
  if (reviewVerdict === "PASS_WITH_NOTES") {
5395
5398
  prompt += `
@@ -5398,6 +5401,14 @@ Read the selected issue requirements, planning context (including plan and PRD c
5398
5401
  }
5399
5402
  return prompt;
5400
5403
  }
5404
+ function formatReviewArtifactPathForPrompt(worktreePath, reviewArtifactPath) {
5405
+ if (!isAbsolute3(reviewArtifactPath)) return reviewArtifactPath;
5406
+ const relativePath = relative2(worktreePath, reviewArtifactPath);
5407
+ if (relativePath && relativePath !== ".." && !relativePath.startsWith(`..${sep2}`) && !isAbsolute3(relativePath)) {
5408
+ return relativePath.replace(/\\/g, "/");
5409
+ }
5410
+ return reviewArtifactPath;
5411
+ }
5401
5412
 
5402
5413
  // pr/pr-body.ts
5403
5414
  import { readFile as readFile2 } from "fs/promises";
@@ -6477,6 +6488,61 @@ function isAllowedDocumentationTokenReference(value) {
6477
6488
  return /^token\s*:\s*["']?<verdict>/i.test(value);
6478
6489
  }
6479
6490
 
6491
+ // issues/final-commit.ts
6492
+ init_common();
6493
+ async function runFinalCommit(options) {
6494
+ const { worktreePath, worktreeState, baseRef, title, body, logger } = options;
6495
+ if (worktreeState?.finalCommit?.completed) {
6496
+ const storedSha = worktreeState.finalCommit.sha;
6497
+ if (!storedSha) {
6498
+ throw new Error("Final Commit state is incomplete: missing stored sha");
6499
+ }
6500
+ const revParse2 = await execCapture("git", ["rev-parse", "HEAD"], {
6501
+ cwd: worktreePath,
6502
+ logger,
6503
+ label: "git rev-parse HEAD"
6504
+ });
6505
+ const currentSha = revParse2.stdout.trim();
6506
+ if (currentSha !== storedSha) {
6507
+ throw new Error(
6508
+ `Final Commit state is stale: stored sha ${storedSha} does not match current HEAD ${currentSha}`
6509
+ );
6510
+ }
6511
+ return { status: "skipped", sha: storedSha };
6512
+ }
6513
+ await assertCanonicalBaseAncestor2({
6514
+ worktreePath,
6515
+ baseRef,
6516
+ stageName: "final commit",
6517
+ logger
6518
+ });
6519
+ await execCapture("git", ["reset", "--soft", baseRef], {
6520
+ cwd: worktreePath,
6521
+ logger,
6522
+ label: "git reset"
6523
+ });
6524
+ await execCapture("git", ["add", "-A"], {
6525
+ cwd: worktreePath,
6526
+ logger,
6527
+ label: "git add"
6528
+ });
6529
+ await execCapture("git", ["commit", "--no-verify", "-m", title, "-m", body], {
6530
+ cwd: worktreePath,
6531
+ logger,
6532
+ label: "git commit"
6533
+ });
6534
+ const revParse = await execCapture("git", ["rev-parse", "HEAD"], {
6535
+ cwd: worktreePath,
6536
+ logger,
6537
+ label: "git rev-parse HEAD"
6538
+ });
6539
+ const sha = revParse.stdout.trim();
6540
+ updateWorktreeRunState(worktreePath, {
6541
+ finalCommit: { completed: true, sha }
6542
+ });
6543
+ return { status: "completed", sha };
6544
+ }
6545
+
6480
6546
  // issues/issue-worktree-resolution.ts
6481
6547
  init_common();
6482
6548
  import { join as join14 } from "path";
@@ -6895,35 +6961,20 @@ async function completeIssueRun(options) {
6895
6961
  );
6896
6962
  const prTitle = prDescriptionAgentResult.title;
6897
6963
  const prBody = prDescriptionAgentResult.body;
6898
- const stateBeforeFinalCommit = readCurrentWorktreeState();
6899
- const finalCommitFromState = stateBeforeFinalCommit?.finalCommit?.completed;
6900
- if (!finalCommitFromState) {
6901
- await finalizeWorktreeCommit({
6902
- worktreePath: executionResult.worktreePath,
6903
- baseRef: `origin/${effectiveBaseBranch}`,
6904
- title: prTitle,
6905
- body: prBody,
6906
- logger
6907
- });
6908
- if (executionResult.worktreePath) {
6909
- const revParse = await execCapture("git", ["rev-parse", "HEAD"], {
6910
- cwd: executionResult.worktreePath,
6911
- logger,
6912
- label: "git rev-parse HEAD"
6913
- });
6914
- updateWorktreeRunState(executionResult.worktreePath, {
6915
- finalCommit: {
6916
- completed: true,
6917
- sha: revParse.stdout.trim()
6918
- }
6919
- });
6920
- }
6921
- }
6922
6964
  if (!executionResult.worktreePath) {
6923
6965
  throw new Error(
6924
6966
  "Lifecycle invariant: GitHub Issue Publication requires a worktree path"
6925
6967
  );
6926
6968
  }
6969
+ const stateBeforeFinalCommit = readCurrentWorktreeState();
6970
+ await runFinalCommit({
6971
+ worktreePath: executionResult.worktreePath,
6972
+ worktreeState: stateBeforeFinalCommit,
6973
+ baseRef: `origin/${effectiveBaseBranch}`,
6974
+ title: prTitle,
6975
+ body: prBody,
6976
+ logger
6977
+ });
6927
6978
  const publication = await publishGitHubIssue({
6928
6979
  issue,
6929
6980
  branchName,
@@ -7008,30 +7059,6 @@ function extractHumanHandoffSummary(artifactContent) {
7008
7059
  function getRefactorArtifactDir(artifactPath) {
7009
7060
  return artifactPath.replace(/\/reviewers\//, "/refactors/").replace(/\/[^/]+$/, "");
7010
7061
  }
7011
- async function finalizeWorktreeCommit(options) {
7012
- const { worktreePath, baseRef, title, body, logger } = options;
7013
- await assertCanonicalBaseAncestor2({
7014
- worktreePath,
7015
- baseRef,
7016
- stageName: "final commit",
7017
- logger
7018
- });
7019
- await execCapture("git", ["reset", "--soft", baseRef], {
7020
- cwd: worktreePath,
7021
- logger,
7022
- label: "git reset"
7023
- });
7024
- await execCapture("git", ["add", "-A"], {
7025
- cwd: worktreePath,
7026
- logger,
7027
- label: "git add"
7028
- });
7029
- await execCapture("git", ["commit", "--no-verify", "-m", title, "-m", body], {
7030
- cwd: worktreePath,
7031
- logger,
7032
- label: "git commit"
7033
- });
7034
- }
7035
7062
  function makeIssueTransitions2(provider, config) {
7036
7063
  return createIssueTransitions(
7037
7064
  {
@@ -7385,74 +7412,244 @@ import {
7385
7412
  writeFileSync as writeFileSync4
7386
7413
  } from "fs";
7387
7414
  import { join as join15 } from "path";
7415
+ import { z as z2 } from "zod";
7416
+
7417
+ // prd-run/repair-guidance.ts
7388
7418
  import { z } from "zod";
7419
+ var PrdRunRepairAttemptSchema = z.object({
7420
+ attemptedAt: z.string().min(1),
7421
+ outcome: z.enum(["blocked", "projection-failed", "unsupported-state"]),
7422
+ failureCode: z.string().min(1),
7423
+ summary: z.string().min(1)
7424
+ }).strict();
7425
+ var PrdRunRepairGuidanceSchema = z.object({
7426
+ createdAt: z.string().min(1),
7427
+ updatedAt: z.string().min(1),
7428
+ blockedGate: z.enum([
7429
+ "receipt-check",
7430
+ "branch-state",
7431
+ "git",
7432
+ "queue",
7433
+ "final-review"
7434
+ ]),
7435
+ blockedStage: z.string().min(1),
7436
+ failureCode: z.string().regex(
7437
+ /^[a-z][a-z0-9-]*$/,
7438
+ "failureCode must be kebab-case (lowercase letters, digits, hyphens)"
7439
+ ),
7440
+ humanReadableReason: z.string().min(1),
7441
+ repairability: z.enum([
7442
+ "automatic-retry-safe",
7443
+ "operator-action",
7444
+ "unsupported-state"
7445
+ ]),
7446
+ nextAction: z.string().min(1),
7447
+ nextRecommendedCommand: z.string().min(1),
7448
+ diagnostics: z.array(z.string()).optional(),
7449
+ offendingPaths: z.array(z.string()).optional(),
7450
+ issue: z.object({
7451
+ number: z.number().int().positive(),
7452
+ title: z.string().optional(),
7453
+ branch: z.string().optional(),
7454
+ worktreePath: z.string().optional()
7455
+ }).strict().optional(),
7456
+ pr: z.object({
7457
+ number: z.number().int().positive().optional(),
7458
+ url: z.string().url().optional()
7459
+ }).strict().optional(),
7460
+ attemptHistory: z.array(PrdRunRepairAttemptSchema).optional(),
7461
+ targetName: z.string().min(1).optional(),
7462
+ baseBranch: z.string().min(1).optional()
7463
+ }).strict();
7464
+ function buildPrdRunRepairGuidance(input) {
7465
+ const now = (/* @__PURE__ */ new Date()).toISOString();
7466
+ return PrdRunRepairGuidanceSchema.parse({
7467
+ createdAt: now,
7468
+ updatedAt: now,
7469
+ blockedGate: input.blockedGate,
7470
+ blockedStage: input.blockedStage,
7471
+ failureCode: input.failureCode,
7472
+ humanReadableReason: input.humanReadableReason,
7473
+ repairability: input.repairability,
7474
+ nextAction: input.nextAction,
7475
+ nextRecommendedCommand: input.nextRecommendedCommand,
7476
+ diagnostics: input.diagnostics,
7477
+ offendingPaths: input.offendingPaths,
7478
+ issue: input.issue,
7479
+ pr: input.pr,
7480
+ targetName: input.targetName,
7481
+ baseBranch: input.baseBranch,
7482
+ attemptHistory: void 0
7483
+ });
7484
+ }
7485
+ function appendPrdRunRepairAttempt(guidance, attempt) {
7486
+ const newAttempt = {
7487
+ attemptedAt: attempt.attemptedAt ?? (/* @__PURE__ */ new Date()).toISOString(),
7488
+ outcome: attempt.outcome,
7489
+ failureCode: attempt.failureCode,
7490
+ summary: attempt.summary
7491
+ };
7492
+ const history = [...guidance.attemptHistory ?? [], newAttempt].slice(-5);
7493
+ return PrdRunRepairGuidanceSchema.parse({
7494
+ ...guidance,
7495
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
7496
+ attemptHistory: history
7497
+ });
7498
+ }
7499
+ function validateActivePrdRunRepairGuidance(record) {
7500
+ const now = (/* @__PURE__ */ new Date()).toISOString();
7501
+ if (record.repairGuidance) {
7502
+ const parsed = PrdRunRepairGuidanceSchema.safeParse(record.repairGuidance);
7503
+ if (parsed.success) {
7504
+ return { ok: true, guidance: parsed.data };
7505
+ }
7506
+ return {
7507
+ ok: false,
7508
+ guidance: {
7509
+ createdAt: now,
7510
+ updatedAt: now,
7511
+ blockedGate: record.blockedGate ?? "queue",
7512
+ blockedStage: "unknown",
7513
+ failureCode: "malformed-repair-guidance",
7514
+ humanReadableReason: "Repair guidance state is malformed or invalid. Inspect the PRD Run record.",
7515
+ repairability: "unsupported-state",
7516
+ nextAction: "inspect-prd-run-state",
7517
+ nextRecommendedCommand: `pourkit prd-run status ${record.prdRef}`,
7518
+ diagnostics: [
7519
+ `Validation error: ${parsed.error?.message ?? "Unknown schema error"}`
7520
+ ]
7521
+ }
7522
+ };
7523
+ }
7524
+ return {
7525
+ ok: false,
7526
+ guidance: {
7527
+ createdAt: now,
7528
+ updatedAt: now,
7529
+ blockedGate: record.blockedGate ?? "queue",
7530
+ blockedStage: "unknown",
7531
+ failureCode: "missing-repair-guidance",
7532
+ humanReadableReason: "No active repair guidance found for a blocked or unresolved record.",
7533
+ repairability: "unsupported-state",
7534
+ nextAction: "inspect-prd-run-state",
7535
+ nextRecommendedCommand: `pourkit prd-run status ${record.prdRef}`,
7536
+ diagnostics: record.diagnostics ? [...record.diagnostics] : []
7537
+ }
7538
+ };
7539
+ }
7540
+ function renderPrdRunRepairGuidance(guidance) {
7541
+ const lines = [];
7542
+ lines.push(`Blocked Gate: ${guidance.blockedGate}`);
7543
+ lines.push(`Blocked Stage: ${guidance.blockedStage}`);
7544
+ lines.push(`Failure Code: ${guidance.failureCode}`);
7545
+ lines.push(`Reason: ${guidance.humanReadableReason}`);
7546
+ lines.push(`Repairability: ${guidance.repairability}`);
7547
+ lines.push(`Next Action: ${guidance.nextAction}`);
7548
+ lines.push(`Command: ${guidance.nextRecommendedCommand}`);
7549
+ if (guidance.targetName) lines.push(`Target: ${guidance.targetName}`);
7550
+ if (guidance.baseBranch) lines.push(`Base: ${guidance.baseBranch}`);
7551
+ if (guidance.issue) {
7552
+ const issueLine = `Issue: #${guidance.issue.number}${guidance.issue.title ? ` - ${guidance.issue.title}` : ""}`;
7553
+ lines.push(issueLine);
7554
+ if (guidance.issue.branch) lines.push(` Branch: ${guidance.issue.branch}`);
7555
+ if (guidance.issue.worktreePath)
7556
+ lines.push(` Worktree: ${guidance.issue.worktreePath}`);
7557
+ }
7558
+ if (guidance.pr) {
7559
+ if (guidance.pr.url) lines.push(`PR: ${guidance.pr.url}`);
7560
+ else if (guidance.pr.number) lines.push(`PR: #${guidance.pr.number}`);
7561
+ }
7562
+ if (guidance.diagnostics && guidance.diagnostics.length > 0) {
7563
+ lines.push("Diagnostics:");
7564
+ for (const d of guidance.diagnostics) {
7565
+ lines.push(` - ${d}`);
7566
+ }
7567
+ }
7568
+ if (guidance.offendingPaths && guidance.offendingPaths.length > 0) {
7569
+ lines.push("Offending Paths:");
7570
+ for (const p of guidance.offendingPaths) {
7571
+ lines.push(` - ${p}`);
7572
+ }
7573
+ }
7574
+ if (guidance.attemptHistory && guidance.attemptHistory.length > 0) {
7575
+ const latest = guidance.attemptHistory[guidance.attemptHistory.length - 1];
7576
+ lines.push(`Latest Attempt: ${latest.outcome} - ${latest.summary}`);
7577
+ if (guidance.attemptHistory.length > 1) {
7578
+ lines.push(`Total Attempts: ${guidance.attemptHistory.length}`);
7579
+ }
7580
+ }
7581
+ return lines;
7582
+ }
7583
+
7584
+ // prd-run/state.ts
7389
7585
  var PRD_RUN_STATE_DIR = ".pourkit/prd-runs";
7390
- var PrdRunRecordSchema = z.object({
7391
- prdRef: z.string().regex(
7586
+ var PrdRunRecordSchema = z2.object({
7587
+ prdRef: z2.string().regex(
7392
7588
  /^PRD-\d{4}$/,
7393
7589
  "PRD ref must use four-digit format (e.g., PRD-0052)"
7394
7590
  ),
7395
- status: z.enum([
7591
+ status: z2.enum([
7396
7592
  "blocked",
7397
7593
  "starting",
7398
7594
  "running",
7399
7595
  "drained",
7400
7596
  "completed_prd_branch"
7401
7597
  ]),
7402
- updatedAt: z.string().min(1),
7403
- blockedGate: z.enum(["receipt-check", "branch-state", "git", "queue", "final-review"]).optional(),
7404
- targetName: z.string().min(1).optional(),
7405
- prdBranch: z.string().min(1).optional(),
7406
- blockedReason: z.string().min(1).optional(),
7407
- diagnostics: z.array(z.string()).optional(),
7408
- offendingPaths: z.array(z.string()).optional(),
7409
- start: z.object({
7410
- status: z.enum(["started", "succeeded", "adopted", "reused"]),
7411
- targetName: z.string().min(1),
7412
- prdBranch: z.string().min(1),
7413
- startBaseBranch: z.string().min(1),
7414
- startBaseCommit: z.string().min(1).optional(),
7415
- branchAction: z.enum(["created", "reused", "adopted"]).optional(),
7416
- startedAt: z.string().min(1).optional(),
7417
- queueStartedAt: z.string().min(1).optional(),
7418
- queueDrainedAt: z.string().min(1).optional(),
7419
- queueProcessedCount: z.number().int().nonnegative().optional(),
7420
- queueCommand: z.literal("queue-run").optional(),
7421
- refreshReceipts: z.tuple([]).optional()
7598
+ updatedAt: z2.string().min(1),
7599
+ repairGuidance: PrdRunRepairGuidanceSchema.optional(),
7600
+ blockedGate: z2.enum(["receipt-check", "branch-state", "git", "queue", "final-review"]).optional(),
7601
+ targetName: z2.string().min(1).optional(),
7602
+ prdBranch: z2.string().min(1).optional(),
7603
+ blockedReason: z2.string().min(1).optional(),
7604
+ diagnostics: z2.array(z2.string()).optional(),
7605
+ offendingPaths: z2.array(z2.string()).optional(),
7606
+ start: z2.object({
7607
+ status: z2.enum(["started", "succeeded", "adopted", "reused"]),
7608
+ targetName: z2.string().min(1),
7609
+ prdBranch: z2.string().min(1),
7610
+ startBaseBranch: z2.string().min(1),
7611
+ startBaseCommit: z2.string().min(1).optional(),
7612
+ branchAction: z2.enum(["created", "reused", "adopted"]).optional(),
7613
+ startedAt: z2.string().min(1).optional(),
7614
+ queueStartedAt: z2.string().min(1).optional(),
7615
+ queueDrainedAt: z2.string().min(1).optional(),
7616
+ queueProcessedCount: z2.number().int().nonnegative().optional(),
7617
+ queueCommand: z2.literal("queue-run").optional(),
7618
+ refreshReceipts: z2.tuple([]).optional()
7422
7619
  }).strict().optional(),
7423
- finalReview: z.object({
7424
- status: z.enum([
7620
+ finalReview: z2.object({
7621
+ status: z2.enum([
7425
7622
  "started",
7426
7623
  "succeeded",
7427
7624
  "blocked",
7428
7625
  "needs_human_review",
7429
7626
  "final_reviewed"
7430
7627
  ]),
7431
- targetName: z.string().min(1),
7432
- prdBranch: z.string().min(1),
7433
- mergeBase: z.string().min(1).optional(),
7434
- verdict: z.enum([
7628
+ targetName: z2.string().min(1),
7629
+ prdBranch: z2.string().min(1),
7630
+ mergeBase: z2.string().min(1).optional(),
7631
+ verdict: z2.enum([
7435
7632
  "pass_no_changes",
7436
7633
  "pass_with_retouch",
7437
7634
  "needs_human_review",
7438
7635
  "blocked"
7439
7636
  ]).optional(),
7440
- artifactPath: z.string().min(1).optional(),
7441
- diagnostics: z.array(z.string()).optional(),
7442
- reviewedAt: z.string().min(1).optional(),
7443
- retouchPrNumber: z.number().int().positive().optional(),
7444
- retouchPrUrl: z.string().url().optional(),
7445
- retouchMergeCommit: z.string().min(1).optional(),
7446
- autoMerge: z.boolean().optional(),
7447
- changedPaths: z.array(z.string()).optional()
7637
+ artifactPath: z2.string().min(1).optional(),
7638
+ diagnostics: z2.array(z2.string()).optional(),
7639
+ reviewedAt: z2.string().min(1).optional(),
7640
+ retouchPrNumber: z2.number().int().positive().optional(),
7641
+ retouchPrUrl: z2.string().url().optional(),
7642
+ retouchMergeCommit: z2.string().min(1).optional(),
7643
+ autoMerge: z2.boolean().optional(),
7644
+ changedPaths: z2.array(z2.string()).optional()
7448
7645
  }).strict().optional(),
7449
- scopeChanges: z.array(
7450
- z.object({
7451
- issueNumber: z.number().int().positive(),
7452
- decision: z.literal("accepted_scope_change"),
7453
- reason: z.string().min(1),
7454
- acceptedBy: z.string().min(1),
7455
- acceptedAt: z.string().min(1)
7646
+ scopeChanges: z2.array(
7647
+ z2.object({
7648
+ issueNumber: z2.number().int().positive(),
7649
+ decision: z2.literal("accepted_scope_change"),
7650
+ reason: z2.string().min(1),
7651
+ acceptedBy: z2.string().min(1),
7652
+ acceptedAt: z2.string().min(1)
7456
7653
  }).strict()
7457
7654
  ).optional()
7458
7655
  }).strict();
@@ -7489,6 +7686,26 @@ function readPrdRun(repoRoot2, prdRef) {
7489
7686
  }
7490
7687
  } catch {
7491
7688
  }
7689
+ try {
7690
+ const raw = JSON.parse(readFileSync15(recordPath, "utf-8"));
7691
+ if (raw && typeof raw === "object" && raw.status === "blocked" && raw.repairGuidance !== void 0) {
7692
+ const { repairGuidance: _unused, ...rawWithoutGuidance } = raw;
7693
+ const baseRecord = PrdRunRecordSchema.omit({
7694
+ repairGuidance: true
7695
+ }).parse(rawWithoutGuidance);
7696
+ return {
7697
+ record: {
7698
+ ...baseRecord,
7699
+ repairGuidance: raw.repairGuidance
7700
+ },
7701
+ diagnostics: [
7702
+ `Repair guidance validation failed at ${recordPath}`,
7703
+ error instanceof Error ? error.message : String(error)
7704
+ ]
7705
+ };
7706
+ }
7707
+ } catch {
7708
+ }
7492
7709
  return {
7493
7710
  record: null,
7494
7711
  diagnostics: [
@@ -7525,14 +7742,11 @@ function listPrdRuns(repoRoot2) {
7525
7742
  }
7526
7743
  function writePrdRunRecord(repoRoot2, record) {
7527
7744
  const normalized = normalizePrdRunRef(record.prdRef);
7745
+ const parsed = PrdRunRecordSchema.parse({ ...record, prdRef: normalized });
7528
7746
  const stateDir = join15(repoRoot2, PRD_RUN_STATE_DIR);
7529
7747
  const recordPath = getRecordPath(repoRoot2, normalized);
7530
7748
  mkdirSync7(stateDir, { recursive: true });
7531
- writeFileSync4(
7532
- recordPath,
7533
- JSON.stringify({ ...record, prdRef: normalized }, null, 2),
7534
- "utf-8"
7535
- );
7749
+ writeFileSync4(recordPath, JSON.stringify(parsed, null, 2), "utf-8");
7536
7750
  }
7537
7751
  function getRecordPath(repoRoot2, prdRef) {
7538
7752
  return join15(
@@ -7888,24 +8102,45 @@ function runOneQueueIssueEffect(options) {
7888
8102
  prdRef
7889
8103
  } = options;
7890
8104
  return Effect9.gen(function* () {
7891
- const outcome = yield* selectNextQueueIssue({
7892
- config,
7893
- issueProvider,
7894
- logger,
7895
- prdRef
7896
- });
7897
- if (!outcome.ok) {
7898
- return {
7899
- selected: null,
7900
- reason: outcome.reason,
7901
- code: outcome.code
7902
- };
8105
+ const resumeIssueNumber = options.queueRunContext?.resumeIssueNumber;
8106
+ let selectedIssue;
8107
+ if (resumeIssueNumber) {
8108
+ const fetched = yield* Effect9.tryPromise({
8109
+ try: () => issueProvider.fetchIssue(resumeIssueNumber),
8110
+ catch: (e) => {
8111
+ if (e instanceof Error) {
8112
+ return new QueueProviderError(
8113
+ `Failed to fetch resume issue #${resumeIssueNumber}: ${e.message}`
8114
+ );
8115
+ }
8116
+ throw e;
8117
+ }
8118
+ });
8119
+ selectedIssue = fetched;
8120
+ logger.step(
8121
+ "info",
8122
+ `Resuming issue #${selectedIssue.number}: ${selectedIssue.title}`
8123
+ );
8124
+ } else {
8125
+ const outcome = yield* selectNextQueueIssue({
8126
+ config,
8127
+ issueProvider,
8128
+ logger,
8129
+ prdRef
8130
+ });
8131
+ if (!outcome.ok) {
8132
+ return {
8133
+ selected: null,
8134
+ reason: outcome.reason,
8135
+ code: outcome.code
8136
+ };
8137
+ }
8138
+ selectedIssue = outcome.issue;
7903
8139
  }
7904
- const { issue: selected } = outcome;
7905
8140
  const baseBranchOverride = options.queueRunContext?.prdBranch;
7906
8141
  const runResult = yield* Effect9.tryPromise({
7907
8142
  try: () => runIssueCommand({
7908
- issueNumber: selected.number,
8143
+ issueNumber: selectedIssue.number,
7909
8144
  targetName,
7910
8145
  config,
7911
8146
  issueProvider,
@@ -7936,7 +8171,7 @@ function runOneQueueIssueEffect(options) {
7936
8171
  logger.raw(` PR URL: ${runResult.prUrl}`);
7937
8172
  }
7938
8173
  logger.raw(` Target: ${runResult.target.name}`);
7939
- return { selected, runResult };
8174
+ return { selected: selectedIssue, runResult };
7940
8175
  });
7941
8176
  }
7942
8177
  function runQueue(options) {
@@ -7960,6 +8195,19 @@ function runQueueLoopEffect(options, results) {
7960
8195
  };
7961
8196
  }
7962
8197
  const newResults = [...results, outcome];
8198
+ if (options.queueRunContext?.resumeIssueNumber !== void 0) {
8199
+ return {
8200
+ drained: true,
8201
+ processedCount: newResults.length,
8202
+ results: newResults,
8203
+ selected: null,
8204
+ reason: "Resumed issue processed.",
8205
+ code: "drained",
8206
+ allProcessedIssuesFinalizedIntoPrdBranch: Boolean(options.queueRunContext?.prdBranch) && newResults.length > 0 && newResults.every(
8207
+ (result) => result.runResult.publicationStatus === "merged"
8208
+ )
8209
+ };
8210
+ }
7963
8211
  const processedIssue = yield* Effect9.tryPromise({
7964
8212
  try: () => options.issueProvider.fetchIssue(outcome.selected.number),
7965
8213
  catch: (e) => {
@@ -8005,72 +8253,79 @@ function validatePrdRunStartEvidence(record, context) {
8005
8253
  if (!record.start) {
8006
8254
  return {
8007
8255
  ok: false,
8008
- guidance: {
8256
+ guidance: buildPrdRunRepairGuidance({
8009
8257
  blockedGate: "branch-state",
8010
- failureCode: "missing_start_evidence",
8011
- reason: `PRD Run ${context.prdRef} has no start receipt.`,
8258
+ blockedStage: "branch-materialization",
8259
+ failureCode: "missing-start-evidence",
8260
+ humanReadableReason: `PRD Run ${context.prdRef} has no start receipt.`,
8012
8261
  repairability: "automatic-retry-safe",
8013
- diagnostics: [],
8014
- offendingPaths: []
8015
- }
8262
+ nextAction: "rerun-prd-run-launch",
8263
+ nextRecommendedCommand: "pourkit prd-run launch"
8264
+ })
8016
8265
  };
8017
8266
  }
8018
8267
  if (!record.start.startBaseBranch) {
8019
8268
  return {
8020
8269
  ok: false,
8021
- guidance: {
8270
+ guidance: buildPrdRunRepairGuidance({
8022
8271
  blockedGate: "branch-state",
8023
- failureCode: "missing_start_base_branch",
8024
- reason: `PRD Run ${context.prdRef} start receipt missing startBaseBranch.`,
8272
+ blockedStage: "branch-materialization",
8273
+ failureCode: "missing-start-base-branch",
8274
+ humanReadableReason: `PRD Run ${context.prdRef} start receipt missing startBaseBranch.`,
8025
8275
  repairability: "operator-action",
8026
- diagnostics: [],
8027
- offendingPaths: []
8028
- }
8276
+ nextAction: "inspect-and-retry",
8277
+ nextRecommendedCommand: "pourkit prd-run launch"
8278
+ })
8029
8279
  };
8030
8280
  }
8031
8281
  if (record.start.startBaseBranch !== context.baseBranch) {
8032
8282
  return {
8033
8283
  ok: false,
8034
- guidance: {
8284
+ guidance: buildPrdRunRepairGuidance({
8035
8285
  blockedGate: "branch-state",
8036
- failureCode: "base_mismatch",
8037
- reason: `PRD Run ${context.prdRef} startBaseBranch "${record.start.startBaseBranch}" does not match expected "${context.baseBranch}".`,
8286
+ blockedStage: "branch-materialization",
8287
+ failureCode: "base-mismatch",
8288
+ humanReadableReason: `PRD Run ${context.prdRef} startBaseBranch "${record.start.startBaseBranch}" does not match expected "${context.baseBranch}".`,
8038
8289
  repairability: "operator-action",
8290
+ nextAction: "inspect-and-retry",
8291
+ nextRecommendedCommand: "pourkit prd-run launch",
8039
8292
  diagnostics: [
8040
8293
  `Recorded startBaseBranch: ${record.start.startBaseBranch}`,
8041
8294
  `Expected baseBranch: ${context.baseBranch}`
8042
- ],
8043
- offendingPaths: []
8044
- }
8295
+ ]
8296
+ })
8045
8297
  };
8046
8298
  }
8047
8299
  if (!record.start.prdBranch) {
8048
8300
  return {
8049
8301
  ok: false,
8050
- guidance: {
8302
+ guidance: buildPrdRunRepairGuidance({
8051
8303
  blockedGate: "branch-state",
8052
- failureCode: "missing_prd_branch",
8053
- reason: `PRD Run ${context.prdRef} start receipt missing prdBranch.`,
8304
+ blockedStage: "branch-materialization",
8305
+ failureCode: "missing-prd-branch",
8306
+ humanReadableReason: `PRD Run ${context.prdRef} start receipt missing prdBranch.`,
8054
8307
  repairability: "operator-action",
8055
- diagnostics: [],
8056
- offendingPaths: []
8057
- }
8308
+ nextAction: "inspect-and-retry",
8309
+ nextRecommendedCommand: "pourkit prd-run launch"
8310
+ })
8058
8311
  };
8059
8312
  }
8060
8313
  if (record.prdRef !== context.prdRef) {
8061
8314
  return {
8062
8315
  ok: false,
8063
- guidance: {
8316
+ guidance: buildPrdRunRepairGuidance({
8064
8317
  blockedGate: "branch-state",
8065
- failureCode: "prd_ref_mismatch",
8066
- reason: `PRD Run prdRef mismatch: "${record.prdRef}" does not match expected "${context.prdRef}".`,
8318
+ blockedStage: "branch-materialization",
8319
+ failureCode: "prd-ref-mismatch",
8320
+ humanReadableReason: `PRD Run prdRef mismatch: "${record.prdRef}" does not match expected "${context.prdRef}".`,
8067
8321
  repairability: "operator-action",
8322
+ nextAction: "inspect-and-retry",
8323
+ nextRecommendedCommand: "pourkit prd-run launch",
8068
8324
  diagnostics: [
8069
8325
  `Recorded prdRef: ${record.prdRef}`,
8070
8326
  `Expected prdRef: ${context.prdRef}`
8071
- ],
8072
- offendingPaths: []
8073
- }
8327
+ ]
8328
+ })
8074
8329
  };
8075
8330
  }
8076
8331
  return { ok: true };
@@ -8080,95 +8335,104 @@ function validatePrdRunDrainEvidence(record, context) {
8080
8335
  if (!start) {
8081
8336
  return {
8082
8337
  ok: false,
8083
- guidance: {
8338
+ guidance: buildPrdRunRepairGuidance({
8084
8339
  blockedGate: "queue",
8085
- failureCode: "missing_drain_evidence",
8086
- reason: `PRD Run ${context.prdRef} has no start receipt for drain validation.`,
8340
+ blockedStage: "queue-drain",
8341
+ failureCode: "missing-drain-evidence",
8342
+ humanReadableReason: `PRD Run ${context.prdRef} has no start receipt for drain validation.`,
8087
8343
  repairability: "automatic-retry-safe",
8088
- diagnostics: [],
8089
- offendingPaths: []
8090
- }
8344
+ nextAction: "rerun-prd-run-launch",
8345
+ nextRecommendedCommand: "pourkit prd-run launch"
8346
+ })
8091
8347
  };
8092
8348
  }
8093
8349
  if (!start.queueStartedAt) {
8094
8350
  return {
8095
8351
  ok: false,
8096
- guidance: {
8352
+ guidance: buildPrdRunRepairGuidance({
8097
8353
  blockedGate: "queue",
8098
- failureCode: "missing_queue_started_at",
8099
- reason: `PRD Run ${context.prdRef} drain evidence missing queueStartedAt.`,
8354
+ blockedStage: "queue-drain",
8355
+ failureCode: "missing-queue-started-at",
8356
+ humanReadableReason: `PRD Run ${context.prdRef} drain evidence missing queueStartedAt.`,
8100
8357
  repairability: "automatic-retry-safe",
8101
- diagnostics: [],
8102
- offendingPaths: []
8103
- }
8358
+ nextAction: "rerun-prd-run-launch",
8359
+ nextRecommendedCommand: "pourkit prd-run launch"
8360
+ })
8104
8361
  };
8105
8362
  }
8106
8363
  if (start.queueCommand !== "queue-run") {
8107
8364
  return {
8108
8365
  ok: false,
8109
- guidance: {
8366
+ guidance: buildPrdRunRepairGuidance({
8110
8367
  blockedGate: "queue",
8111
- failureCode: "missing_queue_command",
8112
- reason: `PRD Run ${context.prdRef} drain evidence missing queue-run command.`,
8368
+ blockedStage: "queue-drain",
8369
+ failureCode: "missing-queue-command",
8370
+ humanReadableReason: `PRD Run ${context.prdRef} drain evidence missing queue-run command.`,
8113
8371
  repairability: "automatic-retry-safe",
8114
- diagnostics: [],
8115
- offendingPaths: []
8116
- }
8372
+ nextAction: "rerun-prd-run-launch",
8373
+ nextRecommendedCommand: "pourkit prd-run launch"
8374
+ })
8117
8375
  };
8118
8376
  }
8119
8377
  if (!start.queueDrainedAt) {
8120
8378
  return {
8121
8379
  ok: false,
8122
- guidance: {
8380
+ guidance: buildPrdRunRepairGuidance({
8123
8381
  blockedGate: "queue",
8124
- failureCode: "missing_queue_drained_at",
8125
- reason: `PRD Run ${context.prdRef} drain evidence missing queueDrainedAt.`,
8382
+ blockedStage: "queue-drain",
8383
+ failureCode: "missing-queue-drained-at",
8384
+ humanReadableReason: `PRD Run ${context.prdRef} drain evidence missing queueDrainedAt.`,
8126
8385
  repairability: "automatic-retry-safe",
8127
- diagnostics: [],
8128
- offendingPaths: []
8129
- }
8386
+ nextAction: "rerun-prd-run-launch",
8387
+ nextRecommendedCommand: "pourkit prd-run launch"
8388
+ })
8130
8389
  };
8131
8390
  }
8132
8391
  if (typeof start.queueProcessedCount !== "number") {
8133
8392
  return {
8134
8393
  ok: false,
8135
- guidance: {
8394
+ guidance: buildPrdRunRepairGuidance({
8136
8395
  blockedGate: "queue",
8137
- failureCode: "missing_queue_processed_count",
8138
- reason: `PRD Run ${context.prdRef} drain evidence missing queueProcessedCount.`,
8396
+ blockedStage: "queue-drain",
8397
+ failureCode: "missing-queue-processed-count",
8398
+ humanReadableReason: `PRD Run ${context.prdRef} drain evidence missing queueProcessedCount.`,
8139
8399
  repairability: "automatic-retry-safe",
8140
- diagnostics: [],
8141
- offendingPaths: []
8142
- }
8400
+ nextAction: "rerun-prd-run-launch",
8401
+ nextRecommendedCommand: "pourkit prd-run launch"
8402
+ })
8143
8403
  };
8144
8404
  }
8145
8405
  if (start.queueProcessedCount <= 0) {
8146
8406
  return {
8147
8407
  ok: false,
8148
- guidance: {
8408
+ guidance: buildPrdRunRepairGuidance({
8149
8409
  blockedGate: "queue",
8150
- failureCode: "zero_processed",
8151
- reason: `PRD Run ${context.prdRef} queue drain processed zero issues.`,
8410
+ blockedStage: "queue-drain",
8411
+ failureCode: "zero-processed",
8412
+ humanReadableReason: `PRD Run ${context.prdRef} queue drain processed zero issues.`,
8152
8413
  repairability: "automatic-retry-safe",
8153
- diagnostics: [`queueProcessedCount: ${start.queueProcessedCount}`],
8154
- offendingPaths: []
8155
- }
8414
+ nextAction: "rerun-prd-run-launch",
8415
+ nextRecommendedCommand: "pourkit prd-run launch",
8416
+ diagnostics: [`queueProcessedCount: ${start.queueProcessedCount}`]
8417
+ })
8156
8418
  };
8157
8419
  }
8158
8420
  if (start.prdBranch !== context.prdBranch) {
8159
8421
  return {
8160
8422
  ok: false,
8161
- guidance: {
8423
+ guidance: buildPrdRunRepairGuidance({
8162
8424
  blockedGate: "queue",
8163
- failureCode: "prd_branch_mismatch",
8164
- reason: `PRD Run ${context.prdRef} prdBranch "${start.prdBranch}" does not match expected "${context.prdBranch}".`,
8425
+ blockedStage: "queue-drain",
8426
+ failureCode: "prd-branch-mismatch",
8427
+ humanReadableReason: `PRD Run ${context.prdRef} prdBranch "${start.prdBranch}" does not match expected "${context.prdBranch}".`,
8165
8428
  repairability: "operator-action",
8429
+ nextAction: "inspect-and-retry",
8430
+ nextRecommendedCommand: "pourkit prd-run launch",
8166
8431
  diagnostics: [
8167
8432
  `Recorded prdBranch: ${start.prdBranch}`,
8168
8433
  `Expected prdBranch: ${context.prdBranch}`
8169
- ],
8170
- offendingPaths: []
8171
- }
8434
+ ]
8435
+ })
8172
8436
  };
8173
8437
  }
8174
8438
  return { ok: true };
@@ -8181,14 +8445,15 @@ function validatePrdRunTerminalEvidence(record, context) {
8181
8445
  if (context.allChildIssuesFinalizedIntoPrdBranch !== true) {
8182
8446
  return {
8183
8447
  ok: false,
8184
- guidance: {
8448
+ guidance: buildPrdRunRepairGuidance({
8185
8449
  blockedGate: "queue",
8186
- failureCode: "missing_child_finalization_evidence",
8187
- reason: `PRD Run ${context.prdRef} is missing proof that all child Issues finalized into ${context.prdBranch}.`,
8450
+ blockedStage: "queue-drain",
8451
+ failureCode: "missing-child-finalization-evidence",
8452
+ humanReadableReason: `PRD Run ${context.prdRef} is missing proof that all child Issues finalized into ${context.prdBranch}.`,
8188
8453
  repairability: "operator-action",
8189
- diagnostics: [],
8190
- offendingPaths: []
8191
- }
8454
+ nextAction: "inspect-and-retry",
8455
+ nextRecommendedCommand: "pourkit prd-run launch"
8456
+ })
8192
8457
  };
8193
8458
  }
8194
8459
  return { ok: true };
@@ -8482,10 +8747,11 @@ function buildBlockedOutcome(repoRoot2, prdRef, guidance, targetName) {
8482
8747
  status: "blocked",
8483
8748
  updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
8484
8749
  blockedGate: guidance.blockedGate,
8485
- blockedReason: guidance.reason,
8486
- diagnostics: [...guidance.diagnostics ?? []],
8487
- offendingPaths: [...guidance.offendingPaths ?? []],
8488
- targetName
8750
+ blockedReason: guidance.humanReadableReason,
8751
+ ...guidance.diagnostics?.length ? { diagnostics: [...guidance.diagnostics] } : {},
8752
+ ...guidance.offendingPaths?.length ? { offendingPaths: [...guidance.offendingPaths] } : {},
8753
+ targetName,
8754
+ repairGuidance: guidance
8489
8755
  });
8490
8756
  return { kind: "blocked", prdRef, guidance };
8491
8757
  }
@@ -8508,17 +8774,21 @@ function persistStartingPrdRunRecord(repoRoot2, prdRef, existingRecord, start, c
8508
8774
  start
8509
8775
  });
8510
8776
  }
8511
- function blocked(repoRoot2, prdRef, gate, failureCode, reason, diagnostics, targetName) {
8777
+ function blocked(repoRoot2, prdRef, gate, failureCode, reason, diagnostics, targetName, stage, repairability = "operator-action") {
8512
8778
  return buildBlockedOutcome(
8513
8779
  repoRoot2,
8514
8780
  prdRef,
8515
- {
8781
+ buildPrdRunRepairGuidance({
8516
8782
  blockedGate: gate,
8783
+ blockedStage: stage ?? gate,
8517
8784
  failureCode,
8518
- reason,
8519
- diagnostics: diagnostics ? [...diagnostics] : [],
8520
- repairability: "operator-action"
8521
- },
8785
+ humanReadableReason: reason,
8786
+ repairability,
8787
+ nextAction: repairability === "automatic-retry-safe" ? "rerun-prd-run-launch" : "inspect-and-retry",
8788
+ nextRecommendedCommand: `pourkit prd-run launch ${prdRef}`,
8789
+ ...diagnostics?.length ? { diagnostics: [...diagnostics] } : {},
8790
+ ...targetName ? { targetName } : {}
8791
+ }),
8522
8792
  targetName
8523
8793
  );
8524
8794
  }
@@ -8530,8 +8800,11 @@ async function startPrdRun(options) {
8530
8800
  options.repoRoot,
8531
8801
  prdRef,
8532
8802
  "branch-state",
8533
- "invalid_target_name",
8534
- `Invalid target name "${options.targetName}". Expected a non-empty target name.`
8803
+ "invalid-target-name",
8804
+ `Invalid target name "${options.targetName}". Expected a non-empty target name.`,
8805
+ void 0,
8806
+ void 0,
8807
+ "start-validation"
8535
8808
  );
8536
8809
  }
8537
8810
  const existingRecord = readPrdRun(options.repoRoot, prdRef);
@@ -8546,10 +8819,11 @@ async function startPrdRun(options) {
8546
8819
  options.repoRoot,
8547
8820
  prdRef,
8548
8821
  baseResolution.gate,
8549
- "base_resolution_failed",
8822
+ "base-resolution-failed",
8550
8823
  baseResolution.reason,
8551
8824
  baseResolution.diagnostics,
8552
- targetName
8825
+ targetName,
8826
+ "start-validation"
8553
8827
  );
8554
8828
  }
8555
8829
  if (existingRecord.record?.start) {
@@ -8559,10 +8833,12 @@ async function startPrdRun(options) {
8559
8833
  options.repoRoot,
8560
8834
  prdRef,
8561
8835
  "branch-state",
8562
- "missing_start_base_branch",
8836
+ "missing-start-base-branch",
8563
8837
  `PRD Run ${prdRef} has a start receipt without startBaseBranch. Run prd-run start to create a fresh start receipt.`,
8564
8838
  [`Recorded start: ${JSON.stringify(existingRecord.record.start)}`],
8565
- targetName
8839
+ targetName,
8840
+ "start-validation",
8841
+ "unsupported-state"
8566
8842
  );
8567
8843
  }
8568
8844
  if (recordedBaseBranch !== baseResolution.baseBranch) {
@@ -8570,13 +8846,14 @@ async function startPrdRun(options) {
8570
8846
  options.repoRoot,
8571
8847
  prdRef,
8572
8848
  "branch-state",
8573
- "base_mismatch",
8849
+ "base-mismatch",
8574
8850
  `PRD Run ${prdRef} start receipt records startBaseBranch "${recordedBaseBranch}" but current base resolution resolves to "${baseResolution.baseBranch}". Use --base with the matching value or create a fresh start receipt.`,
8575
8851
  [
8576
8852
  `Recorded startBaseBranch: ${recordedBaseBranch}`,
8577
8853
  `Current base resolution: ${baseResolution.baseBranch} (source: ${baseResolution.source})`
8578
8854
  ],
8579
- targetName
8855
+ targetName,
8856
+ "start-validation"
8580
8857
  );
8581
8858
  }
8582
8859
  const currentStatus = existingRecord.record.status;
@@ -8595,9 +8872,12 @@ async function startPrdRun(options) {
8595
8872
  options.repoRoot,
8596
8873
  prdRef,
8597
8874
  fetchResult2.gate,
8598
- "fetch_failed",
8875
+ "fetch-failed",
8599
8876
  fetchResult2.reason,
8600
- fetchResult2.diagnostics
8877
+ fetchResult2.diagnostics,
8878
+ targetName,
8879
+ "branch-materialization",
8880
+ "automatic-retry-safe"
8601
8881
  );
8602
8882
  }
8603
8883
  const branchResult2 = inspectRemotePrdBranch(options.repoRoot, prdRef);
@@ -8606,9 +8886,12 @@ async function startPrdRun(options) {
8606
8886
  options.repoRoot,
8607
8887
  prdRef,
8608
8888
  branchResult2.gate,
8609
- "branch_inspection_failed",
8889
+ "branch-inspection-failed",
8610
8890
  branchResult2.reason,
8611
- branchResult2.diagnostics
8891
+ branchResult2.diagnostics,
8892
+ targetName,
8893
+ "branch-materialization",
8894
+ "automatic-retry-safe"
8612
8895
  );
8613
8896
  }
8614
8897
  if (branchResult2.exists) {
@@ -8638,14 +8921,16 @@ async function startPrdRun(options) {
8638
8921
  options.repoRoot,
8639
8922
  prdRef,
8640
8923
  "branch-state",
8641
- "unrecorded_branch_exists",
8924
+ "unrecorded-branch-exists",
8642
8925
  `PRD Branch ${prdRef} already exists remotely but PRD Run state does not record the same branch and start base commit. Use --adopt-existing-branch to adopt it.`,
8643
8926
  [
8644
8927
  `Existing remote branch: ${prdRef}`,
8645
8928
  `Recorded start branch: ${matchingStart.prdBranch}`,
8646
8929
  `Recorded start base commit: ${matchingStart.startBaseCommit}`,
8647
8930
  `Current origin/${recordedBaseBranch} head: ${fetchResult2.startBaseCommit}`
8648
- ]
8931
+ ],
8932
+ targetName,
8933
+ "branch-materialization"
8649
8934
  );
8650
8935
  }
8651
8936
  const fetchPrdResult = fetchPrdBranch(options.repoRoot, prdRef);
@@ -8654,9 +8939,12 @@ async function startPrdRun(options) {
8654
8939
  options.repoRoot,
8655
8940
  prdRef,
8656
8941
  fetchPrdResult.gate,
8657
- "fetch_prd_branch_failed",
8942
+ "fetch-prd-branch-failed",
8658
8943
  fetchPrdResult.reason,
8659
- fetchPrdResult.diagnostics
8944
+ fetchPrdResult.diagnostics,
8945
+ targetName,
8946
+ "branch-materialization",
8947
+ "automatic-retry-safe"
8660
8948
  );
8661
8949
  }
8662
8950
  const ancestryResult = spawnSync2(
@@ -8674,12 +8962,14 @@ async function startPrdRun(options) {
8674
8962
  options.repoRoot,
8675
8963
  prdRef,
8676
8964
  "branch-state",
8677
- "ancestry_check_failed",
8965
+ "ancestry-check-failed",
8678
8966
  `PRD Branch ${prdRef} base ancestry check failed: origin/${recordedBaseBranch} is not an ancestor of origin/${prdRef}. Cannot adopt.`,
8679
8967
  [
8680
8968
  `Base branch: origin/${recordedBaseBranch}`,
8681
8969
  `PRD branch: origin/${prdRef}`
8682
- ]
8970
+ ],
8971
+ targetName,
8972
+ "branch-materialization"
8683
8973
  );
8684
8974
  }
8685
8975
  const adoptedStart = buildStartReceipt({
@@ -8715,9 +9005,12 @@ async function startPrdRun(options) {
8715
9005
  options.repoRoot,
8716
9006
  prdRef,
8717
9007
  fetchResult.gate,
8718
- "fetch_failed",
9008
+ "fetch-failed",
8719
9009
  fetchResult.reason,
8720
- fetchResult.diagnostics
9010
+ fetchResult.diagnostics,
9011
+ targetName,
9012
+ "branch-materialization",
9013
+ "automatic-retry-safe"
8721
9014
  );
8722
9015
  }
8723
9016
  const branchResult = inspectRemotePrdBranch(options.repoRoot, prdRef);
@@ -8726,9 +9019,12 @@ async function startPrdRun(options) {
8726
9019
  options.repoRoot,
8727
9020
  prdRef,
8728
9021
  branchResult.gate,
8729
- "branch_inspection_failed",
9022
+ "branch-inspection-failed",
8730
9023
  branchResult.reason,
8731
- branchResult.diagnostics
9024
+ branchResult.diagnostics,
9025
+ targetName,
9026
+ "branch-materialization",
9027
+ "automatic-retry-safe"
8732
9028
  );
8733
9029
  }
8734
9030
  if (branchResult.exists) {
@@ -8737,14 +9033,16 @@ async function startPrdRun(options) {
8737
9033
  options.repoRoot,
8738
9034
  prdRef,
8739
9035
  "branch-state",
8740
- "unrecorded_branch_exists",
9036
+ "unrecorded-branch-exists",
8741
9037
  `PRD Branch ${prdRef} already exists remotely but PRD Run state does not record the same branch and start base commit. Use --adopt-existing-branch to adopt it.`,
8742
9038
  [
8743
9039
  `Existing remote branch: ${prdRef}`,
8744
9040
  `Recorded start branch: ${existingRecord.record?.start?.prdBranch ?? "(missing)"}`,
8745
9041
  `Recorded start base commit: ${existingRecord.record?.start?.startBaseCommit ?? "(missing)"}`,
8746
9042
  `Current origin/${baseResolution.baseBranch} head: ${fetchResult.startBaseCommit}`
8747
- ]
9043
+ ],
9044
+ targetName,
9045
+ "branch-materialization"
8748
9046
  );
8749
9047
  }
8750
9048
  const fetchPrdResult = fetchPrdBranch(options.repoRoot, prdRef);
@@ -8753,9 +9051,12 @@ async function startPrdRun(options) {
8753
9051
  options.repoRoot,
8754
9052
  prdRef,
8755
9053
  fetchPrdResult.gate,
8756
- "fetch_prd_branch_failed",
9054
+ "fetch-prd-branch-failed",
8757
9055
  fetchPrdResult.reason,
8758
- fetchPrdResult.diagnostics
9056
+ fetchPrdResult.diagnostics,
9057
+ targetName,
9058
+ "branch-materialization",
9059
+ "automatic-retry-safe"
8759
9060
  );
8760
9061
  }
8761
9062
  const ancestryResult = spawnSync2(
@@ -8773,12 +9074,14 @@ async function startPrdRun(options) {
8773
9074
  options.repoRoot,
8774
9075
  prdRef,
8775
9076
  "branch-state",
8776
- "ancestry_check_failed",
9077
+ "ancestry-check-failed",
8777
9078
  `PRD Branch ${prdRef} base ancestry check failed: origin/${baseResolution.baseBranch} is not an ancestor of origin/${prdRef}. Cannot adopt.`,
8778
9079
  [
8779
9080
  `Base branch: origin/${baseResolution.baseBranch}`,
8780
9081
  `PRD branch: origin/${prdRef}`
8781
- ]
9082
+ ],
9083
+ targetName,
9084
+ "branch-materialization"
8782
9085
  );
8783
9086
  }
8784
9087
  const adoptedStart = buildStartReceipt({
@@ -8815,11 +9118,14 @@ async function startPrdRun(options) {
8815
9118
  options.repoRoot,
8816
9119
  prdRef,
8817
9120
  "git",
8818
- "branch_creation_failed",
9121
+ "branch-creation-failed",
8819
9122
  `Failed to create PRD Branch ${prdRef} from ${fetchResult.startBaseCommit}.`,
8820
9123
  [error instanceof Error ? error.message : String(error)].filter(
8821
9124
  (v) => Boolean(v && v.trim())
8822
- )
9125
+ ),
9126
+ targetName,
9127
+ "branch-materialization",
9128
+ "automatic-retry-safe"
8823
9129
  );
8824
9130
  }
8825
9131
  const updatedAt = (/* @__PURE__ */ new Date()).toISOString();
@@ -8842,11 +9148,28 @@ async function startPrdRun(options) {
8842
9148
  diagnostics: []
8843
9149
  };
8844
9150
  }
8845
- function buildLaunchBlockedOutcome(prdRef, guidance, resume, start) {
9151
+ function buildLaunchBlockedOutcome(repoRoot2, prdRef, guidance, resume, start, targetName, startReceipt) {
9152
+ const enrichedGuidance = {
9153
+ ...guidance,
9154
+ targetName: guidance.targetName ?? targetName,
9155
+ baseBranch: guidance.baseBranch ?? startReceipt?.startBaseBranch
9156
+ };
9157
+ writePrdRunRecord(repoRoot2, {
9158
+ prdRef,
9159
+ status: "blocked",
9160
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
9161
+ blockedGate: enrichedGuidance.blockedGate,
9162
+ blockedReason: enrichedGuidance.humanReadableReason,
9163
+ ...enrichedGuidance.diagnostics?.length ? { diagnostics: [...enrichedGuidance.diagnostics] } : {},
9164
+ ...enrichedGuidance.offendingPaths?.length ? { offendingPaths: [...enrichedGuidance.offendingPaths] } : {},
9165
+ ...targetName ? { targetName } : {},
9166
+ ...startReceipt ? { start: startReceipt } : {},
9167
+ repairGuidance: enrichedGuidance
9168
+ });
8846
9169
  return {
8847
9170
  kind: "blocked",
8848
9171
  prdRef,
8849
- guidance,
9172
+ guidance: enrichedGuidance,
8850
9173
  start,
8851
9174
  resume
8852
9175
  };
@@ -8860,32 +9183,146 @@ function writeDrainedRecord(repoRoot2, prdRef, startReceipt, targetName) {
8860
9183
  start: startReceipt
8861
9184
  });
8862
9185
  }
8863
- function writeTerminalRecord(repoRoot2, prdRef, status, targetName, startReceipt, prdBranch) {
8864
- writePrdRunRecord(repoRoot2, {
8865
- prdRef,
8866
- status,
8867
- updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
8868
- targetName,
8869
- prdBranch,
8870
- start: startReceipt
8871
- });
9186
+ function writeTerminalRecord(repoRoot2, prdRef, status, targetName, startReceipt, prdBranch) {
9187
+ writePrdRunRecord(repoRoot2, {
9188
+ prdRef,
9189
+ status,
9190
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
9191
+ targetName,
9192
+ prdBranch,
9193
+ start: startReceipt
9194
+ });
9195
+ }
9196
+ function validateRecordedIssueResumeEvidence(options) {
9197
+ const { prdRef, guidance, startReceipt, targetName } = options;
9198
+ const diagnostics = [];
9199
+ if (guidance.targetName && guidance.targetName !== targetName) {
9200
+ diagnostics.push(
9201
+ `Recorded targetName: ${guidance.targetName}; current targetName: ${targetName}`
9202
+ );
9203
+ }
9204
+ if (guidance.baseBranch && startReceipt?.startBaseBranch && guidance.baseBranch !== startReceipt.startBaseBranch) {
9205
+ diagnostics.push(
9206
+ `Recorded baseBranch: ${guidance.baseBranch}; current startBaseBranch: ${startReceipt.startBaseBranch}`
9207
+ );
9208
+ }
9209
+ const worktreePath = guidance.issue?.worktreePath;
9210
+ if (worktreePath) {
9211
+ const worktreeState = readWorktreeRunState(worktreePath);
9212
+ if (!worktreeState) {
9213
+ diagnostics.push(
9214
+ `Worktree Run State missing or malformed at ${worktreePath}`
9215
+ );
9216
+ } else {
9217
+ if (guidance.issue?.number !== worktreeState.issueNumber) {
9218
+ diagnostics.push(
9219
+ `Recorded issue #${guidance.issue?.number}; Worktree Run State issue #${worktreeState.issueNumber}`
9220
+ );
9221
+ }
9222
+ if (guidance.issue?.branch && guidance.issue.branch !== worktreeState.branchName) {
9223
+ diagnostics.push(
9224
+ `Recorded issue branch: ${guidance.issue.branch}; Worktree Run State branch: ${worktreeState.branchName}`
9225
+ );
9226
+ }
9227
+ if (worktreeState.targetName !== targetName) {
9228
+ diagnostics.push(
9229
+ `Worktree Run State targetName: ${worktreeState.targetName}; current targetName: ${targetName}`
9230
+ );
9231
+ }
9232
+ if (startReceipt?.prdBranch && worktreeState.baseBranch !== startReceipt.prdBranch) {
9233
+ diagnostics.push(
9234
+ `Worktree Run State baseBranch: ${worktreeState.baseBranch}; expected PRD Branch: ${startReceipt.prdBranch}`
9235
+ );
9236
+ }
9237
+ }
9238
+ }
9239
+ if (diagnostics.length === 0) return null;
9240
+ return buildPrdRunRepairGuidance({
9241
+ blockedGate: "queue",
9242
+ blockedStage: guidance.blockedStage || "queue-drain",
9243
+ failureCode: worktreePath ? "worktree-evidence-mismatch" : "branch-evidence-mismatch",
9244
+ humanReadableReason: `PRD Run ${prdRef} recorded repair guidance does not match current resume evidence.`,
9245
+ repairability: "unsupported-state",
9246
+ nextAction: "inspect-prd-run-state",
9247
+ nextRecommendedCommand: `pourkit prd-run status ${prdRef}`,
9248
+ diagnostics,
9249
+ issue: guidance.issue,
9250
+ pr: guidance.pr,
9251
+ targetName: guidance.targetName,
9252
+ baseBranch: guidance.baseBranch
9253
+ });
9254
+ }
9255
+ async function attemptRecordedIssueLabelProjection(options, prdRef, resumeIssueNumber, originalGuidance) {
9256
+ if (resumeIssueNumber === void 0) return true;
9257
+ try {
9258
+ await options.issueProvider.removeLabel(
9259
+ resumeIssueNumber,
9260
+ options.config.labels.agentInProgress
9261
+ );
9262
+ return true;
9263
+ } catch {
9264
+ const state = readPrdRun(options.repoRoot, prdRef).record;
9265
+ const guidance = originalGuidance ?? state?.repairGuidance;
9266
+ if (guidance) {
9267
+ const updated = appendPrdRunRepairAttempt(guidance, {
9268
+ outcome: "projection-failed",
9269
+ failureCode: "label-projection-failed",
9270
+ summary: `Failed to remove "${options.config.labels.agentInProgress}" label from issue #${resumeIssueNumber}`
9271
+ });
9272
+ if (state) {
9273
+ writePrdRunRecord(options.repoRoot, {
9274
+ ...state,
9275
+ repairGuidance: updated,
9276
+ updatedAt: updated.updatedAt
9277
+ });
9278
+ }
9279
+ }
9280
+ return false;
9281
+ }
8872
9282
  }
8873
9283
  async function launchPrdRun(options) {
8874
9284
  const prdRef = normalizePrdRunRef(options.prdRef);
8875
9285
  const existingRecord = readPrdRun(options.repoRoot, prdRef);
8876
9286
  const plan = planPrdRunLaunchResume(existingRecord.record);
9287
+ const rec = existingRecord.record;
9288
+ if (rec && (rec.status === "starting" || rec.status === "running") && !rec.repairGuidance) {
9289
+ return buildLaunchBlockedOutcome(
9290
+ options.repoRoot,
9291
+ prdRef,
9292
+ buildPrdRunRepairGuidance({
9293
+ blockedGate: "branch-state",
9294
+ blockedStage: "start-validation",
9295
+ failureCode: "prd-run-in-progress",
9296
+ humanReadableReason: `PRD Run ${prdRef} is already ${rec.status}. A second launch cannot start another Queue drain while the run is in progress.`,
9297
+ repairability: "automatic-retry-safe",
9298
+ nextAction: "wait-or-inspect-active-run",
9299
+ nextRecommendedCommand: "pourkit prd-run status",
9300
+ diagnostics: [
9301
+ `PRD Run ${prdRef} is in status "${rec.status}" without active repair guidance.`
9302
+ ]
9303
+ }),
9304
+ plan,
9305
+ void 0,
9306
+ options.targetName
9307
+ );
9308
+ }
8877
9309
  if (existingRecord.record === null && existingRecord.diagnostics.length > 0) {
8878
9310
  return buildLaunchBlockedOutcome(
9311
+ options.repoRoot,
8879
9312
  prdRef,
8880
- {
9313
+ buildPrdRunRepairGuidance({
8881
9314
  blockedGate: "receipt-check",
8882
- failureCode: "unsupported_legacy_state",
8883
- reason: `PRD Run ${prdRef} has a malformed or unsupported record. The stored status is no longer a valid launch state.`,
9315
+ blockedStage: "start-validation",
9316
+ failureCode: "unsupported-legacy-state",
9317
+ humanReadableReason: `PRD Run ${prdRef} has a malformed or unsupported record. The stored status is no longer a valid launch state.`,
8884
9318
  repairability: "unsupported-state",
8885
- diagnostics: [...existingRecord.diagnostics],
8886
- offendingPaths: []
8887
- },
8888
- plan
9319
+ nextAction: "inspect-prd-run-state",
9320
+ nextRecommendedCommand: "pourkit prd-run status",
9321
+ diagnostics: [...existingRecord.diagnostics]
9322
+ }),
9323
+ plan,
9324
+ void 0,
9325
+ options.targetName
8889
9326
  );
8890
9327
  }
8891
9328
  if (existingRecord.record?.status === "completed_prd_branch") {
@@ -8904,16 +9341,20 @@ async function launchPrdRun(options) {
8904
9341
  const record = existingRecord.record;
8905
9342
  if (!record.start) {
8906
9343
  return buildLaunchBlockedOutcome(
9344
+ options.repoRoot,
8907
9345
  prdRef,
8908
- {
9346
+ buildPrdRunRepairGuidance({
8909
9347
  blockedGate: "queue",
8910
- failureCode: "missing_drain_evidence",
8911
- reason: `PRD Run ${prdRef} is drained but missing start receipt.`,
9348
+ blockedStage: "queue-drain",
9349
+ failureCode: "missing-drain-evidence",
9350
+ humanReadableReason: `PRD Run ${prdRef} is drained but missing start receipt.`,
8912
9351
  repairability: "automatic-retry-safe",
8913
- diagnostics: [],
8914
- offendingPaths: []
8915
- },
8916
- plan
9352
+ nextAction: "rerun-prd-run-launch",
9353
+ nextRecommendedCommand: "pourkit prd-run launch"
9354
+ }),
9355
+ plan,
9356
+ void 0,
9357
+ options.targetName
8917
9358
  );
8918
9359
  }
8919
9360
  const resolvedTarget = options.config ? resolveTarget(options.config, options.targetName) : null;
@@ -8924,16 +9365,22 @@ async function launchPrdRun(options) {
8924
9365
  });
8925
9366
  if (!baseResolution.ok) {
8926
9367
  return buildLaunchBlockedOutcome(
9368
+ options.repoRoot,
8927
9369
  prdRef,
8928
- {
9370
+ buildPrdRunRepairGuidance({
8929
9371
  blockedGate: baseResolution.gate,
8930
- failureCode: "base_resolution_failed",
8931
- reason: baseResolution.reason,
9372
+ blockedStage: "start-validation",
9373
+ failureCode: "base-resolution-failed",
9374
+ humanReadableReason: baseResolution.reason,
8932
9375
  repairability: "operator-action",
9376
+ nextAction: "inspect-and-retry",
9377
+ nextRecommendedCommand: "pourkit prd-run launch",
8933
9378
  diagnostics: [...baseResolution.diagnostics],
8934
9379
  offendingPaths: [...baseResolution.offendingPaths]
8935
- },
8936
- plan
9380
+ }),
9381
+ plan,
9382
+ void 0,
9383
+ options.targetName
8937
9384
  );
8938
9385
  }
8939
9386
  const drainContext = {
@@ -8946,7 +9393,14 @@ async function launchPrdRun(options) {
8946
9393
  drainContext
8947
9394
  );
8948
9395
  if (!terminalEvidence.ok) {
8949
- return buildLaunchBlockedOutcome(prdRef, terminalEvidence.guidance, plan);
9396
+ return buildLaunchBlockedOutcome(
9397
+ options.repoRoot,
9398
+ prdRef,
9399
+ terminalEvidence.guidance,
9400
+ plan,
9401
+ void 0,
9402
+ options.targetName
9403
+ );
8950
9404
  }
8951
9405
  writeTerminalRecord(
8952
9406
  options.repoRoot,
@@ -8969,18 +9423,23 @@ async function launchPrdRun(options) {
8969
9423
  }
8970
9424
  if (plan.blocked === "missing-start-receipt") {
8971
9425
  return buildLaunchBlockedOutcome(
9426
+ options.repoRoot,
8972
9427
  prdRef,
8973
- {
9428
+ buildPrdRunRepairGuidance({
8974
9429
  blockedGate: "branch-state",
8975
- failureCode: "missing_start_receipt",
8976
- reason: `PRD Run ${prdRef} is missing branch/start state. Run prd-run start or rerun prd-run launch.`,
9430
+ blockedStage: "start-validation",
9431
+ failureCode: "missing-start-receipt",
9432
+ humanReadableReason: `PRD Run ${prdRef} is missing branch/start state. Run prd-run start or rerun prd-run launch.`,
8977
9433
  repairability: "automatic-retry-safe",
9434
+ nextAction: "rerun-prd-run-launch",
9435
+ nextRecommendedCommand: "pourkit prd-run launch",
8978
9436
  diagnostics: [
8979
9437
  `PRD Run ${prdRef} is in status "${existingRecord.record?.status}" but has no start receipt.`
8980
- ],
8981
- offendingPaths: []
8982
- },
8983
- plan
9438
+ ]
9439
+ }),
9440
+ plan,
9441
+ void 0,
9442
+ options.targetName
8984
9443
  );
8985
9444
  }
8986
9445
  let startOutcome;
@@ -9010,6 +9469,62 @@ async function launchPrdRun(options) {
9010
9469
  const currentRecord = readPrdRun(options.repoRoot, prdRef).record;
9011
9470
  const startReceipt = currentRecord?.start;
9012
9471
  const targetName = currentRecord?.targetName ?? options.targetName;
9472
+ let resumeIssueNumber;
9473
+ if (currentRecord?.repairGuidance) {
9474
+ const validation = validateActivePrdRunRepairGuidance(currentRecord);
9475
+ if (!validation.ok) {
9476
+ return buildLaunchBlockedOutcome(
9477
+ options.repoRoot,
9478
+ prdRef,
9479
+ validation.guidance,
9480
+ plan,
9481
+ startOutcome,
9482
+ targetName,
9483
+ startReceipt
9484
+ );
9485
+ }
9486
+ const resumeEvidenceFailure = validateRecordedIssueResumeEvidence({
9487
+ prdRef,
9488
+ guidance: validation.guidance,
9489
+ startReceipt,
9490
+ targetName
9491
+ });
9492
+ if (resumeEvidenceFailure) {
9493
+ return buildLaunchBlockedOutcome(
9494
+ options.repoRoot,
9495
+ prdRef,
9496
+ resumeEvidenceFailure,
9497
+ plan,
9498
+ startOutcome,
9499
+ targetName,
9500
+ startReceipt
9501
+ );
9502
+ }
9503
+ if (validation.guidance.issue?.number) {
9504
+ resumeIssueNumber = validation.guidance.issue.number;
9505
+ } else {
9506
+ return buildLaunchBlockedOutcome(
9507
+ options.repoRoot,
9508
+ prdRef,
9509
+ buildPrdRunRepairGuidance({
9510
+ blockedGate: "queue",
9511
+ blockedStage: "queue-drain",
9512
+ failureCode: "missing-issue-identity",
9513
+ humanReadableReason: `PRD Run ${prdRef} has repair guidance without a recorded Issue identity. Resume is not possible.`,
9514
+ repairability: "unsupported-state",
9515
+ nextAction: "inspect-prd-run-state",
9516
+ nextRecommendedCommand: `pourkit prd-run status ${prdRef}`,
9517
+ diagnostics: [
9518
+ "Repair guidance exists but is missing issue.number field."
9519
+ ]
9520
+ }),
9521
+ plan,
9522
+ startOutcome,
9523
+ targetName,
9524
+ startReceipt
9525
+ );
9526
+ }
9527
+ }
9013
9528
  if (startReceipt) {
9014
9529
  startReceipt.queueStartedAt = (/* @__PURE__ */ new Date()).toISOString();
9015
9530
  startReceipt.queueCommand = "queue-run";
@@ -9019,7 +9534,8 @@ async function launchPrdRun(options) {
9019
9534
  status: "running",
9020
9535
  updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
9021
9536
  targetName,
9022
- start: startReceipt
9537
+ start: startReceipt,
9538
+ repairGuidance: currentRecord?.repairGuidance
9023
9539
  });
9024
9540
  return await launchGithubQueueDrain(
9025
9541
  options,
@@ -9027,98 +9543,78 @@ async function launchPrdRun(options) {
9027
9543
  startReceipt,
9028
9544
  targetName,
9029
9545
  plan,
9030
- startOutcome
9546
+ startOutcome,
9547
+ resumeIssueNumber
9031
9548
  );
9032
9549
  }
9033
- async function launchGithubQueueDrain(options, prdRef, startReceipt, targetName, plan, startOutcome) {
9550
+ async function launchGithubQueueDrain(options, prdRef, startReceipt, targetName, plan, startOutcome, resumeIssueNumber) {
9034
9551
  if (!options.issueProvider || !options.prProvider || !options.executionProvider || !options.logger) {
9035
9552
  const reason = `PRD Run ${prdRef} requires issueProvider, prProvider, executionProvider, and logger for GitHub-backed queue drain.`;
9036
- writePrdRunRecord(options.repoRoot, {
9037
- prdRef,
9038
- status: "blocked",
9039
- updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
9040
- targetName,
9041
- start: startReceipt,
9042
- blockedGate: "queue",
9043
- blockedReason: reason,
9044
- diagnostics: [
9045
- "Missing one or more required providers for GitHub-backed mode.",
9046
- "Provide --issue-provider, --pr-provider, --execution-provider, and --logger options."
9047
- ],
9048
- offendingPaths: []
9049
- });
9050
9553
  return buildLaunchBlockedOutcome(
9554
+ options.repoRoot,
9051
9555
  prdRef,
9052
- {
9556
+ buildPrdRunRepairGuidance({
9053
9557
  blockedGate: "queue",
9054
- failureCode: "missing_github_providers",
9055
- reason,
9558
+ blockedStage: "queue-drain",
9559
+ failureCode: "missing-github-providers",
9560
+ humanReadableReason: reason,
9056
9561
  repairability: "operator-action",
9562
+ nextAction: "inspect-and-retry",
9563
+ nextRecommendedCommand: "pourkit prd-run launch --with-providers",
9057
9564
  diagnostics: [
9058
9565
  "Missing one or more required providers for GitHub-backed mode."
9059
- ],
9060
- offendingPaths: []
9061
- },
9566
+ ]
9567
+ }),
9062
9568
  plan,
9063
- startOutcome
9569
+ startOutcome,
9570
+ targetName,
9571
+ startReceipt
9064
9572
  );
9065
9573
  }
9066
9574
  if (!startReceipt) {
9067
- writePrdRunRecord(options.repoRoot, {
9068
- prdRef,
9069
- status: "blocked",
9070
- updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
9071
- targetName,
9072
- blockedGate: "branch-state",
9073
- blockedReason: `PRD Run ${prdRef} is missing start receipt before GitHub queue drain.`,
9074
- diagnostics: [],
9075
- offendingPaths: []
9076
- });
9077
9575
  return buildLaunchBlockedOutcome(
9576
+ options.repoRoot,
9078
9577
  prdRef,
9079
- {
9578
+ buildPrdRunRepairGuidance({
9080
9579
  blockedGate: "branch-state",
9081
- failureCode: "missing_start_receipt",
9082
- reason: `PRD Run ${prdRef} is missing start receipt before GitHub queue drain.`,
9580
+ blockedStage: "start-validation",
9581
+ failureCode: "missing-start-receipt",
9582
+ humanReadableReason: `PRD Run ${prdRef} is missing start receipt before GitHub queue drain.`,
9083
9583
  repairability: "automatic-retry-safe",
9084
- diagnostics: [],
9085
- offendingPaths: []
9086
- },
9584
+ nextAction: "rerun-prd-run-launch",
9585
+ nextRecommendedCommand: "pourkit prd-run launch"
9586
+ }),
9087
9587
  plan,
9088
- startOutcome
9588
+ startOutcome,
9589
+ targetName
9089
9590
  );
9090
9591
  }
9091
9592
  if (!options.config) {
9092
9593
  const reason = `PRD Run ${prdRef} requires config for GitHub-backed queue drain.`;
9093
- writePrdRunRecord(options.repoRoot, {
9094
- prdRef,
9095
- status: "blocked",
9096
- updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
9097
- targetName,
9098
- start: startReceipt,
9099
- blockedGate: "queue",
9100
- blockedReason: reason,
9101
- diagnostics: ["Missing config for GitHub-backed mode."],
9102
- offendingPaths: []
9103
- });
9104
9594
  return buildLaunchBlockedOutcome(
9595
+ options.repoRoot,
9105
9596
  prdRef,
9106
- {
9597
+ buildPrdRunRepairGuidance({
9107
9598
  blockedGate: "queue",
9108
- failureCode: "missing_config",
9109
- reason,
9599
+ blockedStage: "queue-drain",
9600
+ failureCode: "missing-config",
9601
+ humanReadableReason: reason,
9110
9602
  repairability: "operator-action",
9111
- diagnostics: ["Missing config for GitHub-backed mode."],
9112
- offendingPaths: []
9113
- },
9603
+ nextAction: "inspect-and-retry",
9604
+ nextRecommendedCommand: "pourkit prd-run launch --with-config",
9605
+ diagnostics: ["Missing config for GitHub-backed mode."]
9606
+ }),
9114
9607
  plan,
9115
- startOutcome
9608
+ startOutcome,
9609
+ targetName,
9610
+ startReceipt
9116
9611
  );
9117
9612
  }
9118
9613
  const issueProvider = options.issueProvider;
9119
9614
  const prProvider = options.prProvider;
9120
9615
  const executionProvider = options.executionProvider;
9121
9616
  const logger = options.logger;
9617
+ const originalGuidance = readPrdRun(options.repoRoot, prdRef).record?.repairGuidance;
9122
9618
  try {
9123
9619
  const outcome = await runQueueCommand({
9124
9620
  targetName,
@@ -9133,7 +9629,8 @@ async function launchGithubQueueDrain(options, prdRef, startReceipt, targetName,
9133
9629
  prdRef,
9134
9630
  queueRunContext: {
9135
9631
  prdRef,
9136
- prdBranch: startReceipt.prdBranch
9632
+ prdBranch: startReceipt.prdBranch,
9633
+ ...resumeIssueNumber !== void 0 ? { resumeIssueNumber } : {}
9137
9634
  }
9138
9635
  });
9139
9636
  if (outcome.selected === null && outcome.code === "drained") {
@@ -9141,30 +9638,41 @@ async function launchGithubQueueDrain(options, prdRef, startReceipt, targetName,
9141
9638
  const diagnostics = [
9142
9639
  "Queue drained without processing issues. No PRD-scoped candidates or runnable Issues."
9143
9640
  ];
9144
- writePrdRunRecord(options.repoRoot, {
9145
- prdRef,
9146
- status: "blocked",
9147
- updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
9148
- targetName,
9149
- start: startReceipt,
9150
- blockedGate: "queue",
9151
- blockedReason: diagnostics[0],
9152
- diagnostics,
9153
- offendingPaths: []
9154
- });
9155
- return buildLaunchBlockedOutcome(
9641
+ const result2 = buildLaunchBlockedOutcome(
9642
+ options.repoRoot,
9156
9643
  prdRef,
9157
- {
9644
+ buildPrdRunRepairGuidance({
9158
9645
  blockedGate: "queue",
9159
- failureCode: "zero_processed",
9160
- reason: diagnostics[0],
9646
+ blockedStage: "queue-drain",
9647
+ failureCode: "zero-processed",
9648
+ humanReadableReason: diagnostics[0],
9161
9649
  repairability: "automatic-retry-safe",
9162
- diagnostics,
9163
- offendingPaths: []
9164
- },
9650
+ nextAction: "rerun-prd-run-launch",
9651
+ nextRecommendedCommand: "pourkit prd-run launch",
9652
+ diagnostics
9653
+ }),
9165
9654
  plan,
9166
- startOutcome
9655
+ startOutcome,
9656
+ targetName,
9657
+ startReceipt
9658
+ );
9659
+ const projectionOk2 = await attemptRecordedIssueLabelProjection(
9660
+ options,
9661
+ prdRef,
9662
+ resumeIssueNumber,
9663
+ originalGuidance
9167
9664
  );
9665
+ if (!projectionOk2 && originalGuidance) {
9666
+ const updatedRecord = readPrdRun(options.repoRoot, prdRef).record;
9667
+ return {
9668
+ kind: "blocked",
9669
+ prdRef,
9670
+ guidance: updatedRecord.repairGuidance,
9671
+ start: startOutcome,
9672
+ resume: plan
9673
+ };
9674
+ }
9675
+ return result2;
9168
9676
  }
9169
9677
  startReceipt.queueDrainedAt = (/* @__PURE__ */ new Date()).toISOString();
9170
9678
  startReceipt.queueProcessedCount = outcome.processedCount;
@@ -9184,10 +9692,13 @@ async function launchGithubQueueDrain(options, prdRef, startReceipt, targetName,
9184
9692
  );
9185
9693
  if (!terminalEvidence.ok) {
9186
9694
  return buildLaunchBlockedOutcome(
9695
+ options.repoRoot,
9187
9696
  prdRef,
9188
9697
  terminalEvidence.guidance,
9189
9698
  plan,
9190
- startOutcome
9699
+ startOutcome,
9700
+ targetName,
9701
+ startReceipt
9191
9702
  );
9192
9703
  }
9193
9704
  }
@@ -9213,84 +9724,117 @@ async function launchGithubQueueDrain(options, prdRef, startReceipt, targetName,
9213
9724
  }
9214
9725
  if (outcome.selected === null) {
9215
9726
  const diagnostics = [outcome.reason];
9216
- writePrdRunRecord(options.repoRoot, {
9217
- prdRef,
9218
- status: "blocked",
9219
- updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
9220
- targetName,
9221
- start: startReceipt,
9222
- blockedGate: "queue",
9223
- blockedReason: outcome.reason,
9224
- diagnostics,
9225
- offendingPaths: []
9226
- });
9227
- return buildLaunchBlockedOutcome(
9727
+ const result2 = buildLaunchBlockedOutcome(
9728
+ options.repoRoot,
9228
9729
  prdRef,
9229
- {
9730
+ buildPrdRunRepairGuidance({
9230
9731
  blockedGate: "queue",
9231
- failureCode: "queue_blocked",
9232
- reason: outcome.reason,
9732
+ blockedStage: "queue-drain",
9733
+ failureCode: "queue-blocked",
9734
+ humanReadableReason: outcome.reason,
9233
9735
  repairability: "automatic-retry-safe",
9234
- diagnostics,
9235
- offendingPaths: []
9236
- },
9736
+ nextAction: "rerun-prd-run-launch",
9737
+ nextRecommendedCommand: "pourkit prd-run launch",
9738
+ diagnostics
9739
+ }),
9237
9740
  plan,
9238
- startOutcome
9741
+ startOutcome,
9742
+ targetName,
9743
+ startReceipt
9744
+ );
9745
+ const projectionOk2 = await attemptRecordedIssueLabelProjection(
9746
+ options,
9747
+ prdRef,
9748
+ resumeIssueNumber,
9749
+ originalGuidance
9239
9750
  );
9751
+ if (!projectionOk2 && originalGuidance) {
9752
+ const updatedRecord = readPrdRun(options.repoRoot, prdRef).record;
9753
+ return {
9754
+ kind: "blocked",
9755
+ prdRef,
9756
+ guidance: updatedRecord.repairGuidance,
9757
+ start: startOutcome,
9758
+ resume: plan
9759
+ };
9760
+ }
9761
+ return result2;
9240
9762
  }
9241
9763
  const outcomeReason = `Unexpected queue outcome: selected issue ${outcome.selected.number}`;
9242
9764
  const outcomeDiagnostics = [outcomeReason];
9243
- writePrdRunRecord(options.repoRoot, {
9244
- prdRef,
9245
- status: "blocked",
9246
- updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
9247
- targetName,
9248
- start: startReceipt,
9249
- blockedGate: "queue",
9250
- blockedReason: outcomeReason,
9251
- diagnostics: outcomeDiagnostics,
9252
- offendingPaths: []
9253
- });
9254
- return buildLaunchBlockedOutcome(
9765
+ const result = buildLaunchBlockedOutcome(
9766
+ options.repoRoot,
9255
9767
  prdRef,
9256
- {
9768
+ buildPrdRunRepairGuidance({
9257
9769
  blockedGate: "queue",
9258
- failureCode: "unexpected_queue_outcome",
9259
- reason: outcomeReason,
9770
+ blockedStage: "queue-drain",
9771
+ failureCode: "unexpected-queue-outcome",
9772
+ humanReadableReason: outcomeReason,
9260
9773
  repairability: "operator-action",
9261
- diagnostics: outcomeDiagnostics,
9262
- offendingPaths: []
9263
- },
9774
+ nextAction: "inspect-and-retry",
9775
+ nextRecommendedCommand: "pourkit prd-run launch",
9776
+ diagnostics: outcomeDiagnostics
9777
+ }),
9264
9778
  plan,
9265
- startOutcome
9779
+ startOutcome,
9780
+ targetName,
9781
+ startReceipt
9782
+ );
9783
+ const projectionOk = await attemptRecordedIssueLabelProjection(
9784
+ options,
9785
+ prdRef,
9786
+ resumeIssueNumber,
9787
+ originalGuidance
9266
9788
  );
9789
+ if (!projectionOk && originalGuidance) {
9790
+ const updatedRecord = readPrdRun(options.repoRoot, prdRef).record;
9791
+ return {
9792
+ kind: "blocked",
9793
+ prdRef,
9794
+ guidance: updatedRecord.repairGuidance,
9795
+ start: startOutcome,
9796
+ resume: plan
9797
+ };
9798
+ }
9799
+ return result;
9267
9800
  } catch (error) {
9268
9801
  const msg = error instanceof Error ? error.message : String(error);
9269
9802
  const diagnostics = [msg];
9270
- writePrdRunRecord(options.repoRoot, {
9271
- prdRef,
9272
- status: "blocked",
9273
- updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
9274
- targetName,
9275
- start: startReceipt,
9276
- blockedGate: "queue",
9277
- blockedReason: msg,
9278
- diagnostics,
9279
- offendingPaths: []
9280
- });
9281
- return buildLaunchBlockedOutcome(
9803
+ const result = buildLaunchBlockedOutcome(
9804
+ options.repoRoot,
9282
9805
  prdRef,
9283
- {
9806
+ buildPrdRunRepairGuidance({
9284
9807
  blockedGate: "queue",
9285
- failureCode: "queue_exception",
9286
- reason: msg,
9808
+ blockedStage: "queue-drain",
9809
+ failureCode: "queue-exception",
9810
+ humanReadableReason: msg,
9287
9811
  repairability: "automatic-retry-safe",
9288
- diagnostics,
9289
- offendingPaths: []
9290
- },
9812
+ nextAction: "rerun-prd-run-launch",
9813
+ nextRecommendedCommand: "pourkit prd-run launch",
9814
+ diagnostics
9815
+ }),
9291
9816
  plan,
9292
- startOutcome
9817
+ startOutcome,
9818
+ targetName,
9819
+ startReceipt
9820
+ );
9821
+ const projectionOk = await attemptRecordedIssueLabelProjection(
9822
+ options,
9823
+ prdRef,
9824
+ resumeIssueNumber,
9825
+ originalGuidance
9293
9826
  );
9827
+ if (!projectionOk && originalGuidance) {
9828
+ const updatedRecord = readPrdRun(options.repoRoot, prdRef).record;
9829
+ return {
9830
+ kind: "blocked",
9831
+ prdRef,
9832
+ guidance: updatedRecord.repairGuidance,
9833
+ start: startOutcome,
9834
+ resume: plan
9835
+ };
9836
+ }
9837
+ return result;
9294
9838
  }
9295
9839
  }
9296
9840
 
@@ -9341,7 +9885,7 @@ function mapLaunchPrdRunOutcomeToCommandResult(outcome, options) {
9341
9885
  };
9342
9886
  }
9343
9887
  if (outcome.kind === "blocked") {
9344
- const diagnostics = outcome.guidance.diagnostics ? [...outcome.guidance.diagnostics] : [outcome.guidance.reason];
9888
+ const diagnostics = renderPrdRunRepairGuidance(outcome.guidance);
9345
9889
  return {
9346
9890
  prdRef,
9347
9891
  status: "blocked",
@@ -9350,7 +9894,7 @@ function mapLaunchPrdRunOutcomeToCommandResult(outcome, options) {
9350
9894
  resumed: [...outcome.resume.resumed],
9351
9895
  diagnostics,
9352
9896
  blockedGate: outcome.guidance.blockedGate,
9353
- blockedReason: outcome.guidance.reason,
9897
+ blockedReason: outcome.guidance.humanReadableReason,
9354
9898
  offendingPaths: outcome.guidance.offendingPaths ? [...outcome.guidance.offendingPaths] : [],
9355
9899
  start: outcome.start ? mapStartPrdRunOutcomeToCommandResult(outcome.start) : void 0
9356
9900
  };
@@ -9375,27 +9919,40 @@ function mapStartPrdRunOutcomeToCommandResult(outcome) {
9375
9919
  diagnostics: [...outcome.diagnostics]
9376
9920
  };
9377
9921
  }
9378
- const diagnostics = outcome.guidance.diagnostics ? [...outcome.guidance.diagnostics] : [outcome.guidance.reason];
9379
9922
  return {
9380
9923
  prdRef: outcome.prdRef,
9381
9924
  status: "blocked",
9382
9925
  blockedGate: outcome.guidance.blockedGate,
9383
- blockedReason: outcome.guidance.reason,
9384
- diagnostics,
9926
+ blockedReason: outcome.guidance.humanReadableReason,
9927
+ diagnostics: renderPrdRunRepairGuidance(outcome.guidance),
9385
9928
  offendingPaths: outcome.guidance.offendingPaths ? [...outcome.guidance.offendingPaths] : []
9386
9929
  };
9387
9930
  }
9388
9931
  function runPrdRunStatusCommand(options) {
9389
9932
  const prdRef = normalizePrdRunRef(options.prdRef);
9390
9933
  const { record, diagnostics } = readPrdRun(options.repoRoot, prdRef);
9391
- return {
9392
- prdRef,
9393
- record,
9394
- diagnostics: record?.status === "completed_prd_branch" ? [
9395
- ...diagnostics,
9396
- buildCompletedPrdBranchHint(record.prdBranch ?? prdRef)
9397
- ] : diagnostics
9398
- };
9934
+ if (record?.status === "completed_prd_branch") {
9935
+ return {
9936
+ prdRef,
9937
+ record,
9938
+ diagnostics: [
9939
+ ...diagnostics,
9940
+ buildCompletedPrdBranchHint(record.prdBranch ?? prdRef)
9941
+ ]
9942
+ };
9943
+ }
9944
+ if (record?.status === "blocked") {
9945
+ const validated = validateActivePrdRunRepairGuidance(record);
9946
+ return {
9947
+ prdRef,
9948
+ record,
9949
+ diagnostics: [
9950
+ ...diagnostics,
9951
+ ...renderPrdRunRepairGuidance(validated.guidance)
9952
+ ]
9953
+ };
9954
+ }
9955
+ return { prdRef, record, diagnostics };
9399
9956
  }
9400
9957
  function runPrdRunListCommand(options) {
9401
9958
  return listPrdRuns(options.repoRoot);
@@ -12478,7 +13035,7 @@ async function runSerenaStatusCommand(options) {
12478
13035
  // commands/config-schema.ts
12479
13036
  import { readFileSync as readFileSync18, existsSync as existsSync18 } from "fs";
12480
13037
  import { mkdir as mkdir5, readFile as readFile5, writeFile as writeFile2, readdir as readdir2 } from "fs/promises";
12481
- import { resolve as resolve3, dirname as dirname5, relative as relative2 } from "path";
13038
+ import { resolve as resolve3, dirname as dirname5, relative as relative3 } from "path";
12482
13039
  import { fileURLToPath as fileURLToPath3 } from "url";
12483
13040
  import Ajv2 from "ajv";
12484
13041
  init_common();
@@ -12541,7 +13098,7 @@ async function readPackagedTextFile(filePath) {
12541
13098
  }
12542
13099
  }
12543
13100
  function isPathContained(parent, child) {
12544
- const relativePath = relative2(parent, child);
13101
+ const relativePath = relative3(parent, child);
12545
13102
  return !relativePath.startsWith("..") && !relativePath.startsWith("../");
12546
13103
  }
12547
13104
  async function walkDir2(dir) {
@@ -12796,7 +13353,7 @@ async function validateWorkflowPack(cwd) {
12796
13353
  if (existsSync18(overridesDir)) {
12797
13354
  const overrideFiles = await walkDir2(overridesDir);
12798
13355
  for (const file of overrideFiles) {
12799
- const relPath = relative2(cwd, file);
13356
+ const relPath = relative3(cwd, file);
12800
13357
  if (!warnings.some((w) => w.kind === "overridden" && w.path === relPath)) {
12801
13358
  warnings.push({
12802
13359
  severity: "warning",
@@ -12936,8 +13493,8 @@ async function validateWorkflowPack(cwd) {
12936
13493
  failures.push({
12937
13494
  severity: "failure",
12938
13495
  kind: "path_escape",
12939
- path: relative2(cwd, file),
12940
- message: `Override file path escapes repository: ${relative2(cwd, file)}`
13496
+ path: relative3(cwd, file),
13497
+ message: `Override file path escapes repository: ${relative3(cwd, file)}`
12941
13498
  });
12942
13499
  }
12943
13500
  }
@@ -12949,7 +13506,7 @@ async function validateWorkflowPack(cwd) {
12949
13506
  if (!file.endsWith(".md")) continue;
12950
13507
  try {
12951
13508
  const content = await readFile5(file, "utf-8");
12952
- const relPath = relative2(cwd, file);
13509
+ const relPath = relative3(cwd, file);
12953
13510
  const violations = scanManagedPolicyText(content, relPath);
12954
13511
  for (const v of violations) {
12955
13512
  failures.push({
@@ -12972,7 +13529,7 @@ async function validateWorkflowPack(cwd) {
12972
13529
  if (!existsSync18(skillFile)) continue;
12973
13530
  try {
12974
13531
  const content = await readFile5(skillFile, "utf-8");
12975
- const relPath = relative2(cwd, skillFile);
13532
+ const relPath = relative3(cwd, skillFile);
12976
13533
  const violations = scanManagedPolicyText(content, relPath);
12977
13534
  for (const v of violations) {
12978
13535
  failures.push({
@@ -12993,7 +13550,7 @@ async function validateWorkflowPack(cwd) {
12993
13550
  if (!existsSync18(promptFile)) continue;
12994
13551
  try {
12995
13552
  const content = await readFile5(promptFile, "utf-8");
12996
- const relPath = relative2(cwd, promptFile);
13553
+ const relPath = relative3(cwd, promptFile);
12997
13554
  const violations = scanManagedPolicyText(content, relPath);
12998
13555
  for (const v of violations) {
12999
13556
  failures.push({
@@ -13015,7 +13572,7 @@ async function validateWorkflowPack(cwd) {
13015
13572
  if (!existsSync18(addonSkillFile)) continue;
13016
13573
  try {
13017
13574
  const content = await readFile5(addonSkillFile, "utf-8");
13018
- const relPath = relative2(cwd, addonSkillFile);
13575
+ const relPath = relative3(cwd, addonSkillFile);
13019
13576
  const violations = scanManagedPolicyText(content, relPath);
13020
13577
  for (const v of violations) {
13021
13578
  failures.push({
@@ -13036,7 +13593,7 @@ async function validateWorkflowPack(cwd) {
13036
13593
  if (!existsSync18(addonDocFile)) continue;
13037
13594
  try {
13038
13595
  const content = await readFile5(addonDocFile, "utf-8");
13039
- const relPath = relative2(cwd, addonDocFile);
13596
+ const relPath = relative3(cwd, addonDocFile);
13040
13597
  const violations = scanManagedPolicyText(content, relPath);
13041
13598
  for (const v of violations) {
13042
13599
  failures.push({
@@ -13229,7 +13786,7 @@ async function runConfigSyncSchemaCommand(options) {
13229
13786
  // commands/workflow-pack-sync.ts
13230
13787
  import { existsSync as existsSync19, readdirSync as readdirSync4 } from "fs";
13231
13788
  import { mkdir as mkdir6, readFile as readFile6, writeFile as writeFile3, readdir as readdir3 } from "fs/promises";
13232
- import { resolve as resolve4, dirname as dirname6, relative as relative3, normalize as normalize2 } from "path";
13789
+ import { resolve as resolve4, dirname as dirname6, relative as relative4, normalize as normalize2 } from "path";
13233
13790
  import { fileURLToPath as fileURLToPath4 } from "url";
13234
13791
  var __filename4 = fileURLToPath4(import.meta.url);
13235
13792
  var __dirname4 = dirname6(__filename4);
@@ -13272,7 +13829,7 @@ async function readPackagedTextFile2(filePath) {
13272
13829
  }
13273
13830
  }
13274
13831
  function isPathContained2(parent, child) {
13275
- const relativePath = relative3(parent, child);
13832
+ const relativePath = relative4(parent, child);
13276
13833
  return !relativePath.startsWith("..") && !relativePath.startsWith("../");
13277
13834
  }
13278
13835
  function isProjectOwnedPath(relativePath) {
@@ -13381,7 +13938,7 @@ async function detectOverrides(cwd) {
13381
13938
  return [];
13382
13939
  }
13383
13940
  const files = await walkDir3(overridesDir);
13384
- return files.map((f) => relative3(cwd, f));
13941
+ return files.map((f) => relative4(cwd, f));
13385
13942
  }
13386
13943
  async function detectProjectOwnedFiles(cwd) {
13387
13944
  const found = [];
@@ -13396,7 +13953,7 @@ async function detectProjectOwnedFiles(cwd) {
13396
13953
  if (existsSync19(fullDir)) {
13397
13954
  const files = await walkDir3(fullDir);
13398
13955
  for (const file of files) {
13399
- found.push(relative3(cwd, file));
13956
+ found.push(relative4(cwd, file));
13400
13957
  }
13401
13958
  }
13402
13959
  }
@@ -13649,7 +14206,7 @@ async function syncSkill(skillName, catalog, acc, ctx) {
13649
14206
  return;
13650
14207
  }
13651
14208
  for (const sourceFile of skillFiles) {
13652
- const relPath = relative3(skillDir, sourceFile);
14209
+ const relPath = relative4(skillDir, sourceFile);
13653
14210
  const targetRelativePath = `.pourkit/managed/skills/${skillName}/${relPath}`;
13654
14211
  if (isProjectOwnedPath(targetRelativePath)) {
13655
14212
  skippedProjectOwned.push(targetRelativePath);
@@ -13725,7 +14282,7 @@ async function syncAddonSkill(skillName, acc, ctx) {
13725
14282
  return;
13726
14283
  }
13727
14284
  for (const sourceFile of skillFiles) {
13728
- const relPath = relative3(addonSkillDir, sourceFile);
14285
+ const relPath = relative4(addonSkillDir, sourceFile);
13729
14286
  const targetRelativePath = `.pourkit/managed/addons/release/skills/${skillName}/${relPath}`;
13730
14287
  if (isProjectOwnedPath(targetRelativePath)) {
13731
14288
  skippedProjectOwned.push(targetRelativePath);
@@ -15517,11 +16074,11 @@ function createCliProgram(version) {
15517
16074
  return program;
15518
16075
  }
15519
16076
  async function resolveCliVersion() {
15520
- if (isPackageVersion("0.0.0-next-20260623021955")) {
15521
- return "0.0.0-next-20260623021955";
16077
+ if (isPackageVersion("0.0.0-next-20260624074234")) {
16078
+ return "0.0.0-next-20260624074234";
15522
16079
  }
15523
- if (isReleaseVersion("0.0.0-next-20260623021955")) {
15524
- return "0.0.0-next-20260623021955";
16080
+ if (isReleaseVersion("0.0.0-next-20260624074234")) {
16081
+ return "0.0.0-next-20260624074234";
15525
16082
  }
15526
16083
  try {
15527
16084
  const root = repoRoot();