@pourkit/cli 0.0.0-next-20260614002607 → 0.0.0-next-20260614182520
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 +1136 -1030
- package/dist/cli.js.map +1 -1
- package/dist/e2e/run-live-e2e.js +570 -643
- package/dist/e2e/run-live-e2e.js.map +1 -1
- package/dist/issues/close-issues-on-merge.js +19 -1
- package/dist/issues/close-issues-on-merge.js.map +1 -1
- package/dist/issues/unblock.js +19 -1
- package/dist/issues/unblock.js.map +1 -1
- package/dist/schema/pourkit.schema.hash +1 -0
- package/dist/schema/pourkit.schema.json +356 -0
- package/package.json +6 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../common/logger/src/index.ts","../../shared/common.ts","../../e2e/run-live-e2e.ts","../../commands/issue-run.ts","../../shared/config.ts","../../pr/templates.ts","../../shared/run-context.ts","../../commands/run-verification.ts","../../shared/prompt-guidance.ts","../../shared/worktree-run-state.ts","../../commands/base-refresh.ts","../../failure-resolution/effect-runtime.ts","../../shared/effect-runtime.ts","../../failure-resolution/types.ts","../../shared/attempt-log.ts","../../failure-resolution/stage-attempt.ts","../../commands/conflict-resolution.ts","../../conflicts/conflict-resolution-artifact.ts","../../commands/artifact-validation.ts","../../pr/review-verdict.ts","../../commands/review.ts","../../execution/agent-output-retry.ts","../../shared/effect-services.ts","../../pr/pr-description.ts","../../prd-run/final-review-validation.ts","../../serena/baseline.ts","../../serena/container.ts","../../serena/preflight.ts","../../failure-resolution/failure-resolution-agent.ts","../../failure-resolution/recovery-policy.ts","../../commands/pr-description-agent.ts","../../pr/pr-description-context.ts","../../prd-run/local-merge-coordinator.ts","../../prd-run/local-branches.ts","../../pr/pr-body.ts","../../issues/target-green.ts","../../issues/merge-coordinator.ts","../../commands/issue-final-review-agent.ts","../../issues/issue-transitions.ts","../../issues/stacked-issue.ts","../../commands/issue.ts","../../providers/github-provider.ts","../../providers/github-pr-provider.ts","../../providers/github-client.ts","../../execution/deterministic-agent.ts","../../execution/sandbox-image-build.ts","../../execution/sandbox-image.ts","../../execution/sandbox-options.ts","../../execution/execution-provider.ts","../../e2e/profile.ts","../../e2e/live/harness.ts"],"sourcesContent":["import { createWriteStream } from \"node:fs\";\nimport { mkdirSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { styleText } from \"node:util\";\n\nexport interface PourkitLogger {\n line(msg: string): void;\n raw(msg: string): void;\n step(step: string, msg: string): void;\n status(status: string): void;\n kv(key: string, value: string): void;\n close(): Promise<void>;\n}\n\nexport function createLogger(name: string, filePath?: string): PourkitLogger {\n let fileStream: import(\"fs\").WriteStream | undefined;\n\n if (filePath) {\n mkdirSync(path.dirname(filePath), { recursive: true });\n fileStream = createWriteStream(filePath, { flags: \"a\" });\n }\n\n const write = (terminal: string, plain = terminal) => {\n process.stdout.write(`${terminal}\\n`);\n if (fileStream) {\n fileStream.write(`${plain}\\n`);\n }\n };\n\n return {\n line(msg: string) {\n const ts = timestamp();\n write(`${ts.terminal} ${msg}`, `${ts.plain} ${msg}`);\n },\n\n raw(msg: string) {\n write(msg);\n },\n\n step(step: string, msg: string) {\n const ts = timestamp();\n write(\n `${ts.terminal} ${formatStep(step)} ${formatStepMessage(step, msg)}`,\n `${ts.plain} [${step}] ${msg}`\n );\n },\n\n status(status: string) {\n const ts = timestamp();\n write(\n `${ts.terminal} ${color([\"bold\", \"cyan\"], \"POURKIT\")} ${color(\"cyan\", status)}`,\n `${ts.plain} POURKIT ${status}`\n );\n },\n\n kv(key: string, value: string) {\n const ts = timestamp();\n write(\n `${ts.terminal} ${color(\"dim\", key)}=${formatValue(key, value)}`,\n `${ts.plain} ${key}=${value}`\n );\n },\n\n async close() {\n await new Promise<void>((resolve) => {\n if (!fileStream) {\n resolve();\n return;\n }\n\n const timer = setTimeout(() => {\n if (!fileStream.destroyed) {\n fileStream.destroy();\n }\n resolve();\n }, 2000);\n\n fileStream.end(() => {\n clearTimeout(timer);\n resolve();\n });\n });\n },\n };\n}\n\nfunction timestamp() {\n const now = new Date();\n const time = now.toTimeString().slice(0, 8);\n const ms = String(now.getMilliseconds()).padStart(3, \"0\");\n const plain = `${time}.${ms}`;\n return { terminal: color(\"dim\", plain), plain };\n}\n\nfunction formatStep(step: string) {\n return color(stepStyle(step), `[${step}]`);\n}\n\nfunction formatStepMessage(step: string, msg: string) {\n if (step === \"error\") {\n return color(\"red\", msg);\n }\n if (step === \"warn\") {\n return color(\"yellow\", msg);\n }\n return msg;\n}\n\nfunction formatValue(key: string, value: string) {\n if (/SUCCESS|CREATED|COMMITS/.test(key)) {\n return color(\"green\", value);\n }\n if (/BRANCH|PATH|FILE|URL/.test(key)) {\n return color(\"cyan\", value);\n }\n return color(\"bold\", value);\n}\n\nfunction stepStyle(step: string): Parameters<typeof styleText>[0] {\n switch (step) {\n case \"sandcastle\":\n return [\"bold\", \"cyan\"];\n case \"git\":\n return [\"bold\", \"magenta\"];\n case \"review\":\n case \"reviewer\":\n return [\"bold\", \"blue\"];\n case \"cleanup\":\n return [\"bold\", \"yellow\"];\n case \"error\":\n return [\"bold\", \"red\"];\n case \"warn\":\n return [\"bold\", \"yellow\"];\n case \"info\":\n return \"cyan\";\n default:\n return \"green\";\n }\n}\n\nfunction color(format: Parameters<typeof styleText>[0], text: string) {\n if (process.env.NO_COLOR) {\n return text;\n }\n\n try {\n return styleText(format, text);\n } catch {\n return text;\n }\n}\n","import { mkdir } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { execFile, spawnSync } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport { type PourkitLogger, createLogger } from \"@pourkit/logger\";\n\nconst execFileAsync = promisify(execFile);\n\ntype RunResult = {\n code: number;\n stdout: string;\n stderr: string;\n};\n\nexport type { PourkitLogger };\nexport { createLogger };\n\nexport async function ensureDir(dir: string) {\n await mkdir(dir, { recursive: true });\n}\n\nexport function repoRoot(explicitRoot = process.env.POURKIT_ROOT) {\n if (explicitRoot?.trim()) {\n const root = explicitRoot.trim();\n\n const insideResult = spawnSync(\n \"git\",\n [\"-C\", root, \"rev-parse\", \"--is-inside-work-tree\"],\n { encoding: \"utf8\" }\n );\n\n if (insideResult.status !== 0 || insideResult.stdout.trim() !== \"true\") {\n throw new Error(\n `POURKIT_ROOT is not a valid Git worktree: ${root}\\n${insideResult.stderr || insideResult.stdout}`\n );\n }\n\n const topLevelResult = spawnSync(\n \"git\",\n [\"-C\", root, \"rev-parse\", \"--show-toplevel\"],\n { encoding: \"utf8\" }\n );\n\n if (topLevelResult.status !== 0) {\n throw new Error(\n `Failed to validate POURKIT_ROOT as a Git worktree: ${root}\\n${topLevelResult.stderr || topLevelResult.stdout}`\n );\n }\n\n return topLevelResult.stdout.trim();\n }\n\n const result = spawnSync(\"git\", [\"rev-parse\", \"--show-toplevel\"], {\n encoding: \"utf8\",\n });\n\n if (result.status !== 0) {\n throw new Error(\n `Failed to resolve repo root: ${result.stderr || result.stdout}`\n );\n }\n\n return result.stdout.trim();\n}\n\nexport function repoRelative(root: string, ...segments: string[]) {\n return path.join(root, ...segments);\n}\n\nexport function slugify(value: string) {\n const slug = value\n .toLowerCase()\n .replace(/[^a-z0-9]/g, \"-\")\n .replace(/--+/g, \"-\")\n .replace(/^-+/, \"\")\n .replace(/-+$/, \"\")\n .slice(0, 50);\n\n return slug || \"issue\";\n}\n\nfunction formatCommand(command: string, args: string[]) {\n return [command, ...args]\n .map((part) => {\n if (/^[A-Za-z0-9_\\/.=:,@+-]+$/.test(part)) {\n return part;\n }\n\n return `'${part.replace(/'/g, \"'\\\\''\")}'`;\n })\n .join(\" \");\n}\n\nexport function readMaybeEnvInt(value: string | undefined, fallback: number) {\n const parsed = Number(value ?? fallback);\n return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;\n}\n\nexport async function execCapture(\n command: string,\n args: string[],\n options: {\n cwd?: string;\n env?: NodeJS.ProcessEnv;\n logger?: PourkitLogger;\n label?: string;\n } = {}\n) {\n if (options.logger && options.label) {\n options.logger.step(\n options.label,\n `running ${formatCommand(command, args)}`\n );\n }\n\n let stdout = \"\";\n let stderr = \"\";\n let code = 0;\n\n try {\n const result = await execFileAsync(command, args, {\n cwd: options.cwd,\n env: options.env,\n encoding: \"utf8\",\n maxBuffer: 20 * 1024 * 1024,\n });\n\n stdout =\n typeof result.stdout === \"string\"\n ? result.stdout\n : String(result.stdout ?? \"\");\n stderr =\n typeof result.stderr === \"string\"\n ? result.stderr\n : String(result.stderr ?? \"\");\n } catch (error) {\n const err = error as NodeJS.ErrnoException & {\n stdout?: string;\n stderr?: string;\n code?: number | string;\n };\n stdout = typeof err.stdout === \"string\" ? err.stdout : \"\";\n stderr = typeof err.stderr === \"string\" ? err.stderr : \"\";\n code = typeof err.code === \"number\" ? err.code : 1;\n }\n\n if (code !== 0) {\n throw new Error(\n [\n `command failed: ${formatCommand(command, args)}`,\n `exit code: ${code}`,\n stdout ? `stdout:\\n${stdout}` : \"\",\n stderr ? `stderr:\\n${stderr}` : \"\",\n ]\n .filter(Boolean)\n .join(\"\\n\")\n );\n }\n\n return { code, stdout, stderr } satisfies RunResult;\n}\n\nexport async function execJson<T>(\n command: string,\n args: string[],\n options: {\n cwd?: string;\n env?: NodeJS.ProcessEnv;\n logger?: PourkitLogger;\n label?: string;\n } = {}\n) {\n const result = await execCapture(command, args, options);\n return JSON.parse(result.stdout) as T;\n}\n\nexport function sleep(ms: number) {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nconst TRANSIENT_GH_ERROR =\n /HTTP (502|503|504)\\b|Could not close the issue|GraphQL:.*closeIssue/;\n\nexport async function execCaptureWithRetry(\n command: string,\n args: string[],\n options: {\n cwd?: string;\n env?: NodeJS.ProcessEnv;\n logger?: PourkitLogger;\n label?: string;\n retries?: number;\n backoffMs?: number;\n } = {}\n) {\n const retries = options.retries ?? 3;\n const backoffMs = options.backoffMs ?? 2000;\n let lastError: Error | null = null;\n\n for (let attempt = 1; attempt <= retries; attempt++) {\n try {\n return await execCapture(command, args, options);\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n if (!TRANSIENT_GH_ERROR.test(lastError.message)) {\n throw lastError;\n }\n if (options.logger) {\n options.logger.step(\n options.label ?? command,\n `transient failure (attempt ${attempt}/${retries}), retrying`\n );\n }\n if (attempt < retries) {\n await sleep(backoffMs * Math.pow(2, attempt - 1));\n }\n }\n }\n\n throw lastError!;\n}\n\nasync function execJsonWithRetry<T>(\n command: string,\n args: string[],\n options: {\n cwd?: string;\n env?: NodeJS.ProcessEnv;\n logger?: PourkitLogger;\n label?: string;\n retries?: number;\n backoffMs?: number;\n } = {}\n) {\n const result = await execCaptureWithRetry(command, args, options);\n return JSON.parse(result.stdout) as T;\n}\n\nexport const TYPE_LABELS = [\n \"type:bugfix\",\n \"type:infra\",\n \"type:feature\",\n \"type:polish\",\n \"type:refactor\",\n] as const;\n\n/**\n * Parse `git worktree list --porcelain` output and find the worktree\n * path for a given branch.\n *\n * Returns null if no worktree is registered for that branch.\n */\nexport function parseWorktreeListPorcelain(\n text: string,\n branch: string\n): string | null {\n const entries = text.trim().split(\"\\n\\n\");\n for (const entry of entries) {\n const lines = entry.trim().split(\"\\n\");\n let path = \"\";\n let entryBranch = \"\";\n for (const line of lines) {\n if (line.startsWith(\"worktree \")) {\n path = line.slice(\"worktree \".length);\n } else if (line.startsWith(\"branch refs/heads/\")) {\n entryBranch = line.slice(\"branch refs/heads/\".length);\n }\n }\n if (entryBranch === branch && path) {\n return path;\n }\n }\n return null;\n}\n","import path from \"node:path\";\nimport { existsSync } from \"node:fs\";\nimport { pathToFileURL } from \"node:url\";\nimport { mkdir, readFile, readdir, rm, writeFile } from \"node:fs/promises\";\nimport { runIssueCommand } from \"../commands/issue\";\nimport {\n createLogger,\n execCapture,\n execJson,\n parseWorktreeListPorcelain,\n repoRoot,\n type PourkitLogger,\n} from \"../shared/common\";\nimport {\n getVerificationCommands as getTargetVerificationCommands,\n loadRepoConfig,\n resolveTarget,\n type PourkitConfig,\n} from \"../shared/config\";\nimport { renderBranchName } from \"../pr/templates\";\nimport { GitHubIssueProvider } from \"../providers/github-provider\";\nimport { GitHubPRProvider } from \"../providers/github-pr-provider\";\nimport {\n requireGitHubClient,\n type GitHubClient,\n} from \"../providers/github-client\";\nimport type { PullRequest } from \"../providers/pr-provider\";\nimport { DeterministicExecutionProvider } from \"../execution/deterministic-agent\";\nimport {\n getVerificationCommands,\n composeFailureWithProfile,\n type E2EVerificationProfile,\n} from \"./profile\";\nimport { waitForBranchChecks } from \"../issues/target-green\";\nimport {\n cleanupResources as harnessCleanupResources,\n createE2EIssue as harnessCreateE2EIssue,\n createLiveTargetBranch as harnessCreateLiveTargetBranch,\n fetchIssueLabels,\n persistResources as harnessPersistResources,\n recoverStaleRuns as harnessRecoverStaleRuns,\n runCleanupOnly as harnessRunCleanupOnly,\n} from \"./live/harness\";\n\nexport interface E2EOptions {\n keep: boolean;\n fail: boolean;\n fullCheck: boolean;\n cleanupOnly: boolean;\n targetName?: string;\n}\n\ninterface E2EResources {\n targetBranch?: string;\n issueNumber?: number;\n issueUrl?: string;\n agentBranch?: string;\n prNumber?: number;\n prUrl?: string;\n}\n\ninterface E2EStateFile extends E2EResources {\n runId: string;\n}\n\nconst E2E_STATE_DIR = path.join(\".pourkit\", \".tmp\", \"e2e-runs\");\n\nexport function parseArgs(): E2EOptions {\n const args = process.argv.slice(2);\n let keep = false;\n let fail = false;\n let fullCheck = false;\n let cleanupOnly = false;\n let targetName: string | undefined;\n\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n if (arg === \"--keep\") {\n keep = true;\n } else if (arg === \"--fail\") {\n fail = true;\n } else if (arg === \"--full-check\") {\n fullCheck = true;\n } else if (arg === \"--cleanup-only\") {\n cleanupOnly = true;\n } else if (arg === \"--target\" && args[i + 1]) {\n targetName = args[i + 1];\n i++;\n }\n }\n\n return { keep, fail, fullCheck, cleanupOnly, targetName };\n}\n\nexport function resolveProfile(fullCheck: boolean): E2EVerificationProfile {\n return fullCheck ? \"full-check\" : \"fast\";\n}\n\nexport function isExecutedAsScript(\n currentUrl = import.meta.url,\n entryPoint = process.argv[1]\n): boolean {\n if (!entryPoint) {\n return false;\n }\n\n return currentUrl === pathToFileURL(path.resolve(entryPoint)).href;\n}\n\nexport function resolveE2EConfigFile(root: string): string {\n const explicitConfig = process.env.POURKIT_CONFIG_FILE?.trim();\n if (explicitConfig) {\n return explicitConfig;\n }\n\n if (existsSync(path.join(root, \"pourkit.config.ts\"))) {\n return \"pourkit.config.ts\";\n }\n\n return \"pourkit.config.example.ts\";\n}\n\nfunction generateRunId(): string {\n return `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n}\n\nfunction stateFilePath(root: string, runId: string): string {\n return path.join(root, E2E_STATE_DIR, `${runId}.json`);\n}\n\nasync function persistResources(\n root: string,\n runId: string,\n resources: E2EResources\n): Promise<void> {\n const filePath = stateFilePath(root, runId);\n await mkdir(path.dirname(filePath), { recursive: true });\n const state: E2EStateFile = { runId, ...resources };\n await writeFile(filePath, `${JSON.stringify(state, null, 2)}\\n`, \"utf-8\");\n}\n\nasync function localBranchExists(branchName: string): Promise<boolean> {\n try {\n await execCapture(\"git\", [\n \"show-ref\",\n \"--verify\",\n \"--quiet\",\n `refs/heads/${branchName}`,\n ]);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function remoteBranchExists(branchName: string): Promise<boolean> {\n const result = await execCapture(\"git\", [\n \"ls-remote\",\n \"--heads\",\n \"origin\",\n branchName,\n ]);\n return result.stdout.trim().length > 0;\n}\n\nasync function removeWorktreeForBranch(\n branchName: string,\n logger: PourkitLogger\n): Promise<boolean> {\n try {\n const result = await execCapture(\"git\", [\n \"worktree\",\n \"list\",\n \"--porcelain\",\n ]);\n const worktreePath = parseWorktreeListPorcelain(result.stdout, branchName);\n\n if (!worktreePath) {\n return true;\n }\n\n logger.step(\"cleanup\", `Removing worktree for branch: ${branchName}...`);\n await execCapture(\"git\", [\"worktree\", \"remove\", \"--force\", worktreePath]);\n return true;\n } catch (error) {\n logger.step(\n \"warn\",\n `Failed to remove worktree for branch: ${error instanceof Error ? error.message : String(error)}`\n );\n return false;\n }\n}\n\nasync function deleteLocalBranch(\n branchName: string,\n logger: PourkitLogger\n): Promise<boolean> {\n if (!(await localBranchExists(branchName))) {\n return true;\n }\n\n if (!(await removeWorktreeForBranch(branchName, logger))) {\n return false;\n }\n\n try {\n logger.step(\"cleanup\", `Deleting local branch: ${branchName}...`);\n await execCapture(\"git\", [\"branch\", \"-D\", branchName]);\n return true;\n } catch (error) {\n logger.step(\n \"warn\",\n `Failed to delete local branch: ${error instanceof Error ? error.message : String(error)}`\n );\n return false;\n }\n}\n\nasync function deleteRemoteBranch(\n branchName: string,\n logger: PourkitLogger\n): Promise<boolean> {\n if (!(await remoteBranchExists(branchName))) {\n return true;\n }\n\n try {\n logger.step(\"cleanup\", `Deleting remote branch: ${branchName}...`);\n await execCapture(\"git\", [\"push\", \"origin\", \"--delete\", branchName]);\n return true;\n } catch (error) {\n logger.step(\n \"warn\",\n `Failed to delete remote branch: ${error instanceof Error ? error.message : String(error)}`\n );\n return false;\n }\n}\n\nasync function recoverStaleRuns(\n root: string,\n logger: PourkitLogger\n): Promise<void> {\n const dir = path.join(root, E2E_STATE_DIR);\n\n try {\n const entries = await readdir(dir, { withFileTypes: true });\n for (const entry of entries) {\n if (!entry.isFile() || !entry.name.endsWith(\".json\")) continue;\n\n const filePath = path.join(dir, entry.name);\n try {\n const raw = await readFile(filePath, \"utf-8\");\n const state = JSON.parse(raw) as E2EStateFile;\n let cleanupSucceeded = true;\n\n if (state.agentBranch) {\n cleanupSucceeded =\n (await deleteLocalBranch(state.agentBranch, logger)) &&\n cleanupSucceeded;\n cleanupSucceeded =\n (await deleteRemoteBranch(state.agentBranch, logger)) &&\n cleanupSucceeded;\n }\n\n if (state.targetBranch) {\n cleanupSucceeded =\n (await deleteLocalBranch(state.targetBranch, logger)) &&\n cleanupSucceeded;\n cleanupSucceeded =\n (await deleteRemoteBranch(state.targetBranch, logger)) &&\n cleanupSucceeded;\n }\n\n if (cleanupSucceeded) {\n await rm(filePath, { force: true });\n } else {\n logger.step(\n \"warn\",\n `Preserving stale E2E state ${entry.name} for cleanup retry`\n );\n }\n } catch (error) {\n logger.step(\n \"warn\",\n `Failed to recover stale E2E state ${entry.name}: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") {\n logger.step(\n \"warn\",\n `Failed to scan stale E2E state: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n}\n\nexport function makeE2EConfig(\n baseConfig: PourkitConfig,\n targetName: string | undefined,\n targetBranch: string,\n profile: E2EVerificationProfile\n): PourkitConfig {\n const resolvedTargetName = targetName ?? \"e2e\";\n const target = resolveTarget(baseConfig, resolvedTargetName);\n const strategy = target.strategy;\n const verificationCommands = getVerificationCommands(\n getTargetVerificationCommands(target),\n profile\n );\n\n return {\n ...baseConfig,\n targets: [\n {\n ...target,\n baseBranch: targetBranch,\n strategy: {\n ...strategy,\n verify: { commands: verificationCommands },\n },\n },\n ],\n };\n}\n\nasync function cleanup(\n resources: E2EResources,\n root: string,\n runId: string,\n keep: boolean,\n logger: PourkitLogger,\n client: GitHubClient\n): Promise<void> {\n if (keep) {\n logger.line(\"--keep flag set, preserving E2E resources:\");\n if (resources.issueNumber)\n logger.line(` Issue: #${resources.issueNumber}`);\n if (resources.issueUrl) logger.line(` Issue URL: ${resources.issueUrl}`);\n if (resources.targetBranch)\n logger.line(` Target branch: ${resources.targetBranch}`);\n if (resources.agentBranch)\n logger.line(` Agent branch: ${resources.agentBranch}`);\n if (resources.prNumber)\n logger.line(` PR: #${resources.prNumber} (${resources.prUrl})`);\n return;\n }\n\n logger.line(\"Cleaning up E2E resources...\");\n let cleanupSucceeded = true;\n\n if (resources.prNumber) {\n try {\n const { data } = await client.octokit.rest.pulls.get({\n owner: client.owner,\n repo: client.repo,\n pull_number: resources.prNumber,\n });\n if (data.merged) {\n logger.step(\n \"cleanup\",\n `PR #${resources.prNumber} is merged, skipping close`\n );\n } else {\n logger.step(\"cleanup\", `Closing PR #${resources.prNumber}...`);\n await client.octokit.rest.pulls.update({\n owner: client.owner,\n repo: client.repo,\n pull_number: resources.prNumber,\n state: \"closed\",\n });\n }\n } catch (error) {\n logger.step(\n \"warn\",\n `Failed to close PR: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n\n if (resources.issueNumber) {\n try {\n logger.step(\"cleanup\", `Closing issue #${resources.issueNumber}...`);\n await client.octokit.rest.issues.update({\n owner: client.owner,\n repo: client.repo,\n issue_number: resources.issueNumber,\n state: \"closed\",\n state_reason: \"completed\",\n });\n } catch (error) {\n logger.step(\n \"warn\",\n `Failed to close issue: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n\n if (resources.agentBranch) {\n cleanupSucceeded =\n (await deleteLocalBranch(resources.agentBranch, logger)) &&\n cleanupSucceeded;\n cleanupSucceeded =\n (await deleteRemoteBranch(resources.agentBranch, logger)) &&\n cleanupSucceeded;\n }\n\n if (resources.targetBranch) {\n cleanupSucceeded =\n (await deleteLocalBranch(resources.targetBranch, logger)) &&\n cleanupSucceeded;\n cleanupSucceeded =\n (await deleteRemoteBranch(resources.targetBranch, logger)) &&\n cleanupSucceeded;\n }\n\n if (cleanupSucceeded) {\n await rm(stateFilePath(root, runId), { force: true });\n } else {\n logger.step(\"warn\", \"Preserving E2E state for retry after cleanup failure\");\n }\n\n logger.line(\"Cleanup complete.\");\n}\n\nasync function verifyAssertions(\n pr: PullRequest,\n issueNumber: number,\n targetBranch: string,\n expectedHead: string,\n expectedTitle: string,\n logger: PourkitLogger,\n client: GitHubClient\n): Promise<void> {\n logger.raw(\"\\n=== Running Assertions ===\\n\");\n\n const errors: string[] = [];\n\n if (pr.baseRefName !== targetBranch) {\n errors.push(`PR base is \"${pr.baseRefName}\", expected \"${targetBranch}\"`);\n } else {\n logger.raw(`[✓] PR base is target branch: ${targetBranch}`);\n }\n\n if (pr.headRefName !== expectedHead) {\n errors.push(`PR head is \"${pr.headRefName}\", expected \"${expectedHead}\"`);\n } else {\n logger.raw(`[✓] PR head is agent branch: ${expectedHead}`);\n }\n\n if (pr.title !== expectedTitle) {\n errors.push(`PR title is \"${pr.title}\", expected \"${expectedTitle}\"`);\n } else {\n logger.raw(`[✓] PR title matches template`);\n }\n\n if (\n pr.body !== undefined &&\n !new RegExp(`[Cc]loses\\\\s*#${issueNumber}`).test(pr.body)\n ) {\n errors.push(`PR body does not contain \"Closes #${issueNumber}\"`);\n } else {\n logger.raw(`[✓] PR body contains \"Closes #${issueNumber}\"`);\n }\n\n try {\n await execCapture(\"git\", [\"fetch\", \"origin\", pr.headRefName]);\n const countResult = await execCapture(\"git\", [\n \"rev-list\",\n \"--count\",\n `origin/${pr.headRefName}`,\n ]);\n const commitCount = Number(countResult.stdout.trim());\n if (!Number.isFinite(commitCount) || commitCount <= 0) {\n errors.push(`No commits found on the agent branch ${pr.headRefName}`);\n } else {\n logger.raw(`[✓] Commits exist on agent branch: ${commitCount} commit(s)`);\n }\n } catch (error) {\n errors.push(\n `Failed to verify commits: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n\n try {\n const labelNames = await fetchIssueLabels(issueNumber, client);\n\n if (labelNames.includes(\"pr-open-awaiting-merge\")) {\n errors.push(\n `Issue #${issueNumber} still has \"pr-open-awaiting-merge\" label after merge. Labels: ${labelNames.join(\", \")}`\n );\n } else {\n logger.raw(`[✓] Issue no longer has \"pr-open-awaiting-merge\"`);\n }\n\n if (labelNames.includes(\"ready-for-agent\")) {\n errors.push(\n `Issue #${issueNumber} still has \"ready-for-agent\" label. Labels: ${labelNames.join(\", \")}`\n );\n } else {\n logger.raw(`[✓] Issue no longer has \"ready-for-agent\"`);\n }\n\n if (labelNames.includes(\"agent-in-progress\")) {\n errors.push(\n `Issue #${issueNumber} still has \"agent-in-progress\" label. Labels: ${labelNames.join(\", \")}`\n );\n } else {\n logger.raw(`[✓] Issue no longer has \"agent-in-progress\"`);\n }\n\n if (pr.state !== \"MERGED\") {\n errors.push(`PR state is \"${pr.state}\", expected \"MERGED\"`);\n } else {\n logger.raw(`[✓] PR is merged`);\n }\n } catch (error) {\n errors.push(\n `Failed to verify issue labels: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n\n if (errors.length > 0) {\n logger.raw(\"\\n=== Assertion Failures ===\\n\");\n for (const error of errors) {\n logger.raw(`[✗] ${error}`);\n }\n throw new Error(`${errors.length} assertion(s) failed`);\n }\n\n logger.raw(\"\\n=== All Assertions Passed ===\\n\");\n}\n\nasync function verifyFailureAssertions(\n issueNumber: number,\n logger: PourkitLogger,\n client: GitHubClient\n): Promise<void> {\n logger.raw(\"\\n=== Running Failure Assertions ===\\n\");\n\n const errors: string[] = [];\n\n try {\n const labelNames = await fetchIssueLabels(issueNumber, client);\n\n if (!labelNames.includes(\"ready-for-human\")) {\n errors.push(\n `Issue #${issueNumber} does not have \"ready-for-human\" label. Labels: ${labelNames.join(\", \")}`\n );\n } else {\n logger.raw(`[✓] Issue has \"ready-for-human\" label`);\n }\n\n if (labelNames.includes(\"agent-in-progress\")) {\n errors.push(\n `Issue #${issueNumber} still has \"agent-in-progress\" label. Labels: ${labelNames.join(\", \")}`\n );\n } else {\n logger.raw(`[✓] Issue no longer has \"agent-in-progress\"`);\n }\n } catch (error) {\n errors.push(\n `Failed to verify issue labels: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n\n if (errors.length > 0) {\n logger.raw(\"\\n=== Assertion Failures ===\\n\");\n for (const error of errors) {\n logger.raw(`[✗] ${error}`);\n }\n throw new Error(`${errors.length} assertion(s) failed`);\n }\n\n logger.raw(\"\\n=== All Failure Assertions Passed ===\\n\");\n}\n\nexport function makeFailureE2EConfig(\n baseConfig: PourkitConfig,\n targetName: string | undefined,\n targetBranch: string,\n profile: E2EVerificationProfile\n): PourkitConfig {\n const resolvedTargetName = targetName ?? \"e2e\";\n const target = resolveTarget(baseConfig, resolvedTargetName);\n const strategy = target.strategy;\n const verificationCommands = composeFailureWithProfile(\n getTargetVerificationCommands(target),\n profile\n );\n\n return {\n ...baseConfig,\n targets: [\n {\n ...target,\n baseBranch: targetBranch,\n strategy: {\n ...strategy,\n verify: { commands: verificationCommands },\n },\n },\n ],\n };\n}\n\nasync function runCleanupOnly(\n root: string,\n logger: PourkitLogger\n): Promise<void> {\n logger.line(\"Running cleanup-only mode: deleting stale e2e branches...\");\n\n const result = await execCapture(\"git\", [\"ls-remote\", \"--heads\", \"origin\"]);\n const lines = result.stdout\n .split(\"\\n\")\n .filter((line) => line.trim().length > 0);\n\n const e2eBranchPattern =\n /refs\\/heads\\/(pourkit-e2e-target\\/|pourkit\\/\\d+\\/(e2e-test-issue-|test-live-e2e-))/;\n const branchesToDelete = lines\n .map((line) => {\n const parts = line.split(/\\s+/);\n return parts[1];\n })\n .filter((ref) => e2eBranchPattern.test(ref))\n .map((ref) => ref.replace(\"refs/heads/\", \"\"));\n\n let deletedCount = 0;\n let failedCount = 0;\n\n for (const branch of branchesToDelete) {\n const localOk = await deleteLocalBranch(branch, logger);\n const remoteOk = await deleteRemoteBranch(branch, logger);\n if (localOk && remoteOk) {\n deletedCount++;\n } else {\n failedCount++;\n }\n }\n\n const stateDir = path.join(root, E2E_STATE_DIR);\n try {\n const entries = await readdir(stateDir, { withFileTypes: true });\n for (const entry of entries) {\n if (!entry.isFile() || !entry.name.endsWith(\".json\")) continue;\n const filePath = path.join(stateDir, entry.name);\n await rm(filePath, { force: true });\n logger.step(\"cleanup\", `Removed state file: ${entry.name}`);\n }\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") {\n logger.step(\n \"warn\",\n `Failed to scan state directory: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n\n logger.line(\n `Cleanup-only complete: ${deletedCount} branch(es) deleted, ${failedCount} failure(s)`\n );\n}\n\nasync function runE2E(): Promise<void> {\n const options = parseArgs();\n const runId = generateRunId();\n const root = repoRoot();\n const logPath = path.join(root, \"pourkit\", \"logs\", `e2e-${runId}.log`);\n const logger = createLogger(\"e2e\", logPath);\n const client = await requireGitHubClient({ cwd: root });\n\n logger.line(`Starting E2E test run: ${runId}`);\n logger.line(`Keep resources: ${options.keep}`);\n logger.line(`Failure mode: ${options.fail}`);\n logger.line(`Verification profile: ${resolveProfile(options.fullCheck)}`);\n\n if (options.cleanupOnly) {\n await harnessRunCleanupOnly(root, logger, client);\n await logger.close();\n return;\n }\n\n await harnessRecoverStaleRuns(root, logger);\n\n if (options.fail) {\n await runFailureE2E(options, runId, root, logger);\n } else {\n await runSuccessE2E(options, runId, root, logger, client);\n }\n}\n\nasync function runSuccessE2E(\n options: E2EOptions,\n runId: string,\n root: string,\n logger: PourkitLogger,\n client: GitHubClient\n): Promise<void> {\n const issueProvider = new GitHubIssueProvider(client);\n const executionProvider = new DeterministicExecutionProvider();\n const prProvider = new GitHubPRProvider(client, logger);\n\n const resources: E2EResources = {};\n\n try {\n const targetBranch = await harnessCreateLiveTargetBranch(runId, logger);\n resources.targetBranch = targetBranch;\n if (!options.keep) {\n await harnessPersistResources(root, runId, resources);\n }\n\n const createdIssue = await harnessCreateE2EIssue(\n runId,\n targetBranch,\n logger,\n client\n );\n resources.issueNumber = createdIssue.number;\n resources.issueUrl = createdIssue.url;\n if (!options.keep) {\n await harnessPersistResources(root, runId, resources);\n }\n\n const baseConfig = await loadRepoConfig(root, resolveE2EConfigFile(root));\n const profile = resolveProfile(options.fullCheck);\n const config = makeE2EConfig(\n baseConfig,\n options.targetName,\n targetBranch,\n profile\n );\n const expectedIssue = await issueProvider.fetchIssue(createdIssue.number);\n const expectedTarget = resolveTarget(config, options.targetName);\n resources.agentBranch = renderBranchName(\n expectedTarget.branchTemplate,\n expectedIssue\n );\n if (!options.keep) {\n await harnessPersistResources(root, runId, resources);\n }\n\n logger.raw(`\\nRunning issue command for #${createdIssue.number}...\\n`);\n\n const result = await runIssueCommand({\n issueNumber: createdIssue.number,\n targetName: options.targetName,\n config,\n issueProvider,\n prProvider,\n executionProvider,\n force: false,\n logger,\n repoRoot: root,\n });\n\n resources.agentBranch = result.branchName;\n resources.prNumber = result.prNumber;\n resources.prUrl = result.prUrl;\n if (!options.keep) {\n await harnessPersistResources(root, runId, resources);\n }\n\n logger.raw(`\\nIssue command completed:`);\n logger.raw(` Issue: #${createdIssue.number}`);\n logger.raw(` Branch: ${result.branchName}`);\n logger.raw(` PR: #${result.prNumber} (${result.prUrl})`);\n\n if (!result.prNumber) {\n throw new Error(\"Issue command did not return a PR number\");\n }\n\n const pr = await execJson<PullRequest>(\"gh\", [\n \"pr\",\n \"view\",\n String(result.prNumber),\n \"--json\",\n \"number,nodeId,url,title,body,headRefName,baseRefName,state,headRefOid\",\n ]);\n\n await verifyAssertions(\n pr,\n createdIssue.number,\n targetBranch,\n result.branchName,\n result.prTitle ?? result.issue.title,\n logger,\n client\n );\n\n logger.raw(\"\\n=== Verifying Merge and Target-Green ===\\n\");\n\n if (pr.state !== \"MERGED\") {\n throw new Error(\n `PR #${result.prNumber} was not merged after issue command (state: ${pr.state})`\n );\n }\n logger.raw(`[✓] PR #${result.prNumber} is merged`);\n\n await waitForBranchChecks(prProvider, logger, {\n branchName: targetBranch,\n checksFoundTimeoutMs: config.checks.checksFoundTimeoutSeconds * 1000,\n checksCompletionTimeoutMs:\n config.checks.checksCompletionTimeoutSeconds * 1000,\n pollIntervalMs: config.checks.pollIntervalSeconds * 1000,\n });\n logger.raw(`[✓] Target branch ${targetBranch} is green after merge`);\n\n logger.raw(\"\\n=== E2E Test Passed ===\\n\");\n } catch (error) {\n logger.step(\n \"error\",\n `E2E test failed: ${error instanceof Error ? error.message : String(error)}`\n );\n throw error;\n } finally {\n await harnessCleanupResources(\n resources,\n root,\n runId,\n options.keep,\n logger,\n client\n );\n await logger.close();\n }\n}\n\nasync function runFailureE2E(\n options: E2EOptions,\n runId: string,\n root: string,\n logger: PourkitLogger\n): Promise<void> {\n const client = await requireGitHubClient({ cwd: root });\n const issueProvider = new GitHubIssueProvider(client);\n const executionProvider = new DeterministicExecutionProvider();\n const prProvider = new GitHubPRProvider(client, logger);\n\n const resources: E2EResources = {};\n\n try {\n const targetBranch = await harnessCreateLiveTargetBranch(runId, logger);\n resources.targetBranch = targetBranch;\n if (!options.keep) {\n await harnessPersistResources(root, runId, resources);\n }\n\n const createdIssue = await harnessCreateE2EIssue(\n runId,\n targetBranch,\n logger,\n client\n );\n resources.issueNumber = createdIssue.number;\n resources.issueUrl = createdIssue.url;\n if (!options.keep) {\n await harnessPersistResources(root, runId, resources);\n }\n\n const baseConfig = await loadRepoConfig(root, resolveE2EConfigFile(root));\n const profile = resolveProfile(options.fullCheck);\n const config = makeFailureE2EConfig(\n baseConfig,\n options.targetName,\n targetBranch,\n profile\n );\n const expectedIssue = await issueProvider.fetchIssue(createdIssue.number);\n const expectedTarget = resolveTarget(config, options.targetName);\n resources.agentBranch = renderBranchName(\n expectedTarget.branchTemplate,\n expectedIssue\n );\n if (!options.keep) {\n await harnessPersistResources(root, runId, resources);\n }\n\n logger.raw(\n `\\nRunning issue command for #${createdIssue.number} (failure mode)...\\n`\n );\n\n await runIssueCommand({\n issueNumber: createdIssue.number,\n targetName: options.targetName,\n config,\n issueProvider,\n prProvider,\n executionProvider,\n force: false,\n logger,\n repoRoot: root,\n });\n\n if (!options.keep) {\n await harnessPersistResources(root, runId, resources);\n }\n\n throw new Error(\"Expected runIssueCommand to throw in failure mode\");\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n if (message === \"Expected runIssueCommand to throw in failure mode\") {\n throw error;\n }\n\n logger.raw(`\\nIssue command failed as expected: ${message}`);\n\n await verifyFailureAssertions(resources.issueNumber ?? 0, logger, client);\n\n logger.raw(\"\\n=== E2E Failure Test Passed ===\\n\");\n } finally {\n await cleanup(resources, root, runId, options.keep, logger, client);\n await logger.close();\n }\n}\n\nif (isExecutedAsScript()) {\n runE2E().catch((error) => {\n const msg = `Fatal: ${error instanceof Error ? error.message : String(error)}`;\n console.error(msg);\n process.exit(1);\n });\n}\n","import { existsSync, readFileSync } from \"fs\";\nimport { isAbsolute, join } from \"path\";\nimport type {\n PourkitConfig,\n IssueData,\n ResolvedTarget,\n ResolvedPrdRunMode,\n} from \"../shared/config\";\nimport { resolvePromptTemplatePath, resolveTarget } from \"../shared/config\";\nimport { renderBranchName } from \"../pr/templates\";\nimport type { IssueProvider } from \"../providers/issue-provider\";\nimport type { PRProvider } from \"../providers/pr-provider\";\nimport type {\n ExecutionProvider,\n ExecutionResult,\n} from \"../execution/execution-provider\";\nimport {\n execCapture,\n readMaybeEnvInt,\n parseWorktreeListPorcelain,\n type PourkitLogger,\n} from \"../shared/common\";\nimport {\n buildRunContextArtifact,\n RUN_CONTEXT_PATH_IN_WORKTREE,\n STAGE_SECTIONS,\n} from \"../shared/run-context\";\nimport { appendProtectedWorkGuidance } from \"../shared/prompt-guidance\";\nimport type { SerenaExecutionContext } from \"../execution/opencode-config\";\nimport {\n readWorktreeRunState,\n writeWorktreeRunState,\n updateWorktreeRunState,\n type WorktreeRunState,\n} from \"../shared/worktree-run-state\";\nimport { invalidateAfterBaseRefresh } from \"./base-refresh\";\nimport { runBaseRefreshAttempt } from \"../failure-resolution/effect-runtime\";\nimport {\n RebaseConflict,\n PublishedHistoryRisk,\n} from \"../failure-resolution/types\";\nimport { hasUnresolvedConflictMarkers } from \"./conflict-resolution\";\nimport { Exit } from \"effect\";\nimport { runEffectAndMapExit } from \"../shared/effect-runtime\";\nimport { prepareSerenaForTarget } from \"../serena/preflight\";\nimport {\n constructFailureResolutionPacket,\n runFailureResolutionAgent,\n} from \"../failure-resolution/failure-resolution-agent\";\nimport { FinalizerFailure } from \"../failure-resolution/types\";\nimport {\n runFinalizerAgent,\n type RunFinalizerResult,\n} from \"./pr-description-agent\";\nimport {\n squashMergeLocalIssue,\n hasLocalIssueMergeReceipt,\n} from \"../prd-run/local-merge-coordinator\";\nimport { getLocalPrdBranchName } from \"../prd-run/local-branches\";\nimport { ensureClosingRefs } from \"../pr/pr-body\";\nimport {\n ensureConventionalPrTitle,\n parsePrDescription,\n} from \"../pr/pr-description\";\nimport { runMergeCoordinator } from \"../issues/merge-coordinator\";\nimport { waitForBranchChecks } from \"../issues/target-green\";\nimport {\n runReviewWithRefactorLoop,\n type ReviewLoopResult,\n type RunReviewLoopOptions,\n} from \"./review\";\nimport {\n runIssueFinalReviewAgent,\n type IssueFinalReviewResult,\n} from \"./issue-final-review-agent\";\nimport { validateAgentArtifact } from \"./artifact-validation\";\nimport {\n createIssueTransitions,\n type IssueTransitionsContract,\n} from \"../issues/issue-transitions\";\nimport { parseStackedIssue } from \"../issues/stacked-issue\";\nconst EXECUTION_TIMEOUT_MS =\n readMaybeEnvInt(process.env.POURKIT_TIMEOUT_SECONDS, 30 * 60) * 1000;\n\ntype IssueWorktreeResolution =\n | {\n mode: \"new\";\n branchName: string;\n baseRef: string;\n worktreePath?: undefined;\n }\n | {\n mode: \"existing-worktree\";\n branchName: string;\n baseRef: string;\n worktreePath: string;\n }\n | {\n mode: \"existing-branch\";\n branchName: string;\n baseRef: string;\n worktreePath: string;\n };\n\nexport interface StartIssueRunOptions {\n issueNumber: number;\n targetName?: string;\n config: PourkitConfig;\n issueProvider: IssueProvider;\n prProvider: PRProvider;\n executionProvider: ExecutionProvider;\n force: boolean;\n resetWorktree?: boolean;\n logger: PourkitLogger;\n repoRoot: string;\n baseBranchOverride?: string;\n prdRunMode?: ResolvedPrdRunMode;\n}\n\nexport interface IssueGates {\n isOpen: boolean;\n isReadyForAgent: boolean;\n isNotBlocked: boolean;\n isNotInProgress: boolean;\n}\n\nexport interface IssueGateResult {\n allowed: boolean;\n gates: IssueGates;\n reason?: string;\n}\n\nexport function checkIssueGates(\n issue: IssueData,\n config: PourkitConfig,\n force: boolean\n): IssueGateResult {\n const gates: IssueGates = {\n isOpen: issue.state === \"open\",\n isReadyForAgent: issue.labels.includes(config.labels.readyForAgent),\n isNotBlocked: !issue.labels.includes(config.labels.blocked),\n isNotInProgress: !issue.labels.includes(config.labels.agentInProgress),\n };\n\n if (force) {\n return { allowed: true, gates };\n }\n\n const failed: string[] = [];\n\n if (!gates.isOpen) {\n failed.push(`issue ${issue.number} is not open`);\n }\n\n if (!gates.isReadyForAgent) {\n failed.push(\n `issue ${issue.number} is not labeled ${config.labels.readyForAgent}`\n );\n }\n\n if (!gates.isNotBlocked) {\n failed.push(`issue ${issue.number} is labeled ${config.labels.blocked}`);\n }\n\n if (!gates.isNotInProgress) {\n failed.push(\n `issue ${issue.number} is already labeled ${config.labels.agentInProgress}`\n );\n }\n\n if (failed.length > 0) {\n return {\n allowed: false,\n gates,\n reason: failed.join(\"; \"),\n };\n }\n\n return { allowed: true, gates };\n}\n\nfunction resolveSerenaRuntimeConfig(\n config: PourkitConfig,\n target: ResolvedTarget\n) {\n return {\n enabled: target.serena?.enabled ?? config.serena.enabled,\n required: target.serena?.required ?? config.serena.required,\n autoStart: config.serena.autoStart,\n dataDir: config.serena.dataDir,\n mcpUrl: config.serena.mcpUrl,\n sandboxMcpUrl: config.serena.sandboxMcpUrl,\n };\n}\n\nexport interface IssueRunStartResult {\n issue: IssueData;\n parentPrdIssue?: IssueData;\n target: ResolvedTarget;\n effectiveTarget: ResolvedTarget;\n branchName: string;\n worktreeState: WorktreeRunState | null;\n executionResult: ExecutionResult;\n serena?: SerenaExecutionContext;\n}\n\nexport interface RunIssueResult {\n branchName: string;\n target: ResolvedTarget;\n issue: IssueData;\n prNumber?: number;\n prUrl?: string;\n prTitle?: string;\n prBody?: string;\n noOp: boolean;\n mode?: \"github\" | \"local\";\n localPrdBranch?: string;\n mergeCommit?: string;\n receiptPath?: string;\n failureCode?: string;\n repairGuidance?: string;\n}\n\nexport interface CompleteIssueRunOptions extends StartIssueRunOptions {\n startResult: IssueRunStartResult;\n reviewArtifactPath?: string;\n}\n\nexport function assertIssueFinalReviewPassed(\n worktreeState: WorktreeRunState | null\n): void {\n const ifr = worktreeState?.issueFinalReview;\n if (!ifr || !ifr.completed || ifr.verdict !== \"pass\") {\n throw new Error(\n \"Issue Final Review has not passed. Cannot proceed to finalizer, commit, or PR creation.\"\n );\n }\n}\n\nexport interface AdvanceIssueFinalReviewOptions {\n executionProvider: ExecutionProvider;\n config: PourkitConfig;\n target: ResolvedTarget;\n issue: IssueData;\n parentPrdIssue?: IssueData;\n builderBranch: string;\n worktreePath: string;\n repoRoot: string;\n logger: PourkitLogger;\n reviewArtifactPath?: string;\n worktreeState: WorktreeRunState | null;\n}\n\nexport async function advanceIssueFinalReview(\n options: AdvanceIssueFinalReviewOptions\n): Promise<IssueFinalReviewResult> {\n const {\n executionProvider,\n config,\n target,\n issue,\n parentPrdIssue,\n builderBranch,\n worktreePath,\n repoRoot,\n logger,\n reviewArtifactPath,\n worktreeState,\n } = options;\n\n const ifrFromState = worktreeState?.issueFinalReview;\n if (ifrFromState?.completed && ifrFromState.verdict === \"pass\") {\n if (!ifrFromState.artifactPath) {\n throw new Error(\n \"Issue Final Review state is incomplete: missing artifactPath\"\n );\n }\n const artifactPath = isAbsolute(ifrFromState.artifactPath)\n ? ifrFromState.artifactPath\n : join(worktreePath, ifrFromState.artifactPath);\n const validation = validateAgentArtifact({\n kind: \"issue-final-review\",\n artifactPath,\n issueNumber: issue.number,\n branchName: builderBranch,\n });\n if (!validation.ok) {\n throw new Error(\n `Issue Final Review state artifact is invalid: ${validation.reason}`\n );\n }\n return {\n verdict: \"pass\" as const,\n artifactPath,\n selfRetouched: ifrFromState.selfRetouched ?? false,\n changedPaths: ifrFromState.changedPaths ?? [],\n verificationPassed: ifrFromState.verificationPassed ?? false,\n };\n }\n\n const result = await runIssueFinalReviewAgent({\n executionProvider,\n config,\n target,\n issue,\n parentPrdIssue,\n builderBranch,\n worktreePath,\n repoRoot,\n logger,\n reviewArtifactPath,\n });\n\n if (result.verdict === \"pass\") {\n updateWorktreeRunState(worktreePath, {\n issueFinalReview: {\n completed: true,\n verdict: \"pass\",\n artifactPath: result.artifactPath,\n selfRetouched: result.selfRetouched,\n changedPaths: result.changedPaths,\n verificationPassed: result.verificationPassed,\n },\n });\n }\n\n return result;\n}\n\nexport interface FailIssueRunOptions {\n issueProvider: IssueProvider;\n issueNumber: number;\n config: PourkitConfig;\n logger: PourkitLogger;\n error: Error | string;\n}\n\nexport async function startIssueRun(\n options: StartIssueRunOptions\n): Promise<IssueRunStartResult> {\n const {\n issueNumber,\n targetName,\n config,\n issueProvider,\n prProvider,\n executionProvider,\n force,\n logger,\n } = options;\n const ROOT = options.repoRoot;\n\n const issue = await issueProvider.fetchIssue(issueNumber);\n const parentPrdIssue = await fetchParentPrdIssue(issue, issueProvider);\n\n const gateResult = checkIssueGates(issue, config, force);\n if (!gateResult.allowed) {\n throw new Error(`Issue gates failed: ${gateResult.reason}`);\n }\n\n const target = resolveTarget(config, targetName);\n const effectiveBaseBranch = options.baseBranchOverride || target.baseBranch;\n const effectiveTarget = { ...target, baseBranch: effectiveBaseBranch };\n const branchName = renderBranchName(target.branchTemplate, issue);\n const strategy = target.strategy;\n const serenaRuntimeConfig = resolveSerenaRuntimeConfig(config, target);\n const shouldPrepareSerena =\n serenaRuntimeConfig.enabled || serenaRuntimeConfig.required;\n let serenaExecutionContext: SerenaExecutionContext | undefined;\n\n if (shouldPrepareSerena) {\n const serenaPreflight = await prepareSerenaForTarget({\n repoRoot: ROOT,\n targetName: target.name,\n baseBranch: target.baseBranch,\n dataDir: serenaRuntimeConfig.dataDir,\n mcpUrl: serenaRuntimeConfig.mcpUrl,\n enabled: shouldPrepareSerena,\n required: serenaRuntimeConfig.required,\n autoStart: serenaRuntimeConfig.autoStart,\n logger,\n });\n\n if (serenaPreflight.enabled && serenaPreflight.available) {\n serenaExecutionContext = {\n available: true,\n sandboxMcpUrl: serenaRuntimeConfig.sandboxMcpUrl,\n };\n }\n\n if (serenaPreflight.enabled && !serenaPreflight.available) {\n const message = `Serena preflight unavailable for target ${target.name}: ${serenaPreflight.error}`;\n if (serenaRuntimeConfig.required) {\n throw new Error(message);\n }\n logger.step(\"warn\", message);\n }\n }\n\n if (options.resetWorktree) {\n const existingPr = await prProvider.getPr(branchName);\n if (existingPr && existingPr.state === \"OPEN\") {\n throw new Error(\n `Cannot reset worktree: open PR #${existingPr.number} exists for branch ${branchName}. Close the PR first or omit --reset-worktree.`\n );\n }\n await resetLocalBranchState(ROOT, branchName, logger);\n await syncTargetBranch(ROOT, effectiveBaseBranch, logger);\n }\n\n const prompt = loadBuilderPrompt(\n ROOT,\n strategy.implement.builder.promptTemplate\n );\n\n const resolution = await resolveIssueWorktree(\n ROOT,\n branchName,\n effectiveBaseBranch,\n logger\n );\n\n const worktreeState = resolution.worktreePath\n ? readWorktreeRunState(resolution.worktreePath)\n : null;\n\n if (resolution.mode !== \"new\") {\n const existingPr = await prProvider.getPr(branchName);\n\n const exit = await runBaseRefreshAttempt({\n worktreePath: resolution.worktreePath!,\n baseBranch: effectiveBaseBranch,\n localGitBaseRef: resolution.baseRef,\n logger,\n prNumber: existingPr?.number,\n prState: existingPr?.state,\n });\n\n if (Exit.isSuccess(exit)) {\n const refreshResult = exit.value;\n if (refreshResult.status === \"refreshed\") {\n if (worktreeState?.completedStages.builder) {\n const invalidatedState = invalidateAfterBaseRefresh(worktreeState);\n writeWorktreeRunState(resolution.worktreePath!, invalidatedState);\n }\n }\n } else {\n const cause = exit.cause;\n if (cause._tag === \"Fail\") {\n const failure = cause.error;\n if (failure instanceof RebaseConflict) {\n if (strategy.failureResolution && resolution.worktreePath) {\n await handleRebaseConflict(failure, {\n worktreePath: resolution.worktreePath,\n branchName,\n target,\n config,\n issueNumber,\n issueProvider,\n executionProvider,\n repoRoot: ROOT,\n worktreeState,\n logger,\n });\n } else {\n if (resolution.worktreePath) {\n if (worktreeState) {\n updateWorktreeRunState(resolution.worktreePath, {\n lastFailure: {\n stage: \"baseRefresh\",\n message: `Base refresh conflict detected. Handing off to human: ${failure.message}`,\n },\n });\n } else {\n writeWorktreeRunState(resolution.worktreePath, {\n issueNumber,\n targetName: target.name,\n branchName,\n baseBranch: effectiveBaseBranch,\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n completedStages: {},\n review: { lifetimeIterations: 0 },\n lastFailure: {\n stage: \"baseRefresh\",\n message: `Base refresh conflict detected. Handing off to human: ${failure.message}`,\n },\n });\n }\n }\n await transitionIssueToFailureState(\n issueProvider,\n issueNumber,\n config,\n `Base refresh conflicted: ${failure.message}. Worktree preserved at ${resolution.worktreePath}.`,\n logger\n );\n throw new Error(`Base refresh conflicted: ${failure.message}`);\n }\n } else if (failure instanceof PublishedHistoryRisk) {\n await handlePublishedHistoryRisk(failure, {\n worktreePath: resolution.worktreePath!,\n branchName,\n target,\n config,\n issueNumber,\n issueProvider,\n worktreeState,\n logger,\n });\n } else {\n throw new Error(`Base refresh failed: ${failure.message}`);\n }\n } else {\n const defectMessage =\n cause._tag === \"Die\"\n ? `Base refresh failed with unexpected error: ${cause.defect}`\n : `Base refresh failed with unhandled cause: ${cause._tag}`;\n throw new Error(defectMessage);\n }\n }\n }\n\n const runContextArtifact = buildRunContextArtifact({\n issue,\n parentPrdIssue,\n target: effectiveTarget,\n branchName,\n repoRoot: ROOT,\n reviewerCriteria: strategy.review.reviewer.criteria,\n sections: STAGE_SECTIONS.builder,\n });\n\n await issueProvider.addLabels(issueNumber, [config.labels.agentInProgress]);\n await issueProvider.removeLabel(issueNumber, config.labels.readyForAgent);\n\n let executionResult: ExecutionResult;\n\n const shouldRunBuilder =\n resolution.mode === \"new\"\n ? true\n : worktreeState === null || !worktreeState.completedStages.builder;\n\n if (shouldRunBuilder) {\n executionResult = await executionProvider.execute({\n stage: \"builder\",\n agent: strategy.implement.builder.agent,\n model: strategy.implement.builder.model,\n variant: strategy.implement.builder.variant,\n env: strategy.implement.builder.env,\n prompt,\n target: effectiveTarget,\n repoRoot: ROOT,\n branchName,\n ...(resolution.mode === \"new\" ? { baseRef: resolution.baseRef } : {}),\n sandbox: config.sandbox,\n ...(serenaExecutionContext ? { serena: serenaExecutionContext } : {}),\n autoApprove: true,\n timeoutMs: EXECUTION_TIMEOUT_MS,\n ...(resolution.worktreePath\n ? { worktreePath: resolution.worktreePath }\n : {}),\n artifacts: [runContextArtifact],\n logger,\n });\n\n if (!executionResult.success) {\n throw new Error(`Sandcastle failed: ${executionResult.error}`);\n }\n } else {\n executionResult = {\n success: true,\n branch: branchName,\n worktreePath: resolution.worktreePath!,\n commits: [],\n logPath: null,\n };\n }\n\n if (executionResult.worktreePath) {\n if (worktreeState) {\n updateWorktreeRunState(executionResult.worktreePath, {\n completedStages: { builder: true },\n });\n } else {\n writeWorktreeRunState(executionResult.worktreePath, {\n issueNumber,\n targetName: target.name,\n branchName,\n baseBranch: effectiveBaseBranch,\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n completedStages: { builder: true },\n review: { lifetimeIterations: 0 },\n });\n }\n }\n\n const finalWorktreeState = executionResult.worktreePath\n ? readWorktreeRunState(executionResult.worktreePath)\n : worktreeState;\n\n return {\n issue,\n parentPrdIssue,\n target,\n effectiveTarget,\n branchName,\n worktreeState: finalWorktreeState,\n executionResult,\n ...(serenaExecutionContext ? { serena: serenaExecutionContext } : {}),\n };\n}\n\nasync function fetchParentPrdIssue(\n issue: IssueData,\n issueProvider: IssueProvider\n): Promise<IssueData | undefined> {\n const parentSection = issue.body.match(\n /^## Parent\\s*\\n([\\s\\S]*?)(?=\\n## |$)/im\n )?.[1];\n const parentNumber = parentSection?.match(/#(\\d+)\\b/)?.[1];\n if (!parentNumber) return undefined;\n\n try {\n return await issueProvider.fetchIssue(Number(parentNumber));\n } catch {\n return undefined;\n }\n}\n\nexport async function advanceIssueRunReview(\n options: RunReviewLoopOptions\n): Promise<ReviewLoopResult> {\n const accumulatedRefactorPaths: string[] = [];\n\n const reviewResult = await runEffectAndMapExit(\n runReviewWithRefactorLoop({\n ...options,\n onRefactorProgress: (progress) => {\n if (progress.refactorArtifactPath) {\n accumulatedRefactorPaths.push(progress.refactorArtifactPath);\n }\n updateWorktreeRunState(options.worktreePath, {\n review: {\n lifetimeIterations: progress.lifetimeIterations,\n lastVerdict: progress.lastVerdict,\n lastArtifactPath: progress.lastArtifactPath,\n refactorCompletedForLastReview: true,\n },\n });\n },\n })\n );\n\n updateWorktreeRunState(options.worktreePath, {\n review: {\n lifetimeIterations: reviewResult.lifetimeIterations,\n lastVerdict: reviewResult.verdict,\n lastArtifactPath: reviewResult.artifactPath,\n refactorCompletedForLastReview:\n reviewResult.refactorCompletedForLastReview,\n exhaustedPreviousRun:\n reviewResult.exhaustedMaxIterations ||\n reviewResult.verdict === \"FAIL\" ||\n undefined,\n refactorArtifactPaths:\n accumulatedRefactorPaths.length > 0\n ? accumulatedRefactorPaths\n : undefined,\n },\n });\n\n return reviewResult;\n}\n\nexport async function completeIssueRun(\n options: CompleteIssueRunOptions\n): Promise<RunIssueResult> {\n const {\n issueNumber,\n config,\n issueProvider,\n prProvider,\n executionProvider,\n logger,\n startResult,\n reviewArtifactPath,\n } = options;\n const ROOT = options.repoRoot;\n const { issue, target, branchName, worktreeState, executionResult } =\n startResult;\n const effectiveBaseBranch = options.baseBranchOverride || target.baseBranch;\n const checkWaitOptions = {\n checksFoundTimeoutMs: config.checks.checksFoundTimeoutSeconds * 1000,\n checksCompletionTimeoutMs:\n config.checks.checksCompletionTimeoutSeconds * 1000,\n pollIntervalMs: config.checks.pollIntervalSeconds * 1000,\n };\n\n const ifrState = executionResult.worktreePath\n ? (readWorktreeRunState(executionResult.worktreePath) ?? worktreeState)\n : worktreeState;\n assertIssueFinalReviewPassed(ifrState);\n\n let mergeCompleted = false;\n\n try {\n if (\n executionResult.worktreePath &&\n !worktreeState?.finalCommit?.completed &&\n !worktreeState?.pr?.created &&\n !(await hasWorktreeChanges(\n executionResult.worktreePath,\n `origin/${effectiveBaseBranch}`,\n logger\n ))\n ) {\n logger.step(\n \"info\",\n \"No worktree changes detected after review - closing issue\"\n );\n await closeNoOpIssue(issueProvider, issueNumber, config, logger);\n return {\n branchName,\n target,\n issue,\n noOp: true,\n };\n }\n\n let prTitle = issue.title;\n let prBody: string | undefined;\n let finalizerResult: RunFinalizerResult | undefined;\n\n const isLocalModeForFinalizer = options.prdRunMode?.mode === \"local\";\n\n const finalizerFromState = worktreeState?.finalizer?.completed\n ? worktreeState.finalizer\n : null;\n if (finalizerFromState) {\n try {\n if (finalizerFromState.title && finalizerFromState.body) {\n prTitle = finalizerFromState.title;\n prBody = finalizerFromState.body;\n } else if (finalizerFromState.artifactPath) {\n if (!existsSync(finalizerFromState.artifactPath)) {\n throw new FinalizerFailure({\n message: `Finalizer artifact missing at ${finalizerFromState.artifactPath}`,\n });\n }\n const artifactContent = readFileSync(\n finalizerFromState.artifactPath,\n \"utf-8\"\n );\n const parsed = parsePrDescription(artifactContent);\n prTitle = parsed.title;\n prBody = parsed.body;\n } else {\n throw new FinalizerFailure({\n message:\n \"Finalizer state is incomplete: missing title, body, and artifactPath\",\n });\n }\n } catch (error) {\n if (isLocalModeForFinalizer) {\n return {\n branchName,\n target,\n issue,\n noOp: false,\n mode: \"local\",\n failureCode: \"finalizer_failed\",\n repairGuidance:\n error instanceof Error\n ? error.message\n : \"Finalizer state is invalid\",\n };\n }\n throw error;\n }\n } else {\n try {\n finalizerResult = await runEffectAndMapExit(\n runFinalizerAgent({\n executionProvider,\n config,\n target,\n issue,\n builderBranch: branchName,\n targetBaseBranch: effectiveBaseBranch,\n worktreePath: executionResult.worktreePath,\n reviewArtifactPath,\n repoRoot: ROOT,\n logger,\n })\n );\n } catch (error) {\n if (isLocalModeForFinalizer) {\n return {\n branchName,\n target,\n issue,\n noOp: false,\n mode: \"local\",\n failureCode: \"finalizer_failed\",\n repairGuidance:\n error instanceof Error\n ? error.message\n : \"Finalizer execution failed\",\n };\n }\n throw error;\n }\n prTitle = finalizerResult.title;\n prBody = finalizerResult.body;\n }\n\n prTitle = ensureConventionalPrTitle(\n prTitle,\n executionResult.commits.join(\"\\n\")\n );\n\n const finalBody = ensureClosingRefs(\n prBody ?? `Closes #${issue.number}`,\n issue.number\n );\n\n if (!finalizerFromState && executionResult.worktreePath) {\n updateWorktreeRunState(executionResult.worktreePath, {\n finalizer: {\n completed: true,\n artifactPath: finalizerResult!.artifactPath,\n title: prTitle,\n body: prBody,\n },\n });\n }\n\n const finalCommitFromState = worktreeState?.finalCommit?.completed;\n if (!finalCommitFromState) {\n await finalizeWorktreeCommit({\n worktreePath: executionResult.worktreePath,\n baseRef: `origin/${effectiveBaseBranch}`,\n title: prTitle,\n body: finalBody,\n logger,\n });\n\n if (executionResult.worktreePath) {\n const revParse = await execCapture(\"git\", [\"rev-parse\", \"HEAD\"], {\n cwd: executionResult.worktreePath,\n logger,\n label: \"git rev-parse HEAD\",\n });\n updateWorktreeRunState(executionResult.worktreePath, {\n finalCommit: {\n completed: true,\n sha: revParse.stdout.trim(),\n },\n });\n }\n }\n\n const isLocalMode = options.prdRunMode?.mode === \"local\";\n\n if (isLocalMode) {\n const parsed = parseStackedIssue(issue.title, issue.body);\n const prdId = parsed.parentRef;\n if (!prdId) {\n return {\n branchName,\n target,\n issue,\n noOp: false,\n mode: \"local\",\n failureCode: \"finalizer_failed\",\n repairGuidance:\n \"Local mode requires a PRD reference (## Parent) in the issue body or title. Add the parent PRD reference and retry.\",\n };\n }\n\n const finalizerFromWorktreeState = worktreeState?.finalizer;\n if (finalizerFromWorktreeState && !finalizerFromWorktreeState.completed) {\n return {\n branchName,\n target,\n issue,\n noOp: false,\n mode: \"local\",\n failureCode: \"finalizer_failed\",\n repairGuidance:\n \"Finalizer did not complete on previous run. Re-run the issue finalizer and try again.\",\n };\n }\n\n if (!prTitle || !finalBody) {\n return {\n branchName,\n target,\n issue,\n noOp: false,\n mode: \"local\",\n failureCode: \"finalizer_failed\",\n repairGuidance:\n \"Finalizer produced empty title or body. Re-run the issue finalizer and try again.\",\n };\n }\n\n const existingReceipt = await hasLocalIssueMergeReceipt(\n prdId,\n `issue-${issueNumber}`,\n ROOT\n );\n if (existingReceipt) {\n return {\n branchName,\n target,\n issue,\n noOp: false,\n mode: \"local\",\n failureCode: \"already_merged\",\n localPrdBranch: existingReceipt.localPrdBranch,\n mergeCommit: existingReceipt.mergeCommit,\n receiptPath: join(\n ROOT,\n \".pourkit\",\n \"local-prd-runs\",\n prdId,\n \"merge-receipts\",\n `issue-${issueNumber}.json`\n ),\n };\n }\n\n const mergeResult = await squashMergeLocalIssue(\n prdId,\n `issue-${issueNumber}`,\n {\n finalizerTitle: prTitle,\n finalizerBody: finalBody,\n finalizerArtifactPath: worktreeState?.finalizer?.artifactPath ?? \"\",\n sourceBranch: branchName,\n },\n ROOT\n );\n\n if (!mergeResult.ok) {\n return {\n branchName,\n target,\n issue,\n noOp: false,\n mode: \"local\",\n failureCode: mergeResult.failureCode,\n repairGuidance:\n mergeResult.repairGuidance ??\n `Local squash-merge failed: ${mergeResult.failureCode}`,\n };\n }\n\n await issueProvider.removeLabel(\n issueNumber,\n config.labels.agentInProgress\n );\n await issueProvider.removeLabel(\n issueNumber,\n config.labels.prOpenAwaitingMerge\n );\n\n let childCloseSucceeded = false;\n try {\n await issueProvider.closeIssue(issueNumber);\n childCloseSucceeded = true;\n } catch (error) {\n logger.step(\n \"warn\",\n `Issue #${issueNumber} could not be closed: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n\n if (childCloseSucceeded) {\n await maybeCloseParentAfterChildCompletion(\n issueProvider,\n issueNumber,\n logger\n );\n }\n\n return {\n branchName,\n target,\n issue,\n noOp: false,\n mode: \"local\",\n localPrdBranch: getLocalPrdBranchName(prdId),\n mergeCommit: mergeResult.receipt!.mergeCommit,\n receiptPath: join(\n ROOT,\n \".pourkit\",\n \"local-prd-runs\",\n prdId,\n \"merge-receipts\",\n `issue-${issueNumber}.json`\n ),\n };\n }\n\n let pr: Awaited<ReturnType<PRProvider[\"createPr\"]>>;\n\n if (worktreeState?.pr?.merged) {\n mergeCompleted = true;\n pr = {\n number: worktreeState.pr.number!,\n nodeId: \"\",\n url: worktreeState.pr.url!,\n title: prTitle,\n body: finalBody,\n headRefName: branchName,\n baseRefName: effectiveBaseBranch,\n state: \"MERGED\",\n headRefOid: worktreeState.finalCommit?.sha ?? \"\",\n };\n } else {\n const prFromState =\n worktreeState?.pr?.created || finalCommitFromState\n ? await prProvider.getPr(branchName)\n : null;\n\n if (prFromState && prFromState.state === \"OPEN\") {\n pr = prFromState;\n } else {\n await execCapture(\"git\", [\"push\", \"-u\", \"origin\", branchName], {\n cwd: executionResult.worktreePath,\n logger,\n label: \"git push\",\n });\n\n pr = await prProvider.createPr({\n title: prTitle,\n body: finalBody,\n head: branchName,\n base: effectiveBaseBranch,\n });\n\n if (executionResult.worktreePath) {\n updateWorktreeRunState(executionResult.worktreePath, {\n pr: {\n created: true,\n number: pr.number,\n url: pr.url,\n },\n });\n }\n }\n\n if (target.autoMerge === false) {\n await prProvider.waitForPrChecks(pr.number, checkWaitOptions);\n const transitions = makeIssueTransitions(issueProvider, config);\n await transitions.moveToReadyForHuman(issueNumber);\n return {\n branchName,\n target,\n issue,\n prNumber: pr.number,\n prUrl: pr.url,\n prTitle,\n prBody: finalBody,\n noOp: false,\n };\n }\n\n await issueProvider.addLabels(issueNumber, [\n config.labels.prOpenAwaitingMerge,\n ]);\n const coordinatorResult = await runEffectAndMapExit(\n runMergeCoordinator({\n prProvider,\n logger,\n prNumber: pr.number,\n targetBranch: effectiveBaseBranch,\n matchHeadCommit: pr.headRefOid,\n checkWaitOptions,\n autoMerge: true,\n pr,\n })\n );\n\n if (coordinatorResult.stage === \"merge\") {\n throw coordinatorResult.error;\n }\n\n if (coordinatorResult.stage === \"target-green\") {\n try {\n await issueProvider.removeLabel(\n issueNumber,\n config.labels.prOpenAwaitingMerge\n );\n } catch (labelError) {\n logger.step(\n \"warn\",\n `Failed to remove ${config.labels.prOpenAwaitingMerge} label (cleanup): ${labelError instanceof Error ? labelError.message : String(labelError)}`\n );\n }\n throw coordinatorResult.error;\n }\n\n mergeCompleted = true;\n\n if (executionResult.worktreePath) {\n updateWorktreeRunState(executionResult.worktreePath, {\n pr: { merged: true, created: true },\n });\n }\n }\n\n if (worktreeState?.pr?.merged) {\n await waitForBranchChecks(prProvider, logger, {\n branchName: effectiveBaseBranch,\n checksFoundTimeoutMs: checkWaitOptions.checksFoundTimeoutMs,\n checksCompletionTimeoutMs: checkWaitOptions.checksCompletionTimeoutMs,\n pollIntervalMs: checkWaitOptions.pollIntervalMs,\n });\n }\n\n await issueProvider.removeLabel(issueNumber, config.labels.agentInProgress);\n await issueProvider.removeLabel(\n issueNumber,\n config.labels.prOpenAwaitingMerge\n );\n\n let childCloseSucceeded = false;\n try {\n await issueProvider.closeIssue(issueNumber);\n childCloseSucceeded = true;\n } catch (error) {\n logger.step(\n \"warn\",\n `Issue #${issueNumber} could not be closed: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n\n if (childCloseSucceeded) {\n await maybeCloseParentAfterChildCompletion(\n issueProvider,\n issueNumber,\n logger\n );\n }\n\n return {\n branchName,\n target,\n issue,\n prNumber: pr.number,\n prUrl: pr.url,\n prTitle,\n prBody: finalBody,\n noOp: false,\n };\n } catch (error) {\n if (mergeCompleted) {\n try {\n await issueProvider.removeLabel(\n issueNumber,\n config.labels.prOpenAwaitingMerge\n );\n } catch {\n // Ignore cleanup errors when removing label after merge\n }\n }\n throw error;\n }\n}\n\nexport async function failIssueRun(\n options: FailIssueRunOptions\n): Promise<void> {\n const { issueProvider, issueNumber, config, logger, error } = options;\n await transitionIssueToFailureState(\n issueProvider,\n issueNumber,\n config,\n typeof error === \"string\" ? error : error.message,\n logger\n );\n}\n\nexport interface HumanHandoffOptions {\n issueProvider: IssueProvider;\n issueNumber: number;\n config: PourkitConfig;\n logger: PourkitLogger;\n reviewResult: ReviewLoopResult;\n}\n\nexport async function transitionIssueToHumanHandoff(\n options: HumanHandoffOptions\n): Promise<void> {\n const { issueProvider, issueNumber, config, logger, reviewResult } = options;\n\n const transitions = makeIssueTransitions(issueProvider, config);\n await transitions.moveToReadyForHuman(issueNumber);\n\n const summary = extractHumanHandoffSummary(reviewResult.output);\n const refactorDir = getRefactorArtifactDir(reviewResult.artifactPath);\n\n const comment = [\n \"Pourkit stopped the review/refactor loop because human input is needed.\",\n \"\",\n summary,\n \"\",\n \"Artifacts:\",\n `- Review: ${reviewResult.artifactPath}`,\n `- Refactors: ${refactorDir}`,\n ].join(\"\\n\");\n\n await issueProvider.commentIssue(issueNumber, comment);\n\n logger.step(\"info\", `Issue ${issueNumber} transitioned to human handoff`);\n}\n\nfunction extractHumanHandoffSummary(artifactContent: string): string {\n const lines = artifactContent.split(\"\\n\");\n let inSummary = false;\n const summaryLines: string[] = [];\n for (const line of lines) {\n if (line.startsWith(\"## Human Handoff Summary\")) {\n inSummary = true;\n continue;\n }\n if (inSummary) {\n if (line.startsWith(\"## \")) {\n break;\n }\n summaryLines.push(line);\n }\n }\n return (\n summaryLines.join(\"\\n\").trim() || \"(No Human Handoff Summary provided)\"\n );\n}\n\nfunction getRefactorArtifactDir(artifactPath: string): string {\n return artifactPath\n .replace(/\\/reviewers\\//, \"/refactors/\")\n .replace(/\\/[^/]+$/, \"\");\n}\n\nasync function finalizeWorktreeCommit(options: {\n worktreePath: string;\n baseRef: string;\n title: string;\n body: string;\n logger: PourkitLogger;\n}) {\n const { worktreePath, baseRef, title, body, logger } = options;\n\n await syncRemoteBaseRef(worktreePath, baseRef, logger);\n\n try {\n await execCapture(\"git\", [\"merge-base\", \"--is-ancestor\", baseRef, \"HEAD\"], {\n cwd: worktreePath,\n logger,\n label: \"git merge-base --is-ancestor\",\n });\n } catch {\n throw new Error(\n `Cannot finalize stale worktree: ${baseRef} is not an ancestor of HEAD. Refresh the branch onto the latest target base before creating the final commit.`\n );\n }\n\n await execCapture(\"git\", [\"reset\", \"--soft\", baseRef], {\n cwd: worktreePath,\n logger,\n label: \"git reset\",\n });\n\n await execCapture(\"git\", [\"add\", \"-A\"], {\n cwd: worktreePath,\n logger,\n label: \"git add\",\n });\n\n await execCapture(\"git\", [\"commit\", \"--no-verify\", \"-m\", title, \"-m\", body], {\n cwd: worktreePath,\n logger,\n label: \"git commit\",\n });\n}\n\nasync function guardFinalCommitContent(options: {\n worktreePath: string;\n title: string;\n body: string;\n enabled: boolean;\n logger: PourkitLogger;\n}) {\n const { worktreePath, title, body, enabled, logger } = options;\n if (!enabled) {\n return;\n }\n\n const stagedDiff = await execCapture(\"git\", [\"diff\", \"--cached\"], {\n cwd: worktreePath,\n logger,\n label: \"git diff --cached secret guard\",\n });\n\n assertNoSecretLikeContent([\n {\n source: \"staged diff\",\n content: extractAddedDiffContent(stagedDiff.stdout),\n },\n { source: \"commit title\", content: title },\n { source: \"commit body\", content: body },\n ]);\n}\n\nasync function guardFinalPublishContent(options: {\n worktreePath: string;\n baseRef: string;\n title: string;\n body: string;\n secretLikeContentDetectionEnabled: boolean;\n logger: PourkitLogger;\n}) {\n const {\n worktreePath,\n baseRef,\n title,\n body,\n secretLikeContentDetectionEnabled,\n logger,\n } = options;\n if (!secretLikeContentDetectionEnabled) {\n return;\n }\n\n const finalDiff = await execCapture(\"git\", [\"diff\", `${baseRef}...HEAD`], {\n cwd: worktreePath,\n logger,\n label: \"git diff final secret guard\",\n });\n\n assertNoSecretLikeContent([\n {\n source: \"final diff\",\n content: extractAddedDiffContent(finalDiff.stdout),\n },\n { source: \"PR title\", content: title },\n { source: \"PR body\", content: body },\n ]);\n}\n\nfunction extractAddedDiffContent(diff: string) {\n return diff\n .split(/\\r?\\n/)\n .filter((line) => line.startsWith(\"+\") && !line.startsWith(\"+++\"))\n .map((line) => line.slice(1))\n .join(\"\\n\");\n}\n\nfunction assertNoSecretLikeContent(\n inputs: Array<{ source: string; content: string | undefined }>\n) {\n const findings = inputs.flatMap(({ source, content }) =>\n findSecretLikeContent(source, content ?? \"\")\n );\n\n if (findings.length === 0) {\n return;\n }\n\n const summary = findings\n .slice(0, 5)\n .map((finding) => `${finding.source}: ${finding.kind}`)\n .join(\"; \");\n throw new Error(\n `Secret-like content detected before finalization (${summary}). Redact it before committing, pushing, or creating a PR.`\n );\n}\n\nfunction findSecretLikeContent(source: string, content: string) {\n const findings: Array<{ source: string; kind: string }> = [];\n const patterns: Array<{ kind: string; regex: RegExp }> = [\n {\n kind: \"private key block\",\n regex: /-----BEGIN [A-Z0-9 ]*PRIVATE KEY-----/gi,\n },\n {\n kind: \"GitHub token\",\n regex: /\\b(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9_]{20,}\\b/g,\n },\n {\n kind: \"GitHub fine-grained token\",\n regex: /\\bgithub_pat_[A-Za-z0-9_]{20,}\\b/g,\n },\n { kind: \"npm token\", regex: /\\bnpm_[A-Za-z0-9]{20,}\\b/g },\n { kind: \"OpenAI key\", regex: /\\bsk-(?:proj-)?[A-Za-z0-9_-]{20,}\\b/g },\n { kind: \"AWS access key\", regex: /\\b(?:AKIA|ASIA)[A-Z0-9]{16}\\b/g },\n {\n kind: \"authorization bearer token\",\n regex: /\\bAuthorization\\s*:\\s*Bearer\\s+[^\\s`'\\\"]{12,}/gi,\n },\n {\n kind: \"secret assignment\",\n regex:\n /\\b[A-Z0-9_]*(?:API[_-]?KEY|TOKEN|SECRET|PASSWORD|PASSWD|PRIVATE[_-]?KEY|CLIENT[_-]?SECRET|DATABASE[_-]?URL)[A-Z0-9_]*\\s*[:=]\\s*[\"']?[^\\s\"'`]{8,}/gi,\n },\n ];\n\n for (const { kind, regex } of patterns) {\n for (const match of content.matchAll(regex)) {\n if (isAllowedSecretPlaceholder(match[0])) {\n continue;\n }\n findings.push({ source, kind });\n break;\n }\n }\n\n return findings;\n}\n\nfunction isAllowedSecretPlaceholder(value: string) {\n const normalized = value.toLowerCase();\n return [\n \"<redacted>\",\n \"<example\",\n \"example-\",\n \"dummy-\",\n \"test-\",\n \"placeholder\",\n \"xxxxx\",\n ].some((allowed) => normalized.includes(allowed));\n}\n\nasync function syncRemoteBaseRef(\n worktreePath: string,\n baseRef: string,\n logger: PourkitLogger\n) {\n const remoteBase = parseRemoteBaseRef(baseRef);\n if (!remoteBase) {\n return;\n }\n\n await execCapture(\"git\", [\"fetch\", remoteBase.remote, remoteBase.branch], {\n cwd: worktreePath,\n logger,\n label: \"git fetch target\",\n });\n}\n\nfunction parseRemoteBaseRef(baseRef: string): {\n remote: string;\n branch: string;\n} | null {\n const [remote, ...branchParts] = baseRef.split(\"/\");\n const branch = branchParts.join(\"/\");\n if (!remote || !branch) {\n return null;\n }\n return { remote, branch };\n}\n\nfunction makeIssueTransitions(\n provider: IssueProvider,\n config: PourkitConfig\n): IssueTransitionsContract {\n return createIssueTransitions(\n {\n fetchIssue: provider.fetchIssue.bind(provider),\n addLabels: provider.addLabels.bind(provider),\n removeLabel: provider.removeLabel.bind(provider),\n closeIssue: provider.closeIssue.bind(provider),\n },\n {\n blocked: config.labels.blocked,\n readyForAgent: config.labels.readyForAgent,\n needsTriage: config.labels.needsTriage,\n agentInProgress: config.labels.agentInProgress,\n readyForHuman: config.labels.readyForHuman,\n prOpenAwaitingMerge: config.labels.prOpenAwaitingMerge,\n }\n );\n}\n\nasync function transitionIssueToFailureState(\n provider: IssueProvider,\n issueNumber: number,\n config: PourkitConfig,\n errorMessage: string,\n logger: PourkitLogger\n) {\n const transitions = makeIssueTransitions(provider, config);\n await transitions.moveToReadyForHuman(issueNumber);\n\n logger.step(\n \"error\",\n `Issue ${issueNumber} transitioned to ${config.labels.readyForHuman}: ${errorMessage}`\n );\n}\n\nasync function hasWorktreeChanges(\n worktreePath: string,\n baseRef: string,\n logger: PourkitLogger\n): Promise<boolean> {\n const diffResult = await execCapture(\n \"git\",\n [\"diff\", \"--name-only\", baseRef, \"--\"],\n {\n cwd: worktreePath,\n logger,\n label: \"git diff --name-only\",\n }\n );\n if (diffResult.stdout.trim().length > 0) {\n return true;\n }\n\n const statusResult = await execCapture(\n \"git\",\n [\"status\", \"--porcelain\", \"--untracked-files=all\"],\n {\n cwd: worktreePath,\n logger,\n label: \"git status --porcelain\",\n }\n );\n return statusResult.stdout.trim().length > 0;\n}\n\nasync function closeNoOpIssue(\n provider: IssueProvider,\n issueNumber: number,\n config: PourkitConfig,\n logger: PourkitLogger\n): Promise<void> {\n const transitions = makeIssueTransitions(provider, config);\n\n let closeSucceeded = false;\n try {\n await transitions.closeCompleted(issueNumber);\n closeSucceeded = true;\n logger.step(\"info\", `Issue #${issueNumber} closed (no changes required)`);\n } catch (error) {\n logger.step(\n \"warn\",\n `Issue #${issueNumber} could not be closed: ${error instanceof Error ? error.message : String(error)}`\n );\n logger.step(\n \"info\",\n `Issue #${issueNumber} completed with no changes required`\n );\n }\n\n if (closeSucceeded) {\n await maybeCloseParentAfterChildCompletion(provider, issueNumber, logger);\n }\n}\n\nasync function maybeCloseParentAfterChildCompletion(\n provider: IssueProvider,\n issueNumber: number,\n logger: PourkitLogger\n): Promise<void> {\n try {\n const issue = await provider.fetchIssue(issueNumber);\n const parsed = parseStackedIssue(issue.title, issue.body);\n if (!parsed.parentRef) return;\n if (parsed.warnings.length > 0) return;\n\n const parent = await provider.resolveIssueByCanonicalRef(parsed.parentRef);\n if (!parent) return;\n if (parent.state !== \"open\") return;\n\n const siblings = await provider.listRelatedIssues(parsed.parentRef);\n const openSiblings = siblings.filter(\n (s) => s.number !== issueNumber && s.state === \"open\"\n );\n if (openSiblings.length > 0) return;\n\n await provider.closeIssue(parent.number);\n logger.step(\n \"info\",\n `Parent PRD #${parent.number} closed (last child completed)`\n );\n } catch (error) {\n logger.step(\n \"warn\",\n `Parent completion check failed: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n}\n\nasync function resetLocalBranchState(\n root: string,\n branchName: string,\n logger: PourkitLogger\n): Promise<void> {\n const worktreeList = await execCapture(\n \"git\",\n [\"worktree\", \"list\", \"--porcelain\"],\n { cwd: root, logger, label: \"git worktree list\" }\n );\n\n const existingWorktreePath = resolveRegisteredIssueWorktreePath(\n worktreeList.stdout,\n root,\n branchName\n );\n\n if (existingWorktreePath) {\n logger.step(\"git\", `removing existing worktree: ${existingWorktreePath}`);\n await execCapture(\n \"git\",\n [\"worktree\", \"remove\", \"--force\", existingWorktreePath],\n {\n cwd: root,\n logger,\n label: \"git worktree remove\",\n }\n );\n }\n\n let branchExists = false;\n try {\n await execCapture(\n \"git\",\n [\"show-ref\", \"--verify\", \"--quiet\", `refs/heads/${branchName}`],\n { cwd: root, logger, label: \"git branch exists\" }\n );\n branchExists = true;\n } catch {\n // No local branch to delete.\n }\n\n if (branchExists) {\n logger.step(\"git\", `deleting local branch: ${branchName}`);\n await execCapture(\"git\", [\"branch\", \"-D\", branchName], {\n cwd: root,\n logger,\n label: \"git branch -D\",\n });\n }\n}\n\nasync function resolveIssueWorktree(\n root: string,\n branchName: string,\n baseBranch: string,\n logger: PourkitLogger\n): Promise<IssueWorktreeResolution> {\n const worktreeList = await execCapture(\n \"git\",\n [\"worktree\", \"list\", \"--porcelain\"],\n {\n cwd: root,\n logger,\n label: \"git worktree list\",\n }\n );\n\n const existingWorktreePath = resolveRegisteredIssueWorktreePath(\n worktreeList.stdout,\n root,\n branchName\n );\n\n if (existingWorktreePath) {\n const baseRef = await syncTargetBranch(root, baseBranch, logger);\n return {\n mode: \"existing-worktree\",\n branchName,\n baseRef,\n worktreePath: existingWorktreePath,\n };\n }\n\n let branchExists = false;\n try {\n await execCapture(\n \"git\",\n [\"show-ref\", \"--verify\", \"--quiet\", `refs/heads/${branchName}`],\n {\n cwd: root,\n logger,\n label: \"git branch exists\",\n }\n );\n branchExists = true;\n } catch {\n // No local branch to resume from.\n }\n\n if (branchExists) {\n const worktreePath = issueWorktreePath(root, branchName);\n await execCapture(\"git\", [\"worktree\", \"add\", worktreePath, branchName], {\n cwd: root,\n logger,\n label: \"git worktree add\",\n });\n const baseRef = await syncTargetBranch(root, baseBranch, logger);\n return {\n mode: \"existing-branch\",\n branchName,\n baseRef,\n worktreePath,\n };\n }\n\n const baseRef = await syncTargetBranch(root, baseBranch, logger);\n return { mode: \"new\", branchName, baseRef };\n}\n\nfunction issueWorktreePath(root: string, branchName: string): string {\n return join(root, \".sandcastle\", \"worktrees\", branchName.replace(/\\//g, \"-\"));\n}\n\nfunction resolveRegisteredIssueWorktreePath(\n worktreeListPorcelain: string,\n root: string,\n branchName: string\n): string | null {\n const branchWorktreePath = parseWorktreeListPorcelain(\n worktreeListPorcelain,\n branchName\n );\n if (branchWorktreePath) return branchWorktreePath;\n\n const expectedWorktreePath = issueWorktreePath(root, branchName);\n const entries = worktreeListPorcelain.trim().split(\"\\n\\n\");\n for (const entry of entries) {\n if (\n entry\n .trim()\n .split(\"\\n\")\n .some((line) => line === `worktree ${expectedWorktreePath}`)\n ) {\n return expectedWorktreePath;\n }\n }\n\n return null;\n}\n\nasync function syncTargetBranch(\n root: string,\n baseBranch: string,\n logger: PourkitLogger\n): Promise<string> {\n logger.step(\"git\", `syncing target branch: ${baseBranch}`);\n await execCapture(\"git\", [\"fetch\", \"origin\", baseBranch], {\n cwd: root,\n logger,\n label: \"git fetch target\",\n });\n return `origin/${baseBranch}`;\n}\n\nfunction loadBuilderPrompt(repoRoot: string, promptTemplate: string): string {\n const promptPath = resolvePromptTemplatePath(repoRoot, promptTemplate);\n const promptBody = existsSync(promptPath)\n ? readFileSync(promptPath, \"utf-8\")\n : promptTemplate;\n\n return appendProtectedWorkGuidance(`${promptBody}\n\n## Shared Run Context\n\nRead the selected issue requirements, PRD context, comments, branch context, verification commands, and artifact paths from: ${RUN_CONTEXT_PATH_IN_WORKTREE}`);\n}\n\nasync function handleRebaseConflict(\n failure: RebaseConflict,\n context: {\n worktreePath: string;\n branchName: string;\n target: ResolvedTarget;\n config: PourkitConfig;\n issueNumber: number;\n issueProvider: IssueProvider;\n executionProvider: ExecutionProvider;\n repoRoot: string;\n worktreeState: WorktreeRunState | null;\n logger: PourkitLogger;\n }\n): Promise<void> {\n const frConfig = context.target.strategy.failureResolution;\n if (!frConfig) {\n await transitionIssueToFailureState(\n context.issueProvider,\n context.issueNumber,\n context.config,\n \"No failureResolution configured\",\n context.logger\n );\n throw new Error(\"Base refresh conflicted: no failureResolution configured\");\n }\n\n const maxAttempts =\n frConfig.failureLimits?.RebaseConflict ?? frConfig.maxAttemptsPerFailure;\n let attemptNumber = 0;\n let currentFailure = failure;\n\n while (attemptNumber < maxAttempts) {\n attemptNumber++;\n\n const packet = constructFailureResolutionPacket(currentFailure, {\n stageName: \"baseRefresh\",\n attemptNumber,\n worktreePath: context.worktreePath,\n branchName: context.branchName,\n baseBranch: context.target.baseBranch,\n maxAttempts,\n allowedDecisions: [\"RETRY_STAGE\", \"HANDOFF_TO_HUMAN\", \"FAIL_RUN\"],\n artifactTarget: `.pourkit/.tmp/failure-resolution/attempt-${attemptNumber}.md`,\n });\n\n const result = await runFailureResolutionAgent({\n executionProvider: context.executionProvider,\n config: context.config,\n target: context.target,\n failure: currentFailure,\n packet,\n worktreePath: context.worktreePath,\n repoRoot: context.repoRoot,\n logger: context.logger,\n });\n\n if (result.status === \"handoff\") {\n if (context.worktreeState) {\n updateWorktreeRunState(context.worktreePath, {\n lastFailure: { stage: \"baseRefresh\", message: result.reason },\n });\n } else {\n writeWorktreeRunState(context.worktreePath, {\n issueNumber: context.issueNumber,\n targetName: context.target.name,\n branchName: context.branchName,\n baseBranch: context.target.baseBranch,\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n completedStages: {},\n review: { lifetimeIterations: 0 },\n lastFailure: { stage: \"baseRefresh\", message: result.reason },\n });\n }\n await transitionIssueToFailureState(\n context.issueProvider,\n context.issueNumber,\n context.config,\n result.reason,\n context.logger\n );\n throw new Error(result.reason);\n }\n\n if (result.status === \"fail-run\") {\n if (context.worktreeState) {\n updateWorktreeRunState(context.worktreePath, {\n lastFailure: { stage: \"baseRefresh\", message: result.reason },\n });\n } else {\n writeWorktreeRunState(context.worktreePath, {\n issueNumber: context.issueNumber,\n targetName: context.target.name,\n branchName: context.branchName,\n baseBranch: context.target.baseBranch,\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n completedStages: {},\n review: { lifetimeIterations: 0 },\n lastFailure: { stage: \"baseRefresh\", message: result.reason },\n });\n }\n throw new Error(result.reason);\n }\n\n // Host owns Git state transitions after FR agent: git add + git rebase --continue\n const changedPaths =\n packet.conflictedPaths ?? currentFailure.conflictedPaths;\n\n const markersRemain = await hasUnresolvedConflictMarkers(\n context.worktreePath,\n changedPaths\n );\n if (markersRemain) {\n const message =\n \"Conflict resolution agent resolved artifact but conflict markers remain in files\";\n if (context.worktreeState) {\n updateWorktreeRunState(context.worktreePath, {\n lastFailure: { stage: \"baseRefresh\", message },\n });\n } else {\n writeWorktreeRunState(context.worktreePath, {\n issueNumber: context.issueNumber,\n targetName: context.target.name,\n branchName: context.branchName,\n baseBranch: context.target.baseBranch,\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n completedStages: {},\n review: { lifetimeIterations: 0 },\n lastFailure: { stage: \"baseRefresh\", message },\n });\n }\n await transitionIssueToFailureState(\n context.issueProvider,\n context.issueNumber,\n context.config,\n message,\n context.logger\n );\n throw new Error(message);\n }\n\n await execCapture(\"git\", [\"add\", ...changedPaths], {\n cwd: context.worktreePath,\n logger: context.logger,\n label: \"git add conflicted paths\",\n });\n\n try {\n await execCapture(\"git\", [\"rebase\", \"--continue\"], {\n cwd: context.worktreePath,\n env: { ...process.env, GIT_EDITOR: \"true\" },\n logger: context.logger,\n label: \"git rebase --continue\",\n });\n // Full rebase completed after this commit\n if (context.worktreeState?.completedStages.builder) {\n const invalidatedState = invalidateAfterBaseRefresh(\n context.worktreeState\n );\n writeWorktreeRunState(context.worktreePath, invalidatedState);\n }\n return;\n } catch {\n // rebase --continue hit another conflict — detect new conflicted paths\n const statusResult = await execCapture(\"git\", [\"status\", \"--porcelain\"], {\n cwd: context.worktreePath,\n logger: context.logger,\n label: \"git status\",\n });\n const newConflictedPaths = statusResult.stdout\n .split(\"\\n\")\n .filter((line) => /^(AA|DD|UU|AU|UA|DU|UD)\\s/.test(line))\n .map((line) => line.slice(3).trim())\n .filter(Boolean);\n\n if (newConflictedPaths.length === 0) {\n const message =\n \"git rebase --continue failed with no remaining conflicts\";\n if (context.worktreeState) {\n updateWorktreeRunState(context.worktreePath, {\n lastFailure: { stage: \"baseRefresh\", message },\n });\n } else {\n writeWorktreeRunState(context.worktreePath, {\n issueNumber: context.issueNumber,\n targetName: context.target.name,\n branchName: context.branchName,\n baseBranch: context.target.baseBranch,\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n completedStages: {},\n review: { lifetimeIterations: 0 },\n lastFailure: { stage: \"baseRefresh\", message },\n });\n }\n await transitionIssueToFailureState(\n context.issueProvider,\n context.issueNumber,\n context.config,\n message,\n context.logger\n );\n throw new Error(message);\n }\n\n currentFailure = new RebaseConflict({\n conflictedPaths: newConflictedPaths,\n message: `Rebase conflict in: ${newConflictedPaths.join(\", \")}`,\n });\n }\n }\n\n if (context.worktreeState) {\n updateWorktreeRunState(context.worktreePath, {\n lastFailure: {\n stage: \"baseRefresh\",\n message: `Base refresh recovery exhausted after ${maxAttempts} attempts`,\n },\n });\n } else {\n writeWorktreeRunState(context.worktreePath, {\n issueNumber: context.issueNumber,\n targetName: context.target.name,\n branchName: context.branchName,\n baseBranch: context.target.baseBranch,\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n completedStages: {},\n review: { lifetimeIterations: 0 },\n lastFailure: {\n stage: \"baseRefresh\",\n message: `Base refresh recovery exhausted after ${maxAttempts} attempts`,\n },\n });\n }\n await transitionIssueToFailureState(\n context.issueProvider,\n context.issueNumber,\n context.config,\n `Base refresh recovery exhausted after ${maxAttempts} attempts`,\n context.logger\n );\n throw new Error(\n `Base refresh recovery exhausted after ${maxAttempts} attempts`\n );\n}\n\nasync function handlePublishedHistoryRisk(\n failure: PublishedHistoryRisk,\n context: {\n worktreePath: string;\n branchName: string;\n target: ResolvedTarget;\n config: PourkitConfig;\n issueNumber: number;\n issueProvider: IssueProvider;\n worktreeState: WorktreeRunState | null;\n logger: PourkitLogger;\n }\n): Promise<void> {\n const message = `Cannot auto-refresh published history: PR #${failure.prNumber} (${failure.prState}) exists for branch ${context.branchName}`;\n\n if (context.worktreeState) {\n updateWorktreeRunState(context.worktreePath, {\n lastFailure: { stage: \"baseRefresh\", message },\n });\n } else {\n writeWorktreeRunState(context.worktreePath, {\n issueNumber: context.issueNumber,\n targetName: context.target.name,\n branchName: context.branchName,\n baseBranch: context.target.baseBranch,\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n completedStages: {},\n review: { lifetimeIterations: 0 },\n lastFailure: { stage: \"baseRefresh\", message },\n });\n }\n\n await transitionIssueToFailureState(\n context.issueProvider,\n context.issueNumber,\n context.config,\n message,\n context.logger\n );\n throw new Error(message);\n}\n","import { join } from \"node:path\";\nimport { z } from \"zod\";\n\nexport interface CleanupConfig {\n enabled: boolean;\n worktreeRetentionDays: number;\n logRetentionDays: number;\n}\n\nexport interface SerenaConfig {\n enabled: boolean;\n required: boolean;\n mcpUrl: string;\n sandboxMcpUrl: string;\n dataDir: string;\n autoStart: boolean;\n}\n\nexport interface SerenaConfigInput {\n enabled?: boolean;\n required?: boolean;\n mcpUrl?: string;\n sandboxMcpUrl?: string;\n dataDir?: string;\n autoStart?: boolean;\n}\n\nexport interface TargetSerenaConfig {\n enabled?: boolean;\n required?: boolean;\n}\n\nexport interface PourkitConfig {\n targets: Target[];\n labels: LabelsConfig;\n sandbox: SandboxConfig;\n checks: ChecksConfig;\n cleanup: CleanupConfig;\n serena: SerenaConfig;\n}\n\nexport interface PourkitConfigInput {\n targets: TargetInput[];\n labels: LabelsConfig;\n sandbox: SandboxConfig;\n checks: ChecksConfigInput;\n cleanup?: Partial<CleanupConfig>;\n serena?: SerenaConfigInput;\n}\n\nexport interface StageAgentConfig {\n agent: string;\n model: string;\n variant?: string;\n env?: Record<string, string>;\n promptTemplate: string;\n outputRetries?: OutputRetriesConfig;\n}\n\nexport interface OutputRetriesConfig {\n missingOrEmpty?: number;\n}\n\nexport interface ConflictResolutionConfigInput extends StageAgentConfig {\n maxAttempts: number;\n}\n\nexport interface ConflictResolutionConfig extends StageAgentConfig {\n maxAttempts: number;\n}\n\nexport interface FailureResolutionConfigInput {\n agent: string;\n model: string;\n variant?: string;\n env?: Record<string, string>;\n promptTemplate: string;\n outputRetries?: OutputRetriesConfig;\n maxAttemptsPerFailure: number;\n failureLimits?: Record<string, number>;\n}\n\nexport interface FailureResolutionConfig {\n agent: string;\n model: string;\n variant?: string;\n env?: Record<string, string>;\n promptTemplate: string;\n outputRetries?: OutputRetriesConfig;\n maxAttemptsPerFailure: number;\n failureLimits?: Record<string, number>;\n}\n\nexport interface ReviewerConfig extends StageAgentConfig {\n criteria: string[];\n includeReviewHistory?: boolean;\n /** @deprecated Use strategy.review.passWithNotesRefactorAttempts. */\n passWithNotesRefactorAttempts?: number;\n}\n\nexport interface BuilderConfig extends StageAgentConfig {}\n\nexport interface QueueConfig {\n loop?: boolean;\n}\n\nexport interface ChecksConfigInput {\n requiredLabels: string[];\n allowedAuthors: string[];\n checksFoundTimeoutSeconds?: number;\n checksCompletionTimeoutSeconds?: number;\n pollIntervalSeconds?: number;\n issueListLimit?: number;\n}\n\nexport interface TargetInput {\n name: string;\n baseBranch?: string;\n branchTemplate?: string;\n setupCommands?: VerificationCommandInput[];\n autoMerge?: boolean;\n queue?: QueueConfig;\n serena?: TargetSerenaConfig;\n strategy: ReviewRefactorLoopStrategyInput;\n}\n\nexport interface Target {\n name: string;\n baseBranch: string;\n branchTemplate: string;\n setupCommands?: VerificationCommand[];\n autoMerge?: boolean;\n queue?: QueueConfig;\n serena?: TargetSerenaConfig;\n strategy: ReviewRefactorLoopStrategy;\n}\n\nexport type ResolvedTarget = Target;\n\nexport type TargetStrategy = ReviewRefactorLoopStrategy;\n\nexport type PrdRunMode = \"github\" | \"local\";\nexport type PrdRunModeSource = \"target-config\" | \"cli-override\" | \"default\";\n\nexport interface ResolvedPrdRunMode {\n mode: PrdRunMode;\n source: PrdRunModeSource;\n targetName: string;\n}\n\nexport interface IssueFinalReviewConfig extends StageAgentConfig {\n maxAttempts: number;\n}\n\nexport interface PrdRunFinalReviewConfig extends StageAgentConfig {}\n\nexport interface ReviewRefactorLoopStrategyInput {\n type: \"review-refactor-loop\";\n implement: {\n builder: StageAgentConfig;\n };\n conflictResolution?: ConflictResolutionConfigInput;\n failureResolution: FailureResolutionConfigInput;\n review: {\n reviewer: ReviewerConfig;\n refactor: StageAgentConfig;\n maxIterations: number;\n passWithNotesRefactorAttempts?: number;\n };\n verify?: VerifyConfigInput;\n issueFinalReview: IssueFinalReviewConfig;\n finalize: {\n prDescriptionAgent: StageAgentConfig;\n maxAttempts: number;\n };\n prdRun?: {\n finalReview: PrdRunFinalReviewConfig;\n mode?: PrdRunMode;\n };\n}\n\nexport interface ReviewRefactorLoopStrategy {\n type: \"review-refactor-loop\";\n implement: {\n builder: StageAgentConfig;\n };\n conflictResolution?: ConflictResolutionConfig;\n failureResolution: FailureResolutionConfig;\n review: {\n reviewer: ReviewerConfig;\n refactor: StageAgentConfig;\n maxIterations: number;\n passWithNotesRefactorAttempts: number;\n };\n verify?: VerifyConfig;\n issueFinalReview: IssueFinalReviewConfig;\n finalize: {\n prDescriptionAgent: StageAgentConfig;\n maxAttempts: number;\n };\n prdRun?: {\n finalReview: PrdRunFinalReviewConfig;\n mode?: PrdRunMode;\n };\n}\n\nexport interface VerifyConfig {\n commands: VerificationCommand[];\n}\n\nexport interface VerifyConfigInput {\n commands?: VerificationCommandInput[];\n}\n\nexport interface LabelsConfig {\n readyForAgent: string;\n agentInProgress: string;\n blocked: string;\n prOpenAwaitingMerge: string;\n readyForHuman: string;\n needsTriage: string;\n}\n\nexport interface SandboxConfig {\n provider: string;\n copyToWorktree?: string[];\n mounts?: SandboxMountConfig[];\n env?: Record<string, string>;\n idleTimeoutSeconds?: number;\n forceRebuild?: boolean;\n}\n\nexport interface SandboxMountConfig {\n hostPath: string;\n sandboxPath: string;\n readonly?: boolean;\n}\n\nexport interface VerificationCommand {\n command: string;\n label: string;\n}\n\nexport interface VerificationCommandInput {\n command: string;\n label?: string;\n}\n\nexport interface ChecksConfig {\n requiredLabels: string[];\n allowedAuthors: string[];\n checksFoundTimeoutSeconds: number;\n checksCompletionTimeoutSeconds: number;\n pollIntervalSeconds: number;\n issueListLimit: number;\n}\n\nexport interface IssueData {\n number: number;\n title: string;\n body: string;\n state: \"open\" | \"closed\";\n labels: string[];\n comments: string[];\n createdAt?: Date;\n}\n\n// ---- Zod schemas ----\n\nconst NonEmptyString = z.string().trim().min(1);\n\nconst DEFAULT_MISSING_OR_EMPTY_OUTPUT_RETRIES = 3;\n\nconst OutputRetriesConfigSchema = z\n .object({\n missingOrEmpty: z\n .number()\n .int()\n .nonnegative()\n .default(DEFAULT_MISSING_OR_EMPTY_OUTPUT_RETRIES),\n })\n .strict();\n\nexport function resolveMissingOrEmptyOutputRetries(config?: {\n outputRetries?: { missingOrEmpty?: number };\n}): number {\n return (\n config?.outputRetries?.missingOrEmpty ??\n DEFAULT_MISSING_OR_EMPTY_OUTPUT_RETRIES\n );\n}\n\nconst StageAgentConfigSchema = z\n .object({\n agent: NonEmptyString,\n model: NonEmptyString,\n variant: NonEmptyString.optional(),\n env: z.record(z.string(), z.string()).optional(),\n promptTemplate: NonEmptyString,\n outputRetries: OutputRetriesConfigSchema.optional(),\n })\n .strict();\n\nconst ReviewerConfigSchema = z\n .object({\n agent: NonEmptyString,\n model: NonEmptyString,\n variant: NonEmptyString.optional(),\n env: z.record(z.string(), z.string()).optional(),\n promptTemplate: NonEmptyString,\n outputRetries: OutputRetriesConfigSchema.optional(),\n criteria: z.array(NonEmptyString),\n includeReviewHistory: z.boolean().optional(),\n passWithNotesRefactorAttempts: z.number().int().nonnegative().optional(),\n })\n .strict();\n\nconst VerificationCommandSchema = z\n .object({\n command: z.string().nullable().optional(),\n label: z.string().optional(),\n })\n .strict()\n .refine((d) => d.command && d.command.trim() !== \"\", {\n message: \"must have a non-empty command\",\n })\n .transform((d) => ({\n command: d.command!,\n label: d.label && d.label.trim() !== \"\" ? d.label : undefined,\n }));\n\nconst PrdRunModeSchema = z.enum([\"github\", \"local\"]);\n\nconst QueueConfigSchema = z\n .object({\n loop: z.boolean().optional(),\n })\n .strict();\n\nconst FailureResolutionConfigSchema = z\n .object({\n agent: NonEmptyString,\n model: NonEmptyString,\n variant: NonEmptyString.optional(),\n env: z.record(z.string(), z.string()).optional(),\n promptTemplate: NonEmptyString,\n outputRetries: OutputRetriesConfigSchema.optional(),\n maxAttemptsPerFailure: z.number().int().positive(),\n failureLimits: z.record(z.string(), z.number().int().positive()).optional(),\n })\n .strict();\n\nconst ReviewRefactorLoopStrategySchema = z\n .object({\n type: z.literal(\"review-refactor-loop\"),\n implement: z\n .object({\n builder: StageAgentConfigSchema,\n })\n .strict(),\n conflictResolution: z\n .object({\n agent: NonEmptyString,\n model: NonEmptyString,\n variant: NonEmptyString.optional(),\n env: z.record(z.string(), z.string()).optional(),\n promptTemplate: NonEmptyString,\n maxAttempts: z.number().int().positive(),\n })\n .strict()\n .optional(),\n failureResolution: FailureResolutionConfigSchema,\n review: z\n .object({\n reviewer: ReviewerConfigSchema,\n refactor: StageAgentConfigSchema,\n maxIterations: z.number().int().positive(),\n passWithNotesRefactorAttempts: z\n .number()\n .int()\n .nonnegative()\n .default(2),\n })\n .strict(),\n verify: z\n .object({\n commands: z.preprocess(\n (v) => (Array.isArray(v) ? v : []),\n z.array(VerificationCommandSchema).refine((arr) => arr.length > 0, {\n message: \"must contain at least one command\",\n })\n ),\n })\n .strict()\n .optional(),\n issueFinalReview: StageAgentConfigSchema.extend({\n maxAttempts: z.number().int().positive(),\n }),\n finalize: z\n .object({\n prDescriptionAgent: StageAgentConfigSchema,\n maxAttempts: z.number().int().positive(),\n })\n .strict(),\n prdRun: z\n .object({\n mode: PrdRunModeSchema.optional(),\n // Uses promptTemplate (canonical StageAgentConfig field), not prompt as Issue contract may suggest\n finalReview: StageAgentConfigSchema,\n })\n .strict()\n .optional(),\n })\n .strict();\n\nconst TargetSerenaConfigSchema = z\n .object({\n enabled: z.boolean().optional(),\n required: z.boolean().optional(),\n })\n .strict();\n\nconst TargetSchema = z\n .object({\n name: NonEmptyString,\n baseBranch: z.preprocess(\n (v) => (typeof v === \"string\" && v.length > 0 ? v : undefined),\n NonEmptyString.default(\"main\")\n ),\n branchTemplate: z\n .string()\n .default(\"pourkit/{{issue.number}}/{{issue.slug}}\"),\n setupCommands: z.preprocess(\n (v) => (Array.isArray(v) ? v : undefined),\n z.array(VerificationCommandSchema).default([])\n ),\n autoMerge: z.preprocess(\n (v) => (typeof v === \"boolean\" ? v : undefined),\n z.boolean().default(true)\n ),\n queue: QueueConfigSchema.optional(),\n serena: TargetSerenaConfigSchema.optional(),\n strategy: ReviewRefactorLoopStrategySchema,\n })\n .strict();\n\nconst LabelsSchema = z\n .object({\n readyForAgent: NonEmptyString,\n agentInProgress: NonEmptyString,\n blocked: NonEmptyString,\n prOpenAwaitingMerge: NonEmptyString,\n readyForHuman: NonEmptyString,\n needsTriage: NonEmptyString.optional().default(\"needs-triage\"),\n })\n .strict();\n\nconst SandboxMountSchema = z\n .object({\n hostPath: NonEmptyString,\n sandboxPath: NonEmptyString,\n readonly: z.boolean().default(false),\n })\n .strict();\n\nconst SandboxSchema = z\n .object({\n provider: NonEmptyString,\n copyToWorktree: z.array(NonEmptyString).optional(),\n mounts: z.array(SandboxMountSchema).optional(),\n env: z.record(z.string()).optional(),\n idleTimeoutSeconds: z.preprocess((v) => {\n if (v === undefined) return undefined;\n if (typeof v === \"number\" && Number.isFinite(v) && v > 0) return v;\n return v;\n }, z.number().int().positive().optional()),\n })\n .strict();\n\nconst ChecksSchema = z\n .object({\n requiredLabels: z.array(NonEmptyString),\n allowedAuthors: z.array(NonEmptyString),\n checksFoundTimeoutSeconds: z.number().int().positive().optional(),\n checksCompletionTimeoutSeconds: z.number().int().positive().optional(),\n pollIntervalSeconds: z.number().int().positive().optional(),\n issueListLimit: z.number().int().positive().optional(),\n })\n .strict();\n\nconst CleanupConfigSchema = z\n .object({\n enabled: z.boolean().default(true),\n worktreeRetentionDays: z.number().int().positive().default(14),\n logRetentionDays: z.number().int().positive().default(30),\n })\n .strict();\n\nconst SerenaConfigSchema = z\n .object({\n enabled: z.boolean().default(false),\n required: z.boolean().default(false),\n mcpUrl: NonEmptyString.default(\"http://localhost:9121/mcp\"),\n sandboxMcpUrl: NonEmptyString.default(\"http://localhost:9121/mcp\"),\n dataDir: z.string().default(\".pourkit/serena/\"),\n autoStart: z.boolean().default(false),\n })\n .strict();\n\nconst PourkitConfigSchema = z\n .object({\n targets: z.array(TargetSchema).min(1),\n labels: LabelsSchema,\n sandbox: SandboxSchema,\n checks: ChecksSchema,\n cleanup: CleanupConfigSchema.optional(),\n serena: SerenaConfigSchema.default({}),\n })\n .strict();\n\n// ---- Removed field preflight ----\n\nconst removedFieldReplacements: Record<string, string> = {\n \"config.implementor\": \"targets[].strategy.implement.builder\",\n \"config.reviewer\": \"targets[].strategy.review.reviewer\",\n \"config.refactorer\": \"targets[].strategy.review.refactor\",\n \"config.finalizer\": \"targets[].strategy.finalize.prDescriptionAgent\",\n \"config.maxReviewIterations\": \"targets[].strategy.review.maxIterations\",\n \"config.builder\": \"targets[].strategy.implement.builder\",\n \"targets[].verificationCommands\": \"targets[].strategy.verify.commands\",\n \"targets[].implementor\": \"targets[].strategy.implement.builder\",\n \"targets[].reviewer\": \"targets[].strategy.review.reviewer\",\n \"targets[].refactorer\": \"targets[].strategy.review.refactor\",\n \"targets[].finalizer\": \"targets[].strategy.finalize.prDescriptionAgent\",\n \"targets[].maxReviewIterations\": \"targets[].strategy.review.maxIterations\",\n \"checks.timeoutSeconds\": \"checks.checksCompletionTimeoutSeconds\",\n};\n\nfunction checkRemovedFields(raw: Record<string, unknown>): void {\n const topLevelKeys = [\n \"implementor\",\n \"reviewer\",\n \"refactorer\",\n \"finalizer\",\n \"maxReviewIterations\",\n \"builder\",\n ];\n for (const key of topLevelKeys) {\n if (key in raw) {\n throw new Error(\n `config.${key} has been removed; use ${removedFieldReplacements[`config.${key}`]}`\n );\n }\n }\n\n const targetLevelKeys = [\n \"verificationCommands\",\n \"implementor\",\n \"reviewer\",\n \"refactorer\",\n \"finalizer\",\n \"maxReviewIterations\",\n ];\n if (Array.isArray(raw.targets)) {\n for (let i = 0; i < raw.targets.length; i++) {\n const t = raw.targets[i];\n if (t && typeof t === \"object\") {\n const target = t as Record<string, unknown>;\n for (const key of targetLevelKeys) {\n if (key in target) {\n throw new Error(\n `targets[${i}].${key} has been removed; use ${removedFieldReplacements[`targets[].${key}`]}`\n );\n }\n }\n }\n }\n }\n\n if (raw.checks && typeof raw.checks === \"object\") {\n const checks = raw.checks as Record<string, unknown>;\n if (\"timeoutSeconds\" in checks) {\n throw new Error(\n \"checks.timeoutSeconds has been removed; use checks.checksCompletionTimeoutSeconds\"\n );\n }\n }\n}\n\n// ---- Zod error formatting ----\n\nfunction formatZodPath(path: (string | number)[]): string {\n if (path.length === 0) return \"\";\n let result = \"\";\n for (const segment of path) {\n if (typeof segment === \"number\") {\n result += `[${segment}]`;\n } else {\n result += result ? `.${segment}` : segment;\n }\n }\n return result;\n}\n\nfunction formatFirstZodError(err: z.ZodError): string {\n const issue = err.issues[0];\n const path = formatZodPath(issue.path);\n\n if (\n path === \"targets\" &&\n (issue.code === \"too_small\" || issue.code === \"invalid_type\")\n ) {\n return \"Config must have at least one target\";\n }\n\n if (\n issue.path.length >= 3 &&\n issue.path[0] === \"targets\" &&\n typeof issue.path[1] === \"number\" &&\n issue.path[2] === \"name\" &&\n issue.code === z.ZodIssueCode.too_small\n ) {\n return `Target[${issue.path[1]}] must have a non-empty name`;\n }\n\n switch (issue.code) {\n case z.ZodIssueCode.invalid_type: {\n if (issue.expected === \"object\") {\n return path ? `${path} must be an object` : \"Config must be an object\";\n }\n if (issue.expected === \"integer\") {\n return `${path} must be an integer`;\n }\n if (issue.expected === \"string\") {\n return `${path} must be a string`;\n }\n if (issue.expected === \"number\") {\n return `${path} must be a number`;\n }\n return issue.message;\n }\n case z.ZodIssueCode.too_small:\n if (issue.type === \"string\" && issue.minimum === 1) {\n return `${path} must be a non-empty string`;\n }\n if (issue.type === \"array\" && issue.minimum === 1) {\n return `${path} must not be empty`;\n }\n if (issue.type === \"number\") {\n return `${path} must be a positive number`;\n }\n return issue.message;\n case z.ZodIssueCode.invalid_literal:\n return `${path} must be ${issue.expected}`;\n case z.ZodIssueCode.unrecognized_keys:\n const keyPath = path ? `${path}.${issue.keys[0]}` : issue.keys[0];\n return `${keyPath} is not supported`;\n case z.ZodIssueCode.custom:\n return path ? `${path} ${issue.message}` : issue.message;\n default:\n return issue.message;\n }\n}\n\n// ---- Config parsing ----\n\nexport function parseConfig(raw: unknown): PourkitConfig {\n if (!raw || typeof raw !== \"object\") {\n throw new Error(\"Config must be an object\");\n }\n\n const config = raw as Record<string, unknown>;\n\n if (!Array.isArray(config.targets) || config.targets.length === 0) {\n throw new Error(\"Config must have at least one target\");\n }\n\n checkRemovedFields(config);\n\n const rawTargets = config.targets as Record<string, unknown>[];\n for (let i = 0; i < rawTargets.length; i++) {\n const t = rawTargets[i];\n if (t === null || typeof t !== \"object\") {\n throw new Error(`targets[${i}] must be an object`);\n }\n assertKnownKeys(t, `targets[${i}]`, [\n \"name\",\n \"baseBranch\",\n \"branchTemplate\",\n \"setupCommands\",\n \"autoMerge\",\n \"queue\",\n \"serena\",\n \"strategy\",\n ]);\n }\n\n for (let i = 0; i < rawTargets.length; i++) {\n const t = rawTargets[i];\n const strategy = t?.strategy as Record<string, unknown> | undefined;\n if (\n strategy &&\n typeof strategy === \"object\" &&\n \"conflictResolution\" in strategy\n ) {\n throw new Error(\n `targets[${i}].strategy.conflictResolution has been removed; use targets[${i}].strategy.failureResolution`\n );\n }\n\n if (\n strategy &&\n typeof strategy === \"object\" &&\n strategy.prdRun &&\n typeof strategy.prdRun === \"object\" &&\n \"reconciliation\" in (strategy.prdRun as Record<string, unknown>)\n ) {\n throw new Error(\n `targets[${i}].strategy.prdRun.reconciliation has been removed; PRD Run no longer invokes Architect reconciliation.`\n );\n }\n }\n\n if (config.sandbox && typeof config.sandbox === \"object\") {\n assertKnownKeys(config.sandbox as Record<string, unknown>, \"sandbox\", [\n \"provider\",\n \"copyToWorktree\",\n \"mounts\",\n \"env\",\n \"idleTimeoutSeconds\",\n ]);\n }\n\n const result = PourkitConfigSchema.safeParse(raw);\n if (!result.success) {\n throw new Error(formatFirstZodError(result.error));\n }\n\n const data = result.data;\n\n const targets: Target[] = data.targets.map((t) => {\n const setupCommands = t.setupCommands?.map((cmd, i) => ({\n command: cmd.command,\n label: cmd.label ?? `check-${i}`,\n }));\n const verifyCommands = t.strategy.verify?.commands?.map((cmd, i) => ({\n command: cmd.command,\n label: cmd.label ?? `check-${i}`,\n }));\n return {\n name: t.name,\n baseBranch: t.baseBranch,\n branchTemplate: t.branchTemplate,\n setupCommands,\n autoMerge: t.autoMerge,\n queue: t.queue,\n serena: t.serena,\n strategy: {\n type: \"review-refactor-loop\" as const,\n implement: { builder: t.strategy.implement.builder },\n failureResolution: {\n agent: t.strategy.failureResolution.agent,\n model: t.strategy.failureResolution.model,\n promptTemplate: t.strategy.failureResolution.promptTemplate,\n outputRetries: t.strategy.failureResolution.outputRetries,\n maxAttemptsPerFailure:\n t.strategy.failureResolution.maxAttemptsPerFailure,\n failureLimits: t.strategy.failureResolution.failureLimits,\n },\n review: {\n reviewer: t.strategy.review.reviewer,\n refactor: t.strategy.review.refactor,\n maxIterations: t.strategy.review.maxIterations,\n passWithNotesRefactorAttempts:\n t.strategy.review.passWithNotesRefactorAttempts,\n },\n ...(t.strategy.verify ? { verify: { commands: verifyCommands! } } : {}),\n issueFinalReview: t.strategy.issueFinalReview,\n finalize: {\n prDescriptionAgent: t.strategy.finalize.prDescriptionAgent,\n maxAttempts: t.strategy.finalize.maxAttempts,\n },\n ...(t.strategy.prdRun\n ? {\n prdRun: {\n ...(t.strategy.prdRun.mode\n ? { mode: t.strategy.prdRun.mode }\n : {}),\n finalReview: t.strategy.prdRun.finalReview,\n },\n }\n : {}),\n },\n };\n });\n\n const serena = {\n ...data.serena,\n mcpUrl: process.env.POURKIT_SERENA_MCP_URL ?? data.serena.mcpUrl,\n sandboxMcpUrl:\n process.env.POURKIT_SERENA_SANDBOX_MCP_URL ?? data.serena.sandboxMcpUrl,\n };\n\n if (serena.mcpUrl.trim() === \"\") {\n throw new Error(\"POURKIT_SERENA_MCP_URL must be a non-empty string\");\n }\n\n if (serena.sandboxMcpUrl.trim() === \"\") {\n throw new Error(\n \"POURKIT_SERENA_SANDBOX_MCP_URL must be a non-empty string\"\n );\n }\n\n return {\n targets,\n labels: data.labels,\n sandbox: {\n provider: data.sandbox.provider,\n copyToWorktree: data.sandbox.copyToWorktree,\n mounts: data.sandbox.mounts,\n env: data.sandbox.env,\n idleTimeoutSeconds: data.sandbox.idleTimeoutSeconds,\n },\n checks: {\n requiredLabels: data.checks.requiredLabels,\n allowedAuthors: data.checks.allowedAuthors,\n checksFoundTimeoutSeconds: data.checks.checksFoundTimeoutSeconds ?? 60,\n checksCompletionTimeoutSeconds:\n data.checks.checksCompletionTimeoutSeconds ?? 30 * 60,\n pollIntervalSeconds: data.checks.pollIntervalSeconds ?? 15,\n issueListLimit: data.checks.issueListLimit ?? 50,\n },\n serena,\n cleanup: {\n enabled: data.cleanup?.enabled ?? true,\n worktreeRetentionDays: data.cleanup?.worktreeRetentionDays ?? 14,\n logRetentionDays: data.cleanup?.logRetentionDays ?? 30,\n },\n };\n}\n\n// ---- Key validation helpers (used before Zod for matching error format) ----\n\nfunction assertKnownKeys(\n value: Record<string, unknown>,\n path: string,\n knownKeys: string[]\n) {\n for (const key of Object.keys(value)) {\n if (!knownKeys.includes(key)) {\n throw new Error(`${path}.${key} is not supported`);\n }\n }\n}\n\n// ---- Public API ----\n\nexport function definePourkitConfig(\n config: PourkitConfigInput\n): PourkitConfigInput {\n return config;\n}\n\nexport function getVerificationCommands(target: Target): VerificationCommand[] {\n return target.strategy.verify?.commands ?? [];\n}\n\nexport function resolvePrdRunMode(\n target: Target,\n opts?: { localOverride?: boolean }\n): ResolvedPrdRunMode {\n if (opts?.localOverride === true) {\n return { mode: \"local\", source: \"cli-override\", targetName: target.name };\n }\n\n const configMode = target.strategy.prdRun?.mode;\n if (configMode) {\n return {\n mode: configMode,\n source: \"target-config\",\n targetName: target.name,\n };\n }\n\n return { mode: \"github\", source: \"default\", targetName: target.name };\n}\n\nexport async function loadRepoConfig(\n repoRoot: string,\n configFileName = \"pourkit.config.ts\"\n): Promise<PourkitConfig> {\n const { existsSync } = await import(\"node:fs\");\n const { mkdir, writeFile, rm } = await import(\"node:fs/promises\");\n const { join: pjoin, basename } = await import(\"node:path\");\n const { pathToFileURL } = await import(\"node:url\");\n const { build } = await import(\"esbuild\");\n\n const configPath = pjoin(repoRoot, configFileName);\n\n if (!existsSync(configPath)) {\n throw new Error(\n `No config file found at ${configPath}. Create a ${configFileName} that exports a default PourkitConfig.`\n );\n }\n\n const tmpDir = pjoin(repoRoot, \".pourkit\", \".tmp\", \"config\");\n await mkdir(tmpDir, { recursive: true });\n\n const tmpFile = pjoin(\n tmpDir,\n `pourkit-config-${Date.now()}-${Math.random().toString(36).slice(2, 8)}.mjs`\n );\n\n try {\n await build({\n entryPoints: [configPath],\n bundle: true,\n write: false,\n platform: \"node\",\n format: \"esm\",\n external: [\"node:*\"],\n }).then(async (result) => {\n const output = result.outputFiles[0].text;\n await writeFile(tmpFile, output, \"utf-8\");\n });\n\n const imported = await import(pathToFileURL(tmpFile).href);\n const raw = imported.default;\n\n if (raw === undefined) {\n throw new Error(\"pourkit.config.ts must have a default export\");\n }\n\n return parseConfig(raw);\n } finally {\n try {\n await rm(tmpFile, { force: true });\n } catch {\n // ignore cleanup errors\n }\n }\n}\n\nexport async function loadConfig(configPath: string): Promise<PourkitConfig> {\n const { readFile } = await import(\"node:fs/promises\");\n const { pathToFileURL } = await import(\"node:url\");\n const ext = configPath.split(\".\").pop()?.toLowerCase();\n\n if (ext === \"json\") {\n const raw = await readFile(configPath, \"utf-8\");\n return parseConfig(JSON.parse(raw));\n }\n\n if (ext === \"mjs\" || ext === \"js\") {\n const imported = await import(pathToFileURL(configPath).href);\n const raw = imported.default ?? imported;\n return parseConfig(raw);\n }\n\n throw new Error(`Unsupported config format: ${ext}. Use .json, .mjs, or .js`);\n}\n\nexport function resolvePromptTemplatePath(\n repoRoot: string,\n promptTemplate: string\n): string {\n if (promptTemplate.includes(\"/\")) {\n return join(repoRoot, promptTemplate);\n }\n return join(repoRoot, \".pourkit\", \"prompts\", promptTemplate);\n}\n\nexport function resolveTarget(\n config: PourkitConfig,\n explicitTarget?: string\n): ResolvedTarget {\n if (config.targets.length === 0) {\n throw new Error(\"No targets configured\");\n }\n\n if (config.targets.length === 1) {\n const target = config.targets[0];\n if (explicitTarget && target.name !== explicitTarget) {\n throw new Error(\n `Target \"${explicitTarget}\" not found. Available: ${target.name}`\n );\n }\n return target;\n }\n\n if (!explicitTarget) {\n throw new Error(\n `Multiple targets configured: ${config.targets.map((t) => t.name).join(\", \")}. Use --target to select one.`\n );\n }\n\n const found = config.targets.find((t) => t.name === explicitTarget);\n if (!found) {\n throw new Error(\n `Target \"${explicitTarget}\" not found. Available: ${config.targets.map((t) => t.name).join(\", \")}`\n );\n }\n\n return found;\n}\n","import type { IssueData } from \"../shared/config\";\nimport { slugify } from \"../shared/common\";\n\nexport function renderBranchName(template: string, issue: IssueData): string {\n return renderTemplate(template, issue);\n}\n\nfunction renderTemplate(template: string, issue: IssueData): string {\n const issueSlug = slugify(issue.title);\n\n return template\n .replace(/\\{\\{issue\\.number\\}\\}/g, String(issue.number))\n .replace(/\\{\\{issue\\.title\\}\\}/g, issue.title)\n .replace(/\\{\\{issue\\.body\\}\\}/g, issue.body)\n .replace(/\\{\\{issue\\.slug\\}\\}/g, issueSlug)\n .replace(/\\{\\{issue\\.state\\}\\}/g, issue.state);\n}\n","import { existsSync, readFileSync, readdirSync } from \"fs\";\nimport { isAbsolute, join, relative, resolve } from \"path\";\nimport type { PourkitStage } from \"../execution/execution-provider\";\nimport { buildRunVerificationCommand } from \"../commands/run-verification\";\nimport { getVerificationCommands, type IssueData, type Target } from \"./config\";\n\nexport const RUN_CONTEXT_PATH_IN_WORKTREE = \".pourkit/.tmp/run-context.md\";\n\nexport type RunContextSection =\n | \"issue\"\n | \"prd\"\n | \"comments\"\n | \"branch\"\n | \"verification-commands\"\n | \"review-criteria\"\n | \"artifacts\";\n\nexport const ALL_RUN_CONTEXT_SECTIONS: RunContextSection[] = [\n \"issue\",\n \"prd\",\n \"comments\",\n \"branch\",\n \"verification-commands\",\n \"review-criteria\",\n \"artifacts\",\n];\n\nexport const STAGE_SECTIONS: Record<PourkitStage, RunContextSection[]> = {\n builder: [\n \"issue\",\n \"prd\",\n \"comments\",\n \"branch\",\n \"verification-commands\",\n \"artifacts\",\n ],\n reviewer: [\n \"issue\",\n \"prd\",\n \"comments\",\n \"branch\",\n \"verification-commands\",\n \"review-criteria\",\n \"artifacts\",\n ],\n refactor: [\n \"issue\",\n \"prd\",\n \"comments\",\n \"branch\",\n \"verification-commands\",\n \"review-criteria\",\n \"artifacts\",\n ],\n finalizer: [\n \"issue\",\n \"comments\",\n \"branch\",\n \"verification-commands\",\n \"review-criteria\",\n \"artifacts\",\n ],\n conflictResolution: [\n \"issue\",\n \"comments\",\n \"branch\",\n \"verification-commands\",\n \"artifacts\",\n ],\n failureResolution: [\n \"issue\",\n \"comments\",\n \"branch\",\n \"verification-commands\",\n \"artifacts\",\n ],\n issueFinalReview: [\n \"issue\",\n \"prd\",\n \"comments\",\n \"branch\",\n \"verification-commands\",\n \"review-criteria\",\n \"artifacts\",\n ],\n prdFinalReview: [\n \"issue\",\n \"comments\",\n \"branch\",\n \"verification-commands\",\n \"artifacts\",\n ],\n prdReconciliation: [\n \"issue\",\n \"comments\",\n \"branch\",\n \"verification-commands\",\n \"artifacts\",\n ],\n};\n\nexport interface RunContextOptions {\n issue: IssueData;\n parentPrdIssue?: IssueData;\n target: Target;\n branchName: string;\n repoRoot?: string;\n reviewerCriteria?: string[];\n sections?: RunContextSection[];\n}\n\nexport interface ExecutionArtifact {\n path: string;\n content: string;\n}\n\nexport function buildRunContextArtifact(\n options: RunContextOptions\n): ExecutionArtifact {\n return {\n path: RUN_CONTEXT_PATH_IN_WORKTREE,\n content: buildRunContextMarkdown(options),\n };\n}\n\nexport function buildRunContextMarkdown(options: RunContextOptions): string {\n const {\n issue,\n parentPrdIssue,\n target,\n branchName,\n repoRoot,\n reviewerCriteria = [],\n sections = ALL_RUN_CONTEXT_SECTIONS,\n } = options;\n\n const parts: string[] = [\"# Pourkit Run Context\", \"\"];\n\n if (sections.includes(\"issue\")) {\n parts.push(\n \"## Issue\",\n \"\",\n `- Number: #${issue.number}`,\n `- Title: ${issue.title}`,\n \"\",\n \"### Body\",\n \"\",\n issue.body.trim() || \"(empty issue body)\",\n \"\"\n );\n }\n\n if (sections.includes(\"prd\")) {\n parts.push(...renderPrdContext(issue, parentPrdIssue, repoRoot));\n }\n\n if (sections.includes(\"comments\")) {\n parts.push(\"## Comments\", \"\");\n\n if (issue.comments.length === 0) {\n parts.push(\"(none)\", \"\");\n } else {\n parts.push(\n ...issue.comments.flatMap((comment, index) => [\n `### Comment ${index + 1}`,\n \"\",\n comment.trim() || \"(empty comment)\",\n \"\",\n ])\n );\n }\n }\n\n if (sections.includes(\"branch\")) {\n parts.push(\n \"## Branch\",\n \"\",\n `- Base: ${target.baseBranch}`,\n `- Working Branch: ${branchName}`,\n \"\"\n );\n }\n\n if (sections.includes(\"verification-commands\")) {\n parts.push(...renderCommandList(target, \"Verification Commands\"));\n }\n\n if (sections.includes(\"review-criteria\")) {\n parts.push(...renderCriteria(reviewerCriteria));\n }\n\n if (sections.includes(\"artifacts\")) {\n parts.push(\n \"## Artifacts\",\n \"\",\n \"- Shared run context: `.pourkit/.tmp/run-context.md`\",\n \"- Reviewer outputs dir: `.pourkit/.tmp/reviewers/`\",\n \"- Refactor outputs dir: `.pourkit/.tmp/refactors/`\",\n \"- Finalizer output: `.pourkit/.tmp/finalizer/agent-output.md`\",\n \"\"\n );\n }\n\n return parts.join(\"\\n\");\n}\n\nfunction renderCommandList(target: Target, heading: string) {\n const commands = getVerificationCommands(target);\n const parts = [\n `## ${heading}`,\n \"\",\n `Run this command from the repository root: \\`${buildRunVerificationCommand(target)}\\``,\n \"\",\n ];\n\n if (commands.length > 0) {\n parts.push(\n \"Configured commands executed by the wrapper:\",\n \"\",\n ...commands.map(\n (command) => `- ${command.label}: \\`${command.command}\\``\n ),\n \"\"\n );\n }\n\n return parts;\n}\n\nfunction renderPrdContext(\n issue: IssueData,\n parentPrdIssue: IssueData | undefined,\n repoRoot: string | undefined\n) {\n const parent = extractIssueSection(issue.body, \"Parent\");\n const documents = extractIssueSection(issue.body, \"Plan Documents\");\n const parentRef = parent?.match(/\\bPRD-\\d+\\b/i)?.[0]?.toUpperCase();\n const parentPrdPath =\n parentRef && repoRoot ? findParentPrdPath(repoRoot, parentRef) : null;\n const documentPaths = repoRoot ? extractRepoPaths(documents) : [];\n\n if (!parent && !documents) {\n return [];\n }\n\n const parts = [\"## PRD\", \"\"];\n\n if (parent) {\n parts.push(parent, \"\");\n } else {\n parts.push(\"(not declared in issue body)\", \"\");\n }\n\n if (parentPrdPath && repoRoot) {\n parts.push(\n `### Parent PRD Content: \\`${relative(repoRoot, parentPrdPath)}\\``,\n \"\",\n \"```markdown\",\n readFileSync(parentPrdPath, \"utf-8\").trimEnd(),\n \"```\",\n \"\"\n );\n } else if (parentPrdIssue) {\n parts.push(\n `### Parent PRD Content: #${parentPrdIssue.number} ${parentPrdIssue.title}`,\n \"\",\n \"```markdown\",\n parentPrdIssue.body.trimEnd() || \"(empty PRD body)\",\n \"```\",\n \"\"\n );\n }\n\n parts.push(\"## PRD Documents\", \"\");\n\n if (documents) {\n parts.push(documents, \"\");\n } else {\n parts.push(\"(not declared in issue body)\", \"\");\n }\n\n for (const documentPath of documentPaths) {\n const absolutePath = resolveRepoPath(repoRoot!, documentPath);\n if (!absolutePath || !existsSync(absolutePath)) continue;\n\n parts.push(\n `### Document Content: \\`${documentPath}\\``,\n \"\",\n \"```markdown\",\n readFileSync(absolutePath, \"utf-8\").trimEnd(),\n \"```\",\n \"\"\n );\n }\n\n return parts;\n}\n\nfunction extractIssueSection(body: string, heading: string): string | null {\n const escapedHeading = heading.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n const section = body.match(\n new RegExp(`^## ${escapedHeading}\\\\s*\\\\n([\\\\s\\\\S]*?)(?=\\\\n## |$)`, \"im\")\n )?.[1];\n\n const trimmed = section?.trim();\n return trimmed ? trimmed : null;\n}\n\nfunction extractRepoPaths(section: string | null): string[] {\n if (!section) return [];\n\n const paths = new Set<string>();\n for (const match of section.matchAll(/`([^`]+)`/g)) {\n const value = match[1]?.trim();\n if (value) paths.add(value);\n }\n return Array.from(paths);\n}\n\nfunction resolveRepoPath(repoRoot: string, path: string): string | null {\n if (isAbsolute(path) || path.includes(\"\\0\")) return null;\n\n const resolved = resolve(repoRoot, path);\n const repoRelative = relative(repoRoot, resolved);\n if (repoRelative.startsWith(\"..\") || isAbsolute(repoRelative)) return null;\n\n return resolved;\n}\n\nfunction findParentPrdPath(repoRoot: string, parentRef: string): string | null {\n const directPath = join(\n repoRoot,\n \".pourkit\",\n \"architecture\",\n parentRef,\n \"PRD.md\"\n );\n if (existsSync(directPath)) return directPath;\n\n const architectureRoot = join(repoRoot, \".pourkit\", \"architecture\");\n if (!existsSync(architectureRoot)) return null;\n\n return findPrdMirror(architectureRoot, parentRef);\n}\n\nfunction findPrdMirror(directory: string, parentRef: string): string | null {\n for (const entry of readdirSync(directory, { withFileTypes: true })) {\n const entryPath = join(directory, entry.name);\n if (entry.isDirectory()) {\n if (entry.name.startsWith(parentRef)) {\n const prdPath = join(entryPath, \"PRD.md\");\n if (existsSync(prdPath)) return prdPath;\n }\n\n const nested = findPrdMirror(entryPath, parentRef);\n if (nested) return nested;\n }\n }\n\n return null;\n}\n\nfunction renderCriteria(criteria: string[]) {\n if (criteria.length === 0) {\n return [];\n }\n\n return [\n \"## Review Criteria\",\n \"\",\n ...criteria.map((criterion) => `- ${criterion}`),\n \"\",\n ];\n}\n","import { execCapture, type PourkitLogger } from \"../shared/common\";\nimport {\n getVerificationCommands,\n type Target,\n type VerificationCommand,\n} from \"../shared/config\";\n\nexport interface VerificationCommandResult {\n label: string;\n command: string;\n ok: boolean;\n stdout?: string;\n stderr?: string;\n error?: string;\n}\n\nexport interface RunVerificationResult {\n ok: boolean;\n target: string;\n commands: VerificationCommandResult[];\n diagnostics: string[];\n}\n\nexport function buildRunVerificationCommand(target: Target): string {\n return `pourkit run-verification --target ${target.name}`;\n}\n\nasync function runVerificationCommand(\n command: VerificationCommand,\n cwd: string,\n logger?: PourkitLogger\n): Promise<VerificationCommandResult> {\n try {\n const result = await execCapture(\"bash\", [\"-lc\", command.command], {\n cwd,\n logger,\n label: command.label,\n });\n return {\n label: command.label,\n command: command.command,\n ok: true,\n stdout: result.stdout,\n stderr: result.stderr,\n };\n } catch (error) {\n return {\n label: command.label,\n command: command.command,\n ok: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n}\n\nexport async function runVerificationCommands(options: {\n target: Target;\n cwd: string;\n logger?: PourkitLogger;\n}): Promise<RunVerificationResult> {\n const commands = getVerificationCommands(options.target);\n const diagnostics: string[] = [];\n\n if (commands.length === 0) {\n diagnostics.push(\n `No verification commands configured for target \\\"${options.target.name}\\\".`\n );\n return {\n ok: true,\n target: options.target.name,\n commands: [],\n diagnostics,\n };\n }\n\n const results: VerificationCommandResult[] = [];\n\n for (const command of commands) {\n const result = await runVerificationCommand(\n command,\n options.cwd,\n options.logger\n );\n results.push(result);\n if (!result.ok) {\n diagnostics.push(`Verification failed for \\\"${command.label}\\\".`);\n return {\n ok: false,\n target: options.target.name,\n commands: results,\n diagnostics,\n };\n }\n }\n\n diagnostics.push(\n `Verification passed for target \\\"${options.target.name}\\\".`\n );\n return {\n ok: true,\n target: options.target.name,\n commands: results,\n diagnostics,\n };\n}\n","const PROTECTED_WORK_RULE =\n \"Do **not** revert, delete, or substantially strip already-landed protected sibling/base work unless the issue explicitly requires those files.\";\n\nexport function appendProtectedWorkGuidance(promptBody: string): string {\n return `${promptBody}\n\n## Hard Rule\n\n- ${PROTECTED_WORK_RULE}`;\n}\n","import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"fs\";\nimport { dirname, join } from \"path\";\n\nexport const WORKTREE_RUN_STATE_PATH = \".pourkit/state.json\";\n\nexport type WorktreeRunStage =\n | \"builder\"\n | \"verification\"\n | \"review\"\n | \"issueFinalReview\"\n | \"refactor\"\n | \"finalizer\"\n | \"finalCommit\"\n | \"pr\"\n | \"baseRefresh\"\n | \"conflictResolution\";\n\nexport interface WorktreeRunState {\n issueNumber: number;\n targetName: string;\n branchName: string;\n baseBranch: string;\n createdAt: string;\n updatedAt: string;\n completedStages: {\n builder?: boolean;\n initialVerification?: boolean;\n };\n review: {\n lifetimeIterations: number;\n lastVerdict?:\n | \"PASS\"\n | \"PASS_WITH_NOTES\"\n | \"NEEDS_REFACTOR\"\n | \"FAIL\"\n | \"NEEDS_HUMAN\";\n lastArtifactPath?: string;\n refactorArtifactPaths?: string[];\n refactorCompletedForLastReview?: boolean;\n exhaustedPreviousRun?: boolean;\n };\n issueFinalReview?: {\n completed: boolean;\n verdict?: \"pass\" | \"needs_human_review\";\n artifactPath?: string;\n selfRetouched?: boolean;\n changedPaths?: string[];\n verificationPassed?: boolean;\n };\n finalizer?: {\n completed: boolean;\n artifactPath?: string;\n title?: string;\n body?: string;\n };\n finalCommit?: {\n completed: boolean;\n sha?: string;\n };\n pr?: {\n created: boolean;\n number?: number;\n url?: string;\n merged?: boolean;\n };\n lastFailure?: {\n stage: WorktreeRunStage;\n message: string;\n };\n}\n\nexport function readWorktreeRunState(\n worktreePath: string\n): WorktreeRunState | null {\n const statePath = join(worktreePath, WORKTREE_RUN_STATE_PATH);\n if (!existsSync(statePath)) {\n return null;\n }\n try {\n const raw = JSON.parse(readFileSync(statePath, \"utf-8\"));\n if (isValidWorktreeRunState(raw)) {\n return raw;\n }\n return null;\n } catch {\n return null;\n }\n}\n\nfunction isValidWorktreeRunState(raw: unknown): raw is WorktreeRunState {\n if (typeof raw !== \"object\" || raw === null) return false;\n const obj = raw as Record<string, unknown>;\n if (typeof obj.completedStages !== \"object\" || obj.completedStages === null)\n return false;\n if (typeof obj.review !== \"object\" || obj.review === null) return false;\n const review = obj.review as Record<string, unknown>;\n if (typeof review.lifetimeIterations !== \"number\") return false;\n return true;\n}\n\nexport function writeWorktreeRunState(\n worktreePath: string,\n state: WorktreeRunState\n): void {\n const statePath = join(worktreePath, WORKTREE_RUN_STATE_PATH);\n mkdirSync(dirname(statePath), { recursive: true });\n writeFileSync(statePath, JSON.stringify(state, null, 2), \"utf-8\");\n}\n\nexport function updateWorktreeRunState(\n worktreePath: string,\n update: Partial<WorktreeRunState>\n): void {\n const existing =\n readWorktreeRunState(worktreePath) ?? ({} as WorktreeRunState);\n const merged: WorktreeRunState = {\n ...existing,\n ...update,\n updatedAt: new Date().toISOString(),\n completedStages: {\n ...existing.completedStages,\n ...(update.completedStages ?? {}),\n },\n review: {\n ...existing.review,\n ...(update.review ?? {}),\n },\n issueFinalReview:\n update.issueFinalReview !== undefined\n ? { ...existing.issueFinalReview, ...update.issueFinalReview }\n : existing.issueFinalReview,\n finalizer:\n update.finalizer !== undefined\n ? { ...existing.finalizer, ...update.finalizer }\n : existing.finalizer,\n finalCommit:\n update.finalCommit !== undefined\n ? { ...existing.finalCommit, ...update.finalCommit }\n : existing.finalCommit,\n pr:\n update.pr !== undefined ? { ...existing.pr, ...update.pr } : existing.pr,\n };\n writeWorktreeRunState(worktreePath, merged);\n}\n","import { execCapture, type PourkitLogger } from \"../shared/common\";\nimport type { WorktreeRunState } from \"../shared/worktree-run-state\";\n\nexport type BaseRefreshResult =\n | { status: \"skipped-current\" }\n | { status: \"refreshed\" }\n | { status: \"conflicted\"; message: string; conflictedPaths: string[] }\n | {\n status: \"refused-published-history\";\n prNumber: number;\n prState: \"OPEN\" | \"CLOSED\" | \"MERGED\";\n };\n\nexport interface RefreshStaleIssueBranchOptions {\n worktreePath: string;\n baseBranch: string;\n localGitBaseRef: string;\n logger: PourkitLogger;\n prNumber?: number;\n prState?: \"OPEN\" | \"CLOSED\" | \"MERGED\";\n}\n\nasync function isIssueBranchStale(\n worktreePath: string,\n baseBranch: string,\n logger: PourkitLogger\n): Promise<boolean> {\n try {\n await execCapture(\n \"git\",\n [\"merge-base\", \"--is-ancestor\", baseBranch, \"HEAD\"],\n {\n cwd: worktreePath,\n logger,\n label: \"git merge-base --is-ancestor\",\n }\n );\n return false;\n } catch {\n return true;\n }\n}\n\nexport async function refreshStaleIssueBranch(\n options: RefreshStaleIssueBranchOptions\n): Promise<BaseRefreshResult> {\n const {\n worktreePath,\n baseBranch,\n localGitBaseRef,\n logger,\n prNumber,\n prState,\n } = options;\n\n const stale = await isIssueBranchStale(worktreePath, localGitBaseRef, logger);\n if (!stale) {\n return { status: \"skipped-current\" };\n }\n\n if (prNumber !== undefined && prState !== undefined) {\n return {\n status: \"refused-published-history\",\n prNumber,\n prState,\n };\n }\n\n try {\n await execCapture(\"git\", [\"rebase\", \"--autostash\", localGitBaseRef], {\n cwd: worktreePath,\n logger,\n label: \"git rebase --autostash\",\n });\n return { status: \"refreshed\" };\n } catch (error) {\n let conflictedPaths: string[] = [];\n try {\n const statusResult = await execCapture(\"git\", [\"status\", \"--porcelain\"], {\n cwd: worktreePath,\n logger,\n label: \"git status\",\n });\n conflictedPaths = statusResult.stdout\n .split(\"\\n\")\n .filter((line) => /^(AA|DD|UU|AU|UA|DU|UD)\\s/.test(line))\n .map((line) => line.slice(3).trim())\n .filter(Boolean);\n } catch {\n // Not critical; leave empty if we can't read status\n }\n return {\n status: \"conflicted\",\n message: error instanceof Error ? error.message : String(error),\n conflictedPaths,\n };\n }\n}\n\nexport function invalidateAfterBaseRefresh(\n state: WorktreeRunState\n): WorktreeRunState {\n return {\n issueNumber: state.issueNumber,\n targetName: state.targetName,\n branchName: state.branchName,\n baseBranch: state.baseBranch,\n createdAt: state.createdAt,\n updatedAt: new Date().toISOString(),\n completedStages: {\n builder: state.completedStages.builder,\n },\n review: {\n lifetimeIterations: 0,\n },\n };\n}\n","import { Effect, Exit } from \"effect\";\nimport { runEffect } from \"../shared/effect-runtime\";\nimport { refreshStaleIssueBranch } from \"../commands/base-refresh\";\nimport type { BaseRefreshResult } from \"../commands/base-refresh\";\nimport type { PourkitLogger } from \"../shared/common\";\nimport { RebaseConflict, PublishedHistoryRisk } from \"./types\";\nimport type { StageFailure } from \"./types\";\nimport { createStageAttemptId, recordStageAttempt } from \"./stage-attempt\";\nimport { computeFailureFingerprint } from \"../shared/attempt-log\";\n\nexport interface BaseRefreshOptions {\n worktreePath: string;\n baseBranch: string;\n localGitBaseRef: string;\n logger: PourkitLogger;\n prNumber?: number;\n prState?: \"OPEN\" | \"CLOSED\" | \"MERGED\";\n}\n\nexport interface BaseRefreshSuccess {\n readonly status: \"refreshed\" | \"skipped-current\";\n}\n\nfunction baseRefreshEffect(\n options: BaseRefreshOptions\n): Effect.Effect<BaseRefreshSuccess, StageFailure> {\n return Effect.promise(() => refreshStaleIssueBranch(options)).pipe(\n Effect.flatMap(\n (\n result: BaseRefreshResult\n ): Effect.Effect<BaseRefreshSuccess, StageFailure> => {\n switch (result.status) {\n case \"refreshed\":\n return Effect.succeed({ status: \"refreshed\" as const });\n case \"skipped-current\":\n return Effect.succeed({ status: \"skipped-current\" as const });\n case \"conflicted\":\n return Effect.fail(\n new RebaseConflict({\n conflictedPaths: result.conflictedPaths,\n message: result.message,\n })\n );\n case \"refused-published-history\":\n return Effect.fail(\n new PublishedHistoryRisk({\n prNumber: result.prNumber,\n prState: result.prState,\n })\n );\n }\n }\n )\n );\n}\n\n/**\n * Run a Base Refresh attempt through the shared Effect runtime boundary.\n *\n * This function is an **async adapter seam**: it constructs an Effect\n * program internally and executes it via the shared runtime (runEffect),\n * then returns Promise<Exit<...>> rather than Effect<...>.\n *\n * ## Why the async adapter seam exists\n * The caller (issue-run.ts) uses plain async/await and Exit pattern-matching.\n * Until the caller is itself migrated to Effect, this function preserves the\n * Promise<Exit<...>> interface so no caller changes are needed.\n *\n * ## Future migration\n * When issue-run.ts or its callers adopt Effect, this function can return\n * Effect.Effect<BaseRefreshSuccess, StageFailure> directly and the caller\n * can execute it through the shared runtime.\n */\nexport async function runBaseRefreshAttempt(\n options: BaseRefreshOptions\n): Promise<Exit.Exit<BaseRefreshSuccess, StageFailure>> {\n const attemptId = createStageAttemptId();\n const startedAt = new Date().toISOString();\n\n const program = baseRefreshEffect(options).pipe(\n Effect.tapBoth({\n onSuccess: (success) =>\n Effect.sync(() => {\n recordStageAttempt(options.worktreePath, {\n id: attemptId,\n stage: \"baseRefresh\",\n startedAt,\n completedAt: new Date().toISOString(),\n outcome: \"success\",\n });\n }),\n onFailure: (failure) =>\n Effect.sync(() => {\n recordStageAttempt(options.worktreePath, {\n id: attemptId,\n stage: \"baseRefresh\",\n startedAt,\n completedAt: new Date().toISOString(),\n outcome: \"failure\",\n failureFingerprint: computeFailureFingerprint(\n \"baseRefresh\",\n failure._tag\n ),\n failureType: failure._tag,\n });\n }),\n })\n );\n\n return runEffect(program);\n}\n","/**\n * Shared Effect runtime boundary initialized at CLI startup.\n *\n * ## Purpose\n * All control-plane Effect programs should be executed through this module\n * rather than calling Effect.runPromiseExit directly. This ensures the\n * runtime boundary lives at the CLI edge, not inside command or stage code.\n *\n * ## Usage\n * 1. Call initializeEffectRuntime() at CLI startup (see cli.ts main()).\n * 2. Import runEffect() in Effect control-plane code.\n * 3. Do NOT import Effect.runPromiseExit directly in control-plane modules.\n *\n * ## Design constraints\n * - Thin wrapper: no Effect layers, services, or configuration.\n * - Async adapter seam: returns Promise<Exit<A, E>>, not Effect<A, E>.\n */\nimport { Effect, Exit } from \"effect\";\nimport { UnknownException } from \"effect/Cause\";\n\nlet initialized = false;\n\nexport function initializeEffectRuntime(): void {\n if (initialized) return;\n initialized = true;\n}\n\nexport function isRuntimeInitialized(): boolean {\n return initialized;\n}\n\nexport function runEffect<E, A>(\n program: Effect.Effect<A, E>\n): Promise<Exit.Exit<A, E>> {\n ensureEffectRuntime();\n return Effect.runPromiseExit(program);\n}\n\nfunction ensureEffectRuntime(): void {\n if (!initialized) {\n initializeEffectRuntime();\n }\n}\n\nfunction unwrapError(error: unknown): unknown {\n if (error instanceof UnknownException && error.error !== undefined) {\n return error.error;\n }\n return error;\n}\n\nexport function runEffectAndMapExit<E, A>(\n program: Effect.Effect<A, E>\n): Promise<A> {\n return runEffect(program).then((exit) => {\n if (Exit.isSuccess(exit)) return exit.value;\n const cause = exit.cause;\n if (cause._tag === \"Fail\") {\n const error = unwrapError(cause.error);\n throw error instanceof Error ? error : new Error(String(error));\n }\n const defect =\n cause._tag === \"Die\"\n ? cause.defect\n : cause._tag === \"Interrupt\"\n ? \"interrupted\"\n : `unhandled cause: ${cause._tag}`;\n throw defect instanceof Error\n ? defect\n : new Error(`Unexpected defect: ${String(defect)}`);\n });\n}\n","// fallow-ignore-file unused-class-member\nexport type StageFailureTag =\n | \"BuilderFailure\"\n | \"CheckFailure\"\n | \"ConfigFailure\"\n | \"FailureResolutionAgentFailed\"\n | \"FinalizerFailure\"\n | \"GitHubFailure\"\n | \"MergeFailure\"\n | \"PublishedHistoryRisk\"\n | \"RebaseConflict\"\n | \"RecoveryArtifactInvalid\"\n | \"RefactorFailure\"\n | \"ReviewerFailure\"\n | \"SafetyFailure\";\n\nexport class RebaseConflict extends Error {\n readonly _tag: \"RebaseConflict\" = \"RebaseConflict\";\n readonly conflictedPaths: string[];\n readonly message: string;\n\n constructor(args: {\n readonly conflictedPaths: string[];\n readonly message: string;\n }) {\n super(args.message);\n this.name = \"RebaseConflict\";\n this.conflictedPaths = args.conflictedPaths;\n this.message = args.message;\n }\n}\n\nexport class PublishedHistoryRisk extends Error {\n readonly _tag: \"PublishedHistoryRisk\" = \"PublishedHistoryRisk\";\n readonly prNumber: number;\n readonly prState: \"OPEN\" | \"CLOSED\" | \"MERGED\";\n\n constructor(args: {\n readonly prNumber: number;\n readonly prState: \"OPEN\" | \"CLOSED\" | \"MERGED\";\n }) {\n super(`Published PR #${args.prNumber} is ${args.prState}`);\n this.name = \"PublishedHistoryRisk\";\n this.prNumber = args.prNumber;\n this.prState = args.prState;\n }\n}\n\nexport class RecoveryArtifactInvalid extends Error {\n readonly _tag: \"RecoveryArtifactInvalid\" = \"RecoveryArtifactInvalid\";\n readonly reason: string;\n\n constructor(args: { readonly reason: string }) {\n super(args.reason);\n this.name = \"RecoveryArtifactInvalid\";\n this.reason = args.reason;\n }\n}\n\nexport class FailureResolutionAgentFailed extends Error {\n readonly _tag: \"FailureResolutionAgentFailed\" =\n \"FailureResolutionAgentFailed\";\n readonly reason: string;\n\n constructor(args: { readonly reason: string }) {\n super(args.reason);\n this.name = \"FailureResolutionAgentFailed\";\n this.reason = args.reason;\n }\n}\n\nexport class GitHubFailure extends Error {\n readonly _tag: \"GitHubFailure\" = \"GitHubFailure\";\n readonly statusCode: number | undefined;\n readonly endpoint: string;\n readonly message: string;\n\n constructor(args: {\n readonly statusCode?: number;\n readonly endpoint: string;\n readonly message: string;\n }) {\n super(args.message);\n this.name = \"GitHubFailure\";\n this.statusCode = args.statusCode;\n this.endpoint = args.endpoint;\n this.message = args.message;\n }\n}\n\nexport class CheckFailure extends Error {\n readonly _tag: \"CheckFailure\" = \"CheckFailure\";\n readonly checkName: string;\n readonly exitCode?: number;\n readonly message: string;\n\n constructor(args: {\n readonly checkName: string;\n readonly exitCode?: number;\n readonly message: string;\n }) {\n super(args.message);\n this.name = \"CheckFailure\";\n this.checkName = args.checkName;\n this.exitCode = args.exitCode;\n this.message = args.message;\n }\n}\n\nexport class ConfigFailure extends Error {\n readonly _tag: \"ConfigFailure\" = \"ConfigFailure\";\n readonly configKey: string;\n readonly expectedType: string;\n readonly message: string;\n\n constructor(args: {\n readonly configKey: string;\n readonly expectedType: string;\n readonly message: string;\n }) {\n super(args.message);\n this.name = \"ConfigFailure\";\n this.configKey = args.configKey;\n this.expectedType = args.expectedType;\n this.message = args.message;\n }\n}\n\nexport class SafetyFailure extends Error {\n readonly _tag: \"SafetyFailure\" = \"SafetyFailure\";\n readonly sensitivityKind: \"auth\" | \"secrets\" | \"permissions\" | \"destructive\";\n readonly message: string;\n\n constructor(args: {\n readonly sensitivityKind:\n | \"auth\"\n | \"secrets\"\n | \"permissions\"\n | \"destructive\";\n readonly message: string;\n }) {\n super(args.message);\n this.name = \"SafetyFailure\";\n this.sensitivityKind = args.sensitivityKind;\n this.message = args.message;\n }\n}\n\nexport class BuilderFailure extends Error {\n readonly _tag: \"BuilderFailure\" = \"BuilderFailure\";\n readonly message: string;\n\n constructor(args: { readonly message: string }) {\n super(args.message);\n this.name = \"BuilderFailure\";\n this.message = args.message;\n }\n}\n\nexport class ReviewerFailure extends Error {\n readonly _tag: \"ReviewerFailure\" = \"ReviewerFailure\";\n readonly message: string;\n\n constructor(args: { readonly message: string }) {\n super(args.message);\n this.name = \"ReviewerFailure\";\n this.message = args.message;\n }\n}\n\nexport class RefactorFailure extends Error {\n readonly _tag: \"RefactorFailure\" = \"RefactorFailure\";\n readonly message: string;\n\n constructor(args: { readonly message: string }) {\n super(args.message);\n this.name = \"RefactorFailure\";\n this.message = args.message;\n }\n}\n\nexport class FinalizerFailure extends Error {\n readonly _tag: \"FinalizerFailure\" = \"FinalizerFailure\";\n readonly message: string;\n\n constructor(args: { readonly message: string }) {\n super(args.message);\n this.name = \"FinalizerFailure\";\n this.message = args.message;\n }\n}\n\nexport class MergeFailure extends Error {\n readonly _tag: \"MergeFailure\" = \"MergeFailure\";\n readonly prNumber?: number;\n readonly message: string;\n\n constructor(args: { readonly prNumber?: number; readonly message: string }) {\n super(args.message);\n this.name = \"MergeFailure\";\n this.prNumber = args.prNumber;\n this.message = args.message;\n }\n}\n\nexport type StageFailure =\n | BuilderFailure\n | CheckFailure\n | ConfigFailure\n | FailureResolutionAgentFailed\n | FinalizerFailure\n | GitHubFailure\n | MergeFailure\n | PublishedHistoryRisk\n | RebaseConflict\n | RecoveryArtifactInvalid\n | RefactorFailure\n | ReviewerFailure\n | SafetyFailure;\n\nexport type RecoveryDecision =\n | \"RETRY_STAGE\"\n | \"RESUME_FROM_STAGE\"\n | \"MARK_STAGE_COMPLETE\"\n | \"HANDOFF_TO_HUMAN\"\n | \"FAIL_RUN\";\n\nconst SUPPORTED_DECISIONS: ReadonlySet<string> = new Set([\n \"RETRY_STAGE\",\n \"HANDOFF_TO_HUMAN\",\n \"FAIL_RUN\",\n]);\n\nexport function isSupportedRecoveryDecision(\n decision: string\n): decision is RecoveryDecision {\n return SUPPORTED_DECISIONS.has(decision);\n}\n\nexport interface FailureResolutionPacket {\n readonly failureType: StageFailureTag;\n readonly stageName: string;\n readonly attemptNumber: number;\n readonly worktreePath: string;\n readonly branchName: string;\n readonly baseBranch: string;\n readonly conflictedPaths?: string[];\n readonly failureSummary: string;\n readonly maxAttempts: number;\n readonly allowedDecisions: readonly RecoveryDecision[];\n readonly artifactTarget: string;\n}\n\nexport interface RecoveryArtifactJson {\n readonly recoveryDecision: string;\n readonly summary: string;\n readonly changedFiles: readonly string[];\n readonly verificationSummary?: string;\n readonly verificationCommands?: readonly string[];\n readonly notes?: string;\n}\n\nexport interface RecoveryArtifact {\n readonly raw: string;\n readonly json: RecoveryArtifactJson;\n readonly path: string;\n}\n\nconst JSON_BLOCK_RE = /```json\\n([\\s\\S]*?)```/;\n\nexport function parseRecoveryArtifact(\n markdown: string,\n artifactPath: string\n): RecoveryArtifact {\n const match = JSON_BLOCK_RE.exec(markdown);\n if (!match) {\n throw new RecoveryArtifactInvalid({\n reason: `No JSON code block found in artifact at ${artifactPath}`,\n });\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(match[1]);\n } catch {\n throw new RecoveryArtifactInvalid({\n reason: `Malformed JSON in artifact at ${artifactPath}`,\n });\n }\n\n if (parsed === null || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n throw new RecoveryArtifactInvalid({\n reason: `Expected a JSON object in artifact at ${artifactPath}`,\n });\n }\n\n const json = parsed as Record<string, unknown>;\n\n if (\n typeof json.recoveryDecision !== \"string\" ||\n json.recoveryDecision === \"\"\n ) {\n throw new RecoveryArtifactInvalid({\n reason: `Missing or empty recoveryDecision in artifact at ${artifactPath}`,\n });\n }\n\n if (typeof json.summary !== \"string\" || json.summary === \"\") {\n throw new RecoveryArtifactInvalid({\n reason: `Missing or empty summary in artifact at ${artifactPath}`,\n });\n }\n\n const changedFiles = json.changedFiles;\n if (!Array.isArray(changedFiles)) {\n throw new RecoveryArtifactInvalid({\n reason: `changedFiles must be an array in artifact at ${artifactPath}`,\n });\n }\n if (!changedFiles.every((f: unknown) => typeof f === \"string\")) {\n throw new RecoveryArtifactInvalid({\n reason: `changedFiles must be an array of strings in artifact at ${artifactPath}`,\n });\n }\n\n if (\n json.verificationSummary !== undefined &&\n typeof json.verificationSummary !== \"string\"\n ) {\n throw new RecoveryArtifactInvalid({\n reason: `verificationSummary must be a string in artifact at ${artifactPath}`,\n });\n }\n\n if (json.notes !== undefined && typeof json.notes !== \"string\") {\n throw new RecoveryArtifactInvalid({\n reason: `notes must be a string in artifact at ${artifactPath}`,\n });\n }\n\n if (json.verificationCommands !== undefined) {\n if (!Array.isArray(json.verificationCommands)) {\n throw new RecoveryArtifactInvalid({\n reason: `verificationCommands must be an array in artifact at ${artifactPath}`,\n });\n }\n if (\n !json.verificationCommands.every((c: unknown) => typeof c === \"string\")\n ) {\n throw new RecoveryArtifactInvalid({\n reason: `verificationCommands must be an array of strings in artifact at ${artifactPath}`,\n });\n }\n }\n\n return {\n raw: markdown,\n json: {\n recoveryDecision: json.recoveryDecision,\n summary: json.summary,\n changedFiles: changedFiles as string[],\n verificationSummary: json.verificationSummary as string | undefined,\n verificationCommands: json.verificationCommands as string[] | undefined,\n notes: json.notes as string | undefined,\n },\n path: artifactPath,\n };\n}\n\nexport interface DecisionValidation {\n readonly valid: boolean;\n readonly decision?: RecoveryDecision;\n readonly reason?: string;\n}\n\nexport function validateRecoveryDecision(\n artifact: RecoveryArtifact,\n allowedDecisions: readonly RecoveryDecision[]\n): DecisionValidation {\n const decision = artifact.json.recoveryDecision;\n if (!allowedDecisions.includes(decision as RecoveryDecision)) {\n return {\n valid: false,\n reason: `Decision \"${decision}\" is not in allowed list: ${allowedDecisions.join(\", \")}`,\n };\n }\n if (!isSupportedRecoveryDecision(decision)) {\n return {\n valid: false,\n reason: `Decision \"${decision}\" is not supported in this slice`,\n };\n }\n return { valid: true, decision: decision as RecoveryDecision };\n}\n","import { appendFileSync, existsSync, mkdirSync, readFileSync } from \"fs\";\nimport { dirname, join } from \"path\";\n\nexport type AttemptLogEntryType = \"stage\" | \"recovery\";\nexport type AttemptOutcome = \"success\" | \"failure\" | \"handoff\";\n\nexport interface AttemptLogEntryBase {\n readonly attemptType: AttemptLogEntryType;\n readonly fingerprint: string;\n readonly timestamp: string;\n readonly stage: string;\n readonly outcome: AttemptOutcome;\n}\n\nexport interface StageAttemptEntry extends AttemptLogEntryBase {\n readonly attemptType: \"stage\";\n}\n\nexport interface RecoveryAttemptEntry extends AttemptLogEntryBase {\n readonly attemptType: \"recovery\";\n readonly artifactRef?: string;\n readonly decision?: string;\n}\n\nexport type AttemptLogEntry = StageAttemptEntry | RecoveryAttemptEntry;\n\nexport interface RecoveryBudget {\n readonly used: number;\n readonly remaining: number;\n readonly exhausted: boolean;\n}\n\nconst ATTEMPT_LOG_PATH = \".pourkit/attempt-log.jsonl\";\n\nexport function writeAttemptLog(\n worktreePath: string,\n entry: AttemptLogEntry\n): void {\n const logPath = join(worktreePath, ATTEMPT_LOG_PATH);\n mkdirSync(dirname(logPath), { recursive: true });\n appendFileSync(logPath, JSON.stringify(entry) + \"\\n\", \"utf-8\");\n}\n\nexport function readAttemptLog(worktreePath: string): AttemptLogEntry[] {\n const logPath = join(worktreePath, ATTEMPT_LOG_PATH);\n if (!existsSync(logPath)) {\n return [];\n }\n const raw = readFileSync(logPath, \"utf-8\");\n const lines = raw.split(\"\\n\").filter((l) => l.length > 0);\n const entries: AttemptLogEntry[] = [];\n for (const line of lines) {\n try {\n const parsed = JSON.parse(line);\n if (isValidAttemptLogEntry(parsed)) {\n entries.push(parsed);\n }\n } catch {\n // skip unparseable lines\n }\n }\n return entries;\n}\n\nfunction isValidAttemptLogEntry(raw: unknown): raw is AttemptLogEntry {\n if (typeof raw !== \"object\" || raw === null) return false;\n const obj = raw as Record<string, unknown>;\n if (obj.attemptType !== \"stage\" && obj.attemptType !== \"recovery\")\n return false;\n if (typeof obj.fingerprint !== \"string\") return false;\n if (typeof obj.timestamp !== \"string\") return false;\n if (typeof obj.stage !== \"string\") return false;\n if (\n obj.outcome !== \"success\" &&\n obj.outcome !== \"failure\" &&\n obj.outcome !== \"handoff\"\n )\n return false;\n return true;\n}\n\nexport function recoveryBudgetForFailure(\n worktreePath: string,\n fingerprint: string,\n maxAttempts: number\n): RecoveryBudget {\n const entries = readAttemptLog(worktreePath);\n const used = entries.filter(\n (e) => e.attemptType === \"recovery\" && e.fingerprint === fingerprint\n ).length;\n const remaining = Math.max(0, maxAttempts - used);\n return {\n used,\n remaining,\n exhausted: used >= maxAttempts,\n };\n}\n\nexport function computeFailureFingerprint(\n stage: string,\n failureType: string\n): string {\n return `${stage.toLowerCase()}:${failureType}`;\n}\n","import {\n writeAttemptLog,\n computeFailureFingerprint,\n} from \"../shared/attempt-log\";\n\nexport type StageAttemptId = string;\n\nexport interface StageAttemptRecord {\n readonly id: StageAttemptId;\n readonly stage: string;\n readonly startedAt: string;\n readonly completedAt?: string;\n readonly outcome?: \"success\" | \"failure\" | \"handoff\";\n readonly failureFingerprint?: string;\n readonly failureType?: string;\n}\n\nexport function createStageAttemptId(): StageAttemptId {\n return `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n}\n\nexport function recordStageAttempt(\n worktreePath: string,\n record: StageAttemptRecord\n): void {\n writeAttemptLog(worktreePath, {\n attemptType: \"stage\",\n fingerprint: record.failureFingerprint ?? `${record.stage}:success`,\n timestamp: record.completedAt ?? new Date().toISOString(),\n stage: record.stage,\n outcome:\n record.outcome === \"handoff\"\n ? \"handoff\"\n : record.outcome === \"success\"\n ? \"success\"\n : \"failure\",\n });\n}\n","import { existsSync, readFileSync } from \"fs\";\nimport { join } from \"path\";\nimport type { PourkitConfig, IssueData, Target } from \"../shared/config\";\nimport { resolvePromptTemplatePath } from \"../shared/config\";\nimport type { ExecutionProvider } from \"../execution/execution-provider\";\nimport { execCapture, type PourkitLogger } from \"../shared/common\";\nimport {\n buildRunContextArtifact,\n RUN_CONTEXT_PATH_IN_WORKTREE,\n STAGE_SECTIONS,\n} from \"../shared/run-context\";\nimport { parseConflictResolutionArtifact } from \"../conflicts/conflict-resolution-artifact\";\nimport { validateConflictResolutionArtifactAtPath } from \"./artifact-validation\";\n\nexport type ConflictResolutionRunResult =\n | { status: \"resolved\"; artifactPath: string; files: string[] }\n | { status: \"ambiguous\"; artifactPath: string; message: string }\n | { status: \"failed\"; artifactPath?: string; message: string };\n\nexport interface RunConflictResolutionOnceOptions {\n executionProvider: ExecutionProvider;\n config: PourkitConfig;\n target: Target;\n issue: IssueData;\n branchName: string;\n worktreePath: string;\n repoRoot: string;\n conflictedPaths: string[];\n attempt: number;\n logger: PourkitLogger;\n}\n\nfunction loadConflictResolutionPrompt(\n repoRoot: string,\n promptTemplate: string,\n artifactPath: string\n): string {\n const promptPath = resolvePromptTemplatePath(repoRoot, promptTemplate);\n const promptBody = existsSync(promptPath)\n ? readFileSync(promptPath, \"utf-8\")\n : promptTemplate;\n\n return `${promptBody}\n\n## Shared Run Context\n\nRead the selected issue requirements, comments, branch context, verification commands, and artifact paths from: ${RUN_CONTEXT_PATH_IN_WORKTREE}\n\n## Output\n\nWrite your resolution to: ${artifactPath}\n\nBefore handoff, run: pourkit validate-artifact conflict-resolution ${artifactPath}\n\nDo not provide a separate chat response. The runner only reads the file above.`;\n}\n\nexport async function runConflictResolutionOnce(\n options: RunConflictResolutionOnceOptions\n): Promise<ConflictResolutionRunResult> {\n const {\n executionProvider,\n config,\n target,\n issue,\n branchName,\n worktreePath,\n repoRoot,\n conflictedPaths,\n attempt,\n logger,\n } = options;\n\n const strategyCr = target.strategy.conflictResolution;\n if (!strategyCr) {\n return { status: \"failed\", message: \"No conflictResolution configured\" };\n }\n\n const artifactPath = `.pourkit/.tmp/conflict-resolution/attempt-${attempt}.md`;\n\n const prompt = loadConflictResolutionPrompt(\n repoRoot,\n strategyCr.promptTemplate,\n artifactPath\n );\n\n const runContextArtifact = buildRunContextArtifact({\n issue,\n target,\n branchName,\n sections: STAGE_SECTIONS.conflictResolution,\n });\n\n const executionResult = await executionProvider.execute({\n stage: \"conflictResolution\",\n agent: strategyCr.agent,\n model: strategyCr.model,\n variant: strategyCr.variant,\n env: strategyCr.env,\n prompt,\n target,\n repoRoot,\n branchName,\n sandbox: config.sandbox,\n autoApprove: true,\n worktreePath,\n artifactPath,\n artifacts: [runContextArtifact],\n logger,\n });\n\n if (!executionResult.success) {\n return {\n status: \"failed\",\n message:\n executionResult.error ?? \"Conflict resolution agent execution failed\",\n };\n }\n\n const fullArtifactPath = join(worktreePath, artifactPath);\n if (!existsSync(fullArtifactPath)) {\n return {\n status: \"failed\",\n artifactPath,\n message: \"Conflict resolution agent completed but did not write artifact\",\n };\n }\n\n let artifactContent: string;\n try {\n artifactContent = readFileSync(fullArtifactPath, \"utf-8\");\n } catch (error) {\n return {\n status: \"failed\",\n artifactPath,\n message: `Failed to read conflict resolution artifact: ${error instanceof Error ? error.message : String(error)}`,\n };\n }\n\n const validation = validateConflictResolutionArtifactAtPath({\n artifactPath,\n worktreePath,\n });\n if (!validation.ok) {\n return {\n status: \"failed\",\n artifactPath,\n message: `Invalid conflict resolution artifact: ${validation.reason}`,\n };\n }\n const parsed = parseConflictResolutionArtifact(artifactContent);\n\n if (parsed.status === \"ambiguous\") {\n return {\n status: \"ambiguous\",\n artifactPath,\n message: parsed.summary,\n };\n }\n\n return {\n status: \"resolved\",\n artifactPath,\n files: parsed.files,\n };\n}\n\nconst CONFLICT_MARKER_PATTERN = /<<<<<<<|=======|>>>>>>>/m;\n\nexport async function hasUnresolvedConflictMarkers(\n worktreePath: string,\n files: string[]\n): Promise<boolean> {\n for (const file of files) {\n const filePath = join(worktreePath, file);\n try {\n const content = readFileSync(filePath, \"utf-8\");\n if (CONFLICT_MARKER_PATTERN.test(content)) {\n return true;\n }\n } catch {\n // File not found or unreadable — skip\n }\n }\n return false;\n}\n\nexport type ConflictResolutionLoopResult =\n | { status: \"completed\"; attempts: number }\n | { status: \"ambiguous\"; attempts: number; message: string }\n | { status: \"failed\"; attempts: number; message: string }\n | { status: \"exhausted\"; attempts: number; message: string };\n\nexport async function runConflictResolutionLoop(\n options: Omit<\n RunConflictResolutionOnceOptions,\n \"conflictedPaths\" | \"attempt\"\n > & {\n maxAttempts: number;\n initialConflictedPaths: string[];\n }\n): Promise<ConflictResolutionLoopResult> {\n const { worktreePath, maxAttempts, logger, initialConflictedPaths } = options;\n let attempt = 0;\n let conflictedPaths = initialConflictedPaths;\n\n while (attempt < maxAttempts && conflictedPaths.length > 0) {\n attempt++;\n\n const crResult = await runConflictResolutionOnce({\n ...options,\n conflictedPaths,\n attempt,\n });\n\n if (crResult.status !== \"resolved\") {\n const message =\n crResult.status === \"ambiguous\"\n ? crResult.message\n : (crResult.message ?? \"Conflict resolution agent execution failed\");\n return { status: crResult.status, attempts: attempt, message };\n }\n\n const markersRemain = await hasUnresolvedConflictMarkers(\n worktreePath,\n conflictedPaths\n );\n if (markersRemain) {\n return {\n status: \"ambiguous\",\n attempts: attempt,\n message:\n \"Conflict resolution agent resolved artifact but conflict markers remain in files\",\n };\n }\n\n await execCapture(\"git\", [\"add\", ...conflictedPaths], {\n cwd: worktreePath,\n logger,\n label: \"git add conflicted paths\",\n });\n\n try {\n await execCapture(\"git\", [\"rebase\", \"--continue\"], {\n cwd: worktreePath,\n logger,\n label: \"git rebase --continue\",\n });\n conflictedPaths = [];\n } catch (error) {\n const statusResult = await execCapture(\"git\", [\"status\", \"--porcelain\"], {\n cwd: worktreePath,\n logger,\n label: \"git status\",\n });\n conflictedPaths = statusResult.stdout\n .split(\"\\n\")\n .filter((line) => /^(AA|DD|UU|AU|UA|DU|UD)\\s/.test(line))\n .map((line) => line.slice(3).trim())\n .filter(Boolean);\n\n if (conflictedPaths.length === 0) {\n const rebaseErrorMessage =\n error instanceof Error ? error.message : String(error);\n return {\n status: \"failed\",\n attempts: attempt,\n message: `git rebase --continue failed with no remaining conflicts: ${rebaseErrorMessage}`,\n };\n }\n }\n }\n\n if (conflictedPaths.length > 0) {\n return {\n status: \"exhausted\",\n attempts: attempt,\n message: `Conflict resolution maxAttempts (${maxAttempts}) exhausted with remaining conflicts`,\n };\n }\n\n return { status: \"completed\", attempts: attempt };\n}\n","export type ConflictResolutionArtifactStatus = \"resolved\" | \"ambiguous\";\n\nexport interface ConflictResolutionVerificationRow {\n command: string;\n result: string;\n notes: string;\n}\n\nexport interface ConflictResolutionArtifact {\n status: ConflictResolutionArtifactStatus;\n summary: string;\n files: string[];\n verification?: ConflictResolutionVerificationRow[];\n raw: string;\n}\n\nexport class ConflictResolutionArtifactProtocolError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ConflictResolutionArtifactProtocolError\";\n }\n}\n\nconst VALID_STATUSES: ConflictResolutionArtifactStatus[] = [\n \"resolved\",\n \"ambiguous\",\n];\n\nconst SECTION_HEADING_PATTERN = /^## (Status|Summary|Files|Verification)\\s*$/gm;\n\ninterface SectionMatch {\n heading: \"Status\" | \"Summary\" | \"Files\" | \"Verification\";\n startIndex: number;\n endIndex: number;\n}\n\nfunction extractSections(output: string): SectionMatch[] {\n const sections: SectionMatch[] = [];\n let match: RegExpExecArray | null;\n const re = new RegExp(SECTION_HEADING_PATTERN);\n while ((match = re.exec(output)) !== null) {\n const heading = match[1] as \"Status\" | \"Summary\" | \"Files\" | \"Verification\";\n sections.push({\n heading,\n startIndex: match.index,\n endIndex: match.index + match[0].length,\n });\n }\n return sections;\n}\n\nfunction contentAfter(\n output: string,\n sections: SectionMatch[],\n section: SectionMatch\n): string {\n const index = sections.indexOf(section);\n const nextSection = sections[index + 1];\n const start = section.endIndex;\n const end = nextSection?.startIndex ?? output.length;\n return output.slice(start, end).trim();\n}\n\nfunction extractMarker(output: string): string | null {\n const matches = output.matchAll(\n /<conflict-resolution>\\s*(resolved|ambiguous)\\s*<\\/conflict-resolution>/g\n );\n const results = Array.from(matches);\n if (results.length > 1) {\n throw new ConflictResolutionArtifactProtocolError(\n \"Duplicate <conflict-resolution>...</conflict-resolution> markers\"\n );\n }\n return results.length === 1 ? results[0][1] : null;\n}\n\nfunction parseFileList(filesContent: string): string[] {\n return filesContent\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter((line) => line.startsWith(\"- \"))\n .map((line) => {\n const rest = line.slice(2).trim();\n const codeMatch = rest.match(/^`([^`]+)`/);\n return codeMatch ? codeMatch[1] : rest;\n });\n}\n\nfunction parseVerificationTable(\n content: string\n): ConflictResolutionVerificationRow[] {\n const lines = content\n .split(\"\\n\")\n .map((l) => l.trim())\n .filter(Boolean);\n const tableLines = lines.filter((l) => l.startsWith(\"|\") && l.endsWith(\"|\"));\n\n // index 0 = heading row, index 1 = separator row, index 2+ = data rows\n const dataRows = tableLines.slice(2);\n\n return dataRows.map((row) => {\n const cells = row\n .split(\"|\")\n .slice(1, -1)\n .map((c) => c.trim());\n return {\n command: cells[0] ?? \"\",\n result: cells[1] ?? \"\",\n notes: cells[2] ?? \"\",\n };\n });\n}\n\nexport function parseConflictResolutionArtifact(\n output: string\n): ConflictResolutionArtifact {\n if (!output.trim()) {\n throw new ConflictResolutionArtifactProtocolError(\n \"Empty conflict resolution artifact output\"\n );\n }\n\n const sections = extractSections(output);\n\n const statusSections = sections.filter((s) => s.heading === \"Status\");\n const summarySections = sections.filter((s) => s.heading === \"Summary\");\n const filesSections = sections.filter((s) => s.heading === \"Files\");\n\n if (statusSections.length > 1) {\n throw new ConflictResolutionArtifactProtocolError(\n 'Duplicate \"## Status\" sections'\n );\n }\n if (summarySections.length > 1) {\n throw new ConflictResolutionArtifactProtocolError(\n 'Duplicate \"## Summary\" sections'\n );\n }\n if (filesSections.length > 1) {\n throw new ConflictResolutionArtifactProtocolError(\n 'Duplicate \"## Files\" sections'\n );\n }\n\n const verificationSections = sections.filter(\n (s) => s.heading === \"Verification\"\n );\n\n const statusSection = statusSections[0];\n const summarySection = summarySections[0];\n const filesSection = filesSections[0];\n\n if (!statusSection) {\n throw new ConflictResolutionArtifactProtocolError(\n 'Missing required section \"## Status\"'\n );\n }\n if (!summarySection) {\n throw new ConflictResolutionArtifactProtocolError(\n 'Missing required section \"## Summary\"'\n );\n }\n if (!filesSection) {\n throw new ConflictResolutionArtifactProtocolError(\n 'Missing required section \"## Files\"'\n );\n }\n\n const statusRaw = contentAfter(output, sections, statusSection);\n const summary = contentAfter(output, sections, summarySection);\n const filesContent = contentAfter(output, sections, filesSection);\n\n if (!statusRaw) {\n throw new ConflictResolutionArtifactProtocolError(\n '\"## Status\" section is empty'\n );\n }\n if (!summary) {\n throw new ConflictResolutionArtifactProtocolError(\n '\"## Summary\" section is empty'\n );\n }\n\n if (!VALID_STATUSES.includes(statusRaw as ConflictResolutionArtifactStatus)) {\n throw new ConflictResolutionArtifactProtocolError(\n `Unsupported status \"${statusRaw}\". Allowed statuses: ${VALID_STATUSES.join(\", \")}`\n );\n }\n\n const markerStatus = extractMarker(output);\n if (!markerStatus) {\n throw new ConflictResolutionArtifactProtocolError(\n \"Missing <conflict-resolution>...</conflict-resolution> marker\"\n );\n }\n\n if (markerStatus !== statusRaw) {\n throw new ConflictResolutionArtifactProtocolError(\n `Conflict resolution status \"${statusRaw}\" does not match marker \"${markerStatus}\"`\n );\n }\n\n let verification: ConflictResolutionVerificationRow[] | undefined;\n if (verificationSections.length > 0) {\n const verificationContent = contentAfter(\n output,\n sections,\n verificationSections[0]\n );\n verification = parseVerificationTable(verificationContent);\n }\n\n return {\n status: statusRaw as ConflictResolutionArtifactStatus,\n summary,\n files: parseFileList(filesContent),\n verification,\n raw: output,\n };\n}\n","import { createHash } from \"node:crypto\";\nimport { execSync } from \"node:child_process\";\nimport { existsSync, readdirSync, readFileSync } from \"node:fs\";\nimport { isAbsolute, join, resolve } from \"node:path\";\nimport {\n parseReviewVerdict,\n ReviewVerdictProtocolError,\n} from \"../pr/review-verdict\";\nimport {\n extractLatestFindingIds,\n ReviewArtifactValidationError,\n validateRefactorArtifact,\n validateReviewArtifact,\n} from \"./review\";\nimport {\n parsePrDescription,\n PrDescriptionProtocolError,\n} from \"../pr/pr-description\";\nimport {\n ConflictResolutionArtifactProtocolError,\n parseConflictResolutionArtifact,\n} from \"../conflicts/conflict-resolution-artifact\";\nimport {\n parseRecoveryArtifact,\n type RecoveryDecision,\n RecoveryArtifactInvalid,\n validateRecoveryDecision,\n} from \"../failure-resolution/types\";\nimport { validateFinalReviewAgentOutputs } from \"../prd-run/final-review-validation\";\n\nexport type ArtifactValidationKind =\n | \"reviewer\"\n | \"refactor\"\n | \"finalizer\"\n | \"conflict-resolution\"\n | \"final-review\"\n | \"failure-resolution\"\n | \"reconciliation\"\n | \"planning-manifest\"\n | \"local-prd\"\n | \"local-issue\"\n | \"local-triage\"\n | \"local-prepare\"\n | \"issue-final-review\";\n\nexport type ArtifactValidationResult =\n | {\n ok: true;\n kind: ArtifactValidationKind;\n artifactPath: string;\n diagnostics: string[];\n }\n | {\n ok: false;\n kind: ArtifactValidationKind;\n artifactPath: string;\n reason: string;\n diagnostics: string[];\n };\n\nexport interface ValidateAgentArtifactOptions {\n kind: ArtifactValidationKind;\n artifactPath: string;\n iteration?: number;\n priorRefactorArtifactsProvided?: boolean;\n findingIds?: string[];\n latestReviewArtifactPath?: string;\n allowedDecisions?: RecoveryDecision[];\n worktreePath?: string;\n checkConflictMarkers?: boolean;\n prdRef?: string;\n checkoutBase?: string;\n reviewBase?: string;\n issueNumber?: number;\n branchName?: string;\n}\n\nconst CONFLICT_MARKER_PATTERN = /<<<<<<<|=======|>>>>>>>/m;\n\nfunction invalid(\n options: ValidateAgentArtifactOptions,\n reason: string,\n diagnostics: string[] = []\n): ArtifactValidationResult {\n return {\n ok: false,\n kind: options.kind,\n artifactPath: options.artifactPath,\n reason,\n diagnostics,\n };\n}\n\nfunction valid(\n options: ValidateAgentArtifactOptions,\n diagnostics: string[] = []\n): ArtifactValidationResult {\n return {\n ok: true,\n kind: options.kind,\n artifactPath: options.artifactPath,\n diagnostics,\n };\n}\n\nfunction readArtifact(\n options: ValidateAgentArtifactOptions\n):\n | { ok: true; content: string }\n | { ok: false; result: ArtifactValidationResult } {\n if (!existsSync(options.artifactPath)) {\n return {\n ok: false,\n result: invalid(options, `Artifact missing at ${options.artifactPath}`),\n };\n }\n\n try {\n const content = readFileSync(options.artifactPath, \"utf-8\");\n if (!content.trim()) {\n return { ok: false, result: invalid(options, \"Artifact is empty\") };\n }\n return { ok: true, content };\n } catch (error) {\n return {\n ok: false,\n result: invalid(options, \"Artifact could not be read\", [\n error instanceof Error ? error.message : String(error),\n ]),\n };\n }\n}\n\nfunction validateIssueFinalReviewArtifact(\n parsed: Record<string, unknown>,\n options: ValidateAgentArtifactOptions\n):\n | { ok: true; verdict: string }\n | { ok: false; reason: string; diagnostics: string[] } {\n const diagnostics: string[] = [];\n\n // kind\n if (parsed.kind !== \"issue-final-review\") {\n return {\n ok: false,\n reason: `Artifact kind must be \"issue-final-review\", got ${JSON.stringify(parsed.kind)}`,\n diagnostics,\n };\n }\n diagnostics.push(\"kind: issue-final-review\");\n\n // issueNumber\n if (parsed.issueNumber !== options.issueNumber) {\n return {\n ok: false,\n reason: `Artifact issueNumber ${JSON.stringify(parsed.issueNumber)} does not match expected ${options.issueNumber}`,\n diagnostics,\n };\n }\n diagnostics.push(`issueNumber: ${options.issueNumber}`);\n\n // branchName\n if (parsed.branchName !== options.branchName) {\n return {\n ok: false,\n reason: `Artifact branchName ${JSON.stringify(parsed.branchName)} does not match expected ${JSON.stringify(options.branchName)}`,\n diagnostics,\n };\n }\n diagnostics.push(`branchName: ${options.branchName}`);\n\n // verdict\n const allowedVerdicts = [\"pass\", \"needs_human_review\"];\n if (!allowedVerdicts.includes(parsed.verdict as string)) {\n return {\n ok: false,\n reason: `Verdict must be \"pass\" or \"needs_human_review\", got ${JSON.stringify(parsed.verdict)}`,\n diagnostics: [\n ...diagnostics,\n `verdict: ${JSON.stringify(parsed.verdict)}`,\n ],\n };\n }\n diagnostics.push(`verdict: ${parsed.verdict}`);\n\n // summary\n if (typeof parsed.summary !== \"string\" || parsed.summary.trim() === \"\") {\n return {\n ok: false,\n reason: \"Summary must be a non-empty string\",\n diagnostics,\n };\n }\n diagnostics.push(\"summary: present\");\n\n // changedPaths\n if (\n !Array.isArray(parsed.changedPaths) ||\n !parsed.changedPaths.every((p: unknown) => typeof p === \"string\")\n ) {\n return {\n ok: false,\n reason: \"changedPaths must be an array of strings\",\n diagnostics,\n };\n }\n for (const p of parsed.changedPaths as string[]) {\n const normalized = p.replace(/\\\\/g, \"/\");\n const segments = normalized.split(\"/\");\n if (\n normalized.trim() === \"\" ||\n normalized === \".\" ||\n normalized === \"..\" ||\n isAbsolute(p) ||\n normalized.startsWith(\"/\") ||\n segments.some((segment) => segment === \"..\")\n ) {\n return {\n ok: false,\n reason: `changedPaths must not contain absolute paths or path traversal: ${p}`,\n diagnostics,\n };\n }\n }\n diagnostics.push(\n `changedPaths: ${(parsed.changedPaths as string[]).length} paths`\n );\n\n // selfRetouched\n if (typeof parsed.selfRetouched !== \"boolean\") {\n return {\n ok: false,\n reason: \"selfRetouched must be a boolean\",\n diagnostics,\n };\n }\n diagnostics.push(`selfRetouched: ${parsed.selfRetouched}`);\n\n // verification object\n const verification = parsed.verification as\n | Record<string, unknown>\n | undefined;\n if (!verification || typeof verification !== \"object\") {\n return {\n ok: false,\n reason: \"verification must be an object\",\n diagnostics,\n };\n }\n if (typeof verification.required !== \"boolean\") {\n return {\n ok: false,\n reason: \"verification.required must be a boolean\",\n diagnostics,\n };\n }\n if (typeof verification.passed !== \"boolean\") {\n return {\n ok: false,\n reason: \"verification.passed must be a boolean\",\n diagnostics,\n };\n }\n if (\n !Array.isArray(verification.commands) ||\n !verification.commands.every((c: unknown) => typeof c === \"string\")\n ) {\n return {\n ok: false,\n reason: \"verification.commands must be an array of strings\",\n diagnostics,\n };\n }\n if (typeof verification.summary !== \"string\") {\n return {\n ok: false,\n reason: \"verification.summary must be a string\",\n diagnostics,\n };\n }\n diagnostics.push(\"verification: present\");\n\n // self-retouched pass requires verification passed\n if (parsed.selfRetouched === true && parsed.verdict === \"pass\") {\n if (verification.required !== true || verification.passed !== true) {\n return {\n ok: false,\n reason:\n \"Self-retouched pass requires verification.required === true and verification.passed === true\",\n diagnostics: [\n ...diagnostics,\n `verification.required: ${verification.required}`,\n `verification.passed: ${verification.passed}`,\n ],\n };\n }\n diagnostics.push(\"self-retouched verification: valid\");\n }\n\n // needs_human_review requires needsHumanReason\n if (parsed.verdict === \"needs_human_review\") {\n if (\n typeof parsed.needsHumanReason !== \"string\" ||\n parsed.needsHumanReason.trim() === \"\"\n ) {\n return {\n ok: false,\n reason:\n \"needs_human_review verdict requires non-empty needsHumanReason\",\n diagnostics,\n };\n }\n diagnostics.push(\"needsHumanReason: present\");\n }\n\n return { ok: true, verdict: parsed.verdict as string };\n}\n\nexport function validateAgentArtifact(\n options: ValidateAgentArtifactOptions\n): ArtifactValidationResult {\n const artifact = readArtifact(options);\n if (!artifact.ok) return artifact.result;\n\n try {\n switch (options.kind) {\n case \"reviewer\": {\n const iteration = options.iteration ?? 1;\n const verdict = parseReviewVerdict(artifact.content);\n validateReviewArtifact(\n artifact.content,\n verdict,\n iteration,\n options.priorRefactorArtifactsProvided ?? false\n );\n return valid(options, [`verdict: ${verdict}`]);\n }\n\n case \"refactor\": {\n let findingIds = options.findingIds ?? [];\n if (findingIds.length === 0 && options.latestReviewArtifactPath) {\n const latestReview = readFileSync(\n options.latestReviewArtifactPath,\n \"utf-8\"\n );\n findingIds = extractLatestFindingIds(\n latestReview,\n options.iteration ?? 1\n );\n }\n validateRefactorArtifact(options.artifactPath, findingIds);\n return valid(options, [\n `findingIds: ${findingIds.join(\", \") || \"none\"}`,\n ]);\n }\n\n case \"finalizer\": {\n const parsed = parsePrDescription(artifact.content);\n return valid(options, [`title: ${parsed.title}`]);\n }\n\n case \"conflict-resolution\": {\n const parsed = parseConflictResolutionArtifact(artifact.content);\n if (\n options.checkConflictMarkers !== false &&\n parsed.status === \"resolved\"\n ) {\n const base = options.worktreePath ?? process.cwd();\n const filesWithMarkers = parsed.files.filter((file) => {\n const filePath = resolve(base, file);\n try {\n return CONFLICT_MARKER_PATTERN.test(\n readFileSync(filePath, \"utf-8\")\n );\n } catch {\n return false;\n }\n });\n if (filesWithMarkers.length > 0) {\n return invalid(\n options,\n \"Conflict resolution artifact is resolved but conflict markers remain\",\n filesWithMarkers.map((file) => `marker remains: ${file}`)\n );\n }\n }\n return valid(options, [`status: ${parsed.status}`]);\n }\n\n // QUARANTINED: Retained for Issue Final Review artifact validation via\n // `runPrdRunValidateFinalReviewCommand`. Remove when Issue Final Review\n // is migrated to its own dedicated validator kind.\n case \"final-review\": {\n if (!options.prdRef || !options.checkoutBase || !options.reviewBase) {\n return invalid(\n options,\n \"Final Review artifact validation requires --prd-ref, --checkout-base, and --review-base.\"\n );\n }\n const result = validateFinalReviewAgentOutputs({\n artifactPath: options.artifactPath,\n context: {\n prdRef: options.prdRef,\n prdBranch: options.checkoutBase,\n mergeBase: options.reviewBase,\n },\n });\n if (!result.ok) {\n return invalid(options, result.reason, result.diagnostics);\n }\n return valid(options, [`verdict: ${result.artifact.verdict}`]);\n }\n\n case \"issue-final-review\": {\n if (options.issueNumber === undefined || !options.branchName) {\n return invalid(\n options,\n \"Issue Final Review artifact validation requires --issue-number and --branch-name.\"\n );\n }\n const parsed = JSON.parse(artifact.content);\n if (\n parsed === null ||\n typeof parsed !== \"object\" ||\n Array.isArray(parsed)\n ) {\n return invalid(\n options,\n `Artifact must be a JSON object, got ${Array.isArray(parsed) ? \"array\" : parsed === null ? \"null\" : typeof parsed}`\n );\n }\n const result = validateIssueFinalReviewArtifact(parsed, options);\n if (!result.ok) {\n return invalid(options, result.reason, result.diagnostics);\n }\n return valid(options, [`verdict: ${result.verdict}`]);\n }\n\n case \"failure-resolution\": {\n const parsed = parseRecoveryArtifact(\n artifact.content,\n options.artifactPath\n );\n if (options.allowedDecisions && options.allowedDecisions.length > 0) {\n const decision = validateRecoveryDecision(\n parsed,\n options.allowedDecisions\n );\n if (!decision.valid) {\n return invalid(\n options,\n decision.reason ?? \"Recovery decision invalid\"\n );\n }\n }\n return valid(options, [`decision: ${parsed.json.recoveryDecision}`]);\n }\n\n case \"reconciliation\":\n case \"planning-manifest\":\n return invalid(\n options,\n `Artifact kind \"${options.kind}\" has been removed from PRD Run validation`\n );\n\n case \"local-prd\":\n case \"local-issue\":\n case \"local-triage\":\n return invalid(\n options,\n `Local artifact kind must be validated through runLocalValidateArtifactCommand`\n );\n\n case \"local-prepare\":\n return invalid(\n options,\n `Artifact kind \"${options.kind}\" has been removed from PRD Run validation`\n );\n }\n } catch (error) {\n if (\n error instanceof ReviewArtifactValidationError ||\n error instanceof ReviewVerdictProtocolError ||\n error instanceof PrDescriptionProtocolError ||\n error instanceof ConflictResolutionArtifactProtocolError ||\n error instanceof RecoveryArtifactInvalid ||\n error instanceof Error\n ) {\n return invalid(options, error.message);\n }\n throw error;\n }\n}\n\nexport function runValidateArtifactCommand(options: {\n kind: ArtifactValidationKind;\n artifactPath: string;\n repoRoot: string;\n iteration?: number;\n priorRefactorArtifactsProvided?: boolean;\n findingIds?: string[];\n latestReviewArtifactPath?: string;\n allowedDecisions?: RecoveryDecision[];\n checkConflictMarkers?: boolean;\n prdRef?: string;\n checkoutBase?: string;\n reviewBase?: string;\n issueNumber?: number;\n branchName?: string;\n}): ArtifactValidationResult {\n const artifactPath = resolve(options.repoRoot, options.artifactPath);\n const latestReviewArtifactPath = options.latestReviewArtifactPath\n ? resolve(options.repoRoot, options.latestReviewArtifactPath)\n : undefined;\n\n return validateAgentArtifact({\n ...options,\n artifactPath,\n latestReviewArtifactPath,\n worktreePath: options.repoRoot,\n });\n}\n\nexport function runLocalValidateArtifactCommand(options: {\n kind: ArtifactValidationKind;\n artifactPath: string;\n repoRoot: string;\n extraArgs?: string[];\n}): ArtifactValidationResult {\n const resolvedPath = resolve(options.repoRoot, options.artifactPath);\n const resolvedExtra = (options.extraArgs ?? []).map((p) =>\n isAbsolute(p) ? p : resolve(options.repoRoot, p)\n );\n\n let localResult: LocalValidationResult;\n switch (options.kind) {\n case \"local-prd\":\n localResult = validateLocalPrd(resolvedPath);\n break;\n case \"local-issue\":\n localResult = validateLocalIssue(resolvedPath);\n break;\n case \"local-triage\":\n localResult = validateLocalTriage(resolvedPath, resolvedExtra);\n break;\n default:\n return {\n ok: false,\n kind: options.kind,\n artifactPath: resolvedPath,\n reason: `Unsupported local artifact kind \"${options.kind}\"`,\n diagnostics: [],\n };\n }\n\n if (localResult.ok) {\n return {\n ok: true,\n kind: options.kind,\n artifactPath: resolvedPath,\n diagnostics: [],\n };\n }\n\n const diagnostics: string[] = [];\n if (localResult.gate) diagnostics.push(`gate: ${localResult.gate}`);\n if (localResult.failureCode)\n diagnostics.push(`failureCode: ${localResult.failureCode}`);\n if (localResult.offendingPath)\n diagnostics.push(`offendingPath: ${localResult.offendingPath}`);\n if (localResult.message) diagnostics.push(localResult.message);\n\n return {\n ok: false,\n kind: options.kind,\n artifactPath: resolvedPath,\n reason: localResult.message ?? \"Validation failed\",\n diagnostics,\n };\n}\n\n// ---- Local artifact validation foundation ----\n\nexport type LocalValidationFailureCode =\n | \"missing_store\"\n | \"invalid_prd_artifact\"\n | \"invalid_issue_artifact\"\n | \"linkage_mismatch\"\n | \"triage_inconsistent\"\n | \"branch_unsafe\"\n | \"dirty_worktree\"\n | \"stale_projection\"\n | \"missing_projection\"\n | \"body_hash_mismatch\";\n\nexport interface LocalValidationResult {\n ok: boolean;\n gate?: string;\n failureCode?: LocalValidationFailureCode;\n offendingPath?: string;\n message?: string;\n}\n\n// ---- Local prepare validation ----\n\nexport type LocalPrepareGate =\n | \"store_shape\"\n | \"prd_json_completeness\"\n | \"issue_json_completeness\"\n | \"parent_child_linkage\"\n | \"triage_consistency\"\n | \"branch_safety\"\n | \"projection_freshness\";\n\nexport interface LocalPrepareOptions {\n storePath?: string;\n repoRoot?: string;\n}\n\nfunction getLocalPrepareStorePath(\n repoRoot: string,\n prdPath: string\n): string | undefined {\n const prd = readLocalArtifact<Record<string, unknown>>(prdPath);\n if (!prd.ok || !prd.data || typeof prd.data.id !== \"string\") {\n return undefined;\n }\n return join(repoRoot, \".pourkit\", \"local-prd-runs\", prd.data.id);\n}\n\nexport function validateLocalPrepare(\n prdPath: string,\n issuePaths: string[],\n options?: LocalPrepareOptions\n): LocalValidationResult {\n // Gate 1: Store shape\n let storePath: string;\n if (options?.storePath) {\n storePath = options.storePath;\n } else {\n const prdRaw = readLocalArtifact<Record<string, unknown>>(prdPath);\n if (!prdRaw.ok || !prdRaw.data) {\n return {\n ok: false,\n gate: \"store_shape\",\n failureCode: \"missing_store\",\n offendingPath: prdPath,\n message: \"Cannot read PRD artifact to determine store path\",\n };\n }\n const prdId = prdRaw.data.id;\n if (typeof prdId !== \"string\") {\n return {\n ok: false,\n gate: \"store_shape\",\n failureCode: \"missing_store\",\n message: \"PRD id must be a string to determine store path\",\n };\n }\n storePath = `.pourkit/local-prd-runs/${prdId}/`;\n }\n\n if (!existsSync(storePath)) {\n return {\n ok: false,\n gate: \"store_shape\",\n failureCode: \"missing_store\",\n offendingPath: storePath,\n message: `Local PRD Run Store not found at ${storePath}`,\n };\n }\n\n const issuesStore = join(storePath, \"issues\");\n if (!existsSync(issuesStore)) {\n return {\n ok: false,\n gate: \"store_shape\",\n failureCode: \"missing_store\",\n offendingPath: issuesStore,\n message: `Store at ${storePath} is missing expected subdirectory: issues`,\n };\n }\n\n const prdsStore = join(storePath, \"prds\");\n if (!existsSync(prdsStore)) {\n return {\n ok: false,\n gate: \"store_shape\",\n failureCode: \"missing_store\",\n offendingPath: prdsStore,\n message: `Store at ${storePath} is missing expected subdirectory: prds`,\n };\n }\n\n // Gate 2: PRD JSON completeness\n const prdResult = validateLocalPrd(prdPath);\n if (!prdResult.ok) {\n return { ...prdResult, gate: \"prd_json_completeness\" };\n }\n\n // Gate 3: Issue JSON completeness\n for (const issuePath of issuePaths) {\n const issueResult = validateLocalIssue(issuePath);\n if (!issueResult.ok) {\n return { ...issueResult, gate: \"issue_json_completeness\" };\n }\n }\n\n // Gate 4: Parent/child linkage\n const prd = readLocalArtifact<Record<string, unknown>>(prdPath);\n if (!prd.ok || !prd.data) {\n return {\n ok: false,\n gate: \"parent_child_linkage\",\n failureCode: \"linkage_mismatch\",\n offendingPath: prdPath,\n message: \"Cannot read PRD for linkage check\",\n };\n }\n\n const prdId = prd.data.id as string;\n const childIssueIds = (prd.data.childIssueIds as string[]) ?? [];\n\n const issueDataMap = new Map<string, Record<string, unknown>>();\n for (const issuePath of issuePaths) {\n const issue = readLocalArtifact<Record<string, unknown>>(issuePath);\n if (!issue.ok || !issue.data) {\n return {\n ok: false,\n gate: \"parent_child_linkage\",\n failureCode: \"linkage_mismatch\",\n offendingPath: issuePath,\n message: `Cannot read Issue for linkage check: ${issue.message}`,\n };\n }\n const issueId = issue.data.id as string;\n issueDataMap.set(issueId, issue.data);\n\n if (issue.data.parentPrdId !== prdId) {\n return {\n ok: false,\n gate: \"parent_child_linkage\",\n failureCode: \"linkage_mismatch\",\n offendingPath: issuePath,\n message: `Issue ${issueId} parentPrdId \"${issue.data.parentPrdId}\" does not match PRD id \"${prdId}\"`,\n };\n }\n }\n\n for (const childId of childIssueIds) {\n if (!issueDataMap.has(childId)) {\n return {\n ok: false,\n gate: \"parent_child_linkage\",\n failureCode: \"linkage_mismatch\",\n message: `PRD childIssueIds references \"${childId}\" but no matching Issue artifact found`,\n };\n }\n }\n\n for (const [issueId, issueData] of issueDataMap) {\n const deps = (issueData.dependencyIssueIds as string[]) ?? [];\n for (const depId of deps) {\n if (!issueDataMap.has(depId)) {\n return {\n ok: false,\n gate: \"parent_child_linkage\",\n failureCode: \"linkage_mismatch\",\n message: `Issue ${issueId} dependency \"${depId}\" not found in Issue set`,\n };\n }\n }\n }\n\n const storeIssueIds: string[] = [];\n try {\n const entries = readdirSync(issuesStore);\n for (const entry of entries) {\n if (entry.endsWith(\".json\")) {\n const issuePath = join(issuesStore, entry);\n const issue = readLocalArtifact<Record<string, unknown>>(issuePath);\n if (issue.ok && issue.data) {\n storeIssueIds.push(issue.data.id as string);\n }\n }\n }\n } catch {\n // Cannot read store directory; continue without orphan check\n }\n\n for (const storeIssueId of storeIssueIds) {\n if (!issueDataMap.has(storeIssueId)) {\n return {\n ok: false,\n gate: \"parent_child_linkage\",\n failureCode: \"linkage_mismatch\",\n message: `Issue ${storeIssueId} is an orphan: not referenced by any PRD's childIssueIds`,\n };\n }\n }\n\n // Gate 5: Triage consistency\n const triageResult = validateLocalTriage(prdPath, issuePaths);\n if (!triageResult.ok) {\n return { ...triageResult, gate: \"triage_consistency\" };\n }\n\n // Gate 6: Branch safety\n const protectedBranchNames = [\"dev\", \"next\", \"main\"];\n const barePrdPattern = /^PRD-\\d{4}$/;\n const localPrdBranchPattern = /^local\\/PRD-\\d{4}$/;\n\n const dirtyRaw = tryExecSync(\"git status --porcelain\", options?.repoRoot);\n if (dirtyRaw !== null && dirtyRaw.length > 0) {\n return {\n ok: false,\n gate: \"branch_safety\",\n failureCode: \"dirty_worktree\",\n message: \"Working tree has uncommitted changes\",\n };\n }\n\n const prdBranchData = readLocalArtifact<Record<string, unknown>>(prdPath);\n if (!prdBranchData.ok || !prdBranchData.data) {\n return {\n ok: false,\n gate: \"branch_safety\",\n failureCode: \"branch_unsafe\",\n offendingPath: prdPath,\n message: \"Cannot read PRD for branch safety check\",\n };\n }\n\n const reconciliationTarget = prdBranchData.data\n .reconciliationTarget as Record<string, unknown>;\n const localPrdBranch = reconciliationTarget.localPrdBranch as string;\n if (protectedBranchNames.includes(localPrdBranch)) {\n return {\n ok: false,\n gate: \"branch_safety\",\n failureCode: \"branch_unsafe\",\n message: `PRD localPrdBranch \"${localPrdBranch}\" is a protected branch`,\n };\n }\n if (barePrdPattern.test(localPrdBranch)) {\n return {\n ok: false,\n gate: \"branch_safety\",\n failureCode: \"branch_unsafe\",\n message: `PRD localPrdBranch \"${localPrdBranch}\" matches bare PRD-0000N pattern without local/ prefix`,\n };\n }\n if (!localPrdBranchPattern.test(localPrdBranch)) {\n return {\n ok: false,\n gate: \"branch_safety\",\n failureCode: \"branch_unsafe\",\n message: `PRD localPrdBranch \"${localPrdBranch}\" must match local/PRD-0000N pattern`,\n };\n }\n\n const branchExists = tryExecSync(\n `git branch --list ${localPrdBranch}`,\n options?.repoRoot\n );\n if (branchExists !== null && branchExists.length > 0) {\n return {\n ok: false,\n gate: \"branch_safety\",\n failureCode: \"branch_unsafe\",\n message: `PRD localPrdBranch \"${localPrdBranch}\" already exists locally`,\n };\n }\n\n const remoteExists = tryExecSync(\n `git branch -r --list origin/${localPrdBranch}`,\n options?.repoRoot\n );\n if (remoteExists !== null && remoteExists.length > 0) {\n return {\n ok: false,\n gate: \"branch_safety\",\n failureCode: \"branch_unsafe\",\n message: `PRD localPrdBranch \"${localPrdBranch}\" already exists on remote`,\n };\n }\n\n for (const issuePath of issuePaths) {\n const issue = readLocalArtifact<Record<string, unknown>>(issuePath);\n if (!issue.ok || !issue.data) {\n return {\n ok: false,\n gate: \"branch_safety\",\n failureCode: \"branch_unsafe\",\n offendingPath: issuePath,\n message: `Cannot read Issue for branch safety check: ${issue.message}`,\n };\n }\n const branchName = issue.data.branchName as string;\n\n if (protectedBranchNames.includes(branchName)) {\n return {\n ok: false,\n gate: \"branch_safety\",\n failureCode: \"branch_unsafe\",\n offendingPath: issuePath,\n message: `Issue branch \"${branchName}\" is a protected branch`,\n };\n }\n\n if (barePrdPattern.test(branchName)) {\n return {\n ok: false,\n gate: \"branch_safety\",\n failureCode: \"branch_unsafe\",\n offendingPath: issuePath,\n message: `Issue branch \"${branchName}\" matches bare PRD-0000N pattern without local/ prefix`,\n };\n }\n }\n\n // Gate 7: Projection freshness\n const prdForProjection = readLocalArtifact<Record<string, unknown>>(prdPath);\n if (prdForProjection.ok && prdForProjection.data) {\n const result = checkProjectionFreshness(\n prdForProjection.data,\n prdPath,\n options?.repoRoot\n );\n if (!result.ok) return result;\n }\n\n for (const issuePath of issuePaths) {\n const issue = readLocalArtifact<Record<string, unknown>>(issuePath);\n if (issue.ok && issue.data) {\n const result = checkProjectionFreshness(\n issue.data,\n issuePath,\n options?.repoRoot\n );\n if (!result.ok) return result;\n }\n }\n\n return { ok: true };\n}\n\nfunction tryExecSync(cmd: string, cwd?: string): string | null {\n try {\n return execSync(cmd, { cwd, stdio: [\"ignore\", \"pipe\", \"ignore\"] })\n .toString()\n .trim();\n } catch {\n return null;\n }\n}\n\nfunction checkProjectionFreshness(\n data: Record<string, unknown>,\n artifactPath: string,\n repoRoot?: string\n): LocalValidationResult {\n const bodyMarkdown = data.bodyMarkdown as string;\n const bodyContract = data.bodyContract as Record<string, unknown> | undefined;\n\n if (!bodyContract) return { ok: true };\n\n const bodyHash = bodyContract.bodyHash as string | undefined;\n if (bodyHash) {\n const computedHash = `sha256:${createHash(\"sha256\").update(bodyMarkdown, \"utf-8\").digest(\"hex\")}`;\n if (bodyHash !== computedHash) {\n return {\n ok: false,\n gate: \"projection_freshness\",\n failureCode: \"body_hash_mismatch\",\n offendingPath: artifactPath,\n message: `bodyHash \"${bodyHash}\" does not match computed SHA-256 of bodyMarkdown`,\n };\n }\n }\n\n const renderedPath = bodyContract.renderedMarkdownPath as string | undefined;\n if (!renderedPath) {\n return {\n ok: false,\n gate: \"projection_freshness\",\n failureCode: \"missing_projection\",\n offendingPath: artifactPath,\n message: \"renderedMarkdownPath is missing\",\n };\n }\n\n const renderedPathToRead = isAbsolute(renderedPath)\n ? renderedPath\n : resolve(repoRoot ?? process.cwd(), renderedPath);\n\n if (!existsSync(renderedPathToRead)) {\n return {\n ok: false,\n gate: \"projection_freshness\",\n failureCode: \"missing_projection\",\n offendingPath: renderedPathToRead,\n message: `Rendered Markdown not found at ${renderedPathToRead}`,\n };\n }\n\n const renderedContent = readFileSync(renderedPathToRead, \"utf-8\");\n if (renderedContent !== bodyMarkdown) {\n return {\n ok: false,\n gate: \"projection_freshness\",\n failureCode: \"stale_projection\",\n offendingPath: renderedPathToRead,\n message:\n \"Rendered Markdown content does not match bodyMarkdown byte-for-byte\",\n };\n }\n\n const renderedAt = bodyContract.renderedAt as string | undefined;\n if (renderedAt) {\n try {\n const parsed = new Date(renderedAt);\n if (isNaN(parsed.getTime()) || parsed.toISOString() !== renderedAt) {\n return {\n ok: false,\n gate: \"projection_freshness\",\n failureCode: \"stale_projection\",\n offendingPath: artifactPath,\n message: `renderedAt \"${renderedAt}\" is not a valid ISO 8601 timestamp`,\n };\n }\n } catch {\n return {\n ok: false,\n gate: \"projection_freshness\",\n failureCode: \"stale_projection\",\n offendingPath: artifactPath,\n message: `renderedAt \"${renderedAt}\" is not a valid ISO 8601 timestamp`,\n };\n }\n }\n\n return { ok: true };\n}\n\nexport function readLocalArtifact<T>(\n path: string,\n failureCode?: LocalValidationFailureCode\n): LocalValidationResult & { data?: T } {\n try {\n const raw = readFileSync(path, \"utf-8\");\n const parsed = JSON.parse(raw);\n if (\n parsed === null ||\n typeof parsed !== \"object\" ||\n Array.isArray(parsed)\n ) {\n return {\n ok: false,\n failureCode: failureCode ?? \"invalid_prd_artifact\",\n offendingPath: path,\n message: `Expected a JSON object, got ${Array.isArray(parsed) ? \"array\" : parsed === null ? \"null\" : typeof parsed}`,\n };\n }\n return { ok: true, data: parsed as T };\n } catch (e) {\n return {\n ok: false,\n failureCode: failureCode ?? \"invalid_prd_artifact\",\n offendingPath: path,\n message: `Failed to read or parse: ${e}`,\n };\n }\n}\n\nexport type LocalPrdStatus =\n | \"draft\"\n | \"ready\"\n | \"prepared\"\n | \"running\"\n | \"final-review\"\n | \"reconciliation\"\n | \"complete\"\n | \"blocked\";\n\nconst VALID_LOCAL_PRD_STATUSES: LocalPrdStatus[] = [\n \"draft\",\n \"ready\",\n \"prepared\",\n \"running\",\n \"final-review\",\n \"reconciliation\",\n \"complete\",\n \"blocked\",\n];\n\nconst TO_PRD_REQUIRED_HEADINGS = [\n \"Problem Statement\",\n \"Solution\",\n \"Plan Documents\",\n \"User Stories\",\n \"Implementation Decisions\",\n \"Testing Decisions\",\n \"Out of Scope\",\n \"Further Notes\",\n];\n\nconst TO_ISSUES_REQUIRED_HEADINGS = [\n \"Parent\",\n \"Plan Documents\",\n \"Source of truth for behavior\",\n \"What to build\",\n \"High-level explanation\",\n \"Affected code paths\",\n \"Exploration evidence\",\n \"Contract decisions\",\n \"Execution path matrix\",\n \"Regression contract (CRITICAL)\",\n \"Step-by-step implementation\",\n \"Contracts / interfaces\",\n \"Edge cases\",\n \"Validation\",\n \"Out of scope\",\n \"Priority\",\n \"Acceptance criteria\",\n \"Blocked by\",\n];\n\nconst VALID_LOCAL_ISSUE_STATUSES = [\n \"needs-triage\",\n \"ready-for-agent\",\n \"blocked\",\n \"ready-for-human\",\n \"wontfix\",\n \"running\",\n \"complete\",\n] as const;\n\nconst VALID_ISSUE_TRIAGE_LABELS = [\n \"needs-triage\",\n \"ready-for-agent\",\n \"blocked\",\n \"ready-for-human\",\n \"wontfix\",\n \"running\",\n \"complete\",\n];\n\nconst VALID_ISSUE_CATEGORY_LABELS = [\"bug\", \"enhancement\"];\n\nconst VALID_ISSUE_TYPE_LABELS = [\n \"type:bugfix\",\n \"type:infra\",\n \"type:feature\",\n \"type:polish\",\n \"type:refactor\",\n];\n\nconst ISSUE_RECEIPT_FIELDS = [\n \"createdAt\",\n \"updatedAt\",\n \"preparedAt\",\n \"startedAt\",\n \"completedAt\",\n \"reviewedAt\",\n \"mergedAt\",\n];\n\nconst ISSUE_PROJECTION_FIELDS = [\n \"issueNumber\",\n \"issueUrl\",\n \"publishedAt\",\n \"syncedAt\",\n];\n\nfunction getMarkdownHeadings(markdown: string): string[] {\n const headingRegex = /^## (.+)$/gm;\n const headings: string[] = [];\n let match: RegExpExecArray | null;\n while ((match = headingRegex.exec(markdown)) !== null) {\n headings.push(match[1].trim());\n }\n return headings;\n}\n\nexport function validateLocalPrd(path: string): LocalValidationResult {\n const parsed = readLocalArtifact<Record<string, unknown>>(path);\n if (!parsed.ok) return parsed;\n const data = parsed.data!;\n\n if (data.schemaVersion !== 1) {\n return {\n ok: false,\n failureCode: \"invalid_prd_artifact\",\n offendingPath: path,\n message: \"schemaVersion must be 1\",\n };\n }\n\n if (data.kind !== \"prd\") {\n return {\n ok: false,\n failureCode: \"invalid_prd_artifact\",\n offendingPath: path,\n message: \"kind must be prd\",\n };\n }\n\n if (typeof data.id !== \"string\" || data.id.trim() === \"\") {\n return {\n ok: false,\n failureCode: \"invalid_prd_artifact\",\n offendingPath: path,\n message: \"id must be a non-empty string\",\n };\n }\n\n if (typeof data.title !== \"string\" || data.title.trim() === \"\") {\n return {\n ok: false,\n failureCode: \"invalid_prd_artifact\",\n offendingPath: path,\n message: \"title must be a non-empty string\",\n };\n }\n\n if (\n typeof data.status !== \"string\" ||\n !VALID_LOCAL_PRD_STATUSES.includes(data.status as LocalPrdStatus)\n ) {\n return {\n ok: false,\n failureCode: \"invalid_prd_artifact\",\n offendingPath: path,\n message: `status must be one of: ${VALID_LOCAL_PRD_STATUSES.join(\", \")}`,\n };\n }\n\n if (!Array.isArray(data.childIssueIds)) {\n return {\n ok: false,\n failureCode: \"invalid_prd_artifact\",\n offendingPath: path,\n message: \"childIssueIds must be an array\",\n };\n }\n\n if (!Array.isArray(data.linkedDecisionIds)) {\n return {\n ok: false,\n failureCode: \"invalid_prd_artifact\",\n offendingPath: path,\n message: \"linkedDecisionIds must be an array\",\n };\n }\n\n if (\n !data.reconciliationTarget ||\n typeof data.reconciliationTarget !== \"object\"\n ) {\n return {\n ok: false,\n failureCode: \"invalid_prd_artifact\",\n offendingPath: path,\n message: \"reconciliationTarget must be an object\",\n };\n }\n\n const reconciliationTarget = data.reconciliationTarget as Record<\n string,\n unknown\n >;\n if (\n typeof reconciliationTarget.localPrdBranch !== \"string\" ||\n reconciliationTarget.localPrdBranch.trim() === \"\"\n ) {\n return {\n ok: false,\n failureCode: \"invalid_prd_artifact\",\n offendingPath: path,\n message: \"reconciliationTarget.localPrdBranch must be a non-empty string\",\n };\n }\n\n if (\n typeof reconciliationTarget.integrationBranch !== \"string\" ||\n reconciliationTarget.integrationBranch.trim() === \"\"\n ) {\n return {\n ok: false,\n failureCode: \"invalid_prd_artifact\",\n offendingPath: path,\n message:\n \"reconciliationTarget.integrationBranch must be a non-empty string\",\n };\n }\n\n if (\n typeof data.bodyMarkdown !== \"string\" ||\n data.bodyMarkdown.trim() === \"\"\n ) {\n return {\n ok: false,\n failureCode: \"invalid_prd_artifact\",\n offendingPath: path,\n message: \"bodyMarkdown must be a non-empty string\",\n };\n }\n\n if (!data.bodyContract || typeof data.bodyContract !== \"object\") {\n return {\n ok: false,\n failureCode: \"invalid_prd_artifact\",\n offendingPath: path,\n message: \"bodyContract must be an object\",\n };\n }\n\n const bodyContract = data.bodyContract as Record<string, unknown>;\n if (bodyContract.contract !== \"to-prd\") {\n return {\n ok: false,\n failureCode: \"invalid_prd_artifact\",\n offendingPath: path,\n message: 'bodyContract.contract must be \"to-prd\"',\n };\n }\n\n if (!Array.isArray(bodyContract.requiredHeadings)) {\n return {\n ok: false,\n failureCode: \"invalid_prd_artifact\",\n offendingPath: path,\n message: \"bodyContract.requiredHeadings must be an array\",\n };\n }\n\n const requiredHeadings = bodyContract.requiredHeadings as string[];\n const missingHeadings = TO_PRD_REQUIRED_HEADINGS.filter(\n (h) => !requiredHeadings.includes(h)\n );\n if (missingHeadings.length > 0) {\n return {\n ok: false,\n failureCode: \"invalid_prd_artifact\",\n offendingPath: path,\n message: `bodyContract.requiredHeadings missing: ${missingHeadings.join(\", \")}`,\n };\n }\n\n const markdownHeadings = getMarkdownHeadings(data.bodyMarkdown as string);\n const missingInMarkdown = TO_PRD_REQUIRED_HEADINGS.filter(\n (h) => !markdownHeadings.includes(h)\n );\n if (missingInMarkdown.length > 0) {\n return {\n ok: false,\n failureCode: \"invalid_prd_artifact\",\n offendingPath: path,\n message: `bodyMarkdown missing headings: ${missingInMarkdown.join(\", \")}`,\n };\n }\n\n if (!data.receipts || typeof data.receipts !== \"object\") {\n return {\n ok: false,\n failureCode: \"invalid_prd_artifact\",\n offendingPath: path,\n message: \"receipts must be an object\",\n };\n }\n\n const receipts = data.receipts as Record<string, unknown>;\n const expectedReceiptFields = [\n \"createdAt\",\n \"updatedAt\",\n \"preparedAt\",\n \"startedAt\",\n \"finalReviewedAt\",\n \"reconciledAt\",\n \"completedAt\",\n ];\n for (const field of expectedReceiptFields) {\n if (!(field in receipts)) {\n return {\n ok: false,\n failureCode: \"invalid_prd_artifact\",\n offendingPath: path,\n message: `receipts.${field} is missing`,\n };\n }\n }\n\n if (!data.githubProjection || typeof data.githubProjection !== \"object\") {\n return {\n ok: false,\n failureCode: \"invalid_prd_artifact\",\n offendingPath: path,\n message: \"githubProjection must be an object\",\n };\n }\n\n const githubProjection = data.githubProjection as Record<string, unknown>;\n const expectedProjectionFields = [\n \"issueNumber\",\n \"issueUrl\",\n \"publishedAt\",\n \"syncedAt\",\n ];\n for (const field of expectedProjectionFields) {\n if (!(field in githubProjection)) {\n return {\n ok: false,\n failureCode: \"invalid_prd_artifact\",\n offendingPath: path,\n message: `githubProjection.${field} is missing`,\n };\n }\n }\n\n return { ok: true };\n}\n\nexport function validateLocalIssue(path: string): LocalValidationResult {\n const parsed = readLocalArtifact<Record<string, unknown>>(path);\n if (!parsed.ok) {\n return {\n ok: false,\n failureCode: \"invalid_issue_artifact\",\n offendingPath: path,\n message: parsed.message,\n };\n }\n const data = parsed.data!;\n\n if (data.schemaVersion !== 1) {\n return {\n ok: false,\n failureCode: \"invalid_issue_artifact\",\n offendingPath: path,\n message: \"schemaVersion must be 1\",\n };\n }\n\n if (data.kind !== \"issue\") {\n return {\n ok: false,\n failureCode: \"invalid_issue_artifact\",\n offendingPath: path,\n message: 'kind must be \"issue\"',\n };\n }\n\n if (typeof data.id !== \"string\" || data.id.trim() === \"\") {\n return {\n ok: false,\n failureCode: \"invalid_issue_artifact\",\n offendingPath: path,\n message: \"id must be a non-empty string\",\n };\n }\n\n if (\n typeof data.parentPrdId !== \"string\" ||\n !/^PRD-\\d{4}$/.test(data.parentPrdId.trim())\n ) {\n return {\n ok: false,\n failureCode: \"invalid_issue_artifact\",\n offendingPath: path,\n message: \"parentPrdId must match PRD-0000N format\",\n };\n }\n\n if (typeof data.title !== \"string\" || data.title.trim() === \"\") {\n return {\n ok: false,\n failureCode: \"invalid_issue_artifact\",\n offendingPath: path,\n message: \"title must be a non-empty string\",\n };\n }\n\n if (\n typeof data.status !== \"string\" ||\n !(VALID_LOCAL_ISSUE_STATUSES as readonly string[]).includes(data.status)\n ) {\n return {\n ok: false,\n failureCode: \"invalid_issue_artifact\",\n offendingPath: path,\n message: `status must be one of: ${VALID_LOCAL_ISSUE_STATUSES.join(\", \")}`,\n };\n }\n\n if (!Array.isArray(data.labels)) {\n return {\n ok: false,\n failureCode: \"invalid_issue_artifact\",\n offendingPath: path,\n message: \"labels must be an array\",\n };\n }\n\n const labels = data.labels as string[];\n const triageLabel = labels.find((l) => VALID_ISSUE_TRIAGE_LABELS.includes(l));\n const categoryLabel = labels.find((l) =>\n VALID_ISSUE_CATEGORY_LABELS.includes(l)\n );\n const typeLabel = labels.find((l) => VALID_ISSUE_TYPE_LABELS.includes(l));\n const unknownLabels = labels.filter(\n (l) =>\n !VALID_ISSUE_TRIAGE_LABELS.includes(l) &&\n !VALID_ISSUE_CATEGORY_LABELS.includes(l) &&\n !VALID_ISSUE_TYPE_LABELS.includes(l)\n );\n\n if (!triageLabel) {\n return {\n ok: false,\n failureCode: \"invalid_issue_artifact\",\n offendingPath: path,\n message: `labels must include one triage-state label from: ${VALID_ISSUE_TRIAGE_LABELS.join(\", \")}`,\n };\n }\n if (!categoryLabel) {\n return {\n ok: false,\n failureCode: \"invalid_issue_artifact\",\n offendingPath: path,\n message: `labels must include one category label from: ${VALID_ISSUE_CATEGORY_LABELS.join(\", \")}`,\n };\n }\n if (!typeLabel) {\n return {\n ok: false,\n failureCode: \"invalid_issue_artifact\",\n offendingPath: path,\n message: `labels must include one type label from: ${VALID_ISSUE_TYPE_LABELS.join(\", \")}`,\n };\n }\n\n if (\n data.status !== \"running\" &&\n data.status !== \"complete\" &&\n triageLabel !== data.status\n ) {\n return {\n ok: false,\n failureCode: \"invalid_issue_artifact\",\n offendingPath: path,\n message: `triage-state label must match status: expected \"${data.status}\", got \"${triageLabel}\"`,\n };\n }\n\n // Only one type:* label\n const typeLabels = labels.filter((l) => l.startsWith(\"type:\"));\n if (typeLabels.length > 1) {\n return {\n ok: false,\n failureCode: \"invalid_issue_artifact\",\n offendingPath: path,\n message: \"more than one type:* label found\",\n };\n }\n\n if (labels.length !== 3 || unknownLabels.length > 0) {\n return {\n ok: false,\n failureCode: \"invalid_issue_artifact\",\n offendingPath: path,\n message:\n \"labels must contain exactly 3 entries: one triage-state, one category, one type:*\",\n };\n }\n\n if (!Array.isArray(data.dependencyIssueIds)) {\n return {\n ok: false,\n failureCode: \"invalid_issue_artifact\",\n offendingPath: path,\n message: \"dependencyIssueIds must be an array\",\n };\n }\n\n if (\n typeof data.branchName !== \"string\" ||\n !/^local\\/PRD-\\d{4}\\/I-\\d{2}-[a-z0-9-]+$/.test(data.branchName)\n ) {\n return {\n ok: false,\n failureCode: \"invalid_issue_artifact\",\n offendingPath: path,\n message: \"branchName must match local/PRD-0000N/I-0N-slug pattern\",\n };\n }\n\n if (\n !(data.blockedReason === null || typeof data.blockedReason === \"string\")\n ) {\n return {\n ok: false,\n failureCode: \"invalid_issue_artifact\",\n offendingPath: path,\n message: \"blockedReason must be a string or null\",\n };\n }\n\n if (\n !(\n data.readyForHumanReason === null ||\n typeof data.readyForHumanReason === \"string\"\n )\n ) {\n return {\n ok: false,\n failureCode: \"invalid_issue_artifact\",\n offendingPath: path,\n message: \"readyForHumanReason must be a string or null\",\n };\n }\n\n if (\n typeof data.bodyMarkdown !== \"string\" ||\n data.bodyMarkdown.trim() === \"\"\n ) {\n return {\n ok: false,\n failureCode: \"invalid_issue_artifact\",\n offendingPath: path,\n message: \"bodyMarkdown must be a non-empty string\",\n };\n }\n\n if (!data.bodyContract || typeof data.bodyContract !== \"object\") {\n return {\n ok: false,\n failureCode: \"invalid_issue_artifact\",\n offendingPath: path,\n message: \"bodyContract must be an object\",\n };\n }\n\n const bodyContract = data.bodyContract as Record<string, unknown>;\n if (bodyContract.contract !== \"to-issues\") {\n return {\n ok: false,\n failureCode: \"invalid_issue_artifact\",\n offendingPath: path,\n message: 'bodyContract.contract must be \"to-issues\"',\n };\n }\n\n if (!Array.isArray(bodyContract.requiredHeadings)) {\n return {\n ok: false,\n failureCode: \"invalid_issue_artifact\",\n offendingPath: path,\n message: \"bodyContract.requiredHeadings must be an array\",\n };\n }\n\n const requiredHeadings = bodyContract.requiredHeadings as string[];\n const missingHeadings = TO_ISSUES_REQUIRED_HEADINGS.filter(\n (h) => !requiredHeadings.includes(h)\n );\n if (missingHeadings.length > 0) {\n return {\n ok: false,\n failureCode: \"invalid_issue_artifact\",\n offendingPath: path,\n message: `bodyContract.requiredHeadings missing: ${missingHeadings.join(\", \")}`,\n };\n }\n\n const markdownHeadings = getMarkdownHeadings(data.bodyMarkdown as string);\n const missingInMarkdown = TO_ISSUES_REQUIRED_HEADINGS.filter(\n (h) => !markdownHeadings.includes(h)\n );\n if (missingInMarkdown.length > 0) {\n return {\n ok: false,\n failureCode: \"invalid_issue_artifact\",\n offendingPath: path,\n message: `bodyMarkdown missing headings: ${missingInMarkdown.join(\", \")}`,\n };\n }\n\n if (!data.receipts || typeof data.receipts !== \"object\") {\n return {\n ok: false,\n failureCode: \"invalid_issue_artifact\",\n offendingPath: path,\n message: \"receipts must be an object\",\n };\n }\n\n const receipts = data.receipts as Record<string, unknown>;\n for (const field of ISSUE_RECEIPT_FIELDS) {\n if (!(field in receipts)) {\n return {\n ok: false,\n failureCode: \"invalid_issue_artifact\",\n offendingPath: path,\n message: `receipts.${field} is missing`,\n };\n }\n }\n\n if (!data.githubProjection || typeof data.githubProjection !== \"object\") {\n return {\n ok: false,\n failureCode: \"invalid_issue_artifact\",\n offendingPath: path,\n message: \"githubProjection must be an object\",\n };\n }\n\n const githubProjection = data.githubProjection as Record<string, unknown>;\n for (const field of ISSUE_PROJECTION_FIELDS) {\n if (!(field in githubProjection)) {\n return {\n ok: false,\n failureCode: \"invalid_issue_artifact\",\n offendingPath: path,\n message: `githubProjection.${field} is missing`,\n };\n }\n }\n\n return { ok: true };\n}\n\n// ---- Reconciliation artifact validation ----\n\nexport interface ReconciliationArtifact {\n prdRef: string;\n stage: \"prdReconciliation\";\n checkoutBase: string;\n mergeBase: string;\n evidenceHash: string;\n result: \"no_changes_needed\" | \"changes_produced\" | \"blocked\";\n changedPlanningPaths: string[];\n completionArtifactPaths: string[];\n summary: string;\n diagnostics: string[];\n}\n\nexport interface ReconciliationValidationResult {\n ok: boolean;\n errors?: string[];\n}\n\nconst PRD_REF_PATTERN = /^PRD-\\d{4}$/;\nconst EVIDENCE_HASH_PATTERN = /^[0-9a-f]{64}$/;\nconst RECONCILIATION_TMP_PATH_PREFIX = \".pourkit/.tmp/reconciliation/\";\n\nexport function validateReconciliationArtifact(\n artifact: unknown\n): ReconciliationValidationResult {\n const errors: string[] = [];\n\n if (!artifact || typeof artifact !== \"object\") {\n return { ok: false, errors: [\"Artifact must be an object\"] };\n }\n\n const a = artifact as Record<string, unknown>;\n\n if (typeof a.prdRef !== \"string\" || !PRD_REF_PATTERN.test(a.prdRef)) {\n errors.push(\n `prdRef must match PRD-0000N format, got ${JSON.stringify(a.prdRef)}`\n );\n }\n\n if (a.stage !== \"prdReconciliation\") {\n errors.push(\n `stage must be \"prdReconciliation\", got ${JSON.stringify(a.stage)}`\n );\n }\n\n if (typeof a.checkoutBase !== \"string\" || a.checkoutBase.trim() === \"\") {\n errors.push(\"checkoutBase must be a non-empty string\");\n } else if (!PRD_REF_PATTERN.test(a.checkoutBase.trim())) {\n errors.push(\n `checkoutBase must match active PRD branch format PRD-0000N, got ${JSON.stringify(a.checkoutBase)}`\n );\n }\n\n if (typeof a.mergeBase !== \"string\" || a.mergeBase.trim() === \"\") {\n errors.push(\"mergeBase must be a non-empty string\");\n }\n\n if (\n typeof a.evidenceHash !== \"string\" ||\n !EVIDENCE_HASH_PATTERN.test(a.evidenceHash)\n ) {\n errors.push(\n `evidenceHash must be a 64-char hex string, got ${JSON.stringify(a.evidenceHash)}`\n );\n }\n\n const validResults = [\"no_changes_needed\", \"changes_produced\", \"blocked\"];\n if (!validResults.includes(a.result as string)) {\n errors.push(\n `result must be one of ${validResults.join(\", \")}, got ${JSON.stringify(a.result)}`\n );\n }\n\n if (\n !Array.isArray(a.changedPlanningPaths) ||\n !a.changedPlanningPaths.every((p) => typeof p === \"string\")\n ) {\n errors.push(\"changedPlanningPaths must be an array of strings\");\n } else {\n const unsafePaths = (a.changedPlanningPaths as string[]).filter(\n (p) =>\n p.startsWith(\"../\") ||\n p.includes(\"/../\") ||\n p.startsWith(RECONCILIATION_TMP_PATH_PREFIX)\n );\n if (unsafePaths.length > 0) {\n errors.push(\n \"changedPlanningPaths must not contain path traversal or reconciliation tmp artifacts\"\n );\n }\n }\n\n if (a.result === \"no_changes_needed\") {\n const paths = a.changedPlanningPaths ?? [];\n if (Array.isArray(paths) && paths.length > 0) {\n errors.push(\n `Reconciliation artifact result is \"no_changes_needed\" but changedPlanningPaths is not empty (${paths.length} paths).`\n );\n }\n if (!a.noChangeRationale || typeof a.noChangeRationale !== \"string\") {\n errors.push(\n 'Reconciliation artifact result is \"no_changes_needed\" but noChangeRationale is missing or not a string.'\n );\n }\n }\n\n if (\n !Array.isArray(a.completionArtifactPaths) ||\n !a.completionArtifactPaths.every((p) => typeof p === \"string\")\n ) {\n errors.push(\"completionArtifactPaths must be an array of strings\");\n }\n\n if (typeof a.summary !== \"string\") {\n errors.push(\"summary must be a string\");\n }\n\n if (\n !Array.isArray(a.diagnostics) ||\n !a.diagnostics.every((d) => typeof d === \"string\")\n ) {\n errors.push(\"diagnostics must be an array of strings\");\n }\n\n const diagnostics = (a.diagnostics as string[]) ?? [];\n if (diagnostics.includes(\"completionRecords.final_reviewed\")) {\n errors.push(\n \"Reconciliation artifact must not contain fabricated lifecycle indicators: completionRecords.final_reviewed\"\n );\n }\n\n return errors.length > 0 ? { ok: false, errors } : { ok: true };\n}\n\nexport function validateConflictResolutionArtifactAtPath(options: {\n artifactPath: string;\n worktreePath: string;\n}): ArtifactValidationResult {\n return validateAgentArtifact({\n kind: \"conflict-resolution\",\n artifactPath: join(options.worktreePath, options.artifactPath),\n worktreePath: options.worktreePath,\n });\n}\n\n// ---- Local triage validation ----\n\nexport function validateLocalTriage(\n prdPath: string,\n issuePaths: string[]\n): LocalValidationResult {\n const prd = readLocalArtifact<Record<string, unknown>>(\n prdPath,\n \"triage_inconsistent\"\n );\n if (!prd.ok || !prd.data) {\n return {\n ok: false,\n failureCode: \"triage_inconsistent\",\n offendingPath: prdPath,\n message: prd.message ?? \"Invalid PRD artifact\",\n };\n }\n\n if (issuePaths.length === 0) {\n return { ok: true };\n }\n\n const issues: { path: string; data: Record<string, unknown> }[] = [];\n for (const issuePath of issuePaths) {\n const issue = readLocalArtifact<Record<string, unknown>>(\n issuePath,\n \"triage_inconsistent\"\n );\n if (!issue.ok || !issue.data) {\n return {\n ok: false,\n failureCode: \"triage_inconsistent\",\n offendingPath: issuePath,\n message: issue.message ?? \"Invalid Issue artifact\",\n };\n }\n issues.push({ path: issuePath, data: issue.data });\n }\n\n const issuesById = new Map(issues.map((i) => [i.data.id as string, i]));\n\n // Rule 1: No child Issue has status needs-triage\n const needsTriage = issues.filter((i) => i.data.status === \"needs-triage\");\n if (needsTriage.length > 0) {\n return {\n ok: false,\n failureCode: \"triage_inconsistent\",\n message: `Parent PRD cannot prepare: child Issue(s) still in needs-triage: ${needsTriage.map((i) => i.data.id).join(\", \")}`,\n };\n }\n\n // Rule 2: Every blocked Issue has at least one blocker source\n for (const issue of issues.filter((i) => i.data.status === \"blocked\")) {\n const deps = (issue.data.dependencyIssueIds as string[]) ?? [];\n const blockedReason = issue.data.blockedReason;\n const readyForHumanReason = issue.data.readyForHumanReason;\n if (\n deps.length === 0 &&\n blockedReason == null &&\n readyForHumanReason == null\n ) {\n return {\n ok: false,\n failureCode: \"triage_inconsistent\",\n offendingPath: issue.path,\n message: `Blocked Issue ${issue.data.id} requires at least one blocker source: dependencyIssueIds, blockedReason, or readyForHumanReason`,\n };\n }\n }\n\n // Rule 3: ready-for-human needs readyForHumanReason; wontfix needs blockedReason\n for (const issue of issues.filter(\n (i) => i.data.status === \"ready-for-human\"\n )) {\n if (issue.data.readyForHumanReason == null) {\n return {\n ok: false,\n failureCode: \"triage_inconsistent\",\n offendingPath: issue.path,\n message: `ready-for-human Issue ${issue.data.id} must have a readyForHumanReason`,\n };\n }\n }\n for (const issue of issues.filter((i) => i.data.status === \"wontfix\")) {\n if (issue.data.blockedReason == null) {\n return {\n ok: false,\n failureCode: \"triage_inconsistent\",\n offendingPath: issue.path,\n message: `wontfix Issue ${issue.data.id} must have a blockedReason`,\n };\n }\n }\n\n // Rule 4: At least one child ready-for-agent when any blocked child exists\n const blockedCount = issues.filter((i) => i.data.status === \"blocked\").length;\n if (blockedCount > 0) {\n const readyForAgentCount = issues.filter(\n (i) => i.data.status === \"ready-for-agent\"\n ).length;\n if (readyForAgentCount === 0) {\n return {\n ok: false,\n failureCode: \"triage_inconsistent\",\n message:\n \"At least one child Issue must be ready-for-agent when blocked children exist\",\n };\n }\n }\n\n // Rule 5: Every Issue status matches its triage-state label\n for (const issue of issues) {\n const labels = (issue.data.labels as string[]) ?? [];\n const status = issue.data.status as string;\n const triageLabel = labels.find((l) =>\n (VALID_ISSUE_TRIAGE_LABELS as readonly string[]).includes(l)\n );\n if (\n triageLabel &&\n status !== \"running\" &&\n status !== \"complete\" &&\n triageLabel !== status\n ) {\n return {\n ok: false,\n failureCode: \"triage_inconsistent\",\n offendingPath: issue.path,\n message: `Issue ${issue.data.id} has status \"${status}\" but triage-state label \"${triageLabel}\"`,\n };\n }\n }\n\n // Rule 6: Exactly one triage-state label per Issue\n for (const issue of issues) {\n const labels = (issue.data.labels as string[]) ?? [];\n const triageLabels = labels.filter((l) =>\n (VALID_ISSUE_TRIAGE_LABELS as readonly string[]).includes(l)\n );\n if (triageLabels.length !== 1) {\n return {\n ok: false,\n failureCode: \"triage_inconsistent\",\n offendingPath: issue.path,\n message: `Issue ${issue.data.id} must have exactly one triage-state label, got ${triageLabels.length}`,\n };\n }\n }\n\n // Edge case: ready-for-agent with unmet dependencies\n for (const issue of issues.filter(\n (i) => i.data.status === \"ready-for-agent\"\n )) {\n const deps = (issue.data.dependencyIssueIds as string[]) ?? [];\n for (const depId of deps) {\n const dep = issuesById.get(depId);\n if (dep && dep.data.status !== \"complete\") {\n return {\n ok: false,\n failureCode: \"triage_inconsistent\",\n offendingPath: issue.path,\n message: `ready-for-agent Issue ${issue.data.id} has unresolved dependency ${depId} (status: ${dep.data.status})`,\n };\n }\n }\n }\n\n return { ok: true };\n}\n","export type ReviewVerdict =\n | \"PASS\"\n | \"PASS_WITH_NOTES\"\n | \"NEEDS_REFACTOR\"\n | \"FAIL\"\n | \"NEEDS_HUMAN\";\n\nexport class ReviewVerdictProtocolError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ReviewVerdictProtocolError\";\n }\n}\n\nexport function parseReviewVerdict(output: string): ReviewVerdict {\n const verdictRegex =\n /^\\s*<verdict>\\s*(PASS|PASS_WITH_NOTES|NEEDS_REFACTOR|FAIL|NEEDS_HUMAN)\\s*<\\/verdict>\\s*$/gm;\n const matches = Array.from(output.matchAll(verdictRegex));\n\n if (!matches || matches.length === 0) {\n throw new ReviewVerdictProtocolError(\n \"No <verdict>...</verdict> token found in reviewer output\"\n );\n }\n\n if (matches.length > 1) {\n throw new ReviewVerdictProtocolError(\n \"Multiple <verdict>...</verdict> tokens found in reviewer output\"\n );\n }\n\n const verdict = matches[0][1];\n if (!verdict) {\n throw new ReviewVerdictProtocolError(\n \"Malformed <verdict>...</verdict> token in reviewer output\"\n );\n }\n\n return verdict as ReviewVerdict;\n}\n","import {\n existsSync,\n mkdirSync,\n readFileSync,\n readdirSync,\n writeFileSync,\n} from \"fs\";\nimport { join } from \"path\";\nimport {\n type IssueData,\n type PourkitConfig,\n type Target,\n resolveMissingOrEmptyOutputRetries,\n resolvePromptTemplatePath,\n} from \"../shared/config\";\nimport type { ExecutionProvider } from \"../execution/execution-provider\";\nimport { executeWithMissingOrEmptyArtifactRetry } from \"../execution/agent-output-retry\";\nimport {\n parseReviewVerdict,\n type ReviewVerdict,\n ReviewVerdictProtocolError,\n} from \"../pr/review-verdict\";\nimport { type PourkitLogger } from \"../shared/common\";\nimport {\n RUN_CONTEXT_PATH_IN_WORKTREE,\n buildRunContextArtifact,\n STAGE_SECTIONS,\n} from \"../shared/run-context\";\nimport { appendProtectedWorkGuidance } from \"../shared/prompt-guidance\";\nimport type { SerenaExecutionContext } from \"../execution/opencode-config\";\nimport {\n FileSystem,\n FileSystemDefault,\n ExecutionProvider as ExecutionProviderService,\n} from \"../shared/effect-services\";\nimport { ReviewerFailure } from \"../failure-resolution/types\";\nimport { Effect, Layer } from \"effect\";\n\nexport interface ReviewResult {\n verdict: ReviewVerdict;\n output: string;\n artifactPath: string;\n}\n\nexport interface RunReviewOptions {\n executionProvider: ExecutionProvider;\n config: PourkitConfig;\n target: Target;\n issue: IssueData;\n parentPrdIssue?: IssueData;\n builderBranch: string;\n worktreePath: string;\n repoRoot: string;\n logger: PourkitLogger;\n iteration?: number;\n reviewHistory?: string[];\n priorRefactorArtifacts?: string;\n humanHandoffResolved?: boolean;\n priorReviewerArtifacts?: string;\n}\n\nexport class ReviewArtifactValidationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ReviewArtifactValidationError\";\n }\n}\n\nexport class RefactorArtifactValidationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"RefactorArtifactValidationError\";\n }\n}\n\nconst ALLOWED_REFACTOR_CLASSIFICATIONS = [\n \"accepted\",\n \"rejected\",\n \"deferred\",\n \"blocked\",\n];\n\nfunction normalizeRefactorClassification(raw: string): string {\n const match = raw.match(/^`(accepted|rejected|deferred|blocked)`$/);\n return match?.[1] ?? raw;\n}\n\nexport function extractLatestFindingIds(\n reviewOutput: string,\n iteration: number\n): string[] {\n const findingsSection =\n reviewOutput.split(\"## Findings\")[1]?.split(\"##\")[0] ?? \"\";\n const currentIterationIdRegex = new RegExp(`^R${iteration}\\\\.F\\\\d+$`);\n const ids: string[] = [];\n\n const rows = findingsSection.split(\"\\n\");\n let isHeaderRow = true;\n for (const row of rows) {\n const trimmed = row.trim();\n if (!trimmed.startsWith(\"|\")) continue;\n if (/^\\|[\\s-:|]+$/.test(trimmed)) {\n isHeaderRow = false;\n continue;\n }\n if (isHeaderRow) {\n isHeaderRow = false;\n continue;\n }\n const cells = trimmed\n .split(\"|\")\n .map((c) => c.trim())\n .filter((c) => c !== \"\");\n if (cells.length === 0) continue;\n if (cells[0].toLowerCase() === \"none\" || cells[0].toLowerCase() === \"n/a\")\n continue;\n if (currentIterationIdRegex.test(cells[0])) {\n ids.push(cells[0]);\n }\n }\n\n return ids;\n}\n\nexport function validateRefactorArtifact(\n artifactPath: string,\n findingIds: string[]\n): void {\n if (!existsSync(artifactPath)) {\n throw new RefactorArtifactValidationError(\n `Refactor artifact missing at ${artifactPath}`\n );\n }\n\n const content = readFileSync(artifactPath, \"utf-8\");\n\n if (!content.trim()) {\n throw new RefactorArtifactValidationError(\"Refactor artifact is empty\");\n }\n\n const requiredSections = [\n \"## Finding Responses\",\n \"## Verification\",\n \"## Open Blockers\",\n ];\n for (const section of requiredSections) {\n const sectionRegex = new RegExp(`^${section}\\\\s*$`, \"m\");\n if (!sectionRegex.test(content)) {\n throw new RefactorArtifactValidationError(\n `Refactor artifact missing required section: ${section}`\n );\n }\n }\n\n if (findingIds.length === 0) return;\n\n const findingResponsesSection =\n content.split(\"## Finding Responses\")[1]?.split(\"##\")[0] ?? \"\";\n\n for (const findingId of findingIds) {\n const rows = findingResponsesSection.split(\"\\n\");\n let found = false;\n for (const row of rows) {\n const trimmed = row.trim();\n if (!trimmed.startsWith(\"|\")) continue;\n if (/^\\|[\\s-:|]+$/.test(trimmed)) continue;\n\n const cells = trimmed\n .split(\"|\")\n .map((c) => c.trim())\n .filter((c) => c !== \"\");\n if (cells.length < 2) continue;\n\n if (cells[0] === findingId) {\n const classification = normalizeRefactorClassification(cells[1]);\n if (!ALLOWED_REFACTOR_CLASSIFICATIONS.includes(classification)) {\n throw new RefactorArtifactValidationError(\n `Invalid classification for finding ${findingId}: \"${cells[1]}\". Allowed: ${ALLOWED_REFACTOR_CLASSIFICATIONS.join(\", \")}`\n );\n }\n found = true;\n break;\n }\n }\n\n if (!found) {\n throw new RefactorArtifactValidationError(\n `Refactor artifact missing response for finding: ${findingId}`\n );\n }\n }\n}\n\nexport function validateReviewArtifact(\n output: string,\n verdict: ReviewVerdict,\n iteration: number,\n priorRefactorArtifactsProvided: boolean = false\n): void {\n if (!output.includes(\"## Findings\")) {\n throw new ReviewArtifactValidationError(\n \"Reviewer output must include a ## Findings section\"\n );\n }\n\n const findingsSection = output.split(\"## Findings\")[1]?.split(\"##\")[0] ?? \"\";\n\n if (!findingsSection.trim()) {\n throw new ReviewArtifactValidationError(\n \"Findings section must contain a table with ID and Supersedes columns\"\n );\n }\n\n const hasIdColumn = /^\\|?\\s*ID\\s+\\|/m.test(findingsSection);\n if (!hasIdColumn) {\n throw new ReviewArtifactValidationError(\n \"Findings table must include an ID column\"\n );\n }\n\n const hasSupersedesColumn = /^\\|?\\s*ID\\s+\\|\\s*Supersedes\\s+\\|/m.test(\n findingsSection\n );\n if (!hasSupersedesColumn) {\n throw new ReviewArtifactValidationError(\n \"Findings table must include a Supersedes column\"\n );\n }\n\n const findingIdRegex = /^R\\d+\\.F\\d+$/;\n const currentIterationIdRegex = new RegExp(`^R${iteration}\\\\.F\\\\d+$`);\n const supersedesIdRegex = /^R\\d+\\.F\\d+$/;\n const rows = findingsSection.split(\"\\n\");\n let isHeaderRow = true;\n for (const row of rows) {\n const trimmed = row.trim();\n if (!trimmed.startsWith(\"|\")) continue;\n if (/^\\|[\\s-:|]+$/.test(trimmed)) {\n isHeaderRow = false;\n continue;\n }\n if (isHeaderRow) {\n isHeaderRow = false;\n continue;\n }\n const cells = trimmed\n .split(\"|\")\n .map((c) => c.trim())\n .filter((c) => c !== \"\");\n if (cells.length === 0) continue;\n if (cells[0].toLowerCase() === \"none\" || cells[0].toLowerCase() === \"n/a\")\n continue;\n const idCell = cells[0];\n if (!currentIterationIdRegex.test(idCell)) {\n throw new ReviewArtifactValidationError(\n `Finding ID must match R${iteration}.F{number} format for iteration ${iteration}`\n );\n }\n const supersedesCell = cells[1];\n if (supersedesCell !== \"-\" && !supersedesIdRegex.test(supersedesCell)) {\n throw new ReviewArtifactValidationError(\n `Supersedes must be a hyphen for new findings or a valid finding ID, got: ${supersedesCell}`\n );\n }\n }\n\n if (verdict === \"NEEDS_HUMAN\") {\n if (!output.includes(\"## Human Handoff Summary\")) {\n throw new ReviewArtifactValidationError(\n \"NEEDS_HUMAN verdict requires a Human Handoff Summary section\"\n );\n }\n if (!output.includes(\"## Human Handoff Reason\")) {\n throw new ReviewArtifactValidationError(\n \"NEEDS_HUMAN verdict requires a Human Handoff Reason section\"\n );\n }\n }\n\n if (priorRefactorArtifactsProvided) {\n const verdictIndex = output.indexOf(\"<verdict>\");\n const assessmentIndex = output.indexOf(\n \"## Prior Refactor Response Assessment\"\n );\n if (assessmentIndex === -1) {\n throw new ReviewArtifactValidationError(\n \"Prior Refactor Artifacts were provided but the review is missing a ## Prior Refactor Response Assessment section\"\n );\n }\n if (verdictIndex !== -1 && assessmentIndex > verdictIndex) {\n throw new ReviewArtifactValidationError(\n \"## Prior Refactor Response Assessment must appear before <verdict>\"\n );\n }\n }\n}\n\nfunction runReviewCommandEffect(options: RunReviewOptions) {\n const {\n executionProvider,\n config,\n target,\n issue,\n parentPrdIssue,\n builderBranch,\n worktreePath,\n repoRoot,\n logger,\n iteration,\n reviewHistory,\n priorRefactorArtifacts,\n humanHandoffResolved,\n priorReviewerArtifacts,\n } = options;\n\n const reviewer = target.strategy.review.reviewer;\n if (!reviewer) {\n return Effect.fail(\n new ReviewerFailure({ message: \"No reviewer config found\" })\n );\n }\n\n const artifactPathInWorktree = join(\n \".pourkit\",\n \".tmp\",\n \"reviewers\",\n `iteration-${iteration ?? 1}.md`\n );\n const artifactPath = join(worktreePath, artifactPathInWorktree);\n\n return Effect.gen(function* () {\n const exec = yield* ExecutionProviderService;\n const fs = yield* FileSystem;\n\n const prompt = yield* buildReviewerPromptEffect(\n repoRoot,\n reviewer.promptTemplate,\n reviewer.criteria,\n artifactPathInWorktree,\n iteration ?? 1,\n fs,\n reviewHistory,\n priorRefactorArtifacts,\n humanHandoffResolved,\n priorReviewerArtifacts\n );\n\n const retryResult = yield* Effect.tryPromise({\n try: () =>\n executeWithMissingOrEmptyArtifactRetry({\n executionProvider: {\n execute: async (opts) => {\n const result = await Effect.runPromise(exec.execute(opts as any));\n return { ...result, logPath: result.logPath ?? null };\n },\n },\n missingOrEmptyRetries: resolveMissingOrEmptyOutputRetries(reviewer),\n logger,\n runningMessage: (attempt, total) =>\n `Running reviewer (${attempt}/${total})`,\n retryMessage: (attempt, total) =>\n `Retrying reviewer after empty output (${attempt}/${total})`,\n readArtifact: (path, executionResult) => {\n try {\n return {\n _tag: \"content\" as const,\n value: readReviewArtifact(path, executionResult.logPath),\n path,\n };\n } catch (error) {\n const message =\n error instanceof Error ? error.message : String(error);\n return {\n _tag: message.startsWith(\"Reviewer produced empty output at \")\n ? \"empty\"\n : \"missing\",\n path,\n };\n }\n },\n executionOptions: {\n stage: \"reviewer\" as const,\n iteration,\n agent: reviewer.agent,\n model: reviewer.model,\n variant: reviewer.variant,\n env: reviewer.env,\n prompt,\n target,\n repoRoot,\n branchName: builderBranch,\n sandbox: config.sandbox,\n autoApprove: true,\n artifactPath: artifactPathInWorktree,\n worktreePath,\n artifacts: [\n buildRunContextArtifact({\n issue,\n parentPrdIssue,\n target,\n branchName: builderBranch,\n repoRoot,\n reviewerCriteria: reviewer.criteria,\n sections: STAGE_SECTIONS.reviewer,\n }),\n ],\n logger,\n },\n }),\n catch: (error) =>\n new ReviewerFailure({\n message: error instanceof Error ? error.message : String(error),\n }),\n });\n\n if (!retryResult.executionResult.success) {\n return yield* Effect.fail(\n new ReviewerFailure({\n message: `Reviewer execution failed: ${retryResult.executionResult.error}`,\n })\n );\n }\n\n if (retryResult.artifact._tag !== \"content\") {\n const message =\n retryResult.artifact._tag === \"empty\"\n ? `Reviewer produced empty output at ${retryResult.artifact.path}`\n : `Reviewer did not produce output at ${retryResult.artifact.path}`;\n return yield* Effect.fail(new ReviewerFailure({ message }));\n }\n\n const output = retryResult.artifact.value;\n\n const parsedVerdict = yield* Effect.try({\n try: () => parseReviewVerdict(output),\n catch: (error) => {\n if (error instanceof ReviewVerdictProtocolError) {\n return new ReviewerFailure({\n message: `Review protocol error: ${error.message}`,\n });\n }\n throw error;\n },\n }).pipe(\n Effect.catchAll((error) =>\n error instanceof ReviewerFailure\n ? Effect.fail(error)\n : Effect.die(error)\n )\n );\n\n logger.step(\"info\", `Review verdict: ${parsedVerdict}`);\n\n try {\n validateReviewArtifact(\n output,\n parsedVerdict,\n iteration ?? 1,\n !!priorRefactorArtifacts\n );\n } catch (error) {\n if (error instanceof ReviewArtifactValidationError) {\n return yield* Effect.fail(\n new ReviewerFailure({ message: error.message })\n );\n }\n yield* Effect.die(error);\n }\n\n return { verdict: parsedVerdict, output, artifactPath };\n });\n}\n\nfunction bridgeExecutionProvider(\n ep: import(\"../execution/execution-provider\").ExecutionProvider\n): Layer.Layer<ExecutionProviderService> {\n return Layer.succeed(\n ExecutionProviderService,\n ExecutionProviderService.of({\n execute: (opts) =>\n Effect.tryPromise({\n try: () => ep.execute(opts as any),\n catch: (e) =>\n new Error(\n e instanceof Error ? e.message : `Execution failed: ${String(e)}`\n ),\n }),\n })\n );\n}\n\nexport function runReviewCommand(\n options: RunReviewOptions\n): Effect.Effect<ReviewResult, ReviewerFailure> {\n const { executionProvider } = options;\n\n return runReviewCommandEffect(options).pipe(\n Effect.provide(\n Layer.merge(bridgeExecutionProvider(executionProvider), FileSystemDefault)\n )\n ) as Effect.Effect<ReviewResult, ReviewerFailure>;\n}\n\nfunction buildReviewerPromptEffect(\n repoRoot: string,\n promptTemplate: string,\n criteria: string[],\n artifactPathInWorktree: string,\n iteration: number,\n fs: {\n readonly exists: (path: string) => Effect.Effect<boolean, Error>;\n readonly readFile: (path: string) => Effect.Effect<string, Error>;\n },\n reviewHistory: string[] = [],\n priorRefactorArtifacts?: string,\n humanHandoffResolved?: boolean,\n priorReviewerArtifacts?: string\n): Effect.Effect<string> {\n return Effect.gen(function* () {\n const criteriaBlock = yield* renderReviewCriteriaEffect(\n repoRoot,\n criteria,\n fs\n );\n const { content: renderedTemplate, hasCriteriaPlaceholder } =\n yield* loadReviewerPromptTemplateEffect(\n repoRoot,\n promptTemplate,\n criteriaBlock,\n fs\n );\n\n const priorRefactorBlock = priorRefactorArtifacts\n ? `${priorRefactorArtifacts}`\n : \"\";\n const priorRefactorProtocolReminder = priorRefactorArtifacts\n ? `## Prior Refactor Protocol Reminder\n\nMANDATORY: because this prompt contains ## Prior Refactor Artifacts, your artifact must contain ## Prior Refactor Response Assessment exactly, before verdict. Section headings must match the names defined in this protocol exactly.\n\n`\n : \"\";\n const priorReviewerBlock = priorReviewerArtifacts\n ? `${priorReviewerArtifacts}`\n : \"\";\n const humanHandoffBoundary = humanHandoffResolved\n ? `## Human-Resolved Handoff Boundary\n\nA prior review emitted \\`NEEDS_HUMAN\\` and stopped the agent loop. The issue has since been moved back to \\`ready-for-agent\\`.\n\nBefore carrying forward old blockers, inspect newer issue comments and the current worktree. Treat prior Reviewer and Refactor Artifacts as historical context, not active findings unless they still apply.\n\n`\n : \"\";\n return `${renderedTemplate}\n\n## Shared Run Context\n\nRead the selected issue requirements, PRD context, branch context, verification commands, and artifact paths from: ${RUN_CONTEXT_PATH_IN_WORKTREE}\n\n${\n hasCriteriaPlaceholder\n ? \"\"\n : `## Review Criteria\n\n${criteriaBlock}\n\n`\n}${humanHandoffBoundary}${priorReviewerBlock}${renderReviewHistory(reviewHistory)}${priorRefactorBlock}${priorRefactorProtocolReminder}## Output\n\nWrite your review to: ${artifactPathInWorktree}\n\nBefore handoff, run: pourkit validate-artifact reviewer ${artifactPathInWorktree} --iteration ${iteration}${priorRefactorArtifacts ? \" --prior-refactor-artifacts\" : \"\"}\n\nDo not provide a separate chat response. The runner only reads the file above.\n\nEnd the file with exactly one wrapped verdict token: <verdict>PASS</verdict>, <verdict>PASS_WITH_NOTES</verdict>, <verdict>NEEDS_REFACTOR</verdict>, <verdict>FAIL</verdict>, or <verdict>NEEDS_HUMAN</verdict>. The verdict token must appear exactly once in the output.\n\nFindings must include an ID column with values in the format R${iteration}.F{findingNumber} (e.g., R${iteration}.F1, R${iteration}.F2) and a Supersedes column referencing the finding ID being superseded (or a hyphen for new findings).\n\nWhen verdict is NEEDS_HUMAN, include Human Handoff Summary and Human Handoff Reason sections before the final verdict token.`;\n });\n}\n\nfunction renderReviewHistory(reviewHistory: string[]): string {\n if (reviewHistory.length === 0) {\n return \"\";\n }\n\n return `## Review History\n\n${reviewHistory\n .map((entry, index) => `### Iteration ${index + 1}\\n\\n${entry.trimEnd()}`)\n .join(\"\\n\\n\")}\n\n`;\n}\n\nexport function renderPriorRefactorArtifactsEffect(\n worktreePath: string,\n currentIteration: number\n): Effect.Effect<string, never, FileSystem> {\n return Effect.gen(function* () {\n const fb = yield* FileSystem;\n const refactorsDir = join(worktreePath, \".pourkit\", \".tmp\", \"refactors\");\n const dirExists = yield* fb\n .exists(refactorsDir)\n .pipe(Effect.catchAll(() => Effect.succeed(false)));\n if (!dirExists) return \"\";\n\n const iterationFiles: { num: number; content: string }[] = [];\n for (let i = 0; i < currentIteration; i++) {\n const filePath = join(refactorsDir, `iteration-${i}.md`);\n const fileExists = yield* fb\n .exists(filePath)\n .pipe(Effect.catchAll(() => Effect.succeed(false)));\n if (!fileExists) continue;\n\n const content = yield* fb\n .readFile(filePath)\n .pipe(Effect.catchAll(() => Effect.succeed(\"\")));\n if (content.trim()) {\n iterationFiles.push({ num: i, content });\n }\n }\n\n if (iterationFiles.length === 0) return \"\";\n iterationFiles.sort((a, b) => a.num - b.num);\n\n const iterationsBlocks = iterationFiles\n .map((f) => `### Refactor Iteration ${f.num}\\n\\n${f.content.trimEnd()}`)\n .join(\"\\n\\n\");\n\n return `## Prior Refactor Artifacts\n\nTreat these as conversational context, not source of truth. Inspect the current code independently.\n\n${iterationsBlocks}\n\n`;\n });\n}\n\nexport function renderPriorReviewerArtifactsEffect(\n worktreePath: string,\n currentIteration: number\n): Effect.Effect<string, never, FileSystem> {\n return Effect.gen(function* () {\n const fb = yield* FileSystem;\n const reviewersDir = join(worktreePath, \".pourkit\", \".tmp\", \"reviewers\");\n const dirExists = yield* fb\n .exists(reviewersDir)\n .pipe(Effect.catchAll(() => Effect.succeed(false)));\n if (!dirExists) return \"\";\n\n const iterationFiles: { num: number; content: string }[] = [];\n for (let i = 0; i < currentIteration; i++) {\n const filePath = join(reviewersDir, `iteration-${i}.md`);\n const fileExists = yield* fb\n .exists(filePath)\n .pipe(Effect.catchAll(() => Effect.succeed(false)));\n if (!fileExists) continue;\n\n const content = yield* fb\n .readFile(filePath)\n .pipe(Effect.catchAll(() => Effect.succeed(\"\")));\n if (content.trim()) {\n iterationFiles.push({ num: i, content });\n }\n }\n\n if (iterationFiles.length === 0) return \"\";\n iterationFiles.sort((a, b) => a.num - b.num);\n\n const iterationsBlocks = iterationFiles\n .map((f) => `### Reviewer Iteration ${f.num}\\n\\n${f.content.trimEnd()}`)\n .join(\"\\n\\n\");\n\n return `## Prior Reviewer Artifacts\n\nA prior review was resolved by a human. These artifacts are historical context from before the handoff. Treat them as background, not active findings.\n\n${iterationsBlocks}\n\n`;\n });\n}\n\nfunction loadReviewerPromptTemplateEffect(\n repoRoot: string,\n promptTemplate: string,\n criteriaBlock: string,\n fs: {\n readonly exists: (path: string) => Effect.Effect<boolean, Error>;\n readonly readFile: (path: string) => Effect.Effect<string, Error>;\n }\n): Effect.Effect<{ content: string; hasCriteriaPlaceholder: boolean }> {\n return Effect.gen(function* () {\n const promptTemplatePath = resolvePromptTemplatePath(\n repoRoot,\n promptTemplate\n );\n const exists = yield* fs.exists(promptTemplatePath).pipe(Effect.orDie);\n const promptBody = exists\n ? yield* fs.readFile(promptTemplatePath).pipe(Effect.orDie)\n : promptTemplate;\n const hasCriteriaPlaceholder = promptBody.includes(\"{{REVIEW_CRITERIA}}\");\n\n return {\n content: promptBody.replace(/\\{\\{REVIEW_CRITERIA\\}\\}/g, criteriaBlock),\n hasCriteriaPlaceholder,\n };\n });\n}\n\nfunction renderReviewCriteriaEffect(\n repoRoot: string,\n criteria: string[],\n fs: {\n readonly exists: (path: string) => Effect.Effect<boolean, Error>;\n readonly readFile: (path: string) => Effect.Effect<string, Error>;\n }\n): Effect.Effect<string> {\n return Effect.gen(function* () {\n const parts: string[] = [];\n for (const criterion of criteria) {\n const snippetPath = join(\n repoRoot,\n \".pourkit\",\n \"prompts\",\n `reviewer-${criterion}.snippet.md`\n );\n const exists = yield* fs.exists(snippetPath).pipe(Effect.orDie);\n if (exists) {\n const content = yield* fs.readFile(snippetPath).pipe(Effect.orDie);\n parts.push(content.trimEnd());\n } else {\n parts.push(`- ${criterion}`);\n }\n }\n return parts.join(\"\\n\\n\");\n });\n}\n\nfunction recoverReviewOutputFromString(logContent: string): string | null {\n const startIndex = logContent.indexOf(\"## Findings\");\n if (startIndex === -1) return null;\n const verdictMatch = logContent\n .slice(startIndex)\n .match(\n /<verdict>(PASS|PASS_WITH_NOTES|NEEDS_REFACTOR|FAIL|NEEDS_HUMAN)<\\/verdict>/\n );\n if (!verdictMatch || verdictMatch.index === undefined) return null;\n const recoveredOutput = logContent\n .slice(startIndex, startIndex + verdictMatch.index + verdictMatch[0].length)\n .trim();\n return recoveredOutput.length > 0 ? recoveredOutput : null;\n}\n\nfunction recoverReviewOutputFromLog(logPath: string): string | null {\n if (!existsSync(logPath)) {\n return null;\n }\n\n const logContent = readFileSync(logPath, \"utf-8\");\n return recoverReviewOutputFromString(logContent);\n}\n\nfunction readReviewArtifact(\n artifactPath: string,\n logPath?: string | null\n): string {\n if (existsSync(artifactPath)) {\n const output = readFileSync(artifactPath, \"utf-8\");\n if (output.trim()) {\n return output;\n }\n }\n\n const recoveredOutput = logPath ? recoverReviewOutputFromLog(logPath) : null;\n\n if (recoveredOutput) {\n writeFileSync(artifactPath, recoveredOutput, \"utf-8\");\n return recoveredOutput;\n }\n\n if (!existsSync(artifactPath)) {\n throw new Error(`Reviewer did not produce output at ${artifactPath}`);\n }\n\n throw new Error(`Reviewer produced empty output at ${artifactPath}`);\n}\n\nexport type ReviewLoopVerdict =\n | \"PASS\"\n | \"PASS_WITH_NOTES\"\n | \"FAIL\"\n | \"NEEDS_HUMAN\";\n\nexport interface ReviewLoopResult {\n verdict: ReviewLoopVerdict;\n output: string;\n artifactPath: string;\n iterations: number;\n exhaustedMaxIterations: boolean;\n lifetimeIterations: number;\n refactorCompletedForLastReview: boolean;\n refactorArtifactPaths?: string[];\n}\n\nexport interface RunReviewLoopOptions {\n executionProvider: ExecutionProvider;\n config: PourkitConfig;\n target: Target;\n issue: IssueData;\n parentPrdIssue?: IssueData;\n builderBranch: string;\n worktreePath: string;\n repoRoot: string;\n logger: PourkitLogger;\n startingLifetimeIteration?: number;\n humanHandoffResolved?: boolean;\n serena?: SerenaExecutionContext;\n onRefactorProgress?: (progress: {\n lifetimeIterations: number;\n lastVerdict: ReviewVerdict;\n lastArtifactPath: string;\n refactorArtifactPath?: string;\n }) => void | Promise<void>;\n}\n\nexport function runReviewWithRefactorLoop(\n options: RunReviewLoopOptions\n): Effect.Effect<ReviewLoopResult> {\n const {\n executionProvider,\n config,\n target,\n issue,\n parentPrdIssue,\n builderBranch,\n worktreePath,\n repoRoot,\n logger,\n startingLifetimeIteration = 0,\n humanHandoffResolved,\n serena,\n } = options;\n\n const strategy = target.strategy;\n const reviewer = strategy.review.reviewer;\n if (!reviewer) {\n return Effect.die(new Error(\"No reviewer config found\"));\n }\n const refactorer = strategy.review.refactor;\n if (!refactorer) {\n return Effect.die(new Error(\"No refactorer config found\"));\n }\n const maxIterations = strategy.review.maxIterations;\n const passWithNotesRefactorAttempts =\n strategy.review.passWithNotesRefactorAttempts;\n let resolvedStartingIteration = startingLifetimeIteration;\n {\n const reviewersDir = join(worktreePath, \".pourkit\", \".tmp\", \"reviewers\");\n try {\n const files = readdirSync(reviewersDir);\n let maxExistingIteration = 0;\n for (const file of files) {\n const match = file.match(/^iteration-(\\d+)\\.md$/);\n if (match) {\n const num = parseInt(match[1], 10);\n if (num > maxExistingIteration) {\n maxExistingIteration = num;\n }\n }\n }\n if (maxExistingIteration > resolvedStartingIteration) {\n resolvedStartingIteration = maxExistingIteration;\n }\n } catch {\n // Directory may not exist yet\n }\n }\n\n interface LoopState {\n readonly done: boolean;\n readonly iteration: number;\n readonly lastResult: ReviewResult | null;\n readonly reviewHistory: readonly string[];\n readonly passWithNotesRefactorAttemptsRemaining: number;\n readonly accumulatedRefactorPaths: readonly string[];\n readonly doneResult: ReviewLoopResult | null;\n }\n\n const program = Effect.gen(function* () {\n const fs = yield* FileSystem;\n\n const priorReviewerArtifacts = humanHandoffResolved\n ? (yield* renderPriorReviewerArtifactsEffect(\n worktreePath,\n resolvedStartingIteration + 1\n )) || undefined\n : undefined;\n\n const initialState: LoopState = {\n done: false,\n iteration: 0,\n lastResult: null,\n reviewHistory: [],\n passWithNotesRefactorAttemptsRemaining: passWithNotesRefactorAttempts,\n accumulatedRefactorPaths: [],\n doneResult: null,\n };\n\n const finalState = yield* Effect.iterate(initialState, {\n while: (s) => !s.done && s.iteration < maxIterations,\n body: (s) =>\n Effect.gen(function* () {\n const iteration = s.iteration + 1;\n const lifetimeIteration = resolvedStartingIteration + iteration;\n logger.step(\"info\", `Review iteration ${lifetimeIteration}`);\n\n const priorRefactorArtifactsStr =\n yield* renderPriorRefactorArtifactsEffect(\n worktreePath,\n lifetimeIteration\n );\n\n const reviewResult = yield* runReviewCommandEffect({\n executionProvider: null as any,\n config,\n target,\n issue,\n builderBranch,\n worktreePath,\n repoRoot,\n logger,\n iteration: lifetimeIteration,\n priorRefactorArtifacts: priorRefactorArtifactsStr || undefined,\n humanHandoffResolved,\n priorReviewerArtifacts,\n reviewHistory:\n reviewer.includeReviewHistory && s.reviewHistory.length > 0\n ? [...s.reviewHistory]\n : undefined,\n });\n\n const updatedHistory = [...s.reviewHistory, reviewResult.output];\n\n yield* persistIterationArtifactEffect(\n worktreePath,\n reviewResult.output,\n lifetimeIteration,\n fs\n );\n\n if (reviewResult.verdict === \"PASS\") {\n return {\n ...s,\n done: true,\n iteration,\n lastResult: reviewResult,\n reviewHistory: updatedHistory,\n doneResult: {\n verdict: reviewResult.verdict as ReviewLoopVerdict,\n output: reviewResult.output,\n artifactPath: reviewResult.artifactPath,\n iterations: iteration,\n lifetimeIterations: lifetimeIteration,\n exhaustedMaxIterations: false,\n refactorCompletedForLastReview: false,\n refactorArtifactPaths:\n s.accumulatedRefactorPaths.length > 0\n ? [...s.accumulatedRefactorPaths]\n : undefined,\n },\n } satisfies LoopState;\n }\n\n if (\n reviewResult.verdict === \"PASS_WITH_NOTES\" &&\n s.passWithNotesRefactorAttemptsRemaining === 0\n ) {\n logger.step(\n \"info\",\n \"PASS_WITH_NOTES refactor attempts exhausted, treating as PASS\"\n );\n return {\n ...s,\n done: true,\n iteration,\n lastResult: reviewResult,\n reviewHistory: updatedHistory,\n doneResult: {\n verdict: \"PASS\",\n output: reviewResult.output,\n artifactPath: reviewResult.artifactPath,\n iterations: iteration,\n lifetimeIterations: lifetimeIteration,\n exhaustedMaxIterations: false,\n refactorCompletedForLastReview: false,\n refactorArtifactPaths:\n s.accumulatedRefactorPaths.length > 0\n ? [...s.accumulatedRefactorPaths]\n : undefined,\n },\n } satisfies LoopState;\n }\n\n let updatedPassWithNotesRefactorAttemptsRemaining =\n s.passWithNotesRefactorAttemptsRemaining;\n if (reviewResult.verdict === \"PASS_WITH_NOTES\") {\n updatedPassWithNotesRefactorAttemptsRemaining--;\n logger.step(\n \"info\",\n `PASS_WITH_NOTES refactor attempts remaining: ${updatedPassWithNotesRefactorAttemptsRemaining}`\n );\n }\n\n if (reviewResult.verdict === \"NEEDS_HUMAN\") {\n logger.step(\"info\", \"NEEDS_HUMAN verdict, stopping review loop\");\n return {\n ...s,\n done: true,\n iteration,\n lastResult: reviewResult,\n reviewHistory: updatedHistory,\n doneResult: {\n verdict: \"NEEDS_HUMAN\",\n output: reviewResult.output,\n artifactPath: reviewResult.artifactPath,\n iterations: iteration,\n lifetimeIterations: lifetimeIteration,\n exhaustedMaxIterations: false,\n refactorCompletedForLastReview: false,\n refactorArtifactPaths:\n s.accumulatedRefactorPaths.length > 0\n ? [...s.accumulatedRefactorPaths]\n : undefined,\n },\n } satisfies LoopState;\n }\n\n if (\n reviewResult.verdict === \"NEEDS_REFACTOR\" ||\n reviewResult.verdict === \"PASS_WITH_NOTES\" ||\n reviewResult.verdict === \"FAIL\"\n ) {\n logger.step(\"info\", \"Running refactor agent\");\n const refactorArtifactPathInWorktree = join(\n \".pourkit\",\n \".tmp\",\n \"refactors\",\n `iteration-${lifetimeIteration}.md`\n );\n\n const refactorPrompt = yield* buildRefactorPromptEffect(\n repoRoot,\n refactorer.promptTemplate,\n reviewResult.output,\n refactorArtifactPathInWorktree,\n lifetimeIteration,\n fs\n );\n\n const refactorRetryResult = yield* Effect.tryPromise(() =>\n executeWithMissingOrEmptyArtifactRetry({\n executionProvider,\n missingOrEmptyRetries:\n resolveMissingOrEmptyOutputRetries(refactorer),\n executionOptions: {\n stage: \"refactor\" as const,\n iteration: lifetimeIteration,\n agent: refactorer.agent,\n model: refactorer.model,\n variant: refactorer.variant,\n env: refactorer.env,\n prompt: refactorPrompt,\n target,\n repoRoot,\n branchName: builderBranch,\n sandbox: config.sandbox,\n autoApprove: true,\n artifactPath: refactorArtifactPathInWorktree,\n worktreePath,\n artifacts: [\n buildRunContextArtifact({\n issue,\n parentPrdIssue,\n target,\n branchName: builderBranch,\n repoRoot,\n reviewerCriteria: reviewer.criteria,\n sections: STAGE_SECTIONS.refactor,\n }),\n ],\n ...(serena ? { serena: serena as any } : {}),\n logger,\n },\n })\n );\n const refactorResult = refactorRetryResult.executionResult;\n\n if (!refactorResult.success) {\n logger.step(\n \"warn\",\n \"Refactor execution failed, transitioning to ready-for-human\"\n );\n return {\n ...s,\n done: true,\n iteration,\n lastResult: reviewResult,\n reviewHistory: updatedHistory,\n doneResult: {\n verdict: \"FAIL\",\n output: reviewResult.output,\n artifactPath: reviewResult.artifactPath,\n iterations: iteration,\n lifetimeIterations: resolvedStartingIteration + iteration,\n exhaustedMaxIterations: false,\n refactorCompletedForLastReview: false,\n refactorArtifactPaths:\n s.accumulatedRefactorPaths.length > 0\n ? [...s.accumulatedRefactorPaths]\n : undefined,\n },\n } satisfies LoopState;\n }\n\n if (refactorRetryResult.artifact._tag !== \"content\") {\n logger.step(\n \"warn\",\n `Refactor artifact validation failed: ${\n refactorRetryResult.artifact._tag === \"empty\"\n ? `Refactor artifact is empty at ${refactorRetryResult.artifact.path}`\n : `Refactor artifact missing at ${refactorRetryResult.artifact.path}`\n }`\n );\n return {\n ...s,\n done: true,\n iteration,\n lastResult: reviewResult,\n reviewHistory: updatedHistory,\n doneResult: {\n verdict: \"FAIL\",\n output: reviewResult.output,\n artifactPath: reviewResult.artifactPath,\n iterations: iteration,\n lifetimeIterations: resolvedStartingIteration + iteration,\n exhaustedMaxIterations: false,\n refactorCompletedForLastReview: false,\n refactorArtifactPaths:\n s.accumulatedRefactorPaths.length > 0\n ? [...s.accumulatedRefactorPaths]\n : undefined,\n },\n } satisfies LoopState;\n }\n\n const latestFindingIds = extractLatestFindingIds(\n reviewResult.output,\n lifetimeIteration\n );\n const refactorArtifactPath = join(\n worktreePath,\n refactorArtifactPathInWorktree\n );\n try {\n validateRefactorArtifact(refactorArtifactPath, latestFindingIds);\n } catch (error) {\n if (error instanceof RefactorArtifactValidationError) {\n logger.step(\n \"warn\",\n `Refactor artifact validation failed: ${error.message}`\n );\n return {\n ...s,\n done: true,\n iteration,\n lastResult: reviewResult,\n reviewHistory: updatedHistory,\n doneResult: {\n verdict: \"FAIL\",\n output: reviewResult.output,\n artifactPath: reviewResult.artifactPath,\n iterations: iteration,\n lifetimeIterations: resolvedStartingIteration + iteration,\n exhaustedMaxIterations: false,\n refactorCompletedForLastReview: false,\n refactorArtifactPaths:\n s.accumulatedRefactorPaths.length > 0\n ? [...s.accumulatedRefactorPaths]\n : undefined,\n },\n } satisfies LoopState;\n }\n yield* Effect.die(error);\n }\n\n const updatedAccumulated = [\n ...s.accumulatedRefactorPaths,\n refactorArtifactPath,\n ];\n if (options.onRefactorProgress) {\n yield* Effect.promise(() =>\n Promise.resolve(\n options.onRefactorProgress!({\n lifetimeIterations: resolvedStartingIteration + iteration,\n lastVerdict: reviewResult.verdict,\n lastArtifactPath: reviewResult.artifactPath,\n refactorArtifactPath,\n })\n )\n );\n }\n\n return {\n done: false,\n iteration,\n lastResult: reviewResult,\n reviewHistory: updatedHistory,\n passWithNotesRefactorAttemptsRemaining:\n updatedPassWithNotesRefactorAttemptsRemaining,\n accumulatedRefactorPaths: updatedAccumulated,\n doneResult: null,\n } satisfies LoopState;\n }\n\n return {\n done: false,\n iteration,\n lastResult: reviewResult,\n reviewHistory: updatedHistory,\n passWithNotesRefactorAttemptsRemaining:\n updatedPassWithNotesRefactorAttemptsRemaining,\n accumulatedRefactorPaths: s.accumulatedRefactorPaths,\n doneResult: null,\n } satisfies LoopState;\n }),\n });\n\n if (finalState.done && finalState.doneResult) {\n return finalState.doneResult;\n }\n\n logger.step(\"warn\", `Max review iterations (${maxIterations}) exhausted`);\n return {\n verdict: \"FAIL\" as ReviewLoopVerdict,\n output: finalState.lastResult?.output ?? \"\",\n artifactPath: finalState.lastResult?.artifactPath ?? \"\",\n iterations: finalState.iteration,\n lifetimeIterations: resolvedStartingIteration + finalState.iteration,\n exhaustedMaxIterations: true,\n refactorCompletedForLastReview: true,\n refactorArtifactPaths:\n finalState.accumulatedRefactorPaths.length > 0\n ? [...finalState.accumulatedRefactorPaths]\n : undefined,\n };\n });\n\n const executionLayer = bridgeExecutionProvider(executionProvider);\n return program.pipe(\n Effect.provide(Layer.merge(executionLayer, FileSystemDefault))\n ) as Effect.Effect<ReviewLoopResult>;\n}\n\nexport function persistIterationArtifactEffect(\n worktreePath: string,\n output: string,\n iteration: number,\n fs: {\n readonly mkdir: (path: string) => Effect.Effect<void, Error>;\n readonly writeFile: (\n path: string,\n content: string\n ) => Effect.Effect<void, Error>;\n }\n): Effect.Effect<void> {\n return Effect.gen(function* () {\n const dir = join(worktreePath, \".pourkit\", \".tmp\", \"reviewers\");\n yield* fs.mkdir(dir).pipe(Effect.catchAll(() => Effect.void));\n yield* fs\n .writeFile(join(dir, `iteration-${iteration}.md`), output)\n .pipe(Effect.catchAll(() => Effect.void));\n });\n}\n\nasync function writeArtifact(\n worktreePath: string,\n filename: string,\n output: string\n) {\n try {\n const dir = join(worktreePath, \".pourkit\", \".tmp\", \"reviewers\");\n mkdirSync(dir, { recursive: true });\n writeFileSync(join(dir, filename), output, \"utf-8\");\n } catch {\n // Do not fail pipeline on artifact write errors\n }\n}\n\nasync function persistIterationArtifact(\n worktreePath: string,\n output: string,\n iteration: number\n) {\n await writeArtifact(worktreePath, `iteration-${iteration}.md`, output);\n}\n\nfunction buildRefactorPromptEffect(\n repoRoot: string,\n promptTemplate: string,\n latestReview: string,\n artifactPathInWorktree: string,\n iteration: number,\n fs: {\n readonly exists: (path: string) => Effect.Effect<boolean, Error>;\n readonly readFile: (path: string) => Effect.Effect<string, Error>;\n }\n): Effect.Effect<string> {\n return Effect.gen(function* () {\n const promptTemplatePath = resolvePromptTemplatePath(\n repoRoot,\n promptTemplate\n );\n const exists = yield* fs.exists(promptTemplatePath).pipe(Effect.orDie);\n const promptBody = exists\n ? yield* fs.readFile(promptTemplatePath).pipe(Effect.orDie)\n : promptTemplate;\n\n const findingIds = extractLatestFindingIds(latestReview, iteration);\n const findingArgs = findingIds.map((id) => ` --finding-id ${id}`).join(\"\");\n\n return appendProtectedWorkGuidance(`${promptBody}\n\n## Shared Run Context\n\nRead the selected issue requirements, PRD context, branch context, verification commands, and artifact paths from: ${RUN_CONTEXT_PATH_IN_WORKTREE}\n\n## Latest Review\n\n${latestReview.trimEnd()}\n\n## Output\n\nWrite your refactor artifact to: ${artifactPathInWorktree}\n\nBefore handoff, run: pourkit validate-artifact refactor ${artifactPathInWorktree} --iteration ${iteration}${findingArgs}\n\nWhen you are done, finish with <promise>COMPLETE</promise>.`);\n });\n}\n","import { existsSync, mkdirSync, readFileSync, rmSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport type {\n ExecutionProvider,\n ExecutionProviderOptions,\n ExecutionResult,\n} from \"./execution-provider\";\nimport type { PourkitLogger } from \"../shared/common\";\n\nexport type ArtifactOutputStatus =\n | { readonly _tag: \"content\"; readonly value: string; readonly path: string }\n | { readonly _tag: \"empty\"; readonly path: string }\n | { readonly _tag: \"missing\"; readonly path: string };\n\nexport interface AgentOutputRetryResult {\n readonly executionResult: ExecutionResult;\n readonly artifact: ArtifactOutputStatus;\n readonly attempts: number;\n}\n\nexport interface ExecuteWithMissingOrEmptyArtifactRetryOptions {\n readonly executionProvider: Pick<ExecutionProvider, \"execute\">;\n readonly executionOptions: ExecutionProviderOptions;\n readonly missingOrEmptyRetries: number;\n readonly logger?: PourkitLogger;\n readonly readArtifact?: (\n artifactPath: string,\n executionResult: ExecutionResult\n ) => ArtifactOutputStatus | Promise<ArtifactOutputStatus>;\n readonly runningMessage?: (attempt: number, total: number) => string;\n readonly retryMessage?: (attempt: number, total: number) => string;\n}\n\nexport async function executeWithMissingOrEmptyArtifactRetry({\n executionProvider,\n executionOptions,\n missingOrEmptyRetries,\n logger,\n readArtifact,\n runningMessage,\n retryMessage,\n}: ExecuteWithMissingOrEmptyArtifactRetryOptions): Promise<AgentOutputRetryResult> {\n if (!executionOptions.artifactPath) {\n throw new Error(\"Artifact retry requires executionOptions.artifactPath\");\n }\n\n const totalAttempts = missingOrEmptyRetries + 1;\n let lastResult: ExecutionResult | undefined;\n let lastArtifact: ArtifactOutputStatus | undefined;\n\n for (let attempt = 1; attempt <= totalAttempts; attempt += 1) {\n const message =\n attempt === 1\n ? runningMessage?.(attempt, totalAttempts)\n : retryMessage?.(attempt, totalAttempts);\n if (message) logger?.step(\"info\", message);\n\n prepareArtifactPath(\n join(\n executionOptions.worktreePath ?? executionOptions.repoRoot,\n executionOptions.artifactPath\n )\n );\n\n const executionResult = await executionProvider.execute(executionOptions);\n lastResult = executionResult;\n\n if (!executionResult.success) {\n return {\n executionResult,\n artifact: {\n _tag: \"missing\",\n path: join(\n executionResult.worktreePath,\n executionOptions.artifactPath\n ),\n },\n attempts: attempt,\n };\n }\n\n const fullArtifactPath = join(\n executionResult.worktreePath,\n executionOptions.artifactPath\n );\n const artifact = readArtifact\n ? await readArtifact(fullArtifactPath, executionResult)\n : readArtifactOutput(fullArtifactPath);\n lastArtifact = artifact;\n if (artifact._tag === \"content\") {\n return { executionResult, artifact, attempts: attempt };\n }\n }\n\n return {\n executionResult: lastResult!,\n artifact: lastArtifact!,\n attempts: totalAttempts,\n };\n}\n\nfunction readArtifactOutput(artifactPath: string): ArtifactOutputStatus {\n if (!existsSync(artifactPath)) {\n return { _tag: \"missing\", path: artifactPath };\n }\n const output = readFileSync(artifactPath, \"utf-8\");\n if (!output.trim()) {\n return { _tag: \"empty\", path: artifactPath };\n }\n return { _tag: \"content\", value: output, path: artifactPath };\n}\n\nfunction prepareArtifactPath(artifactPath: string): void {\n mkdirSync(dirname(artifactPath), { recursive: true });\n rmSync(artifactPath, { recursive: true, force: true });\n}\n","import { Context, Effect, Layer } from \"effect\";\nimport { existsSync, mkdirSync, readFileSync, writeFileSync, rmSync } from \"fs\";\nimport {\n writeAttemptLog,\n readAttemptLog,\n type AttemptLogEntry,\n} from \"./attempt-log\";\nimport {\n readWorktreeRunState,\n writeWorktreeRunState,\n updateWorktreeRunState,\n type WorktreeRunState,\n} from \"./worktree-run-state\";\nimport type { Target, SandboxConfig } from \"./config\";\nimport type { ExecutionArtifact } from \"./run-context\";\nimport type { SerenaExecutionContext } from \"../execution/opencode-config\";\nimport type { PourkitLogger } from \"./common\";\nimport type { PourkitStage } from \"../execution/execution-provider\";\n\nclass GitExecutionError extends Error {\n readonly _tag: \"GitExecutionError\" = \"GitExecutionError\";\n readonly message: string;\n\n constructor(args: { readonly message: string }) {\n super(args.message);\n this.name = \"GitExecutionError\";\n this.message = args.message;\n }\n}\n\nexport class FileSystem extends Context.Tag(\"FileSystem\")<\n FileSystem,\n {\n readonly readFile: (path: string) => Effect.Effect<string, Error>;\n readonly writeFile: (\n path: string,\n content: string\n ) => Effect.Effect<void, Error>;\n readonly exists: (path: string) => Effect.Effect<boolean, Error>;\n readonly mkdir: (path: string) => Effect.Effect<void, Error>;\n readonly remove: (path: string) => Effect.Effect<void, Error>;\n }\n>() {}\n\nexport const FileSystemDefault: Layer.Layer<FileSystem> = Layer.succeed(\n FileSystem,\n FileSystem.of({\n readFile: (path) =>\n Effect.try({\n try: () => readFileSync(path, \"utf-8\"),\n catch: (error) =>\n new Error(\n `Failed to read file ${path}: ${error instanceof Error ? error.message : String(error)}`\n ),\n }),\n writeFile: (path, content) =>\n Effect.try({\n try: () => writeFileSync(path, content, \"utf-8\"),\n catch: (error) =>\n new Error(\n `Failed to write file ${path}: ${error instanceof Error ? error.message : String(error)}`\n ),\n }),\n exists: (path) =>\n Effect.try({\n try: () => existsSync(path),\n catch: (error) =>\n new Error(\n `Failed to check existence of ${path}: ${error instanceof Error ? error.message : String(error)}`\n ),\n }),\n mkdir: (path) =>\n Effect.try({\n try: () => mkdirSync(path, { recursive: true }),\n catch: (error) =>\n new Error(\n `Failed to create directory ${path}: ${error instanceof Error ? error.message : String(error)}`\n ),\n }),\n remove: (path) =>\n Effect.try({\n try: () => rmSync(path, { recursive: true, force: true }),\n catch: (error) =>\n new Error(\n `Failed to remove ${path}: ${error instanceof Error ? error.message : String(error)}`\n ),\n }),\n })\n);\n\nexport const FileSystemTest: Layer.Layer<FileSystem> = Layer.succeed(\n FileSystem,\n FileSystem.of({\n readFile: (path) => Effect.succeed(`test content for ${path}`),\n writeFile: (_path, _content) => Effect.void,\n exists: (_path) => Effect.succeed(true),\n mkdir: (_path) => Effect.void,\n remove: (_path) => Effect.void,\n })\n);\n\nexport class GitOperations extends Context.Tag(\"GitOperations\")<\n GitOperations,\n {\n readonly exec: (\n args: string[],\n options?: { readonly cwd?: string }\n ) => Effect.Effect<\n { readonly stdout: string; readonly stderr: string },\n GitExecutionError\n >;\n readonly revParse: (\n ref: string,\n cwd: string\n ) => Effect.Effect<string, GitExecutionError>;\n readonly fetch: (\n remote: string,\n branch: string,\n cwd: string\n ) => Effect.Effect<void, GitExecutionError>;\n readonly mergeBaseIsAncestor: (\n baseRef: string,\n cwd: string\n ) => Effect.Effect<boolean, GitExecutionError>;\n }\n>() {}\n\nexport const GitOperationsDefault: Layer.Layer<GitOperations> = Layer.succeed(\n GitOperations,\n GitOperations.of({\n exec: (args, options) =>\n Effect.tryPromise({\n try: async () => {\n const { execCapture } = await import(\"./common\");\n const result = await execCapture(\"git\", args, {\n cwd: options?.cwd,\n });\n return { stdout: result.stdout, stderr: result.stderr };\n },\n catch: (error) =>\n new GitExecutionError({\n message:\n error instanceof Error\n ? error.message\n : `git exec failed: ${String(error)}`,\n }),\n }),\n revParse: (ref, cwd) =>\n Effect.tryPromise({\n try: async () => {\n const { execCapture } = await import(\"./common\");\n const result = await execCapture(\"git\", [\"rev-parse\", ref], {\n cwd,\n });\n return result.stdout.trim();\n },\n catch: (error) =>\n new GitExecutionError({\n message:\n error instanceof Error\n ? error.message\n : `git rev-parse failed: ${String(error)}`,\n }),\n }),\n fetch: (remote, branch, cwd) =>\n Effect.tryPromise({\n try: async () => {\n const { execCapture } = await import(\"./common\");\n await execCapture(\"git\", [\"fetch\", remote, branch], { cwd });\n },\n catch: (error) =>\n new GitExecutionError({\n message:\n error instanceof Error\n ? error.message\n : `git fetch failed: ${String(error)}`,\n }),\n }),\n mergeBaseIsAncestor: (baseRef, cwd) =>\n Effect.tryPromise({\n try: async () => {\n const { execCapture } = await import(\"./common\");\n await execCapture(\n \"git\",\n [\"merge-base\", \"--is-ancestor\", baseRef, \"HEAD\"],\n { cwd }\n );\n return true;\n },\n catch: (error) =>\n new GitExecutionError({\n message:\n error instanceof Error\n ? error.message\n : `git merge-base failed: ${String(error)}`,\n }),\n }).pipe(\n Effect.catchIf(\n (error): error is GitExecutionError =>\n error instanceof GitExecutionError &&\n error.message.includes(\"merge-base --is-ancestor\") &&\n error.message.includes(\"exit code: 1\"),\n () => Effect.succeed(false)\n )\n ),\n })\n);\n\nexport const GitOperationsTest: Layer.Layer<GitOperations> = Layer.succeed(\n GitOperations,\n GitOperations.of({\n exec: (_args, _options) => Effect.succeed({ stdout: \"\", stderr: \"\" }),\n revParse: (_ref, _cwd) => Effect.succeed(\"abc123def456\"),\n fetch: (_remote, _branch, _cwd) => Effect.void,\n mergeBaseIsAncestor: (_baseRef, _cwd) => Effect.succeed(true),\n })\n);\n\nexport class GitHubApiClient extends Context.Tag(\"GitHubApiClient\")<\n GitHubApiClient,\n {\n readonly getIssue: (\n owner: string,\n repo: string,\n issueNumber: number\n ) => Effect.Effect<unknown, Error>;\n readonly createIssueComment: (\n owner: string,\n repo: string,\n issueNumber: number,\n body: string\n ) => Effect.Effect<unknown, Error>;\n readonly updateIssue: (\n owner: string,\n repo: string,\n issueNumber: number,\n update: Record<string, unknown>\n ) => Effect.Effect<unknown, Error>;\n }\n>() {}\n\nexport const GitHubApiClientTest: Layer.Layer<GitHubApiClient> = Layer.succeed(\n GitHubApiClient,\n GitHubApiClient.of({\n getIssue: (_owner, _repo, _issueNumber) =>\n Effect.succeed({ data: { title: \"Test Issue\", state: \"open\" } }),\n createIssueComment: (_owner, _repo, _issueNumber, _body) =>\n Effect.succeed({ data: { id: 1 } }),\n updateIssue: (_owner, _repo, _issueNumber, _update) =>\n Effect.succeed({ data: { number: _issueNumber } }),\n })\n);\n\nexport class ExecutionProvider extends Context.Tag(\"ExecutionProvider\")<\n ExecutionProvider,\n {\n readonly execute: (\n options: ExecutionProviderOptions\n ) => Effect.Effect<ExecutionResult, Error>;\n }\n>() {}\n\ninterface ExecutionProviderOptions {\n readonly stage: PourkitStage;\n readonly agent: string;\n readonly model: string;\n readonly variant?: string;\n readonly env?: Record<string, string>;\n readonly prompt: string;\n readonly worktreePath?: string;\n readonly target: Target;\n readonly repoRoot: string;\n readonly branchName: string;\n readonly sandbox: SandboxConfig;\n readonly logger: PourkitLogger;\n readonly iteration?: number;\n readonly artifactPath?: string;\n readonly baseRef?: string;\n readonly serena?: SerenaExecutionContext;\n readonly autoApprove?: boolean;\n readonly timeoutMs?: number;\n readonly artifacts?: ExecutionArtifact[];\n}\n\ninterface ExecutionResult {\n readonly success: boolean;\n readonly branch: string;\n readonly worktreePath: string;\n readonly commits: string[];\n readonly error?: string;\n readonly logPath?: string | null;\n}\n\nexport const ExecutionProviderTest: Layer.Layer<ExecutionProvider> =\n Layer.succeed(\n ExecutionProvider,\n ExecutionProvider.of({\n execute: (_options) =>\n Effect.succeed({\n success: true,\n branch: \"test-branch\",\n worktreePath: _options.worktreePath ?? \"/tmp/worktree\",\n commits: [\"abc123\"],\n logPath: \"/tmp/test-log\",\n }),\n })\n );\n\nexport class AttemptLogService extends Context.Tag(\"AttemptLogService\")<\n AttemptLogService,\n {\n readonly writeEntry: (\n worktreePath: string,\n entry: AttemptLogEntry\n ) => Effect.Effect<void, Error>;\n readonly readEntries: (\n worktreePath: string\n ) => Effect.Effect<readonly AttemptLogEntry[], Error>;\n }\n>() {}\n\nexport const AttemptLogServiceTest: Layer.Layer<AttemptLogService> =\n Layer.succeed(\n AttemptLogService,\n AttemptLogService.of({\n writeEntry: (_worktreePath, _entry) => Effect.void,\n readEntries: (_worktreePath) => Effect.succeed([]),\n })\n );\n\nexport class WorktreeRunStateService extends Context.Tag(\n \"WorktreeRunStateService\"\n)<\n WorktreeRunStateService,\n {\n readonly read: (\n worktreePath: string\n ) => Effect.Effect<WorktreeRunState | null, Error>;\n readonly write: (\n worktreePath: string,\n state: WorktreeRunState\n ) => Effect.Effect<void, Error>;\n readonly update: (\n worktreePath: string,\n update: Partial<WorktreeRunState>\n ) => Effect.Effect<void, Error>;\n }\n>() {}\n\nconst WorktreeRunStateServiceTestTimestamp = \"2026-01-01T00:00:00.000Z\";\n\nexport const WorktreeRunStateServiceTest: Layer.Layer<WorktreeRunStateService> =\n Layer.succeed(\n WorktreeRunStateService,\n WorktreeRunStateService.of({\n read: (_worktreePath) =>\n Effect.succeed({\n issueNumber: 0,\n targetName: \"test\",\n branchName: \"test-branch\",\n baseBranch: \"main\",\n createdAt: WorktreeRunStateServiceTestTimestamp,\n updatedAt: WorktreeRunStateServiceTestTimestamp,\n completedStages: {},\n review: {\n lifetimeIterations: 0,\n },\n }),\n write: (_worktreePath, _state) => Effect.void,\n update: (_worktreePath, _update) => Effect.void,\n })\n );\n","export interface PrDescription {\n title: string;\n body: string;\n}\n\nconst CONVENTIONAL_TITLE_PATTERN =\n /^(feat|fix|perf|refactor|docs|test|chore|ci|build)(\\([^)]+\\))?!?:\\s+\\S/;\n\nexport class PrDescriptionProtocolError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"PrDescriptionProtocolError\";\n }\n}\n\nconst SECTION_HEADING_PATTERN = /^## (PR Title|PR Body)\\s*$/gm;\n\ninterface SectionMatch {\n heading: \"PR Title\" | \"PR Body\";\n startIndex: number;\n endIndex: number;\n}\n\nfunction extractSections(output: string): SectionMatch[] {\n const sections: SectionMatch[] = [];\n let match: RegExpExecArray | null;\n\n const re = new RegExp(SECTION_HEADING_PATTERN);\n while ((match = re.exec(output)) !== null) {\n const heading = match[1] as \"PR Title\" | \"PR Body\";\n sections.push({\n heading,\n startIndex: match.index,\n endIndex: match.index + match[0].length,\n });\n }\n\n return sections;\n}\n\nfunction contentAfter(\n output: string,\n sections: SectionMatch[],\n section: SectionMatch\n): string {\n const index = sections.indexOf(section);\n const nextSection = sections[index + 1];\n const start = section.endIndex;\n const end = nextSection?.startIndex ?? output.length;\n return output.slice(start, end).trim();\n}\n\nexport function parsePrDescription(output: string): PrDescription {\n const sections = extractSections(output);\n\n const titleSections = sections.filter((s) => s.heading === \"PR Title\");\n const bodySections = sections.filter((s) => s.heading === \"PR Body\");\n\n if (titleSections.length === 0) {\n throw new PrDescriptionProtocolError(\n 'Missing required section \"## PR Title\"'\n );\n }\n if (titleSections.length > 1) {\n throw new PrDescriptionProtocolError(\n `Duplicate \"## PR Title\" sections found (${titleSections.length})`\n );\n }\n if (bodySections.length === 0) {\n throw new PrDescriptionProtocolError(\n 'Missing required section \"## PR Body\"'\n );\n }\n if (bodySections.length > 1) {\n throw new PrDescriptionProtocolError(\n `Duplicate \"## PR Body\" sections found (${bodySections.length})`\n );\n }\n\n const title = contentAfter(output, sections, titleSections[0]);\n const body = contentAfter(output, sections, bodySections[0]);\n\n if (title.length === 0) {\n throw new PrDescriptionProtocolError('\"## PR Title\" section is empty');\n }\n if (body.length === 0) {\n throw new PrDescriptionProtocolError('\"## PR Body\" section is empty');\n }\n\n return { title, body };\n}\n\nexport function ensureConventionalPrTitle(\n title: string,\n commitSummaries: string\n): string {\n const trimmedTitle = title.trim();\n const normalizedTitle =\n trimmedTitle.match(/^`([^`]+)`$/)?.[1] ?? trimmedTitle;\n if (CONVENTIONAL_TITLE_PATTERN.test(normalizedTitle)) {\n return normalizedTitle;\n }\n\n const inferredType = inferConventionalType(commitSummaries) ?? \"chore\";\n return `${inferredType}: ${normalizedTitle}`;\n}\n\nfunction inferConventionalType(commitSummaries: string): string | null {\n for (const line of commitSummaries.split(\"\\n\")) {\n const subject = line.trim().replace(/^[0-9a-f]+\\s+/, \"\");\n const match = subject.match(CONVENTIONAL_TITLE_PATTERN);\n if (match) {\n return match[1];\n }\n }\n\n return null;\n}\n","/**\n * QUARANTINED: Legacy PRD Final Review validation functions.\n *\n * This file is KEPT because Issue Final Review artifact validation reuses the\n * shared validation functions exported here (see `runPrdRunValidateFinalReviewCommand`\n * and the `final-review` case in `artifact-validation.ts`).\n *\n * Do NOT delete while the `final-review` artifact-validation kind is still\n * active. Remove this file and its test file when Issue Final Review is\n * migrated to its own dedicated validator.\n */\n\nimport { existsSync, readFileSync } from \"node:fs\";\n\nexport type FinalReviewArtifactValidationResult =\n | {\n ok: true;\n verdict: string;\n summary: string;\n diagnostics: string[];\n changedPaths?: string[];\n prdRef?: string;\n stage?: string;\n checkoutBase?: string;\n reviewBase?: string;\n }\n | { ok: false; reason: string; diagnostics: string[] };\n\nexport type FinalReviewSemanticValidationResult =\n | { ok: true }\n | { ok: false; errors: string[]; blockedGate: \"final-review\" };\n\nexport type FinalReviewRetouchScopeValidationResult =\n | { ok: true; changedPaths: string[] }\n | {\n ok: false;\n reason: string;\n diagnostics: string[];\n offendingPaths: string[];\n };\n\nexport type FinalReviewAgentOutputValidationResult =\n | {\n ok: true;\n artifact: Extract<FinalReviewArtifactValidationResult, { ok: true }>;\n retouch?: Extract<FinalReviewRetouchScopeValidationResult, { ok: true }>;\n }\n | {\n ok: false;\n reason: string;\n diagnostics: string[];\n offendingPaths: string[];\n };\n\nexport function parseFinalReviewArtifact(\n artifactPath: string\n): FinalReviewArtifactValidationResult {\n if (!existsSync(artifactPath)) {\n return {\n ok: false,\n reason: \"Final Review artifact not found.\",\n diagnostics: [`Artifact path: ${artifactPath}`],\n };\n }\n\n let content: string;\n try {\n content = readFileSync(artifactPath, \"utf-8\");\n } catch (error) {\n return {\n ok: false,\n reason: \"Final Review artifact could not be read.\",\n diagnostics: [\n error instanceof Error ? error.message : String(error),\n `Artifact path: ${artifactPath}`,\n ],\n };\n }\n\n let parsed: Record<string, unknown>;\n try {\n parsed = JSON.parse(content);\n } catch {\n return {\n ok: false,\n reason: \"Final Review artifact is not valid JSON.\",\n diagnostics: [`Artifact path: ${artifactPath}`],\n };\n }\n\n const verdict = parsed.verdict;\n if (!verdict || typeof verdict !== \"string\") {\n return {\n ok: false,\n reason: \"Final Review artifact is missing a verdict field.\",\n diagnostics: [`Artifact content preview: ${content.slice(0, 300)}`],\n };\n }\n\n const allowedVerdicts = [\n \"pass_no_changes\",\n \"pass_with_retouch\",\n \"needs_human_review\",\n \"blocked\",\n ];\n if (!allowedVerdicts.includes(verdict)) {\n return {\n ok: false,\n reason: `Final Review artifact has unsupported verdict \"${verdict}\".`,\n diagnostics: [`Allowed verdicts: ${allowedVerdicts.join(\", \")}`],\n };\n }\n\n const summary =\n typeof parsed.summary === \"string\"\n ? parsed.summary\n : typeof parsed.reason === \"string\"\n ? parsed.reason\n : String(verdict);\n const diagnostics = Array.isArray(parsed.diagnostics)\n ? (parsed.diagnostics as string[])\n : [];\n const changedPaths = Array.isArray(parsed.changedPaths)\n ? (parsed.changedPaths as string[])\n : undefined;\n\n const isAutoSummary = !parsed.summary && !parsed.reason;\n if (\n verdict === \"pass_with_retouch\" &&\n (!changedPaths || changedPaths.length === 0) &&\n isAutoSummary\n ) {\n return {\n ok: false,\n reason:\n 'Final Review artifact with \"pass_with_retouch\" verdict requires changed paths.',\n diagnostics: [\n \"pass_with_retouch verdict must include a changedPaths array in the artifact or provide a summary/reason with enough context for git diff fallback.\",\n \"Provide changedPaths or a descriptive summary in the artifact.\",\n ],\n };\n }\n\n const prdRef =\n typeof parsed.prdRef === \"string\" && parsed.prdRef.trim()\n ? parsed.prdRef.trim()\n : undefined;\n const stage =\n typeof parsed.stage === \"string\" && parsed.stage.trim()\n ? parsed.stage.trim()\n : undefined;\n const checkoutBase =\n typeof parsed.checkoutBase === \"string\" && parsed.checkoutBase.trim()\n ? parsed.checkoutBase.trim()\n : undefined;\n const reviewBase =\n typeof parsed.reviewBase === \"string\" && parsed.reviewBase.trim()\n ? parsed.reviewBase.trim()\n : undefined;\n\n return {\n ok: true,\n verdict,\n summary,\n diagnostics,\n changedPaths,\n prdRef,\n stage,\n checkoutBase,\n reviewBase,\n };\n}\n\nexport function validateFinalReviewArtifactSemanticIds(\n artifact: {\n prdRef?: string;\n stage?: string;\n checkoutBase?: string;\n reviewBase?: string;\n },\n context: {\n prdRef: string;\n prdBranch: string;\n mergeBase: string;\n }\n): FinalReviewSemanticValidationResult {\n const errors: string[] = [];\n\n if (!artifact.prdRef) {\n errors.push(\"Final Review artifact is missing prdRef.\");\n } else if (artifact.prdRef !== context.prdRef) {\n errors.push(\n `Final Review artifact prdRef \"${artifact.prdRef}\" does not match active PRD Run \"${context.prdRef}\".`\n );\n }\n\n if (!artifact.stage) {\n errors.push(\"Final Review artifact is missing stage field.\");\n } else if (artifact.stage !== \"prdFinalReview\") {\n errors.push(\n `Final Review artifact stage \"${artifact.stage}\" is not \"prdFinalReview\".`\n );\n }\n\n if (!artifact.checkoutBase) {\n errors.push(\"Final Review artifact is missing checkoutBase.\");\n } else if (artifact.checkoutBase !== context.prdBranch) {\n errors.push(\n `Final Review artifact checkoutBase \"${artifact.checkoutBase}\" does not match active PRD Branch \"${context.prdBranch}\".`\n );\n }\n\n if (!artifact.reviewBase) {\n errors.push(\"Final Review artifact is missing reviewBase.\");\n } else if (artifact.reviewBase !== context.mergeBase) {\n errors.push(\n `Final Review artifact reviewBase \"${artifact.reviewBase}\" does not match active merge base \"${context.mergeBase}\".`\n );\n }\n\n if (errors.length > 0) {\n return { ok: false, errors, blockedGate: \"final-review\" };\n }\n\n return { ok: true };\n}\n\nexport function validateFinalReviewRetouchScope(\n changedPaths: string[]\n): FinalReviewRetouchScopeValidationResult {\n if (!changedPaths || changedPaths.length === 0) {\n return {\n ok: false,\n reason:\n \"Final Review retouch scope validation failed. No changed paths available. Provide changed paths or run Final Review with a summary that includes changed paths.\",\n diagnostics: [\"Changed paths list is empty or undefined.\"],\n offendingPaths: [],\n };\n }\n\n const offendingPaths = changedPaths.filter((p) => !isRetouchScopePath(p));\n\n const allowedPaths = changedPaths.filter((p) => isRetouchScopePath(p));\n if (allowedPaths.length === 0) {\n return {\n ok: false,\n reason:\n \"Final Review retouch scope validation failed. No implementation, test, or Changeset paths found for retouch.\",\n diagnostics: [\n \"All changed paths are prohibited for retouch.\",\n ...changedPaths.map((p) => ` - ${p}`),\n ],\n offendingPaths,\n };\n }\n\n if (offendingPaths.length > 0) {\n return {\n ok: false,\n reason:\n \"Final Review retouch scope validation failed. Prohibited paths cannot be included in retouch PR.\",\n diagnostics: [\n \"Prohibited paths found:\",\n ...offendingPaths.map((p) => ` - ${p}`),\n ],\n offendingPaths,\n };\n }\n\n return { ok: true, changedPaths };\n}\n\nexport function validateFinalReviewAgentOutputs(options: {\n artifactPath: string;\n context: {\n prdRef: string;\n prdBranch: string;\n mergeBase: string;\n };\n changedPaths?: string[];\n}): FinalReviewAgentOutputValidationResult {\n const artifact = parseFinalReviewArtifact(options.artifactPath);\n if (!artifact.ok) {\n return { ...artifact, offendingPaths: [] };\n }\n\n const semanticResult = validateFinalReviewArtifactSemanticIds(\n artifact,\n options.context\n );\n if (!semanticResult.ok) {\n return {\n ok: false,\n reason: \"Final Review artifact has mismatched semantic IDs.\",\n diagnostics: semanticResult.errors,\n offendingPaths: [],\n };\n }\n\n if (artifact.verdict !== \"pass_with_retouch\") {\n return { ok: true, artifact };\n }\n\n const changedPaths =\n options.changedPaths && options.changedPaths.length > 0\n ? options.changedPaths\n : artifact.changedPaths;\n const retouch = validateFinalReviewRetouchScope(changedPaths ?? []);\n if (!retouch.ok) {\n return retouch;\n }\n\n return { ok: true, artifact, retouch };\n}\n\nfunction isRetouchScopePath(path: string): boolean {\n if (\n path.startsWith(\".pourkit/plans/\") ||\n path === \".pourkit/CONTEXT.md\" ||\n path.startsWith(\".pourkit/docs/\") ||\n /^\\.pourkit\\/prd-runs\\/[^/]+\\.json$/.test(path)\n ) {\n return false;\n }\n return true;\n}\n","import path from \"node:path\";\nimport { access, mkdir } from \"node:fs/promises\";\nimport { execCapture } from \"../shared/common\";\n\nexport interface SerenaPaths {\n rootDir: string;\n baselineWorktreePath: string;\n dataDir: string;\n}\n\nexport interface RefreshSerenaBaselineOptions {\n repoRoot: string;\n dataDir?: string;\n remoteName?: string;\n baseBranch: string;\n}\n\nexport interface SerenaBaselineStatus {\n exists: boolean;\n baselineWorktreePath: string;\n currentCommit?: string;\n expectedRef: string;\n fresh?: boolean;\n}\n\nexport function resolveSerenaPaths(\n repoRoot: string,\n dataDir = \".pourkit/serena/\"\n): SerenaPaths {\n const rootDir = path.isAbsolute(dataDir)\n ? path.normalize(dataDir)\n : path.resolve(repoRoot, dataDir);\n\n return {\n rootDir,\n baselineWorktreePath: path.join(rootDir, \"baseline\", \"active-repo\"),\n dataDir: path.join(rootDir, \"data\"),\n };\n}\n\nasync function pathExists(dirPath: string): Promise<boolean> {\n try {\n await access(dirPath);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function isGitRepoRoot(repoPath: string): Promise<boolean> {\n try {\n const result = await execCapture(\"git\", [\"rev-parse\", \"--show-toplevel\"], {\n cwd: repoPath,\n label: \"git rev-parse --show-toplevel\",\n });\n return path.resolve(result.stdout.trim()) === path.resolve(repoPath);\n } catch {\n return false;\n }\n}\n\nexport async function ensureBaselineWorktree(options: {\n repoRoot: string;\n dataDir?: string;\n}): Promise<SerenaPaths> {\n const paths = resolveSerenaPaths(options.repoRoot, options.dataDir);\n\n await mkdir(paths.rootDir, { recursive: true });\n await mkdir(paths.dataDir, { recursive: true });\n\n if (!(await pathExists(paths.baselineWorktreePath))) {\n await mkdir(path.dirname(paths.baselineWorktreePath), { recursive: true });\n await execCapture(\n \"git\",\n [\"clone\", options.repoRoot, paths.baselineWorktreePath],\n {\n cwd: options.repoRoot,\n label: \"git clone baseline worktree\",\n }\n );\n return paths;\n }\n\n if (!(await isGitRepoRoot(paths.baselineWorktreePath))) {\n throw new Error(\n `Serena baseline worktree exists but is not a git repo: ${paths.baselineWorktreePath}`\n );\n }\n\n return paths;\n}\n\nexport async function getSerenaBaselineStatus(\n options: RefreshSerenaBaselineOptions\n): Promise<SerenaBaselineStatus> {\n const remoteName = options.remoteName ?? \"origin\";\n const paths = resolveSerenaPaths(options.repoRoot, options.dataDir);\n const expectedRef = `${remoteName}/${options.baseBranch}`;\n\n if (!(await pathExists(paths.baselineWorktreePath))) {\n return {\n exists: false,\n baselineWorktreePath: paths.baselineWorktreePath,\n expectedRef,\n fresh: false,\n };\n }\n\n if (!(await isGitRepoRoot(paths.baselineWorktreePath))) {\n return {\n exists: false,\n baselineWorktreePath: paths.baselineWorktreePath,\n expectedRef,\n fresh: false,\n };\n }\n\n let currentCommit: string | undefined;\n try {\n const currentResult = await execCapture(\"git\", [\"rev-parse\", \"HEAD\"], {\n cwd: paths.baselineWorktreePath,\n label: \"git rev-parse HEAD\",\n });\n currentCommit = currentResult.stdout.trim() || undefined;\n } catch {\n return {\n exists: true,\n baselineWorktreePath: paths.baselineWorktreePath,\n expectedRef,\n fresh: false,\n };\n }\n\n let expectedCommit: string | undefined;\n try {\n const expectedResult = await execCapture(\n \"git\",\n [\"rev-parse\", expectedRef],\n {\n cwd: paths.baselineWorktreePath,\n label: `git rev-parse ${expectedRef}`,\n }\n );\n expectedCommit = expectedResult.stdout.trim() || undefined;\n } catch {\n return {\n exists: true,\n baselineWorktreePath: paths.baselineWorktreePath,\n currentCommit,\n expectedRef,\n fresh: false,\n };\n }\n\n return {\n exists: true,\n baselineWorktreePath: paths.baselineWorktreePath,\n currentCommit,\n expectedRef,\n fresh: currentCommit === expectedCommit,\n };\n}\n\nexport async function refreshSerenaBaseline(\n options: RefreshSerenaBaselineOptions\n): Promise<SerenaBaselineStatus> {\n const remoteName = options.remoteName ?? \"origin\";\n const paths = await ensureBaselineWorktree(options);\n\n await execCapture(\"git\", [\"fetch\", remoteName, options.baseBranch], {\n cwd: paths.baselineWorktreePath,\n label: \"git fetch baseline branch\",\n });\n\n await execCapture(\n \"git\",\n [\"checkout\", \"--detach\", `${remoteName}/${options.baseBranch}`],\n {\n cwd: paths.baselineWorktreePath,\n label: \"git checkout detached baseline branch\",\n }\n );\n\n return getSerenaBaselineStatus(options);\n}\n","import { mkdir } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { execCapture } from \"../shared/common\";\n\nexport interface SerenaSidecarOptions {\n baselineWorktreePath: string;\n dataDir: string;\n mcpPort: number;\n dashboardPort: number;\n image: string;\n mcpUrl?: string;\n containerName?: string;\n}\n\nexport interface SerenaSidecarStatus {\n running: boolean;\n mcpUrl: string;\n dashboardUrl: string;\n containerName: string;\n}\n\nconst DEFAULT_CONTAINER_NAME = \"pourkit-serena-sidecar\";\nconst MCP_CONTAINER_PORT = 9121;\nconst DASHBOARD_CONTAINER_PORT = 24282;\nconst SERENA_DATA_MOUNT = \"/workspaces/serena-data\";\n\ntype DockerInspectResult = {\n State?: {\n Running?: boolean;\n };\n};\n\nfunction resolveSidecarUrls(options: SerenaSidecarOptions) {\n return {\n containerName: options.containerName ?? DEFAULT_CONTAINER_NAME,\n mcpUrl: options.mcpUrl ?? `http://localhost:${options.mcpPort}/mcp`,\n dashboardUrl: `http://localhost:${options.dashboardPort}`,\n };\n}\n\nasync function inspectSidecarContainer(containerName: string) {\n try {\n const result = await execCapture(\"docker\", [\"inspect\", containerName]);\n const parsed = JSON.parse(result.stdout) as DockerInspectResult[];\n return {\n exists: true,\n running: Boolean(parsed[0]?.State?.Running),\n };\n } catch {\n return {\n exists: false,\n running: false,\n };\n }\n}\n\nasync function readSidecarStatus(\n options: SerenaSidecarOptions\n): Promise<SerenaSidecarStatus> {\n const { containerName, mcpUrl, dashboardUrl } = resolveSidecarUrls(options);\n const container = await inspectSidecarContainer(containerName);\n\n return {\n running: container.running,\n mcpUrl,\n dashboardUrl,\n containerName,\n };\n}\n\nfunction buildStartArgs(options: SerenaSidecarOptions, containerName: string) {\n return [\n \"run\",\n \"-d\",\n \"--name\",\n containerName,\n \"--restart\",\n \"unless-stopped\",\n \"-p\",\n `${options.mcpPort}:${MCP_CONTAINER_PORT}`,\n \"-p\",\n `${options.dashboardPort}:${DASHBOARD_CONTAINER_PORT}`,\n \"-v\",\n `${options.baselineWorktreePath}:/workspaces/pourkit`,\n \"-v\",\n `${options.dataDir}:${SERENA_DATA_MOUNT}`,\n \"-e\",\n `SERENA_HOME=${SERENA_DATA_MOUNT}/config`,\n options.image,\n \"serena\",\n \"start-mcp-server\",\n \"--transport\",\n \"streamable-http\",\n \"--port\",\n String(MCP_CONTAINER_PORT),\n \"--host\",\n \"0.0.0.0\",\n ];\n}\n\nexport async function getSerenaSidecarStatus(\n options: SerenaSidecarOptions\n): Promise<SerenaSidecarStatus> {\n return readSidecarStatus(options);\n}\n\nexport async function startSerenaSidecar(\n options: SerenaSidecarOptions\n): Promise<SerenaSidecarStatus> {\n const { containerName } = resolveSidecarUrls(options);\n const container = await inspectSidecarContainer(containerName);\n\n if (container.exists) {\n if (!container.running) {\n await execCapture(\"docker\", [\"start\", containerName]);\n }\n\n return readSidecarStatus(options);\n }\n\n await execCapture(\"docker\", buildStartArgs(options, containerName));\n\n return readSidecarStatus(options);\n}\n\nexport async function indexSerenaProject(\n options: SerenaSidecarOptions\n): Promise<void> {\n const { containerName } = resolveSidecarUrls(options);\n await execCapture(\"docker\", [\n \"exec\",\n containerName,\n \"serena\",\n \"project\",\n \"create\",\n \"--language\",\n \"typescript\",\n \"--index\",\n \"/workspaces/pourkit\",\n ]);\n}\n\nexport async function stopSerenaSidecar(\n options: SerenaSidecarOptions\n): Promise<SerenaSidecarStatus> {\n const { containerName } = resolveSidecarUrls(options);\n\n try {\n await execCapture(\"docker\", [\"stop\", containerName]);\n } catch {\n // Container may already be stopped or absent.\n }\n\n return readSidecarStatus(options);\n}\n\nexport interface PrepareSerenaSidecarConfigOptions {\n baselineWorktreePath: string;\n dataDir: string;\n}\n\nexport async function prepareSerenaSidecarConfig(\n options: PrepareSerenaSidecarConfigOptions\n): Promise<void> {\n const configDir = path.join(options.dataDir, \"config\");\n await mkdir(configDir, { recursive: true });\n}\n","import type { PourkitLogger } from \"../shared/common\";\nimport { ensureBaselineWorktree, refreshSerenaBaseline } from \"./baseline\";\nimport {\n getSerenaSidecarStatus,\n prepareSerenaSidecarConfig,\n startSerenaSidecar,\n} from \"./container\";\n\nconst SERENA_MCP_PORT = 9121;\nconst SERENA_DASHBOARD_PORT = 24282;\nconst SERENA_IMAGE = \"ghcr.io/oraios/serena:latest\";\n\nexport interface PrepareSerenaForTargetOptions {\n repoRoot: string;\n targetName: string;\n baseBranch: string;\n dataDir: string;\n mcpUrl: string;\n enabled: boolean;\n required: boolean;\n autoStart: boolean;\n logger: PourkitLogger;\n}\n\nexport type SerenaPreflightResult =\n | { enabled: false }\n | { enabled: true; available: true; mcpUrl: string }\n | { enabled: true; available: false; error: string };\n\nfunction sidecarOptions(\n paths: {\n baselineWorktreePath: string;\n dataDir: string;\n },\n mcpUrl: string\n) {\n return {\n baselineWorktreePath: paths.baselineWorktreePath,\n dataDir: paths.dataDir,\n mcpPort: SERENA_MCP_PORT,\n dashboardPort: SERENA_DASHBOARD_PORT,\n image: SERENA_IMAGE,\n mcpUrl,\n };\n}\n\nasync function canReachMcp(url: string): Promise<boolean> {\n for (let attempt = 0; attempt < 10; attempt += 1) {\n try {\n await fetch(url, { method: \"GET\", signal: AbortSignal.timeout(500) });\n return true;\n } catch {\n if (attempt < 9) {\n await new Promise((resolve) => setTimeout(resolve, 100));\n }\n }\n }\n\n return false;\n}\n\nfunction formatError(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nexport async function prepareSerenaForTarget(\n options: PrepareSerenaForTargetOptions\n): Promise<SerenaPreflightResult> {\n if (!options.enabled) {\n return { enabled: false };\n }\n\n try {\n const paths = await ensureBaselineWorktree({\n repoRoot: options.repoRoot,\n dataDir: options.dataDir,\n });\n\n await prepareSerenaSidecarConfig({\n baselineWorktreePath: paths.baselineWorktreePath,\n dataDir: paths.dataDir,\n });\n\n const status = options.autoStart\n ? await startSerenaSidecar(sidecarOptions(paths, options.mcpUrl))\n : await getSerenaSidecarStatus(sidecarOptions(paths, options.mcpUrl));\n const mcpReachable = await canReachMcp(options.mcpUrl);\n\n if (!mcpReachable) {\n return {\n enabled: true,\n available: false,\n error: status.running\n ? `Serena MCP is not reachable at ${options.mcpUrl}`\n : `Serena sidecar is not running for target ${options.targetName}`,\n };\n }\n\n await refreshSerenaBaseline({\n repoRoot: options.repoRoot,\n dataDir: options.dataDir,\n baseBranch: options.baseBranch,\n });\n\n return {\n enabled: true,\n available: true,\n mcpUrl: options.mcpUrl,\n };\n } catch (error) {\n return {\n enabled: true,\n available: false,\n error: formatError(error),\n };\n }\n}\n","import { readFileSync } from \"fs\";\nimport { join } from \"path\";\nimport type { ExecutionProvider } from \"../execution/execution-provider\";\nimport { executeWithMissingOrEmptyArtifactRetry } from \"../execution/agent-output-retry\";\nimport type {\n FailureResolutionPacket,\n RecoveryArtifact,\n RecoveryDecision,\n StageFailure,\n StageFailureTag,\n} from \"./types\";\nimport { RebaseConflict } from \"./types\";\nimport { parseRecoveryArtifact, validateRecoveryDecision } from \"./types\";\nimport { validateAgentArtifact } from \"../commands/artifact-validation\";\nimport { evaluateRecoveryPolicy } from \"./recovery-policy\";\nimport {\n writeAttemptLog,\n computeFailureFingerprint,\n} from \"../shared/attempt-log\";\nimport type { PourkitLogger } from \"../shared/common\";\nimport {\n resolveMissingOrEmptyOutputRetries,\n type PourkitConfig,\n type ResolvedTarget,\n} from \"../shared/config\";\n\nexport interface PacketContext {\n readonly stageName: string;\n readonly attemptNumber: number;\n readonly worktreePath: string;\n readonly branchName: string;\n readonly baseBranch: string;\n readonly maxAttempts: number;\n readonly allowedDecisions: readonly RecoveryDecision[];\n readonly artifactTarget: string;\n}\n\nexport function constructFailureResolutionPacket(\n failure: StageFailure,\n context: PacketContext\n): FailureResolutionPacket {\n return {\n failureType: failure._tag as StageFailureTag,\n stageName: context.stageName,\n attemptNumber: context.attemptNumber,\n worktreePath: context.worktreePath,\n branchName: context.branchName,\n baseBranch: context.baseBranch,\n conflictedPaths:\n failure instanceof RebaseConflict ? failure.conflictedPaths : undefined,\n failureSummary: failure.message,\n maxAttempts: context.maxAttempts,\n allowedDecisions: context.allowedDecisions,\n artifactTarget: context.artifactTarget,\n };\n}\n\nexport interface RunFailureResolutionAgentOptions {\n executionProvider: ExecutionProvider;\n config: PourkitConfig;\n target: ResolvedTarget;\n failure: StageFailure;\n packet: FailureResolutionPacket;\n worktreePath: string;\n repoRoot: string;\n logger: PourkitLogger;\n}\n\nexport type FailureResolutionAgentResult =\n | {\n status: \"recovered\";\n decision: RecoveryDecision;\n artifact: RecoveryArtifact;\n }\n | { status: \"handoff\"; decision: \"HANDOFF_TO_HUMAN\"; reason: string }\n | { status: \"fail-run\"; decision: \"FAIL_RUN\"; reason: string };\n\nexport async function runFailureResolutionAgent(\n options: RunFailureResolutionAgentOptions\n): Promise<FailureResolutionAgentResult> {\n const {\n executionProvider,\n config,\n target,\n failure,\n packet,\n worktreePath,\n repoRoot,\n logger,\n } = options;\n const frConfig = target.strategy.failureResolution;\n const artifactPath = packet.artifactTarget;\n const fullArtifactPath = join(worktreePath, artifactPath);\n const fingerprint = computeFailureFingerprint(packet.stageName, failure._tag);\n\n const prompt = [\n `# Failure Resolution: ${packet.failureType}`,\n \"\",\n \"## Failure Context\",\n \"\",\n \"```json\",\n JSON.stringify(packet, null, 2),\n \"```\",\n \"\",\n \"## Instructions\",\n \"\",\n `Write your resolution to: ${artifactPath}`,\n \"Include a ```json block with: recoveryDecision, summary, changedFiles, verificationSummary (optional), verificationCommands (optional), notes (optional).\",\n \"\",\n \"Allowed decisions: \" + packet.allowedDecisions.join(\", \"),\n \"\",\n `Before handoff, run: pourkit validate-artifact failure-resolution ${artifactPath} ${packet.allowedDecisions.map((decision) => `--allowed-decision ${decision}`).join(\" \")}`,\n ].join(\"\\n\");\n\n const retryResult = await executeWithMissingOrEmptyArtifactRetry({\n executionProvider,\n missingOrEmptyRetries: resolveMissingOrEmptyOutputRetries(frConfig),\n executionOptions: {\n stage: \"failureResolution\",\n agent: frConfig.agent,\n model: frConfig.model,\n variant: frConfig.variant,\n env: frConfig.env,\n prompt,\n target,\n repoRoot,\n branchName: packet.branchName,\n sandbox: config.sandbox,\n autoApprove: true,\n worktreePath,\n artifactPath,\n artifacts: [],\n logger,\n },\n });\n const executionResult = retryResult.executionResult;\n\n if (!executionResult.success) {\n await writeRecoveryAttempt(\n worktreePath,\n \"failure\",\n fingerprint,\n `Agent execution failed: ${executionResult.error}`,\n undefined,\n \"HANDOFF_TO_HUMAN\",\n packet.stageName\n );\n return {\n status: \"handoff\",\n decision: \"HANDOFF_TO_HUMAN\",\n reason: `Agent execution failed: ${executionResult.error}`,\n };\n }\n\n if (retryResult.artifact._tag !== \"content\") {\n const reason =\n retryResult.artifact._tag === \"empty\"\n ? \"Agent wrote empty artifact\"\n : \"Agent did not write artifact\";\n await writeRecoveryAttempt(\n worktreePath,\n \"failure\",\n fingerprint,\n reason,\n undefined,\n \"HANDOFF_TO_HUMAN\",\n packet.stageName\n );\n return {\n status: \"handoff\",\n decision: \"HANDOFF_TO_HUMAN\",\n reason,\n };\n }\n\n let artifact: RecoveryArtifact;\n try {\n const md = readFileSync(fullArtifactPath, \"utf-8\");\n const validation = validateAgentArtifact({\n kind: \"failure-resolution\",\n artifactPath: fullArtifactPath,\n allowedDecisions: [...packet.allowedDecisions],\n });\n if (!validation.ok) {\n throw new Error(validation.reason);\n }\n artifact = parseRecoveryArtifact(md, artifactPath);\n } catch (error) {\n const reason =\n error instanceof Error ? error.message : \"Failed to parse artifact\";\n await writeRecoveryAttempt(\n worktreePath,\n \"failure\",\n fingerprint,\n reason,\n undefined,\n \"HANDOFF_TO_HUMAN\",\n packet.stageName\n );\n return { status: \"handoff\", decision: \"HANDOFF_TO_HUMAN\", reason };\n }\n\n const validation = validateRecoveryDecision(\n artifact,\n packet.allowedDecisions\n );\n if (!validation.valid) {\n await writeRecoveryAttempt(\n worktreePath,\n \"failure\",\n fingerprint,\n validation.reason!,\n undefined,\n \"HANDOFF_TO_HUMAN\",\n packet.stageName\n );\n return {\n status: \"handoff\",\n decision: \"HANDOFF_TO_HUMAN\",\n reason: validation.reason!,\n };\n }\n\n const policyResult = await evaluateRecoveryPolicy({\n failure,\n worktreePath,\n fingerprint,\n maxAttempts: packet.maxAttempts,\n agentRecommendedDecision: validation.decision!,\n allowedDecisions: packet.allowedDecisions,\n });\n\n await writeRecoveryAttempt(\n worktreePath,\n policyResult.decision === \"HANDOFF_TO_HUMAN\"\n ? \"handoff\"\n : policyResult.decision === \"FAIL_RUN\"\n ? \"failure\"\n : \"success\",\n fingerprint,\n policyResult.reason,\n artifactPath,\n policyResult.decision,\n packet.stageName\n );\n\n if (policyResult.decision === \"HANDOFF_TO_HUMAN\") {\n return {\n status: \"handoff\",\n decision: \"HANDOFF_TO_HUMAN\",\n reason: policyResult.reason,\n };\n }\n if (policyResult.decision === \"FAIL_RUN\") {\n return {\n status: \"fail-run\",\n decision: \"FAIL_RUN\",\n reason: policyResult.reason,\n };\n }\n return {\n status: \"recovered\",\n decision: policyResult.decision as RecoveryDecision,\n artifact,\n };\n}\n\nasync function writeRecoveryAttempt(\n worktreePath: string,\n outcome: \"success\" | \"failure\" | \"handoff\",\n fingerprint: string,\n summary: string,\n artifactRef?: string,\n decision?: string,\n stageName: string = \"baseRefresh\"\n): Promise<void> {\n writeAttemptLog(worktreePath, {\n attemptType: \"recovery\",\n fingerprint,\n timestamp: new Date().toISOString(),\n stage: stageName,\n outcome,\n artifactRef,\n decision:\n decision ??\n (outcome === \"handoff\"\n ? \"HANDOFF_TO_HUMAN\"\n : outcome === \"success\"\n ? \"RETRY_STAGE\"\n : undefined),\n });\n}\n","import {\n type StageFailure,\n PublishedHistoryRisk,\n SafetyFailure,\n ConfigFailure,\n} from \"./types\";\nimport type { RecoveryDecision } from \"./types\";\nimport { recoveryBudgetForFailure } from \"../shared/attempt-log\";\n\nexport interface RecoveryPolicyParams {\n readonly failure: StageFailure;\n readonly worktreePath: string;\n readonly fingerprint: string;\n readonly maxAttempts: number;\n readonly agentRecommendedDecision: RecoveryDecision;\n readonly allowedDecisions: readonly RecoveryDecision[];\n}\n\nexport interface RecoveryPolicyResult {\n readonly decision: RecoveryDecision;\n readonly reason: string;\n}\n\nexport function isSecuritySensitiveFailure(failure: StageFailure): boolean {\n return (\n failure instanceof PublishedHistoryRisk || failure instanceof SafetyFailure\n );\n}\n\nexport async function evaluateRecoveryPolicy(\n params: RecoveryPolicyParams\n): Promise<RecoveryPolicyResult> {\n if (isSecuritySensitiveFailure(params.failure)) {\n return {\n decision: \"HANDOFF_TO_HUMAN\",\n reason: \"Security-sensitive failure — AI recovery bypassed\",\n };\n }\n\n if (params.failure instanceof ConfigFailure) {\n if (\n params.agentRecommendedDecision !== \"FAIL_RUN\" &&\n params.agentRecommendedDecision !== \"HANDOFF_TO_HUMAN\"\n ) {\n return {\n decision: \"HANDOFF_TO_HUMAN\",\n reason: `ConfigFailure — agent recommended ${params.agentRecommendedDecision} but config errors are not AI-repairable`,\n };\n }\n }\n\n const budget = recoveryBudgetForFailure(\n params.worktreePath,\n params.fingerprint,\n params.maxAttempts\n );\n\n if (budget.exhausted) {\n return {\n decision: \"HANDOFF_TO_HUMAN\",\n reason: `Recovery budget exhausted (${budget.used}/${params.maxAttempts})`,\n };\n }\n\n if (!params.allowedDecisions.includes(params.agentRecommendedDecision)) {\n return {\n decision: \"HANDOFF_TO_HUMAN\",\n reason: `Agent recommended ${params.agentRecommendedDecision} which is not allowed`,\n };\n }\n\n if (params.agentRecommendedDecision === \"FAIL_RUN\") {\n return { decision: \"FAIL_RUN\", reason: \"Agent recommended FAIL_RUN\" };\n }\n\n return {\n decision: params.agentRecommendedDecision,\n reason: \"Agent recommendation accepted\",\n };\n}\n","import { join } from \"path\";\nimport { readFileSync } from \"node:fs\";\nimport type {\n IssueData,\n PourkitConfig,\n StageAgentConfig,\n Target,\n} from \"../shared/config\";\nimport {\n resolveMissingOrEmptyOutputRetries,\n resolvePromptTemplatePath,\n} from \"../shared/config\";\nimport type { ExecutionProvider } from \"../execution/execution-provider\";\nimport { executeWithMissingOrEmptyArtifactRetry } from \"../execution/agent-output-retry\";\nimport {\n ensureConventionalPrTitle,\n parsePrDescription,\n PrDescriptionProtocolError,\n} from \"../pr/pr-description\";\nimport {\n collectFinalizerContextEffect,\n buildFinalizerPrompt,\n} from \"../pr/pr-description-context\";\nimport type { PourkitLogger } from \"../shared/common\";\nimport { buildRunContextArtifact, STAGE_SECTIONS } from \"../shared/run-context\";\nimport {\n FileSystem,\n FileSystemDefault,\n ExecutionProvider as ExecutionProviderService,\n GitOperationsDefault,\n} from \"../shared/effect-services\";\nimport { FinalizerFailure } from \"../failure-resolution/types\";\nimport { Effect, Layer } from \"effect\";\nimport { runEffectAndMapExit } from \"../shared/effect-runtime\";\nimport { validateAgentArtifact } from \"./artifact-validation\";\n\nexport interface RunFinalizerOptions {\n executionProvider: ExecutionProvider;\n config: PourkitConfig;\n target: Target;\n issue: IssueData;\n builderBranch: string;\n targetBaseBranch: string;\n worktreePath: string;\n reviewArtifactPath?: string;\n repoRoot: string;\n logger: PourkitLogger;\n}\n\nexport interface RunFinalizerResult {\n title: string;\n body: string;\n artifactPath: string;\n}\n\nexport interface RunPrDescriptionFinalizerCoreOptions {\n executionProvider: ExecutionProvider;\n config: PourkitConfig;\n target: Target;\n finalizer: StageAgentConfig;\n maxAttempts: number;\n prompt: string;\n branchName: string;\n repoRoot: string;\n worktreePath: string;\n artifactPathInWorktree: string;\n commitSummaries: string;\n logger: PourkitLogger;\n artifacts?: Parameters<ExecutionProvider[\"execute\"]>[0][\"artifacts\"];\n baseRef?: string;\n checkoutBase?: string;\n reviewBase?: string;\n}\n\nfunction bridgeExecutionProvider(\n ep: ExecutionProvider\n): Layer.Layer<ExecutionProviderService> {\n return Layer.succeed(\n ExecutionProviderService,\n ExecutionProviderService.of({\n execute: (opts) =>\n Effect.tryPromise({\n try: () => ep.execute(opts as any),\n catch: (e) =>\n new Error(\n e instanceof Error ? e.message : `Execution failed: ${String(e)}`\n ),\n }),\n })\n );\n}\n\nexport function runFinalizerAgent(\n options: RunFinalizerOptions\n): Effect.Effect<RunFinalizerResult, FinalizerFailure> {\n const { executionProvider } = options;\n\n const artifactPathInWorktree = join(\n \".pourkit\",\n \".tmp\",\n \"finalizer\",\n \"agent-output.md\"\n );\n const artifactPath = join(options.worktreePath, artifactPathInWorktree);\n\n const program = Effect.gen(function* () {\n const fs = yield* FileSystem;\n\n const context = yield* collectFinalizerContextEffect({\n targetBase: options.targetBaseBranch,\n branchName: options.builderBranch,\n worktreePath: options.worktreePath,\n reviewArtifactPath: options.reviewArtifactPath,\n logger: options.logger,\n }).pipe(\n Effect.catchAll((error) =>\n Effect.fail(\n new FinalizerFailure({\n message: `Failed to collect finalizer context: ${error.message}`,\n })\n )\n )\n );\n\n const strategy = options.target.strategy;\n const finalizer = strategy.finalize.prDescriptionAgent;\n\n const resolvedPrompt = yield* loadFinalizerPromptEffect(\n options.repoRoot,\n finalizer.promptTemplate,\n fs\n );\n\n const prompt = buildFinalizerPrompt(context, resolvedPrompt);\n\n const result = yield* runPrDescriptionFinalizerCore({\n executionProvider: options.executionProvider,\n config: options.config,\n target: options.target,\n finalizer,\n maxAttempts: strategy.finalize.maxAttempts,\n prompt,\n branchName: options.builderBranch,\n repoRoot: options.repoRoot,\n worktreePath: options.worktreePath,\n artifactPathInWorktree,\n commitSummaries: context.commits,\n artifacts: [\n buildRunContextArtifact({\n issue: options.issue,\n target: options.target,\n branchName: options.builderBranch,\n reviewerCriteria: strategy.review.reviewer.criteria,\n sections: STAGE_SECTIONS.finalizer,\n }),\n ],\n logger: options.logger,\n });\n\n const output = readFileSync(artifactPath, \"utf-8\");\n\n yield* persistGeneratedArtifactEffect(options.worktreePath, output, fs);\n\n return result;\n });\n\n const executionLayer = bridgeExecutionProvider(executionProvider);\n return program.pipe(\n Effect.provide(\n Layer.mergeAll(executionLayer, FileSystemDefault, GitOperationsDefault)\n )\n ) as Effect.Effect<RunFinalizerResult, FinalizerFailure>;\n}\n\nexport function runPrDescriptionFinalizerCore(\n options: RunPrDescriptionFinalizerCoreOptions\n): Effect.Effect<RunFinalizerResult, FinalizerFailure> {\n const artifactPath = join(\n options.worktreePath,\n options.artifactPathInWorktree\n );\n\n return Effect.gen(function* () {\n let parsed: ReturnType<typeof parsePrDescription> | undefined;\n let lastValidationError: Error | undefined;\n\n for (\n let protocolAttempt = 1;\n protocolAttempt <= options.maxAttempts;\n protocolAttempt++\n ) {\n const retryResult = yield* Effect.tryPromise({\n try: () =>\n executeWithMissingOrEmptyArtifactRetry({\n executionProvider: options.executionProvider,\n missingOrEmptyRetries: resolveMissingOrEmptyOutputRetries(\n options.finalizer\n ),\n logger: options.logger,\n runningMessage: () =>\n `Running finalizer agent (${protocolAttempt}/${options.maxAttempts})`,\n retryMessage: (attempt, total) =>\n `Retrying finalizer after empty output (${attempt}/${total})`,\n executionOptions: {\n stage: \"finalizer\" as const,\n agent: options.finalizer.agent,\n model: options.finalizer.model,\n variant: options.finalizer.variant,\n env: options.finalizer.env,\n prompt: options.prompt,\n target: options.target,\n repoRoot: options.repoRoot,\n branchName: options.branchName,\n sandbox: options.config.sandbox,\n autoApprove: true,\n artifactPath: options.artifactPathInWorktree,\n worktreePath: options.worktreePath,\n artifacts: options.artifacts,\n baseRef: options.baseRef,\n checkoutBase: options.checkoutBase,\n reviewBase: options.reviewBase,\n logger: options.logger,\n },\n }),\n catch: (error) =>\n new FinalizerFailure({\n message: error instanceof Error ? error.message : String(error),\n }),\n });\n const executionResult = retryResult.executionResult;\n\n if (!executionResult.success) {\n return yield* Effect.fail(\n new FinalizerFailure({\n message: `Finalizer agent execution failed: ${executionResult.error}`,\n })\n );\n }\n\n if (retryResult.artifact._tag === \"content\") {\n const validation = validateAgentArtifact({\n kind: \"finalizer\",\n artifactPath,\n });\n if (validation.ok) {\n try {\n parsed = parsePrDescription(retryResult.artifact.value);\n lastValidationError = undefined;\n break;\n } catch (error) {\n lastValidationError =\n error instanceof PrDescriptionProtocolError\n ? new Error(`Finalizer protocol error: ${error.message}`)\n : error instanceof Error\n ? error\n : new Error(String(error));\n }\n } else {\n lastValidationError = new Error(\n `Finalizer protocol error: ${validation.reason}`\n );\n if (protocolAttempt === options.maxAttempts) break;\n }\n } else if (retryResult.artifact._tag === \"empty\") {\n lastValidationError = new Error(\n `Finalizer agent produced empty output at ${artifactPath}`\n );\n break;\n } else {\n lastValidationError = new Error(\n `Finalizer agent did not produce output at ${artifactPath}`\n );\n break;\n }\n }\n\n if (!parsed) {\n return yield* Effect.fail(\n new FinalizerFailure({\n message:\n lastValidationError?.message ?? \"Finalizer validation failed\",\n })\n );\n }\n\n options.logger.step(\"info\", \"Finalizer output generated successfully\");\n\n return {\n title: ensureConventionalPrTitle(parsed.title, options.commitSummaries),\n body: parsed.body,\n artifactPath,\n };\n });\n}\n\nfunction loadFinalizerPromptEffect(\n repoRoot: string,\n promptTemplate: string,\n fs: {\n readonly exists: (path: string) => Effect.Effect<boolean, Error>;\n readonly readFile: (path: string) => Effect.Effect<string, Error>;\n }\n): Effect.Effect<string> {\n return Effect.gen(function* () {\n const promptPath = resolvePromptTemplatePath(repoRoot, promptTemplate);\n const exists = yield* fs.exists(promptPath).pipe(Effect.orDie);\n if (exists) {\n return yield* fs.readFile(promptPath).pipe(Effect.orDie);\n }\n return promptTemplate;\n });\n}\n\nfunction persistGeneratedArtifactEffect(\n worktreePath: string,\n output: string,\n fs: {\n readonly mkdir: (path: string) => Effect.Effect<void, Error>;\n readonly writeFile: (\n path: string,\n content: string\n ) => Effect.Effect<void, Error>;\n }\n): Effect.Effect<void> {\n return Effect.gen(function* () {\n const dir = join(worktreePath, \".pourkit\", \".tmp\", \"finalizer\");\n yield* fs.mkdir(dir).pipe(Effect.catchAll(() => Effect.void));\n yield* fs\n .writeFile(join(dir, \"generated.md\"), output)\n .pipe(Effect.catchAll(() => Effect.void));\n });\n}\n","import { join } from \"path\";\nimport { readFile } from \"node:fs/promises\";\nimport { execCapture, type PourkitLogger } from \"../shared/common\";\nimport { Effect } from \"effect\";\nimport { FileSystem, GitOperations } from \"../shared/effect-services\";\nimport { RUN_CONTEXT_PATH_IN_WORKTREE } from \"../shared/run-context\";\n\nexport interface FinalizerContext {\n commits: string;\n reviewArtifact: string;\n targetBase: string;\n branchName: string;\n}\n\nexport interface CollectContextOptions {\n targetBase: string;\n branchName: string;\n worktreePath: string;\n reviewArtifactPath?: string;\n logger: PourkitLogger;\n}\n\nexport async function collectFinalizerContext(\n options: CollectContextOptions\n): Promise<FinalizerContext> {\n const { targetBase, branchName, worktreePath, reviewArtifactPath, logger } =\n options;\n\n const commits = await collectCommitRange(\n targetBase,\n branchName,\n worktreePath,\n logger\n );\n const reviewArtifact = reviewArtifactPath\n ? await readReviewArtifact(reviewArtifactPath)\n : \"(no review artifact provided)\";\n\n return {\n commits,\n reviewArtifact,\n targetBase,\n branchName,\n };\n}\n\nexport function collectFinalizerContextEffect(\n options: CollectContextOptions\n): Effect.Effect<FinalizerContext, Error, FileSystem | GitOperations> {\n return Effect.gen(function* () {\n const git = yield* GitOperations;\n const fs = yield* FileSystem;\n\n const remoteBase = remoteTargetBase(options.targetBase);\n const result = yield* git\n .exec(\n [\n \"log\",\n `${remoteBase}..${options.branchName}`,\n \"--oneline\",\n \"--no-decorate\",\n ],\n { cwd: options.worktreePath }\n )\n .pipe(\n Effect.catchAll((error) =>\n Effect.fail(\n new Error(`Failed to collect commit range: ${error.message}`)\n )\n )\n );\n const commits = result.stdout.trim();\n\n if (!commits) {\n options.logger.step(\n \"warn\",\n `No commits found between ${options.targetBase} and ${options.branchName}, proceeding with empty commit range`\n );\n }\n\n let reviewArtifact: string;\n if (options.reviewArtifactPath) {\n const content = yield* fs.readFile(options.reviewArtifactPath).pipe(\n Effect.catchIf(\n (error) =>\n error.message.includes(\"ENOENT\") ||\n error.message.includes(\"no such file\"),\n () =>\n Effect.fail(\n new Error(\n `Review artifact not found at ${options.reviewArtifactPath}. Ensure the review stage completed before running finalizer generation.`\n )\n )\n )\n );\n if (!content.trim()) {\n return yield* Effect.fail(\n new Error(\n `Review artifact at ${options.reviewArtifactPath} is empty. Ensure the review stage produced output before running finalizer generation.`\n )\n );\n }\n reviewArtifact = content;\n } else {\n reviewArtifact = \"(no review artifact provided)\";\n }\n\n return {\n commits,\n reviewArtifact,\n targetBase: options.targetBase,\n branchName: options.branchName,\n };\n });\n}\n\nasync function collectCommitRange(\n targetBase: string,\n branchName: string,\n worktreePath: string,\n logger: PourkitLogger\n): Promise<string> {\n const result = await execCapture(\n \"git\",\n [\n \"log\",\n `${remoteTargetBase(targetBase)}..${branchName}`,\n \"--oneline\",\n \"--no-decorate\",\n ],\n { cwd: worktreePath, logger, label: \"git log\" }\n );\n\n const commits = result.stdout.trim();\n if (!commits) {\n logger.step(\n \"warn\",\n `No commits found between ${targetBase} and ${branchName}, proceeding with empty commit range`\n );\n }\n return commits;\n}\n\nfunction remoteTargetBase(targetBase: string): string {\n return targetBase.includes(\"/\") ? targetBase : `origin/${targetBase}`;\n}\n\nasync function readReviewArtifact(artifactPath: string): Promise<string> {\n let content: string;\n try {\n content = await readFile(artifactPath, \"utf-8\");\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n throw new Error(\n `Review artifact not found at ${artifactPath}. Ensure the review stage completed before running finalizer generation.`\n );\n }\n throw error;\n }\n\n if (!content.trim()) {\n throw new Error(\n `Review artifact at ${artifactPath} is empty. Ensure the review stage produced output before running finalizer generation.`\n );\n }\n\n return content;\n}\n\nexport function buildFinalizerPrompt(\n context: FinalizerContext,\n promptTemplate: string\n): string {\n const artifactPathInWorktree = join(\n \".pourkit\",\n \".tmp\",\n \"finalizer\",\n \"agent-output.md\"\n );\n\n return `${promptTemplate}\n\n## Shared Run Context\n\nRead the selected issue requirements, branch context, validation commands, and artifact paths from: ${RUN_CONTEXT_PATH_IN_WORKTREE}\n\n## Branch Context\n\n**Target Base**: ${context.targetBase}\n**Branch**: ${context.branchName}\n\n## Commits\n\n${context.commits || \"(no commits in range)\"}\n\n## Review Artifact\n\n${context.reviewArtifact}\n\n## Output\n\nGenerate a PR title and body that accurately summarize the changes for this issue.\nFormat your output with \"## PR Title\" and \"## PR Body\" sections.\n\nInside \"## PR Body\", use the following canonical structure:\n\n## Summary\n\n- Why this branch exists.\n- What outcome this branch delivers.\n\n## Changes\n\n- Final net change 1.\n- Final net change 2.\n\nRules:\n- Use bullet points only inside both inner sections (no prose paragraphs or commit lists).\n- Use final-state wording (describe what the code does after this PR, not what changed during development).\n- Do not include commit chronology or a list of commit messages.\n- Closing policy: For Issue-backed runs, publish exactly one closing reference for the current Issue (e.g. \"Closes #123\"). Never close parent PRDs, sibling Issues, or unrelated Issues. Omit the closing footer when no Issue is attached.\n\nWrite your finalizer output to: ${artifactPathInWorktree}\n\nBefore handoff, run: pourkit validate-artifact finalizer ${artifactPathInWorktree}`;\n}\n","import { execFileSync } from \"node:child_process\";\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { getLocalPrdBranchName } from \"./local-branches\";\n\nexport type LocalChildIssueState =\n | \"pending_finalizer\"\n | \"finalizer_failed\"\n | \"ready_to_merge\"\n | \"merge_failed\"\n | \"receipt_written\"\n | \"already_merged\";\n\nexport type LocalMergeFailureCode =\n | \"finalizer_failed\"\n | \"not_found\"\n | \"invalid_receipt\"\n | \"conflict\"\n | \"merge_error\"\n | \"receipt_error\"\n | \"already_merged\";\n\nexport interface MergeReceipt {\n prdId: string;\n issueId: string;\n stage: \"child-issue\" | \"final-review\" | \"reconciliation\";\n sourceBranch: string;\n localPrdBranch: string;\n mergeCommit: string;\n finalizerArtifactPath: string;\n completedAt: string;\n}\n\nexport interface SquashMergeInput {\n finalizerTitle: string;\n finalizerBody: string;\n finalizerArtifactPath: string;\n sourceBranch?: string;\n}\n\nexport interface MergeResult {\n ok: boolean;\n receipt?: MergeReceipt;\n failureCode?: LocalMergeFailureCode;\n repairGuidance?: string;\n}\n\nfunction getLocalStorePath(repoRoot: string, prdId: string): string {\n return join(repoRoot, \".pourkit\", \"local-prd-runs\", prdId);\n}\n\nfunction getMergeReceiptPath(\n repoRoot: string,\n prdId: string,\n issueId: string\n): string {\n return join(\n getLocalStorePath(repoRoot, prdId),\n \"merge-receipts\",\n `${issueId}.json`\n );\n}\n\nfunction getIssueArtifactPath(\n repoRoot: string,\n prdId: string,\n issueId: string\n): string {\n return join(getLocalStorePath(repoRoot, prdId), \"issues\", `${issueId}.json`);\n}\n\nfunction readIssueBranchName(\n repoRoot: string,\n prdId: string,\n issueId: string\n): string | null {\n const issuePath = getIssueArtifactPath(repoRoot, prdId, issueId);\n if (!existsSync(issuePath)) return null;\n\n try {\n const content = readFileSync(issuePath, \"utf-8\");\n const parsed = JSON.parse(content);\n return typeof parsed.branchName === \"string\" && parsed.branchName\n ? parsed.branchName\n : null;\n } catch {\n return null;\n }\n}\n\nexport async function hasLocalIssueMergeReceipt(\n prdId: string,\n issueId: string,\n repoRoot?: string\n): Promise<MergeReceipt | null> {\n const root = repoRoot ?? process.cwd();\n const receiptPath = getMergeReceiptPath(root, prdId, issueId);\n if (!existsSync(receiptPath)) return null;\n\n try {\n const content = readFileSync(receiptPath, \"utf-8\");\n const parsed = JSON.parse(content) as MergeReceipt;\n if (\n typeof parsed.prdId === \"string\" &&\n typeof parsed.issueId === \"string\" &&\n typeof parsed.stage === \"string\" &&\n typeof parsed.sourceBranch === \"string\" &&\n typeof parsed.localPrdBranch === \"string\" &&\n typeof parsed.mergeCommit === \"string\" &&\n typeof parsed.completedAt === \"string\"\n ) {\n return parsed;\n }\n return null;\n } catch {\n return null;\n }\n}\n\nexport async function squashMergeLocalIssue(\n prdId: string,\n issueId: string,\n input?: SquashMergeInput,\n repoRoot?: string\n): Promise<MergeResult> {\n const root = repoRoot ?? process.cwd();\n\n const receiptPath = getMergeReceiptPath(root, prdId, issueId);\n if (existsSync(receiptPath)) {\n try {\n const existing: MergeReceipt = JSON.parse(\n readFileSync(receiptPath, \"utf-8\")\n );\n if (\n existing.prdId === prdId &&\n existing.issueId === issueId &&\n existing.mergeCommit\n ) {\n return {\n ok: false,\n failureCode: \"already_merged\",\n repairGuidance: `Issue ${issueId} was already merged into ${existing.localPrdBranch}. Merge commit: ${existing.mergeCommit}`,\n };\n }\n return {\n ok: false,\n failureCode: \"invalid_receipt\",\n repairGuidance: `Merge receipt for ${issueId} belongs to different prd/issue. Remove it manually: ${receiptPath}`,\n };\n } catch {\n return {\n ok: false,\n failureCode: \"invalid_receipt\",\n repairGuidance: `Merge receipt for ${issueId} is corrupted. Remove it manually: ${receiptPath}`,\n };\n }\n }\n\n const sourceBranch =\n input?.sourceBranch ?? readIssueBranchName(root, prdId, issueId);\n if (!sourceBranch) {\n return {\n ok: false,\n failureCode: \"not_found\",\n repairGuidance: `No source branch found for issue ${issueId} under PRD ${prdId}. Ensure the issue artifact exists with a valid branchName field.`,\n };\n }\n\n try {\n execFileSync(\n \"git\",\n [\"show-ref\", \"--verify\", \"--quiet\", `refs/heads/${sourceBranch}`],\n { cwd: root, encoding: \"utf8\", stdio: \"pipe\" }\n );\n } catch {\n return {\n ok: false,\n failureCode: \"not_found\",\n repairGuidance: `Source branch \"${sourceBranch}\" does not exist locally. Check that the branch was created and not deleted.`,\n };\n }\n\n const targetBranch = getLocalPrdBranchName(prdId);\n try {\n execFileSync(\n \"git\",\n [\"show-ref\", \"--verify\", \"--quiet\", `refs/heads/${targetBranch}`],\n { cwd: root, encoding: \"utf8\", stdio: \"pipe\" }\n );\n } catch {\n return {\n ok: false,\n failureCode: \"not_found\",\n repairGuidance: `Local PRD branch \"${targetBranch}\" does not exist. Run \\`prd-run start\\` first to create it.`,\n };\n }\n\n try {\n execFileSync(\"git\", [\"checkout\", targetBranch], {\n cwd: root,\n encoding: \"utf8\",\n stdio: \"pipe\",\n });\n\n let preMergeHead: string;\n try {\n preMergeHead = execFileSync(\"git\", [\"rev-parse\", \"HEAD\"], {\n cwd: root,\n encoding: \"utf8\",\n stdio: \"pipe\",\n }).trim();\n } catch {\n return {\n ok: false,\n failureCode: \"merge_error\",\n repairGuidance: \"Failed to read current HEAD before merge.\",\n };\n }\n\n execFileSync(\"git\", [\"merge\", \"--squash\", sourceBranch], {\n cwd: root,\n encoding: \"utf8\",\n stdio: \"pipe\",\n });\n\n if (input) {\n execFileSync(\n \"git\",\n [\"commit\", \"-m\", input.finalizerTitle, \"-m\", input.finalizerBody],\n { cwd: root, encoding: \"utf8\", stdio: \"pipe\" }\n );\n } else {\n execFileSync(\n \"git\",\n [\"commit\", \"-m\", `Squash merge ${sourceBranch} into ${targetBranch}`],\n { cwd: root, encoding: \"utf8\", stdio: \"pipe\" }\n );\n }\n\n const revParseResult = execFileSync(\"git\", [\"rev-parse\", \"HEAD\"], {\n cwd: root,\n encoding: \"utf8\",\n stdio: \"pipe\",\n });\n const mergeCommit = revParseResult.trim();\n\n const receipt: MergeReceipt = {\n prdId,\n issueId,\n stage: \"child-issue\",\n sourceBranch,\n localPrdBranch: targetBranch,\n mergeCommit,\n finalizerArtifactPath: input?.finalizerArtifactPath ?? \"\",\n completedAt: new Date().toISOString(),\n };\n\n try {\n const receiptsDir = join(\n root,\n \".pourkit\",\n \"local-prd-runs\",\n prdId,\n \"merge-receipts\"\n );\n mkdirSync(receiptsDir, { recursive: true });\n writeFileSync(receiptPath, JSON.stringify(receipt, null, 2), \"utf-8\");\n } catch {\n try {\n execFileSync(\"git\", [\"reset\", \"--hard\", preMergeHead], {\n cwd: root,\n encoding: \"utf8\",\n stdio: \"pipe\",\n });\n } catch {\n // Best-effort rollback; if it fails, the branch may be dirty\n }\n return {\n ok: false,\n failureCode: \"receipt_error\",\n repairGuidance:\n \"Failed to write merge receipt. Check disk space and permissions on .pourkit/local-prd-runs/. The merge commit has been rolled back.\",\n };\n }\n\n return { ok: true, receipt };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n if (message.toLowerCase().includes(\"conflict\")) {\n return {\n ok: false,\n failureCode: \"conflict\",\n repairGuidance:\n \"Merge conflict during squash. Resolve conflicts in the working tree, then retry.\",\n };\n }\n const stderr =\n error instanceof Error && \"stderr\" in error\n ? (error as Error & { stderr: string }).stderr\n : undefined;\n return {\n ok: false,\n failureCode: \"merge_error\",\n repairGuidance: stderr\n ? `Merge failed: ${stderr}`\n : `Merge failed: ${message}`,\n };\n }\n}\n","import { execFileSync, spawnSync } from \"node:child_process\";\n\nexport function getLocalPrdBranchName(prdId: string): string {\n return `local/${prdId}`;\n}\n\nexport interface LocalStartPrerequisites {\n localBranchName: string;\n localBranchExists: boolean;\n localBranchCommit: string;\n localStoreReady: boolean;\n}\n\nexport type MaterializeLocalPrdBranchResult =\n | { ok: true; created: boolean }\n | { ok: false; failureCode: string; message: string };\n\nexport function materializeLocalPrdBranch(\n prdId: string,\n startBaseCommit: string,\n repoRoot?: string\n): MaterializeLocalPrdBranchResult {\n const branch = getLocalPrdBranchName(prdId);\n const root = repoRoot ?? process.cwd();\n\n const branchExists = (() => {\n try {\n return (\n spawnSync(\"git\", [\"rev-parse\", \"--verify\", \"--quiet\", branch], {\n cwd: root,\n encoding: \"utf8\",\n stdio: \"pipe\",\n }).status === 0\n );\n } catch {\n return false;\n }\n })();\n\n if (branchExists) {\n const currentCommit =\n spawnSync(\"git\", [\"rev-parse\", branch], {\n cwd: root,\n encoding: \"utf8\",\n stdio: \"pipe\",\n })\n .stdout?.toString?.()\n .trim() ?? \"\";\n\n if (currentCommit !== startBaseCommit) {\n return {\n ok: false,\n failureCode: \"branch_commit_mismatch\",\n message: `Local PRD branch ${branch} exists at commit ${currentCommit} but expected commit ${startBaseCommit}. The branch has diverged from the start base. To resolve, delete the local branch and rerun start, or manually reset it to the expected commit.`,\n };\n }\n\n return {\n ok: true,\n created: false,\n };\n }\n\n const branchResult = spawnSync(\"git\", [\"branch\", branch, startBaseCommit], {\n cwd: root,\n encoding: \"utf8\",\n stdio: \"pipe\",\n });\n\n if (branchResult.status !== 0) {\n const stderr = branchResult.stderr?.toString?.() ?? \"unknown error\";\n return {\n ok: false,\n failureCode: \"branch_creation_failed\",\n message: `Failed to create local PRD branch ${branch} at ${startBaseCommit}: ${stderr}`,\n };\n }\n\n return { ok: true, created: true };\n}\n\nexport type BranchValidationResult =\n | { ok: true }\n | {\n ok: false;\n failureCode:\n | \"protected_branch\"\n | \"remote_backed_collision\"\n | \"invalid_format\";\n message: string;\n };\n\nconst PROTECTED_BRANCHES = new Set([\"dev\", \"next\", \"main\"]);\n\nconst LOCAL_BRANCH_PATTERN = /^local\\/PRD-\\d{4}(\\/(I-\\d{2}(-[a-z0-9-]+)?)?)?$/;\n\nexport function validateLocalBranchName(name: string): BranchValidationResult {\n if (!name || name.length === 0) {\n return {\n ok: false,\n failureCode: \"invalid_format\",\n message: \"Branch name is empty.\",\n };\n }\n\n if (isProtectedBranch(name)) {\n return {\n ok: false,\n failureCode: \"protected_branch\",\n message: `Branch \"${name}\" is protected.`,\n };\n }\n\n if (!LOCAL_BRANCH_PATTERN.test(name)) {\n return {\n ok: false,\n failureCode: \"invalid_format\",\n message: `Branch \"${name}\" does not match the local branch pattern.`,\n };\n }\n\n return { ok: true };\n}\n\nexport function isProtectedBranch(name: string): boolean {\n return PROTECTED_BRANCHES.has(name);\n}\n\n/**\n * Check if a local PRD branch name has a collision with an existing remote-backed ref.\n *\n * @param localName - Local branch name (e.g. `local/PRD-0052`).\n * @param repoRoot - Optional git repository root for testing. Defaults to `process.cwd()`.\n */\nexport function hasRemoteBackedCollision(\n localName: string,\n repoRoot?: string\n): Promise<BranchValidationResult> {\n const match = localName.match(/^local\\/(PRD-\\d{4})/);\n if (!match) {\n return Promise.resolve({\n ok: false,\n failureCode: \"invalid_format\",\n message: `Cannot extract PRD ref from \"${localName}\".`,\n });\n }\n\n const prdRef = match[1];\n\n try {\n execFileSync(\n \"git\",\n [\"show-ref\", \"--verify\", \"--quiet\", `refs/heads/${prdRef}`],\n {\n cwd: repoRoot ?? process.cwd(),\n encoding: \"utf8\",\n stdio: \"pipe\",\n }\n );\n return Promise.resolve({\n ok: false,\n failureCode: \"remote_backed_collision\",\n message: `Branch \"${prdRef}\" exists locally.`,\n });\n } catch {\n // Local branch does not exist, continue to check remote\n }\n\n try {\n execFileSync(\n \"git\",\n [\"show-ref\", \"--verify\", \"--quiet\", `refs/remotes/origin/${prdRef}`],\n {\n cwd: repoRoot ?? process.cwd(),\n encoding: \"utf8\",\n stdio: \"pipe\",\n }\n );\n return Promise.resolve({\n ok: false,\n failureCode: \"remote_backed_collision\",\n message: `Remote branch \"origin/${prdRef}\" exists.`,\n });\n } catch {\n // Remote branch does not exist\n }\n\n return Promise.resolve({ ok: true });\n}\n","import { readFile } from \"node:fs/promises\";\n\nexport const DEFAULT_MANUAL_PR_BODY = `## Summary\n\n- Summarize why this branch exists.\n\n## Changes\n\n- Summarize the final net change in this branch.`;\n\nexport interface PrBodyOptions {\n body?: string;\n bodyFile?: string;\n issue?: number;\n}\n\nexport interface PrBodyInput {\n defaultBody: string;\n options: PrBodyOptions;\n}\n\nexport async function buildPrBody(input: PrBodyInput): Promise<string> {\n const { defaultBody, options } = input;\n\n let bodyText = await resolveBodyText(defaultBody, options);\n\n bodyText = appendClosingRef(bodyText, options.issue);\n\n return bodyText;\n}\n\nexport function ensureClosingRefs(body: string, issue?: number): string {\n const stripped = stripClosingRefs(body || \"\");\n if (issue === undefined) {\n return stripped;\n }\n if (!stripped) {\n return `Closes #${issue}`;\n }\n return `${stripped}\\n\\nCloses #${issue}`;\n}\n\nfunction stripClosingRefs(body: string): string {\n // Strip whole lines that consist of an optional bullet prefix plus a closing-keyword issue ref\n const linePattern =\n /^[ \\t]*[-*+]\\s+(?:close|closes|closed|fix|fixes|fixed|resolve|resolves|resolved)\\s*:?\\s*#\\d+\\s*$/gim;\n let result = body.replace(linePattern, \"\");\n\n // Strip remaining inline closing refs\n const inlinePattern =\n /(?:close|closes|closed|fix|fixes|fixed|resolve|resolves|resolved)\\s*:?\\s*#\\d+/gi;\n result = result.replace(inlinePattern, \"\").trimEnd();\n\n return result;\n}\n\nasync function resolveBodyText(\n defaultBody: string,\n options: PrBodyOptions\n): Promise<string> {\n if (options.body && options.bodyFile) {\n throw new Error(\"--body and --body-file cannot be used together\");\n }\n\n if (options.body !== undefined) {\n return options.body;\n }\n\n if (options.bodyFile !== undefined) {\n return await readFile(options.bodyFile, \"utf-8\");\n }\n\n return defaultBody;\n}\n\nfunction appendClosingRef(body: string, issue?: number): string {\n if (issue === undefined) {\n return body;\n }\n\n const existingRefs = extractClosingRefs(body);\n\n if (existingRefs.has(issue)) {\n return body;\n }\n\n return `${body}\\n\\nCloses #${issue}`;\n}\n\nfunction extractClosingRefs(body: string): Set<number> {\n const refs = new Set<number>();\n const pattern =\n /(?:close|closes|closed|fix|fixes|fixed|resolve|resolves|resolved)\\s*:?\\s*#(\\d+)/gi;\n let match;\n\n while ((match = pattern.exec(body)) !== null) {\n refs.add(parseInt(match[1], 10));\n }\n\n return refs;\n}\n","import type { PRProvider } from \"../providers/pr-provider\";\nimport { sleep } from \"../shared/common\";\nimport type { PourkitLogger } from \"../shared/common\";\n\nconst RED_CHECK_CONCLUSIONS = new Set([\n \"FAILURE\",\n \"CANCELLED\",\n \"TIMED_OUT\",\n \"STARTUP_FAILURE\",\n \"ACTION_REQUIRED\",\n \"STALE\",\n]);\n\nexport interface WaitForBranchChecksOptions {\n branchName: string;\n checksFoundTimeoutMs?: number;\n checksCompletionTimeoutMs?: number;\n pollIntervalMs?: number;\n stableHeadMs?: number;\n}\n\nexport async function waitForBranchChecks(\n prProvider: PRProvider,\n logger: PourkitLogger,\n options: WaitForBranchChecksOptions\n): Promise<void> {\n const checksFoundTimeoutMs = options.checksFoundTimeoutMs ?? 60 * 1000;\n const checksCompletionTimeoutMs =\n options.checksCompletionTimeoutMs ?? 5 * 60 * 1000;\n const pollIntervalMs = options.pollIntervalMs ?? 15 * 1000;\n const stableHeadMs = options.stableHeadMs ?? pollIntervalMs;\n\n let lastHeadSha = \"\";\n let headStableSince = 0;\n let checksFoundDeadline = 0;\n let checksCompletionDeadline = 0;\n let checksDiscovered = false;\n\n logger.step(\"wait\", `waiting for ${options.branchName} to be green`);\n\n while (true) {\n const observedAt = Date.now();\n const status = await prProvider.getBranchStatus(options.branchName);\n\n if (status.headSha !== lastHeadSha) {\n logger.step(\n \"info\",\n `branch head changed to ${status.headSha.substring(0, 7)}`\n );\n lastHeadSha = status.headSha;\n headStableSince = observedAt;\n if (checksFoundDeadline === 0) {\n checksFoundDeadline = observedAt + checksFoundTimeoutMs;\n }\n checksCompletionDeadline = 0;\n checksDiscovered = false;\n }\n\n if (status.checks.length > 0 && !checksDiscovered) {\n checksDiscovered = true;\n checksCompletionDeadline = observedAt + checksCompletionTimeoutMs;\n logger.step(\"info\", `Checks: ${formatChecks(status.checks)}`);\n }\n\n if (status.state === \"red\") {\n const failedChecks = status.checks\n .filter(\n (c) =>\n c.conclusion !== null && RED_CHECK_CONCLUSIONS.has(c.conclusion)\n )\n .map((c) => c.name)\n .join(\", \");\n throw new Error(\n `Target branch ${options.branchName} is red: ${failedChecks}`\n );\n }\n\n if (status.state === \"green\") {\n const stableForMs = observedAt - headStableSince;\n if (stableForMs < stableHeadMs) {\n logger.step(\n \"info\",\n `target branch is green; waiting for stable head (${stableForMs}/${stableHeadMs}ms)`\n );\n await sleep(pollIntervalMs);\n continue;\n }\n\n logger.step(\"success\", `target branch ${options.branchName} is green`);\n return;\n }\n\n const stableForMs = observedAt - headStableSince;\n if (!checksDiscovered && status.checks.length === 0) {\n if (observedAt >= checksFoundDeadline) {\n if (stableForMs >= stableHeadMs) {\n logger.step(\n \"success\",\n `target branch ${options.branchName} has no checks`\n );\n return;\n }\n\n throw new Error(\n `Timeout waiting for ${options.branchName} to be green`\n );\n }\n\n logger.step(\n \"info\",\n `target branch has no checks yet, waiting... (${secondsRemaining(checksFoundDeadline, observedAt)}s remaining)`\n );\n await sleep(pollIntervalMs);\n continue;\n }\n\n if (checksDiscovered) {\n if (observedAt >= checksCompletionDeadline) {\n throw new Error(\n `Timeout waiting for ${options.branchName} to be green`\n );\n }\n\n logger.step(\n \"info\",\n `target branch is ${status.state}, waiting... (${secondsRemaining(checksCompletionDeadline, observedAt)}s remaining)`\n );\n await sleep(pollIntervalMs);\n continue;\n }\n\n logger.step(\n \"info\",\n `target branch is ${status.state}, waiting... (${secondsRemaining(checksFoundDeadline, observedAt)}s remaining)`\n );\n await sleep(pollIntervalMs);\n }\n}\n\nfunction formatChecks(\n checks: { name: string; conclusion: string | null; status: string | null }[]\n) {\n return checks\n .map((check) => `${check.name}=${check.conclusion ?? check.status}`)\n .join(\", \");\n}\n\nfunction secondsRemaining(deadline: number, observedAt: number) {\n return Math.max(0, Math.ceil((deadline - observedAt) / 1000));\n}\n","import type {\n MergePrOptions,\n PRProvider,\n PullRequest,\n WaitForPrChecksOptions,\n} from \"../providers/pr-provider\";\nimport type { PourkitLogger } from \"../shared/common\";\nimport { waitForBranchChecks } from \"./target-green\";\nimport { Effect, Either } from \"effect\";\nimport { UnknownException } from \"effect/Cause\";\n\nexport interface MergeCoordinatorOptions {\n prProvider: PRProvider;\n logger: PourkitLogger;\n prNumber: number;\n targetBranch: string;\n matchHeadCommit: string;\n checkWaitOptions: WaitForPrChecksOptions;\n autoMerge?: boolean;\n pr?: PullRequest;\n method?: MergePrOptions[\"method\"];\n waitForTargetGreen?: boolean;\n}\n\nexport type MergeCoordinatorResult =\n | { stage: \"completed\"; merged: true }\n | { stage: \"merge\"; merged: false; error: Error }\n | { stage: \"target-green\"; merged: true; error: Error };\n\nfunction unwrapError(error: unknown): unknown {\n if (error instanceof UnknownException && error.error !== undefined) {\n return error.error;\n }\n return error;\n}\n\nexport function runMergeCoordinator(\n options: MergeCoordinatorOptions\n): Effect.Effect<MergeCoordinatorResult> {\n const {\n prProvider,\n logger,\n prNumber,\n targetBranch,\n matchHeadCommit,\n checkWaitOptions,\n } = options;\n const method = options.method ?? \"squash\";\n const waitForTargetGreen = options.waitForTargetGreen ?? true;\n\n return Effect.gen(function* () {\n const checksEither = yield* Effect.either(\n Effect.tryPromise(() =>\n prProvider.waitForPrChecks(prNumber, checkWaitOptions)\n )\n );\n if (Either.isLeft(checksEither)) {\n const rawError = checksEither.left;\n const error = unwrapError(rawError);\n return {\n stage: \"merge\" as const,\n merged: false as const,\n error: error instanceof Error ? error : new Error(String(error)),\n } as MergeCoordinatorResult;\n }\n\n const mergeEither = yield* Effect.either(\n Effect.tryPromise(() =>\n prProvider.mergePr(prNumber, { method, matchHeadCommit })\n )\n );\n if (Either.isLeft(mergeEither)) {\n const rawError = mergeEither.left;\n const error = unwrapError(rawError);\n return {\n stage: \"merge\" as const,\n merged: false as const,\n error: error instanceof Error ? error : new Error(String(error)),\n } as MergeCoordinatorResult;\n }\n\n if (waitForTargetGreen) {\n const targetEither = yield* Effect.either(\n Effect.tryPromise(() =>\n waitForBranchChecks(prProvider, logger, {\n branchName: targetBranch,\n checksFoundTimeoutMs: checkWaitOptions.checksFoundTimeoutMs,\n checksCompletionTimeoutMs:\n checkWaitOptions.checksCompletionTimeoutMs,\n pollIntervalMs: checkWaitOptions.pollIntervalMs,\n })\n )\n );\n if (Either.isLeft(targetEither)) {\n const rawError = targetEither.left;\n const error = unwrapError(rawError);\n return {\n stage: \"target-green\" as const,\n merged: true as const,\n error: error instanceof Error ? error : new Error(String(error)),\n } as MergeCoordinatorResult;\n }\n }\n\n return { stage: \"completed\" as const, merged: true as const };\n });\n}\n","import { existsSync, readFileSync } from \"fs\";\nimport { join } from \"path\";\nimport type { IssueData, PourkitConfig, Target } from \"../shared/config\";\nimport {\n resolvePromptTemplatePath,\n resolveMissingOrEmptyOutputRetries,\n} from \"../shared/config\";\nimport type { ExecutionProvider } from \"../execution/execution-provider\";\nimport { executeWithMissingOrEmptyArtifactRetry } from \"../execution/agent-output-retry\";\nimport type { PourkitLogger } from \"../shared/common\";\nimport { appendProtectedWorkGuidance } from \"../shared/prompt-guidance\";\nimport {\n buildRunContextArtifact,\n RUN_CONTEXT_PATH_IN_WORKTREE,\n STAGE_SECTIONS,\n} from \"../shared/run-context\";\nimport { validateAgentArtifact } from \"./artifact-validation\";\n\nexport const ISSUE_FINAL_REVIEW_ARTIFACT_PATH = join(\n \".pourkit\",\n \".tmp\",\n \"issue-final-review\",\n \"agent-output.json\"\n);\n\nexport interface RunIssueFinalReviewAgentOptions {\n executionProvider: ExecutionProvider;\n config: PourkitConfig;\n target: Target;\n issue: IssueData;\n parentPrdIssue?: IssueData;\n builderBranch: string;\n worktreePath: string;\n /** Reserved for I-05 wiring. Not yet consumed by runIssueFinalReviewAgent. */\n reviewArtifactPath?: string;\n repoRoot: string;\n logger: PourkitLogger;\n}\n\nexport type IssueFinalReviewResult =\n | {\n verdict: \"pass\";\n artifactPath: string;\n selfRetouched: boolean;\n changedPaths: string[];\n verificationPassed: boolean;\n }\n | {\n verdict: \"needs_human_review\";\n artifactPath: string;\n needsHumanReason: string;\n selfRetouched: boolean;\n changedPaths: string[];\n };\n\nexport async function runIssueFinalReviewAgent(\n options: RunIssueFinalReviewAgentOptions\n): Promise<IssueFinalReviewResult> {\n const {\n executionProvider,\n target,\n issue,\n parentPrdIssue,\n builderBranch,\n worktreePath,\n repoRoot,\n logger,\n } = options;\n\n const artifactPathInWorktree = ISSUE_FINAL_REVIEW_ARTIFACT_PATH;\n const artifactPath = join(worktreePath, artifactPathInWorktree);\n\n const strategy = target.strategy;\n const issueFinalReview = strategy.issueFinalReview;\n const agent = issueFinalReview;\n\n const prompt = loadIssueFinalReviewPrompt(repoRoot, agent.promptTemplate);\n\n const entry = await executeWithMissingOrEmptyArtifactRetry({\n executionProvider,\n missingOrEmptyRetries: resolveMissingOrEmptyOutputRetries(agent),\n logger,\n runningMessage: () => \"Running Issue Final Review agent\",\n retryMessage: (attempt, total) =>\n `Retrying Issue Final Review after empty output (${attempt}/${total})`,\n executionOptions: {\n stage: \"issueFinalReview\",\n agent: agent.agent,\n model: agent.model,\n variant: agent.variant,\n env: agent.env,\n prompt,\n target,\n repoRoot,\n branchName: builderBranch,\n sandbox: options.config.sandbox,\n autoApprove: true,\n artifactPath: artifactPathInWorktree,\n worktreePath,\n artifacts: [\n buildRunContextArtifact({\n issue,\n parentPrdIssue,\n target,\n branchName: builderBranch,\n repoRoot,\n reviewerCriteria: strategy.review.reviewer.criteria,\n sections: STAGE_SECTIONS.issueFinalReview,\n }),\n ],\n logger,\n },\n });\n\n const executionResult = entry.executionResult;\n if (!executionResult.success) {\n throw new Error(\n `Issue Final Review agent execution failed: ${executionResult.error}`\n );\n }\n\n let content: string;\n if (entry.artifact._tag === \"content\") {\n content = entry.artifact.value;\n } else if (entry.artifact._tag === \"empty\") {\n throw new Error(\n `Issue Final Review agent produced empty output at ${artifactPath}`\n );\n } else {\n throw new Error(\n `Issue Final Review agent did not produce output at ${artifactPath}`\n );\n }\n\n const validation = validateAgentArtifact({\n kind: \"issue-final-review\",\n artifactPath,\n issueNumber: issue.number,\n branchName: builderBranch,\n });\n if (!validation.ok) {\n throw new Error(\n `Issue Final Review artifact validation failed: ${validation.reason}`\n );\n }\n\n const parsed = JSON.parse(content);\n const verdict = parsed.verdict as string;\n\n if (verdict === \"pass\") {\n return {\n verdict: \"pass\",\n artifactPath,\n selfRetouched: parsed.selfRetouched === true,\n changedPaths: parsed.changedPaths as string[],\n verificationPassed: parsed.verification?.passed === true,\n };\n }\n\n if (verdict === \"needs_human_review\") {\n return {\n verdict: \"needs_human_review\",\n artifactPath,\n needsHumanReason: parsed.needsHumanReason as string,\n selfRetouched: parsed.selfRetouched === true,\n changedPaths: parsed.changedPaths as string[],\n };\n }\n\n throw new Error(\n `Unknown Issue Final Review verdict: ${JSON.stringify(verdict)}`\n );\n}\n\nfunction loadIssueFinalReviewPrompt(\n repoRoot: string,\n promptTemplate: string\n): string {\n const promptPath = resolvePromptTemplatePath(repoRoot, promptTemplate);\n const promptBody = existsSync(promptPath)\n ? readFileSync(promptPath, \"utf-8\")\n : promptTemplate;\n\n return appendProtectedWorkGuidance(`${promptBody}\n\n## Shared Run Context\n\nRead the selected issue requirements, PRD context, comments, branch context, verification commands, and artifact paths from: ${RUN_CONTEXT_PATH_IN_WORKTREE}`);\n}\n","export interface IssueTransitionLabels {\n blocked: string;\n readyForAgent: string;\n needsTriage: string;\n agentInProgress: string;\n readyForHuman: string;\n prOpenAwaitingMerge: string;\n}\n\nexport interface IssueTransitionsContract {\n removeBlocked(issueNumber: number): Promise<void>;\n addReadyForAgent(issueNumber: number): Promise<void>;\n moveToNeedsTriage(issueNumber: number): Promise<void>;\n moveToReadyForHuman(issueNumber: number): Promise<void>;\n closeCompleted(issueNumber: number): Promise<void>;\n}\n\nexport interface IssueTransitionDeps {\n fetchIssue(issueNumber: number): Promise<{ labels: string[] }>;\n addLabels(issueNumber: number, labels: string[]): Promise<void>;\n removeLabel(issueNumber: number, label: string): Promise<void>;\n closeIssue?(issueNumber: number): Promise<void>;\n updateLabels?(\n issueNumber: number,\n removes: string[],\n adds: string[]\n ): Promise<void>;\n}\n\nexport function createIssueTransitions(\n deps: IssueTransitionDeps,\n labels: IssueTransitionLabels\n): IssueTransitionsContract {\n return {\n async removeBlocked(issueNumber: number): Promise<void> {\n await deps.removeLabel(issueNumber, labels.blocked);\n },\n async addReadyForAgent(issueNumber: number): Promise<void> {\n const issue = await deps.fetchIssue(issueNumber);\n if (!issue.labels.includes(labels.readyForAgent)) {\n await deps.addLabels(issueNumber, [labels.readyForAgent]);\n }\n },\n async moveToNeedsTriage(issueNumber: number): Promise<void> {\n if (deps.updateLabels) {\n await deps.updateLabels(\n issueNumber,\n [labels.blocked, labels.readyForAgent],\n [labels.needsTriage]\n );\n } else {\n await deps.removeLabel(issueNumber, labels.blocked);\n const issue = await deps.fetchIssue(issueNumber);\n if (issue.labels.includes(labels.readyForAgent)) {\n await deps.removeLabel(issueNumber, labels.readyForAgent);\n }\n await deps.addLabels(issueNumber, [labels.needsTriage]);\n }\n },\n async moveToReadyForHuman(issueNumber: number): Promise<void> {\n try {\n await deps.removeLabel(issueNumber, labels.agentInProgress);\n } catch {\n // Ignore - label may not exist\n }\n try {\n await deps.removeLabel(issueNumber, labels.readyForAgent);\n } catch {\n // Ignore - label may not exist\n }\n await deps.addLabels(issueNumber, [labels.readyForHuman]);\n },\n async closeCompleted(issueNumber: number): Promise<void> {\n try {\n await deps.removeLabel(issueNumber, labels.agentInProgress);\n } catch {\n // Ignore - label may not exist\n }\n try {\n await deps.removeLabel(issueNumber, labels.prOpenAwaitingMerge);\n } catch {\n // Ignore - label may not exist\n }\n if (!deps.closeIssue) {\n throw new Error(\"closeIssue is required for closeCompleted\");\n }\n await deps.closeIssue(issueNumber);\n },\n };\n}\n","const BODY_PARENT_SECTION_REGEX = /## Parent\\s*\\n([\\s\\S]*?)(?=\\n## |$)/i;\nconst AFFECTED_CODE_PATHS_SECTION_REGEX =\n /## Affected code paths\\s*\\n([\\s\\S]*?)(?=\\n## |$)/i;\nconst PRD_REF_REGEX = /\\b(PRD-\\d+)\\b/i;\nconst CHILD_TITLE_REGEX = /^\\s*(PRD-\\d+)\\s*\\/\\s*I-\\d+\\b/i;\n\nexport type ParsedStackedIssue = {\n parentRef?: string;\n parentSource?: \"body\" | \"title\";\n bodyParentRef?: string;\n titleParentRef?: string;\n affectedCodePaths: string[];\n isChildIssue: boolean;\n siblingGroupingKey?: string;\n warnings: string[];\n};\n\nexport function parseStackedIssue(\n title: string,\n body: string | null\n): ParsedStackedIssue {\n const bodyParentRef = parseParentRefFromBody(body);\n const titleParentRef = parseParentRefFromTitle(title);\n const warnings: string[] = [];\n\n if (bodyParentRef && titleParentRef && bodyParentRef !== titleParentRef) {\n warnings.push(\n `Parent mismatch: body references ${bodyParentRef} but title references ${titleParentRef}`\n );\n }\n\n const parentRef = bodyParentRef ?? titleParentRef;\n const parentSource = bodyParentRef\n ? \"body\"\n : titleParentRef\n ? \"title\"\n : undefined;\n\n return {\n parentRef,\n parentSource,\n bodyParentRef,\n titleParentRef,\n affectedCodePaths: parseAffectedCodePaths(body),\n isChildIssue: Boolean(bodyParentRef ?? titleParentRef),\n siblingGroupingKey: parentRef,\n warnings,\n };\n}\n\nexport function parseParentRefFromBody(\n body: string | null\n): string | undefined {\n if (!body) return undefined;\n\n const section = body.match(BODY_PARENT_SECTION_REGEX)?.[1];\n if (!section) return undefined;\n\n return normalizeParentRef(section.match(PRD_REF_REGEX)?.[1]);\n}\n\nexport function parseParentRefFromTitle(title: string): string | undefined {\n return normalizeParentRef(title.match(CHILD_TITLE_REGEX)?.[1]);\n}\n\nexport function parseAffectedCodePaths(body: string | null): string[] {\n if (!body) return [];\n\n const section = body.match(AFFECTED_CODE_PATHS_SECTION_REGEX)?.[1];\n if (!section) return [];\n\n const paths = new Set<string>();\n\n for (const rawLine of section.split(\"\\n\")) {\n const line = rawLine.trim();\n\n if (!line.startsWith(\"-\")) continue;\n\n if (/^-\\s+(Class\\/Module|Functions\\/Methods|New):/i.test(line)) {\n continue;\n }\n\n const inlineCodePath = line.match(/`([^`]+)`/)?.[1]?.trim();\n if (inlineCodePath) {\n paths.add(inlineCodePath);\n continue;\n }\n\n const plainPath = line.replace(/^-\\s+/, \"\").trim();\n if (looksLikeRepoPath(plainPath)) {\n paths.add(plainPath);\n }\n }\n\n return Array.from(paths);\n}\n\nfunction normalizeParentRef(ref: string | undefined): string | undefined {\n if (!ref) return undefined;\n return ref\n .trim()\n .toUpperCase()\n .replace(/^(PRD-)(\\d+)$/, (_, p, n) => `${p}${n.padStart(4, \"0\")}`);\n}\n\nfunction looksLikeRepoPath(value: string): boolean {\n return /[./][A-Za-z0-9_-]/.test(value) && !value.includes(\":\");\n}\n","import type { PourkitConfig, ResolvedPrdRunMode } from \"../shared/config\";\nimport type { IssueProvider } from \"../providers/issue-provider\";\nimport type { PRProvider } from \"../providers/pr-provider\";\nimport type {\n ExecutionProvider,\n ExecutionSession,\n} from \"../execution/execution-provider\";\nimport type { PourkitLogger } from \"../shared/common\";\nimport {\n startIssueRun,\n advanceIssueRunReview,\n advanceIssueFinalReview,\n completeIssueRun,\n failIssueRun,\n transitionIssueToHumanHandoff,\n type IssueRunStartResult,\n type RunIssueResult,\n} from \"./issue-run\";\nimport { createIssueTransitions } from \"../issues/issue-transitions\";\nimport { StageFailure } from \"../failure-resolution/types\";\n\nclass HumanHandoffStop extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"HumanHandoffStop\";\n }\n}\n\nexport interface RunIssueOptions {\n issueNumber: number;\n targetName?: string;\n config: PourkitConfig;\n issueProvider: IssueProvider;\n prProvider: PRProvider;\n executionProvider: ExecutionProvider;\n force: boolean;\n resetWorktree?: boolean;\n logger: PourkitLogger;\n repoRoot: string;\n baseBranchOverride?: string;\n prdRunMode?: ResolvedPrdRunMode;\n}\n\nexport type { RunIssueResult };\n\nexport async function runIssueCommand(\n options: RunIssueOptions\n): Promise<RunIssueResult> {\n const {\n issueNumber,\n config,\n issueProvider,\n prProvider,\n executionProvider,\n logger,\n } = options;\n\n const ROOT = options.repoRoot;\n\n let executionSession: ExecutionSession | undefined;\n\n try {\n executionSession = await executionProvider.createSession?.();\n const runOptions = executionSession\n ? { ...options, executionProvider: executionSession }\n : options;\n\n const startResult: IssueRunStartResult = await startIssueRun(runOptions);\n const {\n issue,\n parentPrdIssue,\n target,\n effectiveTarget,\n branchName,\n worktreeState,\n executionResult,\n } = startResult;\n\n let reviewArtifactPath: string | undefined;\n\n const reviewAlreadyPassed =\n worktreeState?.review.lastVerdict &&\n [\"PASS\", \"PASS_WITH_NOTES\"].includes(worktreeState.review.lastVerdict) &&\n !worktreeState.review.exhaustedPreviousRun;\n\n if (reviewAlreadyPassed) {\n reviewArtifactPath = worktreeState.review.lastArtifactPath;\n } else {\n const lifetimeIterationsFromState =\n worktreeState?.review.lifetimeIterations ?? 0;\n const humanHandoffResolved =\n worktreeState?.review.lastVerdict === \"NEEDS_HUMAN\";\n const reviewResult = await advanceIssueRunReview({\n executionProvider: runOptions.executionProvider,\n config,\n target: effectiveTarget,\n issue,\n parentPrdIssue,\n builderBranch: branchName,\n worktreePath: executionResult.worktreePath,\n repoRoot: ROOT,\n logger,\n startingLifetimeIteration: lifetimeIterationsFromState,\n humanHandoffResolved,\n serena: startResult.serena,\n });\n\n if (reviewResult.exhaustedMaxIterations) {\n throw new Error(\n `Max review iterations (${reviewResult.iterations}) exhausted`\n );\n }\n\n if (reviewResult.verdict === \"FAIL\") {\n throw new Error(`Review failed with FAIL verdict`);\n }\n\n if (reviewResult.verdict === \"NEEDS_HUMAN\") {\n await transitionIssueToHumanHandoff({\n issueProvider,\n issueNumber,\n config,\n logger,\n reviewResult,\n });\n throw new HumanHandoffStop(\n `Review requires human handoff: NEEDS_HUMAN verdict`\n );\n }\n\n reviewArtifactPath = reviewResult.artifactPath;\n }\n\n const finalReviewResult = await advanceIssueFinalReview({\n executionProvider: runOptions.executionProvider,\n config,\n target: effectiveTarget,\n issue,\n parentPrdIssue,\n builderBranch: branchName,\n worktreePath: executionResult.worktreePath,\n repoRoot: ROOT,\n logger,\n reviewArtifactPath,\n worktreeState,\n });\n\n if (finalReviewResult.verdict === \"needs_human_review\") {\n const transitions = createIssueTransitions(\n {\n fetchIssue: issueProvider.fetchIssue.bind(issueProvider),\n addLabels: issueProvider.addLabels.bind(issueProvider),\n removeLabel: issueProvider.removeLabel.bind(issueProvider),\n closeIssue: issueProvider.closeIssue.bind(issueProvider),\n },\n {\n blocked: config.labels.blocked,\n readyForAgent: config.labels.readyForAgent,\n needsTriage: config.labels.needsTriage,\n agentInProgress: config.labels.agentInProgress,\n readyForHuman: config.labels.readyForHuman,\n prOpenAwaitingMerge: config.labels.prOpenAwaitingMerge,\n }\n );\n await transitions.moveToReadyForHuman(issueNumber);\n\n const comment = [\n \"Pourkit stopped the Issue Final Review because human review is needed.\",\n \"\",\n finalReviewResult.needsHumanReason,\n \"\",\n \"Artifacts:\",\n `- Issue Final Review: ${finalReviewResult.artifactPath}`,\n ].join(\"\\n\");\n await issueProvider.commentIssue(issueNumber, comment);\n\n logger.step(\n \"info\",\n `Issue Final Review requires human handoff for issue ${issueNumber}`\n );\n\n throw new HumanHandoffStop(\n `Issue Final Review requires human handoff: ${finalReviewResult.needsHumanReason}`\n );\n }\n\n return await completeIssueRun({\n ...runOptions,\n startResult,\n reviewArtifactPath,\n });\n } catch (error) {\n if (error instanceof HumanHandoffStop) {\n throw error;\n }\n\n if (error instanceof Error && \"_tag\" in error) {\n await failIssueRun({\n issueProvider,\n issueNumber,\n config,\n logger,\n error: `[${(error as Record<string, unknown>)._tag}] ${error.message}`,\n });\n } else {\n await failIssueRun({\n issueProvider,\n issueNumber,\n config,\n logger,\n error: error instanceof Error ? error : String(error),\n });\n }\n throw error;\n } finally {\n await executionSession?.close();\n }\n}\n","import type { IssueData } from \"../shared/config\";\nimport { parseStackedIssue } from \"../issues/stacked-issue\";\nimport type { BlockedIssue } from \"../issues/blocked-issue\";\nimport type {\n IssueProvider,\n CreateIssueOptions,\n CreatedIssue,\n} from \"./issue-provider\";\nimport type { GitHubClient } from \"./github-client\";\n\nexport class GitHubIssueProvider implements IssueProvider {\n private readonly client: GitHubClient;\n private readonly readyForAgentLabel: string;\n private readonly blockedLabel: string;\n private readonly issueListLimit: number;\n\n constructor(\n client: GitHubClient,\n options?: {\n readyForAgentLabel?: string;\n blockedLabel?: string;\n issueListLimit?: number;\n }\n ) {\n this.client = client;\n this.readyForAgentLabel = options?.readyForAgentLabel ?? \"ready-for-agent\";\n this.blockedLabel = options?.blockedLabel ?? \"blocked\";\n this.issueListLimit = options?.issueListLimit ?? 50;\n }\n\n async createIssue(options: CreateIssueOptions): Promise<CreatedIssue> {\n const { data } = await this.client.octokit.rest.issues.create({\n owner: this.client.owner,\n repo: this.client.repo,\n title: options.title,\n body: options.body ?? \"\",\n labels: options.labels,\n assignees: options.assignees,\n });\n return { number: data.number, url: data.html_url, title: data.title };\n }\n\n async fetchIssue(number: number): Promise<IssueData> {\n const { data } = await this.client.octokit.rest.issues.get({\n owner: this.client.owner,\n repo: this.client.repo,\n issue_number: number,\n });\n\n const commentsData = await this.client.octokit.paginate(\n this.client.octokit.rest.issues.listComments,\n {\n owner: this.client.owner,\n repo: this.client.repo,\n issue_number: number,\n }\n );\n\n return {\n number: data.number,\n title: data.title,\n body: data.body ?? \"\",\n state: data.state as \"open\" | \"closed\",\n labels: data.labels.map((l) =>\n typeof l === \"string\" ? l : (l.name ?? \"\")\n ),\n comments: commentsData.map((c) => c.body ?? \"\"),\n };\n }\n\n async addLabels(issueNumber: number, labels: string[]): Promise<void> {\n if (labels.length === 0) return;\n await this.client.octokit.rest.issues.addLabels({\n owner: this.client.owner,\n repo: this.client.repo,\n issue_number: issueNumber,\n labels,\n });\n }\n\n async removeLabel(issueNumber: number, label: string): Promise<void> {\n await this.client.octokit.rest.issues.removeLabel({\n owner: this.client.owner,\n repo: this.client.repo,\n issue_number: issueNumber,\n name: label,\n });\n }\n\n async closeIssue(issueNumber: number): Promise<void> {\n const { data } = await this.client.octokit.rest.issues.get({\n owner: this.client.owner,\n repo: this.client.repo,\n issue_number: issueNumber,\n });\n if (data.pull_request) return;\n\n const maxRetries = 3;\n const backoffMs = 2000;\n\n for (let attempt = 1; attempt <= maxRetries; attempt++) {\n try {\n await this.client.octokit.rest.issues.update({\n owner: this.client.owner,\n repo: this.client.repo,\n issue_number: issueNumber,\n state: \"closed\",\n state_reason: \"completed\",\n });\n return;\n } catch (error) {\n const isTransient =\n error instanceof Error && /HTTP (502|503|504)\\b/.test(error.message);\n const isOctokitTransient =\n typeof error === \"object\" &&\n error !== null &&\n \"status\" in error &&\n (error.status === 502 ||\n error.status === 503 ||\n error.status === 504);\n if ((!isTransient && !isOctokitTransient) || attempt === maxRetries) {\n throw error;\n }\n await new Promise((r) =>\n setTimeout(r, backoffMs * Math.pow(2, attempt - 1))\n );\n }\n }\n }\n\n async commentIssue(issueNumber: number, body: string): Promise<void> {\n await this.client.octokit.rest.issues.createComment({\n owner: this.client.owner,\n repo: this.client.repo,\n issue_number: issueNumber,\n body,\n });\n }\n\n async getComments(issueNumber: number): Promise<string[]> {\n const data = await this.client.octokit.paginate(\n this.client.octokit.rest.issues.listComments,\n {\n owner: this.client.owner,\n repo: this.client.repo,\n issue_number: issueNumber,\n }\n );\n return data.map((comment) => comment.body ?? \"\");\n }\n\n async listCandidates(): Promise<IssueData[]> {\n const data = await this.client.octokit.paginate(\n this.client.octokit.rest.issues.listForRepo,\n {\n owner: this.client.owner,\n repo: this.client.repo,\n state: \"open\",\n labels: this.readyForAgentLabel,\n per_page: 100,\n }\n );\n\n return data\n .filter((issue) => !issue.pull_request)\n .map((issue) => mapRawIssue(issue))\n .slice(0, this.issueListLimit);\n }\n\n async listBlockedIssues(): Promise<BlockedIssue[]> {\n const data = await this.client.octokit.paginate(\n this.client.octokit.rest.issues.listForRepo,\n {\n owner: this.client.owner,\n repo: this.client.repo,\n state: \"open\",\n labels: this.blockedLabel,\n per_page: 100,\n }\n );\n\n return data\n .filter((issue) => !issue.pull_request)\n .map((issue) => ({\n number: issue.number,\n title: issue.title,\n body: issue.body ?? null,\n labels: issue.labels.map((l) => ({\n name: typeof l === \"string\" ? l : (l.name ?? \"\"),\n })),\n }))\n .slice(0, this.issueListLimit);\n }\n\n async listRelatedIssues(parentRef: string): Promise<IssueData[]> {\n const data = await this.client.octokit.paginate(\n this.client.octokit.rest.issues.listForRepo,\n {\n owner: this.client.owner,\n repo: this.client.repo,\n state: \"all\",\n per_page: 100,\n }\n );\n\n return data\n .filter((issue) => !issue.pull_request)\n .map((issue) => mapRawIssue(issue))\n .slice(0, this.issueListLimit)\n .filter(\n (issue) =>\n parseStackedIssue(issue.title, issue.body).parentRef === parentRef\n );\n }\n\n async resolveIssueByCanonicalRef(ref: string): Promise<IssueData | null> {\n const canonical = ref.trim().toUpperCase();\n const data = await this.client.octokit.paginate(\n this.client.octokit.rest.issues.listForRepo,\n {\n owner: this.client.owner,\n repo: this.client.repo,\n state: \"all\",\n per_page: 100,\n }\n );\n\n const match = data\n .filter((issue) => !issue.pull_request)\n .slice(0, this.issueListLimit)\n .find((issue) => issue.title.toUpperCase().startsWith(`${canonical}:`));\n if (!match) return null;\n return mapRawIssue(match);\n }\n}\n\nfunction mapRawIssue(issue: {\n number: number;\n title: string;\n body?: string | null;\n state: string;\n labels: Array<{ name?: string | null } | string>;\n created_at?: string | null;\n}): IssueData {\n return {\n number: issue.number,\n title: issue.title,\n body: issue.body ?? \"\",\n state: issue.state.toLowerCase() as \"open\" | \"closed\",\n labels: issue.labels.map((l) =>\n typeof l === \"string\" ? l : (l.name ?? \"\")\n ),\n comments: [],\n createdAt: new Date(issue.created_at ?? \"\"),\n };\n}\n","import type {\n PRProvider,\n PullRequest,\n CreatePrOptions,\n CheckStatus,\n EnableAutoMergeOptions,\n MergePrOptions,\n WaitForPrChecksOptions,\n BranchStatus,\n} from \"./pr-provider\";\nimport { sleep } from \"../shared/common\";\nimport type { PourkitLogger } from \"../shared/common\";\nimport type { GitHubClient } from \"./github-client\";\n\nconst TERMINAL_FAILURE_STATES = new Set([\n \"FAILURE\",\n \"CANCELLED\",\n \"TIMED_OUT\",\n \"STARTUP_FAILURE\",\n \"ACTION_REQUIRED\",\n \"STALE\",\n]);\n\nconst GREEN_CHECK_CONCLUSIONS = new Set([\"SUCCESS\", \"NEUTRAL\", \"SKIPPED\"]);\n\nexport class GitHubPRProvider implements PRProvider {\n private client: GitHubClient;\n private logger: PourkitLogger;\n\n constructor(client: GitHubClient, logger: PourkitLogger) {\n this.client = client;\n this.logger = logger;\n }\n\n async createPr(options: CreatePrOptions): Promise<PullRequest> {\n this.logger.step(\"pr\", `creating PR \"${options.title}\"`);\n\n const { data } = await this.client.octokit.rest.pulls.create({\n owner: this.client.owner,\n repo: this.client.repo,\n title: options.title,\n body: options.body,\n head: options.head,\n base: options.base,\n });\n\n const pr = mapOctokitPr(data);\n\n this.logger.kv(\"PR_NUMBER\", String(pr.number));\n this.logger.kv(\"PR_URL\", pr.url);\n\n return pr;\n }\n\n async getPr(branchName: string): Promise<PullRequest | null> {\n try {\n const { data } = await this.client.octokit.rest.pulls.list({\n owner: this.client.owner,\n repo: this.client.repo,\n head: `${this.client.owner}:${branchName}`,\n state: \"all\",\n per_page: 1,\n });\n\n if (data.length === 0) {\n return null;\n }\n\n return mapOctokitPr(data[0]);\n } catch {\n return null;\n }\n }\n\n async getPrByNumber(prNumber: number): Promise<PullRequest | null> {\n try {\n const { data } = await this.client.octokit.rest.pulls.get({\n owner: this.client.owner,\n repo: this.client.repo,\n pull_number: prNumber,\n });\n\n return mapOctokitPr(data);\n } catch {\n return null;\n }\n }\n\n async getCheckStatus(prNumber: number): Promise<CheckStatus[]> {\n try {\n const { data: pr } = await this.client.octokit.rest.pulls.get({\n owner: this.client.owner,\n repo: this.client.repo,\n pull_number: prNumber,\n });\n\n const headSha = pr.head.sha;\n\n const [checkRuns, combinedStatusResponse] = await Promise.all([\n this.client.octokit.paginate(\n this.client.octokit.rest.checks.listForRef,\n {\n owner: this.client.owner,\n repo: this.client.repo,\n ref: headSha,\n }\n ),\n this.client.octokit.rest.repos.getCombinedStatusForRef({\n owner: this.client.owner,\n repo: this.client.repo,\n ref: headSha,\n }),\n ]);\n\n const checks: CheckStatus[] = [];\n\n for (const run of checkRuns) {\n checks.push({\n name: run.name,\n conclusion: mapCheckConclusion(run.conclusion),\n status: mapCheckRunStatus(run.status),\n });\n }\n\n for (const status of combinedStatusResponse.data.statuses) {\n checks.push(\n mapCommitStatus({ context: status.context, state: status.state })\n );\n }\n\n return checks;\n } catch (error) {\n this.logger.step(\n \"warn\",\n `Failed to get check status for PR #${prNumber}: ${error instanceof Error ? error.message : String(error)}`\n );\n return [];\n }\n }\n\n async enableAutoMerge(\n pr: PullRequest,\n options?: EnableAutoMergeOptions\n ): Promise<void> {\n const method = (options?.method ?? \"squash\").toUpperCase();\n\n await this.client.octokit.graphql(\n `mutation enablePullRequestAutoMerge(\n $pullRequestId: ID!\n $mergeMethod: PullRequestMergeMethod\n $expectedHeadOid: GitObjectID\n ) {\n enablePullRequestAutoMerge(input: {\n pullRequestId: $pullRequestId\n mergeMethod: $mergeMethod\n expectedHeadOid: $expectedHeadOid\n }) {\n pullRequest {\n id\n number\n }\n }\n }`,\n {\n pullRequestId: pr.nodeId,\n mergeMethod: method,\n expectedHeadOid: options?.expectedHeadOid,\n }\n );\n }\n\n async mergePr(prNumber: number, options?: MergePrOptions): Promise<void> {\n const method = options?.method ?? \"squash\";\n this.logger.step(\"pr\", `merging PR #${prNumber} with ${method} merge`);\n\n await this.client.octokit.rest.pulls.merge({\n owner: this.client.owner,\n repo: this.client.repo,\n pull_number: prNumber,\n merge_method: method,\n sha: options?.matchHeadCommit,\n });\n }\n\n async waitForPrChecks(\n prNumber: number,\n options?: WaitForPrChecksOptions\n ): Promise<CheckStatus[]> {\n const checksFoundTimeoutMs = options?.checksFoundTimeoutMs ?? 60 * 1000;\n const checksCompletionTimeoutMs =\n options?.checksCompletionTimeoutMs ?? 30 * 60 * 1000;\n const pollIntervalMs = options?.pollIntervalMs ?? 15 * 1000;\n const requiredChecks = options?.requiredChecks ?? [];\n\n const discoveredDeadline = Date.now() + checksFoundTimeoutMs;\n let completionDeadline = 0;\n let checksDiscovered = false;\n this.logger.step(\"pr\", `waiting for checks on PR #${prNumber}`);\n\n while (true) {\n const observedAt = Date.now();\n const checks = await this.getCheckStatus(prNumber);\n\n if (!hasRequiredChecks(checks, requiredChecks)) {\n if (Date.now() >= discoveredDeadline) {\n if (requiredChecks.length === 0) {\n this.logger.step(\n \"info\",\n \"No checks appeared within grace period, treating as passed\"\n );\n return [];\n }\n\n throw new Error(\n `Timeout waiting for required checks on PR #${prNumber}: ${requiredChecks.join(\", \")}`\n );\n }\n\n this.logger.step(\n \"info\",\n requiredChecks.length === 0\n ? `No checks found, waiting... (${secondsRemaining(discoveredDeadline, observedAt)}s remaining)`\n : `Waiting for required checks to appear: ${requiredChecks.join(\", \")} (${secondsRemaining(discoveredDeadline, observedAt)}s remaining)`\n );\n await sleep(pollIntervalMs);\n continue;\n }\n\n const filteredChecks = filterChecks(checks, requiredChecks);\n\n if (!checksDiscovered) {\n checksDiscovered = true;\n completionDeadline = observedAt + checksCompletionTimeoutMs;\n }\n\n this.logger.step(\"info\", `Checks: ${formatChecks(filteredChecks)}`);\n\n const evaluation = evaluateChecks(filteredChecks);\n if (evaluation.complete && evaluation.failed.length === 0) {\n this.logger.step(\"success\", \"All checks passed\");\n return checks;\n }\n\n if (evaluation.complete) {\n throw new Error(`Checks failed: ${formatChecks(evaluation.failed)}`);\n }\n\n if (Date.now() >= completionDeadline) {\n throw new Error(`Timeout waiting for checks on PR #${prNumber}`);\n }\n\n this.logger.step(\n \"info\",\n `Checks still pending, waiting... (${secondsRemaining(completionDeadline, observedAt)}s remaining)`\n );\n await sleep(pollIntervalMs);\n }\n }\n\n async getBranchStatus(branchName: string): Promise<BranchStatus> {\n this.logger.step(\"pr\", `getting branch status for ${branchName}`);\n\n try {\n const targetStatus = await this.getTargetBranchStatus(branchName);\n\n let state: BranchStatus[\"state\"] = \"pending\";\n\n if (targetStatus.checks.length > 0) {\n const hasFailure = targetStatus.checks.some(\n (check) =>\n check.conclusion !== null &&\n TERMINAL_FAILURE_STATES.has(check.conclusion)\n );\n const allComplete = targetStatus.checks.every(\n (check) => check.status === \"COMPLETED\"\n );\n const allGreen = targetStatus.checks.every(\n (check) =>\n check.conclusion !== null &&\n GREEN_CHECK_CONCLUSIONS.has(check.conclusion)\n );\n\n if (hasFailure) {\n state = \"red\";\n } else if (allComplete && allGreen) {\n state = \"green\";\n }\n }\n\n return {\n headSha: targetStatus.headSha,\n state,\n checks: targetStatus.checks,\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(\n `Failed to get branch status for ${branchName}: ${message}`\n );\n }\n }\n\n private async getTargetBranchStatus(\n branchName: string\n ): Promise<{ branchName: string; headSha: string; checks: CheckStatus[] }> {\n const { data: branch } = await this.client.octokit.rest.repos.getBranch({\n owner: this.client.owner,\n repo: this.client.repo,\n branch: branchName,\n });\n\n const headSha = branch.commit.sha;\n\n const [checkRuns, combinedStatusResponse] = await Promise.all([\n this.client.octokit.paginate(this.client.octokit.rest.checks.listForRef, {\n owner: this.client.owner,\n repo: this.client.repo,\n ref: headSha,\n }),\n this.client.octokit.rest.repos.getCombinedStatusForRef({\n owner: this.client.owner,\n repo: this.client.repo,\n ref: headSha,\n }),\n ]);\n\n return {\n branchName,\n headSha,\n checks: [\n ...checkRuns.map((check) => ({\n name: check.name,\n status: mapCheckRunStatus(check.status),\n conclusion: mapCheckConclusion(check.conclusion),\n })),\n ...combinedStatusResponse.data.statuses.map((status) =>\n mapCommitStatus(status)\n ),\n ],\n };\n }\n}\n\nfunction mapOctokitPr(data: {\n number: number;\n node_id: string;\n html_url: string;\n title: string;\n body: string | null;\n head: { ref: string; sha: string };\n base: { ref: string };\n state: string;\n merged?: boolean;\n draft?: boolean;\n merge_commit_sha?: string | null;\n}): PullRequest {\n return {\n number: data.number,\n nodeId: data.node_id,\n url: data.html_url,\n title: data.title,\n body: data.body ?? \"\",\n headRefName: data.head.ref,\n baseRefName: data.base.ref,\n state:\n data.state === \"closed\" ? (data.merged ? \"MERGED\" : \"CLOSED\") : \"OPEN\",\n headRefOid: data.head.sha,\n mergeCommitSha: data.merge_commit_sha ?? undefined,\n };\n}\n\nfunction mapCheckRunStatus(status: string): CheckStatus[\"status\"] {\n const normalized = status.toUpperCase();\n\n if (\n normalized === \"QUEUED\" ||\n normalized === \"IN_PROGRESS\" ||\n normalized === \"COMPLETED\" ||\n normalized === \"WAITING\" ||\n normalized === \"PENDING\" ||\n normalized === \"REQUESTED\"\n ) {\n return normalized as CheckStatus[\"status\"];\n }\n\n return null;\n}\n\nfunction mapCheckConclusion(\n conclusion: string | null\n): CheckStatus[\"conclusion\"] {\n const normalized = conclusion?.toUpperCase();\n\n if (\n normalized === \"SUCCESS\" ||\n normalized === \"FAILURE\" ||\n normalized === \"NEUTRAL\" ||\n normalized === \"SKIPPED\" ||\n normalized === \"STALE\" ||\n normalized === \"STARTUP_FAILURE\" ||\n normalized === \"CANCELLED\" ||\n normalized === \"TIMED_OUT\" ||\n normalized === \"ACTION_REQUIRED\"\n ) {\n return normalized as CheckStatus[\"conclusion\"];\n }\n\n return null;\n}\n\nfunction mapCommitStatus(status: {\n context: string;\n state: string;\n}): CheckStatus {\n const normalized = status.state.toUpperCase();\n\n if (normalized === \"SUCCESS\") {\n return { name: status.context, status: \"COMPLETED\", conclusion: \"SUCCESS\" };\n }\n\n if (normalized === \"PENDING\") {\n return { name: status.context, status: \"PENDING\", conclusion: null };\n }\n\n return { name: status.context, status: \"COMPLETED\", conclusion: \"FAILURE\" };\n}\n\nfunction filterChecks(checks: CheckStatus[], requiredChecks: string[]) {\n return requiredChecks.length > 0\n ? checks.filter((check) => requiredChecks.includes(check.name))\n : checks;\n}\n\nfunction hasRequiredChecks(checks: CheckStatus[], requiredChecks: string[]) {\n return requiredChecks.length === 0\n ? checks.length > 0\n : requiredChecks.every((name) =>\n checks.some((check) => check.name === name)\n );\n}\n\nfunction secondsRemaining(deadline: number, observedAt: number) {\n return Math.max(0, Math.ceil((deadline - observedAt) / 1000));\n}\n\nfunction evaluateChecks(checks: CheckStatus[]) {\n const failed = checks.filter(\n (check) =>\n check.status === \"COMPLETED\" &&\n check.conclusion !== null &&\n !isSuccessfulConclusion(check.conclusion)\n );\n\n return {\n complete: checks.every((check) => check.status === \"COMPLETED\"),\n failed,\n };\n}\n\nfunction isSuccessfulConclusion(\n conclusion: NonNullable<CheckStatus[\"conclusion\"]>\n) {\n return (\n conclusion === \"SUCCESS\" ||\n conclusion === \"NEUTRAL\" ||\n conclusion === \"SKIPPED\"\n );\n}\n\nfunction formatChecks(checks: CheckStatus[]) {\n return checks\n .map((check) => `${check.name}=${check.conclusion ?? check.status}`)\n .join(\", \");\n}\n","import { Octokit } from \"octokit\";\n\nexport interface GitHubClient {\n octokit: Octokit;\n owner: string;\n repo: string;\n}\n\nexport interface GitHubClientOptions {\n cwd?: string;\n env?: NodeJS.ProcessEnv;\n repository?: string;\n}\n\nconst REMOTE_PATTERN = /github\\.com[:/]([^/]+)\\/([^/]+?)(?:\\.git)?$/;\n\nexport function resolveGitHubToken(env: NodeJS.ProcessEnv): string {\n const token = env.POURKIT_GITHUB_TOKEN ?? env.GH_TOKEN ?? env.GITHUB_TOKEN;\n if (!token) {\n throw new Error(\n \"GitHub token is required. Set POURKIT_GITHUB_TOKEN, GH_TOKEN, or GITHUB_TOKEN.\"\n );\n }\n return token;\n}\n\nexport async function resolveGitHubRepository(\n options?: GitHubClientOptions\n): Promise<{ owner: string; repo: string }> {\n if (options?.repository) {\n const parts = options.repository.split(\"/\");\n if (parts.length !== 2 || !parts[0] || !parts[1]) {\n throw new Error(\n `Invalid repository format: \"${options.repository}\". Expected \"owner/repo\".`\n );\n }\n return { owner: parts[0], repo: parts[1] };\n }\n\n const env = options?.env ?? process.env;\n const envRepo = env.GITHUB_REPOSITORY;\n if (envRepo) {\n const parts = envRepo.split(\"/\");\n if (parts.length === 2 && parts[0] && parts[1]) {\n return { owner: parts[0], repo: parts[1] };\n }\n throw new Error(\n `Invalid repository format: \"${envRepo}\". Expected \"owner/repo\".`\n );\n }\n\n const { execCapture } = await import(\"../shared/common\");\n const cwd = options?.cwd;\n try {\n const result = await execCapture(\"git\", [\"remote\", \"get-url\", \"origin\"], {\n cwd,\n });\n const remote = result.stdout.trim();\n const match = remote.match(REMOTE_PATTERN);\n if (match) {\n return { owner: match[1], repo: match[2] };\n }\n } catch {\n // fall through to error\n }\n\n throw new Error(\n \"Could not resolve GitHub repository. Set GITHUB_REPOSITORY env var or ensure a valid 'origin' remote exists.\"\n );\n}\n\nexport async function requireGitHubClient(\n options?: GitHubClientOptions\n): Promise<GitHubClient> {\n const env = options?.env ?? process.env;\n const token = resolveGitHubToken(env);\n const repo = await resolveGitHubRepository(options);\n\n const octokit = new Octokit({ auth: token });\n\n return { octokit, ...repo };\n}\n\nexport async function tryCreateGitHubClient(\n options?: GitHubClientOptions\n): Promise<\n | { ok: true; client: GitHubClient }\n | {\n ok: false;\n reason: \"missing-token\" | \"missing-repository\" | \"invalid-repository\";\n message: string;\n }\n> {\n const env = options?.env ?? process.env;\n\n let token: string;\n try {\n token = resolveGitHubToken(env);\n } catch {\n return {\n ok: false,\n reason: \"missing-token\",\n message: \"GitHub token is not configured.\",\n };\n }\n\n let repo: { owner: string; repo: string };\n try {\n repo = await resolveGitHubRepository(options);\n } catch (e) {\n const message = e instanceof Error ? e.message : String(e);\n if (message.includes(\"Invalid repository format\")) {\n return { ok: false, reason: \"invalid-repository\", message };\n }\n return { ok: false, reason: \"missing-repository\", message };\n }\n\n const octokit = new Octokit({ auth: token });\n\n return { ok: true, client: { octokit, ...repo } };\n}\n","import type {\n AgentProvider,\n AgentCommandOptions,\n PrintCommand,\n} from \"@ai-hero/sandcastle\";\nimport { createWorktree, run } from \"@ai-hero/sandcastle\";\nimport { docker } from \"@ai-hero/sandcastle/sandboxes/docker\";\nimport { ensureSandboxImageBuilt } from \"./sandbox-image-build\";\nimport { buildSandboxOptions } from \"./sandbox-options\";\n\ntype DeterministicParsedStreamEvent =\n | {\n type: \"text\";\n text: string;\n }\n | {\n type: \"result\";\n result: string;\n }\n | {\n type: \"tool_call\";\n name: string;\n args: string;\n }\n | {\n type: \"session_id\";\n sessionId: string;\n };\nimport type {\n ExecutionProvider,\n ExecutionProviderOptions,\n ExecutionResult,\n} from \"./execution-provider\";\nimport { writeExecutionArtifacts } from \"./execution-provider\";\n\ninterface DeterministicAgentOptions {\n env?: Record<string, string>;\n}\n\nclass DeterministicAgentProvider implements AgentProvider {\n readonly name = \"deterministic-agent\";\n readonly env: Record<string, string>;\n readonly captureSessions = false;\n\n constructor(options?: DeterministicAgentOptions) {\n this.env = options?.env ?? {};\n }\n\n buildPrintCommand(_options: AgentCommandOptions): PrintCommand {\n return {\n command: \"bash pourkit/execution/deterministic-agent.sh\",\n };\n }\n\n parseStreamLine(line: string): DeterministicParsedStreamEvent[] {\n const events: DeterministicParsedStreamEvent[] = [];\n\n if (line.includes(\"<promise>COMPLETE</promise>\")) {\n events.push({\n type: \"text\",\n text: line,\n });\n events.push({\n type: \"result\",\n result: \"COMPLETE\",\n });\n } else if (line.trim().length > 0) {\n events.push({\n type: \"text\",\n text: line,\n });\n }\n\n return events;\n }\n}\n\nfunction resolveSandboxProvider(provider: string) {\n if (provider === \"docker\") {\n return docker;\n }\n\n throw new Error(`Unsupported sandbox provider: ${provider}`);\n}\n\nfunction sanitizeBranch(branchName: string) {\n return branchName.replace(/[^A-Za-z0-9._-]/g, \"-\");\n}\n\nexport class DeterministicExecutionProvider implements ExecutionProvider {\n lastResult: ExecutionResult | null = null;\n lastOptions: ExecutionProviderOptions | null = null;\n\n async execute(options: ExecutionProviderOptions): Promise<ExecutionResult> {\n this.lastOptions = options;\n const {\n stage,\n iteration,\n repoRoot: root,\n branchName,\n worktreePath,\n sandbox,\n timeoutMs,\n artifacts = [],\n logger,\n } = options;\n\n const stageLabel =\n iteration !== undefined ? `${stage}:${iteration}` : stage;\n logger.step(\n \"deterministic\",\n `[${stageLabel}] running deterministic agent (no LLM tokens)`\n );\n\n try {\n const logPath = `${root}/.pourkit/logs/${sanitizeBranch(branchName)}-deterministic-${Date.now()}.log`;\n\n await ensureSandboxImageBuilt(root, { force: sandbox.forceRebuild });\n\n const env: Record<string, string> = {\n POURKIT_STAGE: stage,\n POURKIT_BRANCH_NAME: branchName,\n };\n if (options.artifactPath) {\n env.POURKIT_ARTIFACT_PATH = options.artifactPath;\n }\n if (iteration !== undefined) {\n env.POURKIT_REVIEW_ITERATION = String(iteration);\n }\n\n const agent = new DeterministicAgentProvider({ env });\n\n const sandboxOptions = buildSandboxOptions(root, sandbox);\n const sandboxProvider = resolveSandboxProvider(sandbox.provider);\n let createdWorktreePath: string | undefined;\n const result = worktreePath\n ? await (async () => {\n await writeExecutionArtifacts(worktreePath, artifacts);\n return run({\n agent,\n sandbox: sandboxProvider(sandboxOptions),\n cwd: worktreePath,\n branchStrategy: { type: \"head\" },\n prompt: options.prompt,\n maxIterations: 1,\n logging: {\n type: \"file\",\n path: logPath,\n },\n completionSignal: \"<promise>COMPLETE</promise>\",\n ...(timeoutMs ? { signal: AbortSignal.timeout(timeoutMs) } : {}),\n });\n })()\n : await (async () => {\n const worktree = await createWorktree({\n cwd: root,\n branchStrategy: {\n type: \"branch\",\n branch: branchName,\n baseBranch: options.baseRef ?? options.target.baseBranch,\n },\n });\n createdWorktreePath = worktree.worktreePath;\n await writeExecutionArtifacts(worktree.worktreePath, artifacts);\n return worktree.run({\n agent,\n sandbox: sandboxProvider(sandboxOptions),\n prompt: options.prompt,\n maxIterations: 1,\n logging: {\n type: \"file\",\n path: logPath,\n },\n completionSignal: \"<promise>COMPLETE</promise>\",\n ...(timeoutMs ? { signal: AbortSignal.timeout(timeoutMs) } : {}),\n });\n })();\n\n const commits = result.commits.map((c) => c.sha);\n\n logger.kv(\"SANDBOX_SUCCESS\", \"true\");\n logger.kv(\"COMMITS_CREATED\", String(commits.length));\n logger.kv(\"WORKTREE_BRANCH\", result.branch);\n if (result.logFilePath) {\n logger.kv(\"LOG_FILE\", result.logFilePath);\n }\n\n const artifactOnlyStage = stage === \"reviewer\" || stage === \"finalizer\";\n\n if (commits.length === 0 && !artifactOnlyStage) {\n this.lastResult = {\n success: false,\n branch: result.branch,\n worktreePath: worktreePath ?? createdWorktreePath ?? \"\",\n commits: [],\n logPath,\n error: \"Deterministic agent returned zero commits\",\n };\n return this.lastResult;\n }\n\n this.lastResult = {\n success: true,\n branch: result.branch,\n worktreePath: worktreePath ?? createdWorktreePath ?? \"\",\n commits,\n logPath,\n };\n return this.lastResult;\n } catch (error) {\n logger.step(\n \"error\",\n `Deterministic execution failed: ${error instanceof Error ? error.message : String(error)}`\n );\n this.lastResult = {\n success: false,\n branch: \"\",\n worktreePath: \"\",\n commits: [],\n logPath: null,\n error: error instanceof Error ? error.message : String(error),\n };\n return this.lastResult;\n }\n }\n}\n","import path from \"node:path\";\n\nimport { execCapture } from \"../shared/common\";\nimport { sandboxImageName } from \"./sandbox-image\";\n\nexport async function ensureSandboxImageBuilt(\n repoRoot: string,\n options?: { force?: boolean }\n) {\n const imageName = sandboxImageName(repoRoot);\n const dockerfilePath = path.join(repoRoot, \".sandcastle\", \"Dockerfile\");\n\n if (!options?.force) {\n try {\n await execCapture(\"docker\", [\"image\", \"inspect\", imageName]);\n return;\n } catch {\n // image missing, fall through to build\n }\n }\n\n const buildArgs = [\"build\", \"-t\", imageName, \"-f\", dockerfilePath];\n if (options?.force) {\n buildArgs.push(\"--pull\", \"--no-cache\");\n }\n buildArgs.push(repoRoot);\n\n await execCapture(\"docker\", buildArgs);\n}\n","import { createHash } from \"node:crypto\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport path from \"node:path\";\n\nexport function sandboxImageName(repoRoot: string): string {\n const dirName = path.basename(repoRoot.replace(/[\\\\/]+$/, \"\")) || \"local\";\n const sanitized = dirName.toLowerCase().replace(/[^a-z0-9_.-]/g, \"-\");\n const baseName = sanitized || \"local\";\n const dockerfilePath = path.join(repoRoot, \".sandcastle\", \"Dockerfile\");\n\n if (!existsSync(dockerfilePath)) {\n return `sandcastle:${baseName}`;\n }\n\n const fingerprint = createHash(\"sha256\")\n .update(readFileSync(dockerfilePath))\n .digest(\"hex\")\n .slice(0, 8);\n\n return `sandcastle:${baseName}-${fingerprint}`;\n}\n","import type { SandboxConfig, SandboxMountConfig } from \"../shared/config\";\nimport { sandboxImageName } from \"./sandbox-image\";\n\nexport interface SandcastleSandboxOptions {\n imageName: string;\n mounts?: SandboxConfig[\"mounts\"];\n env?: SandboxConfig[\"env\"];\n idleTimeoutSeconds?: number;\n}\n\nexport function buildSandboxOptions(\n repoRoot: string,\n sandbox: SandboxConfig\n): SandcastleSandboxOptions {\n const mounts: SandboxConfig[\"mounts\"] = [];\n if (sandbox.mounts !== undefined) {\n mounts.push(...sandbox.mounts);\n }\n\n return {\n imageName: sandboxImageName(repoRoot),\n ...(mounts.length > 0 ? { mounts } : {}),\n ...(sandbox.env !== undefined ? { env: sandbox.env } : {}),\n ...(sandbox.idleTimeoutSeconds !== undefined\n ? { idleTimeoutSeconds: sandbox.idleTimeoutSeconds }\n : {}),\n };\n}\n","import { mkdtempSync } from \"node:fs\";\nimport { writeFile } from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport { dirname, join } from \"path\";\nimport { ensureDir, execCapture, type PourkitLogger } from \"../shared/common\";\nimport type {\n SandboxConfig,\n Target,\n VerificationCommand,\n} from \"../shared/config\";\nimport type { ExecutionArtifact } from \"../shared/run-context\";\nimport type { SerenaExecutionContext } from \"./opencode-config\";\n\nexport interface ExecutionResult {\n success: boolean;\n branch: string;\n worktreePath: string;\n commits: string[];\n logPath: string | null;\n error?: string;\n}\n\nexport type PourkitStage =\n | \"builder\"\n | \"reviewer\"\n | \"refactor\"\n | \"finalizer\"\n | \"conflictResolution\"\n | \"failureResolution\"\n | \"issueFinalReview\"\n | \"prdFinalReview\"\n | \"prdReconciliation\";\n\nexport interface ExecutionProviderOptions {\n stage: PourkitStage;\n iteration?: number;\n artifactPath?: string;\n worktreePath?: string;\n agent: string;\n model: string;\n variant?: string;\n env?: Record<string, string>;\n prompt: string;\n target: Target;\n repoRoot: string;\n branchName: string;\n baseRef?: string;\n checkoutBase?: string;\n reviewBase?: string;\n sandbox: SandboxConfig;\n serena?: SerenaExecutionContext;\n autoApprove?: boolean;\n timeoutMs?: number;\n artifacts?: ExecutionArtifact[];\n logger: PourkitLogger;\n}\n\nexport interface ExecutionProvider {\n execute(options: ExecutionProviderOptions): Promise<ExecutionResult>;\n createSession?(): Promise<ExecutionSession>;\n}\n\nexport interface ExecutionSession extends ExecutionProvider {\n close(): Promise<void>;\n}\n\nasync function runSetupCommands(\n commands: VerificationCommand[],\n worktreePath: string,\n logger: PourkitLogger\n) {\n for (const command of commands) {\n await execCapture(\"bash\", [\"-lc\", command.command], {\n cwd: worktreePath,\n logger,\n label: command.label,\n });\n }\n}\n\nexport async function writeExecutionArtifacts(\n worktreePath: string,\n artifacts: ExecutionArtifact[]\n) {\n for (const artifact of artifacts) {\n const filePath = join(worktreePath, artifact.path);\n await ensureDir(dirname(filePath));\n await writeFile(filePath, artifact.content, \"utf-8\");\n }\n}\n\nexport class FakeExecutionProvider implements ExecutionProvider {\n private _result: ExecutionResult;\n lastOptions: ExecutionProviderOptions | null = null;\n calls: ExecutionProviderOptions[] = [];\n issueFinalReviewArtifactContent: string | null = null;\n finalReviewArtifactContent: string | null = null;\n reconciliationArtifactContent: string | null = null;\n\n constructor(result: ExecutionResult) {\n this._result = result;\n }\n\n async execute(_options: ExecutionProviderOptions): Promise<ExecutionResult> {\n this.lastOptions = _options;\n this.calls.push(_options);\n const resolvedWorktreePath =\n _options.worktreePath ??\n this._result.worktreePath ??\n mkdtempSync(join(tmpdir(), \"fake-provider-\"));\n if (_options.artifactPath) {\n const artifactPath = join(resolvedWorktreePath, _options.artifactPath);\n await ensureDir(dirname(artifactPath));\n if (_options.stage === \"reviewer\") {\n await writeFile(\n artifactPath,\n [\n \"## Findings\",\n \"\",\n \"| ID | Supersedes | Severity | File/Line | Issue | Recommendation |\",\n \"|----|------------|----------|-----------|-------|----------------|\",\n \"| none | n/a | n/a | n/a | No findings. | n/a |\",\n \"\",\n \"<verdict>PASS</verdict>\",\n ].join(\"\\n\"),\n \"utf-8\"\n );\n }\n if (_options.stage === \"finalizer\") {\n await writeFile(\n artifactPath,\n _options.prompt.includes(\"# Final Review Retouch PR Finalizer\")\n ? \"## PR Title\\n\\nchore: Final Review retouch\\n\\n## PR Body\\n\\nFinal Review retouch body.\"\n : \"## PR Title\\n\\nfix: Test issue\\n\\n## PR Body\\n\\nCloses #42\",\n \"utf-8\"\n );\n }\n if (_options.stage === \"issueFinalReview\") {\n const issueNumber = (() => {\n const branchMatch = _options.branchName?.match(/\\/(\\d+)\\//);\n return branchMatch ? parseInt(branchMatch[1], 10) : 42;\n })();\n const defaultContent = JSON.stringify({\n kind: \"issue-final-review\",\n issueNumber,\n branchName: _options.branchName ?? \"test-branch\",\n verdict: \"pass\",\n summary: \"Issue Final Review passed.\",\n changedPaths: [],\n selfRetouched: false,\n verification: {\n required: false,\n passed: false,\n commands: [],\n summary: \"\",\n },\n needsHumanReason: null,\n });\n const content = this.issueFinalReviewArtifactContent ?? defaultContent;\n await writeFile(artifactPath, content, \"utf-8\");\n }\n if (_options.stage === \"prdReconciliation\") {\n const defaultContent = (() => {\n const prdRefMatch = _options.prompt.match(\n /\"prdRef\":\\s*\"([A-Z]+-\\d+)\"/\n );\n const evidenceHashMatch = _options.prompt.match(\n /\"evidenceHash\":\\s*\"([0-9a-f]{64})\"/\n );\n const prdRef =\n prdRefMatch?.[1] ?? _options.checkoutBase ?? \"PRD-0000\";\n return JSON.stringify({\n prdRef,\n stage: \"prdReconciliation\",\n checkoutBase: _options.checkoutBase ?? prdRef,\n mergeBase: _options.reviewBase ?? _options.baseRef ?? \"\",\n evidenceHash: evidenceHashMatch?.[1] ?? \"0\".repeat(64),\n completionRecords: {},\n result: \"no_changes_needed\",\n changedPlanningPaths: [],\n completionArtifactPaths: [],\n summary:\n \"Architecture review complete, no planning changes required.\",\n diagnostics: [],\n noChangeRationale:\n \"Architecture review complete, no planning changes required.\",\n });\n })();\n const content = (\n this.reconciliationArtifactContent ?? defaultContent\n ).replaceAll(\n \"{{evidenceHash}}\",\n _options.prompt.match(/\"evidenceHash\":\\s*\"([0-9a-f]{64})\"/)?.[1] ??\n \"0\".repeat(64)\n );\n await writeFile(artifactPath, content, \"utf-8\");\n }\n if (_options.stage === \"prdFinalReview\") {\n const defaultContent = (() => {\n const prdRefMatch = _options.prompt.match(\n /\"prdRef\":\\s*\"([A-Z]+-\\d+)\"/\n );\n const prdRef = prdRefMatch?.[1] ?? \"PRD-0000\";\n return JSON.stringify({\n prdRef,\n stage: \"prdFinalReview\",\n checkoutBase: _options.checkoutBase ?? prdRef,\n reviewBase: _options.reviewBase ?? _options.baseRef ?? \"\",\n verdict: \"pass_no_changes\",\n summary: \"Final review passed with no changes needed.\",\n });\n })();\n const content = this.finalReviewArtifactContent ?? defaultContent;\n await writeFile(artifactPath, content, \"utf-8\");\n if (content) {\n const parsed = JSON.parse(content);\n if (\n parsed.verdict === \"pass_with_retouch\" &&\n Array.isArray(parsed.retouchFiles)\n ) {\n for (const rf of parsed.retouchFiles) {\n const fullPath = join(resolvedWorktreePath, rf.path);\n await ensureDir(dirname(fullPath));\n await writeFile(fullPath, rf.content, \"utf-8\");\n }\n }\n }\n }\n }\n return {\n ...this._result,\n worktreePath: resolvedWorktreePath,\n };\n }\n\n get result(): ExecutionResult {\n return this._result;\n }\n\n set result(value: ExecutionResult) {\n this._result = value;\n }\n}\n","import type { VerificationCommand } from \"../shared/config\";\n\nexport type E2EVerificationProfile = \"fast\" | \"full-check\" | \"failure\";\n\nexport function getVerificationCommands(\n baseCommands: VerificationCommand[],\n profile: E2EVerificationProfile\n): VerificationCommand[] {\n if (profile === \"failure\") {\n return [{ command: \"exit 1\", label: \"fail-e2e\" }];\n }\n if (profile === \"full-check\") {\n return [\n { command: \"npm run prettier:check\", label: \"prettier:check\" },\n { command: \"npm run typecheck\", label: \"typecheck\" },\n { command: \"npm run test\", label: \"tests\" },\n { command: \"npm run build\", label: \"build\" },\n ];\n }\n return baseCommands;\n}\n\nexport function composeFailureWithProfile(\n baseCommands: VerificationCommand[],\n profile: E2EVerificationProfile\n): VerificationCommand[] {\n const commands = getVerificationCommands(baseCommands, profile);\n return [{ command: \"exit 1\", label: \"fail-e2e\" }, ...commands];\n}\n","import path from \"node:path\";\nimport {\n access,\n mkdir,\n readFile,\n readdir,\n rm,\n writeFile,\n} from \"node:fs/promises\";\nimport type {\n ExecutionProvider,\n ExecutionProviderOptions,\n ExecutionResult,\n} from \"../../execution/execution-provider\";\nimport type {\n BranchStatus,\n CheckStatus,\n EnableAutoMergeOptions,\n MergePrOptions,\n PRProvider,\n PullRequest,\n WaitForPrChecksOptions,\n} from \"../../providers/pr-provider\";\nimport {\n execCapture,\n parseWorktreeListPorcelain,\n type PourkitLogger,\n} from \"../../shared/common\";\nimport type { GitHubClient } from \"../../providers/github-client\";\n\nexport interface E2EResources {\n targetBranch?: string;\n issueNumber?: number;\n issueUrl?: string;\n agentBranch?: string;\n prNumber?: number;\n prUrl?: string;\n}\n\ntype ReviewVerdict = \"PASS\" | \"PASS_WITH_NOTES\" | \"NEEDS_REFACTOR\" | \"FAIL\";\n\nexport interface LabelAssertionOptions {\n present?: string[];\n absent?: string[];\n}\n\nexport interface ExecutionFailureInjection {\n error?: string;\n throwMessage?: string;\n}\n\nexport interface ReviewerInjection extends ExecutionFailureInjection {\n verdicts?: ReviewVerdict[];\n invalidProtocol?: boolean;\n}\n\nexport interface RefactorInjection extends ExecutionFailureInjection {\n failIterations?: number[];\n commits?: string[];\n}\n\nexport interface FinalizerInjection extends ExecutionFailureInjection {\n invalidProtocol?: boolean;\n title?: string;\n body?: string;\n}\n\nexport interface IssueFinalReviewInjection extends ExecutionFailureInjection {\n invalidProtocol?: boolean;\n verdict?: \"pass\" | \"needs_human_review\";\n humanReason?: string;\n selfRetouched?: boolean;\n changedPaths?: string[];\n verificationPassed?: boolean;\n}\n\nexport interface FailureResolutionInjection extends ExecutionFailureInjection {\n artifact?: string;\n resolve?: (options: ExecutionProviderOptions) => Promise<void> | void;\n}\n\nexport interface ScenarioExecutionInjections {\n builder?: ExecutionFailureInjection;\n reviewer?: ReviewerInjection;\n refactor?: RefactorInjection;\n issueFinalReview?: IssueFinalReviewInjection;\n finalizer?: FinalizerInjection;\n failureResolution?: FailureResolutionInjection;\n}\n\nexport interface ScenarioPrInjections {\n branchStatuses?: BranchStatus[];\n waitForChecksDelayMs?: number;\n waitForChecksError?: string;\n waitForChecksResult?: CheckStatus[];\n requireWaitForChecksBeforeMerge?: boolean;\n expectLabelBeforeMerge?: {\n issueNumber: number;\n label: string;\n };\n}\n\nfunction makeSyntheticExecutionResult(\n options: ExecutionProviderOptions,\n success: boolean,\n commits: string[] = [],\n error?: string\n): ExecutionResult {\n return {\n success,\n branch: options.branchName,\n worktreePath: options.worktreePath ?? \"\",\n commits,\n logPath: null,\n ...(error ? { error } : {}),\n };\n}\n\nasync function maybeThrowInjectedFailure(\n injection: ExecutionFailureInjection | undefined\n): Promise<void> {\n if (injection?.throwMessage) {\n throw new Error(injection.throwMessage);\n }\n}\n\nasync function writeScenarioArtifact(\n worktreePath: string,\n artifactPath: string,\n content: string\n): Promise<void> {\n const filePath = path.join(worktreePath, artifactPath);\n await mkdir(path.dirname(filePath), { recursive: true });\n await writeFile(filePath, content, \"utf-8\");\n}\n\nexport class ScenarioExecutionProvider implements ExecutionProvider {\n readonly stageCalls: string[] = [];\n readonly reviewIterations: number[] = [];\n readonly refactorIterations: number[] = [];\n readonly issueFinalReviewCalls: ExecutionProviderOptions[] = [];\n readonly prdFinalReviewCalls: ExecutionProviderOptions[] = [];\n\n constructor(\n private readonly baseProvider: ExecutionProvider,\n readonly injections: ScenarioExecutionInjections = {}\n ) {}\n\n // fallow-ignore-next-line unused-class-member\n resetRunTracking(): void {\n this.stageCalls.length = 0;\n this.reviewIterations.length = 0;\n this.refactorIterations.length = 0;\n }\n\n async execute(options: ExecutionProviderOptions): Promise<ExecutionResult> {\n this.stageCalls.push(options.stage);\n\n if (options.stage === \"builder\") {\n await maybeThrowInjectedFailure(this.injections.builder);\n if (this.injections.builder?.error) {\n return makeSyntheticExecutionResult(\n options,\n false,\n [],\n this.injections.builder.error\n );\n }\n return this.baseProvider.execute(options);\n }\n\n if (options.stage === \"reviewer\") {\n await maybeThrowInjectedFailure(this.injections.reviewer);\n if (this.injections.reviewer?.error) {\n return makeSyntheticExecutionResult(\n options,\n false,\n [],\n this.injections.reviewer.error\n );\n }\n\n this.reviewIterations.push(options.iteration ?? 1);\n const verdicts = this.injections.reviewer?.verdicts ?? [\"PASS\"];\n const verdict =\n verdicts[\n Math.min(this.reviewIterations.length - 1, verdicts.length - 1)\n ];\n const artifactPath =\n options.artifactPath ?? \".pourkit/.tmp/reviewers/iteration-1.md\";\n const content = this.injections.reviewer?.invalidProtocol\n ? \"invalid reviewer artifact\"\n : [\n \"## Findings\",\n \"\",\n \"| ID | Supersedes | Severity | File/Line | Issue | Recommendation |\",\n \"|----|------------|----------|-----------|-------|----------------|\",\n \"| none | n/a | n/a | n/a | No findings. | n/a |\",\n \"\",\n `<verdict>${verdict}</verdict>`,\n ].join(\"\\n\");\n\n await writeScenarioArtifact(\n options.worktreePath ?? \"\",\n artifactPath,\n content\n );\n return makeSyntheticExecutionResult(options, true);\n }\n\n if (options.stage === \"refactor\") {\n await maybeThrowInjectedFailure(this.injections.refactor);\n this.refactorIterations.push(options.iteration ?? 1);\n if (\n this.injections.refactor?.error &&\n this.injections.refactor.failIterations?.includes(\n options.iteration ?? 1\n )\n ) {\n return makeSyntheticExecutionResult(\n options,\n false,\n [],\n this.injections.refactor.error\n );\n }\n\n return makeSyntheticExecutionResult(\n options,\n true,\n this.injections.refactor?.commits ?? [\n `synthetic-refactor-${options.iteration ?? 1}`,\n ]\n );\n }\n\n if (options.stage === \"issueFinalReview\") {\n await maybeThrowInjectedFailure(this.injections.issueFinalReview);\n this.issueFinalReviewCalls.push(options);\n if (this.injections.issueFinalReview?.error) {\n return makeSyntheticExecutionResult(\n options,\n false,\n [],\n this.injections.issueFinalReview.error\n );\n }\n\n const artifactPath =\n options.artifactPath ??\n \".pourkit/.tmp/issue-final-review/agent-output.json\";\n const verdict = this.injections.issueFinalReview?.verdict ?? \"pass\";\n const selfRetouched =\n this.injections.issueFinalReview?.selfRetouched ?? false;\n const verificationPassed =\n this.injections.issueFinalReview?.verificationPassed ?? selfRetouched;\n const content = this.injections.issueFinalReview?.invalidProtocol\n ? \"invalid issue final review artifact\"\n : JSON.stringify({\n kind: \"issue-final-review\",\n issueNumber:\n Number(options.branchName.match(/\\/(\\d+)\\//)?.[1]) || 0,\n branchName: options.branchName,\n verdict,\n summary:\n verdict === \"pass\"\n ? \"Issue Final Review passed.\"\n : \"Issue Final Review needs human review.\",\n changedPaths: this.injections.issueFinalReview?.changedPaths ?? [],\n selfRetouched,\n verification: {\n required: selfRetouched,\n passed: verificationPassed,\n commands: selfRetouched\n ? [\"live e2e synthetic verification\"]\n : [],\n summary: selfRetouched\n ? verificationPassed\n ? \"Synthetic verification passed.\"\n : \"Synthetic verification failed.\"\n : \"No self-retouch verification required.\",\n },\n needsHumanReason:\n verdict === \"needs_human_review\"\n ? (this.injections.issueFinalReview?.humanReason ??\n \"Live E2E requested human review.\")\n : null,\n });\n\n await writeScenarioArtifact(\n options.worktreePath ?? \"\",\n artifactPath,\n content\n );\n return makeSyntheticExecutionResult(options, true);\n }\n\n if (options.stage === \"prdFinalReview\") {\n this.prdFinalReviewCalls.push(options);\n const artifactPath =\n options.artifactPath ?? \".pourkit/final-review-artifact.json\";\n const prdRefMatch = options.prompt.match(/\"prdRef\":\\s*\"([A-Z]+-\\d+)\"/);\n const prdRef = prdRefMatch?.[1] ?? options.branchName;\n const content = JSON.stringify({\n prdRef,\n stage: \"prdFinalReview\",\n checkoutBase: options.checkoutBase ?? options.branchName,\n reviewBase: options.reviewBase ?? options.baseRef ?? \"\",\n verdict: \"pass_no_changes\",\n summary: \"Final review passed with no changes needed.\",\n });\n const worktreePath = options.worktreePath ?? options.repoRoot;\n\n await writeScenarioArtifact(worktreePath, artifactPath, content);\n return {\n ...makeSyntheticExecutionResult(options, true),\n worktreePath,\n };\n }\n\n if (options.stage === \"failureResolution\") {\n await maybeThrowInjectedFailure(this.injections.failureResolution);\n if (this.injections.failureResolution?.error) {\n return makeSyntheticExecutionResult(\n options,\n false,\n [],\n this.injections.failureResolution.error\n );\n }\n\n if (this.injections.failureResolution?.resolve) {\n await this.injections.failureResolution.resolve(options);\n }\n\n const artifactPath =\n options.artifactPath ?? \".pourkit/.tmp/failure-resolution/attempt-1.md\";\n const content =\n this.injections.failureResolution?.artifact ??\n [\n \"# Recovery Report\",\n \"\",\n \"```json\",\n JSON.stringify({\n recoveryDecision: \"RETRY_STAGE\",\n summary: \"Resolved deterministic live E2E conflict.\",\n changedFiles: [],\n verificationSummary: \"Not run by deterministic live harness.\",\n verificationCommands: [],\n }),\n \"```\",\n ].join(\"\\n\");\n\n await writeScenarioArtifact(\n options.worktreePath ?? \"\",\n artifactPath,\n content\n );\n return makeSyntheticExecutionResult(options, true);\n }\n\n await maybeThrowInjectedFailure(this.injections.finalizer);\n if (this.injections.finalizer?.error) {\n return makeSyntheticExecutionResult(\n options,\n false,\n [],\n this.injections.finalizer.error\n );\n }\n\n const artifactPath =\n options.artifactPath ?? \".pourkit/.tmp/finalizer/agent-output.md\";\n const title = this.injections.finalizer?.title ?? \"Generated PR Title\";\n const body = this.injections.finalizer?.body ?? \"Generated PR body content\";\n const content = this.injections.finalizer?.invalidProtocol\n ? \"invalid finalizer artifact\"\n : `## PR Title\\n\\n${title}\\n\\n## PR Body\\n\\n${body}`;\n\n await writeScenarioArtifact(\n options.worktreePath ?? \"\",\n artifactPath,\n content\n );\n return makeSyntheticExecutionResult(options, true);\n }\n}\n\nexport class ScenarioPrProvider implements PRProvider {\n waitForPrChecksCalls = 0;\n mergeCalls = 0;\n branchStatusCalls = 0;\n\n constructor(\n private readonly baseProvider: PRProvider,\n private readonly client: GitHubClient,\n private readonly injections: ScenarioPrInjections = {}\n ) {}\n\n // fallow-ignore-next-line unused-class-member\n setExpectedLabelBeforeMerge(issueNumber: number, label: string): void {\n this.injections.expectLabelBeforeMerge = { issueNumber, label };\n }\n\n createPr(options: {\n title: string;\n body: string;\n head: string;\n base: string;\n }): Promise<PullRequest> {\n return this.baseProvider.createPr(options);\n }\n\n getPr(branchName: string): Promise<PullRequest | null> {\n return this.baseProvider.getPr(branchName);\n }\n\n getPrByNumber(prNumber: number): Promise<PullRequest | null> {\n if (!this.baseProvider.getPrByNumber) {\n return Promise.resolve(null);\n }\n return this.baseProvider.getPrByNumber(prNumber);\n }\n\n getCheckStatus(prNumber: number): Promise<CheckStatus[]> {\n return this.baseProvider.getCheckStatus(prNumber);\n }\n\n async enableAutoMerge(\n _pr: PullRequest,\n _options?: EnableAutoMergeOptions\n ): Promise<void> {\n return this.baseProvider.enableAutoMerge(_pr, _options);\n }\n\n async mergePr(prNumber: number, options?: MergePrOptions): Promise<void> {\n this.mergeCalls++;\n if (\n this.injections.requireWaitForChecksBeforeMerge &&\n this.waitForPrChecksCalls === 0\n ) {\n throw new Error(\"mergePr called before waitForPrChecks\");\n }\n\n if (this.injections.expectLabelBeforeMerge) {\n await assertIssueLabels(\n this.injections.expectLabelBeforeMerge.issueNumber,\n {\n present: [this.injections.expectLabelBeforeMerge.label],\n },\n this.client\n );\n }\n\n await this.baseProvider.mergePr(prNumber, options);\n }\n\n async waitForPrChecks(\n prNumber: number,\n options?: WaitForPrChecksOptions\n ): Promise<CheckStatus[]> {\n this.waitForPrChecksCalls++;\n\n if (this.injections.waitForChecksDelayMs) {\n await new Promise((resolve) =>\n setTimeout(resolve, this.injections.waitForChecksDelayMs)\n );\n }\n\n if (this.injections.waitForChecksError) {\n throw new Error(this.injections.waitForChecksError);\n }\n\n if (this.injections.waitForChecksResult) {\n return this.injections.waitForChecksResult;\n }\n\n return this.baseProvider.waitForPrChecks(prNumber, options);\n }\n\n async getBranchStatus(branchName: string): Promise<BranchStatus> {\n this.branchStatusCalls++;\n const statuses = this.injections.branchStatuses;\n if (statuses && statuses.length > 0) {\n return statuses[\n Math.min(this.branchStatusCalls - 1, statuses.length - 1)\n ];\n }\n return this.baseProvider.getBranchStatus(branchName);\n }\n}\n\ninterface E2EStateFile extends E2EResources {\n runId: string;\n}\n\nconst E2E_STATE_DIR = path.join(\".pourkit\", \".tmp\", \"e2e-runs\");\n\nexport function stateFilePath(root: string, runId: string): string {\n return path.join(root, E2E_STATE_DIR, `${runId}.json`);\n}\n\nexport async function persistResources(\n root: string,\n runId: string,\n resources: E2EResources\n): Promise<void> {\n const filePath = stateFilePath(root, runId);\n await mkdir(path.dirname(filePath), { recursive: true });\n const state: E2EStateFile = { runId, ...resources };\n await writeFile(filePath, `${JSON.stringify(state, null, 2)}\\n`, \"utf-8\");\n}\n\nexport async function localBranchExists(branchName: string): Promise<boolean> {\n try {\n await execCapture(\"git\", [\n \"show-ref\",\n \"--verify\",\n \"--quiet\",\n `refs/heads/${branchName}`,\n ]);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function removeWorktreeForBranch(\n branchName: string,\n logger: PourkitLogger\n): Promise<boolean> {\n try {\n const result = await execCapture(\"git\", [\n \"worktree\",\n \"list\",\n \"--porcelain\",\n ]);\n const worktreePath = parseWorktreeListPorcelain(result.stdout, branchName);\n\n if (!worktreePath) {\n return true;\n }\n\n logger.step(\"cleanup\", `Removing worktree for branch: ${branchName}...`);\n await execCapture(\"git\", [\"worktree\", \"remove\", \"--force\", worktreePath]);\n return true;\n } catch (error) {\n logger.step(\n \"warn\",\n `Failed to remove worktree for branch: ${error instanceof Error ? error.message : String(error)}`\n );\n return false;\n }\n}\n\nexport async function worktreeExistsForBranch(\n branchName: string\n): Promise<boolean> {\n try {\n const result = await execCapture(\"git\", [\n \"worktree\",\n \"list\",\n \"--porcelain\",\n ]);\n const worktreePath = parseWorktreeListPorcelain(result.stdout, branchName);\n return worktreePath !== null;\n } catch {\n return false;\n }\n}\n\nexport async function worktreePathForBranch(\n branchName: string\n): Promise<string | null> {\n try {\n const result = await execCapture(\"git\", [\n \"worktree\",\n \"list\",\n \"--porcelain\",\n ]);\n return parseWorktreeListPorcelain(result.stdout, branchName);\n } catch {\n return null;\n }\n}\n\nexport async function fileExists(filePath: string): Promise<boolean> {\n try {\n await access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function deleteLocalBranch(\n branchName: string,\n logger: PourkitLogger\n): Promise<boolean> {\n if (!(await localBranchExists(branchName))) {\n return true;\n }\n\n if (!(await removeWorktreeForBranch(branchName, logger))) {\n return false;\n }\n\n try {\n logger.step(\"cleanup\", `Deleting local branch: ${branchName}...`);\n await execCapture(\"git\", [\"branch\", \"-D\", branchName]);\n return true;\n } catch (error) {\n logger.step(\n \"warn\",\n `Failed to delete local branch: ${error instanceof Error ? error.message : String(error)}`\n );\n return false;\n }\n}\n\nasync function deleteRemoteBranch(\n branchName: string,\n logger: PourkitLogger\n): Promise<boolean> {\n if (!(await remoteBranchExists(branchName))) {\n return true;\n }\n\n try {\n logger.step(\"cleanup\", `Deleting remote branch: ${branchName}...`);\n await execCapture(\"git\", [\"push\", \"origin\", \"--delete\", branchName]);\n return true;\n } catch (error) {\n logger.step(\n \"warn\",\n `Failed to delete remote branch: ${error instanceof Error ? error.message : String(error)}`\n );\n return false;\n }\n}\n\nexport async function createE2EIssue(\n runId: string,\n targetBranch: string,\n logger: PourkitLogger,\n client: GitHubClient,\n title = `E2E Test Issue ${runId}`,\n body?: string\n): Promise<{ number: number; url: string }> {\n const issueBody =\n body ??\n [\n `This is an automatically created E2E test issue for run ${runId}.`,\n \"\",\n `Target branch: ${targetBranch}`,\n \"\",\n \"This issue should be processed by the deterministic agent and cleaned up after the test completes.\",\n ].join(\"\\n\");\n\n logger.step(\"issue\", `Creating GitHub issue: \"${title}\"`);\n\n const { data } = await client.octokit.rest.issues.create({\n owner: client.owner,\n repo: client.repo,\n title,\n body: issueBody,\n labels: [\"ready-for-agent\", \"type:infra\", \"pourkit-e2e\"],\n });\n\n logger.line(`Created issue #${data.number}`);\n return { number: data.number, url: data.html_url };\n}\n\nexport async function createLiveTargetBranch(\n runId: string,\n logger: PourkitLogger,\n baseBranch = \"main\"\n): Promise<string> {\n const targetBranch = `pourkit-e2e-target/${runId}`;\n logger.step(\"git\", `Creating target branch: ${targetBranch}`);\n await execCapture(\"git\", [\n \"fetch\",\n \"origin\",\n `${baseBranch}:refs/remotes/origin/${baseBranch}`,\n ]);\n await execCapture(\"git\", [\n \"branch\",\n \"--force\",\n targetBranch,\n `origin/${baseBranch}`,\n ]);\n await execCapture(\"git\", [\n \"push\",\n \"--no-verify\",\n \"-u\",\n \"origin\",\n targetBranch,\n ]);\n return targetBranch;\n}\n\nexport async function fetchIssueLabels(\n issueNumber: number,\n client: GitHubClient\n): Promise<string[]> {\n const { data } = await client.octokit.rest.issues.get({\n owner: client.owner,\n repo: client.repo,\n issue_number: issueNumber,\n });\n\n return data.labels.map((l) => (typeof l === \"string\" ? l : (l.name ?? \"\")));\n}\n\nexport async function assertIssueLabels(\n issueNumber: number,\n options: LabelAssertionOptions,\n client: GitHubClient\n): Promise<void> {\n const labels = await fetchIssueLabels(issueNumber, client);\n const missing = (options.present ?? []).filter(\n (label) => !labels.includes(label)\n );\n const unexpected = (options.absent ?? []).filter((label) =>\n labels.includes(label)\n );\n\n if (missing.length === 0 && unexpected.length === 0) {\n return;\n }\n\n const messages: string[] = [];\n if (missing.length > 0) {\n messages.push(`missing labels: ${missing.join(\", \")}`);\n }\n if (unexpected.length > 0) {\n messages.push(`unexpected labels: ${unexpected.join(\", \")}`);\n }\n\n throw new Error(\n `Issue #${issueNumber} label assertion failed (${messages.join(\"; \")}). Current labels: ${labels.join(\", \")}`\n );\n}\n\nexport async function lookupPrByBranch(\n branchName: string,\n client: GitHubClient\n): Promise<PullRequest | null> {\n const { data } = await client.octokit.rest.pulls.list({\n owner: client.owner,\n repo: client.repo,\n head: `${client.owner}:${branchName}`,\n state: \"all\",\n per_page: 1,\n });\n\n if (data.length === 0) return null;\n\n const pr = data[0];\n return {\n number: pr.number,\n nodeId: pr.node_id,\n url: pr.html_url,\n title: pr.title,\n body: pr.body ?? \"\",\n headRefName: pr.head.ref,\n baseRefName: pr.base.ref,\n state:\n pr.state === \"closed\" ? (pr.merged_at ? \"MERGED\" : \"CLOSED\") : \"OPEN\",\n headRefOid: pr.head.sha,\n };\n}\n\nexport async function remoteBranchExists(branchName: string): Promise<boolean> {\n const result = await execCapture(\"git\", [\n \"ls-remote\",\n \"--heads\",\n \"origin\",\n branchName,\n ]);\n return result.stdout.trim().length > 0;\n}\n\nexport async function getTargetBranchStatus(\n prProvider: PRProvider,\n targetBranch: string\n): Promise<BranchStatus> {\n return prProvider.getBranchStatus(targetBranch);\n}\n\nasync function recoverStateFile(\n filePath: string,\n logger: PourkitLogger\n): Promise<boolean> {\n try {\n const raw = await readFile(filePath, \"utf-8\");\n const state = JSON.parse(raw) as E2EStateFile;\n let cleanupSucceeded = true;\n\n if (state.agentBranch) {\n cleanupSucceeded =\n (await deleteLocalBranch(state.agentBranch, logger)) &&\n cleanupSucceeded;\n cleanupSucceeded =\n (await deleteRemoteBranch(state.agentBranch, logger)) &&\n cleanupSucceeded;\n }\n\n if (state.targetBranch) {\n cleanupSucceeded =\n (await deleteLocalBranch(state.targetBranch, logger)) &&\n cleanupSucceeded;\n cleanupSucceeded =\n (await deleteRemoteBranch(state.targetBranch, logger)) &&\n cleanupSucceeded;\n }\n\n if (cleanupSucceeded) {\n await rm(filePath, { force: true });\n return true;\n }\n\n logger.step(\n \"warn\",\n `Preserving stale E2E state ${path.basename(filePath)} for cleanup retry`\n );\n return false;\n } catch (error) {\n logger.step(\n \"warn\",\n `Failed to recover stale E2E state ${path.basename(filePath)}: ${error instanceof Error ? error.message : String(error)}`\n );\n return false;\n }\n}\n\nexport async function recoverStaleRuns(\n root: string,\n logger: PourkitLogger\n): Promise<void> {\n const dir = path.join(root, E2E_STATE_DIR);\n\n try {\n const entries = await readdir(dir, { withFileTypes: true });\n for (const entry of entries) {\n if (!entry.isFile() || !entry.name.endsWith(\".json\")) continue;\n await recoverStateFile(path.join(dir, entry.name), logger);\n }\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") {\n logger.step(\n \"warn\",\n `Failed to scan stale E2E state: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n}\n\nexport async function cleanupResources(\n resources: E2EResources,\n root: string,\n runId: string,\n keep: boolean,\n logger: PourkitLogger,\n client: GitHubClient\n): Promise<void> {\n if (keep) {\n logger.line(\"--keep flag set, preserving E2E resources:\");\n if (resources.issueNumber)\n logger.line(` Issue: #${resources.issueNumber}`);\n if (resources.issueUrl) logger.line(` Issue URL: ${resources.issueUrl}`);\n if (resources.targetBranch)\n logger.line(` Target branch: ${resources.targetBranch}`);\n if (resources.agentBranch)\n logger.line(` Agent branch: ${resources.agentBranch}`);\n if (resources.prNumber)\n logger.line(` PR: #${resources.prNumber} (${resources.prUrl})`);\n return;\n }\n\n logger.line(\"Cleaning up E2E resources...\");\n let cleanupSucceeded = true;\n\n if (resources.prNumber) {\n try {\n const { data } = await client.octokit.rest.pulls.get({\n owner: client.owner,\n repo: client.repo,\n pull_number: resources.prNumber,\n });\n if (data.merged) {\n logger.step(\n \"cleanup\",\n `PR #${resources.prNumber} is merged, skipping close`\n );\n } else {\n logger.step(\"cleanup\", `Closing PR #${resources.prNumber}...`);\n await client.octokit.rest.pulls.update({\n owner: client.owner,\n repo: client.repo,\n pull_number: resources.prNumber,\n state: \"closed\",\n });\n }\n } catch (error) {\n logger.step(\n \"warn\",\n `Failed to close PR: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n\n if (resources.issueNumber) {\n try {\n logger.step(\"cleanup\", `Closing issue #${resources.issueNumber}...`);\n await client.octokit.rest.issues.update({\n owner: client.owner,\n repo: client.repo,\n issue_number: resources.issueNumber,\n state: \"closed\",\n state_reason: \"completed\",\n });\n } catch (error) {\n logger.step(\n \"warn\",\n `Failed to close issue: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n\n if (resources.agentBranch) {\n cleanupSucceeded =\n (await deleteLocalBranch(resources.agentBranch, logger)) &&\n cleanupSucceeded;\n cleanupSucceeded =\n (await deleteRemoteBranch(resources.agentBranch, logger)) &&\n cleanupSucceeded;\n }\n\n if (resources.targetBranch) {\n cleanupSucceeded =\n (await deleteLocalBranch(resources.targetBranch, logger)) &&\n cleanupSucceeded;\n cleanupSucceeded =\n (await deleteRemoteBranch(resources.targetBranch, logger)) &&\n cleanupSucceeded;\n }\n\n if (cleanupSucceeded) {\n await rm(stateFilePath(root, runId), { force: true });\n } else {\n logger.step(\"warn\", \"Preserving E2E state for retry after cleanup failure\");\n }\n\n logger.line(\"Cleanup complete.\");\n}\n\nexport interface QueueLoopCleanupIssue {\n issueNumber: number;\n agentBranch?: string;\n prNumber?: number;\n}\n\nexport interface QueueLoopCleanupResources {\n targetBranch: string;\n issues: QueueLoopCleanupIssue[];\n}\n\nexport async function cleanupQueueLoopResources(\n resources: QueueLoopCleanupResources,\n root: string,\n runId: string,\n logger: PourkitLogger,\n client: GitHubClient\n): Promise<string[]> {\n const errors: string[] = [];\n\n logger.line(\"Cleaning up Queue Loop E2E resources...\");\n\n for (const issue of resources.issues) {\n let prNumber = issue.prNumber;\n\n if (!prNumber && issue.agentBranch) {\n try {\n const pr = await lookupPrByBranch(issue.agentBranch, client);\n if (pr) {\n prNumber = pr.number;\n }\n } catch {}\n }\n\n if (prNumber) {\n try {\n const { data } = await client.octokit.rest.pulls.get({\n owner: client.owner,\n repo: client.repo,\n pull_number: prNumber,\n });\n if (!data.merged) {\n logger.step(\"cleanup\", `Closing PR #${prNumber}...`);\n await client.octokit.rest.pulls.update({\n owner: client.owner,\n repo: client.repo,\n pull_number: prNumber,\n state: \"closed\",\n });\n }\n } catch (error) {\n errors.push(`Failed to close PR #${prNumber}`);\n logger.step(\n \"warn\",\n `Failed to close PR #${prNumber}: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n }\n\n for (const issue of resources.issues) {\n try {\n logger.step(\"cleanup\", `Closing issue #${issue.issueNumber}...`);\n await client.octokit.rest.issues.update({\n owner: client.owner,\n repo: client.repo,\n issue_number: issue.issueNumber,\n state: \"closed\",\n state_reason: \"completed\",\n });\n } catch (error) {\n errors.push(`Failed to close issue #${issue.issueNumber}`);\n logger.step(\n \"warn\",\n `Failed to close issue #${issue.issueNumber}: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n\n for (const issue of resources.issues) {\n if (issue.agentBranch) {\n if (!(await deleteLocalBranch(issue.agentBranch, logger))) {\n errors.push(`Failed to delete local branch ${issue.agentBranch}`);\n }\n if (!(await deleteRemoteBranch(issue.agentBranch, logger))) {\n errors.push(`Failed to delete remote branch ${issue.agentBranch}`);\n }\n }\n }\n\n if (!(await deleteLocalBranch(resources.targetBranch, logger))) {\n errors.push(\n `Failed to delete local target branch ${resources.targetBranch}`\n );\n }\n if (!(await deleteRemoteBranch(resources.targetBranch, logger))) {\n errors.push(\n `Failed to delete remote target branch ${resources.targetBranch}`\n );\n }\n\n try {\n await rm(stateFilePath(root, runId), { force: true });\n } catch (error) {\n errors.push(\"Failed to remove state file\");\n }\n\n logger.line(\"Queue Loop cleanup complete.\");\n return errors;\n}\n\nexport async function runCleanupOnly(\n root: string,\n logger: PourkitLogger,\n client: GitHubClient\n): Promise<void> {\n logger.line(\"Running cleanup-only mode: deleting stale e2e branches...\");\n\n const result = await execCapture(\"git\", [\"ls-remote\", \"--heads\", \"origin\"]);\n const lines = result.stdout\n .split(\"\\n\")\n .filter((line) => line.trim().length > 0);\n\n const e2eBranchPattern =\n /refs\\/heads\\/(pourkit-e2e-target\\/|pourkit\\/\\d+\\/(e2e-test-issue-|test-live-e2e-))/;\n const branchesToDelete = lines\n .map((line) => {\n const parts = line.split(/\\s+/);\n return parts[1];\n })\n .filter((ref) => e2eBranchPattern.test(ref))\n .map((ref) => ref.replace(\"refs/heads/\", \"\"));\n\n let deletedCount = 0;\n let failedCount = 0;\n\n for (const branch of branchesToDelete) {\n const localOk = await deleteLocalBranch(branch, logger);\n const remoteOk = await deleteRemoteBranch(branch, logger);\n if (localOk && remoteOk) {\n deletedCount++;\n } else {\n failedCount++;\n }\n }\n\n const issueLabel = \"pourkit-e2e\";\n let closedIssueCount = 0;\n let failedIssueCount = 0;\n\n const openIssues = await client.octokit.paginate(\n client.octokit.rest.issues.listForRepo,\n {\n owner: client.owner,\n repo: client.repo,\n state: \"open\",\n labels: issueLabel,\n per_page: 100,\n }\n );\n\n const issues = openIssues.filter((issue) => !issue.pull_request);\n\n for (const issue of issues) {\n try {\n logger.step(\"cleanup\", `Closing e2e issue #${issue.number}...`);\n await client.octokit.rest.issues.update({\n owner: client.owner,\n repo: client.repo,\n issue_number: issue.number,\n state: \"closed\",\n state_reason: \"completed\",\n });\n closedIssueCount++;\n } catch (error) {\n failedIssueCount++;\n logger.step(\n \"warn\",\n `Failed to close e2e issue #${issue.number}: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n\n const stateDir = path.join(root, E2E_STATE_DIR);\n try {\n const entries = await readdir(stateDir, { withFileTypes: true });\n for (const entry of entries) {\n if (!entry.isFile() || !entry.name.endsWith(\".json\")) continue;\n const filePath = path.join(stateDir, entry.name);\n await rm(filePath, { force: true });\n logger.step(\"cleanup\", `Removed state file: ${entry.name}`);\n }\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") {\n logger.step(\n \"warn\",\n `Failed to scan state directory: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n\n logger.line(\n `Cleanup-only complete: ${deletedCount} branch(es) deleted, ${closedIssueCount} issue(s) closed, ${failedCount + failedIssueCount} failure(s)`\n );\n}\n"],"mappings":"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","names":["resolve","path","resolve","path","existsSync","mkdir","readFile","readdir","rm","writeFile","existsSync","readFileSync","isAbsolute","join","path","repoRoot","existsSync","mkdir","writeFile","rm","pathToFileURL","repoRoot","join","repoRoot","path","repoRelative","join","existsSync","mkdirSync","readFileSync","join","Effect","existsSync","mkdirSync","readFileSync","dirname","join","Effect","existsSync","readFileSync","join","existsSync","readdirSync","readFileSync","isAbsolute","join","resolve","existsSync","mkdirSync","readFileSync","readdirSync","writeFileSync","join","existsSync","mkdirSync","readFileSync","dirname","join","readArtifact","Effect","existsSync","mkdirSync","readFileSync","writeFileSync","rmSync","path","execCapture","Effect","Layer","existsSync","readFileSync","repoRoot","join","path","repoRoot","Effect","join","existsSync","readFileSync","writeFileSync","readdirSync","Layer","repoRoot","Effect","SECTION_HEADING_PATTERN","extractSections","contentAfter","existsSync","readFileSync","path","existsSync","readFileSync","isAbsolute","resolve","CONFLICT_MARKER_PATTERN","join","readFileSync","Exit","path","mkdir","repoRoot","mkdir","path","path","mkdir","resolve","readFileSync","join","repoRoot","join","readFileSync","validation","join","readFileSync","join","Effect","Effect","join","Effect","Layer","bridgeExecutionProvider","Layer","Effect","join","readFileSync","repoRoot","execFileSync","existsSync","mkdirSync","readFileSync","writeFileSync","join","spawnSync","repoRoot","join","existsSync","readFileSync","execFileSync","mkdirSync","writeFileSync","readFile","stableForMs","Effect","UnknownException","unwrapError","existsSync","readFileSync","join","join","repoRoot","existsSync","readFileSync","repoRoot","isAbsolute","join","Exit","existsSync","readFileSync","childCloseSucceeded","baseRef","join","repoRoot","existsSync","readFileSync","run","secondsRemaining","formatChecks","execCapture","path","createHash","existsSync","readFileSync","path","repoRoot","repoRoot","path","repoRoot","dirname","join","join","dirname","getVerificationCommands","path","access","mkdir","readFile","writeFile","path","mkdir","writeFile","readFile","path","path","E2E_STATE_DIR","path","existsSync","stateFilePath","localBranchExists","remoteBranchExists","removeWorktreeForBranch","deleteLocalBranch","deleteRemoteBranch","getVerificationCommands","deleteLocalBranch","deleteRemoteBranch","rm","stateFilePath","path"]}
|
|
1
|
+
{"version":3,"sources":["../../../common/logger/src/index.ts","../../shared/common.ts","../../e2e/run-live-e2e.ts","../../commands/issue-run.ts","../../shared/config.ts","../../pr/templates.ts","../../shared/run-context.ts","../../commands/run-verification.ts","../../shared/prompt-guidance.ts","../../shared/worktree-run-state.ts","../../commands/base-refresh.ts","../../failure-resolution/effect-runtime.ts","../../shared/effect-runtime.ts","../../failure-resolution/types.ts","../../shared/attempt-log.ts","../../failure-resolution/stage-attempt.ts","../../commands/conflict-resolution.ts","../../conflicts/conflict-resolution-artifact.ts","../../commands/artifact-validation.ts","../../pr/review-verdict.ts","../../commands/review.ts","../../execution/agent-output-retry.ts","../../shared/effect-services.ts","../../pr/pr-description.ts","../../serena/baseline.ts","../../serena/container.ts","../../serena/preflight.ts","../../failure-resolution/failure-resolution-agent.ts","../../failure-resolution/recovery-policy.ts","../../commands/pr-description-agent.ts","../../pr/pr-description-context.ts","../../prd-run/local-merge-coordinator.ts","../../prd-run/local-branches.ts","../../pr/pr-body.ts","../../issues/target-green.ts","../../issues/merge-coordinator.ts","../../commands/issue-final-review-agent.ts","../../issues/issue-transitions.ts","../../issues/stacked-issue.ts","../../commands/issue.ts","../../providers/github-provider.ts","../../providers/github-pr-provider.ts","../../providers/github-client.ts","../../execution/deterministic-agent.ts","../../execution/sandbox-image-build.ts","../../execution/sandbox-image.ts","../../execution/sandbox-options.ts","../../execution/execution-provider.ts","../../e2e/profile.ts","../../e2e/live/harness.ts"],"sourcesContent":["import { createWriteStream } from \"node:fs\";\nimport { mkdirSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { styleText } from \"node:util\";\n\nexport interface PourkitLogger {\n line(msg: string): void;\n raw(msg: string): void;\n step(step: string, msg: string): void;\n status(status: string): void;\n kv(key: string, value: string): void;\n close(): Promise<void>;\n}\n\nexport function createLogger(name: string, filePath?: string): PourkitLogger {\n let fileStream: import(\"fs\").WriteStream | undefined;\n\n if (filePath) {\n mkdirSync(path.dirname(filePath), { recursive: true });\n fileStream = createWriteStream(filePath, { flags: \"a\" });\n }\n\n const write = (terminal: string, plain = terminal) => {\n process.stdout.write(`${terminal}\\n`);\n if (fileStream) {\n fileStream.write(`${plain}\\n`);\n }\n };\n\n return {\n line(msg: string) {\n const ts = timestamp();\n write(`${ts.terminal} ${msg}`, `${ts.plain} ${msg}`);\n },\n\n raw(msg: string) {\n write(msg);\n },\n\n step(step: string, msg: string) {\n const ts = timestamp();\n write(\n `${ts.terminal} ${formatStep(step)} ${formatStepMessage(step, msg)}`,\n `${ts.plain} [${step}] ${msg}`\n );\n },\n\n status(status: string) {\n const ts = timestamp();\n write(\n `${ts.terminal} ${color([\"bold\", \"cyan\"], \"POURKIT\")} ${color(\"cyan\", status)}`,\n `${ts.plain} POURKIT ${status}`\n );\n },\n\n kv(key: string, value: string) {\n const ts = timestamp();\n write(\n `${ts.terminal} ${color(\"dim\", key)}=${formatValue(key, value)}`,\n `${ts.plain} ${key}=${value}`\n );\n },\n\n async close() {\n await new Promise<void>((resolve) => {\n if (!fileStream) {\n resolve();\n return;\n }\n\n const timer = setTimeout(() => {\n if (!fileStream.destroyed) {\n fileStream.destroy();\n }\n resolve();\n }, 2000);\n\n fileStream.end(() => {\n clearTimeout(timer);\n resolve();\n });\n });\n },\n };\n}\n\nfunction timestamp() {\n const now = new Date();\n const time = now.toTimeString().slice(0, 8);\n const ms = String(now.getMilliseconds()).padStart(3, \"0\");\n const plain = `${time}.${ms}`;\n return { terminal: color(\"dim\", plain), plain };\n}\n\nfunction formatStep(step: string) {\n return color(stepStyle(step), `[${step}]`);\n}\n\nfunction formatStepMessage(step: string, msg: string) {\n if (step === \"error\") {\n return color(\"red\", msg);\n }\n if (step === \"warn\") {\n return color(\"yellow\", msg);\n }\n return msg;\n}\n\nfunction formatValue(key: string, value: string) {\n if (/SUCCESS|CREATED|COMMITS/.test(key)) {\n return color(\"green\", value);\n }\n if (/BRANCH|PATH|FILE|URL/.test(key)) {\n return color(\"cyan\", value);\n }\n return color(\"bold\", value);\n}\n\nfunction stepStyle(step: string): Parameters<typeof styleText>[0] {\n switch (step) {\n case \"sandcastle\":\n return [\"bold\", \"cyan\"];\n case \"git\":\n return [\"bold\", \"magenta\"];\n case \"review\":\n case \"reviewer\":\n return [\"bold\", \"blue\"];\n case \"cleanup\":\n return [\"bold\", \"yellow\"];\n case \"error\":\n return [\"bold\", \"red\"];\n case \"warn\":\n return [\"bold\", \"yellow\"];\n case \"info\":\n return \"cyan\";\n default:\n return \"green\";\n }\n}\n\nfunction color(format: Parameters<typeof styleText>[0], text: string) {\n if (process.env.NO_COLOR) {\n return text;\n }\n\n try {\n return styleText(format, text);\n } catch {\n return text;\n }\n}\n","import { mkdir } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { execFile, spawnSync } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport { type PourkitLogger, createLogger } from \"@pourkit/logger\";\n\nconst execFileAsync = promisify(execFile);\n\ntype RunResult = {\n code: number;\n stdout: string;\n stderr: string;\n};\n\nexport type { PourkitLogger };\nexport { createLogger };\n\nexport async function ensureDir(dir: string) {\n await mkdir(dir, { recursive: true });\n}\n\nexport function repoRoot(explicitRoot = process.env.POURKIT_ROOT) {\n if (explicitRoot?.trim()) {\n const root = explicitRoot.trim();\n\n const insideResult = spawnSync(\n \"git\",\n [\"-C\", root, \"rev-parse\", \"--is-inside-work-tree\"],\n { encoding: \"utf8\" }\n );\n\n if (insideResult.status !== 0 || insideResult.stdout.trim() !== \"true\") {\n throw new Error(\n `POURKIT_ROOT is not a valid Git worktree: ${root}\\n${insideResult.stderr || insideResult.stdout}`\n );\n }\n\n const topLevelResult = spawnSync(\n \"git\",\n [\"-C\", root, \"rev-parse\", \"--show-toplevel\"],\n { encoding: \"utf8\" }\n );\n\n if (topLevelResult.status !== 0) {\n throw new Error(\n `Failed to validate POURKIT_ROOT as a Git worktree: ${root}\\n${topLevelResult.stderr || topLevelResult.stdout}`\n );\n }\n\n return topLevelResult.stdout.trim();\n }\n\n const result = spawnSync(\"git\", [\"rev-parse\", \"--show-toplevel\"], {\n encoding: \"utf8\",\n });\n\n if (result.status !== 0) {\n throw new Error(\n `Failed to resolve repo root: ${result.stderr || result.stdout}`\n );\n }\n\n return result.stdout.trim();\n}\n\nexport function repoRelative(root: string, ...segments: string[]) {\n return path.join(root, ...segments);\n}\n\nexport function slugify(value: string) {\n const slug = value\n .toLowerCase()\n .replace(/[^a-z0-9]/g, \"-\")\n .replace(/--+/g, \"-\")\n .replace(/^-+/, \"\")\n .replace(/-+$/, \"\")\n .slice(0, 50);\n\n return slug || \"issue\";\n}\n\nfunction formatCommand(command: string, args: string[]) {\n return [command, ...args]\n .map((part) => {\n if (/^[A-Za-z0-9_\\/.=:,@+-]+$/.test(part)) {\n return part;\n }\n\n return `'${part.replace(/'/g, \"'\\\\''\")}'`;\n })\n .join(\" \");\n}\n\nexport function readMaybeEnvInt(value: string | undefined, fallback: number) {\n const parsed = Number(value ?? fallback);\n return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;\n}\n\nexport async function execCapture(\n command: string,\n args: string[],\n options: {\n cwd?: string;\n env?: NodeJS.ProcessEnv;\n logger?: PourkitLogger;\n label?: string;\n } = {}\n) {\n if (options.logger && options.label) {\n options.logger.step(\n options.label,\n `running ${formatCommand(command, args)}`\n );\n }\n\n let stdout = \"\";\n let stderr = \"\";\n let code = 0;\n\n try {\n const result = await execFileAsync(command, args, {\n cwd: options.cwd,\n env: options.env,\n encoding: \"utf8\",\n maxBuffer: 20 * 1024 * 1024,\n });\n\n stdout =\n typeof result.stdout === \"string\"\n ? result.stdout\n : String(result.stdout ?? \"\");\n stderr =\n typeof result.stderr === \"string\"\n ? result.stderr\n : String(result.stderr ?? \"\");\n } catch (error) {\n const err = error as NodeJS.ErrnoException & {\n stdout?: string;\n stderr?: string;\n code?: number | string;\n };\n stdout = typeof err.stdout === \"string\" ? err.stdout : \"\";\n stderr = typeof err.stderr === \"string\" ? err.stderr : \"\";\n code = typeof err.code === \"number\" ? err.code : 1;\n }\n\n if (code !== 0) {\n throw new Error(\n [\n `command failed: ${formatCommand(command, args)}`,\n `exit code: ${code}`,\n stdout ? `stdout:\\n${stdout}` : \"\",\n stderr ? `stderr:\\n${stderr}` : \"\",\n ]\n .filter(Boolean)\n .join(\"\\n\")\n );\n }\n\n return { code, stdout, stderr } satisfies RunResult;\n}\n\nexport async function execJson<T>(\n command: string,\n args: string[],\n options: {\n cwd?: string;\n env?: NodeJS.ProcessEnv;\n logger?: PourkitLogger;\n label?: string;\n } = {}\n) {\n const result = await execCapture(command, args, options);\n return JSON.parse(result.stdout) as T;\n}\n\nexport function sleep(ms: number) {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nconst TRANSIENT_GH_ERROR =\n /HTTP (502|503|504)\\b|Could not close the issue|GraphQL:.*closeIssue/;\n\nexport async function execCaptureWithRetry(\n command: string,\n args: string[],\n options: {\n cwd?: string;\n env?: NodeJS.ProcessEnv;\n logger?: PourkitLogger;\n label?: string;\n retries?: number;\n backoffMs?: number;\n } = {}\n) {\n const retries = options.retries ?? 3;\n const backoffMs = options.backoffMs ?? 2000;\n let lastError: Error | null = null;\n\n for (let attempt = 1; attempt <= retries; attempt++) {\n try {\n return await execCapture(command, args, options);\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n if (!TRANSIENT_GH_ERROR.test(lastError.message)) {\n throw lastError;\n }\n if (options.logger) {\n options.logger.step(\n options.label ?? command,\n `transient failure (attempt ${attempt}/${retries}), retrying`\n );\n }\n if (attempt < retries) {\n await sleep(backoffMs * Math.pow(2, attempt - 1));\n }\n }\n }\n\n throw lastError!;\n}\n\nasync function execJsonWithRetry<T>(\n command: string,\n args: string[],\n options: {\n cwd?: string;\n env?: NodeJS.ProcessEnv;\n logger?: PourkitLogger;\n label?: string;\n retries?: number;\n backoffMs?: number;\n } = {}\n) {\n const result = await execCaptureWithRetry(command, args, options);\n return JSON.parse(result.stdout) as T;\n}\n\nexport const TYPE_LABELS = [\n \"type:bugfix\",\n \"type:infra\",\n \"type:feature\",\n \"type:polish\",\n \"type:refactor\",\n] as const;\n\n/**\n * Parse `git worktree list --porcelain` output and find the worktree\n * path for a given branch.\n *\n * Returns null if no worktree is registered for that branch.\n */\nexport function parseWorktreeListPorcelain(\n text: string,\n branch: string\n): string | null {\n const entries = text.trim().split(\"\\n\\n\");\n for (const entry of entries) {\n const lines = entry.trim().split(\"\\n\");\n let path = \"\";\n let entryBranch = \"\";\n for (const line of lines) {\n if (line.startsWith(\"worktree \")) {\n path = line.slice(\"worktree \".length);\n } else if (line.startsWith(\"branch refs/heads/\")) {\n entryBranch = line.slice(\"branch refs/heads/\".length);\n }\n }\n if (entryBranch === branch && path) {\n return path;\n }\n }\n return null;\n}\n\nconst TOKEN_LIKE_PATTERNS = [\n /gh[ps]_[A-Za-z0-9]{20,}/g,\n /token[=:_\\s][A-Za-z0-9_-]{20,}/gi,\n /secret[=:_\\s][A-Za-z0-9_-]{20,}/gi,\n /credential[=:_\\s][A-Za-z0-9_-]{20,}/gi,\n /key[=:_\\s][A-Za-z0-9_-]{20,}/gi,\n /bearer\\s+[A-Za-z0-9_-]{20,}/gi,\n /authorization:\\s*Bearer\\s+[A-Za-z0-9_-]{20,}/gi,\n /xox[baprs]-[A-Za-z0-9_-]{10,}/g,\n];\n\nexport function redactSensitiveValues(input: string): string {\n let redacted = input;\n for (const pattern of TOKEN_LIKE_PATTERNS) {\n redacted = redacted.replace(pattern, \"[REDACTED]\");\n }\n return redacted;\n}\n","import path from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport { mkdir, readFile, readdir, rm, writeFile } from \"node:fs/promises\";\nimport { runIssueCommand } from \"../commands/issue\";\nimport {\n createLogger,\n execCapture,\n execJson,\n parseWorktreeListPorcelain,\n repoRoot,\n type PourkitLogger,\n} from \"../shared/common\";\nimport {\n getVerificationCommands as getTargetVerificationCommands,\n loadConfig,\n loadRepoConfig,\n resolveTarget,\n type PourkitConfig,\n} from \"../shared/config\";\nimport { renderBranchName } from \"../pr/templates\";\nimport { GitHubIssueProvider } from \"../providers/github-provider\";\nimport { GitHubPRProvider } from \"../providers/github-pr-provider\";\nimport {\n requireGitHubClient,\n type GitHubClient,\n} from \"../providers/github-client\";\nimport type { PullRequest } from \"../providers/pr-provider\";\nimport { DeterministicExecutionProvider } from \"../execution/deterministic-agent\";\nimport {\n getVerificationCommands,\n composeFailureWithProfile,\n type E2EVerificationProfile,\n} from \"./profile\";\nimport { waitForBranchChecks } from \"../issues/target-green\";\nimport {\n cleanupResources as harnessCleanupResources,\n createE2EIssue as harnessCreateE2EIssue,\n createLiveTargetBranch as harnessCreateLiveTargetBranch,\n fetchIssueLabels,\n persistResources as harnessPersistResources,\n recoverStaleRuns as harnessRecoverStaleRuns,\n runCleanupOnly as harnessRunCleanupOnly,\n} from \"./live/harness\";\n\nexport interface E2EOptions {\n keep: boolean;\n fail: boolean;\n fullCheck: boolean;\n cleanupOnly: boolean;\n targetName?: string;\n}\n\ninterface E2EResources {\n targetBranch?: string;\n issueNumber?: number;\n issueUrl?: string;\n agentBranch?: string;\n prNumber?: number;\n prUrl?: string;\n}\n\ninterface E2EStateFile extends E2EResources {\n runId: string;\n}\n\nconst E2E_STATE_DIR = path.join(\".pourkit\", \".tmp\", \"e2e-runs\");\n\nexport function parseArgs(): E2EOptions {\n const args = process.argv.slice(2);\n let keep = false;\n let fail = false;\n let fullCheck = false;\n let cleanupOnly = false;\n let targetName: string | undefined;\n\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n if (arg === \"--keep\") {\n keep = true;\n } else if (arg === \"--fail\") {\n fail = true;\n } else if (arg === \"--full-check\") {\n fullCheck = true;\n } else if (arg === \"--cleanup-only\") {\n cleanupOnly = true;\n } else if (arg === \"--target\" && args[i + 1]) {\n targetName = args[i + 1];\n i++;\n }\n }\n\n return { keep, fail, fullCheck, cleanupOnly, targetName };\n}\n\nexport function resolveProfile(fullCheck: boolean): E2EVerificationProfile {\n return fullCheck ? \"full-check\" : \"fast\";\n}\n\nexport function isExecutedAsScript(\n currentUrl = import.meta.url,\n entryPoint = process.argv[1]\n): boolean {\n if (!entryPoint) {\n return false;\n }\n\n return currentUrl === pathToFileURL(path.resolve(entryPoint)).href;\n}\n\nexport function resolveE2EConfigFile(root: string): string {\n const explicitConfig = process.env.POURKIT_CONFIG_FILE?.trim();\n if (explicitConfig) {\n return explicitConfig;\n }\n\n return path.join(\".pourkit\", \"config.json\");\n}\n\nfunction generateRunId(): string {\n return `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n}\n\nfunction stateFilePath(root: string, runId: string): string {\n return path.join(root, E2E_STATE_DIR, `${runId}.json`);\n}\n\nasync function persistResources(\n root: string,\n runId: string,\n resources: E2EResources\n): Promise<void> {\n const filePath = stateFilePath(root, runId);\n await mkdir(path.dirname(filePath), { recursive: true });\n const state: E2EStateFile = { runId, ...resources };\n await writeFile(filePath, `${JSON.stringify(state, null, 2)}\\n`, \"utf-8\");\n}\n\nasync function localBranchExists(branchName: string): Promise<boolean> {\n try {\n await execCapture(\"git\", [\n \"show-ref\",\n \"--verify\",\n \"--quiet\",\n `refs/heads/${branchName}`,\n ]);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function remoteBranchExists(branchName: string): Promise<boolean> {\n const result = await execCapture(\"git\", [\n \"ls-remote\",\n \"--heads\",\n \"origin\",\n branchName,\n ]);\n return result.stdout.trim().length > 0;\n}\n\nasync function removeWorktreeForBranch(\n branchName: string,\n logger: PourkitLogger\n): Promise<boolean> {\n try {\n const result = await execCapture(\"git\", [\n \"worktree\",\n \"list\",\n \"--porcelain\",\n ]);\n const worktreePath = parseWorktreeListPorcelain(result.stdout, branchName);\n\n if (!worktreePath) {\n return true;\n }\n\n logger.step(\"cleanup\", `Removing worktree for branch: ${branchName}...`);\n await execCapture(\"git\", [\"worktree\", \"remove\", \"--force\", worktreePath]);\n return true;\n } catch (error) {\n logger.step(\n \"warn\",\n `Failed to remove worktree for branch: ${error instanceof Error ? error.message : String(error)}`\n );\n return false;\n }\n}\n\nasync function deleteLocalBranch(\n branchName: string,\n logger: PourkitLogger\n): Promise<boolean> {\n if (!(await localBranchExists(branchName))) {\n return true;\n }\n\n if (!(await removeWorktreeForBranch(branchName, logger))) {\n return false;\n }\n\n try {\n logger.step(\"cleanup\", `Deleting local branch: ${branchName}...`);\n await execCapture(\"git\", [\"branch\", \"-D\", branchName]);\n return true;\n } catch (error) {\n logger.step(\n \"warn\",\n `Failed to delete local branch: ${error instanceof Error ? error.message : String(error)}`\n );\n return false;\n }\n}\n\nasync function deleteRemoteBranch(\n branchName: string,\n logger: PourkitLogger\n): Promise<boolean> {\n if (!(await remoteBranchExists(branchName))) {\n return true;\n }\n\n try {\n logger.step(\"cleanup\", `Deleting remote branch: ${branchName}...`);\n await execCapture(\"git\", [\"push\", \"origin\", \"--delete\", branchName]);\n return true;\n } catch (error) {\n logger.step(\n \"warn\",\n `Failed to delete remote branch: ${error instanceof Error ? error.message : String(error)}`\n );\n return false;\n }\n}\n\nasync function recoverStaleRuns(\n root: string,\n logger: PourkitLogger\n): Promise<void> {\n const dir = path.join(root, E2E_STATE_DIR);\n\n try {\n const entries = await readdir(dir, { withFileTypes: true });\n for (const entry of entries) {\n if (!entry.isFile() || !entry.name.endsWith(\".json\")) continue;\n\n const filePath = path.join(dir, entry.name);\n try {\n const raw = await readFile(filePath, \"utf-8\");\n const state = JSON.parse(raw) as E2EStateFile;\n let cleanupSucceeded = true;\n\n if (state.agentBranch) {\n cleanupSucceeded =\n (await deleteLocalBranch(state.agentBranch, logger)) &&\n cleanupSucceeded;\n cleanupSucceeded =\n (await deleteRemoteBranch(state.agentBranch, logger)) &&\n cleanupSucceeded;\n }\n\n if (state.targetBranch) {\n cleanupSucceeded =\n (await deleteLocalBranch(state.targetBranch, logger)) &&\n cleanupSucceeded;\n cleanupSucceeded =\n (await deleteRemoteBranch(state.targetBranch, logger)) &&\n cleanupSucceeded;\n }\n\n if (cleanupSucceeded) {\n await rm(filePath, { force: true });\n } else {\n logger.step(\n \"warn\",\n `Preserving stale E2E state ${entry.name} for cleanup retry`\n );\n }\n } catch (error) {\n logger.step(\n \"warn\",\n `Failed to recover stale E2E state ${entry.name}: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") {\n logger.step(\n \"warn\",\n `Failed to scan stale E2E state: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n}\n\nexport function makeE2EConfig(\n baseConfig: PourkitConfig,\n targetName: string | undefined,\n targetBranch: string,\n profile: E2EVerificationProfile\n): PourkitConfig {\n const resolvedTargetName = targetName ?? \"e2e\";\n const target = resolveTarget(baseConfig, resolvedTargetName);\n const strategy = target.strategy;\n const verificationCommands = getVerificationCommands(\n getTargetVerificationCommands(target),\n profile\n );\n\n return {\n ...baseConfig,\n targets: [\n {\n ...target,\n baseBranch: targetBranch,\n strategy: {\n ...strategy,\n verify: { commands: verificationCommands },\n },\n },\n ],\n };\n}\n\nasync function cleanup(\n resources: E2EResources,\n root: string,\n runId: string,\n keep: boolean,\n logger: PourkitLogger,\n client: GitHubClient\n): Promise<void> {\n if (keep) {\n logger.line(\"--keep flag set, preserving E2E resources:\");\n if (resources.issueNumber)\n logger.line(` Issue: #${resources.issueNumber}`);\n if (resources.issueUrl) logger.line(` Issue URL: ${resources.issueUrl}`);\n if (resources.targetBranch)\n logger.line(` Target branch: ${resources.targetBranch}`);\n if (resources.agentBranch)\n logger.line(` Agent branch: ${resources.agentBranch}`);\n if (resources.prNumber)\n logger.line(` PR: #${resources.prNumber} (${resources.prUrl})`);\n return;\n }\n\n logger.line(\"Cleaning up E2E resources...\");\n let cleanupSucceeded = true;\n\n if (resources.prNumber) {\n try {\n const { data } = await client.octokit.rest.pulls.get({\n owner: client.owner,\n repo: client.repo,\n pull_number: resources.prNumber,\n });\n if (data.merged) {\n logger.step(\n \"cleanup\",\n `PR #${resources.prNumber} is merged, skipping close`\n );\n } else {\n logger.step(\"cleanup\", `Closing PR #${resources.prNumber}...`);\n await client.octokit.rest.pulls.update({\n owner: client.owner,\n repo: client.repo,\n pull_number: resources.prNumber,\n state: \"closed\",\n });\n }\n } catch (error) {\n logger.step(\n \"warn\",\n `Failed to close PR: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n\n if (resources.issueNumber) {\n try {\n logger.step(\"cleanup\", `Closing issue #${resources.issueNumber}...`);\n await client.octokit.rest.issues.update({\n owner: client.owner,\n repo: client.repo,\n issue_number: resources.issueNumber,\n state: \"closed\",\n state_reason: \"completed\",\n });\n } catch (error) {\n logger.step(\n \"warn\",\n `Failed to close issue: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n\n if (resources.agentBranch) {\n cleanupSucceeded =\n (await deleteLocalBranch(resources.agentBranch, logger)) &&\n cleanupSucceeded;\n cleanupSucceeded =\n (await deleteRemoteBranch(resources.agentBranch, logger)) &&\n cleanupSucceeded;\n }\n\n if (resources.targetBranch) {\n cleanupSucceeded =\n (await deleteLocalBranch(resources.targetBranch, logger)) &&\n cleanupSucceeded;\n cleanupSucceeded =\n (await deleteRemoteBranch(resources.targetBranch, logger)) &&\n cleanupSucceeded;\n }\n\n if (cleanupSucceeded) {\n await rm(stateFilePath(root, runId), { force: true });\n } else {\n logger.step(\"warn\", \"Preserving E2E state for retry after cleanup failure\");\n }\n\n logger.line(\"Cleanup complete.\");\n}\n\nasync function verifyAssertions(\n pr: PullRequest,\n issueNumber: number,\n targetBranch: string,\n expectedHead: string,\n expectedTitle: string,\n logger: PourkitLogger,\n client: GitHubClient\n): Promise<void> {\n logger.raw(\"\\n=== Running Assertions ===\\n\");\n\n const errors: string[] = [];\n\n if (pr.baseRefName !== targetBranch) {\n errors.push(`PR base is \"${pr.baseRefName}\", expected \"${targetBranch}\"`);\n } else {\n logger.raw(`[✓] PR base is target branch: ${targetBranch}`);\n }\n\n if (pr.headRefName !== expectedHead) {\n errors.push(`PR head is \"${pr.headRefName}\", expected \"${expectedHead}\"`);\n } else {\n logger.raw(`[✓] PR head is agent branch: ${expectedHead}`);\n }\n\n if (pr.title !== expectedTitle) {\n errors.push(`PR title is \"${pr.title}\", expected \"${expectedTitle}\"`);\n } else {\n logger.raw(`[✓] PR title matches template`);\n }\n\n if (\n pr.body !== undefined &&\n !new RegExp(`[Cc]loses\\\\s*#${issueNumber}`).test(pr.body)\n ) {\n errors.push(`PR body does not contain \"Closes #${issueNumber}\"`);\n } else {\n logger.raw(`[✓] PR body contains \"Closes #${issueNumber}\"`);\n }\n\n try {\n await execCapture(\"git\", [\"fetch\", \"origin\", pr.headRefName]);\n const countResult = await execCapture(\"git\", [\n \"rev-list\",\n \"--count\",\n `origin/${pr.headRefName}`,\n ]);\n const commitCount = Number(countResult.stdout.trim());\n if (!Number.isFinite(commitCount) || commitCount <= 0) {\n errors.push(`No commits found on the agent branch ${pr.headRefName}`);\n } else {\n logger.raw(`[✓] Commits exist on agent branch: ${commitCount} commit(s)`);\n }\n } catch (error) {\n errors.push(\n `Failed to verify commits: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n\n try {\n const labelNames = await fetchIssueLabels(issueNumber, client);\n\n if (labelNames.includes(\"pr-open-awaiting-merge\")) {\n errors.push(\n `Issue #${issueNumber} still has \"pr-open-awaiting-merge\" label after merge. Labels: ${labelNames.join(\", \")}`\n );\n } else {\n logger.raw(`[✓] Issue no longer has \"pr-open-awaiting-merge\"`);\n }\n\n if (labelNames.includes(\"ready-for-agent\")) {\n errors.push(\n `Issue #${issueNumber} still has \"ready-for-agent\" label. Labels: ${labelNames.join(\", \")}`\n );\n } else {\n logger.raw(`[✓] Issue no longer has \"ready-for-agent\"`);\n }\n\n if (labelNames.includes(\"agent-in-progress\")) {\n errors.push(\n `Issue #${issueNumber} still has \"agent-in-progress\" label. Labels: ${labelNames.join(\", \")}`\n );\n } else {\n logger.raw(`[✓] Issue no longer has \"agent-in-progress\"`);\n }\n\n if (pr.state !== \"MERGED\") {\n errors.push(`PR state is \"${pr.state}\", expected \"MERGED\"`);\n } else {\n logger.raw(`[✓] PR is merged`);\n }\n } catch (error) {\n errors.push(\n `Failed to verify issue labels: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n\n if (errors.length > 0) {\n logger.raw(\"\\n=== Assertion Failures ===\\n\");\n for (const error of errors) {\n logger.raw(`[✗] ${error}`);\n }\n throw new Error(`${errors.length} assertion(s) failed`);\n }\n\n logger.raw(\"\\n=== All Assertions Passed ===\\n\");\n}\n\nasync function verifyFailureAssertions(\n issueNumber: number,\n logger: PourkitLogger,\n client: GitHubClient\n): Promise<void> {\n logger.raw(\"\\n=== Running Failure Assertions ===\\n\");\n\n const errors: string[] = [];\n\n try {\n const labelNames = await fetchIssueLabels(issueNumber, client);\n\n if (!labelNames.includes(\"ready-for-human\")) {\n errors.push(\n `Issue #${issueNumber} does not have \"ready-for-human\" label. Labels: ${labelNames.join(\", \")}`\n );\n } else {\n logger.raw(`[✓] Issue has \"ready-for-human\" label`);\n }\n\n if (labelNames.includes(\"agent-in-progress\")) {\n errors.push(\n `Issue #${issueNumber} still has \"agent-in-progress\" label. Labels: ${labelNames.join(\", \")}`\n );\n } else {\n logger.raw(`[✓] Issue no longer has \"agent-in-progress\"`);\n }\n } catch (error) {\n errors.push(\n `Failed to verify issue labels: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n\n if (errors.length > 0) {\n logger.raw(\"\\n=== Assertion Failures ===\\n\");\n for (const error of errors) {\n logger.raw(`[✗] ${error}`);\n }\n throw new Error(`${errors.length} assertion(s) failed`);\n }\n\n logger.raw(\"\\n=== All Failure Assertions Passed ===\\n\");\n}\n\nexport function makeFailureE2EConfig(\n baseConfig: PourkitConfig,\n targetName: string | undefined,\n targetBranch: string,\n profile: E2EVerificationProfile\n): PourkitConfig {\n const resolvedTargetName = targetName ?? \"e2e\";\n const target = resolveTarget(baseConfig, resolvedTargetName);\n const strategy = target.strategy;\n const verificationCommands = composeFailureWithProfile(\n getTargetVerificationCommands(target),\n profile\n );\n\n return {\n ...baseConfig,\n targets: [\n {\n ...target,\n baseBranch: targetBranch,\n strategy: {\n ...strategy,\n verify: { commands: verificationCommands },\n },\n },\n ],\n };\n}\n\nasync function runCleanupOnly(\n root: string,\n logger: PourkitLogger\n): Promise<void> {\n logger.line(\"Running cleanup-only mode: deleting stale e2e branches...\");\n\n const result = await execCapture(\"git\", [\"ls-remote\", \"--heads\", \"origin\"]);\n const lines = result.stdout\n .split(\"\\n\")\n .filter((line) => line.trim().length > 0);\n\n const e2eBranchPattern =\n /refs\\/heads\\/(pourkit-e2e-target\\/|pourkit\\/\\d+\\/(e2e-test-issue-|test-live-e2e-))/;\n const branchesToDelete = lines\n .map((line) => {\n const parts = line.split(/\\s+/);\n return parts[1];\n })\n .filter((ref) => e2eBranchPattern.test(ref))\n .map((ref) => ref.replace(\"refs/heads/\", \"\"));\n\n let deletedCount = 0;\n let failedCount = 0;\n\n for (const branch of branchesToDelete) {\n const localOk = await deleteLocalBranch(branch, logger);\n const remoteOk = await deleteRemoteBranch(branch, logger);\n if (localOk && remoteOk) {\n deletedCount++;\n } else {\n failedCount++;\n }\n }\n\n const stateDir = path.join(root, E2E_STATE_DIR);\n try {\n const entries = await readdir(stateDir, { withFileTypes: true });\n for (const entry of entries) {\n if (!entry.isFile() || !entry.name.endsWith(\".json\")) continue;\n const filePath = path.join(stateDir, entry.name);\n await rm(filePath, { force: true });\n logger.step(\"cleanup\", `Removed state file: ${entry.name}`);\n }\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") {\n logger.step(\n \"warn\",\n `Failed to scan state directory: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n\n logger.line(\n `Cleanup-only complete: ${deletedCount} branch(es) deleted, ${failedCount} failure(s)`\n );\n}\n\nasync function runE2E(): Promise<void> {\n const options = parseArgs();\n const runId = generateRunId();\n const root = repoRoot();\n const logPath = path.join(root, \"pourkit\", \"logs\", `e2e-${runId}.log`);\n const logger = createLogger(\"e2e\", logPath);\n const client = await requireGitHubClient({ cwd: root });\n\n logger.line(`Starting E2E test run: ${runId}`);\n logger.line(`Keep resources: ${options.keep}`);\n logger.line(`Failure mode: ${options.fail}`);\n logger.line(`Verification profile: ${resolveProfile(options.fullCheck)}`);\n\n if (options.cleanupOnly) {\n await harnessRunCleanupOnly(root, logger, client);\n await logger.close();\n return;\n }\n\n await harnessRecoverStaleRuns(root, logger);\n\n if (options.fail) {\n await runFailureE2E(options, runId, root, logger);\n } else {\n await runSuccessE2E(options, runId, root, logger, client);\n }\n}\n\nasync function runSuccessE2E(\n options: E2EOptions,\n runId: string,\n root: string,\n logger: PourkitLogger,\n client: GitHubClient\n): Promise<void> {\n const issueProvider = new GitHubIssueProvider(client);\n const executionProvider = new DeterministicExecutionProvider();\n const prProvider = new GitHubPRProvider(client, logger);\n\n const resources: E2EResources = {};\n\n try {\n const targetBranch = await harnessCreateLiveTargetBranch(runId, logger);\n resources.targetBranch = targetBranch;\n if (!options.keep) {\n await harnessPersistResources(root, runId, resources);\n }\n\n const createdIssue = await harnessCreateE2EIssue(\n runId,\n targetBranch,\n logger,\n client\n );\n resources.issueNumber = createdIssue.number;\n resources.issueUrl = createdIssue.url;\n if (!options.keep) {\n await harnessPersistResources(root, runId, resources);\n }\n\n const e2eConfigFile = resolveE2EConfigFile(root);\n const baseConfig =\n e2eConfigFile === path.join(\".pourkit\", \"config.json\")\n ? await loadRepoConfig(root)\n : await loadConfig(path.resolve(root, e2eConfigFile));\n const profile = resolveProfile(options.fullCheck);\n const config = makeE2EConfig(\n baseConfig,\n options.targetName,\n targetBranch,\n profile\n );\n const expectedIssue = await issueProvider.fetchIssue(createdIssue.number);\n const expectedTarget = resolveTarget(config, options.targetName);\n resources.agentBranch = renderBranchName(\n expectedTarget.branchTemplate,\n expectedIssue\n );\n if (!options.keep) {\n await harnessPersistResources(root, runId, resources);\n }\n\n logger.raw(`\\nRunning issue command for #${createdIssue.number}...\\n`);\n\n const result = await runIssueCommand({\n issueNumber: createdIssue.number,\n targetName: options.targetName,\n config,\n issueProvider,\n prProvider,\n executionProvider,\n force: false,\n logger,\n repoRoot: root,\n });\n\n resources.agentBranch = result.branchName;\n resources.prNumber = result.prNumber;\n resources.prUrl = result.prUrl;\n if (!options.keep) {\n await harnessPersistResources(root, runId, resources);\n }\n\n logger.raw(`\\nIssue command completed:`);\n logger.raw(` Issue: #${createdIssue.number}`);\n logger.raw(` Branch: ${result.branchName}`);\n logger.raw(` PR: #${result.prNumber} (${result.prUrl})`);\n\n if (!result.prNumber) {\n throw new Error(\"Issue command did not return a PR number\");\n }\n\n const pr = await execJson<PullRequest>(\"gh\", [\n \"pr\",\n \"view\",\n String(result.prNumber),\n \"--json\",\n \"number,nodeId,url,title,body,headRefName,baseRefName,state,headRefOid\",\n ]);\n\n await verifyAssertions(\n pr,\n createdIssue.number,\n targetBranch,\n result.branchName,\n result.prTitle ?? result.issue.title,\n logger,\n client\n );\n\n logger.raw(\"\\n=== Verifying Merge and Target-Green ===\\n\");\n\n if (pr.state !== \"MERGED\") {\n throw new Error(\n `PR #${result.prNumber} was not merged after issue command (state: ${pr.state})`\n );\n }\n logger.raw(`[✓] PR #${result.prNumber} is merged`);\n\n await waitForBranchChecks(prProvider, logger, {\n branchName: targetBranch,\n checksFoundTimeoutMs: config.checks.checksFoundTimeoutSeconds * 1000,\n checksCompletionTimeoutMs:\n config.checks.checksCompletionTimeoutSeconds * 1000,\n pollIntervalMs: config.checks.pollIntervalSeconds * 1000,\n });\n logger.raw(`[✓] Target branch ${targetBranch} is green after merge`);\n\n logger.raw(\"\\n=== E2E Test Passed ===\\n\");\n } catch (error) {\n logger.step(\n \"error\",\n `E2E test failed: ${error instanceof Error ? error.message : String(error)}`\n );\n throw error;\n } finally {\n await harnessCleanupResources(\n resources,\n root,\n runId,\n options.keep,\n logger,\n client\n );\n await logger.close();\n }\n}\n\nasync function runFailureE2E(\n options: E2EOptions,\n runId: string,\n root: string,\n logger: PourkitLogger\n): Promise<void> {\n const client = await requireGitHubClient({ cwd: root });\n const issueProvider = new GitHubIssueProvider(client);\n const executionProvider = new DeterministicExecutionProvider();\n const prProvider = new GitHubPRProvider(client, logger);\n\n const resources: E2EResources = {};\n\n try {\n const targetBranch = await harnessCreateLiveTargetBranch(runId, logger);\n resources.targetBranch = targetBranch;\n if (!options.keep) {\n await harnessPersistResources(root, runId, resources);\n }\n\n const createdIssue = await harnessCreateE2EIssue(\n runId,\n targetBranch,\n logger,\n client\n );\n resources.issueNumber = createdIssue.number;\n resources.issueUrl = createdIssue.url;\n if (!options.keep) {\n await harnessPersistResources(root, runId, resources);\n }\n\n const e2eConfigFile = resolveE2EConfigFile(root);\n const baseConfig =\n e2eConfigFile === path.join(\".pourkit\", \"config.json\")\n ? await loadRepoConfig(root)\n : await loadConfig(path.resolve(root, e2eConfigFile));\n const profile = resolveProfile(options.fullCheck);\n const config = makeFailureE2EConfig(\n baseConfig,\n options.targetName,\n targetBranch,\n profile\n );\n const expectedIssue = await issueProvider.fetchIssue(createdIssue.number);\n const expectedTarget = resolveTarget(config, options.targetName);\n resources.agentBranch = renderBranchName(\n expectedTarget.branchTemplate,\n expectedIssue\n );\n if (!options.keep) {\n await harnessPersistResources(root, runId, resources);\n }\n\n logger.raw(\n `\\nRunning issue command for #${createdIssue.number} (failure mode)...\\n`\n );\n\n await runIssueCommand({\n issueNumber: createdIssue.number,\n targetName: options.targetName,\n config,\n issueProvider,\n prProvider,\n executionProvider,\n force: false,\n logger,\n repoRoot: root,\n });\n\n if (!options.keep) {\n await harnessPersistResources(root, runId, resources);\n }\n\n throw new Error(\"Expected runIssueCommand to throw in failure mode\");\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n if (message === \"Expected runIssueCommand to throw in failure mode\") {\n throw error;\n }\n\n logger.raw(`\\nIssue command failed as expected: ${message}`);\n\n await verifyFailureAssertions(resources.issueNumber ?? 0, logger, client);\n\n logger.raw(\"\\n=== E2E Failure Test Passed ===\\n\");\n } finally {\n await cleanup(resources, root, runId, options.keep, logger, client);\n await logger.close();\n }\n}\n\nif (isExecutedAsScript()) {\n runE2E().catch((error) => {\n const msg = `Fatal: ${error instanceof Error ? error.message : String(error)}`;\n console.error(msg);\n process.exit(1);\n });\n}\n","import { existsSync, readFileSync } from \"fs\";\nimport { isAbsolute, join } from \"path\";\nimport type {\n PourkitConfig,\n IssueData,\n ResolvedTarget,\n ResolvedPrdRunMode,\n} from \"../shared/config\";\nimport { resolvePromptTemplatePath, resolveTarget } from \"../shared/config\";\nimport { renderBranchName } from \"../pr/templates\";\nimport type { IssueProvider } from \"../providers/issue-provider\";\nimport type { PRProvider } from \"../providers/pr-provider\";\nimport type {\n ExecutionProvider,\n ExecutionResult,\n} from \"../execution/execution-provider\";\nimport {\n execCapture,\n readMaybeEnvInt,\n parseWorktreeListPorcelain,\n type PourkitLogger,\n} from \"../shared/common\";\nimport {\n buildRunContextArtifact,\n RUN_CONTEXT_PATH_IN_WORKTREE,\n STAGE_SECTIONS,\n} from \"../shared/run-context\";\nimport { appendProtectedWorkGuidance } from \"../shared/prompt-guidance\";\nimport type { SerenaExecutionContext } from \"../execution/opencode-config\";\nimport {\n readWorktreeRunState,\n writeWorktreeRunState,\n updateWorktreeRunState,\n type WorktreeRunState,\n} from \"../shared/worktree-run-state\";\nimport { invalidateAfterBaseRefresh } from \"./base-refresh\";\nimport { runBaseRefreshAttempt } from \"../failure-resolution/effect-runtime\";\nimport {\n RebaseConflict,\n PublishedHistoryRisk,\n} from \"../failure-resolution/types\";\nimport { hasUnresolvedConflictMarkers } from \"./conflict-resolution\";\nimport { Exit } from \"effect\";\nimport { runEffectAndMapExit } from \"../shared/effect-runtime\";\nimport { prepareSerenaForTarget } from \"../serena/preflight\";\nimport {\n constructFailureResolutionPacket,\n runFailureResolutionAgent,\n} from \"../failure-resolution/failure-resolution-agent\";\nimport { FinalizerFailure } from \"../failure-resolution/types\";\nimport {\n runFinalizerAgent,\n type RunFinalizerResult,\n} from \"./pr-description-agent\";\nimport {\n squashMergeLocalIssue,\n hasLocalIssueMergeReceipt,\n} from \"../prd-run/local-merge-coordinator\";\nimport { getLocalPrdBranchName } from \"../prd-run/local-branches\";\nimport { ensureClosingRefs } from \"../pr/pr-body\";\nimport {\n ensureConventionalPrTitle,\n parsePrDescription,\n} from \"../pr/pr-description\";\nimport { runMergeCoordinator } from \"../issues/merge-coordinator\";\nimport { waitForBranchChecks } from \"../issues/target-green\";\nimport {\n runReviewWithRefactorLoop,\n type ReviewLoopResult,\n type RunReviewLoopOptions,\n} from \"./review\";\nimport {\n runIssueFinalReviewAgent,\n type IssueFinalReviewResult,\n} from \"./issue-final-review-agent\";\nimport { validateAgentArtifact } from \"./artifact-validation\";\nimport {\n createIssueTransitions,\n type IssueTransitionsContract,\n} from \"../issues/issue-transitions\";\nimport { parseStackedIssue } from \"../issues/stacked-issue\";\nconst EXECUTION_TIMEOUT_MS =\n readMaybeEnvInt(process.env.POURKIT_TIMEOUT_SECONDS, 30 * 60) * 1000;\n\ntype IssueWorktreeResolution =\n | {\n mode: \"new\";\n branchName: string;\n baseRef: string;\n worktreePath?: undefined;\n }\n | {\n mode: \"existing-worktree\";\n branchName: string;\n baseRef: string;\n worktreePath: string;\n }\n | {\n mode: \"existing-branch\";\n branchName: string;\n baseRef: string;\n worktreePath: string;\n };\n\nexport interface StartIssueRunOptions {\n issueNumber: number;\n targetName?: string;\n config: PourkitConfig;\n issueProvider: IssueProvider;\n prProvider: PRProvider;\n executionProvider: ExecutionProvider;\n force: boolean;\n resetWorktree?: boolean;\n logger: PourkitLogger;\n repoRoot: string;\n baseBranchOverride?: string;\n prdRunMode?: ResolvedPrdRunMode;\n}\n\nexport interface IssueGates {\n isOpen: boolean;\n isReadyForAgent: boolean;\n isNotBlocked: boolean;\n isNotInProgress: boolean;\n}\n\nexport interface IssueGateResult {\n allowed: boolean;\n gates: IssueGates;\n reason?: string;\n}\n\nexport function checkIssueGates(\n issue: IssueData,\n config: PourkitConfig,\n force: boolean\n): IssueGateResult {\n const gates: IssueGates = {\n isOpen: issue.state === \"open\",\n isReadyForAgent: issue.labels.includes(config.labels.readyForAgent),\n isNotBlocked: !issue.labels.includes(config.labels.blocked),\n isNotInProgress: !issue.labels.includes(config.labels.agentInProgress),\n };\n\n if (force) {\n return { allowed: true, gates };\n }\n\n const failed: string[] = [];\n\n if (!gates.isOpen) {\n failed.push(`issue ${issue.number} is not open`);\n }\n\n if (!gates.isReadyForAgent) {\n failed.push(\n `issue ${issue.number} is not labeled ${config.labels.readyForAgent}`\n );\n }\n\n if (!gates.isNotBlocked) {\n failed.push(`issue ${issue.number} is labeled ${config.labels.blocked}`);\n }\n\n if (!gates.isNotInProgress) {\n failed.push(\n `issue ${issue.number} is already labeled ${config.labels.agentInProgress}`\n );\n }\n\n if (failed.length > 0) {\n return {\n allowed: false,\n gates,\n reason: failed.join(\"; \"),\n };\n }\n\n return { allowed: true, gates };\n}\n\nfunction resolveSerenaRuntimeConfig(\n config: PourkitConfig,\n target: ResolvedTarget\n) {\n return {\n enabled: target.serena?.enabled ?? config.serena.enabled,\n required: target.serena?.required ?? config.serena.required,\n autoStart: config.serena.autoStart,\n dataDir: config.serena.dataDir,\n mcpUrl: config.serena.mcpUrl,\n sandboxMcpUrl: config.serena.sandboxMcpUrl,\n };\n}\n\nexport interface IssueRunStartResult {\n issue: IssueData;\n parentPrdIssue?: IssueData;\n target: ResolvedTarget;\n effectiveTarget: ResolvedTarget;\n branchName: string;\n worktreeState: WorktreeRunState | null;\n executionResult: ExecutionResult;\n serena?: SerenaExecutionContext;\n}\n\nexport interface RunIssueResult {\n branchName: string;\n target: ResolvedTarget;\n issue: IssueData;\n prNumber?: number;\n prUrl?: string;\n prTitle?: string;\n prBody?: string;\n noOp: boolean;\n mode?: \"github\" | \"local\";\n localPrdBranch?: string;\n mergeCommit?: string;\n receiptPath?: string;\n failureCode?: string;\n repairGuidance?: string;\n}\n\nexport interface CompleteIssueRunOptions extends StartIssueRunOptions {\n startResult: IssueRunStartResult;\n reviewArtifactPath?: string;\n}\n\nfunction assertIssueFinalReviewPassed(\n worktreeState: WorktreeRunState | null\n): void {\n const ifr = worktreeState?.issueFinalReview;\n if (!ifr || !ifr.completed || ifr.verdict !== \"pass\") {\n throw new Error(\n \"Issue Final Review has not passed. Cannot proceed to finalizer, commit, or PR creation.\"\n );\n }\n}\n\nexport interface AdvanceIssueFinalReviewOptions {\n executionProvider: ExecutionProvider;\n config: PourkitConfig;\n target: ResolvedTarget;\n issue: IssueData;\n parentPrdIssue?: IssueData;\n builderBranch: string;\n worktreePath: string;\n repoRoot: string;\n logger: PourkitLogger;\n reviewArtifactPath?: string;\n worktreeState: WorktreeRunState | null;\n}\n\nexport async function advanceIssueFinalReview(\n options: AdvanceIssueFinalReviewOptions\n): Promise<IssueFinalReviewResult> {\n const {\n executionProvider,\n config,\n target,\n issue,\n parentPrdIssue,\n builderBranch,\n worktreePath,\n repoRoot,\n logger,\n reviewArtifactPath,\n worktreeState,\n } = options;\n\n const ifrFromState = worktreeState?.issueFinalReview;\n if (ifrFromState?.completed && ifrFromState.verdict === \"pass\") {\n if (!ifrFromState.artifactPath) {\n throw new Error(\n \"Issue Final Review state is incomplete: missing artifactPath\"\n );\n }\n const artifactPath = isAbsolute(ifrFromState.artifactPath)\n ? ifrFromState.artifactPath\n : join(worktreePath, ifrFromState.artifactPath);\n const validation = validateAgentArtifact({\n kind: \"issue-final-review\",\n artifactPath,\n issueNumber: issue.number,\n branchName: builderBranch,\n });\n if (!validation.ok) {\n throw new Error(\n `Issue Final Review state artifact is invalid: ${validation.reason}`\n );\n }\n return {\n verdict: \"pass\" as const,\n artifactPath,\n selfRetouched: ifrFromState.selfRetouched ?? false,\n changedPaths: ifrFromState.changedPaths ?? [],\n verificationPassed: ifrFromState.verificationPassed ?? false,\n };\n }\n\n const result = await runIssueFinalReviewAgent({\n executionProvider,\n config,\n target,\n issue,\n parentPrdIssue,\n builderBranch,\n worktreePath,\n repoRoot,\n logger,\n reviewArtifactPath,\n });\n\n await assertCanonicalBaseAncestor({\n worktreePath,\n baseRef: `origin/${target.baseBranch}`,\n stageName: \"Issue Final Review\",\n logger,\n });\n\n if (result.verdict === \"pass\") {\n updateWorktreeRunState(worktreePath, {\n issueFinalReview: {\n completed: true,\n verdict: \"pass\",\n artifactPath: result.artifactPath,\n selfRetouched: result.selfRetouched,\n changedPaths: result.changedPaths,\n verificationPassed: result.verificationPassed,\n },\n });\n }\n\n return result;\n}\n\nexport interface FailIssueRunOptions {\n issueProvider: IssueProvider;\n issueNumber: number;\n config: PourkitConfig;\n logger: PourkitLogger;\n error: Error | string;\n}\n\nexport async function startIssueRun(\n options: StartIssueRunOptions\n): Promise<IssueRunStartResult> {\n const {\n issueNumber,\n targetName,\n config,\n issueProvider,\n prProvider,\n executionProvider,\n force,\n logger,\n } = options;\n const ROOT = options.repoRoot;\n\n const issue = await issueProvider.fetchIssue(issueNumber);\n const parentPrdIssue = await fetchParentPrdIssue(issue, issueProvider);\n\n const gateResult = checkIssueGates(issue, config, force);\n if (!gateResult.allowed) {\n throw new Error(`Issue gates failed: ${gateResult.reason}`);\n }\n\n const target = resolveTarget(config, targetName);\n const effectiveBaseBranch = options.baseBranchOverride || target.baseBranch;\n const effectiveTarget = { ...target, baseBranch: effectiveBaseBranch };\n const branchName = renderBranchName(target.branchTemplate, issue);\n const strategy = target.strategy;\n const serenaRuntimeConfig = resolveSerenaRuntimeConfig(config, target);\n const shouldPrepareSerena =\n serenaRuntimeConfig.enabled || serenaRuntimeConfig.required;\n let serenaExecutionContext: SerenaExecutionContext | undefined;\n\n if (shouldPrepareSerena) {\n const serenaPreflight = await prepareSerenaForTarget({\n repoRoot: ROOT,\n targetName: target.name,\n baseBranch: target.baseBranch,\n dataDir: serenaRuntimeConfig.dataDir,\n mcpUrl: serenaRuntimeConfig.mcpUrl,\n enabled: shouldPrepareSerena,\n required: serenaRuntimeConfig.required,\n autoStart: serenaRuntimeConfig.autoStart,\n logger,\n });\n\n if (serenaPreflight.enabled && serenaPreflight.available) {\n serenaExecutionContext = {\n available: true,\n sandboxMcpUrl: serenaRuntimeConfig.sandboxMcpUrl,\n };\n }\n\n if (serenaPreflight.enabled && !serenaPreflight.available) {\n const message = `Serena preflight unavailable for target ${target.name}: ${serenaPreflight.error}`;\n if (serenaRuntimeConfig.required) {\n throw new Error(message);\n }\n logger.step(\"warn\", message);\n }\n }\n\n if (options.resetWorktree) {\n const existingPr = await prProvider.getPr(branchName);\n if (existingPr && existingPr.state === \"OPEN\") {\n throw new Error(\n `Cannot reset worktree: open PR #${existingPr.number} exists for branch ${branchName}. Close the PR first or omit --reset-worktree.`\n );\n }\n await resetLocalBranchState(ROOT, branchName, logger);\n await syncTargetBranch(ROOT, effectiveBaseBranch, logger);\n }\n\n const prompt = loadBuilderPrompt(\n ROOT,\n strategy.implement.builder.promptTemplate\n );\n\n const resolution = await resolveIssueWorktree(\n ROOT,\n branchName,\n effectiveBaseBranch,\n logger\n );\n\n const worktreeState = resolution.worktreePath\n ? readWorktreeRunState(resolution.worktreePath)\n : null;\n\n if (resolution.mode !== \"new\") {\n const existingPr = await prProvider.getPr(branchName);\n\n const exit = await runBaseRefreshAttempt({\n worktreePath: resolution.worktreePath!,\n baseBranch: effectiveBaseBranch,\n localGitBaseRef: resolution.baseRef,\n logger,\n prNumber: existingPr?.number,\n prState: existingPr?.state,\n });\n\n if (Exit.isSuccess(exit)) {\n const refreshResult = exit.value;\n if (refreshResult.status === \"refreshed\") {\n if (worktreeState?.completedStages.builder) {\n const invalidatedState = invalidateAfterBaseRefresh(worktreeState);\n writeWorktreeRunState(resolution.worktreePath!, invalidatedState);\n }\n }\n } else {\n const cause = exit.cause;\n if (cause._tag === \"Fail\") {\n const failure = cause.error;\n if (failure instanceof RebaseConflict) {\n if (strategy.failureResolution && resolution.worktreePath) {\n await handleRebaseConflict(failure, {\n worktreePath: resolution.worktreePath,\n branchName,\n target,\n config,\n issueNumber,\n issueProvider,\n executionProvider,\n repoRoot: ROOT,\n worktreeState,\n logger,\n });\n } else {\n if (resolution.worktreePath) {\n if (worktreeState) {\n updateWorktreeRunState(resolution.worktreePath, {\n lastFailure: {\n stage: \"baseRefresh\",\n message: `Base refresh conflict detected. Handing off to human: ${failure.message}`,\n },\n });\n } else {\n writeWorktreeRunState(resolution.worktreePath, {\n issueNumber,\n targetName: target.name,\n branchName,\n baseBranch: effectiveBaseBranch,\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n completedStages: {},\n review: { lifetimeIterations: 0 },\n lastFailure: {\n stage: \"baseRefresh\",\n message: `Base refresh conflict detected. Handing off to human: ${failure.message}`,\n },\n });\n }\n }\n await transitionIssueToFailureState(\n issueProvider,\n issueNumber,\n config,\n `Base refresh conflicted: ${failure.message}. Worktree preserved at ${resolution.worktreePath}.`,\n logger\n );\n throw new Error(`Base refresh conflicted: ${failure.message}`);\n }\n } else if (failure instanceof PublishedHistoryRisk) {\n await handlePublishedHistoryRisk(failure, {\n worktreePath: resolution.worktreePath!,\n branchName,\n target,\n config,\n issueNumber,\n issueProvider,\n worktreeState,\n logger,\n });\n } else {\n throw new Error(`Base refresh failed: ${failure.message}`);\n }\n } else {\n const defectMessage =\n cause._tag === \"Die\"\n ? `Base refresh failed with unexpected error: ${cause.defect}`\n : `Base refresh failed with unhandled cause: ${cause._tag}`;\n throw new Error(defectMessage);\n }\n }\n }\n\n const runContextArtifact = buildRunContextArtifact({\n issue,\n parentPrdIssue,\n target: effectiveTarget,\n branchName,\n repoRoot: ROOT,\n reviewerCriteria: strategy.review.reviewer.criteria,\n sections: STAGE_SECTIONS.builder,\n });\n\n await issueProvider.addLabels(issueNumber, [config.labels.agentInProgress]);\n await issueProvider.removeLabel(issueNumber, config.labels.readyForAgent);\n\n let executionResult: ExecutionResult;\n\n const shouldRunBuilder =\n resolution.mode === \"new\"\n ? true\n : worktreeState === null || !worktreeState.completedStages.builder;\n\n if (shouldRunBuilder) {\n executionResult = await executionProvider.execute({\n stage: \"builder\",\n agent: strategy.implement.builder.agent,\n model: strategy.implement.builder.model,\n variant: strategy.implement.builder.variant,\n env: strategy.implement.builder.env,\n prompt,\n target: effectiveTarget,\n repoRoot: ROOT,\n branchName,\n ...(resolution.mode === \"new\" ? { baseRef: resolution.baseRef } : {}),\n sandbox: config.sandbox,\n ...(serenaExecutionContext ? { serena: serenaExecutionContext } : {}),\n autoApprove: true,\n timeoutMs: EXECUTION_TIMEOUT_MS,\n ...(resolution.worktreePath\n ? { worktreePath: resolution.worktreePath }\n : {}),\n artifacts: [runContextArtifact],\n logger,\n });\n\n if (!executionResult.success) {\n throw new Error(`Sandcastle failed: ${executionResult.error}`);\n }\n } else {\n executionResult = {\n success: true,\n branch: branchName,\n worktreePath: resolution.worktreePath!,\n commits: [],\n logPath: null,\n };\n }\n\n if (executionResult.worktreePath) {\n if (shouldRunBuilder) {\n await assertCanonicalBaseAncestor({\n worktreePath: executionResult.worktreePath,\n baseRef: `origin/${effectiveBaseBranch}`,\n stageName: \"Builder\",\n logger,\n });\n }\n\n if (worktreeState) {\n updateWorktreeRunState(executionResult.worktreePath, {\n completedStages: { builder: true },\n });\n } else {\n writeWorktreeRunState(executionResult.worktreePath, {\n issueNumber,\n targetName: target.name,\n branchName,\n baseBranch: effectiveBaseBranch,\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n completedStages: { builder: true },\n review: { lifetimeIterations: 0 },\n });\n }\n }\n\n const finalWorktreeState = executionResult.worktreePath\n ? readWorktreeRunState(executionResult.worktreePath)\n : worktreeState;\n\n return {\n issue,\n parentPrdIssue,\n target,\n effectiveTarget,\n branchName,\n worktreeState: finalWorktreeState,\n executionResult,\n ...(serenaExecutionContext ? { serena: serenaExecutionContext } : {}),\n };\n}\n\nasync function fetchParentPrdIssue(\n issue: IssueData,\n issueProvider: IssueProvider\n): Promise<IssueData | undefined> {\n const parentSection = issue.body.match(\n /^## Parent\\s*\\n([\\s\\S]*?)(?=\\n## |$)/im\n )?.[1];\n const parentNumber = parentSection?.match(/#(\\d+)\\b/)?.[1];\n if (!parentNumber) return undefined;\n\n try {\n return await issueProvider.fetchIssue(Number(parentNumber));\n } catch {\n return undefined;\n }\n}\n\nexport async function advanceIssueRunReview(\n options: RunReviewLoopOptions\n): Promise<ReviewLoopResult> {\n const accumulatedRefactorPaths: string[] = [];\n\n const reviewResult = await runEffectAndMapExit(\n runReviewWithRefactorLoop({\n ...options,\n onRefactorProgress: (progress) => {\n if (progress.refactorArtifactPath) {\n accumulatedRefactorPaths.push(progress.refactorArtifactPath);\n }\n updateWorktreeRunState(options.worktreePath, {\n review: {\n lifetimeIterations: progress.lifetimeIterations,\n lastVerdict: progress.lastVerdict,\n lastArtifactPath: progress.lastArtifactPath,\n refactorCompletedForLastReview: true,\n },\n });\n },\n })\n );\n\n await assertCanonicalBaseAncestor({\n worktreePath: options.worktreePath,\n baseRef: `origin/${options.target.baseBranch}`,\n stageName: \"Review/Refactor\",\n logger: options.logger,\n });\n\n updateWorktreeRunState(options.worktreePath, {\n review: {\n lifetimeIterations: reviewResult.lifetimeIterations,\n lastVerdict: reviewResult.verdict,\n lastArtifactPath: reviewResult.artifactPath,\n refactorCompletedForLastReview:\n reviewResult.refactorCompletedForLastReview,\n exhaustedPreviousRun:\n reviewResult.exhaustedMaxIterations ||\n reviewResult.verdict === \"FAIL\" ||\n undefined,\n refactorArtifactPaths:\n accumulatedRefactorPaths.length > 0\n ? accumulatedRefactorPaths\n : undefined,\n },\n });\n\n return reviewResult;\n}\n\nexport async function completeIssueRun(\n options: CompleteIssueRunOptions\n): Promise<RunIssueResult> {\n const {\n issueNumber,\n config,\n issueProvider,\n prProvider,\n executionProvider,\n logger,\n startResult,\n reviewArtifactPath,\n } = options;\n const ROOT = options.repoRoot;\n const { issue, target, branchName, worktreeState, executionResult } =\n startResult;\n const effectiveBaseBranch = options.baseBranchOverride || target.baseBranch;\n const checkWaitOptions = {\n checksFoundTimeoutMs: config.checks.checksFoundTimeoutSeconds * 1000,\n checksCompletionTimeoutMs:\n config.checks.checksCompletionTimeoutSeconds * 1000,\n pollIntervalMs: config.checks.pollIntervalSeconds * 1000,\n };\n\n const ifrState = executionResult.worktreePath\n ? (readWorktreeRunState(executionResult.worktreePath) ?? worktreeState)\n : worktreeState;\n assertIssueFinalReviewPassed(ifrState);\n\n let mergeCompleted = false;\n\n try {\n if (\n executionResult.worktreePath &&\n !worktreeState?.finalCommit?.completed &&\n !worktreeState?.pr?.created &&\n !(await hasWorktreeChanges(\n executionResult.worktreePath,\n `origin/${effectiveBaseBranch}`,\n logger\n ))\n ) {\n logger.step(\n \"info\",\n \"No worktree changes detected after review - closing issue\"\n );\n await closeNoOpIssue(issueProvider, issueNumber, config, logger);\n return {\n branchName,\n target,\n issue,\n noOp: true,\n };\n }\n\n let prTitle = issue.title;\n let prBody: string | undefined;\n let finalizerResult: RunFinalizerResult | undefined;\n\n const isLocalModeForFinalizer = options.prdRunMode?.mode === \"local\";\n\n const finalizerFromState = worktreeState?.finalizer?.completed\n ? worktreeState.finalizer\n : null;\n if (finalizerFromState) {\n try {\n if (finalizerFromState.title && finalizerFromState.body) {\n prTitle = finalizerFromState.title;\n prBody = finalizerFromState.body;\n } else if (finalizerFromState.artifactPath) {\n if (!existsSync(finalizerFromState.artifactPath)) {\n throw new FinalizerFailure({\n message: `Finalizer artifact missing at ${finalizerFromState.artifactPath}`,\n });\n }\n const artifactContent = readFileSync(\n finalizerFromState.artifactPath,\n \"utf-8\"\n );\n const parsed = parsePrDescription(artifactContent);\n prTitle = parsed.title;\n prBody = parsed.body;\n } else {\n throw new FinalizerFailure({\n message:\n \"Finalizer state is incomplete: missing title, body, and artifactPath\",\n });\n }\n } catch (error) {\n if (isLocalModeForFinalizer) {\n return {\n branchName,\n target,\n issue,\n noOp: false,\n mode: \"local\",\n failureCode: \"finalizer_failed\",\n repairGuidance:\n error instanceof Error\n ? error.message\n : \"Finalizer state is invalid\",\n };\n }\n throw error;\n }\n } else {\n try {\n finalizerResult = await runEffectAndMapExit(\n runFinalizerAgent({\n executionProvider,\n config,\n target,\n issue,\n builderBranch: branchName,\n targetBaseBranch: effectiveBaseBranch,\n worktreePath: executionResult.worktreePath,\n reviewArtifactPath,\n repoRoot: ROOT,\n logger,\n })\n );\n } catch (error) {\n if (isLocalModeForFinalizer) {\n return {\n branchName,\n target,\n issue,\n noOp: false,\n mode: \"local\",\n failureCode: \"finalizer_failed\",\n repairGuidance:\n error instanceof Error\n ? error.message\n : \"Finalizer execution failed\",\n };\n }\n throw error;\n }\n prTitle = finalizerResult.title;\n prBody = finalizerResult.body;\n\n if (executionResult.worktreePath) {\n await assertCanonicalBaseAncestor({\n worktreePath: executionResult.worktreePath,\n baseRef: `origin/${effectiveBaseBranch}`,\n stageName: \"Finalizer\",\n logger,\n });\n }\n }\n\n prTitle = ensureConventionalPrTitle(\n prTitle,\n executionResult.commits.join(\"\\n\")\n );\n\n const finalBody = ensureClosingRefs(\n prBody ?? `Closes #${issue.number}`,\n issue.number\n );\n\n if (!finalizerFromState && executionResult.worktreePath) {\n updateWorktreeRunState(executionResult.worktreePath, {\n finalizer: {\n completed: true,\n artifactPath: finalizerResult!.artifactPath,\n title: prTitle,\n body: prBody,\n },\n });\n }\n\n const finalCommitFromState = worktreeState?.finalCommit?.completed;\n if (!finalCommitFromState) {\n await finalizeWorktreeCommit({\n worktreePath: executionResult.worktreePath,\n baseRef: `origin/${effectiveBaseBranch}`,\n title: prTitle,\n body: finalBody,\n logger,\n });\n\n if (executionResult.worktreePath) {\n const revParse = await execCapture(\"git\", [\"rev-parse\", \"HEAD\"], {\n cwd: executionResult.worktreePath,\n logger,\n label: \"git rev-parse HEAD\",\n });\n updateWorktreeRunState(executionResult.worktreePath, {\n finalCommit: {\n completed: true,\n sha: revParse.stdout.trim(),\n },\n });\n }\n }\n\n const isLocalMode = options.prdRunMode?.mode === \"local\";\n\n if (isLocalMode) {\n const parsed = parseStackedIssue(issue.title, issue.body);\n const prdId = parsed.parentRef;\n if (!prdId) {\n return {\n branchName,\n target,\n issue,\n noOp: false,\n mode: \"local\",\n failureCode: \"finalizer_failed\",\n repairGuidance:\n \"Local mode requires a PRD reference (## Parent) in the issue body or title. Add the parent PRD reference and retry.\",\n };\n }\n\n const finalizerFromWorktreeState = worktreeState?.finalizer;\n if (finalizerFromWorktreeState && !finalizerFromWorktreeState.completed) {\n return {\n branchName,\n target,\n issue,\n noOp: false,\n mode: \"local\",\n failureCode: \"finalizer_failed\",\n repairGuidance:\n \"Finalizer did not complete on previous run. Re-run the issue finalizer and try again.\",\n };\n }\n\n if (!prTitle || !finalBody) {\n return {\n branchName,\n target,\n issue,\n noOp: false,\n mode: \"local\",\n failureCode: \"finalizer_failed\",\n repairGuidance:\n \"Finalizer produced empty title or body. Re-run the issue finalizer and try again.\",\n };\n }\n\n const existingReceipt = await hasLocalIssueMergeReceipt(\n prdId,\n `issue-${issueNumber}`,\n ROOT\n );\n if (existingReceipt) {\n return {\n branchName,\n target,\n issue,\n noOp: false,\n mode: \"local\",\n failureCode: \"already_merged\",\n localPrdBranch: existingReceipt.localPrdBranch,\n mergeCommit: existingReceipt.mergeCommit,\n receiptPath: join(\n ROOT,\n \".pourkit\",\n \"local-prd-runs\",\n prdId,\n \"merge-receipts\",\n `issue-${issueNumber}.json`\n ),\n };\n }\n\n const mergeResult = await squashMergeLocalIssue(\n prdId,\n `issue-${issueNumber}`,\n {\n finalizerTitle: prTitle,\n finalizerBody: finalBody,\n finalizerArtifactPath: worktreeState?.finalizer?.artifactPath ?? \"\",\n sourceBranch: branchName,\n },\n ROOT\n );\n\n if (!mergeResult.ok) {\n return {\n branchName,\n target,\n issue,\n noOp: false,\n mode: \"local\",\n failureCode: mergeResult.failureCode,\n repairGuidance:\n mergeResult.repairGuidance ??\n `Local squash-merge failed: ${mergeResult.failureCode}`,\n };\n }\n\n await issueProvider.removeLabel(\n issueNumber,\n config.labels.agentInProgress\n );\n await issueProvider.removeLabel(\n issueNumber,\n config.labels.prOpenAwaitingMerge\n );\n\n let childCloseSucceeded = false;\n try {\n await issueProvider.closeIssue(issueNumber);\n childCloseSucceeded = true;\n } catch (error) {\n logger.step(\n \"warn\",\n `Issue #${issueNumber} could not be closed: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n\n if (childCloseSucceeded) {\n await maybeCloseParentAfterChildCompletion(\n issueProvider,\n issueNumber,\n logger\n );\n }\n\n return {\n branchName,\n target,\n issue,\n noOp: false,\n mode: \"local\",\n localPrdBranch: getLocalPrdBranchName(prdId),\n mergeCommit: mergeResult.receipt!.mergeCommit,\n receiptPath: join(\n ROOT,\n \".pourkit\",\n \"local-prd-runs\",\n prdId,\n \"merge-receipts\",\n `issue-${issueNumber}.json`\n ),\n };\n }\n\n let pr: Awaited<ReturnType<PRProvider[\"createPr\"]>>;\n\n if (worktreeState?.pr?.merged) {\n mergeCompleted = true;\n pr = {\n number: worktreeState.pr.number!,\n nodeId: \"\",\n url: worktreeState.pr.url!,\n title: prTitle,\n body: finalBody,\n headRefName: branchName,\n baseRefName: effectiveBaseBranch,\n state: \"MERGED\",\n headRefOid: worktreeState.finalCommit?.sha ?? \"\",\n };\n } else {\n const prFromState =\n worktreeState?.pr?.created || finalCommitFromState\n ? await prProvider.getPr(branchName)\n : null;\n\n if (prFromState && prFromState.state === \"OPEN\") {\n pr = prFromState;\n } else {\n await execCapture(\"git\", [\"push\", \"-u\", \"origin\", branchName], {\n cwd: executionResult.worktreePath,\n logger,\n label: \"git push\",\n });\n\n pr = await prProvider.createPr({\n title: prTitle,\n body: finalBody,\n head: branchName,\n base: effectiveBaseBranch,\n });\n\n if (executionResult.worktreePath) {\n updateWorktreeRunState(executionResult.worktreePath, {\n pr: {\n created: true,\n number: pr.number,\n url: pr.url,\n },\n });\n }\n }\n\n if (target.autoMerge === false) {\n await prProvider.waitForPrChecks(pr.number, checkWaitOptions);\n const transitions = makeIssueTransitions(issueProvider, config);\n await transitions.moveToReadyForHuman(issueNumber);\n return {\n branchName,\n target,\n issue,\n prNumber: pr.number,\n prUrl: pr.url,\n prTitle,\n prBody: finalBody,\n noOp: false,\n };\n }\n\n await issueProvider.addLabels(issueNumber, [\n config.labels.prOpenAwaitingMerge,\n ]);\n const coordinatorResult = await runEffectAndMapExit(\n runMergeCoordinator({\n prProvider,\n logger,\n prNumber: pr.number,\n targetBranch: effectiveBaseBranch,\n matchHeadCommit: pr.headRefOid,\n checkWaitOptions,\n autoMerge: true,\n pr,\n })\n );\n\n if (coordinatorResult.stage === \"merge\") {\n throw coordinatorResult.error;\n }\n\n if (coordinatorResult.stage === \"target-green\") {\n try {\n await issueProvider.removeLabel(\n issueNumber,\n config.labels.prOpenAwaitingMerge\n );\n } catch (labelError) {\n logger.step(\n \"warn\",\n `Failed to remove ${config.labels.prOpenAwaitingMerge} label (cleanup): ${labelError instanceof Error ? labelError.message : String(labelError)}`\n );\n }\n throw coordinatorResult.error;\n }\n\n mergeCompleted = true;\n\n if (executionResult.worktreePath) {\n updateWorktreeRunState(executionResult.worktreePath, {\n pr: { merged: true, created: true },\n });\n }\n }\n\n if (worktreeState?.pr?.merged) {\n await waitForBranchChecks(prProvider, logger, {\n branchName: effectiveBaseBranch,\n checksFoundTimeoutMs: checkWaitOptions.checksFoundTimeoutMs,\n checksCompletionTimeoutMs: checkWaitOptions.checksCompletionTimeoutMs,\n pollIntervalMs: checkWaitOptions.pollIntervalMs,\n });\n }\n\n await issueProvider.removeLabel(issueNumber, config.labels.agentInProgress);\n await issueProvider.removeLabel(\n issueNumber,\n config.labels.prOpenAwaitingMerge\n );\n\n let childCloseSucceeded = false;\n try {\n await issueProvider.closeIssue(issueNumber);\n childCloseSucceeded = true;\n } catch (error) {\n logger.step(\n \"warn\",\n `Issue #${issueNumber} could not be closed: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n\n if (childCloseSucceeded) {\n await maybeCloseParentAfterChildCompletion(\n issueProvider,\n issueNumber,\n logger\n );\n }\n\n return {\n branchName,\n target,\n issue,\n prNumber: pr.number,\n prUrl: pr.url,\n prTitle,\n prBody: finalBody,\n noOp: false,\n };\n } catch (error) {\n if (mergeCompleted) {\n try {\n await issueProvider.removeLabel(\n issueNumber,\n config.labels.prOpenAwaitingMerge\n );\n } catch {\n // Ignore cleanup errors when removing label after merge\n }\n }\n throw error;\n }\n}\n\nexport async function failIssueRun(\n options: FailIssueRunOptions\n): Promise<void> {\n const { issueProvider, issueNumber, config, logger, error } = options;\n await transitionIssueToFailureState(\n issueProvider,\n issueNumber,\n config,\n typeof error === \"string\" ? error : error.message,\n logger\n );\n}\n\nexport interface HumanHandoffOptions {\n issueProvider: IssueProvider;\n issueNumber: number;\n config: PourkitConfig;\n logger: PourkitLogger;\n reviewResult: ReviewLoopResult;\n}\n\nexport async function transitionIssueToHumanHandoff(\n options: HumanHandoffOptions\n): Promise<void> {\n const { issueProvider, issueNumber, config, logger, reviewResult } = options;\n\n const transitions = makeIssueTransitions(issueProvider, config);\n await transitions.moveToReadyForHuman(issueNumber);\n\n const summary = extractHumanHandoffSummary(reviewResult.output);\n const refactorDir = getRefactorArtifactDir(reviewResult.artifactPath);\n\n const comment = [\n \"Pourkit stopped the review/refactor loop because human input is needed.\",\n \"\",\n summary,\n \"\",\n \"Artifacts:\",\n `- Review: ${reviewResult.artifactPath}`,\n `- Refactors: ${refactorDir}`,\n ].join(\"\\n\");\n\n await issueProvider.commentIssue(issueNumber, comment);\n\n logger.step(\"info\", `Issue ${issueNumber} transitioned to human handoff`);\n}\n\nfunction extractHumanHandoffSummary(artifactContent: string): string {\n const lines = artifactContent.split(\"\\n\");\n let inSummary = false;\n const summaryLines: string[] = [];\n for (const line of lines) {\n if (line.startsWith(\"## Human Handoff Summary\")) {\n inSummary = true;\n continue;\n }\n if (inSummary) {\n if (line.startsWith(\"## \")) {\n break;\n }\n summaryLines.push(line);\n }\n }\n return (\n summaryLines.join(\"\\n\").trim() || \"(No Human Handoff Summary provided)\"\n );\n}\n\nfunction getRefactorArtifactDir(artifactPath: string): string {\n return artifactPath\n .replace(/\\/reviewers\\//, \"/refactors/\")\n .replace(/\\/[^/]+$/, \"\");\n}\n\nasync function finalizeWorktreeCommit(options: {\n worktreePath: string;\n baseRef: string;\n title: string;\n body: string;\n logger: PourkitLogger;\n}) {\n const { worktreePath, baseRef, title, body, logger } = options;\n\n await assertCanonicalBaseAncestor({\n worktreePath,\n baseRef,\n stageName: \"final commit\",\n logger,\n });\n\n await execCapture(\"git\", [\"reset\", \"--soft\", baseRef], {\n cwd: worktreePath,\n logger,\n label: \"git reset\",\n });\n\n await execCapture(\"git\", [\"add\", \"-A\"], {\n cwd: worktreePath,\n logger,\n label: \"git add\",\n });\n\n await execCapture(\"git\", [\"commit\", \"--no-verify\", \"-m\", title, \"-m\", body], {\n cwd: worktreePath,\n logger,\n label: \"git commit\",\n });\n}\n\nasync function assertCanonicalBaseAncestor(options: {\n worktreePath: string;\n baseRef: string;\n stageName: string;\n logger: PourkitLogger;\n}) {\n const { worktreePath, baseRef, stageName, logger } = options;\n\n await syncRemoteBaseRef(worktreePath, baseRef, logger);\n\n try {\n await execCapture(\"git\", [\"merge-base\", \"--is-ancestor\", baseRef, \"HEAD\"], {\n cwd: worktreePath,\n logger,\n label: \"git merge-base --is-ancestor\",\n });\n } catch {\n throw new Error(\n `Cannot continue after ${stageName}: ${baseRef} is not an ancestor of HEAD. An agent may have moved the issue branch behind the canonical base; refresh the branch onto the latest target base before continuing.`\n );\n }\n}\n\nasync function guardFinalCommitContent(options: {\n worktreePath: string;\n title: string;\n body: string;\n enabled: boolean;\n logger: PourkitLogger;\n}) {\n const { worktreePath, title, body, enabled, logger } = options;\n if (!enabled) {\n return;\n }\n\n const stagedDiff = await execCapture(\"git\", [\"diff\", \"--cached\"], {\n cwd: worktreePath,\n logger,\n label: \"git diff --cached secret guard\",\n });\n\n assertNoSecretLikeContent([\n {\n source: \"staged diff\",\n content: extractAddedDiffContent(stagedDiff.stdout),\n },\n { source: \"commit title\", content: title },\n { source: \"commit body\", content: body },\n ]);\n}\n\nasync function guardFinalPublishContent(options: {\n worktreePath: string;\n baseRef: string;\n title: string;\n body: string;\n secretLikeContentDetectionEnabled: boolean;\n logger: PourkitLogger;\n}) {\n const {\n worktreePath,\n baseRef,\n title,\n body,\n secretLikeContentDetectionEnabled,\n logger,\n } = options;\n if (!secretLikeContentDetectionEnabled) {\n return;\n }\n\n const finalDiff = await execCapture(\"git\", [\"diff\", `${baseRef}...HEAD`], {\n cwd: worktreePath,\n logger,\n label: \"git diff final secret guard\",\n });\n\n assertNoSecretLikeContent([\n {\n source: \"final diff\",\n content: extractAddedDiffContent(finalDiff.stdout),\n },\n { source: \"PR title\", content: title },\n { source: \"PR body\", content: body },\n ]);\n}\n\nfunction extractAddedDiffContent(diff: string) {\n return diff\n .split(/\\r?\\n/)\n .filter((line) => line.startsWith(\"+\") && !line.startsWith(\"+++\"))\n .map((line) => line.slice(1))\n .join(\"\\n\");\n}\n\nfunction assertNoSecretLikeContent(\n inputs: Array<{ source: string; content: string | undefined }>\n) {\n const findings = inputs.flatMap(({ source, content }) =>\n findSecretLikeContent(source, content ?? \"\")\n );\n\n if (findings.length === 0) {\n return;\n }\n\n const summary = findings\n .slice(0, 5)\n .map((finding) => `${finding.source}: ${finding.kind}`)\n .join(\"; \");\n throw new Error(\n `Secret-like content detected before finalization (${summary}). Redact it before committing, pushing, or creating a PR.`\n );\n}\n\nfunction findSecretLikeContent(source: string, content: string) {\n const findings: Array<{ source: string; kind: string }> = [];\n const patterns: Array<{ kind: string; regex: RegExp }> = [\n {\n kind: \"private key block\",\n regex: /-----BEGIN [A-Z0-9 ]*PRIVATE KEY-----/gi,\n },\n {\n kind: \"GitHub token\",\n regex: /\\b(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9_]{20,}\\b/g,\n },\n {\n kind: \"GitHub fine-grained token\",\n regex: /\\bgithub_pat_[A-Za-z0-9_]{20,}\\b/g,\n },\n { kind: \"npm token\", regex: /\\bnpm_[A-Za-z0-9]{20,}\\b/g },\n { kind: \"OpenAI key\", regex: /\\bsk-(?:proj-)?[A-Za-z0-9_-]{20,}\\b/g },\n { kind: \"AWS access key\", regex: /\\b(?:AKIA|ASIA)[A-Z0-9]{16}\\b/g },\n {\n kind: \"authorization bearer token\",\n regex: /\\bAuthorization\\s*:\\s*Bearer\\s+[^\\s`'\\\"]{12,}/gi,\n },\n {\n kind: \"secret assignment\",\n regex:\n /\\b[A-Z0-9_]*(?:API[_-]?KEY|TOKEN|SECRET|PASSWORD|PASSWD|PRIVATE[_-]?KEY|CLIENT[_-]?SECRET|DATABASE[_-]?URL)[A-Z0-9_]*\\s*[:=]\\s*[\"']?[^\\s\"'`]{8,}/gi,\n },\n ];\n\n for (const { kind, regex } of patterns) {\n for (const match of content.matchAll(regex)) {\n if (isAllowedSecretPlaceholder(match[0])) {\n continue;\n }\n findings.push({ source, kind });\n break;\n }\n }\n\n return findings;\n}\n\nfunction isAllowedSecretPlaceholder(value: string) {\n const normalized = value.toLowerCase();\n return [\n \"<redacted>\",\n \"<example\",\n \"example-\",\n \"dummy-\",\n \"test-\",\n \"placeholder\",\n \"xxxxx\",\n ].some((allowed) => normalized.includes(allowed));\n}\n\nasync function syncRemoteBaseRef(\n worktreePath: string,\n baseRef: string,\n logger: PourkitLogger\n) {\n const remoteBase = parseRemoteBaseRef(baseRef);\n if (!remoteBase) {\n return;\n }\n\n await execCapture(\"git\", [\"fetch\", remoteBase.remote, remoteBase.branch], {\n cwd: worktreePath,\n logger,\n label: \"git fetch target\",\n });\n}\n\nfunction parseRemoteBaseRef(baseRef: string): {\n remote: string;\n branch: string;\n} | null {\n const [remote, ...branchParts] = baseRef.split(\"/\");\n const branch = branchParts.join(\"/\");\n if (!remote || !branch) {\n return null;\n }\n return { remote, branch };\n}\n\nfunction makeIssueTransitions(\n provider: IssueProvider,\n config: PourkitConfig\n): IssueTransitionsContract {\n return createIssueTransitions(\n {\n fetchIssue: provider.fetchIssue.bind(provider),\n addLabels: provider.addLabels.bind(provider),\n removeLabel: provider.removeLabel.bind(provider),\n closeIssue: provider.closeIssue.bind(provider),\n },\n {\n blocked: config.labels.blocked,\n readyForAgent: config.labels.readyForAgent,\n needsTriage: config.labels.needsTriage,\n agentInProgress: config.labels.agentInProgress,\n readyForHuman: config.labels.readyForHuman,\n prOpenAwaitingMerge: config.labels.prOpenAwaitingMerge,\n }\n );\n}\n\nasync function transitionIssueToFailureState(\n provider: IssueProvider,\n issueNumber: number,\n config: PourkitConfig,\n errorMessage: string,\n logger: PourkitLogger\n) {\n const transitions = makeIssueTransitions(provider, config);\n await transitions.moveToReadyForHuman(issueNumber);\n\n logger.step(\n \"error\",\n `Issue ${issueNumber} transitioned to ${config.labels.readyForHuman}: ${errorMessage}`\n );\n}\n\nasync function hasWorktreeChanges(\n worktreePath: string,\n baseRef: string,\n logger: PourkitLogger\n): Promise<boolean> {\n const diffResult = await execCapture(\n \"git\",\n [\"diff\", \"--name-only\", baseRef, \"--\"],\n {\n cwd: worktreePath,\n logger,\n label: \"git diff --name-only\",\n }\n );\n if (diffResult.stdout.trim().length > 0) {\n return true;\n }\n\n const statusResult = await execCapture(\n \"git\",\n [\"status\", \"--porcelain\", \"--untracked-files=all\"],\n {\n cwd: worktreePath,\n logger,\n label: \"git status --porcelain\",\n }\n );\n return statusResult.stdout.trim().length > 0;\n}\n\nasync function closeNoOpIssue(\n provider: IssueProvider,\n issueNumber: number,\n config: PourkitConfig,\n logger: PourkitLogger\n): Promise<void> {\n const transitions = makeIssueTransitions(provider, config);\n\n let closeSucceeded = false;\n try {\n await transitions.closeCompleted(issueNumber);\n closeSucceeded = true;\n logger.step(\"info\", `Issue #${issueNumber} closed (no changes required)`);\n } catch (error) {\n logger.step(\n \"warn\",\n `Issue #${issueNumber} could not be closed: ${error instanceof Error ? error.message : String(error)}`\n );\n logger.step(\n \"info\",\n `Issue #${issueNumber} completed with no changes required`\n );\n }\n\n if (closeSucceeded) {\n await maybeCloseParentAfterChildCompletion(provider, issueNumber, logger);\n }\n}\n\nasync function maybeCloseParentAfterChildCompletion(\n provider: IssueProvider,\n issueNumber: number,\n logger: PourkitLogger\n): Promise<void> {\n try {\n const issue = await provider.fetchIssue(issueNumber);\n const parsed = parseStackedIssue(issue.title, issue.body);\n if (!parsed.parentRef) return;\n if (parsed.warnings.length > 0) return;\n\n const parent = await provider.resolveIssueByCanonicalRef(parsed.parentRef);\n if (!parent) return;\n if (parent.state !== \"open\") return;\n\n const siblings = await provider.listRelatedIssues(parsed.parentRef);\n const openSiblings = siblings.filter(\n (s) => s.number !== issueNumber && s.state === \"open\"\n );\n if (openSiblings.length > 0) return;\n\n await provider.closeIssue(parent.number);\n logger.step(\n \"info\",\n `Parent PRD #${parent.number} closed (last child completed)`\n );\n } catch (error) {\n logger.step(\n \"warn\",\n `Parent completion check failed: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n}\n\nasync function resetLocalBranchState(\n root: string,\n branchName: string,\n logger: PourkitLogger\n): Promise<void> {\n const worktreeList = await execCapture(\n \"git\",\n [\"worktree\", \"list\", \"--porcelain\"],\n { cwd: root, logger, label: \"git worktree list\" }\n );\n\n const existingWorktreePath = resolveRegisteredIssueWorktreePath(\n worktreeList.stdout,\n root,\n branchName\n );\n\n if (existingWorktreePath) {\n logger.step(\"git\", `removing existing worktree: ${existingWorktreePath}`);\n await execCapture(\n \"git\",\n [\"worktree\", \"remove\", \"--force\", existingWorktreePath],\n {\n cwd: root,\n logger,\n label: \"git worktree remove\",\n }\n );\n }\n\n let branchExists = false;\n try {\n await execCapture(\n \"git\",\n [\"show-ref\", \"--verify\", \"--quiet\", `refs/heads/${branchName}`],\n { cwd: root, logger, label: \"git branch exists\" }\n );\n branchExists = true;\n } catch {\n // No local branch to delete.\n }\n\n if (branchExists) {\n logger.step(\"git\", `deleting local branch: ${branchName}`);\n await execCapture(\"git\", [\"branch\", \"-D\", branchName], {\n cwd: root,\n logger,\n label: \"git branch -D\",\n });\n }\n}\n\nasync function resolveIssueWorktree(\n root: string,\n branchName: string,\n baseBranch: string,\n logger: PourkitLogger\n): Promise<IssueWorktreeResolution> {\n const worktreeList = await execCapture(\n \"git\",\n [\"worktree\", \"list\", \"--porcelain\"],\n {\n cwd: root,\n logger,\n label: \"git worktree list\",\n }\n );\n\n const existingWorktreePath = resolveRegisteredIssueWorktreePath(\n worktreeList.stdout,\n root,\n branchName\n );\n\n if (existingWorktreePath) {\n const baseRef = await syncTargetBranch(root, baseBranch, logger);\n return {\n mode: \"existing-worktree\",\n branchName,\n baseRef,\n worktreePath: existingWorktreePath,\n };\n }\n\n let branchExists = false;\n try {\n await execCapture(\n \"git\",\n [\"show-ref\", \"--verify\", \"--quiet\", `refs/heads/${branchName}`],\n {\n cwd: root,\n logger,\n label: \"git branch exists\",\n }\n );\n branchExists = true;\n } catch {\n // No local branch to resume from.\n }\n\n if (branchExists) {\n const worktreePath = issueWorktreePath(root, branchName);\n await execCapture(\"git\", [\"worktree\", \"add\", worktreePath, branchName], {\n cwd: root,\n logger,\n label: \"git worktree add\",\n });\n const baseRef = await syncTargetBranch(root, baseBranch, logger);\n return {\n mode: \"existing-branch\",\n branchName,\n baseRef,\n worktreePath,\n };\n }\n\n const baseRef = await syncTargetBranch(root, baseBranch, logger);\n return { mode: \"new\", branchName, baseRef };\n}\n\nfunction issueWorktreePath(root: string, branchName: string): string {\n return join(root, \".sandcastle\", \"worktrees\", branchName.replace(/\\//g, \"-\"));\n}\n\nfunction resolveRegisteredIssueWorktreePath(\n worktreeListPorcelain: string,\n root: string,\n branchName: string\n): string | null {\n const branchWorktreePath = parseWorktreeListPorcelain(\n worktreeListPorcelain,\n branchName\n );\n if (branchWorktreePath) return branchWorktreePath;\n\n const expectedWorktreePath = issueWorktreePath(root, branchName);\n const entries = worktreeListPorcelain.trim().split(\"\\n\\n\");\n for (const entry of entries) {\n if (\n entry\n .trim()\n .split(\"\\n\")\n .some((line) => line === `worktree ${expectedWorktreePath}`)\n ) {\n return expectedWorktreePath;\n }\n }\n\n return null;\n}\n\nasync function syncTargetBranch(\n root: string,\n baseBranch: string,\n logger: PourkitLogger\n): Promise<string> {\n logger.step(\"git\", `syncing target branch: ${baseBranch}`);\n await execCapture(\"git\", [\"fetch\", \"origin\", baseBranch], {\n cwd: root,\n logger,\n label: \"git fetch target\",\n });\n return `origin/${baseBranch}`;\n}\n\nfunction loadBuilderPrompt(repoRoot: string, promptTemplate: string): string {\n const promptPath = resolvePromptTemplatePath(repoRoot, promptTemplate);\n const promptBody = existsSync(promptPath)\n ? readFileSync(promptPath, \"utf-8\")\n : promptTemplate;\n\n return appendProtectedWorkGuidance(`${promptBody}\n\n## Shared Run Context\n\nRead the selected issue requirements, PRD context, comments, branch context, verification commands, and artifact paths from: ${RUN_CONTEXT_PATH_IN_WORKTREE}`);\n}\n\nasync function handleRebaseConflict(\n failure: RebaseConflict,\n context: {\n worktreePath: string;\n branchName: string;\n target: ResolvedTarget;\n config: PourkitConfig;\n issueNumber: number;\n issueProvider: IssueProvider;\n executionProvider: ExecutionProvider;\n repoRoot: string;\n worktreeState: WorktreeRunState | null;\n logger: PourkitLogger;\n }\n): Promise<void> {\n const frConfig = context.target.strategy.failureResolution;\n if (!frConfig) {\n await transitionIssueToFailureState(\n context.issueProvider,\n context.issueNumber,\n context.config,\n \"No failureResolution configured\",\n context.logger\n );\n throw new Error(\"Base refresh conflicted: no failureResolution configured\");\n }\n\n const maxAttempts =\n frConfig.failureLimits?.RebaseConflict ?? frConfig.maxAttemptsPerFailure;\n let attemptNumber = 0;\n let currentFailure = failure;\n\n while (attemptNumber < maxAttempts) {\n attemptNumber++;\n\n const packet = constructFailureResolutionPacket(currentFailure, {\n stageName: \"baseRefresh\",\n attemptNumber,\n worktreePath: context.worktreePath,\n branchName: context.branchName,\n baseBranch: context.target.baseBranch,\n maxAttempts,\n allowedDecisions: [\"RETRY_STAGE\", \"HANDOFF_TO_HUMAN\", \"FAIL_RUN\"],\n artifactTarget: `.pourkit/.tmp/failure-resolution/attempt-${attemptNumber}.md`,\n });\n\n const result = await runFailureResolutionAgent({\n executionProvider: context.executionProvider,\n config: context.config,\n target: context.target,\n failure: currentFailure,\n packet,\n worktreePath: context.worktreePath,\n repoRoot: context.repoRoot,\n logger: context.logger,\n });\n\n if (result.status === \"handoff\") {\n if (context.worktreeState) {\n updateWorktreeRunState(context.worktreePath, {\n lastFailure: { stage: \"baseRefresh\", message: result.reason },\n });\n } else {\n writeWorktreeRunState(context.worktreePath, {\n issueNumber: context.issueNumber,\n targetName: context.target.name,\n branchName: context.branchName,\n baseBranch: context.target.baseBranch,\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n completedStages: {},\n review: { lifetimeIterations: 0 },\n lastFailure: { stage: \"baseRefresh\", message: result.reason },\n });\n }\n await transitionIssueToFailureState(\n context.issueProvider,\n context.issueNumber,\n context.config,\n result.reason,\n context.logger\n );\n throw new Error(result.reason);\n }\n\n if (result.status === \"fail-run\") {\n if (context.worktreeState) {\n updateWorktreeRunState(context.worktreePath, {\n lastFailure: { stage: \"baseRefresh\", message: result.reason },\n });\n } else {\n writeWorktreeRunState(context.worktreePath, {\n issueNumber: context.issueNumber,\n targetName: context.target.name,\n branchName: context.branchName,\n baseBranch: context.target.baseBranch,\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n completedStages: {},\n review: { lifetimeIterations: 0 },\n lastFailure: { stage: \"baseRefresh\", message: result.reason },\n });\n }\n throw new Error(result.reason);\n }\n\n // Host owns Git state transitions after FR agent: git add + git rebase --continue\n const changedPaths =\n packet.conflictedPaths ?? currentFailure.conflictedPaths;\n\n const markersRemain = await hasUnresolvedConflictMarkers(\n context.worktreePath,\n changedPaths\n );\n if (markersRemain) {\n const message =\n \"Conflict resolution agent resolved artifact but conflict markers remain in files\";\n if (context.worktreeState) {\n updateWorktreeRunState(context.worktreePath, {\n lastFailure: { stage: \"baseRefresh\", message },\n });\n } else {\n writeWorktreeRunState(context.worktreePath, {\n issueNumber: context.issueNumber,\n targetName: context.target.name,\n branchName: context.branchName,\n baseBranch: context.target.baseBranch,\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n completedStages: {},\n review: { lifetimeIterations: 0 },\n lastFailure: { stage: \"baseRefresh\", message },\n });\n }\n await transitionIssueToFailureState(\n context.issueProvider,\n context.issueNumber,\n context.config,\n message,\n context.logger\n );\n throw new Error(message);\n }\n\n await execCapture(\"git\", [\"add\", ...changedPaths], {\n cwd: context.worktreePath,\n logger: context.logger,\n label: \"git add conflicted paths\",\n });\n\n try {\n await execCapture(\"git\", [\"rebase\", \"--continue\"], {\n cwd: context.worktreePath,\n env: { ...process.env, GIT_EDITOR: \"true\" },\n logger: context.logger,\n label: \"git rebase --continue\",\n });\n // Full rebase completed after this commit\n if (context.worktreeState?.completedStages.builder) {\n const invalidatedState = invalidateAfterBaseRefresh(\n context.worktreeState\n );\n writeWorktreeRunState(context.worktreePath, invalidatedState);\n }\n return;\n } catch {\n // rebase --continue hit another conflict — detect new conflicted paths\n const statusResult = await execCapture(\"git\", [\"status\", \"--porcelain\"], {\n cwd: context.worktreePath,\n logger: context.logger,\n label: \"git status\",\n });\n const newConflictedPaths = statusResult.stdout\n .split(\"\\n\")\n .filter((line) => /^(AA|DD|UU|AU|UA|DU|UD)\\s/.test(line))\n .map((line) => line.slice(3).trim())\n .filter(Boolean);\n\n if (newConflictedPaths.length === 0) {\n const message =\n \"git rebase --continue failed with no remaining conflicts\";\n if (context.worktreeState) {\n updateWorktreeRunState(context.worktreePath, {\n lastFailure: { stage: \"baseRefresh\", message },\n });\n } else {\n writeWorktreeRunState(context.worktreePath, {\n issueNumber: context.issueNumber,\n targetName: context.target.name,\n branchName: context.branchName,\n baseBranch: context.target.baseBranch,\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n completedStages: {},\n review: { lifetimeIterations: 0 },\n lastFailure: { stage: \"baseRefresh\", message },\n });\n }\n await transitionIssueToFailureState(\n context.issueProvider,\n context.issueNumber,\n context.config,\n message,\n context.logger\n );\n throw new Error(message);\n }\n\n currentFailure = new RebaseConflict({\n conflictedPaths: newConflictedPaths,\n message: `Rebase conflict in: ${newConflictedPaths.join(\", \")}`,\n });\n }\n }\n\n if (context.worktreeState) {\n updateWorktreeRunState(context.worktreePath, {\n lastFailure: {\n stage: \"baseRefresh\",\n message: `Base refresh recovery exhausted after ${maxAttempts} attempts`,\n },\n });\n } else {\n writeWorktreeRunState(context.worktreePath, {\n issueNumber: context.issueNumber,\n targetName: context.target.name,\n branchName: context.branchName,\n baseBranch: context.target.baseBranch,\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n completedStages: {},\n review: { lifetimeIterations: 0 },\n lastFailure: {\n stage: \"baseRefresh\",\n message: `Base refresh recovery exhausted after ${maxAttempts} attempts`,\n },\n });\n }\n await transitionIssueToFailureState(\n context.issueProvider,\n context.issueNumber,\n context.config,\n `Base refresh recovery exhausted after ${maxAttempts} attempts`,\n context.logger\n );\n throw new Error(\n `Base refresh recovery exhausted after ${maxAttempts} attempts`\n );\n}\n\nasync function handlePublishedHistoryRisk(\n failure: PublishedHistoryRisk,\n context: {\n worktreePath: string;\n branchName: string;\n target: ResolvedTarget;\n config: PourkitConfig;\n issueNumber: number;\n issueProvider: IssueProvider;\n worktreeState: WorktreeRunState | null;\n logger: PourkitLogger;\n }\n): Promise<void> {\n const message = `Cannot auto-refresh published history: PR #${failure.prNumber} (${failure.prState}) exists for branch ${context.branchName}`;\n\n if (context.worktreeState) {\n updateWorktreeRunState(context.worktreePath, {\n lastFailure: { stage: \"baseRefresh\", message },\n });\n } else {\n writeWorktreeRunState(context.worktreePath, {\n issueNumber: context.issueNumber,\n targetName: context.target.name,\n branchName: context.branchName,\n baseBranch: context.target.baseBranch,\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n completedStages: {},\n review: { lifetimeIterations: 0 },\n lastFailure: { stage: \"baseRefresh\", message },\n });\n }\n\n await transitionIssueToFailureState(\n context.issueProvider,\n context.issueNumber,\n context.config,\n message,\n context.logger\n );\n throw new Error(message);\n}\n","import { readFileSync } from \"node:fs\";\nimport { fileURLToPath } from \"node:url\";\nimport { dirname, isAbsolute, join, normalize, sep, resolve } from \"node:path\";\nimport Ajv from \"ajv\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n// Load packaged schema once at module init\nconst SCHEMA_PATH = resolve(__dirname, \"../schema/pourkit.schema.json\");\nlet _schema: Record<string, unknown> | null = null;\nlet _validate: ((data: unknown) => boolean) | null = null;\nlet _ajvErrors: any = null;\n\nfunction getValidator(): (data: unknown) => boolean {\n if (!_validate) {\n const schema = _schema ?? JSON.parse(readFileSync(SCHEMA_PATH, \"utf-8\"));\n _schema = schema;\n const ajv = new Ajv({ strict: true });\n ajv.addKeyword(\"x-pourkit-schema-version\");\n const validate = ajv.compile(schema);\n _validate = (data: unknown) => {\n _ajvErrors = null;\n const valid = validate(data);\n if (!valid) _ajvErrors = validate.errors;\n return valid;\n };\n }\n return _validate;\n}\n\nexport interface CleanupConfig {\n enabled: boolean;\n worktreeRetentionDays: number;\n logRetentionDays: number;\n}\n\nexport interface SerenaConfig {\n enabled: boolean;\n required: boolean;\n mcpUrl: string;\n sandboxMcpUrl: string;\n dataDir: string;\n autoStart: boolean;\n}\n\nexport interface TargetSerenaConfig {\n enabled?: boolean;\n required?: boolean;\n}\n\nexport interface PourkitConfig {\n targets: Target[];\n labels: LabelsConfig;\n sandbox: SandboxConfig;\n checks: ChecksConfig;\n cleanup: CleanupConfig;\n serena: SerenaConfig;\n}\n\nexport interface StageAgentConfig {\n agent: string;\n model: string;\n variant?: string;\n env?: Record<string, string>;\n promptTemplate: string;\n outputRetries?: OutputRetriesConfig;\n}\n\nexport interface OutputRetriesConfig {\n missingOrEmpty?: number;\n}\n\nexport interface ConflictResolutionConfigInput extends StageAgentConfig {\n maxAttempts: number;\n}\n\nexport interface ConflictResolutionConfig extends StageAgentConfig {\n maxAttempts: number;\n}\n\nexport interface FailureResolutionConfigInput {\n agent: string;\n model: string;\n variant?: string;\n env?: Record<string, string>;\n promptTemplate: string;\n outputRetries?: OutputRetriesConfig;\n maxAttemptsPerFailure: number;\n failureLimits?: Record<string, number>;\n}\n\nexport interface FailureResolutionConfig {\n agent: string;\n model: string;\n variant?: string;\n env?: Record<string, string>;\n promptTemplate: string;\n outputRetries?: OutputRetriesConfig;\n maxAttemptsPerFailure: number;\n failureLimits?: Record<string, number>;\n}\n\nexport interface ReviewerConfig extends StageAgentConfig {\n criteria: string[];\n includeReviewHistory?: boolean;\n passWithNotesRefactorAttempts?: number;\n}\n\nexport interface BuilderConfig extends StageAgentConfig {}\n\nexport interface QueueConfig {\n loop?: boolean;\n}\n\nexport interface TargetInput {\n name: string;\n baseBranch: string;\n branchTemplate?: string;\n prdRun?: { mode?: PrdRunMode };\n setupCommands?: VerificationCommandInput[];\n autoMerge?: boolean;\n queue?: QueueConfig;\n serena?: TargetSerenaConfig;\n strategy: ReviewRefactorLoopStrategyInput;\n}\n\nexport interface Target {\n name: string;\n baseBranch: string;\n branchTemplate: string;\n prdRun?: { mode?: PrdRunMode };\n setupCommands?: VerificationCommand[];\n autoMerge?: boolean;\n queue?: QueueConfig;\n serena?: TargetSerenaConfig;\n strategy: ReviewRefactorLoopStrategy;\n}\n\nexport type ResolvedTarget = Target;\n\nexport type TargetStrategy = ReviewRefactorLoopStrategy;\n\nexport type PrdRunMode = \"github\" | \"local\";\nexport type PrdRunModeSource = \"target-config\" | \"cli-override\" | \"default\";\n\nexport interface ResolvedPrdRunMode {\n mode: PrdRunMode;\n source: PrdRunModeSource;\n targetName: string;\n}\n\nexport interface IssueFinalReviewConfig extends StageAgentConfig {\n maxAttempts: number;\n}\n\nexport interface ReviewRefactorLoopStrategyInput {\n type: \"review-refactor-loop\";\n implement: {\n builder: StageAgentConfig;\n };\n conflictResolution?: ConflictResolutionConfigInput;\n failureResolution: FailureResolutionConfigInput;\n review: {\n reviewer: ReviewerConfig;\n refactor: StageAgentConfig;\n maxIterations: number;\n passWithNotesRefactorAttempts?: number;\n };\n verify?: VerifyConfigInput;\n issueFinalReview: IssueFinalReviewConfig;\n finalize: {\n prDescriptionAgent: StageAgentConfig;\n maxAttempts: number;\n };\n}\n\nexport interface ReviewRefactorLoopStrategy {\n type: \"review-refactor-loop\";\n implement: {\n builder: StageAgentConfig;\n };\n conflictResolution?: ConflictResolutionConfig;\n failureResolution: FailureResolutionConfig;\n review: {\n reviewer: ReviewerConfig;\n refactor: StageAgentConfig;\n maxIterations: number;\n passWithNotesRefactorAttempts: number;\n };\n verify?: VerifyConfig;\n issueFinalReview: IssueFinalReviewConfig;\n finalize: {\n prDescriptionAgent: StageAgentConfig;\n maxAttempts: number;\n };\n /** @deprecated Strategy-level prdRun is removed in JSON config; use Target.prdRun instead. */\n prdRun?: {\n /** @deprecated prdRun.mode has moved to Target.prdRun.mode */\n mode?: PrdRunMode;\n /** @deprecated prdRun.finalReview is removed */\n finalReview?: StageAgentConfig;\n };\n}\n\nexport interface VerifyConfig {\n commands: VerificationCommand[];\n}\n\nexport interface VerifyConfigInput {\n commands?: VerificationCommandInput[];\n}\n\nexport interface LabelsConfig {\n readyForAgent: string;\n agentInProgress: string;\n blocked: string;\n prOpenAwaitingMerge: string;\n readyForHuman: string;\n needsTriage: string;\n}\n\nexport interface SandboxConfig {\n provider: string;\n copyToWorktree?: string[];\n mounts?: SandboxMountConfig[];\n env?: Record<string, string>;\n idleTimeoutSeconds?: number;\n forceRebuild?: boolean;\n}\n\nexport interface SandboxMountConfig {\n hostPath: string;\n sandboxPath: string;\n readonly?: boolean;\n}\n\nexport interface VerificationCommand {\n command: string;\n label: string;\n}\n\nexport interface VerificationCommandInput {\n command: string;\n label?: string;\n}\n\nexport interface ChecksConfig {\n requiredLabels: string[];\n allowedAuthors: string[];\n checksFoundTimeoutSeconds: number;\n checksCompletionTimeoutSeconds: number;\n pollIntervalSeconds: number;\n issueListLimit: number;\n}\n\nexport interface IssueData {\n number: number;\n title: string;\n body: string;\n state: \"open\" | \"closed\";\n labels: string[];\n comments: string[];\n createdAt?: Date;\n}\n\n// ---- Default constants ----\n\nconst DEFAULT_MISSING_OR_EMPTY_OUTPUT_RETRIES = 3;\nconst DEFAULT_BRANCH_TEMPLATE = \"pourkit/{{issue.number}}/{{issue.slug}}\";\n\nexport function resolveMissingOrEmptyOutputRetries(config?: {\n outputRetries?: { missingOrEmpty?: number };\n}): number {\n return (\n config?.outputRetries?.missingOrEmpty ??\n DEFAULT_MISSING_OR_EMPTY_OUTPUT_RETRIES\n );\n}\n\n// ---- Removed field preflight ----\n\nconst removedFieldReplacements: Record<string, string> = {\n \"config.implementor\": \"targets[].strategy.implement.builder\",\n \"config.reviewer\": \"targets[].strategy.review.reviewer\",\n \"config.refactorer\": \"targets[].strategy.review.refactor\",\n \"config.finalizer\": \"targets[].strategy.finalize.prDescriptionAgent\",\n \"config.maxReviewIterations\": \"targets[].strategy.review.maxIterations\",\n \"config.builder\": \"targets[].strategy.implement.builder\",\n \"targets[].verificationCommands\": \"targets[].strategy.verify.commands\",\n \"targets[].implementor\": \"targets[].strategy.implement.builder\",\n \"targets[].reviewer\": \"targets[].strategy.review.reviewer\",\n \"targets[].refactorer\": \"targets[].strategy.review.refactor\",\n \"targets[].finalizer\": \"targets[].strategy.finalize.prDescriptionAgent\",\n \"targets[].maxReviewIterations\": \"targets[].strategy.review.maxIterations\",\n \"checks.timeoutSeconds\": \"checks.checksCompletionTimeoutSeconds\",\n};\n\nfunction checkRemovedFields(raw: Record<string, unknown>): void {\n const topLevelKeys = [\n \"implementor\",\n \"reviewer\",\n \"refactorer\",\n \"finalizer\",\n \"maxReviewIterations\",\n \"builder\",\n ];\n for (const key of topLevelKeys) {\n if (key in raw) {\n throw new Error(\n `config.${key} has been removed; use ${removedFieldReplacements[`config.${key}`]}`\n );\n }\n }\n\n const targetLevelKeys = [\n \"verificationCommands\",\n \"implementor\",\n \"reviewer\",\n \"refactorer\",\n \"finalizer\",\n \"maxReviewIterations\",\n ];\n if (Array.isArray(raw.targets)) {\n for (let i = 0; i < raw.targets.length; i++) {\n const t = raw.targets[i];\n if (t && typeof t === \"object\") {\n const target = t as Record<string, unknown>;\n for (const key of targetLevelKeys) {\n if (key in target) {\n throw new Error(\n `targets[${i}].${key} has been removed; use ${removedFieldReplacements[`targets[].${key}`]}`\n );\n }\n }\n }\n }\n }\n\n if (raw.checks && typeof raw.checks === \"object\") {\n const checks = raw.checks as Record<string, unknown>;\n if (\"timeoutSeconds\" in checks) {\n throw new Error(\n \"checks.timeoutSeconds has been removed; use checks.checksCompletionTimeoutSeconds\"\n );\n }\n }\n}\n\n// ---- Ajv error formatting ----\n\nfunction formatAjvPath(instancePath: string): string {\n if (!instancePath || instancePath === \"/\") return \"\";\n const parts = instancePath.split(\"/\").slice(1);\n let result = \"\";\n for (const segment of parts) {\n if (/^\\d+$/.test(segment)) {\n result += `[${segment}]`;\n } else {\n result += result ? `.${segment}` : segment;\n }\n }\n return result;\n}\n\nfunction formatFirstAjvError(errors: any[]): string {\n const error = errors[0];\n const path = formatAjvPath(error.instancePath);\n\n if (error.keyword === \"required\") {\n const missingParam = (error.params as { missingProperty: string })\n .missingProperty;\n if (missingParam === \"targets\") {\n return \"Config must have at least one target\";\n }\n if (path === \"\" && missingParam === \"targets\") {\n return \"Config must have at least one target\";\n }\n if (path) {\n return `${path} must have required property '${missingParam}'`;\n }\n return `${missingParam} must be an object`;\n }\n\n if (error.keyword === \"additionalProperties\") {\n const additionalProp = (error.params as { additionalProperty: string })\n .additionalProperty;\n const keyPath = path ? `${path}.${additionalProp}` : additionalProp;\n return `${keyPath} is not supported`;\n }\n\n if (error.keyword === \"minLength\") {\n if (path) {\n return `${path} must be a non-empty string`;\n }\n return \"Config must be a non-empty string\";\n }\n\n if (error.keyword === \"const\") {\n const allowedValue = (error.params as { allowedValue: unknown })\n .allowedValue;\n return `${path || \"Config\"} must be ${JSON.stringify(allowedValue)}`;\n }\n\n if (error.keyword === \"enum\") {\n const allowedValues = (error.params as { allowedValues: unknown[] })\n .allowedValues;\n return `${path} must be one of: ${allowedValues.map((v) => JSON.stringify(v)).join(\", \")}`;\n }\n\n if (error.keyword === \"minimum\" || error.keyword === \"exclusiveMinimum\") {\n const limit = (error.params as { limit: number }).limit;\n if (limit === 1) {\n return `${path} must be a positive number`;\n }\n return `${path} must be at least ${limit}`;\n }\n\n if (error.keyword === \"type\") {\n const expected = (error.params as { type: string }).type;\n if (path === \"\") {\n return `Config must be an object`;\n }\n if (expected === \"object\") {\n return `${path} must be an object`;\n }\n if (expected === \"integer\") {\n return `${path} must be an integer`;\n }\n if (expected === \"string\") {\n return `${path} must be a string`;\n }\n if (expected === \"number\") {\n return `${path} must be a number`;\n }\n return `${path} must be ${expected === \"integer\" ? \"an integer\" : `a ${expected}`}`;\n }\n\n if (error.keyword === \"minItems\") {\n return `${path} must contain at least one item`;\n }\n\n if (error.keyword === \"pattern\") {\n return `${path} has an invalid format`;\n }\n\n return `${path || \"Config\"} ${error.message || \"is invalid\"}`;\n}\n\nfunction applyOutputRetriesDefaults(\n retries: OutputRetriesConfig | undefined\n): OutputRetriesConfig | undefined {\n if (retries === undefined) return undefined;\n return {\n missingOrEmpty:\n retries.missingOrEmpty ?? DEFAULT_MISSING_OR_EMPTY_OUTPUT_RETRIES,\n };\n}\n\nfunction applyStageAgentDefaults(agent: StageAgentConfig): StageAgentConfig {\n return {\n ...agent,\n outputRetries: applyOutputRetriesDefaults(agent.outputRetries),\n };\n}\n\nfunction assertRepoRelativePath(value: string, location: string): void {\n const normalized = normalize(value);\n if (\n isAbsolute(value) ||\n isAbsolute(normalized) ||\n normalized === \"..\" ||\n normalized.startsWith(`..${sep}`)\n ) {\n throw new Error(\n `${location} must stay within the repository and be repo-relative; got \"${value}\"`\n );\n }\n}\n\nfunction assertBaseBranch(value: string, location: string): void {\n if (value.includes(\"/\")) {\n throw new Error(\n `${location} must be a local branch name, not a remote-qualified, tag, ref, or path-like name; got \"${value}\"`\n );\n }\n\n if (/^[0-9a-f]{7,40}$/i.test(value)) {\n throw new Error(\n `${location} must be a branch name, not a commit SHA; got \"${value}\"`\n );\n }\n}\n\nfunction assertStageAgentPath(\n agent: Record<string, unknown> | undefined,\n location: string\n): void {\n if (!agent) return;\n const promptTemplate = agent.promptTemplate;\n if (typeof promptTemplate === \"string\") {\n assertRepoRelativePath(promptTemplate, `${location}.promptTemplate`);\n }\n}\n\nfunction validateConfigSemantics(data: Record<string, unknown>): void {\n const sandbox = data.sandbox as Record<string, unknown> | undefined;\n const copyToWorktree = sandbox?.copyToWorktree as string[] | undefined;\n copyToWorktree?.forEach((entry, index) => {\n assertRepoRelativePath(entry, `sandbox.copyToWorktree[${index}]`);\n });\n\n const targetNames = new Set<string>();\n (data.targets as Record<string, unknown>[]).forEach((target, targetIndex) => {\n const name = target.name as string;\n if (targetNames.has(name)) {\n throw new Error(\n `Duplicate target name \"${name}\"; target names must be unique`\n );\n }\n targetNames.add(name);\n\n assertBaseBranch(\n target.baseBranch as string,\n `targets[${targetIndex}].baseBranch`\n );\n\n const strategy = target.strategy as Record<string, unknown>;\n const implement = strategy.implement as Record<string, unknown>;\n const review = strategy.review as Record<string, unknown>;\n const finalize = strategy.finalize as Record<string, unknown>;\n\n assertStageAgentPath(\n implement.builder as Record<string, unknown> | undefined,\n `targets[${targetIndex}].strategy.implement.builder`\n );\n assertStageAgentPath(\n strategy.conflictResolution as Record<string, unknown> | undefined,\n `targets[${targetIndex}].strategy.conflictResolution`\n );\n assertStageAgentPath(\n strategy.failureResolution as Record<string, unknown> | undefined,\n `targets[${targetIndex}].strategy.failureResolution`\n );\n assertStageAgentPath(\n review.reviewer as Record<string, unknown> | undefined,\n `targets[${targetIndex}].strategy.review.reviewer`\n );\n assertStageAgentPath(\n review.refactor as Record<string, unknown> | undefined,\n `targets[${targetIndex}].strategy.review.refactor`\n );\n assertStageAgentPath(\n strategy.issueFinalReview as Record<string, unknown> | undefined,\n `targets[${targetIndex}].strategy.issueFinalReview`\n );\n assertStageAgentPath(\n finalize.prDescriptionAgent as Record<string, unknown> | undefined,\n `targets[${targetIndex}].strategy.finalize.prDescriptionAgent`\n );\n });\n}\n\n// ---- Assert known keys (used before schema validation for compat hints) ----\n\nfunction assertKnownKeys(\n value: Record<string, unknown>,\n path: string,\n knownKeys: string[]\n) {\n for (const key of Object.keys(value)) {\n if (!knownKeys.includes(key)) {\n throw new Error(`${path}.${key} is not supported`);\n }\n }\n}\n\n// ---- Config parsing ----\n\nexport function parseConfig(raw: unknown): PourkitConfig {\n if (!raw || typeof raw !== \"object\") {\n throw new Error(\"Config must be an object\");\n }\n\n const config = raw as Record<string, unknown>;\n\n if (!Array.isArray(config.targets) || config.targets.length === 0) {\n throw new Error(\"Config must have at least one target\");\n }\n\n checkRemovedFields(config);\n\n const rawTargets = config.targets as Record<string, unknown>[];\n for (let i = 0; i < rawTargets.length; i++) {\n const t = rawTargets[i];\n if (t === null || typeof t !== \"object\") {\n throw new Error(`targets[${i}] must be an object`);\n }\n assertKnownKeys(t, `targets[${i}]`, [\n \"name\",\n \"baseBranch\",\n \"branchTemplate\",\n \"prdRun\",\n \"setupCommands\",\n \"autoMerge\",\n \"queue\",\n \"serena\",\n \"strategy\",\n ]);\n }\n\n for (let i = 0; i < rawTargets.length; i++) {\n const t = rawTargets[i];\n const strategy = t?.strategy as Record<string, unknown> | undefined;\n if (\n strategy &&\n typeof strategy === \"object\" &&\n \"conflictResolution\" in strategy\n ) {\n throw new Error(\n `targets[${i}].strategy.conflictResolution has been removed; use targets[${i}].strategy.failureResolution`\n );\n }\n\n if (\n strategy &&\n typeof strategy === \"object\" &&\n strategy.prdRun &&\n typeof strategy.prdRun === \"object\"\n ) {\n const prdRun = strategy.prdRun as Record<string, unknown>;\n if (\"reconciliation\" in prdRun) {\n throw new Error(\n `targets[${i}].strategy.prdRun.reconciliation has been removed; PRD Run no longer invokes Architect reconciliation.`\n );\n }\n if (\"finalReview\" in prdRun) {\n throw new Error(\n `targets[${i}].strategy.prdRun.finalReview has been removed; PRD-wide Final Review is no longer part of the PRD Run lifecycle. Use targets[${i}].strategy.issueFinalReview instead.`\n );\n }\n throw new Error(\n `targets[${i}].strategy.prdRun is not supported in the new config; use targets[${i}].prdRun instead.`\n );\n }\n }\n\n if (config.sandbox && typeof config.sandbox === \"object\") {\n assertKnownKeys(config.sandbox as Record<string, unknown>, \"sandbox\", [\n \"provider\",\n \"copyToWorktree\",\n \"mounts\",\n \"env\",\n \"idleTimeoutSeconds\",\n \"forceRebuild\",\n ]);\n }\n\n // Validate against packaged JSON Schema\n const validate = getValidator();\n if (!validate(raw)) {\n throw new Error(\n formatFirstAjvError(\n _ajvErrors ?? [\n {\n instancePath: \"\",\n message: \"validation failed\",\n keyword: \"error\",\n params: {},\n },\n ]\n )\n );\n }\n\n const data = config as Record<string, unknown>;\n\n validateConfigSemantics(data);\n\n const targets: Target[] = (data.targets as Record<string, unknown>[]).map(\n (t) => {\n const input = t as Record<string, unknown>;\n const strategy = input.strategy as Record<string, unknown>;\n const implement = strategy.implement as Record<string, unknown>;\n const failureResolution = strategy.failureResolution as Record<\n string,\n unknown\n >;\n const review = strategy.review as Record<string, unknown>;\n const reviewReviewer = review.reviewer as Record<string, unknown>;\n const reviewRefactor = review.refactor as Record<string, unknown>;\n const finalize = strategy.finalize as Record<string, unknown>;\n const issueFinalReview = strategy.issueFinalReview as Record<\n string,\n unknown\n >;\n\n const setupCommands = (\n input.setupCommands as Record<string, unknown>[] | undefined\n )?.map((cmd, i) => ({\n command: cmd.command as string,\n label: (cmd.label as string) ?? `check-${i}`,\n }));\n\n const verifyCommands = (\n strategy.verify as Record<string, unknown> | undefined\n )?.commands\n ? ((strategy.verify as Record<string, unknown>).commands as Record<\n string,\n unknown\n >[])\n : undefined;\n\n const verifyLabeled = verifyCommands?.map((cmd, i) => ({\n command: cmd.command as string,\n label: (cmd.label as string) ?? `check-${i}`,\n })) as VerificationCommand[] | undefined;\n\n return {\n name: input.name as string,\n baseBranch: input.baseBranch as string,\n branchTemplate:\n (input.branchTemplate as string) ?? DEFAULT_BRANCH_TEMPLATE,\n prdRun: input.prdRun as { mode?: PrdRunMode } | undefined,\n setupCommands,\n autoMerge:\n input.autoMerge !== undefined ? (input.autoMerge as boolean) : true,\n queue: input.queue as QueueConfig | undefined,\n serena: input.serena as TargetSerenaConfig | undefined,\n strategy: {\n type: \"review-refactor-loop\" as const,\n implement: {\n builder: applyStageAgentDefaults(\n implement.builder as unknown as StageAgentConfig\n ),\n },\n failureResolution: {\n agent: failureResolution.agent as string,\n model: failureResolution.model as string,\n variant: failureResolution.variant as string | undefined,\n env: failureResolution.env as Record<string, string> | undefined,\n promptTemplate: failureResolution.promptTemplate as string,\n outputRetries: applyOutputRetriesDefaults(\n failureResolution.outputRetries as OutputRetriesConfig | undefined\n ),\n maxAttemptsPerFailure:\n failureResolution.maxAttemptsPerFailure as number,\n failureLimits: failureResolution.failureLimits as\n | Record<string, number>\n | undefined,\n },\n review: {\n reviewer: {\n agent: reviewReviewer.agent as string,\n model: reviewReviewer.model as string,\n variant: reviewReviewer.variant as string | undefined,\n env: reviewReviewer.env as Record<string, string> | undefined,\n promptTemplate: reviewReviewer.promptTemplate as string,\n outputRetries: applyOutputRetriesDefaults(\n reviewReviewer.outputRetries as OutputRetriesConfig | undefined\n ),\n criteria: reviewReviewer.criteria as string[],\n includeReviewHistory: reviewReviewer.includeReviewHistory as\n | boolean\n | undefined,\n passWithNotesRefactorAttempts:\n reviewReviewer.passWithNotesRefactorAttempts as\n | number\n | undefined,\n },\n refactor: applyStageAgentDefaults(\n reviewRefactor as unknown as StageAgentConfig\n ),\n maxIterations: review.maxIterations as number,\n passWithNotesRefactorAttempts:\n (review.passWithNotesRefactorAttempts as number) ?? 2,\n },\n ...(verifyLabeled ? { verify: { commands: verifyLabeled } } : {}),\n issueFinalReview: {\n ...(issueFinalReview as unknown as StageAgentConfig),\n maxAttempts: issueFinalReview.maxAttempts as number,\n outputRetries: applyOutputRetriesDefaults(\n issueFinalReview.outputRetries as OutputRetriesConfig | undefined\n ),\n },\n finalize: {\n prDescriptionAgent: applyStageAgentDefaults(\n finalize.prDescriptionAgent as unknown as StageAgentConfig\n ),\n maxAttempts: finalize.maxAttempts as number,\n },\n } as ReviewRefactorLoopStrategy,\n };\n }\n );\n\n const serenaRaw = data.serena as Record<string, unknown> | undefined;\n const serenaDefaults = {\n mcpUrl:\n (serenaRaw?.mcpUrl as string | undefined) ?? \"http://localhost:9121/mcp\",\n sandboxMcpUrl:\n (serenaRaw?.sandboxMcpUrl as string | undefined) ??\n \"http://localhost:9121/mcp\",\n dataDir: (serenaRaw?.dataDir as string | undefined) ?? \".pourkit/serena/\",\n };\n\n const serena: SerenaConfig = {\n enabled: (serenaRaw?.enabled as boolean | undefined) ?? false,\n required: (serenaRaw?.required as boolean | undefined) ?? false,\n mcpUrl: process.env.POURKIT_SERENA_MCP_URL ?? serenaDefaults.mcpUrl,\n sandboxMcpUrl:\n process.env.POURKIT_SERENA_SANDBOX_MCP_URL ??\n serenaDefaults.sandboxMcpUrl,\n dataDir: serenaDefaults.dataDir,\n autoStart: (serenaRaw?.autoStart as boolean | undefined) ?? false,\n };\n\n if (serena.mcpUrl.trim() === \"\") {\n throw new Error(\"POURKIT_SERENA_MCP_URL must be a non-empty string\");\n }\n\n if (serena.sandboxMcpUrl.trim() === \"\") {\n throw new Error(\n \"POURKIT_SERENA_SANDBOX_MCP_URL must be a non-empty string\"\n );\n }\n\n const checksRaw = data.checks as Record<string, unknown> | undefined;\n const labelsRaw = data.labels as Record<string, unknown> | undefined;\n const cleanupRaw = data.cleanup as Record<string, unknown> | undefined;\n\n const sandboxRaw = data.sandbox as Record<string, unknown> | undefined;\n\n return {\n targets,\n labels: {\n readyForAgent: (labelsRaw?.readyForAgent as string) ?? \"ready-for-agent\",\n agentInProgress:\n (labelsRaw?.agentInProgress as string) ?? \"agent-in-progress\",\n blocked: (labelsRaw?.blocked as string) ?? \"blocked\",\n prOpenAwaitingMerge:\n (labelsRaw?.prOpenAwaitingMerge as string) ?? \"pr-open-awaiting-merge\",\n readyForHuman: (labelsRaw?.readyForHuman as string) ?? \"ready-for-human\",\n needsTriage: (labelsRaw?.needsTriage as string) ?? \"needs-triage\",\n },\n sandbox: {\n provider: (sandboxRaw?.provider as string) ?? \"docker\",\n copyToWorktree: sandboxRaw?.copyToWorktree as string[] | undefined,\n mounts: sandboxRaw?.mounts\n ? (\n sandboxRaw.mounts as {\n hostPath: string;\n sandboxPath: string;\n readonly?: boolean;\n }[]\n ).map((m) => ({\n hostPath: m.hostPath,\n sandboxPath: m.sandboxPath,\n readonly: m.readonly ?? false,\n }))\n : undefined,\n env: sandboxRaw?.env as Record<string, string> | undefined,\n idleTimeoutSeconds: sandboxRaw?.idleTimeoutSeconds as number | undefined,\n forceRebuild: sandboxRaw?.forceRebuild as boolean | undefined,\n },\n checks: {\n requiredLabels: (checksRaw?.requiredLabels as string[]) ?? [],\n allowedAuthors: (checksRaw?.allowedAuthors as string[]) ?? [],\n checksFoundTimeoutSeconds:\n (checksRaw?.checksFoundTimeoutSeconds as number) ?? 60,\n checksCompletionTimeoutSeconds:\n (checksRaw?.checksCompletionTimeoutSeconds as number) ?? 30 * 60,\n pollIntervalSeconds: (checksRaw?.pollIntervalSeconds as number) ?? 15,\n issueListLimit: (checksRaw?.issueListLimit as number) ?? 50,\n },\n serena,\n cleanup: {\n enabled: (cleanupRaw?.enabled as boolean) ?? true,\n worktreeRetentionDays:\n (cleanupRaw?.worktreeRetentionDays as number) ?? 14,\n logRetentionDays: (cleanupRaw?.logRetentionDays as number) ?? 30,\n },\n };\n}\n\n// ---- Key validation helpers ----\n\n// ---- Public API ----\n\nexport function getVerificationCommands(target: Target): VerificationCommand[] {\n return target.strategy.verify?.commands ?? [];\n}\n\nexport function resolvePrdRunMode(\n target: Target,\n opts?: { localOverride?: boolean }\n): ResolvedPrdRunMode {\n if (opts?.localOverride === true) {\n return { mode: \"local\", source: \"cli-override\", targetName: target.name };\n }\n\n const configMode = target.prdRun?.mode;\n if (configMode) {\n return {\n mode: configMode,\n source: \"target-config\",\n targetName: target.name,\n };\n }\n\n return { mode: \"github\", source: \"default\", targetName: target.name };\n}\n\nconst OBSOLETE_CONFIG_PATHS = [\n \"pourkit.config.ts\",\n \"pourkit.config.mjs\",\n \"pourkit.config.js\",\n \"pourkit.json\",\n];\n\nconst CANONICAL_CONFIG_PATH = \".pourkit/config.json\";\n\nexport async function loadRepoConfig(\n repoRoot: string,\n _configFileName?: string\n): Promise<PourkitConfig> {\n const { existsSync } = await import(\"node:fs\");\n const { join: pjoin } = await import(\"node:path\");\n\n // Check obsolete config paths first (before checking canonical)\n for (const obPath of OBSOLETE_CONFIG_PATHS) {\n const fullPath = pjoin(repoRoot, obPath);\n if (existsSync(fullPath)) {\n const isRootJson = obPath === \"pourkit.json\";\n throw new Error(\n isRootJson\n ? `Found root ${obPath}, but Pourkit config now lives at ${CANONICAL_CONFIG_PATH}. Move the file and update \"$schema\" to \"./schema/pourkit.schema.json\".`\n : `Found ${obPath}, but executable config is no longer supported. Move configuration to ${CANONICAL_CONFIG_PATH} with \"$schema\": \"./schema/pourkit.schema.json\".`\n );\n }\n }\n\n const configPath = pjoin(repoRoot, CANONICAL_CONFIG_PATH);\n\n if (!existsSync(configPath)) {\n throw new Error(\n `No Pourkit config found at ${CANONICAL_CONFIG_PATH}. Run pourkit init or create ${CANONICAL_CONFIG_PATH} with \"$schema\": \"./schema/pourkit.schema.json\".`\n );\n }\n\n const { readFile } = await import(\"node:fs/promises\");\n const raw = await readFile(configPath, \"utf-8\");\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch (err: unknown) {\n const message = err instanceof SyntaxError ? err.message : String(err);\n throw new Error(`${CANONICAL_CONFIG_PATH}: Invalid JSON — ${message}`);\n }\n\n return parseConfig(parsed);\n}\n\nexport async function loadConfig(configPath: string): Promise<PourkitConfig> {\n const { readFile } = await import(\"node:fs/promises\");\n const ext = configPath.split(\".\").pop()?.toLowerCase();\n\n if (ext === \"json\") {\n const raw = await readFile(configPath, \"utf-8\");\n return parseConfig(JSON.parse(raw));\n }\n\n if (ext === \"mjs\" || ext === \"js\" || ext === \"ts\") {\n throw new Error(\n `Executable config (${ext}) is no longer supported. Use .pourkit/config.json with \"$schema\": \"./schema/pourkit.schema.json\".`\n );\n }\n\n throw new Error(`Unsupported config format: ${ext}`);\n}\n\nexport function resolvePromptTemplatePath(\n repoRoot: string,\n promptTemplate: string\n): string {\n if (promptTemplate.includes(\"/\")) {\n return join(repoRoot, promptTemplate);\n }\n return join(repoRoot, \".pourkit\", \"prompts\", promptTemplate);\n}\n\nexport function resolveTarget(\n config: PourkitConfig,\n explicitTarget?: string\n): ResolvedTarget {\n if (config.targets.length === 0) {\n throw new Error(\"No targets configured\");\n }\n\n if (config.targets.length === 1) {\n const target = config.targets[0];\n if (explicitTarget && target.name !== explicitTarget) {\n throw new Error(\n `Target \"${explicitTarget}\" not found. Available: ${target.name}`\n );\n }\n return target;\n }\n\n if (!explicitTarget) {\n throw new Error(\n `Multiple targets configured: ${config.targets.map((t) => t.name).join(\", \")}. Use --target to select one.`\n );\n }\n\n const found = config.targets.find((t) => t.name === explicitTarget);\n if (!found) {\n throw new Error(\n `Target \"${explicitTarget}\" not found. Available: ${config.targets.map((t) => t.name).join(\", \")}`\n );\n }\n\n return found;\n}\n","import type { IssueData } from \"../shared/config\";\nimport { slugify } from \"../shared/common\";\n\nexport function renderBranchName(template: string, issue: IssueData): string {\n return renderTemplate(template, issue);\n}\n\nfunction renderTemplate(template: string, issue: IssueData): string {\n const issueSlug = slugify(issue.title);\n\n return template\n .replace(/\\{\\{issue\\.number\\}\\}/g, String(issue.number))\n .replace(/\\{\\{issue\\.title\\}\\}/g, issue.title)\n .replace(/\\{\\{issue\\.body\\}\\}/g, issue.body)\n .replace(/\\{\\{issue\\.slug\\}\\}/g, issueSlug)\n .replace(/\\{\\{issue\\.state\\}\\}/g, issue.state);\n}\n","import { existsSync, readFileSync, readdirSync } from \"fs\";\nimport { isAbsolute, join, relative, resolve } from \"path\";\nimport type { PourkitStage } from \"../execution/execution-provider\";\nimport { buildRunVerificationCommand } from \"../commands/run-verification\";\nimport { getVerificationCommands, type IssueData, type Target } from \"./config\";\n\nexport const RUN_CONTEXT_PATH_IN_WORKTREE = \".pourkit/.tmp/run-context.md\";\n\nexport type RunContextSection =\n | \"issue\"\n | \"prd\"\n | \"comments\"\n | \"branch\"\n | \"verification-commands\"\n | \"review-criteria\"\n | \"artifacts\";\n\nexport const ALL_RUN_CONTEXT_SECTIONS: RunContextSection[] = [\n \"issue\",\n \"prd\",\n \"comments\",\n \"branch\",\n \"verification-commands\",\n \"review-criteria\",\n \"artifacts\",\n];\n\nexport const STAGE_SECTIONS: Record<PourkitStage, RunContextSection[]> = {\n builder: [\n \"issue\",\n \"prd\",\n \"comments\",\n \"branch\",\n \"verification-commands\",\n \"artifacts\",\n ],\n reviewer: [\n \"issue\",\n \"prd\",\n \"comments\",\n \"branch\",\n \"verification-commands\",\n \"review-criteria\",\n \"artifacts\",\n ],\n refactor: [\n \"issue\",\n \"prd\",\n \"comments\",\n \"branch\",\n \"verification-commands\",\n \"review-criteria\",\n \"artifacts\",\n ],\n finalizer: [\n \"issue\",\n \"comments\",\n \"branch\",\n \"verification-commands\",\n \"review-criteria\",\n \"artifacts\",\n ],\n conflictResolution: [\n \"issue\",\n \"comments\",\n \"branch\",\n \"verification-commands\",\n \"artifacts\",\n ],\n failureResolution: [\n \"issue\",\n \"comments\",\n \"branch\",\n \"verification-commands\",\n \"artifacts\",\n ],\n issueFinalReview: [\n \"issue\",\n \"prd\",\n \"comments\",\n \"branch\",\n \"verification-commands\",\n \"review-criteria\",\n \"artifacts\",\n ],\n prdFinalReview: [\n \"issue\",\n \"comments\",\n \"branch\",\n \"verification-commands\",\n \"artifacts\",\n ],\n};\n\nexport interface RunContextOptions {\n issue: IssueData;\n parentPrdIssue?: IssueData;\n target: Target;\n branchName: string;\n repoRoot?: string;\n reviewerCriteria?: string[];\n sections?: RunContextSection[];\n}\n\nexport interface ExecutionArtifact {\n path: string;\n content: string;\n}\n\nexport function buildRunContextArtifact(\n options: RunContextOptions\n): ExecutionArtifact {\n return {\n path: RUN_CONTEXT_PATH_IN_WORKTREE,\n content: buildRunContextMarkdown(options),\n };\n}\n\nexport function buildRunContextMarkdown(options: RunContextOptions): string {\n const {\n issue,\n parentPrdIssue,\n target,\n branchName,\n repoRoot,\n reviewerCriteria = [],\n sections = ALL_RUN_CONTEXT_SECTIONS,\n } = options;\n\n const parts: string[] = [\"# Pourkit Run Context\", \"\"];\n\n if (sections.includes(\"issue\")) {\n parts.push(\n \"## Issue\",\n \"\",\n `- Number: #${issue.number}`,\n `- Title: ${issue.title}`,\n \"\",\n \"### Body\",\n \"\",\n issue.body.trim() || \"(empty issue body)\",\n \"\"\n );\n }\n\n if (sections.includes(\"prd\")) {\n parts.push(...renderPrdContext(issue, parentPrdIssue, repoRoot));\n }\n\n if (sections.includes(\"comments\")) {\n parts.push(\"## Comments\", \"\");\n\n if (issue.comments.length === 0) {\n parts.push(\"(none)\", \"\");\n } else {\n parts.push(\n ...issue.comments.flatMap((comment, index) => [\n `### Comment ${index + 1}`,\n \"\",\n comment.trim() || \"(empty comment)\",\n \"\",\n ])\n );\n }\n }\n\n if (sections.includes(\"branch\")) {\n const canonicalBaseRef = `origin/${target.baseBranch}`;\n parts.push(\n \"## Branch\",\n \"\",\n `- Base: ${target.baseBranch}`,\n `- Canonical Base Ref: ${canonicalBaseRef}`,\n `- Working Branch: ${branchName}`,\n \"\",\n \"Use the canonical base ref for scope checks, commit ranges, and diffs. Do not use a bare PRD/base branch name such as `PRD-0063`; local branches with those names may be stale.\",\n \"\",\n \"Runner-owned Git operations: do not run destructive history/worktree commands such as `git reset --hard`, `git checkout .`, `git clean`, `git rebase`, `git merge`, or `git branch -f`. Edit files only; the runner owns branch/base movement.\",\n \"\"\n );\n }\n\n if (sections.includes(\"verification-commands\")) {\n parts.push(...renderCommandList(target, \"Verification Commands\"));\n }\n\n if (sections.includes(\"review-criteria\")) {\n parts.push(...renderCriteria(reviewerCriteria));\n }\n\n if (sections.includes(\"artifacts\")) {\n parts.push(\n \"## Artifacts\",\n \"\",\n \"- Shared run context: `.pourkit/.tmp/run-context.md`\",\n \"- Reviewer outputs dir: `.pourkit/.tmp/reviewers/`\",\n \"- Refactor outputs dir: `.pourkit/.tmp/refactors/`\",\n \"- Finalizer output: `.pourkit/.tmp/finalizer/agent-output.md`\",\n \"\"\n );\n }\n\n return parts.join(\"\\n\");\n}\n\nfunction renderCommandList(target: Target, heading: string) {\n const commands = getVerificationCommands(target);\n const parts = [\n `## ${heading}`,\n \"\",\n `Run this command from the repository root: \\`${buildRunVerificationCommand(target)}\\``,\n \"\",\n ];\n\n if (commands.length > 0) {\n parts.push(\n \"Configured commands executed by the wrapper:\",\n \"\",\n ...commands.map(\n (command) => `- ${command.label}: \\`${command.command}\\``\n ),\n \"\"\n );\n }\n\n return parts;\n}\n\nfunction renderPrdContext(\n issue: IssueData,\n parentPrdIssue: IssueData | undefined,\n repoRoot: string | undefined\n) {\n const parent = extractIssueSection(issue.body, \"Parent\");\n const documents = extractIssueSection(issue.body, \"Plan Documents\");\n const parentRef = parent?.match(/\\bPRD-\\d+\\b/i)?.[0]?.toUpperCase();\n const parentPrdPath =\n parentRef && repoRoot ? findParentPrdPath(repoRoot, parentRef) : null;\n const documentPaths = repoRoot ? extractRepoPaths(documents) : [];\n\n if (!parent && !documents) {\n return [];\n }\n\n const parts = [\"## PRD\", \"\"];\n\n if (parent) {\n parts.push(parent, \"\");\n } else {\n parts.push(\"(not declared in issue body)\", \"\");\n }\n\n if (parentPrdPath && repoRoot) {\n parts.push(\n `### Parent PRD Content: \\`${relative(repoRoot, parentPrdPath)}\\``,\n \"\",\n \"```markdown\",\n readFileSync(parentPrdPath, \"utf-8\").trimEnd(),\n \"```\",\n \"\"\n );\n } else if (parentPrdIssue) {\n parts.push(\n `### Parent PRD Content: #${parentPrdIssue.number} ${parentPrdIssue.title}`,\n \"\",\n \"```markdown\",\n parentPrdIssue.body.trimEnd() || \"(empty PRD body)\",\n \"```\",\n \"\"\n );\n }\n\n parts.push(\"## PRD Documents\", \"\");\n\n if (documents) {\n parts.push(documents, \"\");\n } else {\n parts.push(\"(not declared in issue body)\", \"\");\n }\n\n for (const documentPath of documentPaths) {\n const absolutePath = resolveRepoPath(repoRoot!, documentPath);\n if (!absolutePath || !existsSync(absolutePath)) continue;\n\n parts.push(\n `### Document Content: \\`${documentPath}\\``,\n \"\",\n \"```markdown\",\n readFileSync(absolutePath, \"utf-8\").trimEnd(),\n \"```\",\n \"\"\n );\n }\n\n return parts;\n}\n\nfunction extractIssueSection(body: string, heading: string): string | null {\n const escapedHeading = heading.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n const section = body.match(\n new RegExp(`^## ${escapedHeading}\\\\s*\\\\n([\\\\s\\\\S]*?)(?=\\\\n## |$)`, \"im\")\n )?.[1];\n\n const trimmed = section?.trim();\n return trimmed ? trimmed : null;\n}\n\nfunction extractRepoPaths(section: string | null): string[] {\n if (!section) return [];\n\n const paths = new Set<string>();\n for (const match of section.matchAll(/`([^`]+)`/g)) {\n const value = match[1]?.trim();\n if (value) paths.add(value);\n }\n return Array.from(paths);\n}\n\nfunction resolveRepoPath(repoRoot: string, path: string): string | null {\n if (isAbsolute(path) || path.includes(\"\\0\")) return null;\n\n const resolved = resolve(repoRoot, path);\n const repoRelative = relative(repoRoot, resolved);\n if (repoRelative.startsWith(\"..\") || isAbsolute(repoRelative)) return null;\n\n return resolved;\n}\n\nfunction findParentPrdPath(repoRoot: string, parentRef: string): string | null {\n const plansRoot = join(repoRoot, \".pourkit\", \"plans\");\n if (!existsSync(plansRoot)) return null;\n\n return findPrdInPlans(plansRoot, parentRef);\n}\n\nfunction findPrdInPlans(directory: string, parentRef: string): string | null {\n for (const entry of readdirSync(directory, { withFileTypes: true })) {\n const entryPath = join(directory, entry.name);\n if (entry.isDirectory()) {\n const prdNumber = parentRef.match(/^PRD-(\\d+)$/)?.[1];\n if (\n entry.name.startsWith(parentRef) ||\n (prdNumber && entry.name.startsWith(`${prdNumber}-`))\n ) {\n const prdPath = join(entryPath, \"PRD.md\");\n if (existsSync(prdPath)) return prdPath;\n }\n\n const nested = findPrdInPlans(entryPath, parentRef);\n if (nested) return nested;\n }\n }\n\n return null;\n}\n\nfunction renderCriteria(criteria: string[]) {\n if (criteria.length === 0) {\n return [];\n }\n\n return [\n \"## Review Criteria\",\n \"\",\n ...criteria.map((criterion) => `- ${criterion}`),\n \"\",\n ];\n}\n","import { execCapture, type PourkitLogger } from \"../shared/common\";\nimport {\n getVerificationCommands,\n type Target,\n type VerificationCommand,\n} from \"../shared/config\";\n\nexport interface VerificationCommandResult {\n label: string;\n command: string;\n ok: boolean;\n stdout?: string;\n stderr?: string;\n error?: string;\n}\n\nexport interface RunVerificationResult {\n ok: boolean;\n target: string;\n commands: VerificationCommandResult[];\n diagnostics: string[];\n}\n\nexport function buildRunVerificationCommand(target: Target): string {\n return `pourkit run-verification --target ${target.name}`;\n}\n\nasync function runVerificationCommand(\n command: VerificationCommand,\n cwd: string,\n logger?: PourkitLogger\n): Promise<VerificationCommandResult> {\n try {\n const result = await execCapture(\"bash\", [\"-lc\", command.command], {\n cwd,\n logger,\n label: command.label,\n });\n return {\n label: command.label,\n command: command.command,\n ok: true,\n stdout: result.stdout,\n stderr: result.stderr,\n };\n } catch (error) {\n return {\n label: command.label,\n command: command.command,\n ok: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n}\n\nexport async function runVerificationCommands(options: {\n target: Target;\n cwd: string;\n logger?: PourkitLogger;\n}): Promise<RunVerificationResult> {\n const commands = getVerificationCommands(options.target);\n const diagnostics: string[] = [];\n\n if (commands.length === 0) {\n diagnostics.push(\n `No verification commands configured for target \\\"${options.target.name}\\\".`\n );\n return {\n ok: true,\n target: options.target.name,\n commands: [],\n diagnostics,\n };\n }\n\n const results: VerificationCommandResult[] = [];\n\n for (const command of commands) {\n const result = await runVerificationCommand(\n command,\n options.cwd,\n options.logger\n );\n results.push(result);\n if (!result.ok) {\n diagnostics.push(`Verification failed for \\\"${command.label}\\\".`);\n return {\n ok: false,\n target: options.target.name,\n commands: results,\n diagnostics,\n };\n }\n }\n\n diagnostics.push(\n `Verification passed for target \\\"${options.target.name}\\\".`\n );\n return {\n ok: true,\n target: options.target.name,\n commands: results,\n diagnostics,\n };\n}\n","const PROTECTED_WORK_RULE =\n \"Do **not** revert, delete, or substantially strip already-landed protected sibling/base work unless the issue explicitly requires those files.\";\n\nconst RUNNER_OWNED_GIT_RULE =\n \"Do **not** move Git history or reset the Worktree. Do not run `git reset --hard`, `git checkout .`, `git clean`, `git rebase`, `git merge`, `git branch -f`, or equivalent destructive history/worktree commands; branch/base changes are runner-owned.\";\n\nexport function appendProtectedWorkGuidance(promptBody: string): string {\n return `${promptBody}\n\n## Hard Rule\n\n- ${PROTECTED_WORK_RULE}\n- ${RUNNER_OWNED_GIT_RULE}`;\n}\n","import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"fs\";\nimport { dirname, join } from \"path\";\n\nexport const WORKTREE_RUN_STATE_PATH = \".pourkit/state.json\";\n\nexport type WorktreeRunStage =\n | \"builder\"\n | \"verification\"\n | \"review\"\n | \"issueFinalReview\"\n | \"refactor\"\n | \"finalizer\"\n | \"finalCommit\"\n | \"pr\"\n | \"baseRefresh\"\n | \"conflictResolution\";\n\nexport interface WorktreeRunState {\n issueNumber: number;\n targetName: string;\n branchName: string;\n baseBranch: string;\n createdAt: string;\n updatedAt: string;\n completedStages: {\n builder?: boolean;\n initialVerification?: boolean;\n };\n review: {\n lifetimeIterations: number;\n lastVerdict?:\n | \"PASS\"\n | \"PASS_WITH_NOTES\"\n | \"NEEDS_REFACTOR\"\n | \"FAIL\"\n | \"NEEDS_HUMAN\";\n lastArtifactPath?: string;\n refactorArtifactPaths?: string[];\n refactorCompletedForLastReview?: boolean;\n exhaustedPreviousRun?: boolean;\n };\n issueFinalReview?: {\n completed: boolean;\n verdict?: \"pass\" | \"needs_human_review\";\n artifactPath?: string;\n selfRetouched?: boolean;\n changedPaths?: string[];\n verificationPassed?: boolean;\n };\n finalizer?: {\n completed: boolean;\n artifactPath?: string;\n title?: string;\n body?: string;\n };\n finalCommit?: {\n completed: boolean;\n sha?: string;\n };\n pr?: {\n created: boolean;\n number?: number;\n url?: string;\n merged?: boolean;\n };\n lastFailure?: {\n stage: WorktreeRunStage;\n message: string;\n };\n}\n\nexport function readWorktreeRunState(\n worktreePath: string\n): WorktreeRunState | null {\n const statePath = join(worktreePath, WORKTREE_RUN_STATE_PATH);\n if (!existsSync(statePath)) {\n return null;\n }\n try {\n const raw = JSON.parse(readFileSync(statePath, \"utf-8\"));\n if (isValidWorktreeRunState(raw)) {\n return raw;\n }\n return null;\n } catch {\n return null;\n }\n}\n\nfunction isValidWorktreeRunState(raw: unknown): raw is WorktreeRunState {\n if (typeof raw !== \"object\" || raw === null) return false;\n const obj = raw as Record<string, unknown>;\n if (typeof obj.completedStages !== \"object\" || obj.completedStages === null)\n return false;\n if (typeof obj.review !== \"object\" || obj.review === null) return false;\n const review = obj.review as Record<string, unknown>;\n if (typeof review.lifetimeIterations !== \"number\") return false;\n return true;\n}\n\nexport function writeWorktreeRunState(\n worktreePath: string,\n state: WorktreeRunState\n): void {\n const statePath = join(worktreePath, WORKTREE_RUN_STATE_PATH);\n mkdirSync(dirname(statePath), { recursive: true });\n writeFileSync(statePath, JSON.stringify(state, null, 2), \"utf-8\");\n}\n\nexport function updateWorktreeRunState(\n worktreePath: string,\n update: Partial<WorktreeRunState>\n): void {\n const existing =\n readWorktreeRunState(worktreePath) ?? ({} as WorktreeRunState);\n const merged: WorktreeRunState = {\n ...existing,\n ...update,\n updatedAt: new Date().toISOString(),\n completedStages: {\n ...existing.completedStages,\n ...(update.completedStages ?? {}),\n },\n review: {\n ...existing.review,\n ...(update.review ?? {}),\n },\n issueFinalReview:\n update.issueFinalReview !== undefined\n ? { ...existing.issueFinalReview, ...update.issueFinalReview }\n : existing.issueFinalReview,\n finalizer:\n update.finalizer !== undefined\n ? { ...existing.finalizer, ...update.finalizer }\n : existing.finalizer,\n finalCommit:\n update.finalCommit !== undefined\n ? { ...existing.finalCommit, ...update.finalCommit }\n : existing.finalCommit,\n pr:\n update.pr !== undefined ? { ...existing.pr, ...update.pr } : existing.pr,\n };\n writeWorktreeRunState(worktreePath, merged);\n}\n","import { execCapture, type PourkitLogger } from \"../shared/common\";\nimport type { WorktreeRunState } from \"../shared/worktree-run-state\";\n\nexport type BaseRefreshResult =\n | { status: \"skipped-current\" }\n | { status: \"refreshed\" }\n | { status: \"conflicted\"; message: string; conflictedPaths: string[] }\n | {\n status: \"refused-published-history\";\n prNumber: number;\n prState: \"OPEN\" | \"CLOSED\" | \"MERGED\";\n };\n\nexport interface RefreshStaleIssueBranchOptions {\n worktreePath: string;\n baseBranch: string;\n localGitBaseRef: string;\n logger: PourkitLogger;\n prNumber?: number;\n prState?: \"OPEN\" | \"CLOSED\" | \"MERGED\";\n}\n\nasync function isIssueBranchStale(\n worktreePath: string,\n baseBranch: string,\n logger: PourkitLogger\n): Promise<boolean> {\n try {\n await execCapture(\n \"git\",\n [\"merge-base\", \"--is-ancestor\", baseBranch, \"HEAD\"],\n {\n cwd: worktreePath,\n logger,\n label: \"git merge-base --is-ancestor\",\n }\n );\n return false;\n } catch {\n return true;\n }\n}\n\nexport async function refreshStaleIssueBranch(\n options: RefreshStaleIssueBranchOptions\n): Promise<BaseRefreshResult> {\n const {\n worktreePath,\n baseBranch,\n localGitBaseRef,\n logger,\n prNumber,\n prState,\n } = options;\n\n const stale = await isIssueBranchStale(worktreePath, localGitBaseRef, logger);\n if (!stale) {\n return { status: \"skipped-current\" };\n }\n\n if (prNumber !== undefined && prState !== undefined) {\n return {\n status: \"refused-published-history\",\n prNumber,\n prState,\n };\n }\n\n try {\n await execCapture(\"git\", [\"rebase\", \"--autostash\", localGitBaseRef], {\n cwd: worktreePath,\n logger,\n label: \"git rebase --autostash\",\n });\n return { status: \"refreshed\" };\n } catch (error) {\n let conflictedPaths: string[] = [];\n try {\n const statusResult = await execCapture(\"git\", [\"status\", \"--porcelain\"], {\n cwd: worktreePath,\n logger,\n label: \"git status\",\n });\n conflictedPaths = statusResult.stdout\n .split(\"\\n\")\n .filter((line) => /^(AA|DD|UU|AU|UA|DU|UD)\\s/.test(line))\n .map((line) => line.slice(3).trim())\n .filter(Boolean);\n } catch {\n // Not critical; leave empty if we can't read status\n }\n return {\n status: \"conflicted\",\n message: error instanceof Error ? error.message : String(error),\n conflictedPaths,\n };\n }\n}\n\nexport function invalidateAfterBaseRefresh(\n state: WorktreeRunState\n): WorktreeRunState {\n return {\n issueNumber: state.issueNumber,\n targetName: state.targetName,\n branchName: state.branchName,\n baseBranch: state.baseBranch,\n createdAt: state.createdAt,\n updatedAt: new Date().toISOString(),\n completedStages: {\n builder: state.completedStages.builder,\n },\n review: {\n lifetimeIterations: 0,\n },\n };\n}\n","import { Effect, Exit } from \"effect\";\nimport { runEffect } from \"../shared/effect-runtime\";\nimport { refreshStaleIssueBranch } from \"../commands/base-refresh\";\nimport type { BaseRefreshResult } from \"../commands/base-refresh\";\nimport type { PourkitLogger } from \"../shared/common\";\nimport { RebaseConflict, PublishedHistoryRisk } from \"./types\";\nimport type { StageFailure } from \"./types\";\nimport { createStageAttemptId, recordStageAttempt } from \"./stage-attempt\";\nimport { computeFailureFingerprint } from \"../shared/attempt-log\";\n\nexport interface BaseRefreshOptions {\n worktreePath: string;\n baseBranch: string;\n localGitBaseRef: string;\n logger: PourkitLogger;\n prNumber?: number;\n prState?: \"OPEN\" | \"CLOSED\" | \"MERGED\";\n}\n\nexport interface BaseRefreshSuccess {\n readonly status: \"refreshed\" | \"skipped-current\";\n}\n\nfunction baseRefreshEffect(\n options: BaseRefreshOptions\n): Effect.Effect<BaseRefreshSuccess, StageFailure> {\n return Effect.promise(() => refreshStaleIssueBranch(options)).pipe(\n Effect.flatMap(\n (\n result: BaseRefreshResult\n ): Effect.Effect<BaseRefreshSuccess, StageFailure> => {\n switch (result.status) {\n case \"refreshed\":\n return Effect.succeed({ status: \"refreshed\" as const });\n case \"skipped-current\":\n return Effect.succeed({ status: \"skipped-current\" as const });\n case \"conflicted\":\n return Effect.fail(\n new RebaseConflict({\n conflictedPaths: result.conflictedPaths,\n message: result.message,\n })\n );\n case \"refused-published-history\":\n return Effect.fail(\n new PublishedHistoryRisk({\n prNumber: result.prNumber,\n prState: result.prState,\n })\n );\n }\n }\n )\n );\n}\n\n/**\n * Run a Base Refresh attempt through the shared Effect runtime boundary.\n *\n * This function is an **async adapter seam**: it constructs an Effect\n * program internally and executes it via the shared runtime (runEffect),\n * then returns Promise<Exit<...>> rather than Effect<...>.\n *\n * ## Why the async adapter seam exists\n * The caller (issue-run.ts) uses plain async/await and Exit pattern-matching.\n * Until the caller is itself migrated to Effect, this function preserves the\n * Promise<Exit<...>> interface so no caller changes are needed.\n *\n * ## Future migration\n * When issue-run.ts or its callers adopt Effect, this function can return\n * Effect.Effect<BaseRefreshSuccess, StageFailure> directly and the caller\n * can execute it through the shared runtime.\n */\nexport async function runBaseRefreshAttempt(\n options: BaseRefreshOptions\n): Promise<Exit.Exit<BaseRefreshSuccess, StageFailure>> {\n const attemptId = createStageAttemptId();\n const startedAt = new Date().toISOString();\n\n const program = baseRefreshEffect(options).pipe(\n Effect.tapBoth({\n onSuccess: (success) =>\n Effect.sync(() => {\n recordStageAttempt(options.worktreePath, {\n id: attemptId,\n stage: \"baseRefresh\",\n startedAt,\n completedAt: new Date().toISOString(),\n outcome: \"success\",\n });\n }),\n onFailure: (failure) =>\n Effect.sync(() => {\n recordStageAttempt(options.worktreePath, {\n id: attemptId,\n stage: \"baseRefresh\",\n startedAt,\n completedAt: new Date().toISOString(),\n outcome: \"failure\",\n failureFingerprint: computeFailureFingerprint(\n \"baseRefresh\",\n failure._tag\n ),\n failureType: failure._tag,\n });\n }),\n })\n );\n\n return runEffect(program);\n}\n","/**\n * Shared Effect runtime boundary initialized at CLI startup.\n *\n * ## Purpose\n * All control-plane Effect programs should be executed through this module\n * rather than calling Effect.runPromiseExit directly. This ensures the\n * runtime boundary lives at the CLI edge, not inside command or stage code.\n *\n * ## Usage\n * 1. Call initializeEffectRuntime() at CLI startup (see cli.ts main()).\n * 2. Import runEffect() in Effect control-plane code.\n * 3. Do NOT import Effect.runPromiseExit directly in control-plane modules.\n *\n * ## Design constraints\n * - Thin wrapper: no Effect layers, services, or configuration.\n * - Async adapter seam: returns Promise<Exit<A, E>>, not Effect<A, E>.\n */\nimport { Effect, Exit } from \"effect\";\nimport { UnknownException } from \"effect/Cause\";\n\nlet initialized = false;\n\nexport function initializeEffectRuntime(): void {\n if (initialized) return;\n initialized = true;\n}\n\nexport function isRuntimeInitialized(): boolean {\n return initialized;\n}\n\nexport function runEffect<E, A>(\n program: Effect.Effect<A, E>\n): Promise<Exit.Exit<A, E>> {\n ensureEffectRuntime();\n return Effect.runPromiseExit(program);\n}\n\nfunction ensureEffectRuntime(): void {\n if (!initialized) {\n initializeEffectRuntime();\n }\n}\n\nfunction unwrapError(error: unknown): unknown {\n if (error instanceof UnknownException && error.error !== undefined) {\n return error.error;\n }\n return error;\n}\n\nexport function runEffectAndMapExit<E, A>(\n program: Effect.Effect<A, E>\n): Promise<A> {\n return runEffect(program).then((exit) => {\n if (Exit.isSuccess(exit)) return exit.value;\n const cause = exit.cause;\n if (cause._tag === \"Fail\") {\n const error = unwrapError(cause.error);\n throw error instanceof Error ? error : new Error(String(error));\n }\n const defect =\n cause._tag === \"Die\"\n ? cause.defect\n : cause._tag === \"Interrupt\"\n ? \"interrupted\"\n : `unhandled cause: ${cause._tag}`;\n throw defect instanceof Error\n ? defect\n : new Error(`Unexpected defect: ${String(defect)}`);\n });\n}\n","// fallow-ignore-file unused-class-member\nexport type StageFailureTag =\n | \"BuilderFailure\"\n | \"CheckFailure\"\n | \"ConfigFailure\"\n | \"FailureResolutionAgentFailed\"\n | \"FinalizerFailure\"\n | \"GitHubFailure\"\n | \"MergeFailure\"\n | \"PublishedHistoryRisk\"\n | \"RebaseConflict\"\n | \"RecoveryArtifactInvalid\"\n | \"RefactorFailure\"\n | \"ReviewerFailure\"\n | \"SafetyFailure\";\n\nexport class RebaseConflict extends Error {\n readonly _tag: \"RebaseConflict\" = \"RebaseConflict\";\n readonly conflictedPaths: string[];\n readonly message: string;\n\n constructor(args: {\n readonly conflictedPaths: string[];\n readonly message: string;\n }) {\n super(args.message);\n this.name = \"RebaseConflict\";\n this.conflictedPaths = args.conflictedPaths;\n this.message = args.message;\n }\n}\n\nexport class PublishedHistoryRisk extends Error {\n readonly _tag: \"PublishedHistoryRisk\" = \"PublishedHistoryRisk\";\n readonly prNumber: number;\n readonly prState: \"OPEN\" | \"CLOSED\" | \"MERGED\";\n\n constructor(args: {\n readonly prNumber: number;\n readonly prState: \"OPEN\" | \"CLOSED\" | \"MERGED\";\n }) {\n super(`Published PR #${args.prNumber} is ${args.prState}`);\n this.name = \"PublishedHistoryRisk\";\n this.prNumber = args.prNumber;\n this.prState = args.prState;\n }\n}\n\nexport class RecoveryArtifactInvalid extends Error {\n readonly _tag: \"RecoveryArtifactInvalid\" = \"RecoveryArtifactInvalid\";\n readonly reason: string;\n\n constructor(args: { readonly reason: string }) {\n super(args.reason);\n this.name = \"RecoveryArtifactInvalid\";\n this.reason = args.reason;\n }\n}\n\nexport class FailureResolutionAgentFailed extends Error {\n readonly _tag: \"FailureResolutionAgentFailed\" =\n \"FailureResolutionAgentFailed\";\n readonly reason: string;\n\n constructor(args: { readonly reason: string }) {\n super(args.reason);\n this.name = \"FailureResolutionAgentFailed\";\n this.reason = args.reason;\n }\n}\n\nexport class GitHubFailure extends Error {\n readonly _tag: \"GitHubFailure\" = \"GitHubFailure\";\n readonly statusCode: number | undefined;\n readonly endpoint: string;\n readonly message: string;\n\n constructor(args: {\n readonly statusCode?: number;\n readonly endpoint: string;\n readonly message: string;\n }) {\n super(args.message);\n this.name = \"GitHubFailure\";\n this.statusCode = args.statusCode;\n this.endpoint = args.endpoint;\n this.message = args.message;\n }\n}\n\nexport class CheckFailure extends Error {\n readonly _tag: \"CheckFailure\" = \"CheckFailure\";\n readonly checkName: string;\n readonly exitCode?: number;\n readonly message: string;\n\n constructor(args: {\n readonly checkName: string;\n readonly exitCode?: number;\n readonly message: string;\n }) {\n super(args.message);\n this.name = \"CheckFailure\";\n this.checkName = args.checkName;\n this.exitCode = args.exitCode;\n this.message = args.message;\n }\n}\n\nexport class ConfigFailure extends Error {\n readonly _tag: \"ConfigFailure\" = \"ConfigFailure\";\n readonly configKey: string;\n readonly expectedType: string;\n readonly message: string;\n\n constructor(args: {\n readonly configKey: string;\n readonly expectedType: string;\n readonly message: string;\n }) {\n super(args.message);\n this.name = \"ConfigFailure\";\n this.configKey = args.configKey;\n this.expectedType = args.expectedType;\n this.message = args.message;\n }\n}\n\nexport class SafetyFailure extends Error {\n readonly _tag: \"SafetyFailure\" = \"SafetyFailure\";\n readonly sensitivityKind: \"auth\" | \"secrets\" | \"permissions\" | \"destructive\";\n readonly message: string;\n\n constructor(args: {\n readonly sensitivityKind:\n | \"auth\"\n | \"secrets\"\n | \"permissions\"\n | \"destructive\";\n readonly message: string;\n }) {\n super(args.message);\n this.name = \"SafetyFailure\";\n this.sensitivityKind = args.sensitivityKind;\n this.message = args.message;\n }\n}\n\nexport class BuilderFailure extends Error {\n readonly _tag: \"BuilderFailure\" = \"BuilderFailure\";\n readonly message: string;\n\n constructor(args: { readonly message: string }) {\n super(args.message);\n this.name = \"BuilderFailure\";\n this.message = args.message;\n }\n}\n\nexport class ReviewerFailure extends Error {\n readonly _tag: \"ReviewerFailure\" = \"ReviewerFailure\";\n readonly message: string;\n\n constructor(args: { readonly message: string }) {\n super(args.message);\n this.name = \"ReviewerFailure\";\n this.message = args.message;\n }\n}\n\nexport class RefactorFailure extends Error {\n readonly _tag: \"RefactorFailure\" = \"RefactorFailure\";\n readonly message: string;\n\n constructor(args: { readonly message: string }) {\n super(args.message);\n this.name = \"RefactorFailure\";\n this.message = args.message;\n }\n}\n\nexport class FinalizerFailure extends Error {\n readonly _tag: \"FinalizerFailure\" = \"FinalizerFailure\";\n readonly message: string;\n\n constructor(args: { readonly message: string }) {\n super(args.message);\n this.name = \"FinalizerFailure\";\n this.message = args.message;\n }\n}\n\nexport class MergeFailure extends Error {\n readonly _tag: \"MergeFailure\" = \"MergeFailure\";\n readonly prNumber?: number;\n readonly message: string;\n\n constructor(args: { readonly prNumber?: number; readonly message: string }) {\n super(args.message);\n this.name = \"MergeFailure\";\n this.prNumber = args.prNumber;\n this.message = args.message;\n }\n}\n\nexport type StageFailure =\n | BuilderFailure\n | CheckFailure\n | ConfigFailure\n | FailureResolutionAgentFailed\n | FinalizerFailure\n | GitHubFailure\n | MergeFailure\n | PublishedHistoryRisk\n | RebaseConflict\n | RecoveryArtifactInvalid\n | RefactorFailure\n | ReviewerFailure\n | SafetyFailure;\n\nexport type RecoveryDecision =\n | \"RETRY_STAGE\"\n | \"RESUME_FROM_STAGE\"\n | \"MARK_STAGE_COMPLETE\"\n | \"HANDOFF_TO_HUMAN\"\n | \"FAIL_RUN\";\n\nconst SUPPORTED_DECISIONS: ReadonlySet<string> = new Set([\n \"RETRY_STAGE\",\n \"HANDOFF_TO_HUMAN\",\n \"FAIL_RUN\",\n]);\n\nexport function isSupportedRecoveryDecision(\n decision: string\n): decision is RecoveryDecision {\n return SUPPORTED_DECISIONS.has(decision);\n}\n\nexport interface FailureResolutionPacket {\n readonly failureType: StageFailureTag;\n readonly stageName: string;\n readonly attemptNumber: number;\n readonly worktreePath: string;\n readonly branchName: string;\n readonly baseBranch: string;\n readonly conflictedPaths?: string[];\n readonly failureSummary: string;\n readonly maxAttempts: number;\n readonly allowedDecisions: readonly RecoveryDecision[];\n readonly artifactTarget: string;\n}\n\nexport interface RecoveryArtifactJson {\n readonly recoveryDecision: string;\n readonly summary: string;\n readonly changedFiles: readonly string[];\n readonly verificationSummary?: string;\n readonly verificationCommands?: readonly string[];\n readonly notes?: string;\n}\n\nexport interface RecoveryArtifact {\n readonly raw: string;\n readonly json: RecoveryArtifactJson;\n readonly path: string;\n}\n\nconst JSON_BLOCK_RE = /```json\\n([\\s\\S]*?)```/;\n\nexport function parseRecoveryArtifact(\n markdown: string,\n artifactPath: string\n): RecoveryArtifact {\n const match = JSON_BLOCK_RE.exec(markdown);\n if (!match) {\n throw new RecoveryArtifactInvalid({\n reason: `No JSON code block found in artifact at ${artifactPath}`,\n });\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(match[1]);\n } catch {\n throw new RecoveryArtifactInvalid({\n reason: `Malformed JSON in artifact at ${artifactPath}`,\n });\n }\n\n if (parsed === null || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n throw new RecoveryArtifactInvalid({\n reason: `Expected a JSON object in artifact at ${artifactPath}`,\n });\n }\n\n const json = parsed as Record<string, unknown>;\n\n if (\n typeof json.recoveryDecision !== \"string\" ||\n json.recoveryDecision === \"\"\n ) {\n throw new RecoveryArtifactInvalid({\n reason: `Missing or empty recoveryDecision in artifact at ${artifactPath}`,\n });\n }\n\n if (typeof json.summary !== \"string\" || json.summary === \"\") {\n throw new RecoveryArtifactInvalid({\n reason: `Missing or empty summary in artifact at ${artifactPath}`,\n });\n }\n\n const changedFiles = json.changedFiles;\n if (!Array.isArray(changedFiles)) {\n throw new RecoveryArtifactInvalid({\n reason: `changedFiles must be an array in artifact at ${artifactPath}`,\n });\n }\n if (!changedFiles.every((f: unknown) => typeof f === \"string\")) {\n throw new RecoveryArtifactInvalid({\n reason: `changedFiles must be an array of strings in artifact at ${artifactPath}`,\n });\n }\n\n if (\n json.verificationSummary !== undefined &&\n typeof json.verificationSummary !== \"string\"\n ) {\n throw new RecoveryArtifactInvalid({\n reason: `verificationSummary must be a string in artifact at ${artifactPath}`,\n });\n }\n\n if (json.notes !== undefined && typeof json.notes !== \"string\") {\n throw new RecoveryArtifactInvalid({\n reason: `notes must be a string in artifact at ${artifactPath}`,\n });\n }\n\n if (json.verificationCommands !== undefined) {\n if (!Array.isArray(json.verificationCommands)) {\n throw new RecoveryArtifactInvalid({\n reason: `verificationCommands must be an array in artifact at ${artifactPath}`,\n });\n }\n if (\n !json.verificationCommands.every((c: unknown) => typeof c === \"string\")\n ) {\n throw new RecoveryArtifactInvalid({\n reason: `verificationCommands must be an array of strings in artifact at ${artifactPath}`,\n });\n }\n }\n\n return {\n raw: markdown,\n json: {\n recoveryDecision: json.recoveryDecision,\n summary: json.summary,\n changedFiles: changedFiles as string[],\n verificationSummary: json.verificationSummary as string | undefined,\n verificationCommands: json.verificationCommands as string[] | undefined,\n notes: json.notes as string | undefined,\n },\n path: artifactPath,\n };\n}\n\nexport interface DecisionValidation {\n readonly valid: boolean;\n readonly decision?: RecoveryDecision;\n readonly reason?: string;\n}\n\nexport function validateRecoveryDecision(\n artifact: RecoveryArtifact,\n allowedDecisions: readonly RecoveryDecision[]\n): DecisionValidation {\n const decision = artifact.json.recoveryDecision;\n if (!allowedDecisions.includes(decision as RecoveryDecision)) {\n return {\n valid: false,\n reason: `Decision \"${decision}\" is not in allowed list: ${allowedDecisions.join(\", \")}`,\n };\n }\n if (!isSupportedRecoveryDecision(decision)) {\n return {\n valid: false,\n reason: `Decision \"${decision}\" is not supported in this slice`,\n };\n }\n return { valid: true, decision: decision as RecoveryDecision };\n}\n","import { appendFileSync, existsSync, mkdirSync, readFileSync } from \"fs\";\nimport { dirname, join } from \"path\";\n\nexport type AttemptLogEntryType = \"stage\" | \"recovery\";\nexport type AttemptOutcome = \"success\" | \"failure\" | \"handoff\";\n\nexport interface AttemptLogEntryBase {\n readonly attemptType: AttemptLogEntryType;\n readonly fingerprint: string;\n readonly timestamp: string;\n readonly stage: string;\n readonly outcome: AttemptOutcome;\n}\n\nexport interface StageAttemptEntry extends AttemptLogEntryBase {\n readonly attemptType: \"stage\";\n}\n\nexport interface RecoveryAttemptEntry extends AttemptLogEntryBase {\n readonly attemptType: \"recovery\";\n readonly artifactRef?: string;\n readonly decision?: string;\n}\n\nexport type AttemptLogEntry = StageAttemptEntry | RecoveryAttemptEntry;\n\nexport interface RecoveryBudget {\n readonly used: number;\n readonly remaining: number;\n readonly exhausted: boolean;\n}\n\nconst ATTEMPT_LOG_PATH = \".pourkit/attempt-log.jsonl\";\n\nexport function writeAttemptLog(\n worktreePath: string,\n entry: AttemptLogEntry\n): void {\n const logPath = join(worktreePath, ATTEMPT_LOG_PATH);\n mkdirSync(dirname(logPath), { recursive: true });\n appendFileSync(logPath, JSON.stringify(entry) + \"\\n\", \"utf-8\");\n}\n\nexport function readAttemptLog(worktreePath: string): AttemptLogEntry[] {\n const logPath = join(worktreePath, ATTEMPT_LOG_PATH);\n if (!existsSync(logPath)) {\n return [];\n }\n const raw = readFileSync(logPath, \"utf-8\");\n const lines = raw.split(\"\\n\").filter((l) => l.length > 0);\n const entries: AttemptLogEntry[] = [];\n for (const line of lines) {\n try {\n const parsed = JSON.parse(line);\n if (isValidAttemptLogEntry(parsed)) {\n entries.push(parsed);\n }\n } catch {\n // skip unparseable lines\n }\n }\n return entries;\n}\n\nfunction isValidAttemptLogEntry(raw: unknown): raw is AttemptLogEntry {\n if (typeof raw !== \"object\" || raw === null) return false;\n const obj = raw as Record<string, unknown>;\n if (obj.attemptType !== \"stage\" && obj.attemptType !== \"recovery\")\n return false;\n if (typeof obj.fingerprint !== \"string\") return false;\n if (typeof obj.timestamp !== \"string\") return false;\n if (typeof obj.stage !== \"string\") return false;\n if (\n obj.outcome !== \"success\" &&\n obj.outcome !== \"failure\" &&\n obj.outcome !== \"handoff\"\n )\n return false;\n return true;\n}\n\nexport function recoveryBudgetForFailure(\n worktreePath: string,\n fingerprint: string,\n maxAttempts: number\n): RecoveryBudget {\n const entries = readAttemptLog(worktreePath);\n const used = entries.filter(\n (e) => e.attemptType === \"recovery\" && e.fingerprint === fingerprint\n ).length;\n const remaining = Math.max(0, maxAttempts - used);\n return {\n used,\n remaining,\n exhausted: used >= maxAttempts,\n };\n}\n\nexport function computeFailureFingerprint(\n stage: string,\n failureType: string\n): string {\n return `${stage.toLowerCase()}:${failureType}`;\n}\n","import {\n writeAttemptLog,\n computeFailureFingerprint,\n} from \"../shared/attempt-log\";\n\nexport type StageAttemptId = string;\n\nexport interface StageAttemptRecord {\n readonly id: StageAttemptId;\n readonly stage: string;\n readonly startedAt: string;\n readonly completedAt?: string;\n readonly outcome?: \"success\" | \"failure\" | \"handoff\";\n readonly failureFingerprint?: string;\n readonly failureType?: string;\n}\n\nexport function createStageAttemptId(): StageAttemptId {\n return `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n}\n\nexport function recordStageAttempt(\n worktreePath: string,\n record: StageAttemptRecord\n): void {\n writeAttemptLog(worktreePath, {\n attemptType: \"stage\",\n fingerprint: record.failureFingerprint ?? `${record.stage}:success`,\n timestamp: record.completedAt ?? new Date().toISOString(),\n stage: record.stage,\n outcome:\n record.outcome === \"handoff\"\n ? \"handoff\"\n : record.outcome === \"success\"\n ? \"success\"\n : \"failure\",\n });\n}\n","import { existsSync, readFileSync } from \"fs\";\nimport { join } from \"path\";\nimport type { PourkitConfig, IssueData, Target } from \"../shared/config\";\nimport { resolvePromptTemplatePath } from \"../shared/config\";\nimport type { ExecutionProvider } from \"../execution/execution-provider\";\nimport { execCapture, type PourkitLogger } from \"../shared/common\";\nimport {\n buildRunContextArtifact,\n RUN_CONTEXT_PATH_IN_WORKTREE,\n STAGE_SECTIONS,\n} from \"../shared/run-context\";\nimport { parseConflictResolutionArtifact } from \"../conflicts/conflict-resolution-artifact\";\nimport { validateConflictResolutionArtifactAtPath } from \"./artifact-validation\";\n\nexport type ConflictResolutionRunResult =\n | { status: \"resolved\"; artifactPath: string; files: string[] }\n | { status: \"ambiguous\"; artifactPath: string; message: string }\n | { status: \"failed\"; artifactPath?: string; message: string };\n\nexport interface RunConflictResolutionOnceOptions {\n executionProvider: ExecutionProvider;\n config: PourkitConfig;\n target: Target;\n issue: IssueData;\n branchName: string;\n worktreePath: string;\n repoRoot: string;\n conflictedPaths: string[];\n attempt: number;\n logger: PourkitLogger;\n}\n\nfunction loadConflictResolutionPrompt(\n repoRoot: string,\n promptTemplate: string,\n artifactPath: string\n): string {\n const promptPath = resolvePromptTemplatePath(repoRoot, promptTemplate);\n const promptBody = existsSync(promptPath)\n ? readFileSync(promptPath, \"utf-8\")\n : promptTemplate;\n\n return `${promptBody}\n\n## Shared Run Context\n\nRead the selected issue requirements, comments, branch context, verification commands, and artifact paths from: ${RUN_CONTEXT_PATH_IN_WORKTREE}\n\n## Output\n\nWrite your resolution to: ${artifactPath}\n\nBefore handoff, run: pourkit validate-artifact conflict-resolution ${artifactPath}\n\nDo not provide a separate chat response. The runner only reads the file above.`;\n}\n\nexport async function runConflictResolutionOnce(\n options: RunConflictResolutionOnceOptions\n): Promise<ConflictResolutionRunResult> {\n const {\n executionProvider,\n config,\n target,\n issue,\n branchName,\n worktreePath,\n repoRoot,\n conflictedPaths,\n attempt,\n logger,\n } = options;\n\n const strategyCr = target.strategy.conflictResolution;\n if (!strategyCr) {\n return { status: \"failed\", message: \"No conflictResolution configured\" };\n }\n\n const artifactPath = `.pourkit/.tmp/conflict-resolution/attempt-${attempt}.md`;\n\n const prompt = loadConflictResolutionPrompt(\n repoRoot,\n strategyCr.promptTemplate,\n artifactPath\n );\n\n const runContextArtifact = buildRunContextArtifact({\n issue,\n target,\n branchName,\n sections: STAGE_SECTIONS.conflictResolution,\n });\n\n const executionResult = await executionProvider.execute({\n stage: \"conflictResolution\",\n agent: strategyCr.agent,\n model: strategyCr.model,\n variant: strategyCr.variant,\n env: strategyCr.env,\n prompt,\n target,\n repoRoot,\n branchName,\n sandbox: config.sandbox,\n autoApprove: true,\n worktreePath,\n artifactPath,\n artifacts: [runContextArtifact],\n logger,\n });\n\n if (!executionResult.success) {\n return {\n status: \"failed\",\n message:\n executionResult.error ?? \"Conflict resolution agent execution failed\",\n };\n }\n\n const fullArtifactPath = join(worktreePath, artifactPath);\n if (!existsSync(fullArtifactPath)) {\n return {\n status: \"failed\",\n artifactPath,\n message: \"Conflict resolution agent completed but did not write artifact\",\n };\n }\n\n let artifactContent: string;\n try {\n artifactContent = readFileSync(fullArtifactPath, \"utf-8\");\n } catch (error) {\n return {\n status: \"failed\",\n artifactPath,\n message: `Failed to read conflict resolution artifact: ${error instanceof Error ? error.message : String(error)}`,\n };\n }\n\n const validation = validateConflictResolutionArtifactAtPath({\n artifactPath,\n worktreePath,\n });\n if (!validation.ok) {\n return {\n status: \"failed\",\n artifactPath,\n message: `Invalid conflict resolution artifact: ${validation.reason}`,\n };\n }\n const parsed = parseConflictResolutionArtifact(artifactContent);\n\n if (parsed.status === \"ambiguous\") {\n return {\n status: \"ambiguous\",\n artifactPath,\n message: parsed.summary,\n };\n }\n\n return {\n status: \"resolved\",\n artifactPath,\n files: parsed.files,\n };\n}\n\nconst CONFLICT_MARKER_PATTERN = /<<<<<<<|=======|>>>>>>>/m;\n\nexport async function hasUnresolvedConflictMarkers(\n worktreePath: string,\n files: string[]\n): Promise<boolean> {\n for (const file of files) {\n const filePath = join(worktreePath, file);\n try {\n const content = readFileSync(filePath, \"utf-8\");\n if (CONFLICT_MARKER_PATTERN.test(content)) {\n return true;\n }\n } catch {\n // File not found or unreadable — skip\n }\n }\n return false;\n}\n\nexport type ConflictResolutionLoopResult =\n | { status: \"completed\"; attempts: number }\n | { status: \"ambiguous\"; attempts: number; message: string }\n | { status: \"failed\"; attempts: number; message: string }\n | { status: \"exhausted\"; attempts: number; message: string };\n\nexport async function runConflictResolutionLoop(\n options: Omit<\n RunConflictResolutionOnceOptions,\n \"conflictedPaths\" | \"attempt\"\n > & {\n maxAttempts: number;\n initialConflictedPaths: string[];\n }\n): Promise<ConflictResolutionLoopResult> {\n const { worktreePath, maxAttempts, logger, initialConflictedPaths } = options;\n let attempt = 0;\n let conflictedPaths = initialConflictedPaths;\n\n while (attempt < maxAttempts && conflictedPaths.length > 0) {\n attempt++;\n\n const crResult = await runConflictResolutionOnce({\n ...options,\n conflictedPaths,\n attempt,\n });\n\n if (crResult.status !== \"resolved\") {\n const message =\n crResult.status === \"ambiguous\"\n ? crResult.message\n : (crResult.message ?? \"Conflict resolution agent execution failed\");\n return { status: crResult.status, attempts: attempt, message };\n }\n\n const markersRemain = await hasUnresolvedConflictMarkers(\n worktreePath,\n conflictedPaths\n );\n if (markersRemain) {\n return {\n status: \"ambiguous\",\n attempts: attempt,\n message:\n \"Conflict resolution agent resolved artifact but conflict markers remain in files\",\n };\n }\n\n await execCapture(\"git\", [\"add\", ...conflictedPaths], {\n cwd: worktreePath,\n logger,\n label: \"git add conflicted paths\",\n });\n\n try {\n await execCapture(\"git\", [\"rebase\", \"--continue\"], {\n cwd: worktreePath,\n logger,\n label: \"git rebase --continue\",\n });\n conflictedPaths = [];\n } catch (error) {\n const statusResult = await execCapture(\"git\", [\"status\", \"--porcelain\"], {\n cwd: worktreePath,\n logger,\n label: \"git status\",\n });\n conflictedPaths = statusResult.stdout\n .split(\"\\n\")\n .filter((line) => /^(AA|DD|UU|AU|UA|DU|UD)\\s/.test(line))\n .map((line) => line.slice(3).trim())\n .filter(Boolean);\n\n if (conflictedPaths.length === 0) {\n const rebaseErrorMessage =\n error instanceof Error ? error.message : String(error);\n return {\n status: \"failed\",\n attempts: attempt,\n message: `git rebase --continue failed with no remaining conflicts: ${rebaseErrorMessage}`,\n };\n }\n }\n }\n\n if (conflictedPaths.length > 0) {\n return {\n status: \"exhausted\",\n attempts: attempt,\n message: `Conflict resolution maxAttempts (${maxAttempts}) exhausted with remaining conflicts`,\n };\n }\n\n return { status: \"completed\", attempts: attempt };\n}\n","export type ConflictResolutionArtifactStatus = \"resolved\" | \"ambiguous\";\n\nexport interface ConflictResolutionVerificationRow {\n command: string;\n result: string;\n notes: string;\n}\n\nexport interface ConflictResolutionArtifact {\n status: ConflictResolutionArtifactStatus;\n summary: string;\n files: string[];\n verification?: ConflictResolutionVerificationRow[];\n raw: string;\n}\n\nexport class ConflictResolutionArtifactProtocolError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ConflictResolutionArtifactProtocolError\";\n }\n}\n\nconst VALID_STATUSES: ConflictResolutionArtifactStatus[] = [\n \"resolved\",\n \"ambiguous\",\n];\n\nconst SECTION_HEADING_PATTERN = /^## (Status|Summary|Files|Verification)\\s*$/gm;\n\ninterface SectionMatch {\n heading: \"Status\" | \"Summary\" | \"Files\" | \"Verification\";\n startIndex: number;\n endIndex: number;\n}\n\nfunction extractSections(output: string): SectionMatch[] {\n const sections: SectionMatch[] = [];\n let match: RegExpExecArray | null;\n const re = new RegExp(SECTION_HEADING_PATTERN);\n while ((match = re.exec(output)) !== null) {\n const heading = match[1] as \"Status\" | \"Summary\" | \"Files\" | \"Verification\";\n sections.push({\n heading,\n startIndex: match.index,\n endIndex: match.index + match[0].length,\n });\n }\n return sections;\n}\n\nfunction contentAfter(\n output: string,\n sections: SectionMatch[],\n section: SectionMatch\n): string {\n const index = sections.indexOf(section);\n const nextSection = sections[index + 1];\n const start = section.endIndex;\n const end = nextSection?.startIndex ?? output.length;\n return output.slice(start, end).trim();\n}\n\nfunction extractMarker(output: string): string | null {\n const matches = output.matchAll(\n /<conflict-resolution>\\s*(resolved|ambiguous)\\s*<\\/conflict-resolution>/g\n );\n const results = Array.from(matches);\n if (results.length > 1) {\n throw new ConflictResolutionArtifactProtocolError(\n \"Duplicate <conflict-resolution>...</conflict-resolution> markers\"\n );\n }\n return results.length === 1 ? results[0][1] : null;\n}\n\nfunction parseFileList(filesContent: string): string[] {\n return filesContent\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter((line) => line.startsWith(\"- \"))\n .map((line) => {\n const rest = line.slice(2).trim();\n const codeMatch = rest.match(/^`([^`]+)`/);\n return codeMatch ? codeMatch[1] : rest;\n });\n}\n\nfunction parseVerificationTable(\n content: string\n): ConflictResolutionVerificationRow[] {\n const lines = content\n .split(\"\\n\")\n .map((l) => l.trim())\n .filter(Boolean);\n const tableLines = lines.filter((l) => l.startsWith(\"|\") && l.endsWith(\"|\"));\n\n // index 0 = heading row, index 1 = separator row, index 2+ = data rows\n const dataRows = tableLines.slice(2);\n\n return dataRows.map((row) => {\n const cells = row\n .split(\"|\")\n .slice(1, -1)\n .map((c) => c.trim());\n return {\n command: cells[0] ?? \"\",\n result: cells[1] ?? \"\",\n notes: cells[2] ?? \"\",\n };\n });\n}\n\nexport function parseConflictResolutionArtifact(\n output: string\n): ConflictResolutionArtifact {\n if (!output.trim()) {\n throw new ConflictResolutionArtifactProtocolError(\n \"Empty conflict resolution artifact output\"\n );\n }\n\n const sections = extractSections(output);\n\n const statusSections = sections.filter((s) => s.heading === \"Status\");\n const summarySections = sections.filter((s) => s.heading === \"Summary\");\n const filesSections = sections.filter((s) => s.heading === \"Files\");\n\n if (statusSections.length > 1) {\n throw new ConflictResolutionArtifactProtocolError(\n 'Duplicate \"## Status\" sections'\n );\n }\n if (summarySections.length > 1) {\n throw new ConflictResolutionArtifactProtocolError(\n 'Duplicate \"## Summary\" sections'\n );\n }\n if (filesSections.length > 1) {\n throw new ConflictResolutionArtifactProtocolError(\n 'Duplicate \"## Files\" sections'\n );\n }\n\n const verificationSections = sections.filter(\n (s) => s.heading === \"Verification\"\n );\n\n const statusSection = statusSections[0];\n const summarySection = summarySections[0];\n const filesSection = filesSections[0];\n\n if (!statusSection) {\n throw new ConflictResolutionArtifactProtocolError(\n 'Missing required section \"## Status\"'\n );\n }\n if (!summarySection) {\n throw new ConflictResolutionArtifactProtocolError(\n 'Missing required section \"## Summary\"'\n );\n }\n if (!filesSection) {\n throw new ConflictResolutionArtifactProtocolError(\n 'Missing required section \"## Files\"'\n );\n }\n\n const statusRaw = contentAfter(output, sections, statusSection);\n const summary = contentAfter(output, sections, summarySection);\n const filesContent = contentAfter(output, sections, filesSection);\n\n if (!statusRaw) {\n throw new ConflictResolutionArtifactProtocolError(\n '\"## Status\" section is empty'\n );\n }\n if (!summary) {\n throw new ConflictResolutionArtifactProtocolError(\n '\"## Summary\" section is empty'\n );\n }\n\n if (!VALID_STATUSES.includes(statusRaw as ConflictResolutionArtifactStatus)) {\n throw new ConflictResolutionArtifactProtocolError(\n `Unsupported status \"${statusRaw}\". Allowed statuses: ${VALID_STATUSES.join(\", \")}`\n );\n }\n\n const markerStatus = extractMarker(output);\n if (!markerStatus) {\n throw new ConflictResolutionArtifactProtocolError(\n \"Missing <conflict-resolution>...</conflict-resolution> marker\"\n );\n }\n\n if (markerStatus !== statusRaw) {\n throw new ConflictResolutionArtifactProtocolError(\n `Conflict resolution status \"${statusRaw}\" does not match marker \"${markerStatus}\"`\n );\n }\n\n let verification: ConflictResolutionVerificationRow[] | undefined;\n if (verificationSections.length > 0) {\n const verificationContent = contentAfter(\n output,\n sections,\n verificationSections[0]\n );\n verification = parseVerificationTable(verificationContent);\n }\n\n return {\n status: statusRaw as ConflictResolutionArtifactStatus,\n summary,\n files: parseFileList(filesContent),\n verification,\n raw: output,\n };\n}\n","import { createHash } from \"node:crypto\";\nimport { execSync } from \"node:child_process\";\nimport { existsSync, readdirSync, readFileSync } from \"node:fs\";\nimport { isAbsolute, join, resolve } from \"node:path\";\nimport {\n parseReviewVerdict,\n ReviewVerdictProtocolError,\n} from \"../pr/review-verdict\";\nimport {\n extractLatestFindingIds,\n ReviewArtifactValidationError,\n validateRefactorArtifact,\n validateReviewArtifact,\n} from \"./review\";\nimport {\n parsePrDescription,\n PrDescriptionProtocolError,\n} from \"../pr/pr-description\";\nimport {\n ConflictResolutionArtifactProtocolError,\n parseConflictResolutionArtifact,\n} from \"../conflicts/conflict-resolution-artifact\";\nimport {\n parseRecoveryArtifact,\n type RecoveryDecision,\n RecoveryArtifactInvalid,\n validateRecoveryDecision,\n} from \"../failure-resolution/types\";\n\nexport type ArtifactValidationKind =\n | \"reviewer\"\n | \"refactor\"\n | \"finalizer\"\n | \"conflict-resolution\"\n | \"failure-resolution\"\n | \"local-prd\"\n | \"local-issue\"\n | \"local-triage\"\n | \"local-prepare\"\n | \"issue-final-review\";\n\nexport type ArtifactValidationResult =\n | {\n ok: true;\n kind: ArtifactValidationKind;\n artifactPath: string;\n diagnostics: string[];\n }\n | {\n ok: false;\n kind: ArtifactValidationKind;\n artifactPath: string;\n reason: string;\n diagnostics: string[];\n };\n\nexport interface ValidateAgentArtifactOptions {\n kind: ArtifactValidationKind;\n artifactPath: string;\n iteration?: number;\n priorRefactorArtifactsProvided?: boolean;\n findingIds?: string[];\n latestReviewArtifactPath?: string;\n allowedDecisions?: RecoveryDecision[];\n worktreePath?: string;\n checkConflictMarkers?: boolean;\n issueNumber?: number;\n branchName?: string;\n}\n\nconst CONFLICT_MARKER_PATTERN = /<<<<<<<|=======|>>>>>>>/m;\n\nfunction invalid(\n options: ValidateAgentArtifactOptions,\n reason: string,\n diagnostics: string[] = []\n): ArtifactValidationResult {\n return {\n ok: false,\n kind: options.kind,\n artifactPath: options.artifactPath,\n reason,\n diagnostics,\n };\n}\n\nfunction valid(\n options: ValidateAgentArtifactOptions,\n diagnostics: string[] = []\n): ArtifactValidationResult {\n return {\n ok: true,\n kind: options.kind,\n artifactPath: options.artifactPath,\n diagnostics,\n };\n}\n\nfunction readArtifact(\n options: ValidateAgentArtifactOptions\n):\n | { ok: true; content: string }\n | { ok: false; result: ArtifactValidationResult } {\n if (!existsSync(options.artifactPath)) {\n return {\n ok: false,\n result: invalid(options, `Artifact missing at ${options.artifactPath}`),\n };\n }\n\n try {\n const content = readFileSync(options.artifactPath, \"utf-8\");\n if (!content.trim()) {\n return { ok: false, result: invalid(options, \"Artifact is empty\") };\n }\n return { ok: true, content };\n } catch (error) {\n return {\n ok: false,\n result: invalid(options, \"Artifact could not be read\", [\n error instanceof Error ? error.message : String(error),\n ]),\n };\n }\n}\n\nfunction validateIssueFinalReviewArtifact(\n parsed: Record<string, unknown>,\n options: ValidateAgentArtifactOptions\n):\n | { ok: true; verdict: string }\n | { ok: false; reason: string; diagnostics: string[] } {\n const diagnostics: string[] = [];\n\n // kind\n if (parsed.kind !== \"issue-final-review\") {\n return {\n ok: false,\n reason: `Artifact kind must be \"issue-final-review\", got ${JSON.stringify(parsed.kind)}`,\n diagnostics,\n };\n }\n diagnostics.push(\"kind: issue-final-review\");\n\n // issueNumber\n if (parsed.issueNumber !== options.issueNumber) {\n return {\n ok: false,\n reason: `Artifact issueNumber ${JSON.stringify(parsed.issueNumber)} does not match expected ${options.issueNumber}`,\n diagnostics,\n };\n }\n diagnostics.push(`issueNumber: ${options.issueNumber}`);\n\n // branchName\n if (parsed.branchName !== options.branchName) {\n return {\n ok: false,\n reason: `Artifact branchName ${JSON.stringify(parsed.branchName)} does not match expected ${JSON.stringify(options.branchName)}`,\n diagnostics,\n };\n }\n diagnostics.push(`branchName: ${options.branchName}`);\n\n // verdict\n const allowedVerdicts = [\"pass\", \"needs_human_review\"];\n if (!allowedVerdicts.includes(parsed.verdict as string)) {\n return {\n ok: false,\n reason: `Verdict must be \"pass\" or \"needs_human_review\", got ${JSON.stringify(parsed.verdict)}`,\n diagnostics: [\n ...diagnostics,\n `verdict: ${JSON.stringify(parsed.verdict)}`,\n ],\n };\n }\n diagnostics.push(`verdict: ${parsed.verdict}`);\n\n // summary\n if (typeof parsed.summary !== \"string\" || parsed.summary.trim() === \"\") {\n return {\n ok: false,\n reason: \"Summary must be a non-empty string\",\n diagnostics,\n };\n }\n diagnostics.push(\"summary: present\");\n\n // changedPaths\n if (\n !Array.isArray(parsed.changedPaths) ||\n !parsed.changedPaths.every((p: unknown) => typeof p === \"string\")\n ) {\n return {\n ok: false,\n reason: \"changedPaths must be an array of strings\",\n diagnostics,\n };\n }\n for (const p of parsed.changedPaths as string[]) {\n const normalized = p.replace(/\\\\/g, \"/\");\n const segments = normalized.split(\"/\");\n if (\n normalized.trim() === \"\" ||\n normalized === \".\" ||\n normalized === \"..\" ||\n isAbsolute(p) ||\n normalized.startsWith(\"/\") ||\n segments.some((segment) => segment === \"..\")\n ) {\n return {\n ok: false,\n reason: `changedPaths must not contain absolute paths or path traversal: ${p}`,\n diagnostics,\n };\n }\n }\n diagnostics.push(\n `changedPaths: ${(parsed.changedPaths as string[]).length} paths`\n );\n\n // selfRetouched\n if (typeof parsed.selfRetouched !== \"boolean\") {\n return {\n ok: false,\n reason: \"selfRetouched must be a boolean\",\n diagnostics,\n };\n }\n diagnostics.push(`selfRetouched: ${parsed.selfRetouched}`);\n\n // verification object\n const verification = parsed.verification as\n | Record<string, unknown>\n | undefined;\n if (!verification || typeof verification !== \"object\") {\n return {\n ok: false,\n reason: \"verification must be an object\",\n diagnostics,\n };\n }\n if (typeof verification.required !== \"boolean\") {\n return {\n ok: false,\n reason: \"verification.required must be a boolean\",\n diagnostics,\n };\n }\n if (typeof verification.passed !== \"boolean\") {\n return {\n ok: false,\n reason: \"verification.passed must be a boolean\",\n diagnostics,\n };\n }\n if (\n !Array.isArray(verification.commands) ||\n !verification.commands.every((c: unknown) => typeof c === \"string\")\n ) {\n return {\n ok: false,\n reason: \"verification.commands must be an array of strings\",\n diagnostics,\n };\n }\n if (typeof verification.summary !== \"string\") {\n return {\n ok: false,\n reason: \"verification.summary must be a string\",\n diagnostics,\n };\n }\n diagnostics.push(\"verification: present\");\n\n // self-retouched pass requires verification passed\n if (parsed.selfRetouched === true && parsed.verdict === \"pass\") {\n if (verification.required !== true || verification.passed !== true) {\n return {\n ok: false,\n reason:\n \"Self-retouched pass requires verification.required === true and verification.passed === true\",\n diagnostics: [\n ...diagnostics,\n `verification.required: ${verification.required}`,\n `verification.passed: ${verification.passed}`,\n ],\n };\n }\n diagnostics.push(\"self-retouched verification: valid\");\n }\n\n // needs_human_review requires needsHumanReason\n if (parsed.verdict === \"needs_human_review\") {\n if (\n typeof parsed.needsHumanReason !== \"string\" ||\n parsed.needsHumanReason.trim() === \"\"\n ) {\n return {\n ok: false,\n reason:\n \"needs_human_review verdict requires non-empty needsHumanReason\",\n diagnostics,\n };\n }\n diagnostics.push(\"needsHumanReason: present\");\n }\n\n return { ok: true, verdict: parsed.verdict as string };\n}\n\nexport function validateAgentArtifact(\n options: ValidateAgentArtifactOptions\n): ArtifactValidationResult {\n const artifact = readArtifact(options);\n if (!artifact.ok) return artifact.result;\n\n try {\n switch (options.kind) {\n case \"reviewer\": {\n const iteration = options.iteration ?? 1;\n const verdict = parseReviewVerdict(artifact.content);\n validateReviewArtifact(\n artifact.content,\n verdict,\n iteration,\n options.priorRefactorArtifactsProvided ?? false\n );\n return valid(options, [`verdict: ${verdict}`]);\n }\n\n case \"refactor\": {\n let findingIds = options.findingIds ?? [];\n if (findingIds.length === 0 && options.latestReviewArtifactPath) {\n const latestReview = readFileSync(\n options.latestReviewArtifactPath,\n \"utf-8\"\n );\n findingIds = extractLatestFindingIds(\n latestReview,\n options.iteration ?? 1\n );\n }\n validateRefactorArtifact(options.artifactPath, findingIds);\n return valid(options, [\n `findingIds: ${findingIds.join(\", \") || \"none\"}`,\n ]);\n }\n\n case \"finalizer\": {\n const parsed = parsePrDescription(artifact.content);\n return valid(options, [`title: ${parsed.title}`]);\n }\n\n case \"conflict-resolution\": {\n const parsed = parseConflictResolutionArtifact(artifact.content);\n if (\n options.checkConflictMarkers !== false &&\n parsed.status === \"resolved\"\n ) {\n const base = options.worktreePath ?? process.cwd();\n const filesWithMarkers = parsed.files.filter((file) => {\n const filePath = resolve(base, file);\n try {\n return CONFLICT_MARKER_PATTERN.test(\n readFileSync(filePath, \"utf-8\")\n );\n } catch {\n return false;\n }\n });\n if (filesWithMarkers.length > 0) {\n return invalid(\n options,\n \"Conflict resolution artifact is resolved but conflict markers remain\",\n filesWithMarkers.map((file) => `marker remains: ${file}`)\n );\n }\n }\n return valid(options, [`status: ${parsed.status}`]);\n }\n\n case \"issue-final-review\": {\n if (options.issueNumber === undefined || !options.branchName) {\n return invalid(\n options,\n \"Issue Final Review artifact validation requires --issue-number and --branch-name.\"\n );\n }\n const parsed = JSON.parse(artifact.content);\n if (\n parsed === null ||\n typeof parsed !== \"object\" ||\n Array.isArray(parsed)\n ) {\n return invalid(\n options,\n `Artifact must be a JSON object, got ${Array.isArray(parsed) ? \"array\" : parsed === null ? \"null\" : typeof parsed}`\n );\n }\n const result = validateIssueFinalReviewArtifact(parsed, options);\n if (!result.ok) {\n return invalid(options, result.reason, result.diagnostics);\n }\n return valid(options, [`verdict: ${result.verdict}`]);\n }\n\n case \"failure-resolution\": {\n const parsed = parseRecoveryArtifact(\n artifact.content,\n options.artifactPath\n );\n if (options.allowedDecisions && options.allowedDecisions.length > 0) {\n const decision = validateRecoveryDecision(\n parsed,\n options.allowedDecisions\n );\n if (!decision.valid) {\n return invalid(\n options,\n decision.reason ?? \"Recovery decision invalid\"\n );\n }\n }\n return valid(options, [`decision: ${parsed.json.recoveryDecision}`]);\n }\n\n case \"local-prd\":\n case \"local-issue\":\n case \"local-triage\":\n return invalid(\n options,\n `Local artifact kind must be validated through runLocalValidateArtifactCommand`\n );\n\n case \"local-prepare\":\n return invalid(\n options,\n `Artifact kind \"${options.kind}\" has been removed from PRD Run validation`\n );\n }\n } catch (error) {\n if (\n error instanceof ReviewArtifactValidationError ||\n error instanceof ReviewVerdictProtocolError ||\n error instanceof PrDescriptionProtocolError ||\n error instanceof ConflictResolutionArtifactProtocolError ||\n error instanceof RecoveryArtifactInvalid ||\n error instanceof Error\n ) {\n return invalid(options, error.message);\n }\n throw error;\n }\n}\n\nexport function runValidateArtifactCommand(options: {\n kind: ArtifactValidationKind;\n artifactPath: string;\n repoRoot: string;\n iteration?: number;\n priorRefactorArtifactsProvided?: boolean;\n findingIds?: string[];\n latestReviewArtifactPath?: string;\n allowedDecisions?: RecoveryDecision[];\n checkConflictMarkers?: boolean;\n issueNumber?: number;\n branchName?: string;\n}): ArtifactValidationResult {\n const artifactPath = resolve(options.repoRoot, options.artifactPath);\n const latestReviewArtifactPath = options.latestReviewArtifactPath\n ? resolve(options.repoRoot, options.latestReviewArtifactPath)\n : undefined;\n\n return validateAgentArtifact({\n ...options,\n artifactPath,\n latestReviewArtifactPath,\n worktreePath: options.repoRoot,\n });\n}\n\nexport function runLocalValidateArtifactCommand(options: {\n kind: ArtifactValidationKind;\n artifactPath: string;\n repoRoot: string;\n extraArgs?: string[];\n}): ArtifactValidationResult {\n const resolvedPath = resolve(options.repoRoot, options.artifactPath);\n const resolvedExtra = (options.extraArgs ?? []).map((p) =>\n isAbsolute(p) ? p : resolve(options.repoRoot, p)\n );\n\n let localResult: LocalValidationResult;\n switch (options.kind) {\n case \"local-prd\":\n localResult = validateLocalPrd(resolvedPath);\n break;\n case \"local-issue\":\n localResult = validateLocalIssue(resolvedPath);\n break;\n case \"local-triage\":\n localResult = validateLocalTriage(resolvedPath, resolvedExtra);\n break;\n default:\n return {\n ok: false,\n kind: options.kind,\n artifactPath: resolvedPath,\n reason: `Unsupported local artifact kind \"${options.kind}\"`,\n diagnostics: [],\n };\n }\n\n if (localResult.ok) {\n return {\n ok: true,\n kind: options.kind,\n artifactPath: resolvedPath,\n diagnostics: [],\n };\n }\n\n const diagnostics: string[] = [];\n if (localResult.gate) diagnostics.push(`gate: ${localResult.gate}`);\n if (localResult.failureCode)\n diagnostics.push(`failureCode: ${localResult.failureCode}`);\n if (localResult.offendingPath)\n diagnostics.push(`offendingPath: ${localResult.offendingPath}`);\n if (localResult.message) diagnostics.push(localResult.message);\n\n return {\n ok: false,\n kind: options.kind,\n artifactPath: resolvedPath,\n reason: localResult.message ?? \"Validation failed\",\n diagnostics,\n };\n}\n\n// ---- Local artifact validation foundation ----\n\nexport type LocalValidationFailureCode =\n | \"missing_store\"\n | \"invalid_prd_artifact\"\n | \"invalid_issue_artifact\"\n | \"linkage_mismatch\"\n | \"triage_inconsistent\"\n | \"branch_unsafe\"\n | \"dirty_worktree\"\n | \"stale_projection\"\n | \"missing_projection\"\n | \"body_hash_mismatch\";\n\nexport interface LocalValidationResult {\n ok: boolean;\n gate?: string;\n failureCode?: LocalValidationFailureCode;\n offendingPath?: string;\n message?: string;\n}\n\n// ---- Local prepare validation ----\n\nexport type LocalPrepareGate =\n | \"store_shape\"\n | \"prd_json_completeness\"\n | \"issue_json_completeness\"\n | \"parent_child_linkage\"\n | \"triage_consistency\"\n | \"branch_safety\"\n | \"projection_freshness\";\n\nexport interface LocalPrepareOptions {\n storePath?: string;\n repoRoot?: string;\n}\n\nfunction getLocalPrepareStorePath(\n repoRoot: string,\n prdPath: string\n): string | undefined {\n const prd = readLocalArtifact<Record<string, unknown>>(prdPath);\n if (!prd.ok || !prd.data || typeof prd.data.id !== \"string\") {\n return undefined;\n }\n return join(repoRoot, \".pourkit\", \"local-prd-runs\", prd.data.id);\n}\n\nexport function validateLocalPrepare(\n prdPath: string,\n issuePaths: string[],\n options?: LocalPrepareOptions\n): LocalValidationResult {\n // Gate 1: Store shape\n let storePath: string;\n if (options?.storePath) {\n storePath = options.storePath;\n } else {\n const prdRaw = readLocalArtifact<Record<string, unknown>>(prdPath);\n if (!prdRaw.ok || !prdRaw.data) {\n return {\n ok: false,\n gate: \"store_shape\",\n failureCode: \"missing_store\",\n offendingPath: prdPath,\n message: \"Cannot read PRD artifact to determine store path\",\n };\n }\n const prdId = prdRaw.data.id;\n if (typeof prdId !== \"string\") {\n return {\n ok: false,\n gate: \"store_shape\",\n failureCode: \"missing_store\",\n message: \"PRD id must be a string to determine store path\",\n };\n }\n storePath = `.pourkit/local-prd-runs/${prdId}/`;\n }\n\n if (!existsSync(storePath)) {\n return {\n ok: false,\n gate: \"store_shape\",\n failureCode: \"missing_store\",\n offendingPath: storePath,\n message: `Local PRD Run Store not found at ${storePath}`,\n };\n }\n\n const issuesStore = join(storePath, \"issues\");\n if (!existsSync(issuesStore)) {\n return {\n ok: false,\n gate: \"store_shape\",\n failureCode: \"missing_store\",\n offendingPath: issuesStore,\n message: `Store at ${storePath} is missing expected subdirectory: issues`,\n };\n }\n\n const prdsStore = join(storePath, \"prds\");\n if (!existsSync(prdsStore)) {\n return {\n ok: false,\n gate: \"store_shape\",\n failureCode: \"missing_store\",\n offendingPath: prdsStore,\n message: `Store at ${storePath} is missing expected subdirectory: prds`,\n };\n }\n\n // Gate 2: PRD JSON completeness\n const prdResult = validateLocalPrd(prdPath);\n if (!prdResult.ok) {\n return { ...prdResult, gate: \"prd_json_completeness\" };\n }\n\n // Gate 3: Issue JSON completeness\n for (const issuePath of issuePaths) {\n const issueResult = validateLocalIssue(issuePath);\n if (!issueResult.ok) {\n return { ...issueResult, gate: \"issue_json_completeness\" };\n }\n }\n\n // Gate 4: Parent/child linkage\n const prd = readLocalArtifact<Record<string, unknown>>(prdPath);\n if (!prd.ok || !prd.data) {\n return {\n ok: false,\n gate: \"parent_child_linkage\",\n failureCode: \"linkage_mismatch\",\n offendingPath: prdPath,\n message: \"Cannot read PRD for linkage check\",\n };\n }\n\n const prdId = prd.data.id as string;\n const childIssueIds = (prd.data.childIssueIds as string[]) ?? [];\n\n const issueDataMap = new Map<string, Record<string, unknown>>();\n for (const issuePath of issuePaths) {\n const issue = readLocalArtifact<Record<string, unknown>>(issuePath);\n if (!issue.ok || !issue.data) {\n return {\n ok: false,\n gate: \"parent_child_linkage\",\n failureCode: \"linkage_mismatch\",\n offendingPath: issuePath,\n message: `Cannot read Issue for linkage check: ${issue.message}`,\n };\n }\n const issueId = issue.data.id as string;\n issueDataMap.set(issueId, issue.data);\n\n if (issue.data.parentPrdId !== prdId) {\n return {\n ok: false,\n gate: \"parent_child_linkage\",\n failureCode: \"linkage_mismatch\",\n offendingPath: issuePath,\n message: `Issue ${issueId} parentPrdId \"${issue.data.parentPrdId}\" does not match PRD id \"${prdId}\"`,\n };\n }\n }\n\n for (const childId of childIssueIds) {\n if (!issueDataMap.has(childId)) {\n return {\n ok: false,\n gate: \"parent_child_linkage\",\n failureCode: \"linkage_mismatch\",\n message: `PRD childIssueIds references \"${childId}\" but no matching Issue artifact found`,\n };\n }\n }\n\n for (const [issueId, issueData] of issueDataMap) {\n const deps = (issueData.dependencyIssueIds as string[]) ?? [];\n for (const depId of deps) {\n if (!issueDataMap.has(depId)) {\n return {\n ok: false,\n gate: \"parent_child_linkage\",\n failureCode: \"linkage_mismatch\",\n message: `Issue ${issueId} dependency \"${depId}\" not found in Issue set`,\n };\n }\n }\n }\n\n const storeIssueIds: string[] = [];\n try {\n const entries = readdirSync(issuesStore);\n for (const entry of entries) {\n if (entry.endsWith(\".json\")) {\n const issuePath = join(issuesStore, entry);\n const issue = readLocalArtifact<Record<string, unknown>>(issuePath);\n if (issue.ok && issue.data) {\n storeIssueIds.push(issue.data.id as string);\n }\n }\n }\n } catch {\n // Cannot read store directory; continue without orphan check\n }\n\n for (const storeIssueId of storeIssueIds) {\n if (!issueDataMap.has(storeIssueId)) {\n return {\n ok: false,\n gate: \"parent_child_linkage\",\n failureCode: \"linkage_mismatch\",\n message: `Issue ${storeIssueId} is an orphan: not referenced by any PRD's childIssueIds`,\n };\n }\n }\n\n // Gate 5: Triage consistency\n const triageResult = validateLocalTriage(prdPath, issuePaths);\n if (!triageResult.ok) {\n return { ...triageResult, gate: \"triage_consistency\" };\n }\n\n // Gate 6: Branch safety\n const protectedBranchNames = [\"dev\", \"next\", \"main\"];\n const barePrdPattern = /^PRD-\\d{4}$/;\n const localPrdBranchPattern = /^local\\/PRD-\\d{4}$/;\n\n const dirtyRaw = tryExecSync(\"git status --porcelain\", options?.repoRoot);\n if (dirtyRaw !== null && dirtyRaw.length > 0) {\n return {\n ok: false,\n gate: \"branch_safety\",\n failureCode: \"dirty_worktree\",\n message: \"Working tree has uncommitted changes\",\n };\n }\n\n const prdBranchData = readLocalArtifact<Record<string, unknown>>(prdPath);\n if (!prdBranchData.ok || !prdBranchData.data) {\n return {\n ok: false,\n gate: \"branch_safety\",\n failureCode: \"branch_unsafe\",\n offendingPath: prdPath,\n message: \"Cannot read PRD for branch safety check\",\n };\n }\n\n const reconciliationTarget = prdBranchData.data\n .reconciliationTarget as Record<string, unknown>;\n const localPrdBranch = reconciliationTarget.localPrdBranch as string;\n if (protectedBranchNames.includes(localPrdBranch)) {\n return {\n ok: false,\n gate: \"branch_safety\",\n failureCode: \"branch_unsafe\",\n message: `PRD localPrdBranch \"${localPrdBranch}\" is a protected branch`,\n };\n }\n if (barePrdPattern.test(localPrdBranch)) {\n return {\n ok: false,\n gate: \"branch_safety\",\n failureCode: \"branch_unsafe\",\n message: `PRD localPrdBranch \"${localPrdBranch}\" matches bare PRD-0000N pattern without local/ prefix`,\n };\n }\n if (!localPrdBranchPattern.test(localPrdBranch)) {\n return {\n ok: false,\n gate: \"branch_safety\",\n failureCode: \"branch_unsafe\",\n message: `PRD localPrdBranch \"${localPrdBranch}\" must match local/PRD-0000N pattern`,\n };\n }\n\n const branchExists = tryExecSync(\n `git branch --list ${localPrdBranch}`,\n options?.repoRoot\n );\n if (branchExists !== null && branchExists.length > 0) {\n return {\n ok: false,\n gate: \"branch_safety\",\n failureCode: \"branch_unsafe\",\n message: `PRD localPrdBranch \"${localPrdBranch}\" already exists locally`,\n };\n }\n\n const remoteExists = tryExecSync(\n `git branch -r --list origin/${localPrdBranch}`,\n options?.repoRoot\n );\n if (remoteExists !== null && remoteExists.length > 0) {\n return {\n ok: false,\n gate: \"branch_safety\",\n failureCode: \"branch_unsafe\",\n message: `PRD localPrdBranch \"${localPrdBranch}\" already exists on remote`,\n };\n }\n\n for (const issuePath of issuePaths) {\n const issue = readLocalArtifact<Record<string, unknown>>(issuePath);\n if (!issue.ok || !issue.data) {\n return {\n ok: false,\n gate: \"branch_safety\",\n failureCode: \"branch_unsafe\",\n offendingPath: issuePath,\n message: `Cannot read Issue for branch safety check: ${issue.message}`,\n };\n }\n const branchName = issue.data.branchName as string;\n\n if (protectedBranchNames.includes(branchName)) {\n return {\n ok: false,\n gate: \"branch_safety\",\n failureCode: \"branch_unsafe\",\n offendingPath: issuePath,\n message: `Issue branch \"${branchName}\" is a protected branch`,\n };\n }\n\n if (barePrdPattern.test(branchName)) {\n return {\n ok: false,\n gate: \"branch_safety\",\n failureCode: \"branch_unsafe\",\n offendingPath: issuePath,\n message: `Issue branch \"${branchName}\" matches bare PRD-0000N pattern without local/ prefix`,\n };\n }\n }\n\n // Gate 7: Projection freshness\n const prdForProjection = readLocalArtifact<Record<string, unknown>>(prdPath);\n if (prdForProjection.ok && prdForProjection.data) {\n const result = checkProjectionFreshness(\n prdForProjection.data,\n prdPath,\n options?.repoRoot\n );\n if (!result.ok) return result;\n }\n\n for (const issuePath of issuePaths) {\n const issue = readLocalArtifact<Record<string, unknown>>(issuePath);\n if (issue.ok && issue.data) {\n const result = checkProjectionFreshness(\n issue.data,\n issuePath,\n options?.repoRoot\n );\n if (!result.ok) return result;\n }\n }\n\n return { ok: true };\n}\n\nfunction tryExecSync(cmd: string, cwd?: string): string | null {\n try {\n return execSync(cmd, { cwd, stdio: [\"ignore\", \"pipe\", \"ignore\"] })\n .toString()\n .trim();\n } catch {\n return null;\n }\n}\n\nfunction checkProjectionFreshness(\n data: Record<string, unknown>,\n artifactPath: string,\n repoRoot?: string\n): LocalValidationResult {\n const bodyMarkdown = data.bodyMarkdown as string;\n const bodyContract = data.bodyContract as Record<string, unknown> | undefined;\n\n if (!bodyContract) return { ok: true };\n\n const bodyHash = bodyContract.bodyHash as string | undefined;\n if (bodyHash) {\n const computedHash = `sha256:${createHash(\"sha256\").update(bodyMarkdown, \"utf-8\").digest(\"hex\")}`;\n if (bodyHash !== computedHash) {\n return {\n ok: false,\n gate: \"projection_freshness\",\n failureCode: \"body_hash_mismatch\",\n offendingPath: artifactPath,\n message: `bodyHash \"${bodyHash}\" does not match computed SHA-256 of bodyMarkdown`,\n };\n }\n }\n\n const renderedPath = bodyContract.renderedMarkdownPath as string | undefined;\n if (!renderedPath) {\n return {\n ok: false,\n gate: \"projection_freshness\",\n failureCode: \"missing_projection\",\n offendingPath: artifactPath,\n message: \"renderedMarkdownPath is missing\",\n };\n }\n\n const renderedPathToRead = isAbsolute(renderedPath)\n ? renderedPath\n : resolve(repoRoot ?? process.cwd(), renderedPath);\n\n if (!existsSync(renderedPathToRead)) {\n return {\n ok: false,\n gate: \"projection_freshness\",\n failureCode: \"missing_projection\",\n offendingPath: renderedPathToRead,\n message: `Rendered Markdown not found at ${renderedPathToRead}`,\n };\n }\n\n const renderedContent = readFileSync(renderedPathToRead, \"utf-8\");\n if (renderedContent !== bodyMarkdown) {\n return {\n ok: false,\n gate: \"projection_freshness\",\n failureCode: \"stale_projection\",\n offendingPath: renderedPathToRead,\n message:\n \"Rendered Markdown content does not match bodyMarkdown byte-for-byte\",\n };\n }\n\n const renderedAt = bodyContract.renderedAt as string | undefined;\n if (renderedAt) {\n try {\n const parsed = new Date(renderedAt);\n if (isNaN(parsed.getTime()) || parsed.toISOString() !== renderedAt) {\n return {\n ok: false,\n gate: \"projection_freshness\",\n failureCode: \"stale_projection\",\n offendingPath: artifactPath,\n message: `renderedAt \"${renderedAt}\" is not a valid ISO 8601 timestamp`,\n };\n }\n } catch {\n return {\n ok: false,\n gate: \"projection_freshness\",\n failureCode: \"stale_projection\",\n offendingPath: artifactPath,\n message: `renderedAt \"${renderedAt}\" is not a valid ISO 8601 timestamp`,\n };\n }\n }\n\n return { ok: true };\n}\n\nexport function readLocalArtifact<T>(\n path: string,\n failureCode?: LocalValidationFailureCode\n): LocalValidationResult & { data?: T } {\n try {\n const raw = readFileSync(path, \"utf-8\");\n const parsed = JSON.parse(raw);\n if (\n parsed === null ||\n typeof parsed !== \"object\" ||\n Array.isArray(parsed)\n ) {\n return {\n ok: false,\n failureCode: failureCode ?? \"invalid_prd_artifact\",\n offendingPath: path,\n message: `Expected a JSON object, got ${Array.isArray(parsed) ? \"array\" : parsed === null ? \"null\" : typeof parsed}`,\n };\n }\n return { ok: true, data: parsed as T };\n } catch (e) {\n return {\n ok: false,\n failureCode: failureCode ?? \"invalid_prd_artifact\",\n offendingPath: path,\n message: `Failed to read or parse: ${e}`,\n };\n }\n}\n\nexport type LocalPrdStatus =\n | \"draft\"\n | \"ready\"\n | \"prepared\"\n | \"running\"\n | \"final-review\"\n | \"reconciliation\"\n | \"complete\"\n | \"blocked\";\n\nconst VALID_LOCAL_PRD_STATUSES: LocalPrdStatus[] = [\n \"draft\",\n \"ready\",\n \"prepared\",\n \"running\",\n \"final-review\",\n \"reconciliation\",\n \"complete\",\n \"blocked\",\n];\n\nconst TO_PRD_REQUIRED_HEADINGS = [\n \"Problem Statement\",\n \"Solution\",\n \"Plan Documents\",\n \"User Stories\",\n \"Implementation Decisions\",\n \"Testing Decisions\",\n \"Out of Scope\",\n \"Further Notes\",\n];\n\nconst TO_ISSUES_REQUIRED_HEADINGS = [\n \"Parent\",\n \"Plan Documents\",\n \"Source of truth for behavior\",\n \"What to build\",\n \"High-level explanation\",\n \"Affected code paths\",\n \"Exploration evidence\",\n \"Contract decisions\",\n \"Execution path matrix\",\n \"Regression contract (CRITICAL)\",\n \"Step-by-step implementation\",\n \"Contracts / interfaces\",\n \"Edge cases\",\n \"Validation\",\n \"Out of scope\",\n \"Priority\",\n \"Acceptance criteria\",\n \"Blocked by\",\n];\n\nconst VALID_LOCAL_ISSUE_STATUSES = [\n \"needs-triage\",\n \"ready-for-agent\",\n \"blocked\",\n \"ready-for-human\",\n \"wontfix\",\n \"running\",\n \"complete\",\n] as const;\n\nconst VALID_ISSUE_TRIAGE_LABELS = [\n \"needs-triage\",\n \"ready-for-agent\",\n \"blocked\",\n \"ready-for-human\",\n \"wontfix\",\n \"running\",\n \"complete\",\n];\n\nconst VALID_ISSUE_CATEGORY_LABELS = [\"bug\", \"enhancement\"];\n\nconst VALID_ISSUE_TYPE_LABELS = [\n \"type:bugfix\",\n \"type:infra\",\n \"type:feature\",\n \"type:polish\",\n \"type:refactor\",\n];\n\nconst ISSUE_RECEIPT_FIELDS = [\n \"createdAt\",\n \"updatedAt\",\n \"preparedAt\",\n \"startedAt\",\n \"completedAt\",\n \"reviewedAt\",\n \"mergedAt\",\n];\n\nconst ISSUE_PROJECTION_FIELDS = [\n \"issueNumber\",\n \"issueUrl\",\n \"publishedAt\",\n \"syncedAt\",\n];\n\nfunction getMarkdownHeadings(markdown: string): string[] {\n const headingRegex = /^## (.+)$/gm;\n const headings: string[] = [];\n let match: RegExpExecArray | null;\n while ((match = headingRegex.exec(markdown)) !== null) {\n headings.push(match[1].trim());\n }\n return headings;\n}\n\nexport function validateLocalPrd(path: string): LocalValidationResult {\n const parsed = readLocalArtifact<Record<string, unknown>>(path);\n if (!parsed.ok) return parsed;\n const data = parsed.data!;\n\n if (data.schemaVersion !== 1) {\n return {\n ok: false,\n failureCode: \"invalid_prd_artifact\",\n offendingPath: path,\n message: \"schemaVersion must be 1\",\n };\n }\n\n if (data.kind !== \"prd\") {\n return {\n ok: false,\n failureCode: \"invalid_prd_artifact\",\n offendingPath: path,\n message: \"kind must be prd\",\n };\n }\n\n if (typeof data.id !== \"string\" || data.id.trim() === \"\") {\n return {\n ok: false,\n failureCode: \"invalid_prd_artifact\",\n offendingPath: path,\n message: \"id must be a non-empty string\",\n };\n }\n\n if (typeof data.title !== \"string\" || data.title.trim() === \"\") {\n return {\n ok: false,\n failureCode: \"invalid_prd_artifact\",\n offendingPath: path,\n message: \"title must be a non-empty string\",\n };\n }\n\n if (\n typeof data.status !== \"string\" ||\n !VALID_LOCAL_PRD_STATUSES.includes(data.status as LocalPrdStatus)\n ) {\n return {\n ok: false,\n failureCode: \"invalid_prd_artifact\",\n offendingPath: path,\n message: `status must be one of: ${VALID_LOCAL_PRD_STATUSES.join(\", \")}`,\n };\n }\n\n if (!Array.isArray(data.childIssueIds)) {\n return {\n ok: false,\n failureCode: \"invalid_prd_artifact\",\n offendingPath: path,\n message: \"childIssueIds must be an array\",\n };\n }\n\n if (!Array.isArray(data.linkedDecisionIds)) {\n return {\n ok: false,\n failureCode: \"invalid_prd_artifact\",\n offendingPath: path,\n message: \"linkedDecisionIds must be an array\",\n };\n }\n\n if (\n !data.reconciliationTarget ||\n typeof data.reconciliationTarget !== \"object\"\n ) {\n return {\n ok: false,\n failureCode: \"invalid_prd_artifact\",\n offendingPath: path,\n message: \"reconciliationTarget must be an object\",\n };\n }\n\n const reconciliationTarget = data.reconciliationTarget as Record<\n string,\n unknown\n >;\n if (\n typeof reconciliationTarget.localPrdBranch !== \"string\" ||\n reconciliationTarget.localPrdBranch.trim() === \"\"\n ) {\n return {\n ok: false,\n failureCode: \"invalid_prd_artifact\",\n offendingPath: path,\n message: \"reconciliationTarget.localPrdBranch must be a non-empty string\",\n };\n }\n\n if (\n typeof reconciliationTarget.integrationBranch !== \"string\" ||\n reconciliationTarget.integrationBranch.trim() === \"\"\n ) {\n return {\n ok: false,\n failureCode: \"invalid_prd_artifact\",\n offendingPath: path,\n message:\n \"reconciliationTarget.integrationBranch must be a non-empty string\",\n };\n }\n\n if (\n typeof data.bodyMarkdown !== \"string\" ||\n data.bodyMarkdown.trim() === \"\"\n ) {\n return {\n ok: false,\n failureCode: \"invalid_prd_artifact\",\n offendingPath: path,\n message: \"bodyMarkdown must be a non-empty string\",\n };\n }\n\n if (!data.bodyContract || typeof data.bodyContract !== \"object\") {\n return {\n ok: false,\n failureCode: \"invalid_prd_artifact\",\n offendingPath: path,\n message: \"bodyContract must be an object\",\n };\n }\n\n const bodyContract = data.bodyContract as Record<string, unknown>;\n if (bodyContract.contract !== \"to-prd\") {\n return {\n ok: false,\n failureCode: \"invalid_prd_artifact\",\n offendingPath: path,\n message: 'bodyContract.contract must be \"to-prd\"',\n };\n }\n\n if (!Array.isArray(bodyContract.requiredHeadings)) {\n return {\n ok: false,\n failureCode: \"invalid_prd_artifact\",\n offendingPath: path,\n message: \"bodyContract.requiredHeadings must be an array\",\n };\n }\n\n const requiredHeadings = bodyContract.requiredHeadings as string[];\n const missingHeadings = TO_PRD_REQUIRED_HEADINGS.filter(\n (h) => !requiredHeadings.includes(h)\n );\n if (missingHeadings.length > 0) {\n return {\n ok: false,\n failureCode: \"invalid_prd_artifact\",\n offendingPath: path,\n message: `bodyContract.requiredHeadings missing: ${missingHeadings.join(\", \")}`,\n };\n }\n\n const markdownHeadings = getMarkdownHeadings(data.bodyMarkdown as string);\n const missingInMarkdown = TO_PRD_REQUIRED_HEADINGS.filter(\n (h) => !markdownHeadings.includes(h)\n );\n if (missingInMarkdown.length > 0) {\n return {\n ok: false,\n failureCode: \"invalid_prd_artifact\",\n offendingPath: path,\n message: `bodyMarkdown missing headings: ${missingInMarkdown.join(\", \")}`,\n };\n }\n\n if (!data.receipts || typeof data.receipts !== \"object\") {\n return {\n ok: false,\n failureCode: \"invalid_prd_artifact\",\n offendingPath: path,\n message: \"receipts must be an object\",\n };\n }\n\n const receipts = data.receipts as Record<string, unknown>;\n const expectedReceiptFields = [\n \"createdAt\",\n \"updatedAt\",\n \"preparedAt\",\n \"startedAt\",\n \"finalReviewedAt\",\n \"reconciledAt\",\n \"completedAt\",\n ];\n for (const field of expectedReceiptFields) {\n if (!(field in receipts)) {\n return {\n ok: false,\n failureCode: \"invalid_prd_artifact\",\n offendingPath: path,\n message: `receipts.${field} is missing`,\n };\n }\n }\n\n if (!data.githubProjection || typeof data.githubProjection !== \"object\") {\n return {\n ok: false,\n failureCode: \"invalid_prd_artifact\",\n offendingPath: path,\n message: \"githubProjection must be an object\",\n };\n }\n\n const githubProjection = data.githubProjection as Record<string, unknown>;\n const expectedProjectionFields = [\n \"issueNumber\",\n \"issueUrl\",\n \"publishedAt\",\n \"syncedAt\",\n ];\n for (const field of expectedProjectionFields) {\n if (!(field in githubProjection)) {\n return {\n ok: false,\n failureCode: \"invalid_prd_artifact\",\n offendingPath: path,\n message: `githubProjection.${field} is missing`,\n };\n }\n }\n\n return { ok: true };\n}\n\nexport function validateLocalIssue(path: string): LocalValidationResult {\n const parsed = readLocalArtifact<Record<string, unknown>>(path);\n if (!parsed.ok) {\n return {\n ok: false,\n failureCode: \"invalid_issue_artifact\",\n offendingPath: path,\n message: parsed.message,\n };\n }\n const data = parsed.data!;\n\n if (data.schemaVersion !== 1) {\n return {\n ok: false,\n failureCode: \"invalid_issue_artifact\",\n offendingPath: path,\n message: \"schemaVersion must be 1\",\n };\n }\n\n if (data.kind !== \"issue\") {\n return {\n ok: false,\n failureCode: \"invalid_issue_artifact\",\n offendingPath: path,\n message: 'kind must be \"issue\"',\n };\n }\n\n if (typeof data.id !== \"string\" || data.id.trim() === \"\") {\n return {\n ok: false,\n failureCode: \"invalid_issue_artifact\",\n offendingPath: path,\n message: \"id must be a non-empty string\",\n };\n }\n\n if (\n typeof data.parentPrdId !== \"string\" ||\n !/^PRD-\\d{4}$/.test(data.parentPrdId.trim())\n ) {\n return {\n ok: false,\n failureCode: \"invalid_issue_artifact\",\n offendingPath: path,\n message: \"parentPrdId must match PRD-0000N format\",\n };\n }\n\n if (typeof data.title !== \"string\" || data.title.trim() === \"\") {\n return {\n ok: false,\n failureCode: \"invalid_issue_artifact\",\n offendingPath: path,\n message: \"title must be a non-empty string\",\n };\n }\n\n if (\n typeof data.status !== \"string\" ||\n !(VALID_LOCAL_ISSUE_STATUSES as readonly string[]).includes(data.status)\n ) {\n return {\n ok: false,\n failureCode: \"invalid_issue_artifact\",\n offendingPath: path,\n message: `status must be one of: ${VALID_LOCAL_ISSUE_STATUSES.join(\", \")}`,\n };\n }\n\n if (!Array.isArray(data.labels)) {\n return {\n ok: false,\n failureCode: \"invalid_issue_artifact\",\n offendingPath: path,\n message: \"labels must be an array\",\n };\n }\n\n const labels = data.labels as string[];\n const triageLabel = labels.find((l) => VALID_ISSUE_TRIAGE_LABELS.includes(l));\n const categoryLabel = labels.find((l) =>\n VALID_ISSUE_CATEGORY_LABELS.includes(l)\n );\n const typeLabel = labels.find((l) => VALID_ISSUE_TYPE_LABELS.includes(l));\n const unknownLabels = labels.filter(\n (l) =>\n !VALID_ISSUE_TRIAGE_LABELS.includes(l) &&\n !VALID_ISSUE_CATEGORY_LABELS.includes(l) &&\n !VALID_ISSUE_TYPE_LABELS.includes(l)\n );\n\n if (!triageLabel) {\n return {\n ok: false,\n failureCode: \"invalid_issue_artifact\",\n offendingPath: path,\n message: `labels must include one triage-state label from: ${VALID_ISSUE_TRIAGE_LABELS.join(\", \")}`,\n };\n }\n if (!categoryLabel) {\n return {\n ok: false,\n failureCode: \"invalid_issue_artifact\",\n offendingPath: path,\n message: `labels must include one category label from: ${VALID_ISSUE_CATEGORY_LABELS.join(\", \")}`,\n };\n }\n if (!typeLabel) {\n return {\n ok: false,\n failureCode: \"invalid_issue_artifact\",\n offendingPath: path,\n message: `labels must include one type label from: ${VALID_ISSUE_TYPE_LABELS.join(\", \")}`,\n };\n }\n\n if (\n data.status !== \"running\" &&\n data.status !== \"complete\" &&\n triageLabel !== data.status\n ) {\n return {\n ok: false,\n failureCode: \"invalid_issue_artifact\",\n offendingPath: path,\n message: `triage-state label must match status: expected \"${data.status}\", got \"${triageLabel}\"`,\n };\n }\n\n // Only one type:* label\n const typeLabels = labels.filter((l) => l.startsWith(\"type:\"));\n if (typeLabels.length > 1) {\n return {\n ok: false,\n failureCode: \"invalid_issue_artifact\",\n offendingPath: path,\n message: \"more than one type:* label found\",\n };\n }\n\n if (labels.length !== 3 || unknownLabels.length > 0) {\n return {\n ok: false,\n failureCode: \"invalid_issue_artifact\",\n offendingPath: path,\n message:\n \"labels must contain exactly 3 entries: one triage-state, one category, one type:*\",\n };\n }\n\n if (!Array.isArray(data.dependencyIssueIds)) {\n return {\n ok: false,\n failureCode: \"invalid_issue_artifact\",\n offendingPath: path,\n message: \"dependencyIssueIds must be an array\",\n };\n }\n\n if (\n typeof data.branchName !== \"string\" ||\n !/^local\\/PRD-\\d{4}\\/I-\\d{2}-[a-z0-9-]+$/.test(data.branchName)\n ) {\n return {\n ok: false,\n failureCode: \"invalid_issue_artifact\",\n offendingPath: path,\n message: \"branchName must match local/PRD-0000N/I-0N-slug pattern\",\n };\n }\n\n if (\n !(data.blockedReason === null || typeof data.blockedReason === \"string\")\n ) {\n return {\n ok: false,\n failureCode: \"invalid_issue_artifact\",\n offendingPath: path,\n message: \"blockedReason must be a string or null\",\n };\n }\n\n if (\n !(\n data.readyForHumanReason === null ||\n typeof data.readyForHumanReason === \"string\"\n )\n ) {\n return {\n ok: false,\n failureCode: \"invalid_issue_artifact\",\n offendingPath: path,\n message: \"readyForHumanReason must be a string or null\",\n };\n }\n\n if (\n typeof data.bodyMarkdown !== \"string\" ||\n data.bodyMarkdown.trim() === \"\"\n ) {\n return {\n ok: false,\n failureCode: \"invalid_issue_artifact\",\n offendingPath: path,\n message: \"bodyMarkdown must be a non-empty string\",\n };\n }\n\n if (!data.bodyContract || typeof data.bodyContract !== \"object\") {\n return {\n ok: false,\n failureCode: \"invalid_issue_artifact\",\n offendingPath: path,\n message: \"bodyContract must be an object\",\n };\n }\n\n const bodyContract = data.bodyContract as Record<string, unknown>;\n if (bodyContract.contract !== \"to-issues\") {\n return {\n ok: false,\n failureCode: \"invalid_issue_artifact\",\n offendingPath: path,\n message: 'bodyContract.contract must be \"to-issues\"',\n };\n }\n\n if (!Array.isArray(bodyContract.requiredHeadings)) {\n return {\n ok: false,\n failureCode: \"invalid_issue_artifact\",\n offendingPath: path,\n message: \"bodyContract.requiredHeadings must be an array\",\n };\n }\n\n const requiredHeadings = bodyContract.requiredHeadings as string[];\n const missingHeadings = TO_ISSUES_REQUIRED_HEADINGS.filter(\n (h) => !requiredHeadings.includes(h)\n );\n if (missingHeadings.length > 0) {\n return {\n ok: false,\n failureCode: \"invalid_issue_artifact\",\n offendingPath: path,\n message: `bodyContract.requiredHeadings missing: ${missingHeadings.join(\", \")}`,\n };\n }\n\n const markdownHeadings = getMarkdownHeadings(data.bodyMarkdown as string);\n const missingInMarkdown = TO_ISSUES_REQUIRED_HEADINGS.filter(\n (h) => !markdownHeadings.includes(h)\n );\n if (missingInMarkdown.length > 0) {\n return {\n ok: false,\n failureCode: \"invalid_issue_artifact\",\n offendingPath: path,\n message: `bodyMarkdown missing headings: ${missingInMarkdown.join(\", \")}`,\n };\n }\n\n if (!data.receipts || typeof data.receipts !== \"object\") {\n return {\n ok: false,\n failureCode: \"invalid_issue_artifact\",\n offendingPath: path,\n message: \"receipts must be an object\",\n };\n }\n\n const receipts = data.receipts as Record<string, unknown>;\n for (const field of ISSUE_RECEIPT_FIELDS) {\n if (!(field in receipts)) {\n return {\n ok: false,\n failureCode: \"invalid_issue_artifact\",\n offendingPath: path,\n message: `receipts.${field} is missing`,\n };\n }\n }\n\n if (!data.githubProjection || typeof data.githubProjection !== \"object\") {\n return {\n ok: false,\n failureCode: \"invalid_issue_artifact\",\n offendingPath: path,\n message: \"githubProjection must be an object\",\n };\n }\n\n const githubProjection = data.githubProjection as Record<string, unknown>;\n for (const field of ISSUE_PROJECTION_FIELDS) {\n if (!(field in githubProjection)) {\n return {\n ok: false,\n failureCode: \"invalid_issue_artifact\",\n offendingPath: path,\n message: `githubProjection.${field} is missing`,\n };\n }\n }\n\n return { ok: true };\n}\n\nexport function validateConflictResolutionArtifactAtPath(options: {\n artifactPath: string;\n worktreePath: string;\n}): ArtifactValidationResult {\n return validateAgentArtifact({\n kind: \"conflict-resolution\",\n artifactPath: join(options.worktreePath, options.artifactPath),\n worktreePath: options.worktreePath,\n });\n}\n\n// ---- Local triage validation ----\n\nexport function validateLocalTriage(\n prdPath: string,\n issuePaths: string[]\n): LocalValidationResult {\n const prd = readLocalArtifact<Record<string, unknown>>(\n prdPath,\n \"triage_inconsistent\"\n );\n if (!prd.ok || !prd.data) {\n return {\n ok: false,\n failureCode: \"triage_inconsistent\",\n offendingPath: prdPath,\n message: prd.message ?? \"Invalid PRD artifact\",\n };\n }\n\n if (issuePaths.length === 0) {\n return { ok: true };\n }\n\n const issues: { path: string; data: Record<string, unknown> }[] = [];\n for (const issuePath of issuePaths) {\n const issue = readLocalArtifact<Record<string, unknown>>(\n issuePath,\n \"triage_inconsistent\"\n );\n if (!issue.ok || !issue.data) {\n return {\n ok: false,\n failureCode: \"triage_inconsistent\",\n offendingPath: issuePath,\n message: issue.message ?? \"Invalid Issue artifact\",\n };\n }\n issues.push({ path: issuePath, data: issue.data });\n }\n\n const issuesById = new Map(issues.map((i) => [i.data.id as string, i]));\n\n // Rule 1: No child Issue has status needs-triage\n const needsTriage = issues.filter((i) => i.data.status === \"needs-triage\");\n if (needsTriage.length > 0) {\n return {\n ok: false,\n failureCode: \"triage_inconsistent\",\n message: `Parent PRD cannot prepare: child Issue(s) still in needs-triage: ${needsTriage.map((i) => i.data.id).join(\", \")}`,\n };\n }\n\n // Rule 2: Every blocked Issue has at least one blocker source\n for (const issue of issues.filter((i) => i.data.status === \"blocked\")) {\n const deps = (issue.data.dependencyIssueIds as string[]) ?? [];\n const blockedReason = issue.data.blockedReason;\n const readyForHumanReason = issue.data.readyForHumanReason;\n if (\n deps.length === 0 &&\n blockedReason == null &&\n readyForHumanReason == null\n ) {\n return {\n ok: false,\n failureCode: \"triage_inconsistent\",\n offendingPath: issue.path,\n message: `Blocked Issue ${issue.data.id} requires at least one blocker source: dependencyIssueIds, blockedReason, or readyForHumanReason`,\n };\n }\n }\n\n // Rule 3: ready-for-human needs readyForHumanReason; wontfix needs blockedReason\n for (const issue of issues.filter(\n (i) => i.data.status === \"ready-for-human\"\n )) {\n if (issue.data.readyForHumanReason == null) {\n return {\n ok: false,\n failureCode: \"triage_inconsistent\",\n offendingPath: issue.path,\n message: `ready-for-human Issue ${issue.data.id} must have a readyForHumanReason`,\n };\n }\n }\n for (const issue of issues.filter((i) => i.data.status === \"wontfix\")) {\n if (issue.data.blockedReason == null) {\n return {\n ok: false,\n failureCode: \"triage_inconsistent\",\n offendingPath: issue.path,\n message: `wontfix Issue ${issue.data.id} must have a blockedReason`,\n };\n }\n }\n\n // Rule 4: At least one child ready-for-agent when any blocked child exists\n const blockedCount = issues.filter((i) => i.data.status === \"blocked\").length;\n if (blockedCount > 0) {\n const readyForAgentCount = issues.filter(\n (i) => i.data.status === \"ready-for-agent\"\n ).length;\n if (readyForAgentCount === 0) {\n return {\n ok: false,\n failureCode: \"triage_inconsistent\",\n message:\n \"At least one child Issue must be ready-for-agent when blocked children exist\",\n };\n }\n }\n\n // Rule 5: Every Issue status matches its triage-state label\n for (const issue of issues) {\n const labels = (issue.data.labels as string[]) ?? [];\n const status = issue.data.status as string;\n const triageLabel = labels.find((l) =>\n (VALID_ISSUE_TRIAGE_LABELS as readonly string[]).includes(l)\n );\n if (\n triageLabel &&\n status !== \"running\" &&\n status !== \"complete\" &&\n triageLabel !== status\n ) {\n return {\n ok: false,\n failureCode: \"triage_inconsistent\",\n offendingPath: issue.path,\n message: `Issue ${issue.data.id} has status \"${status}\" but triage-state label \"${triageLabel}\"`,\n };\n }\n }\n\n // Rule 6: Exactly one triage-state label per Issue\n for (const issue of issues) {\n const labels = (issue.data.labels as string[]) ?? [];\n const triageLabels = labels.filter((l) =>\n (VALID_ISSUE_TRIAGE_LABELS as readonly string[]).includes(l)\n );\n if (triageLabels.length !== 1) {\n return {\n ok: false,\n failureCode: \"triage_inconsistent\",\n offendingPath: issue.path,\n message: `Issue ${issue.data.id} must have exactly one triage-state label, got ${triageLabels.length}`,\n };\n }\n }\n\n // Edge case: ready-for-agent with unmet dependencies\n for (const issue of issues.filter(\n (i) => i.data.status === \"ready-for-agent\"\n )) {\n const deps = (issue.data.dependencyIssueIds as string[]) ?? [];\n for (const depId of deps) {\n const dep = issuesById.get(depId);\n if (dep && dep.data.status !== \"complete\") {\n return {\n ok: false,\n failureCode: \"triage_inconsistent\",\n offendingPath: issue.path,\n message: `ready-for-agent Issue ${issue.data.id} has unresolved dependency ${depId} (status: ${dep.data.status})`,\n };\n }\n }\n }\n\n return { ok: true };\n}\n","export type ReviewVerdict =\n | \"PASS\"\n | \"PASS_WITH_NOTES\"\n | \"NEEDS_REFACTOR\"\n | \"FAIL\"\n | \"NEEDS_HUMAN\";\n\nexport class ReviewVerdictProtocolError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ReviewVerdictProtocolError\";\n }\n}\n\nexport function parseReviewVerdict(output: string): ReviewVerdict {\n const verdictRegex =\n /^\\s*<verdict>\\s*(PASS|PASS_WITH_NOTES|NEEDS_REFACTOR|FAIL|NEEDS_HUMAN)\\s*<\\/verdict>\\s*$/gm;\n const matches = Array.from(output.matchAll(verdictRegex));\n\n if (!matches || matches.length === 0) {\n throw new ReviewVerdictProtocolError(\n \"No <verdict>...</verdict> token found in reviewer output\"\n );\n }\n\n if (matches.length > 1) {\n throw new ReviewVerdictProtocolError(\n \"Multiple <verdict>...</verdict> tokens found in reviewer output\"\n );\n }\n\n const verdict = matches[0][1];\n if (!verdict) {\n throw new ReviewVerdictProtocolError(\n \"Malformed <verdict>...</verdict> token in reviewer output\"\n );\n }\n\n return verdict as ReviewVerdict;\n}\n","import {\n existsSync,\n mkdirSync,\n readFileSync,\n readdirSync,\n writeFileSync,\n} from \"fs\";\nimport { join } from \"path\";\nimport {\n type IssueData,\n type PourkitConfig,\n type Target,\n resolveMissingOrEmptyOutputRetries,\n resolvePromptTemplatePath,\n} from \"../shared/config\";\nimport type { ExecutionProvider } from \"../execution/execution-provider\";\nimport { executeWithMissingOrEmptyArtifactRetry } from \"../execution/agent-output-retry\";\nimport {\n parseReviewVerdict,\n type ReviewVerdict,\n ReviewVerdictProtocolError,\n} from \"../pr/review-verdict\";\nimport { type PourkitLogger } from \"../shared/common\";\nimport {\n RUN_CONTEXT_PATH_IN_WORKTREE,\n buildRunContextArtifact,\n STAGE_SECTIONS,\n} from \"../shared/run-context\";\nimport { appendProtectedWorkGuidance } from \"../shared/prompt-guidance\";\nimport type { SerenaExecutionContext } from \"../execution/opencode-config\";\nimport {\n FileSystem,\n FileSystemDefault,\n ExecutionProvider as ExecutionProviderService,\n} from \"../shared/effect-services\";\nimport { ReviewerFailure } from \"../failure-resolution/types\";\nimport { Effect, Layer } from \"effect\";\n\nexport interface ReviewResult {\n verdict: ReviewVerdict;\n output: string;\n artifactPath: string;\n}\n\nexport interface RunReviewOptions {\n executionProvider: ExecutionProvider;\n config: PourkitConfig;\n target: Target;\n issue: IssueData;\n parentPrdIssue?: IssueData;\n builderBranch: string;\n worktreePath: string;\n repoRoot: string;\n logger: PourkitLogger;\n iteration?: number;\n reviewHistory?: string[];\n priorRefactorArtifacts?: string;\n humanHandoffResolved?: boolean;\n priorReviewerArtifacts?: string;\n}\n\nexport class ReviewArtifactValidationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ReviewArtifactValidationError\";\n }\n}\n\nexport class RefactorArtifactValidationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"RefactorArtifactValidationError\";\n }\n}\n\nconst ALLOWED_REFACTOR_CLASSIFICATIONS = [\n \"accepted\",\n \"rejected\",\n \"deferred\",\n \"blocked\",\n];\n\nfunction normalizeRefactorClassification(raw: string): string {\n const match = raw.match(/^`(accepted|rejected|deferred|blocked)`$/);\n return match?.[1] ?? raw;\n}\n\nexport function extractLatestFindingIds(\n reviewOutput: string,\n iteration: number\n): string[] {\n const findingsSection =\n reviewOutput.split(\"## Findings\")[1]?.split(\"##\")[0] ?? \"\";\n const currentIterationIdRegex = new RegExp(`^R${iteration}\\\\.F\\\\d+$`);\n const ids: string[] = [];\n\n const rows = findingsSection.split(\"\\n\");\n let isHeaderRow = true;\n for (const row of rows) {\n const trimmed = row.trim();\n if (!trimmed.startsWith(\"|\")) continue;\n if (/^\\|[\\s-:|]+$/.test(trimmed)) {\n isHeaderRow = false;\n continue;\n }\n if (isHeaderRow) {\n isHeaderRow = false;\n continue;\n }\n const cells = trimmed\n .split(\"|\")\n .map((c) => c.trim())\n .filter((c) => c !== \"\");\n if (cells.length === 0) continue;\n if (cells[0].toLowerCase() === \"none\" || cells[0].toLowerCase() === \"n/a\")\n continue;\n if (currentIterationIdRegex.test(cells[0])) {\n ids.push(cells[0]);\n }\n }\n\n return ids;\n}\n\nexport function validateRefactorArtifact(\n artifactPath: string,\n findingIds: string[]\n): void {\n if (!existsSync(artifactPath)) {\n throw new RefactorArtifactValidationError(\n `Refactor artifact missing at ${artifactPath}`\n );\n }\n\n const content = readFileSync(artifactPath, \"utf-8\");\n\n if (!content.trim()) {\n throw new RefactorArtifactValidationError(\"Refactor artifact is empty\");\n }\n\n const requiredSections = [\n \"## Finding Responses\",\n \"## Verification\",\n \"## Open Blockers\",\n ];\n for (const section of requiredSections) {\n const sectionRegex = new RegExp(`^${section}\\\\s*$`, \"m\");\n if (!sectionRegex.test(content)) {\n throw new RefactorArtifactValidationError(\n `Refactor artifact missing required section: ${section}`\n );\n }\n }\n\n if (findingIds.length === 0) return;\n\n const findingResponsesSection =\n content.split(\"## Finding Responses\")[1]?.split(\"##\")[0] ?? \"\";\n\n for (const findingId of findingIds) {\n const rows = findingResponsesSection.split(\"\\n\");\n let found = false;\n for (const row of rows) {\n const trimmed = row.trim();\n if (!trimmed.startsWith(\"|\")) continue;\n if (/^\\|[\\s-:|]+$/.test(trimmed)) continue;\n\n const cells = trimmed\n .split(\"|\")\n .map((c) => c.trim())\n .filter((c) => c !== \"\");\n if (cells.length < 2) continue;\n\n if (cells[0] === findingId) {\n const classification = normalizeRefactorClassification(cells[1]);\n if (!ALLOWED_REFACTOR_CLASSIFICATIONS.includes(classification)) {\n throw new RefactorArtifactValidationError(\n `Invalid classification for finding ${findingId}: \"${cells[1]}\". Allowed: ${ALLOWED_REFACTOR_CLASSIFICATIONS.join(\", \")}`\n );\n }\n found = true;\n break;\n }\n }\n\n if (!found) {\n throw new RefactorArtifactValidationError(\n `Refactor artifact missing response for finding: ${findingId}`\n );\n }\n }\n}\n\nexport function validateReviewArtifact(\n output: string,\n verdict: ReviewVerdict,\n iteration: number,\n priorRefactorArtifactsProvided: boolean = false\n): void {\n if (!output.includes(\"## Findings\")) {\n throw new ReviewArtifactValidationError(\n \"Reviewer output must include a ## Findings section\"\n );\n }\n\n const findingsSection = output.split(\"## Findings\")[1]?.split(\"##\")[0] ?? \"\";\n\n if (!findingsSection.trim()) {\n throw new ReviewArtifactValidationError(\n \"Findings section must contain a table with ID and Supersedes columns\"\n );\n }\n\n const hasIdColumn = /^\\|?\\s*ID\\s+\\|/m.test(findingsSection);\n if (!hasIdColumn) {\n throw new ReviewArtifactValidationError(\n \"Findings table must include an ID column\"\n );\n }\n\n const hasSupersedesColumn = /^\\|?\\s*ID\\s+\\|\\s*Supersedes\\s+\\|/m.test(\n findingsSection\n );\n if (!hasSupersedesColumn) {\n throw new ReviewArtifactValidationError(\n \"Findings table must include a Supersedes column\"\n );\n }\n\n const findingIdRegex = /^R\\d+\\.F\\d+$/;\n const currentIterationIdRegex = new RegExp(`^R${iteration}\\\\.F\\\\d+$`);\n const supersedesIdRegex = /^R\\d+\\.F\\d+$/;\n const rows = findingsSection.split(\"\\n\");\n let isHeaderRow = true;\n for (const row of rows) {\n const trimmed = row.trim();\n if (!trimmed.startsWith(\"|\")) continue;\n if (/^\\|[\\s-:|]+$/.test(trimmed)) {\n isHeaderRow = false;\n continue;\n }\n if (isHeaderRow) {\n isHeaderRow = false;\n continue;\n }\n const cells = trimmed\n .split(\"|\")\n .map((c) => c.trim())\n .filter((c) => c !== \"\");\n if (cells.length === 0) continue;\n if (cells[0].toLowerCase() === \"none\" || cells[0].toLowerCase() === \"n/a\")\n continue;\n const idCell = cells[0];\n if (!currentIterationIdRegex.test(idCell)) {\n throw new ReviewArtifactValidationError(\n `Finding ID must match R${iteration}.F{number} format for iteration ${iteration}`\n );\n }\n const supersedesCell = cells[1];\n if (supersedesCell !== \"-\" && !supersedesIdRegex.test(supersedesCell)) {\n throw new ReviewArtifactValidationError(\n `Supersedes must be a hyphen for new findings or a valid finding ID, got: ${supersedesCell}`\n );\n }\n }\n\n if (verdict === \"NEEDS_HUMAN\") {\n if (!output.includes(\"## Human Handoff Summary\")) {\n throw new ReviewArtifactValidationError(\n \"NEEDS_HUMAN verdict requires a Human Handoff Summary section\"\n );\n }\n if (!output.includes(\"## Human Handoff Reason\")) {\n throw new ReviewArtifactValidationError(\n \"NEEDS_HUMAN verdict requires a Human Handoff Reason section\"\n );\n }\n }\n\n if (priorRefactorArtifactsProvided) {\n const verdictIndex = output.indexOf(\"<verdict>\");\n const assessmentIndex = output.indexOf(\n \"## Prior Refactor Response Assessment\"\n );\n if (assessmentIndex === -1) {\n throw new ReviewArtifactValidationError(\n \"Prior Refactor Artifacts were provided but the review is missing a ## Prior Refactor Response Assessment section\"\n );\n }\n if (verdictIndex !== -1 && assessmentIndex > verdictIndex) {\n throw new ReviewArtifactValidationError(\n \"## Prior Refactor Response Assessment must appear before <verdict>\"\n );\n }\n }\n}\n\nfunction runReviewCommandEffect(options: RunReviewOptions) {\n const {\n executionProvider,\n config,\n target,\n issue,\n parentPrdIssue,\n builderBranch,\n worktreePath,\n repoRoot,\n logger,\n iteration,\n reviewHistory,\n priorRefactorArtifacts,\n humanHandoffResolved,\n priorReviewerArtifacts,\n } = options;\n\n const reviewer = target.strategy.review.reviewer;\n if (!reviewer) {\n return Effect.fail(\n new ReviewerFailure({ message: \"No reviewer config found\" })\n );\n }\n\n const artifactPathInWorktree = join(\n \".pourkit\",\n \".tmp\",\n \"reviewers\",\n `iteration-${iteration ?? 1}.md`\n );\n const artifactPath = join(worktreePath, artifactPathInWorktree);\n\n return Effect.gen(function* () {\n const exec = yield* ExecutionProviderService;\n const fs = yield* FileSystem;\n\n const prompt = yield* buildReviewerPromptEffect(\n repoRoot,\n reviewer.promptTemplate,\n reviewer.criteria,\n artifactPathInWorktree,\n iteration ?? 1,\n fs,\n reviewHistory,\n priorRefactorArtifacts,\n humanHandoffResolved,\n priorReviewerArtifacts\n );\n\n const retryResult = yield* Effect.tryPromise({\n try: () =>\n executeWithMissingOrEmptyArtifactRetry({\n executionProvider: {\n execute: async (opts) => {\n const result = await Effect.runPromise(exec.execute(opts as any));\n return { ...result, logPath: result.logPath ?? null };\n },\n },\n missingOrEmptyRetries: resolveMissingOrEmptyOutputRetries(reviewer),\n logger,\n runningMessage: (attempt, total) =>\n `Running reviewer (${attempt}/${total})`,\n retryMessage: (attempt, total) =>\n `Retrying reviewer after empty output (${attempt}/${total})`,\n readArtifact: (path, executionResult) => {\n try {\n return {\n _tag: \"content\" as const,\n value: readReviewArtifact(path, executionResult.logPath),\n path,\n };\n } catch (error) {\n const message =\n error instanceof Error ? error.message : String(error);\n return {\n _tag: message.startsWith(\"Reviewer produced empty output at \")\n ? \"empty\"\n : \"missing\",\n path,\n };\n }\n },\n executionOptions: {\n stage: \"reviewer\" as const,\n iteration,\n agent: reviewer.agent,\n model: reviewer.model,\n variant: reviewer.variant,\n env: reviewer.env,\n prompt,\n target,\n repoRoot,\n branchName: builderBranch,\n sandbox: config.sandbox,\n autoApprove: true,\n artifactPath: artifactPathInWorktree,\n worktreePath,\n artifacts: [\n buildRunContextArtifact({\n issue,\n parentPrdIssue,\n target,\n branchName: builderBranch,\n repoRoot,\n reviewerCriteria: reviewer.criteria,\n sections: STAGE_SECTIONS.reviewer,\n }),\n ],\n logger,\n },\n }),\n catch: (error) =>\n new ReviewerFailure({\n message: error instanceof Error ? error.message : String(error),\n }),\n });\n\n if (!retryResult.executionResult.success) {\n return yield* Effect.fail(\n new ReviewerFailure({\n message: `Reviewer execution failed: ${retryResult.executionResult.error}`,\n })\n );\n }\n\n if (retryResult.artifact._tag !== \"content\") {\n const message =\n retryResult.artifact._tag === \"empty\"\n ? `Reviewer produced empty output at ${retryResult.artifact.path}`\n : `Reviewer did not produce output at ${retryResult.artifact.path}`;\n return yield* Effect.fail(new ReviewerFailure({ message }));\n }\n\n const output = retryResult.artifact.value;\n\n const parsedVerdict = yield* Effect.try({\n try: () => parseReviewVerdict(output),\n catch: (error) => {\n if (error instanceof ReviewVerdictProtocolError) {\n return new ReviewerFailure({\n message: `Review protocol error: ${error.message}`,\n });\n }\n throw error;\n },\n }).pipe(\n Effect.catchAll((error) =>\n error instanceof ReviewerFailure\n ? Effect.fail(error)\n : Effect.die(error)\n )\n );\n\n logger.step(\"info\", `Review verdict: ${parsedVerdict}`);\n\n try {\n validateReviewArtifact(\n output,\n parsedVerdict,\n iteration ?? 1,\n !!priorRefactorArtifacts\n );\n } catch (error) {\n if (error instanceof ReviewArtifactValidationError) {\n return yield* Effect.fail(\n new ReviewerFailure({ message: error.message })\n );\n }\n yield* Effect.die(error);\n }\n\n return { verdict: parsedVerdict, output, artifactPath };\n });\n}\n\nfunction bridgeExecutionProvider(\n ep: import(\"../execution/execution-provider\").ExecutionProvider\n): Layer.Layer<ExecutionProviderService> {\n return Layer.succeed(\n ExecutionProviderService,\n ExecutionProviderService.of({\n execute: (opts) =>\n Effect.tryPromise({\n try: () => ep.execute(opts as any),\n catch: (e) =>\n new Error(\n e instanceof Error ? e.message : `Execution failed: ${String(e)}`\n ),\n }),\n })\n );\n}\n\nexport function runReviewCommand(\n options: RunReviewOptions\n): Effect.Effect<ReviewResult, ReviewerFailure> {\n const { executionProvider } = options;\n\n return runReviewCommandEffect(options).pipe(\n Effect.provide(\n Layer.merge(bridgeExecutionProvider(executionProvider), FileSystemDefault)\n )\n ) as Effect.Effect<ReviewResult, ReviewerFailure>;\n}\n\nfunction buildReviewerPromptEffect(\n repoRoot: string,\n promptTemplate: string,\n criteria: string[],\n artifactPathInWorktree: string,\n iteration: number,\n fs: {\n readonly exists: (path: string) => Effect.Effect<boolean, Error>;\n readonly readFile: (path: string) => Effect.Effect<string, Error>;\n },\n reviewHistory: string[] = [],\n priorRefactorArtifacts?: string,\n humanHandoffResolved?: boolean,\n priorReviewerArtifacts?: string\n): Effect.Effect<string> {\n return Effect.gen(function* () {\n const criteriaBlock = yield* renderReviewCriteriaEffect(\n repoRoot,\n criteria,\n fs\n );\n const { content: renderedTemplate, hasCriteriaPlaceholder } =\n yield* loadReviewerPromptTemplateEffect(\n repoRoot,\n promptTemplate,\n criteriaBlock,\n fs\n );\n\n const priorRefactorBlock = priorRefactorArtifacts\n ? `${priorRefactorArtifacts}`\n : \"\";\n const priorRefactorProtocolReminder = priorRefactorArtifacts\n ? `## Prior Refactor Protocol Reminder\n\nMANDATORY: because this prompt contains ## Prior Refactor Artifacts, your artifact must contain ## Prior Refactor Response Assessment exactly, before verdict. Section headings must match the names defined in this protocol exactly.\n\n`\n : \"\";\n const priorReviewerBlock = priorReviewerArtifacts\n ? `${priorReviewerArtifacts}`\n : \"\";\n const humanHandoffBoundary = humanHandoffResolved\n ? `## Human-Resolved Handoff Boundary\n\nA prior review emitted \\`NEEDS_HUMAN\\` and stopped the agent loop. The issue has since been moved back to \\`ready-for-agent\\`.\n\nBefore carrying forward old blockers, inspect newer issue comments and the current worktree. Treat prior Reviewer and Refactor Artifacts as historical context, not active findings unless they still apply.\n\n`\n : \"\";\n return appendProtectedWorkGuidance(`${renderedTemplate}\n\n## Shared Run Context\n\nRead the selected issue requirements, PRD context, branch context, verification commands, and artifact paths from: ${RUN_CONTEXT_PATH_IN_WORKTREE}\n\n## Initial Verification Pass\n\n- First read ${RUN_CONTEXT_PATH_IN_WORKTREE} only far enough to identify the configured verification commands.\n- Before reviewing code, diffs, artifacts, or prior findings, run each configured verification command yourself from the Worktree.\n- Run the commands exactly as configured. Do not substitute narrower commands unless the configured command cannot run.\n- If a configured command fails, keep reviewing after recording the failure details; use the failure output as review evidence.\n- If a command cannot run because the environment is missing required setup, dependencies, or scripts outside agent control, treat it as a human handoff blocker.\n- If no verification commands are configured, note that and proceed with normal review.\n\n## Scope Evidence Rules\n\n- Use the Run Context's canonical base ref, for example \\`origin/<base>\\`, for scope diffs and commit ranges.\n- Do not use bare PRD/base branch names such as \\`PRD-0063\\`, \\`main\\`, or \\`dev\\` for scope decisions; local branches with those names may be stale.\n- Only call a file or commit out of scope when it is part of the working branch's delta from the canonical base ref.\n- Do not recommend reverting accepted sibling/base work. If a file is present or changed on the canonical base ref, it is not this Issue's scope overreach.\n- If scope evidence is ambiguous, use \\`NEEDS_HUMAN\\` or ask for a runner/base mismatch decision instead of telling Refactor to revert files.\n\n${\n hasCriteriaPlaceholder\n ? \"\"\n : `## Review Criteria\n\n${criteriaBlock}\n\n`\n}${humanHandoffBoundary}${priorReviewerBlock}${renderReviewHistory(reviewHistory)}${priorRefactorBlock}${priorRefactorProtocolReminder}## Output\n\nWrite your review to: ${artifactPathInWorktree}\n\nBefore handoff, run: pourkit validate-artifact reviewer ${artifactPathInWorktree} --iteration ${iteration}${priorRefactorArtifacts ? \" --prior-refactor-artifacts\" : \"\"}\n\nDo not provide a separate chat response. The runner only reads the file above.\n\nEnd the file with exactly one wrapped verdict token: <verdict>PASS</verdict>, <verdict>PASS_WITH_NOTES</verdict>, <verdict>NEEDS_REFACTOR</verdict>, <verdict>FAIL</verdict>, or <verdict>NEEDS_HUMAN</verdict>. The verdict token must appear exactly once in the output.\n\nFindings must include an ID column with values in the format R${iteration}.F{findingNumber} (e.g., R${iteration}.F1, R${iteration}.F2) and a Supersedes column referencing the finding ID being superseded (or a hyphen for new findings).\n\nWhen verdict is NEEDS_HUMAN, include Human Handoff Summary and Human Handoff Reason sections before the final verdict token.`);\n });\n}\n\nfunction renderReviewHistory(reviewHistory: string[]): string {\n if (reviewHistory.length === 0) {\n return \"\";\n }\n\n return `## Review History\n\n${reviewHistory\n .map((entry, index) => `### Iteration ${index + 1}\\n\\n${entry.trimEnd()}`)\n .join(\"\\n\\n\")}\n\n`;\n}\n\nexport function renderPriorRefactorArtifactsEffect(\n worktreePath: string,\n currentIteration: number\n): Effect.Effect<string, never, FileSystem> {\n return Effect.gen(function* () {\n const fb = yield* FileSystem;\n const refactorsDir = join(worktreePath, \".pourkit\", \".tmp\", \"refactors\");\n const dirExists = yield* fb\n .exists(refactorsDir)\n .pipe(Effect.catchAll(() => Effect.succeed(false)));\n if (!dirExists) return \"\";\n\n const iterationFiles: { num: number; content: string }[] = [];\n for (let i = 0; i < currentIteration; i++) {\n const filePath = join(refactorsDir, `iteration-${i}.md`);\n const fileExists = yield* fb\n .exists(filePath)\n .pipe(Effect.catchAll(() => Effect.succeed(false)));\n if (!fileExists) continue;\n\n const content = yield* fb\n .readFile(filePath)\n .pipe(Effect.catchAll(() => Effect.succeed(\"\")));\n if (content.trim()) {\n iterationFiles.push({ num: i, content });\n }\n }\n\n if (iterationFiles.length === 0) return \"\";\n iterationFiles.sort((a, b) => a.num - b.num);\n\n const iterationsBlocks = iterationFiles\n .map((f) => `### Refactor Iteration ${f.num}\\n\\n${f.content.trimEnd()}`)\n .join(\"\\n\\n\");\n\n return `## Prior Refactor Artifacts\n\nTreat these as conversational context, not source of truth. Inspect the current code independently.\n\n${iterationsBlocks}\n\n`;\n });\n}\n\nexport function renderPriorReviewerArtifactsEffect(\n worktreePath: string,\n currentIteration: number\n): Effect.Effect<string, never, FileSystem> {\n return Effect.gen(function* () {\n const fb = yield* FileSystem;\n const reviewersDir = join(worktreePath, \".pourkit\", \".tmp\", \"reviewers\");\n const dirExists = yield* fb\n .exists(reviewersDir)\n .pipe(Effect.catchAll(() => Effect.succeed(false)));\n if (!dirExists) return \"\";\n\n const iterationFiles: { num: number; content: string }[] = [];\n for (let i = 0; i < currentIteration; i++) {\n const filePath = join(reviewersDir, `iteration-${i}.md`);\n const fileExists = yield* fb\n .exists(filePath)\n .pipe(Effect.catchAll(() => Effect.succeed(false)));\n if (!fileExists) continue;\n\n const content = yield* fb\n .readFile(filePath)\n .pipe(Effect.catchAll(() => Effect.succeed(\"\")));\n if (content.trim()) {\n iterationFiles.push({ num: i, content });\n }\n }\n\n if (iterationFiles.length === 0) return \"\";\n iterationFiles.sort((a, b) => a.num - b.num);\n\n const iterationsBlocks = iterationFiles\n .map((f) => `### Reviewer Iteration ${f.num}\\n\\n${f.content.trimEnd()}`)\n .join(\"\\n\\n\");\n\n return `## Prior Reviewer Artifacts\n\nA prior review was resolved by a human. These artifacts are historical context from before the handoff. Treat them as background, not active findings.\n\n${iterationsBlocks}\n\n`;\n });\n}\n\nfunction loadReviewerPromptTemplateEffect(\n repoRoot: string,\n promptTemplate: string,\n criteriaBlock: string,\n fs: {\n readonly exists: (path: string) => Effect.Effect<boolean, Error>;\n readonly readFile: (path: string) => Effect.Effect<string, Error>;\n }\n): Effect.Effect<{ content: string; hasCriteriaPlaceholder: boolean }> {\n return Effect.gen(function* () {\n const promptTemplatePath = resolvePromptTemplatePath(\n repoRoot,\n promptTemplate\n );\n const exists = yield* fs.exists(promptTemplatePath).pipe(Effect.orDie);\n const promptBody = exists\n ? yield* fs.readFile(promptTemplatePath).pipe(Effect.orDie)\n : promptTemplate;\n const hasCriteriaPlaceholder = promptBody.includes(\"{{REVIEW_CRITERIA}}\");\n\n return {\n content: promptBody.replace(/\\{\\{REVIEW_CRITERIA\\}\\}/g, criteriaBlock),\n hasCriteriaPlaceholder,\n };\n });\n}\n\nfunction renderReviewCriteriaEffect(\n repoRoot: string,\n criteria: string[],\n fs: {\n readonly exists: (path: string) => Effect.Effect<boolean, Error>;\n readonly readFile: (path: string) => Effect.Effect<string, Error>;\n }\n): Effect.Effect<string> {\n return Effect.gen(function* () {\n const parts: string[] = [];\n for (const criterion of criteria) {\n const snippetPath = join(\n repoRoot,\n \".pourkit\",\n \"prompts\",\n `reviewer-${criterion}.snippet.md`\n );\n const exists = yield* fs.exists(snippetPath).pipe(Effect.orDie);\n if (exists) {\n const content = yield* fs.readFile(snippetPath).pipe(Effect.orDie);\n parts.push(content.trimEnd());\n } else {\n parts.push(`- ${criterion}`);\n }\n }\n return parts.join(\"\\n\\n\");\n });\n}\n\nfunction recoverReviewOutputFromString(logContent: string): string | null {\n const startIndex = logContent.indexOf(\"## Findings\");\n if (startIndex === -1) return null;\n const verdictMatch = logContent\n .slice(startIndex)\n .match(\n /<verdict>(PASS|PASS_WITH_NOTES|NEEDS_REFACTOR|FAIL|NEEDS_HUMAN)<\\/verdict>/\n );\n if (!verdictMatch || verdictMatch.index === undefined) return null;\n const recoveredOutput = logContent\n .slice(startIndex, startIndex + verdictMatch.index + verdictMatch[0].length)\n .trim();\n return recoveredOutput.length > 0 ? recoveredOutput : null;\n}\n\nfunction recoverReviewOutputFromLog(logPath: string): string | null {\n if (!existsSync(logPath)) {\n return null;\n }\n\n const logContent = readFileSync(logPath, \"utf-8\");\n return recoverReviewOutputFromString(logContent);\n}\n\nfunction readReviewArtifact(\n artifactPath: string,\n logPath?: string | null\n): string {\n if (existsSync(artifactPath)) {\n const output = readFileSync(artifactPath, \"utf-8\");\n if (output.trim()) {\n return output;\n }\n }\n\n const recoveredOutput = logPath ? recoverReviewOutputFromLog(logPath) : null;\n\n if (recoveredOutput) {\n writeFileSync(artifactPath, recoveredOutput, \"utf-8\");\n return recoveredOutput;\n }\n\n if (!existsSync(artifactPath)) {\n throw new Error(`Reviewer did not produce output at ${artifactPath}`);\n }\n\n throw new Error(`Reviewer produced empty output at ${artifactPath}`);\n}\n\nexport type ReviewLoopVerdict =\n | \"PASS\"\n | \"PASS_WITH_NOTES\"\n | \"FAIL\"\n | \"NEEDS_HUMAN\";\n\nexport interface ReviewLoopResult {\n verdict: ReviewLoopVerdict;\n output: string;\n artifactPath: string;\n iterations: number;\n exhaustedMaxIterations: boolean;\n lifetimeIterations: number;\n refactorCompletedForLastReview: boolean;\n refactorArtifactPaths?: string[];\n}\n\nexport interface RunReviewLoopOptions {\n executionProvider: ExecutionProvider;\n config: PourkitConfig;\n target: Target;\n issue: IssueData;\n parentPrdIssue?: IssueData;\n builderBranch: string;\n worktreePath: string;\n repoRoot: string;\n logger: PourkitLogger;\n startingLifetimeIteration?: number;\n humanHandoffResolved?: boolean;\n serena?: SerenaExecutionContext;\n onRefactorProgress?: (progress: {\n lifetimeIterations: number;\n lastVerdict: ReviewVerdict;\n lastArtifactPath: string;\n refactorArtifactPath?: string;\n }) => void | Promise<void>;\n}\n\nexport function runReviewWithRefactorLoop(\n options: RunReviewLoopOptions\n): Effect.Effect<ReviewLoopResult> {\n const {\n executionProvider,\n config,\n target,\n issue,\n parentPrdIssue,\n builderBranch,\n worktreePath,\n repoRoot,\n logger,\n startingLifetimeIteration = 0,\n humanHandoffResolved,\n serena,\n } = options;\n\n const strategy = target.strategy;\n const reviewer = strategy.review.reviewer;\n if (!reviewer) {\n return Effect.die(new Error(\"No reviewer config found\"));\n }\n const refactorer = strategy.review.refactor;\n if (!refactorer) {\n return Effect.die(new Error(\"No refactorer config found\"));\n }\n const maxIterations = strategy.review.maxIterations;\n const passWithNotesRefactorAttempts =\n strategy.review.passWithNotesRefactorAttempts;\n let resolvedStartingIteration = startingLifetimeIteration;\n {\n const reviewersDir = join(worktreePath, \".pourkit\", \".tmp\", \"reviewers\");\n try {\n const files = readdirSync(reviewersDir);\n let maxExistingIteration = 0;\n for (const file of files) {\n const match = file.match(/^iteration-(\\d+)\\.md$/);\n if (match) {\n const num = parseInt(match[1], 10);\n if (num > maxExistingIteration) {\n maxExistingIteration = num;\n }\n }\n }\n if (maxExistingIteration > resolvedStartingIteration) {\n resolvedStartingIteration = maxExistingIteration;\n }\n } catch {\n // Directory may not exist yet\n }\n }\n\n interface LoopState {\n readonly done: boolean;\n readonly iteration: number;\n readonly lastResult: ReviewResult | null;\n readonly reviewHistory: readonly string[];\n readonly passWithNotesRefactorAttemptsRemaining: number;\n readonly accumulatedRefactorPaths: readonly string[];\n readonly doneResult: ReviewLoopResult | null;\n }\n\n const program = Effect.gen(function* () {\n const fs = yield* FileSystem;\n\n const priorReviewerArtifacts = humanHandoffResolved\n ? (yield* renderPriorReviewerArtifactsEffect(\n worktreePath,\n resolvedStartingIteration + 1\n )) || undefined\n : undefined;\n\n const initialState: LoopState = {\n done: false,\n iteration: 0,\n lastResult: null,\n reviewHistory: [],\n passWithNotesRefactorAttemptsRemaining: passWithNotesRefactorAttempts,\n accumulatedRefactorPaths: [],\n doneResult: null,\n };\n\n const finalState = yield* Effect.iterate(initialState, {\n while: (s) => !s.done && s.iteration < maxIterations,\n body: (s) =>\n Effect.gen(function* () {\n const iteration = s.iteration + 1;\n const lifetimeIteration = resolvedStartingIteration + iteration;\n logger.step(\"info\", `Review iteration ${lifetimeIteration}`);\n\n const priorRefactorArtifactsStr =\n yield* renderPriorRefactorArtifactsEffect(\n worktreePath,\n lifetimeIteration\n );\n\n const reviewResult = yield* runReviewCommandEffect({\n executionProvider: null as any,\n config,\n target,\n issue,\n builderBranch,\n worktreePath,\n repoRoot,\n logger,\n iteration: lifetimeIteration,\n priorRefactorArtifacts: priorRefactorArtifactsStr || undefined,\n humanHandoffResolved,\n priorReviewerArtifacts,\n reviewHistory:\n reviewer.includeReviewHistory && s.reviewHistory.length > 0\n ? [...s.reviewHistory]\n : undefined,\n });\n\n const updatedHistory = [...s.reviewHistory, reviewResult.output];\n\n yield* persistIterationArtifactEffect(\n worktreePath,\n reviewResult.output,\n lifetimeIteration,\n fs\n );\n\n if (reviewResult.verdict === \"PASS\") {\n return {\n ...s,\n done: true,\n iteration,\n lastResult: reviewResult,\n reviewHistory: updatedHistory,\n doneResult: {\n verdict: reviewResult.verdict as ReviewLoopVerdict,\n output: reviewResult.output,\n artifactPath: reviewResult.artifactPath,\n iterations: iteration,\n lifetimeIterations: lifetimeIteration,\n exhaustedMaxIterations: false,\n refactorCompletedForLastReview: false,\n refactorArtifactPaths:\n s.accumulatedRefactorPaths.length > 0\n ? [...s.accumulatedRefactorPaths]\n : undefined,\n },\n } satisfies LoopState;\n }\n\n if (\n reviewResult.verdict === \"PASS_WITH_NOTES\" &&\n s.passWithNotesRefactorAttemptsRemaining === 0\n ) {\n logger.step(\n \"info\",\n \"PASS_WITH_NOTES refactor attempts exhausted, treating as PASS\"\n );\n return {\n ...s,\n done: true,\n iteration,\n lastResult: reviewResult,\n reviewHistory: updatedHistory,\n doneResult: {\n verdict: \"PASS\",\n output: reviewResult.output,\n artifactPath: reviewResult.artifactPath,\n iterations: iteration,\n lifetimeIterations: lifetimeIteration,\n exhaustedMaxIterations: false,\n refactorCompletedForLastReview: false,\n refactorArtifactPaths:\n s.accumulatedRefactorPaths.length > 0\n ? [...s.accumulatedRefactorPaths]\n : undefined,\n },\n } satisfies LoopState;\n }\n\n let updatedPassWithNotesRefactorAttemptsRemaining =\n s.passWithNotesRefactorAttemptsRemaining;\n if (reviewResult.verdict === \"PASS_WITH_NOTES\") {\n updatedPassWithNotesRefactorAttemptsRemaining--;\n logger.step(\n \"info\",\n `PASS_WITH_NOTES refactor attempts remaining: ${updatedPassWithNotesRefactorAttemptsRemaining}`\n );\n }\n\n if (reviewResult.verdict === \"NEEDS_HUMAN\") {\n logger.step(\"info\", \"NEEDS_HUMAN verdict, stopping review loop\");\n return {\n ...s,\n done: true,\n iteration,\n lastResult: reviewResult,\n reviewHistory: updatedHistory,\n doneResult: {\n verdict: \"NEEDS_HUMAN\",\n output: reviewResult.output,\n artifactPath: reviewResult.artifactPath,\n iterations: iteration,\n lifetimeIterations: lifetimeIteration,\n exhaustedMaxIterations: false,\n refactorCompletedForLastReview: false,\n refactorArtifactPaths:\n s.accumulatedRefactorPaths.length > 0\n ? [...s.accumulatedRefactorPaths]\n : undefined,\n },\n } satisfies LoopState;\n }\n\n if (\n reviewResult.verdict === \"NEEDS_REFACTOR\" ||\n reviewResult.verdict === \"PASS_WITH_NOTES\" ||\n reviewResult.verdict === \"FAIL\"\n ) {\n logger.step(\"info\", \"Running refactor agent\");\n const refactorArtifactPathInWorktree = join(\n \".pourkit\",\n \".tmp\",\n \"refactors\",\n `iteration-${lifetimeIteration}.md`\n );\n\n const refactorPrompt = yield* buildRefactorPromptEffect(\n repoRoot,\n refactorer.promptTemplate,\n reviewResult.output,\n refactorArtifactPathInWorktree,\n lifetimeIteration,\n fs\n );\n\n const refactorRetryResult = yield* Effect.tryPromise(() =>\n executeWithMissingOrEmptyArtifactRetry({\n executionProvider,\n missingOrEmptyRetries:\n resolveMissingOrEmptyOutputRetries(refactorer),\n executionOptions: {\n stage: \"refactor\" as const,\n iteration: lifetimeIteration,\n agent: refactorer.agent,\n model: refactorer.model,\n variant: refactorer.variant,\n env: refactorer.env,\n prompt: refactorPrompt,\n target,\n repoRoot,\n branchName: builderBranch,\n sandbox: config.sandbox,\n autoApprove: true,\n artifactPath: refactorArtifactPathInWorktree,\n worktreePath,\n artifacts: [\n buildRunContextArtifact({\n issue,\n parentPrdIssue,\n target,\n branchName: builderBranch,\n repoRoot,\n reviewerCriteria: reviewer.criteria,\n sections: STAGE_SECTIONS.refactor,\n }),\n ],\n ...(serena ? { serena: serena as any } : {}),\n logger,\n },\n })\n );\n const refactorResult = refactorRetryResult.executionResult;\n\n if (!refactorResult.success) {\n logger.step(\n \"warn\",\n \"Refactor execution failed, transitioning to ready-for-human\"\n );\n return {\n ...s,\n done: true,\n iteration,\n lastResult: reviewResult,\n reviewHistory: updatedHistory,\n doneResult: {\n verdict: \"FAIL\",\n output: reviewResult.output,\n artifactPath: reviewResult.artifactPath,\n iterations: iteration,\n lifetimeIterations: resolvedStartingIteration + iteration,\n exhaustedMaxIterations: false,\n refactorCompletedForLastReview: false,\n refactorArtifactPaths:\n s.accumulatedRefactorPaths.length > 0\n ? [...s.accumulatedRefactorPaths]\n : undefined,\n },\n } satisfies LoopState;\n }\n\n if (refactorRetryResult.artifact._tag !== \"content\") {\n logger.step(\n \"warn\",\n `Refactor artifact validation failed: ${\n refactorRetryResult.artifact._tag === \"empty\"\n ? `Refactor artifact is empty at ${refactorRetryResult.artifact.path}`\n : `Refactor artifact missing at ${refactorRetryResult.artifact.path}`\n }`\n );\n return {\n ...s,\n done: true,\n iteration,\n lastResult: reviewResult,\n reviewHistory: updatedHistory,\n doneResult: {\n verdict: \"FAIL\",\n output: reviewResult.output,\n artifactPath: reviewResult.artifactPath,\n iterations: iteration,\n lifetimeIterations: resolvedStartingIteration + iteration,\n exhaustedMaxIterations: false,\n refactorCompletedForLastReview: false,\n refactorArtifactPaths:\n s.accumulatedRefactorPaths.length > 0\n ? [...s.accumulatedRefactorPaths]\n : undefined,\n },\n } satisfies LoopState;\n }\n\n const latestFindingIds = extractLatestFindingIds(\n reviewResult.output,\n lifetimeIteration\n );\n const refactorArtifactPath = join(\n worktreePath,\n refactorArtifactPathInWorktree\n );\n try {\n validateRefactorArtifact(refactorArtifactPath, latestFindingIds);\n } catch (error) {\n if (error instanceof RefactorArtifactValidationError) {\n logger.step(\n \"warn\",\n `Refactor artifact validation failed: ${error.message}`\n );\n return {\n ...s,\n done: true,\n iteration,\n lastResult: reviewResult,\n reviewHistory: updatedHistory,\n doneResult: {\n verdict: \"FAIL\",\n output: reviewResult.output,\n artifactPath: reviewResult.artifactPath,\n iterations: iteration,\n lifetimeIterations: resolvedStartingIteration + iteration,\n exhaustedMaxIterations: false,\n refactorCompletedForLastReview: false,\n refactorArtifactPaths:\n s.accumulatedRefactorPaths.length > 0\n ? [...s.accumulatedRefactorPaths]\n : undefined,\n },\n } satisfies LoopState;\n }\n yield* Effect.die(error);\n }\n\n const updatedAccumulated = [\n ...s.accumulatedRefactorPaths,\n refactorArtifactPath,\n ];\n if (options.onRefactorProgress) {\n yield* Effect.promise(() =>\n Promise.resolve(\n options.onRefactorProgress!({\n lifetimeIterations: resolvedStartingIteration + iteration,\n lastVerdict: reviewResult.verdict,\n lastArtifactPath: reviewResult.artifactPath,\n refactorArtifactPath,\n })\n )\n );\n }\n\n return {\n done: false,\n iteration,\n lastResult: reviewResult,\n reviewHistory: updatedHistory,\n passWithNotesRefactorAttemptsRemaining:\n updatedPassWithNotesRefactorAttemptsRemaining,\n accumulatedRefactorPaths: updatedAccumulated,\n doneResult: null,\n } satisfies LoopState;\n }\n\n return {\n done: false,\n iteration,\n lastResult: reviewResult,\n reviewHistory: updatedHistory,\n passWithNotesRefactorAttemptsRemaining:\n updatedPassWithNotesRefactorAttemptsRemaining,\n accumulatedRefactorPaths: s.accumulatedRefactorPaths,\n doneResult: null,\n } satisfies LoopState;\n }),\n });\n\n if (finalState.done && finalState.doneResult) {\n return finalState.doneResult;\n }\n\n logger.step(\"warn\", `Max review iterations (${maxIterations}) exhausted`);\n return {\n verdict: \"FAIL\" as ReviewLoopVerdict,\n output: finalState.lastResult?.output ?? \"\",\n artifactPath: finalState.lastResult?.artifactPath ?? \"\",\n iterations: finalState.iteration,\n lifetimeIterations: resolvedStartingIteration + finalState.iteration,\n exhaustedMaxIterations: true,\n refactorCompletedForLastReview: true,\n refactorArtifactPaths:\n finalState.accumulatedRefactorPaths.length > 0\n ? [...finalState.accumulatedRefactorPaths]\n : undefined,\n };\n });\n\n const executionLayer = bridgeExecutionProvider(executionProvider);\n return program.pipe(\n Effect.provide(Layer.merge(executionLayer, FileSystemDefault))\n ) as Effect.Effect<ReviewLoopResult>;\n}\n\nexport function persistIterationArtifactEffect(\n worktreePath: string,\n output: string,\n iteration: number,\n fs: {\n readonly mkdir: (path: string) => Effect.Effect<void, Error>;\n readonly writeFile: (\n path: string,\n content: string\n ) => Effect.Effect<void, Error>;\n }\n): Effect.Effect<void> {\n return Effect.gen(function* () {\n const dir = join(worktreePath, \".pourkit\", \".tmp\", \"reviewers\");\n yield* fs.mkdir(dir).pipe(Effect.catchAll(() => Effect.void));\n yield* fs\n .writeFile(join(dir, `iteration-${iteration}.md`), output)\n .pipe(Effect.catchAll(() => Effect.void));\n });\n}\n\nasync function writeArtifact(\n worktreePath: string,\n filename: string,\n output: string\n) {\n try {\n const dir = join(worktreePath, \".pourkit\", \".tmp\", \"reviewers\");\n mkdirSync(dir, { recursive: true });\n writeFileSync(join(dir, filename), output, \"utf-8\");\n } catch {\n // Do not fail pipeline on artifact write errors\n }\n}\n\nasync function persistIterationArtifact(\n worktreePath: string,\n output: string,\n iteration: number\n) {\n await writeArtifact(worktreePath, `iteration-${iteration}.md`, output);\n}\n\nfunction buildRefactorPromptEffect(\n repoRoot: string,\n promptTemplate: string,\n latestReview: string,\n artifactPathInWorktree: string,\n iteration: number,\n fs: {\n readonly exists: (path: string) => Effect.Effect<boolean, Error>;\n readonly readFile: (path: string) => Effect.Effect<string, Error>;\n }\n): Effect.Effect<string> {\n return Effect.gen(function* () {\n const promptTemplatePath = resolvePromptTemplatePath(\n repoRoot,\n promptTemplate\n );\n const exists = yield* fs.exists(promptTemplatePath).pipe(Effect.orDie);\n const promptBody = exists\n ? yield* fs.readFile(promptTemplatePath).pipe(Effect.orDie)\n : promptTemplate;\n\n const findingIds = extractLatestFindingIds(latestReview, iteration);\n const findingArgs = findingIds.map((id) => ` --finding-id ${id}`).join(\"\");\n\n return appendProtectedWorkGuidance(`${promptBody}\n\n## Shared Run Context\n\nRead the selected issue requirements, PRD context, branch context, verification commands, and artifact paths from: ${RUN_CONTEXT_PATH_IN_WORKTREE}\n\n## Latest Review\n\n${latestReview.trimEnd()}\n\n## Output\n\nWrite your refactor artifact to: ${artifactPathInWorktree}\n\nBefore handoff, run: pourkit validate-artifact refactor ${artifactPathInWorktree} --iteration ${iteration}${findingArgs}\n\nWhen you are done, finish with <promise>COMPLETE</promise>.`);\n });\n}\n","import { existsSync, mkdirSync, readFileSync, rmSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport type {\n ExecutionProvider,\n ExecutionProviderOptions,\n ExecutionResult,\n} from \"./execution-provider\";\nimport type { PourkitLogger } from \"../shared/common\";\n\nexport type ArtifactOutputStatus =\n | { readonly _tag: \"content\"; readonly value: string; readonly path: string }\n | { readonly _tag: \"empty\"; readonly path: string }\n | { readonly _tag: \"missing\"; readonly path: string };\n\nexport interface AgentOutputRetryResult {\n readonly executionResult: ExecutionResult;\n readonly artifact: ArtifactOutputStatus;\n readonly attempts: number;\n}\n\nexport interface ExecuteWithMissingOrEmptyArtifactRetryOptions {\n readonly executionProvider: Pick<ExecutionProvider, \"execute\">;\n readonly executionOptions: ExecutionProviderOptions;\n readonly missingOrEmptyRetries: number;\n readonly logger?: PourkitLogger;\n readonly readArtifact?: (\n artifactPath: string,\n executionResult: ExecutionResult\n ) => ArtifactOutputStatus | Promise<ArtifactOutputStatus>;\n readonly runningMessage?: (attempt: number, total: number) => string;\n readonly retryMessage?: (attempt: number, total: number) => string;\n}\n\nexport async function executeWithMissingOrEmptyArtifactRetry({\n executionProvider,\n executionOptions,\n missingOrEmptyRetries,\n logger,\n readArtifact,\n runningMessage,\n retryMessage,\n}: ExecuteWithMissingOrEmptyArtifactRetryOptions): Promise<AgentOutputRetryResult> {\n if (!executionOptions.artifactPath) {\n throw new Error(\"Artifact retry requires executionOptions.artifactPath\");\n }\n\n const totalAttempts = missingOrEmptyRetries + 1;\n let lastResult: ExecutionResult | undefined;\n let lastArtifact: ArtifactOutputStatus | undefined;\n\n for (let attempt = 1; attempt <= totalAttempts; attempt += 1) {\n const message =\n attempt === 1\n ? runningMessage?.(attempt, totalAttempts)\n : retryMessage?.(attempt, totalAttempts);\n if (message) logger?.step(\"info\", message);\n\n prepareArtifactPath(\n join(\n executionOptions.worktreePath ?? executionOptions.repoRoot,\n executionOptions.artifactPath\n )\n );\n\n const executionResult = await executionProvider.execute(executionOptions);\n lastResult = executionResult;\n\n if (!executionResult.success) {\n return {\n executionResult,\n artifact: {\n _tag: \"missing\",\n path: join(\n executionResult.worktreePath,\n executionOptions.artifactPath\n ),\n },\n attempts: attempt,\n };\n }\n\n const fullArtifactPath = join(\n executionResult.worktreePath,\n executionOptions.artifactPath\n );\n const artifact = readArtifact\n ? await readArtifact(fullArtifactPath, executionResult)\n : readArtifactOutput(fullArtifactPath);\n lastArtifact = artifact;\n if (artifact._tag === \"content\") {\n return { executionResult, artifact, attempts: attempt };\n }\n }\n\n return {\n executionResult: lastResult!,\n artifact: lastArtifact!,\n attempts: totalAttempts,\n };\n}\n\nfunction readArtifactOutput(artifactPath: string): ArtifactOutputStatus {\n if (!existsSync(artifactPath)) {\n return { _tag: \"missing\", path: artifactPath };\n }\n const output = readFileSync(artifactPath, \"utf-8\");\n if (!output.trim()) {\n return { _tag: \"empty\", path: artifactPath };\n }\n return { _tag: \"content\", value: output, path: artifactPath };\n}\n\nfunction prepareArtifactPath(artifactPath: string): void {\n mkdirSync(dirname(artifactPath), { recursive: true });\n rmSync(artifactPath, { recursive: true, force: true });\n}\n","import { Context, Effect, Layer } from \"effect\";\nimport { existsSync, mkdirSync, readFileSync, writeFileSync, rmSync } from \"fs\";\nimport {\n writeAttemptLog,\n readAttemptLog,\n type AttemptLogEntry,\n} from \"./attempt-log\";\nimport {\n readWorktreeRunState,\n writeWorktreeRunState,\n updateWorktreeRunState,\n type WorktreeRunState,\n} from \"./worktree-run-state\";\nimport type { Target, SandboxConfig } from \"./config\";\nimport type { ExecutionArtifact } from \"./run-context\";\nimport type { SerenaExecutionContext } from \"../execution/opencode-config\";\nimport type { PourkitLogger } from \"./common\";\nimport type { PourkitStage } from \"../execution/execution-provider\";\n\nclass GitExecutionError extends Error {\n readonly _tag: \"GitExecutionError\" = \"GitExecutionError\";\n readonly message: string;\n\n constructor(args: { readonly message: string }) {\n super(args.message);\n this.name = \"GitExecutionError\";\n this.message = args.message;\n }\n}\n\nexport class FileSystem extends Context.Tag(\"FileSystem\")<\n FileSystem,\n {\n readonly readFile: (path: string) => Effect.Effect<string, Error>;\n readonly writeFile: (\n path: string,\n content: string\n ) => Effect.Effect<void, Error>;\n readonly exists: (path: string) => Effect.Effect<boolean, Error>;\n readonly mkdir: (path: string) => Effect.Effect<void, Error>;\n readonly remove: (path: string) => Effect.Effect<void, Error>;\n }\n>() {}\n\nexport const FileSystemDefault: Layer.Layer<FileSystem> = Layer.succeed(\n FileSystem,\n FileSystem.of({\n readFile: (path) =>\n Effect.try({\n try: () => readFileSync(path, \"utf-8\"),\n catch: (error) =>\n new Error(\n `Failed to read file ${path}: ${error instanceof Error ? error.message : String(error)}`\n ),\n }),\n writeFile: (path, content) =>\n Effect.try({\n try: () => writeFileSync(path, content, \"utf-8\"),\n catch: (error) =>\n new Error(\n `Failed to write file ${path}: ${error instanceof Error ? error.message : String(error)}`\n ),\n }),\n exists: (path) =>\n Effect.try({\n try: () => existsSync(path),\n catch: (error) =>\n new Error(\n `Failed to check existence of ${path}: ${error instanceof Error ? error.message : String(error)}`\n ),\n }),\n mkdir: (path) =>\n Effect.try({\n try: () => mkdirSync(path, { recursive: true }),\n catch: (error) =>\n new Error(\n `Failed to create directory ${path}: ${error instanceof Error ? error.message : String(error)}`\n ),\n }),\n remove: (path) =>\n Effect.try({\n try: () => rmSync(path, { recursive: true, force: true }),\n catch: (error) =>\n new Error(\n `Failed to remove ${path}: ${error instanceof Error ? error.message : String(error)}`\n ),\n }),\n })\n);\n\nexport const FileSystemTest: Layer.Layer<FileSystem> = Layer.succeed(\n FileSystem,\n FileSystem.of({\n readFile: (path) => Effect.succeed(`test content for ${path}`),\n writeFile: (_path, _content) => Effect.void,\n exists: (_path) => Effect.succeed(true),\n mkdir: (_path) => Effect.void,\n remove: (_path) => Effect.void,\n })\n);\n\nexport class GitOperations extends Context.Tag(\"GitOperations\")<\n GitOperations,\n {\n readonly exec: (\n args: string[],\n options?: { readonly cwd?: string }\n ) => Effect.Effect<\n { readonly stdout: string; readonly stderr: string },\n GitExecutionError\n >;\n readonly revParse: (\n ref: string,\n cwd: string\n ) => Effect.Effect<string, GitExecutionError>;\n readonly fetch: (\n remote: string,\n branch: string,\n cwd: string\n ) => Effect.Effect<void, GitExecutionError>;\n readonly mergeBaseIsAncestor: (\n baseRef: string,\n cwd: string\n ) => Effect.Effect<boolean, GitExecutionError>;\n }\n>() {}\n\nexport const GitOperationsDefault: Layer.Layer<GitOperations> = Layer.succeed(\n GitOperations,\n GitOperations.of({\n exec: (args, options) =>\n Effect.tryPromise({\n try: async () => {\n const { execCapture } = await import(\"./common\");\n const result = await execCapture(\"git\", args, {\n cwd: options?.cwd,\n });\n return { stdout: result.stdout, stderr: result.stderr };\n },\n catch: (error) =>\n new GitExecutionError({\n message:\n error instanceof Error\n ? error.message\n : `git exec failed: ${String(error)}`,\n }),\n }),\n revParse: (ref, cwd) =>\n Effect.tryPromise({\n try: async () => {\n const { execCapture } = await import(\"./common\");\n const result = await execCapture(\"git\", [\"rev-parse\", ref], {\n cwd,\n });\n return result.stdout.trim();\n },\n catch: (error) =>\n new GitExecutionError({\n message:\n error instanceof Error\n ? error.message\n : `git rev-parse failed: ${String(error)}`,\n }),\n }),\n fetch: (remote, branch, cwd) =>\n Effect.tryPromise({\n try: async () => {\n const { execCapture } = await import(\"./common\");\n await execCapture(\"git\", [\"fetch\", remote, branch], { cwd });\n },\n catch: (error) =>\n new GitExecutionError({\n message:\n error instanceof Error\n ? error.message\n : `git fetch failed: ${String(error)}`,\n }),\n }),\n mergeBaseIsAncestor: (baseRef, cwd) =>\n Effect.tryPromise({\n try: async () => {\n const { execCapture } = await import(\"./common\");\n await execCapture(\n \"git\",\n [\"merge-base\", \"--is-ancestor\", baseRef, \"HEAD\"],\n { cwd }\n );\n return true;\n },\n catch: (error) =>\n new GitExecutionError({\n message:\n error instanceof Error\n ? error.message\n : `git merge-base failed: ${String(error)}`,\n }),\n }).pipe(\n Effect.catchIf(\n (error): error is GitExecutionError =>\n error instanceof GitExecutionError &&\n error.message.includes(\"merge-base --is-ancestor\") &&\n error.message.includes(\"exit code: 1\"),\n () => Effect.succeed(false)\n )\n ),\n })\n);\n\nexport const GitOperationsTest: Layer.Layer<GitOperations> = Layer.succeed(\n GitOperations,\n GitOperations.of({\n exec: (_args, _options) => Effect.succeed({ stdout: \"\", stderr: \"\" }),\n revParse: (_ref, _cwd) => Effect.succeed(\"abc123def456\"),\n fetch: (_remote, _branch, _cwd) => Effect.void,\n mergeBaseIsAncestor: (_baseRef, _cwd) => Effect.succeed(true),\n })\n);\n\nexport class GitHubApiClient extends Context.Tag(\"GitHubApiClient\")<\n GitHubApiClient,\n {\n readonly getIssue: (\n owner: string,\n repo: string,\n issueNumber: number\n ) => Effect.Effect<unknown, Error>;\n readonly createIssueComment: (\n owner: string,\n repo: string,\n issueNumber: number,\n body: string\n ) => Effect.Effect<unknown, Error>;\n readonly updateIssue: (\n owner: string,\n repo: string,\n issueNumber: number,\n update: Record<string, unknown>\n ) => Effect.Effect<unknown, Error>;\n }\n>() {}\n\nexport const GitHubApiClientTest: Layer.Layer<GitHubApiClient> = Layer.succeed(\n GitHubApiClient,\n GitHubApiClient.of({\n getIssue: (_owner, _repo, _issueNumber) =>\n Effect.succeed({ data: { title: \"Test Issue\", state: \"open\" } }),\n createIssueComment: (_owner, _repo, _issueNumber, _body) =>\n Effect.succeed({ data: { id: 1 } }),\n updateIssue: (_owner, _repo, _issueNumber, _update) =>\n Effect.succeed({ data: { number: _issueNumber } }),\n })\n);\n\nexport class ExecutionProvider extends Context.Tag(\"ExecutionProvider\")<\n ExecutionProvider,\n {\n readonly execute: (\n options: ExecutionProviderOptions\n ) => Effect.Effect<ExecutionResult, Error>;\n }\n>() {}\n\ninterface ExecutionProviderOptions {\n readonly stage: PourkitStage;\n readonly agent: string;\n readonly model: string;\n readonly variant?: string;\n readonly env?: Record<string, string>;\n readonly prompt: string;\n readonly worktreePath?: string;\n readonly target: Target;\n readonly repoRoot: string;\n readonly branchName: string;\n readonly sandbox: SandboxConfig;\n readonly logger: PourkitLogger;\n readonly iteration?: number;\n readonly artifactPath?: string;\n readonly baseRef?: string;\n readonly serena?: SerenaExecutionContext;\n readonly autoApprove?: boolean;\n readonly timeoutMs?: number;\n readonly artifacts?: ExecutionArtifact[];\n}\n\ninterface ExecutionResult {\n readonly success: boolean;\n readonly branch: string;\n readonly worktreePath: string;\n readonly commits: string[];\n readonly error?: string;\n readonly logPath?: string | null;\n}\n\nexport const ExecutionProviderTest: Layer.Layer<ExecutionProvider> =\n Layer.succeed(\n ExecutionProvider,\n ExecutionProvider.of({\n execute: (_options) =>\n Effect.succeed({\n success: true,\n branch: \"test-branch\",\n worktreePath: _options.worktreePath ?? \"/tmp/worktree\",\n commits: [\"abc123\"],\n logPath: \"/tmp/test-log\",\n }),\n })\n );\n\nexport class AttemptLogService extends Context.Tag(\"AttemptLogService\")<\n AttemptLogService,\n {\n readonly writeEntry: (\n worktreePath: string,\n entry: AttemptLogEntry\n ) => Effect.Effect<void, Error>;\n readonly readEntries: (\n worktreePath: string\n ) => Effect.Effect<readonly AttemptLogEntry[], Error>;\n }\n>() {}\n\nexport const AttemptLogServiceTest: Layer.Layer<AttemptLogService> =\n Layer.succeed(\n AttemptLogService,\n AttemptLogService.of({\n writeEntry: (_worktreePath, _entry) => Effect.void,\n readEntries: (_worktreePath) => Effect.succeed([]),\n })\n );\n\nexport class WorktreeRunStateService extends Context.Tag(\n \"WorktreeRunStateService\"\n)<\n WorktreeRunStateService,\n {\n readonly read: (\n worktreePath: string\n ) => Effect.Effect<WorktreeRunState | null, Error>;\n readonly write: (\n worktreePath: string,\n state: WorktreeRunState\n ) => Effect.Effect<void, Error>;\n readonly update: (\n worktreePath: string,\n update: Partial<WorktreeRunState>\n ) => Effect.Effect<void, Error>;\n }\n>() {}\n\nconst WorktreeRunStateServiceTestTimestamp = \"2026-01-01T00:00:00.000Z\";\n\nexport const WorktreeRunStateServiceTest: Layer.Layer<WorktreeRunStateService> =\n Layer.succeed(\n WorktreeRunStateService,\n WorktreeRunStateService.of({\n read: (_worktreePath) =>\n Effect.succeed({\n issueNumber: 0,\n targetName: \"test\",\n branchName: \"test-branch\",\n baseBranch: \"main\",\n createdAt: WorktreeRunStateServiceTestTimestamp,\n updatedAt: WorktreeRunStateServiceTestTimestamp,\n completedStages: {},\n review: {\n lifetimeIterations: 0,\n },\n }),\n write: (_worktreePath, _state) => Effect.void,\n update: (_worktreePath, _update) => Effect.void,\n })\n );\n","export interface PrDescription {\n title: string;\n body: string;\n}\n\nconst CONVENTIONAL_TITLE_PATTERN =\n /^(feat|fix|perf|refactor|docs|test|chore|ci|build)(\\([^)]+\\))?!?:\\s+\\S/;\n\nexport class PrDescriptionProtocolError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"PrDescriptionProtocolError\";\n }\n}\n\nconst SECTION_HEADING_PATTERN = /^## (PR Title|PR Body)\\s*$/gm;\n\ninterface SectionMatch {\n heading: \"PR Title\" | \"PR Body\";\n startIndex: number;\n endIndex: number;\n}\n\nfunction extractSections(output: string): SectionMatch[] {\n const sections: SectionMatch[] = [];\n let match: RegExpExecArray | null;\n\n const re = new RegExp(SECTION_HEADING_PATTERN);\n while ((match = re.exec(output)) !== null) {\n const heading = match[1] as \"PR Title\" | \"PR Body\";\n sections.push({\n heading,\n startIndex: match.index,\n endIndex: match.index + match[0].length,\n });\n }\n\n return sections;\n}\n\nfunction contentAfter(\n output: string,\n sections: SectionMatch[],\n section: SectionMatch\n): string {\n const index = sections.indexOf(section);\n const nextSection = sections[index + 1];\n const start = section.endIndex;\n const end = nextSection?.startIndex ?? output.length;\n return output.slice(start, end).trim();\n}\n\nexport function parsePrDescription(output: string): PrDescription {\n const sections = extractSections(output);\n\n const titleSections = sections.filter((s) => s.heading === \"PR Title\");\n const bodySections = sections.filter((s) => s.heading === \"PR Body\");\n\n if (titleSections.length === 0) {\n throw new PrDescriptionProtocolError(\n 'Missing required section \"## PR Title\"'\n );\n }\n if (titleSections.length > 1) {\n throw new PrDescriptionProtocolError(\n `Duplicate \"## PR Title\" sections found (${titleSections.length})`\n );\n }\n if (bodySections.length === 0) {\n throw new PrDescriptionProtocolError(\n 'Missing required section \"## PR Body\"'\n );\n }\n if (bodySections.length > 1) {\n throw new PrDescriptionProtocolError(\n `Duplicate \"## PR Body\" sections found (${bodySections.length})`\n );\n }\n\n const title = contentAfter(output, sections, titleSections[0]);\n const body = contentAfter(output, sections, bodySections[0]);\n\n if (title.length === 0) {\n throw new PrDescriptionProtocolError('\"## PR Title\" section is empty');\n }\n if (body.length === 0) {\n throw new PrDescriptionProtocolError('\"## PR Body\" section is empty');\n }\n\n return { title, body };\n}\n\nexport function ensureConventionalPrTitle(\n title: string,\n commitSummaries: string\n): string {\n const trimmedTitle = title.trim();\n const normalizedTitle =\n trimmedTitle.match(/^`([^`]+)`$/)?.[1] ?? trimmedTitle;\n if (CONVENTIONAL_TITLE_PATTERN.test(normalizedTitle)) {\n return normalizedTitle;\n }\n\n const inferredType = inferConventionalType(commitSummaries) ?? \"chore\";\n return `${inferredType}: ${normalizedTitle}`;\n}\n\nfunction inferConventionalType(commitSummaries: string): string | null {\n for (const line of commitSummaries.split(\"\\n\")) {\n const subject = line.trim().replace(/^[0-9a-f]+\\s+/, \"\");\n const match = subject.match(CONVENTIONAL_TITLE_PATTERN);\n if (match) {\n return match[1];\n }\n }\n\n return null;\n}\n","import path from \"node:path\";\nimport { access, mkdir } from \"node:fs/promises\";\nimport { execCapture } from \"../shared/common\";\n\nexport interface SerenaPaths {\n rootDir: string;\n baselineWorktreePath: string;\n dataDir: string;\n}\n\nexport interface RefreshSerenaBaselineOptions {\n repoRoot: string;\n dataDir?: string;\n remoteName?: string;\n baseBranch: string;\n}\n\nexport interface SerenaBaselineStatus {\n exists: boolean;\n baselineWorktreePath: string;\n currentCommit?: string;\n expectedRef: string;\n fresh?: boolean;\n}\n\nexport function resolveSerenaPaths(\n repoRoot: string,\n dataDir = \".pourkit/serena/\"\n): SerenaPaths {\n const rootDir = path.isAbsolute(dataDir)\n ? path.normalize(dataDir)\n : path.resolve(repoRoot, dataDir);\n\n return {\n rootDir,\n baselineWorktreePath: path.join(rootDir, \"baseline\", \"active-repo\"),\n dataDir: path.join(rootDir, \"data\"),\n };\n}\n\nasync function pathExists(dirPath: string): Promise<boolean> {\n try {\n await access(dirPath);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function isGitRepoRoot(repoPath: string): Promise<boolean> {\n try {\n const result = await execCapture(\"git\", [\"rev-parse\", \"--show-toplevel\"], {\n cwd: repoPath,\n label: \"git rev-parse --show-toplevel\",\n });\n return path.resolve(result.stdout.trim()) === path.resolve(repoPath);\n } catch {\n return false;\n }\n}\n\nexport async function ensureBaselineWorktree(options: {\n repoRoot: string;\n dataDir?: string;\n}): Promise<SerenaPaths> {\n const paths = resolveSerenaPaths(options.repoRoot, options.dataDir);\n\n await mkdir(paths.rootDir, { recursive: true });\n await mkdir(paths.dataDir, { recursive: true });\n\n if (!(await pathExists(paths.baselineWorktreePath))) {\n await mkdir(path.dirname(paths.baselineWorktreePath), { recursive: true });\n await execCapture(\n \"git\",\n [\"clone\", options.repoRoot, paths.baselineWorktreePath],\n {\n cwd: options.repoRoot,\n label: \"git clone baseline worktree\",\n }\n );\n return paths;\n }\n\n if (!(await isGitRepoRoot(paths.baselineWorktreePath))) {\n throw new Error(\n `Serena baseline worktree exists but is not a git repo: ${paths.baselineWorktreePath}`\n );\n }\n\n return paths;\n}\n\nexport async function getSerenaBaselineStatus(\n options: RefreshSerenaBaselineOptions\n): Promise<SerenaBaselineStatus> {\n const remoteName = options.remoteName ?? \"origin\";\n const paths = resolveSerenaPaths(options.repoRoot, options.dataDir);\n const expectedRef = `${remoteName}/${options.baseBranch}`;\n\n if (!(await pathExists(paths.baselineWorktreePath))) {\n return {\n exists: false,\n baselineWorktreePath: paths.baselineWorktreePath,\n expectedRef,\n fresh: false,\n };\n }\n\n if (!(await isGitRepoRoot(paths.baselineWorktreePath))) {\n return {\n exists: false,\n baselineWorktreePath: paths.baselineWorktreePath,\n expectedRef,\n fresh: false,\n };\n }\n\n let currentCommit: string | undefined;\n try {\n const currentResult = await execCapture(\"git\", [\"rev-parse\", \"HEAD\"], {\n cwd: paths.baselineWorktreePath,\n label: \"git rev-parse HEAD\",\n });\n currentCommit = currentResult.stdout.trim() || undefined;\n } catch {\n return {\n exists: true,\n baselineWorktreePath: paths.baselineWorktreePath,\n expectedRef,\n fresh: false,\n };\n }\n\n let expectedCommit: string | undefined;\n try {\n const expectedResult = await execCapture(\n \"git\",\n [\"rev-parse\", expectedRef],\n {\n cwd: paths.baselineWorktreePath,\n label: `git rev-parse ${expectedRef}`,\n }\n );\n expectedCommit = expectedResult.stdout.trim() || undefined;\n } catch {\n return {\n exists: true,\n baselineWorktreePath: paths.baselineWorktreePath,\n currentCommit,\n expectedRef,\n fresh: false,\n };\n }\n\n return {\n exists: true,\n baselineWorktreePath: paths.baselineWorktreePath,\n currentCommit,\n expectedRef,\n fresh: currentCommit === expectedCommit,\n };\n}\n\nexport async function refreshSerenaBaseline(\n options: RefreshSerenaBaselineOptions\n): Promise<SerenaBaselineStatus> {\n const remoteName = options.remoteName ?? \"origin\";\n const paths = await ensureBaselineWorktree(options);\n\n await execCapture(\"git\", [\"fetch\", remoteName, options.baseBranch], {\n cwd: paths.baselineWorktreePath,\n label: \"git fetch baseline branch\",\n });\n\n await execCapture(\n \"git\",\n [\"checkout\", \"--detach\", `${remoteName}/${options.baseBranch}`],\n {\n cwd: paths.baselineWorktreePath,\n label: \"git checkout detached baseline branch\",\n }\n );\n\n return getSerenaBaselineStatus(options);\n}\n","import { mkdir } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { execCapture } from \"../shared/common\";\n\nexport interface SerenaSidecarOptions {\n baselineWorktreePath: string;\n dataDir: string;\n mcpPort: number;\n dashboardPort: number;\n image: string;\n mcpUrl?: string;\n containerName?: string;\n}\n\nexport interface SerenaSidecarStatus {\n running: boolean;\n mcpUrl: string;\n dashboardUrl: string;\n containerName: string;\n}\n\nconst DEFAULT_CONTAINER_NAME = \"pourkit-serena-sidecar\";\nconst MCP_CONTAINER_PORT = 9121;\nconst DASHBOARD_CONTAINER_PORT = 24282;\nconst SERENA_DATA_MOUNT = \"/workspaces/serena-data\";\n\ntype DockerInspectResult = {\n State?: {\n Running?: boolean;\n };\n};\n\nfunction resolveSidecarUrls(options: SerenaSidecarOptions) {\n return {\n containerName: options.containerName ?? DEFAULT_CONTAINER_NAME,\n mcpUrl: options.mcpUrl ?? `http://localhost:${options.mcpPort}/mcp`,\n dashboardUrl: `http://localhost:${options.dashboardPort}`,\n };\n}\n\nasync function inspectSidecarContainer(containerName: string) {\n try {\n const result = await execCapture(\"docker\", [\"inspect\", containerName]);\n const parsed = JSON.parse(result.stdout) as DockerInspectResult[];\n return {\n exists: true,\n running: Boolean(parsed[0]?.State?.Running),\n };\n } catch {\n return {\n exists: false,\n running: false,\n };\n }\n}\n\nasync function readSidecarStatus(\n options: SerenaSidecarOptions\n): Promise<SerenaSidecarStatus> {\n const { containerName, mcpUrl, dashboardUrl } = resolveSidecarUrls(options);\n const container = await inspectSidecarContainer(containerName);\n\n return {\n running: container.running,\n mcpUrl,\n dashboardUrl,\n containerName,\n };\n}\n\nfunction buildStartArgs(options: SerenaSidecarOptions, containerName: string) {\n return [\n \"run\",\n \"-d\",\n \"--name\",\n containerName,\n \"--restart\",\n \"unless-stopped\",\n \"-p\",\n `${options.mcpPort}:${MCP_CONTAINER_PORT}`,\n \"-p\",\n `${options.dashboardPort}:${DASHBOARD_CONTAINER_PORT}`,\n \"-v\",\n `${options.baselineWorktreePath}:/workspaces/pourkit`,\n \"-v\",\n `${options.dataDir}:${SERENA_DATA_MOUNT}`,\n \"-e\",\n `SERENA_HOME=${SERENA_DATA_MOUNT}/config`,\n options.image,\n \"serena\",\n \"start-mcp-server\",\n \"--transport\",\n \"streamable-http\",\n \"--port\",\n String(MCP_CONTAINER_PORT),\n \"--host\",\n \"0.0.0.0\",\n ];\n}\n\nexport async function getSerenaSidecarStatus(\n options: SerenaSidecarOptions\n): Promise<SerenaSidecarStatus> {\n return readSidecarStatus(options);\n}\n\nexport async function startSerenaSidecar(\n options: SerenaSidecarOptions\n): Promise<SerenaSidecarStatus> {\n const { containerName } = resolveSidecarUrls(options);\n const container = await inspectSidecarContainer(containerName);\n\n if (container.exists) {\n if (!container.running) {\n await execCapture(\"docker\", [\"start\", containerName]);\n }\n\n return readSidecarStatus(options);\n }\n\n await execCapture(\"docker\", buildStartArgs(options, containerName));\n\n return readSidecarStatus(options);\n}\n\nexport async function indexSerenaProject(\n options: SerenaSidecarOptions\n): Promise<void> {\n const { containerName } = resolveSidecarUrls(options);\n await execCapture(\"docker\", [\n \"exec\",\n containerName,\n \"serena\",\n \"project\",\n \"create\",\n \"--language\",\n \"typescript\",\n \"--index\",\n \"/workspaces/pourkit\",\n ]);\n}\n\nexport async function stopSerenaSidecar(\n options: SerenaSidecarOptions\n): Promise<SerenaSidecarStatus> {\n const { containerName } = resolveSidecarUrls(options);\n\n try {\n await execCapture(\"docker\", [\"stop\", containerName]);\n } catch {\n // Container may already be stopped or absent.\n }\n\n return readSidecarStatus(options);\n}\n\nexport interface PrepareSerenaSidecarConfigOptions {\n baselineWorktreePath: string;\n dataDir: string;\n}\n\nexport async function prepareSerenaSidecarConfig(\n options: PrepareSerenaSidecarConfigOptions\n): Promise<void> {\n const configDir = path.join(options.dataDir, \"config\");\n await mkdir(configDir, { recursive: true });\n}\n","import type { PourkitLogger } from \"../shared/common\";\nimport { ensureBaselineWorktree, refreshSerenaBaseline } from \"./baseline\";\nimport {\n getSerenaSidecarStatus,\n prepareSerenaSidecarConfig,\n startSerenaSidecar,\n} from \"./container\";\n\nconst SERENA_MCP_PORT = 9121;\nconst SERENA_DASHBOARD_PORT = 24282;\nconst SERENA_IMAGE = \"ghcr.io/oraios/serena:latest\";\n\nexport interface PrepareSerenaForTargetOptions {\n repoRoot: string;\n targetName: string;\n baseBranch: string;\n dataDir: string;\n mcpUrl: string;\n enabled: boolean;\n required: boolean;\n autoStart: boolean;\n logger: PourkitLogger;\n}\n\nexport type SerenaPreflightResult =\n | { enabled: false }\n | { enabled: true; available: true; mcpUrl: string }\n | { enabled: true; available: false; error: string };\n\nfunction sidecarOptions(\n paths: {\n baselineWorktreePath: string;\n dataDir: string;\n },\n mcpUrl: string\n) {\n return {\n baselineWorktreePath: paths.baselineWorktreePath,\n dataDir: paths.dataDir,\n mcpPort: SERENA_MCP_PORT,\n dashboardPort: SERENA_DASHBOARD_PORT,\n image: SERENA_IMAGE,\n mcpUrl,\n };\n}\n\nasync function canReachMcp(url: string): Promise<boolean> {\n for (let attempt = 0; attempt < 10; attempt += 1) {\n try {\n await fetch(url, { method: \"GET\", signal: AbortSignal.timeout(500) });\n return true;\n } catch {\n if (attempt < 9) {\n await new Promise((resolve) => setTimeout(resolve, 100));\n }\n }\n }\n\n return false;\n}\n\nfunction formatError(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nexport async function prepareSerenaForTarget(\n options: PrepareSerenaForTargetOptions\n): Promise<SerenaPreflightResult> {\n if (!options.enabled) {\n return { enabled: false };\n }\n\n try {\n const paths = await ensureBaselineWorktree({\n repoRoot: options.repoRoot,\n dataDir: options.dataDir,\n });\n\n await prepareSerenaSidecarConfig({\n baselineWorktreePath: paths.baselineWorktreePath,\n dataDir: paths.dataDir,\n });\n\n const status = options.autoStart\n ? await startSerenaSidecar(sidecarOptions(paths, options.mcpUrl))\n : await getSerenaSidecarStatus(sidecarOptions(paths, options.mcpUrl));\n const mcpReachable = await canReachMcp(options.mcpUrl);\n\n if (!mcpReachable) {\n return {\n enabled: true,\n available: false,\n error: status.running\n ? `Serena MCP is not reachable at ${options.mcpUrl}`\n : `Serena sidecar is not running for target ${options.targetName}`,\n };\n }\n\n await refreshSerenaBaseline({\n repoRoot: options.repoRoot,\n dataDir: options.dataDir,\n baseBranch: options.baseBranch,\n });\n\n return {\n enabled: true,\n available: true,\n mcpUrl: options.mcpUrl,\n };\n } catch (error) {\n return {\n enabled: true,\n available: false,\n error: formatError(error),\n };\n }\n}\n","import { readFileSync } from \"fs\";\nimport { join } from \"path\";\nimport type { ExecutionProvider } from \"../execution/execution-provider\";\nimport { executeWithMissingOrEmptyArtifactRetry } from \"../execution/agent-output-retry\";\nimport type {\n FailureResolutionPacket,\n RecoveryArtifact,\n RecoveryDecision,\n StageFailure,\n StageFailureTag,\n} from \"./types\";\nimport { RebaseConflict } from \"./types\";\nimport { parseRecoveryArtifact, validateRecoveryDecision } from \"./types\";\nimport { validateAgentArtifact } from \"../commands/artifact-validation\";\nimport { evaluateRecoveryPolicy } from \"./recovery-policy\";\nimport {\n writeAttemptLog,\n computeFailureFingerprint,\n} from \"../shared/attempt-log\";\nimport type { PourkitLogger } from \"../shared/common\";\nimport {\n resolveMissingOrEmptyOutputRetries,\n type PourkitConfig,\n type ResolvedTarget,\n} from \"../shared/config\";\n\nexport interface PacketContext {\n readonly stageName: string;\n readonly attemptNumber: number;\n readonly worktreePath: string;\n readonly branchName: string;\n readonly baseBranch: string;\n readonly maxAttempts: number;\n readonly allowedDecisions: readonly RecoveryDecision[];\n readonly artifactTarget: string;\n}\n\nexport function constructFailureResolutionPacket(\n failure: StageFailure,\n context: PacketContext\n): FailureResolutionPacket {\n return {\n failureType: failure._tag as StageFailureTag,\n stageName: context.stageName,\n attemptNumber: context.attemptNumber,\n worktreePath: context.worktreePath,\n branchName: context.branchName,\n baseBranch: context.baseBranch,\n conflictedPaths:\n failure instanceof RebaseConflict ? failure.conflictedPaths : undefined,\n failureSummary: failure.message,\n maxAttempts: context.maxAttempts,\n allowedDecisions: context.allowedDecisions,\n artifactTarget: context.artifactTarget,\n };\n}\n\nexport interface RunFailureResolutionAgentOptions {\n executionProvider: ExecutionProvider;\n config: PourkitConfig;\n target: ResolvedTarget;\n failure: StageFailure;\n packet: FailureResolutionPacket;\n worktreePath: string;\n repoRoot: string;\n logger: PourkitLogger;\n}\n\nexport type FailureResolutionAgentResult =\n | {\n status: \"recovered\";\n decision: RecoveryDecision;\n artifact: RecoveryArtifact;\n }\n | { status: \"handoff\"; decision: \"HANDOFF_TO_HUMAN\"; reason: string }\n | { status: \"fail-run\"; decision: \"FAIL_RUN\"; reason: string };\n\nexport async function runFailureResolutionAgent(\n options: RunFailureResolutionAgentOptions\n): Promise<FailureResolutionAgentResult> {\n const {\n executionProvider,\n config,\n target,\n failure,\n packet,\n worktreePath,\n repoRoot,\n logger,\n } = options;\n const frConfig = target.strategy.failureResolution;\n const artifactPath = packet.artifactTarget;\n const fullArtifactPath = join(worktreePath, artifactPath);\n const fingerprint = computeFailureFingerprint(packet.stageName, failure._tag);\n\n const prompt = [\n `# Failure Resolution: ${packet.failureType}`,\n \"\",\n \"## Failure Context\",\n \"\",\n \"```json\",\n JSON.stringify(packet, null, 2),\n \"```\",\n \"\",\n \"## Instructions\",\n \"\",\n `Write your resolution to: ${artifactPath}`,\n \"Include a ```json block with: recoveryDecision, summary, changedFiles, verificationSummary (optional), verificationCommands (optional), notes (optional).\",\n \"\",\n \"Allowed decisions: \" + packet.allowedDecisions.join(\", \"),\n \"\",\n `Before handoff, run: pourkit validate-artifact failure-resolution ${artifactPath} ${packet.allowedDecisions.map((decision) => `--allowed-decision ${decision}`).join(\" \")}`,\n ].join(\"\\n\");\n\n const retryResult = await executeWithMissingOrEmptyArtifactRetry({\n executionProvider,\n missingOrEmptyRetries: resolveMissingOrEmptyOutputRetries(frConfig),\n executionOptions: {\n stage: \"failureResolution\",\n agent: frConfig.agent,\n model: frConfig.model,\n variant: frConfig.variant,\n env: frConfig.env,\n prompt,\n target,\n repoRoot,\n branchName: packet.branchName,\n sandbox: config.sandbox,\n autoApprove: true,\n worktreePath,\n artifactPath,\n artifacts: [],\n logger,\n },\n });\n const executionResult = retryResult.executionResult;\n\n if (!executionResult.success) {\n await writeRecoveryAttempt(\n worktreePath,\n \"failure\",\n fingerprint,\n `Agent execution failed: ${executionResult.error}`,\n undefined,\n \"HANDOFF_TO_HUMAN\",\n packet.stageName\n );\n return {\n status: \"handoff\",\n decision: \"HANDOFF_TO_HUMAN\",\n reason: `Agent execution failed: ${executionResult.error}`,\n };\n }\n\n if (retryResult.artifact._tag !== \"content\") {\n const reason =\n retryResult.artifact._tag === \"empty\"\n ? \"Agent wrote empty artifact\"\n : \"Agent did not write artifact\";\n await writeRecoveryAttempt(\n worktreePath,\n \"failure\",\n fingerprint,\n reason,\n undefined,\n \"HANDOFF_TO_HUMAN\",\n packet.stageName\n );\n return {\n status: \"handoff\",\n decision: \"HANDOFF_TO_HUMAN\",\n reason,\n };\n }\n\n let artifact: RecoveryArtifact;\n try {\n const md = readFileSync(fullArtifactPath, \"utf-8\");\n const validation = validateAgentArtifact({\n kind: \"failure-resolution\",\n artifactPath: fullArtifactPath,\n allowedDecisions: [...packet.allowedDecisions],\n });\n if (!validation.ok) {\n throw new Error(validation.reason);\n }\n artifact = parseRecoveryArtifact(md, artifactPath);\n } catch (error) {\n const reason =\n error instanceof Error ? error.message : \"Failed to parse artifact\";\n await writeRecoveryAttempt(\n worktreePath,\n \"failure\",\n fingerprint,\n reason,\n undefined,\n \"HANDOFF_TO_HUMAN\",\n packet.stageName\n );\n return { status: \"handoff\", decision: \"HANDOFF_TO_HUMAN\", reason };\n }\n\n const validation = validateRecoveryDecision(\n artifact,\n packet.allowedDecisions\n );\n if (!validation.valid) {\n await writeRecoveryAttempt(\n worktreePath,\n \"failure\",\n fingerprint,\n validation.reason!,\n undefined,\n \"HANDOFF_TO_HUMAN\",\n packet.stageName\n );\n return {\n status: \"handoff\",\n decision: \"HANDOFF_TO_HUMAN\",\n reason: validation.reason!,\n };\n }\n\n const policyResult = await evaluateRecoveryPolicy({\n failure,\n worktreePath,\n fingerprint,\n maxAttempts: packet.maxAttempts,\n agentRecommendedDecision: validation.decision!,\n allowedDecisions: packet.allowedDecisions,\n });\n\n await writeRecoveryAttempt(\n worktreePath,\n policyResult.decision === \"HANDOFF_TO_HUMAN\"\n ? \"handoff\"\n : policyResult.decision === \"FAIL_RUN\"\n ? \"failure\"\n : \"success\",\n fingerprint,\n policyResult.reason,\n artifactPath,\n policyResult.decision,\n packet.stageName\n );\n\n if (policyResult.decision === \"HANDOFF_TO_HUMAN\") {\n return {\n status: \"handoff\",\n decision: \"HANDOFF_TO_HUMAN\",\n reason: policyResult.reason,\n };\n }\n if (policyResult.decision === \"FAIL_RUN\") {\n return {\n status: \"fail-run\",\n decision: \"FAIL_RUN\",\n reason: policyResult.reason,\n };\n }\n return {\n status: \"recovered\",\n decision: policyResult.decision as RecoveryDecision,\n artifact,\n };\n}\n\nasync function writeRecoveryAttempt(\n worktreePath: string,\n outcome: \"success\" | \"failure\" | \"handoff\",\n fingerprint: string,\n summary: string,\n artifactRef?: string,\n decision?: string,\n stageName: string = \"baseRefresh\"\n): Promise<void> {\n writeAttemptLog(worktreePath, {\n attemptType: \"recovery\",\n fingerprint,\n timestamp: new Date().toISOString(),\n stage: stageName,\n outcome,\n artifactRef,\n decision:\n decision ??\n (outcome === \"handoff\"\n ? \"HANDOFF_TO_HUMAN\"\n : outcome === \"success\"\n ? \"RETRY_STAGE\"\n : undefined),\n });\n}\n","import {\n type StageFailure,\n PublishedHistoryRisk,\n SafetyFailure,\n ConfigFailure,\n} from \"./types\";\nimport type { RecoveryDecision } from \"./types\";\nimport { recoveryBudgetForFailure } from \"../shared/attempt-log\";\n\nexport interface RecoveryPolicyParams {\n readonly failure: StageFailure;\n readonly worktreePath: string;\n readonly fingerprint: string;\n readonly maxAttempts: number;\n readonly agentRecommendedDecision: RecoveryDecision;\n readonly allowedDecisions: readonly RecoveryDecision[];\n}\n\nexport interface RecoveryPolicyResult {\n readonly decision: RecoveryDecision;\n readonly reason: string;\n}\n\nexport function isSecuritySensitiveFailure(failure: StageFailure): boolean {\n return (\n failure instanceof PublishedHistoryRisk || failure instanceof SafetyFailure\n );\n}\n\nexport async function evaluateRecoveryPolicy(\n params: RecoveryPolicyParams\n): Promise<RecoveryPolicyResult> {\n if (isSecuritySensitiveFailure(params.failure)) {\n return {\n decision: \"HANDOFF_TO_HUMAN\",\n reason: \"Security-sensitive failure — AI recovery bypassed\",\n };\n }\n\n if (params.failure instanceof ConfigFailure) {\n if (\n params.agentRecommendedDecision !== \"FAIL_RUN\" &&\n params.agentRecommendedDecision !== \"HANDOFF_TO_HUMAN\"\n ) {\n return {\n decision: \"HANDOFF_TO_HUMAN\",\n reason: `ConfigFailure — agent recommended ${params.agentRecommendedDecision} but config errors are not AI-repairable`,\n };\n }\n }\n\n const budget = recoveryBudgetForFailure(\n params.worktreePath,\n params.fingerprint,\n params.maxAttempts\n );\n\n if (budget.exhausted) {\n return {\n decision: \"HANDOFF_TO_HUMAN\",\n reason: `Recovery budget exhausted (${budget.used}/${params.maxAttempts})`,\n };\n }\n\n if (!params.allowedDecisions.includes(params.agentRecommendedDecision)) {\n return {\n decision: \"HANDOFF_TO_HUMAN\",\n reason: `Agent recommended ${params.agentRecommendedDecision} which is not allowed`,\n };\n }\n\n if (params.agentRecommendedDecision === \"FAIL_RUN\") {\n return { decision: \"FAIL_RUN\", reason: \"Agent recommended FAIL_RUN\" };\n }\n\n return {\n decision: params.agentRecommendedDecision,\n reason: \"Agent recommendation accepted\",\n };\n}\n","import { join } from \"path\";\nimport { readFileSync } from \"node:fs\";\nimport type {\n IssueData,\n PourkitConfig,\n StageAgentConfig,\n Target,\n} from \"../shared/config\";\nimport {\n resolveMissingOrEmptyOutputRetries,\n resolvePromptTemplatePath,\n} from \"../shared/config\";\nimport type { ExecutionProvider } from \"../execution/execution-provider\";\nimport { executeWithMissingOrEmptyArtifactRetry } from \"../execution/agent-output-retry\";\nimport {\n ensureConventionalPrTitle,\n parsePrDescription,\n PrDescriptionProtocolError,\n} from \"../pr/pr-description\";\nimport {\n collectFinalizerContextEffect,\n buildFinalizerPrompt,\n} from \"../pr/pr-description-context\";\nimport type { PourkitLogger } from \"../shared/common\";\nimport { buildRunContextArtifact, STAGE_SECTIONS } from \"../shared/run-context\";\nimport {\n FileSystem,\n FileSystemDefault,\n ExecutionProvider as ExecutionProviderService,\n GitOperationsDefault,\n} from \"../shared/effect-services\";\nimport { FinalizerFailure } from \"../failure-resolution/types\";\nimport { Effect, Layer } from \"effect\";\nimport { runEffectAndMapExit } from \"../shared/effect-runtime\";\nimport { validateAgentArtifact } from \"./artifact-validation\";\n\nexport interface RunFinalizerOptions {\n executionProvider: ExecutionProvider;\n config: PourkitConfig;\n target: Target;\n issue: IssueData;\n builderBranch: string;\n targetBaseBranch: string;\n worktreePath: string;\n reviewArtifactPath?: string;\n repoRoot: string;\n logger: PourkitLogger;\n}\n\nexport interface RunFinalizerResult {\n title: string;\n body: string;\n artifactPath: string;\n}\n\ninterface RunPrDescriptionFinalizerCoreOptions {\n executionProvider: ExecutionProvider;\n config: PourkitConfig;\n target: Target;\n finalizer: StageAgentConfig;\n maxAttempts: number;\n prompt: string;\n branchName: string;\n repoRoot: string;\n worktreePath: string;\n artifactPathInWorktree: string;\n commitSummaries: string;\n logger: PourkitLogger;\n artifacts?: Parameters<ExecutionProvider[\"execute\"]>[0][\"artifacts\"];\n baseRef?: string;\n checkoutBase?: string;\n reviewBase?: string;\n}\n\nfunction bridgeExecutionProvider(\n ep: ExecutionProvider\n): Layer.Layer<ExecutionProviderService> {\n return Layer.succeed(\n ExecutionProviderService,\n ExecutionProviderService.of({\n execute: (opts) =>\n Effect.tryPromise({\n try: () => ep.execute(opts as any),\n catch: (e) =>\n new Error(\n e instanceof Error ? e.message : `Execution failed: ${String(e)}`\n ),\n }),\n })\n );\n}\n\nexport function runFinalizerAgent(\n options: RunFinalizerOptions\n): Effect.Effect<RunFinalizerResult, FinalizerFailure> {\n const { executionProvider } = options;\n\n const artifactPathInWorktree = join(\n \".pourkit\",\n \".tmp\",\n \"finalizer\",\n \"agent-output.md\"\n );\n const artifactPath = join(options.worktreePath, artifactPathInWorktree);\n\n const program = Effect.gen(function* () {\n const fs = yield* FileSystem;\n\n const context = yield* collectFinalizerContextEffect({\n targetBase: options.targetBaseBranch,\n branchName: options.builderBranch,\n worktreePath: options.worktreePath,\n reviewArtifactPath: options.reviewArtifactPath,\n logger: options.logger,\n }).pipe(\n Effect.catchAll((error) =>\n Effect.fail(\n new FinalizerFailure({\n message: `Failed to collect finalizer context: ${error.message}`,\n })\n )\n )\n );\n\n const strategy = options.target.strategy;\n const finalizer = strategy.finalize.prDescriptionAgent;\n\n const resolvedPrompt = yield* loadFinalizerPromptEffect(\n options.repoRoot,\n finalizer.promptTemplate,\n fs\n );\n\n const prompt = buildFinalizerPrompt(context, resolvedPrompt);\n\n const result = yield* runPrDescriptionFinalizerCore({\n executionProvider: options.executionProvider,\n config: options.config,\n target: options.target,\n finalizer,\n maxAttempts: strategy.finalize.maxAttempts,\n prompt,\n branchName: options.builderBranch,\n repoRoot: options.repoRoot,\n worktreePath: options.worktreePath,\n artifactPathInWorktree,\n commitSummaries: context.commits,\n artifacts: [\n buildRunContextArtifact({\n issue: options.issue,\n target: options.target,\n branchName: options.builderBranch,\n reviewerCriteria: strategy.review.reviewer.criteria,\n sections: STAGE_SECTIONS.finalizer,\n }),\n ],\n logger: options.logger,\n });\n\n const output = readFileSync(artifactPath, \"utf-8\");\n\n yield* persistGeneratedArtifactEffect(options.worktreePath, output, fs);\n\n return result;\n });\n\n const executionLayer = bridgeExecutionProvider(executionProvider);\n return program.pipe(\n Effect.provide(\n Layer.mergeAll(executionLayer, FileSystemDefault, GitOperationsDefault)\n )\n ) as Effect.Effect<RunFinalizerResult, FinalizerFailure>;\n}\n\nfunction runPrDescriptionFinalizerCore(\n options: RunPrDescriptionFinalizerCoreOptions\n): Effect.Effect<RunFinalizerResult, FinalizerFailure> {\n const artifactPath = join(\n options.worktreePath,\n options.artifactPathInWorktree\n );\n\n return Effect.gen(function* () {\n let parsed: ReturnType<typeof parsePrDescription> | undefined;\n let lastValidationError: Error | undefined;\n\n for (\n let protocolAttempt = 1;\n protocolAttempt <= options.maxAttempts;\n protocolAttempt++\n ) {\n const retryResult = yield* Effect.tryPromise({\n try: () =>\n executeWithMissingOrEmptyArtifactRetry({\n executionProvider: options.executionProvider,\n missingOrEmptyRetries: resolveMissingOrEmptyOutputRetries(\n options.finalizer\n ),\n logger: options.logger,\n runningMessage: () =>\n `Running finalizer agent (${protocolAttempt}/${options.maxAttempts})`,\n retryMessage: (attempt, total) =>\n `Retrying finalizer after empty output (${attempt}/${total})`,\n executionOptions: {\n stage: \"finalizer\" as const,\n agent: options.finalizer.agent,\n model: options.finalizer.model,\n variant: options.finalizer.variant,\n env: options.finalizer.env,\n prompt: options.prompt,\n target: options.target,\n repoRoot: options.repoRoot,\n branchName: options.branchName,\n sandbox: options.config.sandbox,\n autoApprove: true,\n artifactPath: options.artifactPathInWorktree,\n worktreePath: options.worktreePath,\n artifacts: options.artifacts,\n baseRef: options.baseRef,\n checkoutBase: options.checkoutBase,\n reviewBase: options.reviewBase,\n logger: options.logger,\n },\n }),\n catch: (error) =>\n new FinalizerFailure({\n message: error instanceof Error ? error.message : String(error),\n }),\n });\n const executionResult = retryResult.executionResult;\n\n if (!executionResult.success) {\n return yield* Effect.fail(\n new FinalizerFailure({\n message: `Finalizer agent execution failed: ${executionResult.error}`,\n })\n );\n }\n\n if (retryResult.artifact._tag === \"content\") {\n const validation = validateAgentArtifact({\n kind: \"finalizer\",\n artifactPath,\n });\n if (validation.ok) {\n try {\n parsed = parsePrDescription(retryResult.artifact.value);\n lastValidationError = undefined;\n break;\n } catch (error) {\n lastValidationError =\n error instanceof PrDescriptionProtocolError\n ? new Error(`Finalizer protocol error: ${error.message}`)\n : error instanceof Error\n ? error\n : new Error(String(error));\n }\n } else {\n lastValidationError = new Error(\n `Finalizer protocol error: ${validation.reason}`\n );\n if (protocolAttempt === options.maxAttempts) break;\n }\n } else if (retryResult.artifact._tag === \"empty\") {\n lastValidationError = new Error(\n `Finalizer agent produced empty output at ${artifactPath}`\n );\n break;\n } else {\n lastValidationError = new Error(\n `Finalizer agent did not produce output at ${artifactPath}`\n );\n break;\n }\n }\n\n if (!parsed) {\n return yield* Effect.fail(\n new FinalizerFailure({\n message:\n lastValidationError?.message ?? \"Finalizer validation failed\",\n })\n );\n }\n\n options.logger.step(\"info\", \"Finalizer output generated successfully\");\n\n return {\n title: ensureConventionalPrTitle(parsed.title, options.commitSummaries),\n body: parsed.body,\n artifactPath,\n };\n });\n}\n\nfunction loadFinalizerPromptEffect(\n repoRoot: string,\n promptTemplate: string,\n fs: {\n readonly exists: (path: string) => Effect.Effect<boolean, Error>;\n readonly readFile: (path: string) => Effect.Effect<string, Error>;\n }\n): Effect.Effect<string> {\n return Effect.gen(function* () {\n const promptPath = resolvePromptTemplatePath(repoRoot, promptTemplate);\n const exists = yield* fs.exists(promptPath).pipe(Effect.orDie);\n if (exists) {\n return yield* fs.readFile(promptPath).pipe(Effect.orDie);\n }\n return promptTemplate;\n });\n}\n\nfunction persistGeneratedArtifactEffect(\n worktreePath: string,\n output: string,\n fs: {\n readonly mkdir: (path: string) => Effect.Effect<void, Error>;\n readonly writeFile: (\n path: string,\n content: string\n ) => Effect.Effect<void, Error>;\n }\n): Effect.Effect<void> {\n return Effect.gen(function* () {\n const dir = join(worktreePath, \".pourkit\", \".tmp\", \"finalizer\");\n yield* fs.mkdir(dir).pipe(Effect.catchAll(() => Effect.void));\n yield* fs\n .writeFile(join(dir, \"generated.md\"), output)\n .pipe(Effect.catchAll(() => Effect.void));\n });\n}\n","import { join } from \"path\";\nimport { readFile } from \"node:fs/promises\";\nimport { execCapture, type PourkitLogger } from \"../shared/common\";\nimport { Effect } from \"effect\";\nimport { FileSystem, GitOperations } from \"../shared/effect-services\";\nimport { RUN_CONTEXT_PATH_IN_WORKTREE } from \"../shared/run-context\";\n\nexport interface FinalizerContext {\n commits: string;\n reviewArtifact: string;\n targetBase: string;\n branchName: string;\n}\n\nexport interface CollectContextOptions {\n targetBase: string;\n branchName: string;\n worktreePath: string;\n reviewArtifactPath?: string;\n logger: PourkitLogger;\n}\n\nexport async function collectFinalizerContext(\n options: CollectContextOptions\n): Promise<FinalizerContext> {\n const { targetBase, branchName, worktreePath, reviewArtifactPath, logger } =\n options;\n\n const commits = await collectCommitRange(\n targetBase,\n branchName,\n worktreePath,\n logger\n );\n const reviewArtifact = reviewArtifactPath\n ? await readReviewArtifact(reviewArtifactPath)\n : \"(no review artifact provided)\";\n\n return {\n commits,\n reviewArtifact,\n targetBase,\n branchName,\n };\n}\n\nexport function collectFinalizerContextEffect(\n options: CollectContextOptions\n): Effect.Effect<FinalizerContext, Error, FileSystem | GitOperations> {\n return Effect.gen(function* () {\n const git = yield* GitOperations;\n const fs = yield* FileSystem;\n\n const remoteBase = remoteTargetBase(options.targetBase);\n const result = yield* git\n .exec(\n [\n \"log\",\n `${remoteBase}..${options.branchName}`,\n \"--oneline\",\n \"--no-decorate\",\n ],\n { cwd: options.worktreePath }\n )\n .pipe(\n Effect.catchAll((error) =>\n Effect.fail(\n new Error(`Failed to collect commit range: ${error.message}`)\n )\n )\n );\n const commits = result.stdout.trim();\n\n if (!commits) {\n options.logger.step(\n \"warn\",\n `No commits found between ${options.targetBase} and ${options.branchName}, proceeding with empty commit range`\n );\n }\n\n let reviewArtifact: string;\n if (options.reviewArtifactPath) {\n const content = yield* fs.readFile(options.reviewArtifactPath).pipe(\n Effect.catchIf(\n (error) =>\n error.message.includes(\"ENOENT\") ||\n error.message.includes(\"no such file\"),\n () =>\n Effect.fail(\n new Error(\n `Review artifact not found at ${options.reviewArtifactPath}. Ensure the review stage completed before running finalizer generation.`\n )\n )\n )\n );\n if (!content.trim()) {\n return yield* Effect.fail(\n new Error(\n `Review artifact at ${options.reviewArtifactPath} is empty. Ensure the review stage produced output before running finalizer generation.`\n )\n );\n }\n reviewArtifact = content;\n } else {\n reviewArtifact = \"(no review artifact provided)\";\n }\n\n return {\n commits,\n reviewArtifact,\n targetBase: options.targetBase,\n branchName: options.branchName,\n };\n });\n}\n\nasync function collectCommitRange(\n targetBase: string,\n branchName: string,\n worktreePath: string,\n logger: PourkitLogger\n): Promise<string> {\n const result = await execCapture(\n \"git\",\n [\n \"log\",\n `${remoteTargetBase(targetBase)}..${branchName}`,\n \"--oneline\",\n \"--no-decorate\",\n ],\n { cwd: worktreePath, logger, label: \"git log\" }\n );\n\n const commits = result.stdout.trim();\n if (!commits) {\n logger.step(\n \"warn\",\n `No commits found between ${targetBase} and ${branchName}, proceeding with empty commit range`\n );\n }\n return commits;\n}\n\nfunction remoteTargetBase(targetBase: string): string {\n return targetBase.includes(\"/\") ? targetBase : `origin/${targetBase}`;\n}\n\nasync function readReviewArtifact(artifactPath: string): Promise<string> {\n let content: string;\n try {\n content = await readFile(artifactPath, \"utf-8\");\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n throw new Error(\n `Review artifact not found at ${artifactPath}. Ensure the review stage completed before running finalizer generation.`\n );\n }\n throw error;\n }\n\n if (!content.trim()) {\n throw new Error(\n `Review artifact at ${artifactPath} is empty. Ensure the review stage produced output before running finalizer generation.`\n );\n }\n\n return content;\n}\n\nexport function buildFinalizerPrompt(\n context: FinalizerContext,\n promptTemplate: string\n): string {\n const artifactPathInWorktree = join(\n \".pourkit\",\n \".tmp\",\n \"finalizer\",\n \"agent-output.md\"\n );\n\n return `${promptTemplate}\n\n## Shared Run Context\n\nRead the selected issue requirements, branch context, validation commands, and artifact paths from: ${RUN_CONTEXT_PATH_IN_WORKTREE}\n\n## Branch Context\n\n**Target Base**: ${context.targetBase}\n**Branch**: ${context.branchName}\n\n## Commits\n\n${context.commits || \"(no commits in range)\"}\n\n## Review Artifact\n\n${context.reviewArtifact}\n\n## Output\n\nGenerate a PR title and body that accurately summarize the changes for this issue.\nFormat your output with \"## PR Title\" and \"## PR Body\" sections.\n\nInside \"## PR Body\", use the following canonical structure:\n\n## Summary\n\n- Why this branch exists.\n- What outcome this branch delivers.\n\n## Changes\n\n- Final net change 1.\n- Final net change 2.\n\nRules:\n- Use bullet points only inside both inner sections (no prose paragraphs or commit lists).\n- Use final-state wording (describe what the code does after this PR, not what changed during development).\n- Do not include commit chronology or a list of commit messages.\n- Closing policy: For Issue-backed runs, publish exactly one closing reference for the current Issue (e.g. \"Closes #123\"). Never close parent PRDs, sibling Issues, or unrelated Issues. Omit the closing footer when no Issue is attached.\n\nWrite your finalizer output to: ${artifactPathInWorktree}\n\nBefore handoff, run: pourkit validate-artifact finalizer ${artifactPathInWorktree}`;\n}\n","import { execFileSync } from \"node:child_process\";\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { getLocalPrdBranchName } from \"./local-branches\";\n\ntype LocalChildIssueState =\n | \"pending_finalizer\"\n | \"finalizer_failed\"\n | \"ready_to_merge\"\n | \"merge_failed\"\n | \"receipt_written\"\n | \"already_merged\";\n\nexport type LocalMergeFailureCode =\n | \"finalizer_failed\"\n | \"not_found\"\n | \"invalid_receipt\"\n | \"conflict\"\n | \"merge_error\"\n | \"receipt_error\"\n | \"already_merged\";\n\nexport interface MergeReceipt {\n prdId: string;\n issueId: string;\n stage: \"child-issue\" | \"final-review\" | \"reconciliation\";\n sourceBranch: string;\n localPrdBranch: string;\n mergeCommit: string;\n finalizerArtifactPath: string;\n completedAt: string;\n}\n\nexport interface SquashMergeInput {\n finalizerTitle: string;\n finalizerBody: string;\n finalizerArtifactPath: string;\n sourceBranch?: string;\n}\n\nexport interface MergeResult {\n ok: boolean;\n receipt?: MergeReceipt;\n failureCode?: LocalMergeFailureCode;\n repairGuidance?: string;\n}\n\nfunction getLocalStorePath(repoRoot: string, prdId: string): string {\n return join(repoRoot, \".pourkit\", \"local-prd-runs\", prdId);\n}\n\nfunction getMergeReceiptPath(\n repoRoot: string,\n prdId: string,\n issueId: string\n): string {\n return join(\n getLocalStorePath(repoRoot, prdId),\n \"merge-receipts\",\n `${issueId}.json`\n );\n}\n\nfunction getIssueArtifactPath(\n repoRoot: string,\n prdId: string,\n issueId: string\n): string {\n return join(getLocalStorePath(repoRoot, prdId), \"issues\", `${issueId}.json`);\n}\n\nfunction readIssueBranchName(\n repoRoot: string,\n prdId: string,\n issueId: string\n): string | null {\n const issuePath = getIssueArtifactPath(repoRoot, prdId, issueId);\n if (!existsSync(issuePath)) return null;\n\n try {\n const content = readFileSync(issuePath, \"utf-8\");\n const parsed = JSON.parse(content);\n return typeof parsed.branchName === \"string\" && parsed.branchName\n ? parsed.branchName\n : null;\n } catch {\n return null;\n }\n}\n\nexport async function hasLocalIssueMergeReceipt(\n prdId: string,\n issueId: string,\n repoRoot?: string\n): Promise<MergeReceipt | null> {\n const root = repoRoot ?? process.cwd();\n const receiptPath = getMergeReceiptPath(root, prdId, issueId);\n if (!existsSync(receiptPath)) return null;\n\n try {\n const content = readFileSync(receiptPath, \"utf-8\");\n const parsed = JSON.parse(content) as MergeReceipt;\n if (\n typeof parsed.prdId === \"string\" &&\n typeof parsed.issueId === \"string\" &&\n typeof parsed.stage === \"string\" &&\n typeof parsed.sourceBranch === \"string\" &&\n typeof parsed.localPrdBranch === \"string\" &&\n typeof parsed.mergeCommit === \"string\" &&\n typeof parsed.completedAt === \"string\"\n ) {\n return parsed;\n }\n return null;\n } catch {\n return null;\n }\n}\n\nexport async function squashMergeLocalIssue(\n prdId: string,\n issueId: string,\n input?: SquashMergeInput,\n repoRoot?: string\n): Promise<MergeResult> {\n const root = repoRoot ?? process.cwd();\n\n const receiptPath = getMergeReceiptPath(root, prdId, issueId);\n if (existsSync(receiptPath)) {\n try {\n const existing: MergeReceipt = JSON.parse(\n readFileSync(receiptPath, \"utf-8\")\n );\n if (\n existing.prdId === prdId &&\n existing.issueId === issueId &&\n existing.mergeCommit\n ) {\n return {\n ok: false,\n failureCode: \"already_merged\",\n repairGuidance: `Issue ${issueId} was already merged into ${existing.localPrdBranch}. Merge commit: ${existing.mergeCommit}`,\n };\n }\n return {\n ok: false,\n failureCode: \"invalid_receipt\",\n repairGuidance: `Merge receipt for ${issueId} belongs to different prd/issue. Remove it manually: ${receiptPath}`,\n };\n } catch {\n return {\n ok: false,\n failureCode: \"invalid_receipt\",\n repairGuidance: `Merge receipt for ${issueId} is corrupted. Remove it manually: ${receiptPath}`,\n };\n }\n }\n\n const sourceBranch =\n input?.sourceBranch ?? readIssueBranchName(root, prdId, issueId);\n if (!sourceBranch) {\n return {\n ok: false,\n failureCode: \"not_found\",\n repairGuidance: `No source branch found for issue ${issueId} under PRD ${prdId}. Ensure the issue artifact exists with a valid branchName field.`,\n };\n }\n\n try {\n execFileSync(\n \"git\",\n [\"show-ref\", \"--verify\", \"--quiet\", `refs/heads/${sourceBranch}`],\n { cwd: root, encoding: \"utf8\", stdio: \"pipe\" }\n );\n } catch {\n return {\n ok: false,\n failureCode: \"not_found\",\n repairGuidance: `Source branch \"${sourceBranch}\" does not exist locally. Check that the branch was created and not deleted.`,\n };\n }\n\n const targetBranch = getLocalPrdBranchName(prdId);\n try {\n execFileSync(\n \"git\",\n [\"show-ref\", \"--verify\", \"--quiet\", `refs/heads/${targetBranch}`],\n { cwd: root, encoding: \"utf8\", stdio: \"pipe\" }\n );\n } catch {\n return {\n ok: false,\n failureCode: \"not_found\",\n repairGuidance: `Local PRD branch \"${targetBranch}\" does not exist. Run \\`prd-run start\\` first to create it.`,\n };\n }\n\n try {\n execFileSync(\"git\", [\"checkout\", targetBranch], {\n cwd: root,\n encoding: \"utf8\",\n stdio: \"pipe\",\n });\n\n let preMergeHead: string;\n try {\n preMergeHead = execFileSync(\"git\", [\"rev-parse\", \"HEAD\"], {\n cwd: root,\n encoding: \"utf8\",\n stdio: \"pipe\",\n }).trim();\n } catch {\n return {\n ok: false,\n failureCode: \"merge_error\",\n repairGuidance: \"Failed to read current HEAD before merge.\",\n };\n }\n\n execFileSync(\"git\", [\"merge\", \"--squash\", sourceBranch], {\n cwd: root,\n encoding: \"utf8\",\n stdio: \"pipe\",\n });\n\n if (input) {\n execFileSync(\n \"git\",\n [\"commit\", \"-m\", input.finalizerTitle, \"-m\", input.finalizerBody],\n { cwd: root, encoding: \"utf8\", stdio: \"pipe\" }\n );\n } else {\n execFileSync(\n \"git\",\n [\"commit\", \"-m\", `Squash merge ${sourceBranch} into ${targetBranch}`],\n { cwd: root, encoding: \"utf8\", stdio: \"pipe\" }\n );\n }\n\n const revParseResult = execFileSync(\"git\", [\"rev-parse\", \"HEAD\"], {\n cwd: root,\n encoding: \"utf8\",\n stdio: \"pipe\",\n });\n const mergeCommit = revParseResult.trim();\n\n const receipt: MergeReceipt = {\n prdId,\n issueId,\n stage: \"child-issue\",\n sourceBranch,\n localPrdBranch: targetBranch,\n mergeCommit,\n finalizerArtifactPath: input?.finalizerArtifactPath ?? \"\",\n completedAt: new Date().toISOString(),\n };\n\n try {\n const receiptsDir = join(\n root,\n \".pourkit\",\n \"local-prd-runs\",\n prdId,\n \"merge-receipts\"\n );\n mkdirSync(receiptsDir, { recursive: true });\n writeFileSync(receiptPath, JSON.stringify(receipt, null, 2), \"utf-8\");\n } catch {\n try {\n execFileSync(\"git\", [\"reset\", \"--hard\", preMergeHead], {\n cwd: root,\n encoding: \"utf8\",\n stdio: \"pipe\",\n });\n } catch {\n // Best-effort rollback; if it fails, the branch may be dirty\n }\n return {\n ok: false,\n failureCode: \"receipt_error\",\n repairGuidance:\n \"Failed to write merge receipt. Check disk space and permissions on .pourkit/local-prd-runs/. The merge commit has been rolled back.\",\n };\n }\n\n return { ok: true, receipt };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n if (message.toLowerCase().includes(\"conflict\")) {\n return {\n ok: false,\n failureCode: \"conflict\",\n repairGuidance:\n \"Merge conflict during squash. Resolve conflicts in the working tree, then retry.\",\n };\n }\n const stderr =\n error instanceof Error && \"stderr\" in error\n ? (error as Error & { stderr: string }).stderr\n : undefined;\n return {\n ok: false,\n failureCode: \"merge_error\",\n repairGuidance: stderr\n ? `Merge failed: ${stderr}`\n : `Merge failed: ${message}`,\n };\n }\n}\n","import { execFileSync, spawnSync } from \"node:child_process\";\n\nexport function getLocalPrdBranchName(prdId: string): string {\n return `local/${prdId}`;\n}\n\ninterface LocalStartPrerequisites {\n localBranchName: string;\n localBranchExists: boolean;\n localBranchCommit: string;\n localStoreReady: boolean;\n}\n\nexport type MaterializeLocalPrdBranchResult =\n | { ok: true; created: boolean }\n | { ok: false; failureCode: string; message: string };\n\nexport function materializeLocalPrdBranch(\n prdId: string,\n startBaseCommit: string,\n repoRoot?: string\n): MaterializeLocalPrdBranchResult {\n const branch = getLocalPrdBranchName(prdId);\n const root = repoRoot ?? process.cwd();\n\n const branchExists = (() => {\n try {\n return (\n spawnSync(\"git\", [\"rev-parse\", \"--verify\", \"--quiet\", branch], {\n cwd: root,\n encoding: \"utf8\",\n stdio: \"pipe\",\n }).status === 0\n );\n } catch {\n return false;\n }\n })();\n\n if (branchExists) {\n const currentCommit =\n spawnSync(\"git\", [\"rev-parse\", branch], {\n cwd: root,\n encoding: \"utf8\",\n stdio: \"pipe\",\n })\n .stdout?.toString?.()\n .trim() ?? \"\";\n\n if (currentCommit !== startBaseCommit) {\n return {\n ok: false,\n failureCode: \"branch_commit_mismatch\",\n message: `Local PRD branch ${branch} exists at commit ${currentCommit} but expected commit ${startBaseCommit}. The branch has diverged from the start base. To resolve, delete the local branch and rerun start, or manually reset it to the expected commit.`,\n };\n }\n\n return {\n ok: true,\n created: false,\n };\n }\n\n const branchResult = spawnSync(\"git\", [\"branch\", branch, startBaseCommit], {\n cwd: root,\n encoding: \"utf8\",\n stdio: \"pipe\",\n });\n\n if (branchResult.status !== 0) {\n const stderr = branchResult.stderr?.toString?.() ?? \"unknown error\";\n return {\n ok: false,\n failureCode: \"branch_creation_failed\",\n message: `Failed to create local PRD branch ${branch} at ${startBaseCommit}: ${stderr}`,\n };\n }\n\n return { ok: true, created: true };\n}\n\nexport type BranchValidationResult =\n | { ok: true }\n | {\n ok: false;\n failureCode:\n | \"protected_branch\"\n | \"remote_backed_collision\"\n | \"invalid_format\";\n message: string;\n };\n\nconst PROTECTED_BRANCHES = new Set([\"dev\", \"next\", \"main\"]);\n\nconst LOCAL_BRANCH_PATTERN = /^local\\/PRD-\\d{4}(\\/(I-\\d{2}(-[a-z0-9-]+)?)?)?$/;\n\nexport function validateLocalBranchName(name: string): BranchValidationResult {\n if (!name || name.length === 0) {\n return {\n ok: false,\n failureCode: \"invalid_format\",\n message: \"Branch name is empty.\",\n };\n }\n\n if (isProtectedBranch(name)) {\n return {\n ok: false,\n failureCode: \"protected_branch\",\n message: `Branch \"${name}\" is protected.`,\n };\n }\n\n if (!LOCAL_BRANCH_PATTERN.test(name)) {\n return {\n ok: false,\n failureCode: \"invalid_format\",\n message: `Branch \"${name}\" does not match the local branch pattern.`,\n };\n }\n\n return { ok: true };\n}\n\nexport function isProtectedBranch(name: string): boolean {\n return PROTECTED_BRANCHES.has(name);\n}\n\n/**\n * Check if a local PRD branch name has a collision with an existing remote-backed ref.\n *\n * @param localName - Local branch name (e.g. `local/PRD-0052`).\n * @param repoRoot - Optional git repository root for testing. Defaults to `process.cwd()`.\n */\nexport function hasRemoteBackedCollision(\n localName: string,\n repoRoot?: string\n): Promise<BranchValidationResult> {\n const match = localName.match(/^local\\/(PRD-\\d{4})/);\n if (!match) {\n return Promise.resolve({\n ok: false,\n failureCode: \"invalid_format\",\n message: `Cannot extract PRD ref from \"${localName}\".`,\n });\n }\n\n const prdRef = match[1];\n\n try {\n execFileSync(\n \"git\",\n [\"show-ref\", \"--verify\", \"--quiet\", `refs/heads/${prdRef}`],\n {\n cwd: repoRoot ?? process.cwd(),\n encoding: \"utf8\",\n stdio: \"pipe\",\n }\n );\n return Promise.resolve({\n ok: false,\n failureCode: \"remote_backed_collision\",\n message: `Branch \"${prdRef}\" exists locally.`,\n });\n } catch {\n // Local branch does not exist, continue to check remote\n }\n\n try {\n execFileSync(\n \"git\",\n [\"show-ref\", \"--verify\", \"--quiet\", `refs/remotes/origin/${prdRef}`],\n {\n cwd: repoRoot ?? process.cwd(),\n encoding: \"utf8\",\n stdio: \"pipe\",\n }\n );\n return Promise.resolve({\n ok: false,\n failureCode: \"remote_backed_collision\",\n message: `Remote branch \"origin/${prdRef}\" exists.`,\n });\n } catch {\n // Remote branch does not exist\n }\n\n return Promise.resolve({ ok: true });\n}\n","import { readFile } from \"node:fs/promises\";\n\nexport const DEFAULT_MANUAL_PR_BODY = `## Summary\n\n- Summarize why this branch exists.\n\n## Changes\n\n- Summarize the final net change in this branch.`;\n\nexport interface PrBodyOptions {\n body?: string;\n bodyFile?: string;\n issue?: number;\n}\n\nexport interface PrBodyInput {\n defaultBody: string;\n options: PrBodyOptions;\n}\n\nexport async function buildPrBody(input: PrBodyInput): Promise<string> {\n const { defaultBody, options } = input;\n\n let bodyText = await resolveBodyText(defaultBody, options);\n\n bodyText = appendClosingRef(bodyText, options.issue);\n\n return bodyText;\n}\n\nexport function ensureClosingRefs(body: string, issue?: number): string {\n const stripped = stripClosingRefs(body || \"\");\n if (issue === undefined) {\n return stripped;\n }\n if (!stripped) {\n return `Closes #${issue}`;\n }\n return `${stripped}\\n\\nCloses #${issue}`;\n}\n\nfunction stripClosingRefs(body: string): string {\n // Strip whole lines that consist of an optional bullet prefix plus a closing-keyword issue ref\n const linePattern =\n /^[ \\t]*[-*+]\\s+(?:close|closes|closed|fix|fixes|fixed|resolve|resolves|resolved)\\s*:?\\s*#\\d+\\s*$/gim;\n let result = body.replace(linePattern, \"\");\n\n // Strip remaining inline closing refs\n const inlinePattern =\n /(?:close|closes|closed|fix|fixes|fixed|resolve|resolves|resolved)\\s*:?\\s*#\\d+/gi;\n result = result.replace(inlinePattern, \"\").trimEnd();\n\n return result;\n}\n\nasync function resolveBodyText(\n defaultBody: string,\n options: PrBodyOptions\n): Promise<string> {\n if (options.body && options.bodyFile) {\n throw new Error(\"--body and --body-file cannot be used together\");\n }\n\n if (options.body !== undefined) {\n return options.body;\n }\n\n if (options.bodyFile !== undefined) {\n return await readFile(options.bodyFile, \"utf-8\");\n }\n\n return defaultBody;\n}\n\nfunction appendClosingRef(body: string, issue?: number): string {\n if (issue === undefined) {\n return body;\n }\n\n const existingRefs = extractClosingRefs(body);\n\n if (existingRefs.has(issue)) {\n return body;\n }\n\n return `${body}\\n\\nCloses #${issue}`;\n}\n\nfunction extractClosingRefs(body: string): Set<number> {\n const refs = new Set<number>();\n const pattern =\n /(?:close|closes|closed|fix|fixes|fixed|resolve|resolves|resolved)\\s*:?\\s*#(\\d+)/gi;\n let match;\n\n while ((match = pattern.exec(body)) !== null) {\n refs.add(parseInt(match[1], 10));\n }\n\n return refs;\n}\n","import type { PRProvider } from \"../providers/pr-provider\";\nimport { sleep } from \"../shared/common\";\nimport type { PourkitLogger } from \"../shared/common\";\n\nconst RED_CHECK_CONCLUSIONS = new Set([\n \"FAILURE\",\n \"CANCELLED\",\n \"TIMED_OUT\",\n \"STARTUP_FAILURE\",\n \"ACTION_REQUIRED\",\n \"STALE\",\n]);\n\nexport interface WaitForBranchChecksOptions {\n branchName: string;\n checksFoundTimeoutMs?: number;\n checksCompletionTimeoutMs?: number;\n pollIntervalMs?: number;\n stableHeadMs?: number;\n}\n\nexport async function waitForBranchChecks(\n prProvider: PRProvider,\n logger: PourkitLogger,\n options: WaitForBranchChecksOptions\n): Promise<void> {\n const checksFoundTimeoutMs = options.checksFoundTimeoutMs ?? 60 * 1000;\n const checksCompletionTimeoutMs =\n options.checksCompletionTimeoutMs ?? 5 * 60 * 1000;\n const pollIntervalMs = options.pollIntervalMs ?? 15 * 1000;\n const stableHeadMs = options.stableHeadMs ?? pollIntervalMs;\n\n let lastHeadSha = \"\";\n let headStableSince = 0;\n let checksFoundDeadline = 0;\n let checksCompletionDeadline = 0;\n let checksDiscovered = false;\n\n logger.step(\"wait\", `waiting for ${options.branchName} to be green`);\n\n while (true) {\n const observedAt = Date.now();\n const status = await prProvider.getBranchStatus(options.branchName);\n\n if (status.headSha !== lastHeadSha) {\n logger.step(\n \"info\",\n `branch head changed to ${status.headSha.substring(0, 7)}`\n );\n lastHeadSha = status.headSha;\n headStableSince = observedAt;\n if (checksFoundDeadline === 0) {\n checksFoundDeadline = observedAt + checksFoundTimeoutMs;\n }\n checksCompletionDeadline = 0;\n checksDiscovered = false;\n }\n\n if (status.checks.length > 0 && !checksDiscovered) {\n checksDiscovered = true;\n checksCompletionDeadline = observedAt + checksCompletionTimeoutMs;\n logger.step(\"info\", `Checks: ${formatChecks(status.checks)}`);\n }\n\n if (status.state === \"red\") {\n const failedChecks = status.checks\n .filter(\n (c) =>\n c.conclusion !== null && RED_CHECK_CONCLUSIONS.has(c.conclusion)\n )\n .map((c) => c.name)\n .join(\", \");\n throw new Error(\n `Target branch ${options.branchName} is red: ${failedChecks}`\n );\n }\n\n if (status.state === \"green\") {\n const stableForMs = observedAt - headStableSince;\n if (stableForMs < stableHeadMs) {\n logger.step(\n \"info\",\n `target branch is green; waiting for stable head (${stableForMs}/${stableHeadMs}ms)`\n );\n await sleep(pollIntervalMs);\n continue;\n }\n\n logger.step(\"success\", `target branch ${options.branchName} is green`);\n return;\n }\n\n const stableForMs = observedAt - headStableSince;\n if (!checksDiscovered && status.checks.length === 0) {\n if (observedAt >= checksFoundDeadline) {\n if (stableForMs >= stableHeadMs) {\n logger.step(\n \"success\",\n `target branch ${options.branchName} has no checks`\n );\n return;\n }\n\n throw new Error(\n `Timeout waiting for ${options.branchName} to be green`\n );\n }\n\n logger.step(\n \"info\",\n `target branch has no checks yet, waiting... (${secondsRemaining(checksFoundDeadline, observedAt)}s remaining)`\n );\n await sleep(pollIntervalMs);\n continue;\n }\n\n if (checksDiscovered) {\n if (observedAt >= checksCompletionDeadline) {\n throw new Error(\n `Timeout waiting for ${options.branchName} to be green`\n );\n }\n\n logger.step(\n \"info\",\n `target branch is ${status.state}, waiting... (${secondsRemaining(checksCompletionDeadline, observedAt)}s remaining)`\n );\n await sleep(pollIntervalMs);\n continue;\n }\n\n logger.step(\n \"info\",\n `target branch is ${status.state}, waiting... (${secondsRemaining(checksFoundDeadline, observedAt)}s remaining)`\n );\n await sleep(pollIntervalMs);\n }\n}\n\nfunction formatChecks(\n checks: { name: string; conclusion: string | null; status: string | null }[]\n) {\n return checks\n .map((check) => `${check.name}=${check.conclusion ?? check.status}`)\n .join(\", \");\n}\n\nfunction secondsRemaining(deadline: number, observedAt: number) {\n return Math.max(0, Math.ceil((deadline - observedAt) / 1000));\n}\n","import type {\n MergePrOptions,\n PRProvider,\n PullRequest,\n WaitForPrChecksOptions,\n} from \"../providers/pr-provider\";\nimport type { PourkitLogger } from \"../shared/common\";\nimport { waitForBranchChecks } from \"./target-green\";\nimport { Effect, Either } from \"effect\";\nimport { UnknownException } from \"effect/Cause\";\n\nexport interface MergeCoordinatorOptions {\n prProvider: PRProvider;\n logger: PourkitLogger;\n prNumber: number;\n targetBranch: string;\n matchHeadCommit: string;\n checkWaitOptions: WaitForPrChecksOptions;\n autoMerge?: boolean;\n pr?: PullRequest;\n method?: MergePrOptions[\"method\"];\n waitForTargetGreen?: boolean;\n}\n\nexport type MergeCoordinatorResult =\n | { stage: \"completed\"; merged: true }\n | { stage: \"merge\"; merged: false; error: Error }\n | { stage: \"target-green\"; merged: true; error: Error };\n\nfunction unwrapError(error: unknown): unknown {\n if (error instanceof UnknownException && error.error !== undefined) {\n return error.error;\n }\n return error;\n}\n\nexport function runMergeCoordinator(\n options: MergeCoordinatorOptions\n): Effect.Effect<MergeCoordinatorResult> {\n const {\n prProvider,\n logger,\n prNumber,\n targetBranch,\n matchHeadCommit,\n checkWaitOptions,\n } = options;\n const method = options.method ?? \"squash\";\n const waitForTargetGreen = options.waitForTargetGreen ?? true;\n\n return Effect.gen(function* () {\n const checksEither = yield* Effect.either(\n Effect.tryPromise(() =>\n prProvider.waitForPrChecks(prNumber, checkWaitOptions)\n )\n );\n if (Either.isLeft(checksEither)) {\n const rawError = checksEither.left;\n const error = unwrapError(rawError);\n return {\n stage: \"merge\" as const,\n merged: false as const,\n error: error instanceof Error ? error : new Error(String(error)),\n } as MergeCoordinatorResult;\n }\n\n const mergeEither = yield* Effect.either(\n Effect.tryPromise(() =>\n prProvider.mergePr(prNumber, { method, matchHeadCommit })\n )\n );\n if (Either.isLeft(mergeEither)) {\n const rawError = mergeEither.left;\n const error = unwrapError(rawError);\n return {\n stage: \"merge\" as const,\n merged: false as const,\n error: error instanceof Error ? error : new Error(String(error)),\n } as MergeCoordinatorResult;\n }\n\n if (waitForTargetGreen) {\n const targetEither = yield* Effect.either(\n Effect.tryPromise(() =>\n waitForBranchChecks(prProvider, logger, {\n branchName: targetBranch,\n checksFoundTimeoutMs: checkWaitOptions.checksFoundTimeoutMs,\n checksCompletionTimeoutMs:\n checkWaitOptions.checksCompletionTimeoutMs,\n pollIntervalMs: checkWaitOptions.pollIntervalMs,\n })\n )\n );\n if (Either.isLeft(targetEither)) {\n const rawError = targetEither.left;\n const error = unwrapError(rawError);\n return {\n stage: \"target-green\" as const,\n merged: true as const,\n error: error instanceof Error ? error : new Error(String(error)),\n } as MergeCoordinatorResult;\n }\n }\n\n return { stage: \"completed\" as const, merged: true as const };\n });\n}\n","import { existsSync, readFileSync } from \"fs\";\nimport { join } from \"path\";\nimport type { IssueData, PourkitConfig, Target } from \"../shared/config\";\nimport {\n resolvePromptTemplatePath,\n resolveMissingOrEmptyOutputRetries,\n} from \"../shared/config\";\nimport type { ExecutionProvider } from \"../execution/execution-provider\";\nimport { executeWithMissingOrEmptyArtifactRetry } from \"../execution/agent-output-retry\";\nimport type { PourkitLogger } from \"../shared/common\";\nimport { appendProtectedWorkGuidance } from \"../shared/prompt-guidance\";\nimport {\n buildRunContextArtifact,\n RUN_CONTEXT_PATH_IN_WORKTREE,\n STAGE_SECTIONS,\n} from \"../shared/run-context\";\nimport { validateAgentArtifact } from \"./artifact-validation\";\n\nconst ISSUE_FINAL_REVIEW_ARTIFACT_PATH = join(\n \".pourkit\",\n \".tmp\",\n \"issue-final-review\",\n \"agent-output.json\"\n);\n\nexport interface RunIssueFinalReviewAgentOptions {\n executionProvider: ExecutionProvider;\n config: PourkitConfig;\n target: Target;\n issue: IssueData;\n parentPrdIssue?: IssueData;\n builderBranch: string;\n worktreePath: string;\n /** Reserved for I-05 wiring. Not yet consumed by runIssueFinalReviewAgent. */\n reviewArtifactPath?: string;\n repoRoot: string;\n logger: PourkitLogger;\n}\n\nexport type IssueFinalReviewResult =\n | {\n verdict: \"pass\";\n artifactPath: string;\n selfRetouched: boolean;\n changedPaths: string[];\n verificationPassed: boolean;\n }\n | {\n verdict: \"needs_human_review\";\n artifactPath: string;\n needsHumanReason: string;\n selfRetouched: boolean;\n changedPaths: string[];\n };\n\nexport async function runIssueFinalReviewAgent(\n options: RunIssueFinalReviewAgentOptions\n): Promise<IssueFinalReviewResult> {\n const {\n executionProvider,\n target,\n issue,\n parentPrdIssue,\n builderBranch,\n worktreePath,\n repoRoot,\n logger,\n } = options;\n\n const artifactPathInWorktree = ISSUE_FINAL_REVIEW_ARTIFACT_PATH;\n const artifactPath = join(worktreePath, artifactPathInWorktree);\n\n const strategy = target.strategy;\n const issueFinalReview = strategy.issueFinalReview;\n const agent = issueFinalReview;\n\n const prompt = loadIssueFinalReviewPrompt(repoRoot, agent.promptTemplate);\n\n const entry = await executeWithMissingOrEmptyArtifactRetry({\n executionProvider,\n missingOrEmptyRetries: resolveMissingOrEmptyOutputRetries(agent),\n logger,\n runningMessage: () => \"Running Issue Final Review agent\",\n retryMessage: (attempt, total) =>\n `Retrying Issue Final Review after empty output (${attempt}/${total})`,\n executionOptions: {\n stage: \"issueFinalReview\",\n agent: agent.agent,\n model: agent.model,\n variant: agent.variant,\n env: agent.env,\n prompt,\n target,\n repoRoot,\n branchName: builderBranch,\n sandbox: options.config.sandbox,\n autoApprove: true,\n artifactPath: artifactPathInWorktree,\n worktreePath,\n artifacts: [\n buildRunContextArtifact({\n issue,\n parentPrdIssue,\n target,\n branchName: builderBranch,\n repoRoot,\n reviewerCriteria: strategy.review.reviewer.criteria,\n sections: STAGE_SECTIONS.issueFinalReview,\n }),\n ],\n logger,\n },\n });\n\n const executionResult = entry.executionResult;\n if (!executionResult.success) {\n throw new Error(\n `Issue Final Review agent execution failed: ${executionResult.error}`\n );\n }\n\n let content: string;\n if (entry.artifact._tag === \"content\") {\n content = entry.artifact.value;\n } else if (entry.artifact._tag === \"empty\") {\n throw new Error(\n `Issue Final Review agent produced empty output at ${artifactPath}`\n );\n } else {\n throw new Error(\n `Issue Final Review agent did not produce output at ${artifactPath}`\n );\n }\n\n const validation = validateAgentArtifact({\n kind: \"issue-final-review\",\n artifactPath,\n issueNumber: issue.number,\n branchName: builderBranch,\n });\n if (!validation.ok) {\n throw new Error(\n `Issue Final Review artifact validation failed: ${validation.reason}`\n );\n }\n\n const parsed = JSON.parse(content);\n const verdict = parsed.verdict as string;\n\n if (verdict === \"pass\") {\n return {\n verdict: \"pass\",\n artifactPath,\n selfRetouched: parsed.selfRetouched === true,\n changedPaths: parsed.changedPaths as string[],\n verificationPassed: parsed.verification?.passed === true,\n };\n }\n\n if (verdict === \"needs_human_review\") {\n return {\n verdict: \"needs_human_review\",\n artifactPath,\n needsHumanReason: parsed.needsHumanReason as string,\n selfRetouched: parsed.selfRetouched === true,\n changedPaths: parsed.changedPaths as string[],\n };\n }\n\n throw new Error(\n `Unknown Issue Final Review verdict: ${JSON.stringify(verdict)}`\n );\n}\n\nfunction loadIssueFinalReviewPrompt(\n repoRoot: string,\n promptTemplate: string\n): string {\n const promptPath = resolvePromptTemplatePath(repoRoot, promptTemplate);\n const promptBody = existsSync(promptPath)\n ? readFileSync(promptPath, \"utf-8\")\n : promptTemplate;\n\n return appendProtectedWorkGuidance(`${promptBody}\n\n## Shared Run Context\n\nRead the selected issue requirements, PRD context, comments, branch context, verification commands, and artifact paths from: ${RUN_CONTEXT_PATH_IN_WORKTREE}\n\n## Initial Verification Pass\n\n- First read ${RUN_CONTEXT_PATH_IN_WORKTREE} only far enough to identify the configured verification commands.\n- Before reviewing code, diffs, artifacts, or prior findings, run each configured verification command yourself from the Worktree.\n- Run the commands exactly as configured. Do not substitute narrower commands unless the configured command cannot run.\n- If a configured command fails, keep reviewing after recording the failure details; use the failure output as review evidence.\n- If a command cannot run because the environment is missing required setup, dependencies, or scripts outside agent control, treat it as a human handoff blocker.\n- If no verification commands are configured, note that and proceed with normal review.`);\n}\n","export interface IssueTransitionLabels {\n blocked: string;\n readyForAgent: string;\n needsTriage: string;\n agentInProgress: string;\n readyForHuman: string;\n prOpenAwaitingMerge: string;\n}\n\nexport interface IssueTransitionsContract {\n removeBlocked(issueNumber: number): Promise<void>;\n addReadyForAgent(issueNumber: number): Promise<void>;\n moveToNeedsTriage(issueNumber: number): Promise<void>;\n moveToReadyForHuman(issueNumber: number): Promise<void>;\n closeCompleted(issueNumber: number): Promise<void>;\n}\n\nexport interface IssueTransitionDeps {\n fetchIssue(issueNumber: number): Promise<{ labels: string[] }>;\n addLabels(issueNumber: number, labels: string[]): Promise<void>;\n removeLabel(issueNumber: number, label: string): Promise<void>;\n closeIssue?(issueNumber: number): Promise<void>;\n updateLabels?(\n issueNumber: number,\n removes: string[],\n adds: string[]\n ): Promise<void>;\n}\n\nexport function createIssueTransitions(\n deps: IssueTransitionDeps,\n labels: IssueTransitionLabels\n): IssueTransitionsContract {\n return {\n async removeBlocked(issueNumber: number): Promise<void> {\n await deps.removeLabel(issueNumber, labels.blocked);\n },\n async addReadyForAgent(issueNumber: number): Promise<void> {\n const issue = await deps.fetchIssue(issueNumber);\n if (!issue.labels.includes(labels.readyForAgent)) {\n await deps.addLabels(issueNumber, [labels.readyForAgent]);\n }\n },\n async moveToNeedsTriage(issueNumber: number): Promise<void> {\n if (deps.updateLabels) {\n await deps.updateLabels(\n issueNumber,\n [labels.blocked, labels.readyForAgent],\n [labels.needsTriage]\n );\n } else {\n await deps.removeLabel(issueNumber, labels.blocked);\n const issue = await deps.fetchIssue(issueNumber);\n if (issue.labels.includes(labels.readyForAgent)) {\n await deps.removeLabel(issueNumber, labels.readyForAgent);\n }\n await deps.addLabels(issueNumber, [labels.needsTriage]);\n }\n },\n async moveToReadyForHuman(issueNumber: number): Promise<void> {\n try {\n await deps.removeLabel(issueNumber, labels.agentInProgress);\n } catch {\n // Ignore - label may not exist\n }\n try {\n await deps.removeLabel(issueNumber, labels.readyForAgent);\n } catch {\n // Ignore - label may not exist\n }\n await deps.addLabels(issueNumber, [labels.readyForHuman]);\n },\n async closeCompleted(issueNumber: number): Promise<void> {\n try {\n await deps.removeLabel(issueNumber, labels.agentInProgress);\n } catch {\n // Ignore - label may not exist\n }\n try {\n await deps.removeLabel(issueNumber, labels.prOpenAwaitingMerge);\n } catch {\n // Ignore - label may not exist\n }\n if (!deps.closeIssue) {\n throw new Error(\"closeIssue is required for closeCompleted\");\n }\n await deps.closeIssue(issueNumber);\n },\n };\n}\n","const BODY_PARENT_SECTION_REGEX = /## Parent\\s*\\n([\\s\\S]*?)(?=\\n## |$)/i;\nconst AFFECTED_CODE_PATHS_SECTION_REGEX =\n /## Affected code paths\\s*\\n([\\s\\S]*?)(?=\\n## |$)/i;\nconst PRD_REF_REGEX = /\\b(PRD-\\d+)\\b/i;\nconst CHILD_TITLE_REGEX = /^\\s*(PRD-\\d+)\\s*\\/\\s*I-\\d+\\b/i;\n\nexport type ParsedStackedIssue = {\n parentRef?: string;\n parentSource?: \"body\" | \"title\";\n bodyParentRef?: string;\n titleParentRef?: string;\n affectedCodePaths: string[];\n isChildIssue: boolean;\n siblingGroupingKey?: string;\n warnings: string[];\n};\n\nexport function parseStackedIssue(\n title: string,\n body: string | null\n): ParsedStackedIssue {\n const bodyParentRef = parseParentRefFromBody(body);\n const titleParentRef = parseParentRefFromTitle(title);\n const warnings: string[] = [];\n\n if (bodyParentRef && titleParentRef && bodyParentRef !== titleParentRef) {\n warnings.push(\n `Parent mismatch: body references ${bodyParentRef} but title references ${titleParentRef}`\n );\n }\n\n const parentRef = bodyParentRef ?? titleParentRef;\n const parentSource = bodyParentRef\n ? \"body\"\n : titleParentRef\n ? \"title\"\n : undefined;\n\n return {\n parentRef,\n parentSource,\n bodyParentRef,\n titleParentRef,\n affectedCodePaths: parseAffectedCodePaths(body),\n isChildIssue: Boolean(bodyParentRef ?? titleParentRef),\n siblingGroupingKey: parentRef,\n warnings,\n };\n}\n\nexport function parseParentRefFromBody(\n body: string | null\n): string | undefined {\n if (!body) return undefined;\n\n const section = body.match(BODY_PARENT_SECTION_REGEX)?.[1];\n if (!section) return undefined;\n\n return normalizeParentRef(section.match(PRD_REF_REGEX)?.[1]);\n}\n\nexport function parseParentRefFromTitle(title: string): string | undefined {\n return normalizeParentRef(title.match(CHILD_TITLE_REGEX)?.[1]);\n}\n\nexport function parseAffectedCodePaths(body: string | null): string[] {\n if (!body) return [];\n\n const section = body.match(AFFECTED_CODE_PATHS_SECTION_REGEX)?.[1];\n if (!section) return [];\n\n const paths = new Set<string>();\n\n for (const rawLine of section.split(\"\\n\")) {\n const line = rawLine.trim();\n\n if (!line.startsWith(\"-\")) continue;\n\n if (/^-\\s+(Class\\/Module|Functions\\/Methods|New):/i.test(line)) {\n continue;\n }\n\n const inlineCodePath = line.match(/`([^`]+)`/)?.[1]?.trim();\n if (inlineCodePath) {\n paths.add(inlineCodePath);\n continue;\n }\n\n const plainPath = line.replace(/^-\\s+/, \"\").trim();\n if (looksLikeRepoPath(plainPath)) {\n paths.add(plainPath);\n }\n }\n\n return Array.from(paths);\n}\n\nfunction normalizeParentRef(ref: string | undefined): string | undefined {\n if (!ref) return undefined;\n return ref\n .trim()\n .toUpperCase()\n .replace(/^(PRD-)(\\d+)$/, (_, p, n) => `${p}${n.padStart(4, \"0\")}`);\n}\n\nfunction looksLikeRepoPath(value: string): boolean {\n return /[./][A-Za-z0-9_-]/.test(value) && !value.includes(\":\");\n}\n","import type { PourkitConfig, ResolvedPrdRunMode } from \"../shared/config\";\nimport type { IssueProvider } from \"../providers/issue-provider\";\nimport type { PRProvider } from \"../providers/pr-provider\";\nimport type {\n ExecutionProvider,\n ExecutionSession,\n} from \"../execution/execution-provider\";\nimport type { PourkitLogger } from \"../shared/common\";\nimport {\n startIssueRun,\n advanceIssueRunReview,\n advanceIssueFinalReview,\n completeIssueRun,\n failIssueRun,\n transitionIssueToHumanHandoff,\n type IssueRunStartResult,\n type RunIssueResult,\n} from \"./issue-run\";\nimport { createIssueTransitions } from \"../issues/issue-transitions\";\nimport { StageFailure } from \"../failure-resolution/types\";\n\nclass HumanHandoffStop extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"HumanHandoffStop\";\n }\n}\n\nexport interface RunIssueOptions {\n issueNumber: number;\n targetName?: string;\n config: PourkitConfig;\n issueProvider: IssueProvider;\n prProvider: PRProvider;\n executionProvider: ExecutionProvider;\n force: boolean;\n resetWorktree?: boolean;\n logger: PourkitLogger;\n repoRoot: string;\n baseBranchOverride?: string;\n prdRunMode?: ResolvedPrdRunMode;\n}\n\nexport type { RunIssueResult };\n\nexport async function runIssueCommand(\n options: RunIssueOptions\n): Promise<RunIssueResult> {\n const {\n issueNumber,\n config,\n issueProvider,\n prProvider,\n executionProvider,\n logger,\n } = options;\n\n const ROOT = options.repoRoot;\n\n let executionSession: ExecutionSession | undefined;\n\n try {\n executionSession = await executionProvider.createSession?.();\n const runOptions = executionSession\n ? { ...options, executionProvider: executionSession }\n : options;\n\n const startResult: IssueRunStartResult = await startIssueRun(runOptions);\n const {\n issue,\n parentPrdIssue,\n target,\n effectiveTarget,\n branchName,\n worktreeState,\n executionResult,\n } = startResult;\n\n let reviewArtifactPath: string | undefined;\n\n const reviewAlreadyPassed =\n worktreeState?.review.lastVerdict &&\n [\"PASS\", \"PASS_WITH_NOTES\"].includes(worktreeState.review.lastVerdict) &&\n !worktreeState.review.exhaustedPreviousRun;\n\n if (reviewAlreadyPassed) {\n reviewArtifactPath = worktreeState.review.lastArtifactPath;\n } else {\n const lifetimeIterationsFromState =\n worktreeState?.review.lifetimeIterations ?? 0;\n const humanHandoffResolved =\n worktreeState?.review.lastVerdict === \"NEEDS_HUMAN\";\n const reviewResult = await advanceIssueRunReview({\n executionProvider: runOptions.executionProvider,\n config,\n target: effectiveTarget,\n issue,\n parentPrdIssue,\n builderBranch: branchName,\n worktreePath: executionResult.worktreePath,\n repoRoot: ROOT,\n logger,\n startingLifetimeIteration: lifetimeIterationsFromState,\n humanHandoffResolved,\n serena: startResult.serena,\n });\n\n if (reviewResult.exhaustedMaxIterations) {\n throw new Error(\n `Max review iterations (${reviewResult.iterations}) exhausted`\n );\n }\n\n if (reviewResult.verdict === \"FAIL\") {\n throw new Error(`Review failed with FAIL verdict`);\n }\n\n if (reviewResult.verdict === \"NEEDS_HUMAN\") {\n await transitionIssueToHumanHandoff({\n issueProvider,\n issueNumber,\n config,\n logger,\n reviewResult,\n });\n throw new HumanHandoffStop(\n `Review requires human handoff: NEEDS_HUMAN verdict`\n );\n }\n\n reviewArtifactPath = reviewResult.artifactPath;\n }\n\n const finalReviewResult = await advanceIssueFinalReview({\n executionProvider: runOptions.executionProvider,\n config,\n target: effectiveTarget,\n issue,\n parentPrdIssue,\n builderBranch: branchName,\n worktreePath: executionResult.worktreePath,\n repoRoot: ROOT,\n logger,\n reviewArtifactPath,\n worktreeState,\n });\n\n if (finalReviewResult.verdict === \"needs_human_review\") {\n const transitions = createIssueTransitions(\n {\n fetchIssue: issueProvider.fetchIssue.bind(issueProvider),\n addLabels: issueProvider.addLabels.bind(issueProvider),\n removeLabel: issueProvider.removeLabel.bind(issueProvider),\n closeIssue: issueProvider.closeIssue.bind(issueProvider),\n },\n {\n blocked: config.labels.blocked,\n readyForAgent: config.labels.readyForAgent,\n needsTriage: config.labels.needsTriage,\n agentInProgress: config.labels.agentInProgress,\n readyForHuman: config.labels.readyForHuman,\n prOpenAwaitingMerge: config.labels.prOpenAwaitingMerge,\n }\n );\n await transitions.moveToReadyForHuman(issueNumber);\n\n const comment = [\n \"Pourkit stopped the Issue Final Review because human review is needed.\",\n \"\",\n finalReviewResult.needsHumanReason,\n \"\",\n \"Artifacts:\",\n `- Issue Final Review: ${finalReviewResult.artifactPath}`,\n ].join(\"\\n\");\n await issueProvider.commentIssue(issueNumber, comment);\n\n logger.step(\n \"info\",\n `Issue Final Review requires human handoff for issue ${issueNumber}`\n );\n\n throw new HumanHandoffStop(\n `Issue Final Review requires human handoff: ${finalReviewResult.needsHumanReason}`\n );\n }\n\n return await completeIssueRun({\n ...runOptions,\n startResult,\n reviewArtifactPath,\n });\n } catch (error) {\n if (error instanceof HumanHandoffStop) {\n throw error;\n }\n\n if (error instanceof Error && \"_tag\" in error) {\n await failIssueRun({\n issueProvider,\n issueNumber,\n config,\n logger,\n error: `[${(error as Record<string, unknown>)._tag}] ${error.message}`,\n });\n } else {\n await failIssueRun({\n issueProvider,\n issueNumber,\n config,\n logger,\n error: error instanceof Error ? error : String(error),\n });\n }\n throw error;\n } finally {\n await executionSession?.close();\n }\n}\n","import type { IssueData } from \"../shared/config\";\nimport { parseStackedIssue } from \"../issues/stacked-issue\";\nimport type { BlockedIssue } from \"../issues/blocked-issue\";\nimport type {\n IssueProvider,\n CreateIssueOptions,\n CreatedIssue,\n} from \"./issue-provider\";\nimport type { GitHubClient } from \"./github-client\";\n\nexport class GitHubIssueProvider implements IssueProvider {\n private readonly client: GitHubClient;\n private readonly readyForAgentLabel: string;\n private readonly blockedLabel: string;\n private readonly issueListLimit: number;\n\n constructor(\n client: GitHubClient,\n options?: {\n readyForAgentLabel?: string;\n blockedLabel?: string;\n issueListLimit?: number;\n }\n ) {\n this.client = client;\n this.readyForAgentLabel = options?.readyForAgentLabel ?? \"ready-for-agent\";\n this.blockedLabel = options?.blockedLabel ?? \"blocked\";\n this.issueListLimit = options?.issueListLimit ?? 50;\n }\n\n async createIssue(options: CreateIssueOptions): Promise<CreatedIssue> {\n const { data } = await this.client.octokit.rest.issues.create({\n owner: this.client.owner,\n repo: this.client.repo,\n title: options.title,\n body: options.body ?? \"\",\n labels: options.labels,\n assignees: options.assignees,\n });\n return { number: data.number, url: data.html_url, title: data.title };\n }\n\n async fetchIssue(number: number): Promise<IssueData> {\n const { data } = await this.client.octokit.rest.issues.get({\n owner: this.client.owner,\n repo: this.client.repo,\n issue_number: number,\n });\n\n const commentsData = await this.client.octokit.paginate(\n this.client.octokit.rest.issues.listComments,\n {\n owner: this.client.owner,\n repo: this.client.repo,\n issue_number: number,\n }\n );\n\n return {\n number: data.number,\n title: data.title,\n body: data.body ?? \"\",\n state: data.state as \"open\" | \"closed\",\n labels: data.labels.map((l) =>\n typeof l === \"string\" ? l : (l.name ?? \"\")\n ),\n comments: commentsData.map((c) => c.body ?? \"\"),\n };\n }\n\n async addLabels(issueNumber: number, labels: string[]): Promise<void> {\n if (labels.length === 0) return;\n await this.client.octokit.rest.issues.addLabels({\n owner: this.client.owner,\n repo: this.client.repo,\n issue_number: issueNumber,\n labels,\n });\n }\n\n async removeLabel(issueNumber: number, label: string): Promise<void> {\n await this.client.octokit.rest.issues.removeLabel({\n owner: this.client.owner,\n repo: this.client.repo,\n issue_number: issueNumber,\n name: label,\n });\n }\n\n async closeIssue(issueNumber: number): Promise<void> {\n const { data } = await this.client.octokit.rest.issues.get({\n owner: this.client.owner,\n repo: this.client.repo,\n issue_number: issueNumber,\n });\n if (data.pull_request) return;\n\n const maxRetries = 3;\n const backoffMs = 2000;\n\n for (let attempt = 1; attempt <= maxRetries; attempt++) {\n try {\n await this.client.octokit.rest.issues.update({\n owner: this.client.owner,\n repo: this.client.repo,\n issue_number: issueNumber,\n state: \"closed\",\n state_reason: \"completed\",\n });\n return;\n } catch (error) {\n const isTransient =\n error instanceof Error && /HTTP (502|503|504)\\b/.test(error.message);\n const isOctokitTransient =\n typeof error === \"object\" &&\n error !== null &&\n \"status\" in error &&\n (error.status === 502 ||\n error.status === 503 ||\n error.status === 504);\n if ((!isTransient && !isOctokitTransient) || attempt === maxRetries) {\n throw error;\n }\n await new Promise((r) =>\n setTimeout(r, backoffMs * Math.pow(2, attempt - 1))\n );\n }\n }\n }\n\n async commentIssue(issueNumber: number, body: string): Promise<void> {\n await this.client.octokit.rest.issues.createComment({\n owner: this.client.owner,\n repo: this.client.repo,\n issue_number: issueNumber,\n body,\n });\n }\n\n async getComments(issueNumber: number): Promise<string[]> {\n const data = await this.client.octokit.paginate(\n this.client.octokit.rest.issues.listComments,\n {\n owner: this.client.owner,\n repo: this.client.repo,\n issue_number: issueNumber,\n }\n );\n return data.map((comment) => comment.body ?? \"\");\n }\n\n async listCandidates(): Promise<IssueData[]> {\n const data = await this.client.octokit.paginate(\n this.client.octokit.rest.issues.listForRepo,\n {\n owner: this.client.owner,\n repo: this.client.repo,\n state: \"open\",\n labels: this.readyForAgentLabel,\n per_page: 100,\n }\n );\n\n return data\n .filter((issue) => !issue.pull_request)\n .map((issue) => mapRawIssue(issue))\n .slice(0, this.issueListLimit);\n }\n\n async listBlockedIssues(): Promise<BlockedIssue[]> {\n const data = await this.client.octokit.paginate(\n this.client.octokit.rest.issues.listForRepo,\n {\n owner: this.client.owner,\n repo: this.client.repo,\n state: \"open\",\n labels: this.blockedLabel,\n per_page: 100,\n }\n );\n\n return data\n .filter((issue) => !issue.pull_request)\n .map((issue) => ({\n number: issue.number,\n title: issue.title,\n body: issue.body ?? null,\n labels: issue.labels.map((l) => ({\n name: typeof l === \"string\" ? l : (l.name ?? \"\"),\n })),\n }))\n .slice(0, this.issueListLimit);\n }\n\n async listRelatedIssues(parentRef: string): Promise<IssueData[]> {\n const data = await this.client.octokit.paginate(\n this.client.octokit.rest.issues.listForRepo,\n {\n owner: this.client.owner,\n repo: this.client.repo,\n state: \"all\",\n per_page: 100,\n }\n );\n\n return data\n .filter((issue) => !issue.pull_request)\n .map((issue) => mapRawIssue(issue))\n .slice(0, this.issueListLimit)\n .filter(\n (issue) =>\n parseStackedIssue(issue.title, issue.body).parentRef === parentRef\n );\n }\n\n async resolveIssueByCanonicalRef(ref: string): Promise<IssueData | null> {\n const canonical = ref.trim().toUpperCase();\n const data = await this.client.octokit.paginate(\n this.client.octokit.rest.issues.listForRepo,\n {\n owner: this.client.owner,\n repo: this.client.repo,\n state: \"all\",\n per_page: 100,\n }\n );\n\n const match = data\n .filter((issue) => !issue.pull_request)\n .slice(0, this.issueListLimit)\n .find((issue) => issue.title.toUpperCase().startsWith(`${canonical}:`));\n if (!match) return null;\n return mapRawIssue(match);\n }\n}\n\nfunction mapRawIssue(issue: {\n number: number;\n title: string;\n body?: string | null;\n state: string;\n labels: Array<{ name?: string | null } | string>;\n created_at?: string | null;\n}): IssueData {\n return {\n number: issue.number,\n title: issue.title,\n body: issue.body ?? \"\",\n state: issue.state.toLowerCase() as \"open\" | \"closed\",\n labels: issue.labels.map((l) =>\n typeof l === \"string\" ? l : (l.name ?? \"\")\n ),\n comments: [],\n createdAt: new Date(issue.created_at ?? \"\"),\n };\n}\n","import type {\n PRProvider,\n PullRequest,\n CreatePrOptions,\n CheckStatus,\n EnableAutoMergeOptions,\n MergePrOptions,\n WaitForPrChecksOptions,\n BranchStatus,\n} from \"./pr-provider\";\nimport { sleep } from \"../shared/common\";\nimport type { PourkitLogger } from \"../shared/common\";\nimport type { GitHubClient } from \"./github-client\";\n\nconst TERMINAL_FAILURE_STATES = new Set([\n \"FAILURE\",\n \"CANCELLED\",\n \"TIMED_OUT\",\n \"STARTUP_FAILURE\",\n \"ACTION_REQUIRED\",\n \"STALE\",\n]);\n\nconst GREEN_CHECK_CONCLUSIONS = new Set([\"SUCCESS\", \"NEUTRAL\", \"SKIPPED\"]);\n\nexport class GitHubPRProvider implements PRProvider {\n private client: GitHubClient;\n private logger: PourkitLogger;\n\n constructor(client: GitHubClient, logger: PourkitLogger) {\n this.client = client;\n this.logger = logger;\n }\n\n async createPr(options: CreatePrOptions): Promise<PullRequest> {\n this.logger.step(\"pr\", `creating PR \"${options.title}\"`);\n\n const { data } = await this.client.octokit.rest.pulls.create({\n owner: this.client.owner,\n repo: this.client.repo,\n title: options.title,\n body: options.body,\n head: options.head,\n base: options.base,\n });\n\n const pr = mapOctokitPr(data);\n\n this.logger.kv(\"PR_NUMBER\", String(pr.number));\n this.logger.kv(\"PR_URL\", pr.url);\n\n return pr;\n }\n\n async getPr(branchName: string): Promise<PullRequest | null> {\n try {\n const { data } = await this.client.octokit.rest.pulls.list({\n owner: this.client.owner,\n repo: this.client.repo,\n head: `${this.client.owner}:${branchName}`,\n state: \"all\",\n per_page: 1,\n });\n\n if (data.length === 0) {\n return null;\n }\n\n return mapOctokitPr(data[0]);\n } catch {\n return null;\n }\n }\n\n async getPrByNumber(prNumber: number): Promise<PullRequest | null> {\n try {\n const { data } = await this.client.octokit.rest.pulls.get({\n owner: this.client.owner,\n repo: this.client.repo,\n pull_number: prNumber,\n });\n\n return mapOctokitPr(data);\n } catch {\n return null;\n }\n }\n\n async getCheckStatus(prNumber: number): Promise<CheckStatus[]> {\n try {\n const { data: pr } = await this.client.octokit.rest.pulls.get({\n owner: this.client.owner,\n repo: this.client.repo,\n pull_number: prNumber,\n });\n\n const headSha = pr.head.sha;\n\n const [checkRuns, combinedStatusResponse] = await Promise.all([\n this.client.octokit.paginate(\n this.client.octokit.rest.checks.listForRef,\n {\n owner: this.client.owner,\n repo: this.client.repo,\n ref: headSha,\n }\n ),\n this.client.octokit.rest.repos.getCombinedStatusForRef({\n owner: this.client.owner,\n repo: this.client.repo,\n ref: headSha,\n }),\n ]);\n\n const checks: CheckStatus[] = [];\n\n for (const run of checkRuns) {\n checks.push({\n name: run.name,\n conclusion: mapCheckConclusion(run.conclusion),\n status: mapCheckRunStatus(run.status),\n });\n }\n\n for (const status of combinedStatusResponse.data.statuses) {\n checks.push(\n mapCommitStatus({ context: status.context, state: status.state })\n );\n }\n\n return checks;\n } catch (error) {\n this.logger.step(\n \"warn\",\n `Failed to get check status for PR #${prNumber}: ${error instanceof Error ? error.message : String(error)}`\n );\n return [];\n }\n }\n\n async enableAutoMerge(\n pr: PullRequest,\n options?: EnableAutoMergeOptions\n ): Promise<void> {\n const method = (options?.method ?? \"squash\").toUpperCase();\n\n await this.client.octokit.graphql(\n `mutation enablePullRequestAutoMerge(\n $pullRequestId: ID!\n $mergeMethod: PullRequestMergeMethod\n $expectedHeadOid: GitObjectID\n ) {\n enablePullRequestAutoMerge(input: {\n pullRequestId: $pullRequestId\n mergeMethod: $mergeMethod\n expectedHeadOid: $expectedHeadOid\n }) {\n pullRequest {\n id\n number\n }\n }\n }`,\n {\n pullRequestId: pr.nodeId,\n mergeMethod: method,\n expectedHeadOid: options?.expectedHeadOid,\n }\n );\n }\n\n async mergePr(prNumber: number, options?: MergePrOptions): Promise<void> {\n const method = options?.method ?? \"squash\";\n this.logger.step(\"pr\", `merging PR #${prNumber} with ${method} merge`);\n\n await this.client.octokit.rest.pulls.merge({\n owner: this.client.owner,\n repo: this.client.repo,\n pull_number: prNumber,\n merge_method: method,\n sha: options?.matchHeadCommit,\n });\n }\n\n async waitForPrChecks(\n prNumber: number,\n options?: WaitForPrChecksOptions\n ): Promise<CheckStatus[]> {\n const checksFoundTimeoutMs = options?.checksFoundTimeoutMs ?? 60 * 1000;\n const checksCompletionTimeoutMs =\n options?.checksCompletionTimeoutMs ?? 30 * 60 * 1000;\n const pollIntervalMs = options?.pollIntervalMs ?? 15 * 1000;\n const requiredChecks = options?.requiredChecks ?? [];\n\n const discoveredDeadline = Date.now() + checksFoundTimeoutMs;\n let completionDeadline = 0;\n let checksDiscovered = false;\n this.logger.step(\"pr\", `waiting for checks on PR #${prNumber}`);\n\n while (true) {\n const observedAt = Date.now();\n const checks = await this.getCheckStatus(prNumber);\n\n if (!hasRequiredChecks(checks, requiredChecks)) {\n if (Date.now() >= discoveredDeadline) {\n if (requiredChecks.length === 0) {\n this.logger.step(\n \"info\",\n \"No checks appeared within grace period, treating as passed\"\n );\n return [];\n }\n\n throw new Error(\n `Timeout waiting for required checks on PR #${prNumber}: ${requiredChecks.join(\", \")}`\n );\n }\n\n this.logger.step(\n \"info\",\n requiredChecks.length === 0\n ? `No checks found, waiting... (${secondsRemaining(discoveredDeadline, observedAt)}s remaining)`\n : `Waiting for required checks to appear: ${requiredChecks.join(\", \")} (${secondsRemaining(discoveredDeadline, observedAt)}s remaining)`\n );\n await sleep(pollIntervalMs);\n continue;\n }\n\n const filteredChecks = filterChecks(checks, requiredChecks);\n\n if (!checksDiscovered) {\n checksDiscovered = true;\n completionDeadline = observedAt + checksCompletionTimeoutMs;\n }\n\n this.logger.step(\"info\", `Checks: ${formatChecks(filteredChecks)}`);\n\n const evaluation = evaluateChecks(filteredChecks);\n if (evaluation.complete && evaluation.failed.length === 0) {\n this.logger.step(\"success\", \"All checks passed\");\n return checks;\n }\n\n if (evaluation.complete) {\n throw new Error(`Checks failed: ${formatChecks(evaluation.failed)}`);\n }\n\n if (Date.now() >= completionDeadline) {\n throw new Error(`Timeout waiting for checks on PR #${prNumber}`);\n }\n\n this.logger.step(\n \"info\",\n `Checks still pending, waiting... (${secondsRemaining(completionDeadline, observedAt)}s remaining)`\n );\n await sleep(pollIntervalMs);\n }\n }\n\n async getBranchStatus(branchName: string): Promise<BranchStatus> {\n this.logger.step(\"pr\", `getting branch status for ${branchName}`);\n\n try {\n const targetStatus = await this.getTargetBranchStatus(branchName);\n\n let state: BranchStatus[\"state\"] = \"pending\";\n\n if (targetStatus.checks.length > 0) {\n const hasFailure = targetStatus.checks.some(\n (check) =>\n check.conclusion !== null &&\n TERMINAL_FAILURE_STATES.has(check.conclusion)\n );\n const allComplete = targetStatus.checks.every(\n (check) => check.status === \"COMPLETED\"\n );\n const allGreen = targetStatus.checks.every(\n (check) =>\n check.conclusion !== null &&\n GREEN_CHECK_CONCLUSIONS.has(check.conclusion)\n );\n\n if (hasFailure) {\n state = \"red\";\n } else if (allComplete && allGreen) {\n state = \"green\";\n }\n }\n\n return {\n headSha: targetStatus.headSha,\n state,\n checks: targetStatus.checks,\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(\n `Failed to get branch status for ${branchName}: ${message}`\n );\n }\n }\n\n private async getTargetBranchStatus(\n branchName: string\n ): Promise<{ branchName: string; headSha: string; checks: CheckStatus[] }> {\n const { data: branch } = await this.client.octokit.rest.repos.getBranch({\n owner: this.client.owner,\n repo: this.client.repo,\n branch: branchName,\n });\n\n const headSha = branch.commit.sha;\n\n const [checkRuns, combinedStatusResponse] = await Promise.all([\n this.client.octokit.paginate(this.client.octokit.rest.checks.listForRef, {\n owner: this.client.owner,\n repo: this.client.repo,\n ref: headSha,\n }),\n this.client.octokit.rest.repos.getCombinedStatusForRef({\n owner: this.client.owner,\n repo: this.client.repo,\n ref: headSha,\n }),\n ]);\n\n return {\n branchName,\n headSha,\n checks: [\n ...checkRuns.map((check) => ({\n name: check.name,\n status: mapCheckRunStatus(check.status),\n conclusion: mapCheckConclusion(check.conclusion),\n })),\n ...combinedStatusResponse.data.statuses.map((status) =>\n mapCommitStatus(status)\n ),\n ],\n };\n }\n}\n\nfunction mapOctokitPr(data: {\n number: number;\n node_id: string;\n html_url: string;\n title: string;\n body: string | null;\n head: { ref: string; sha: string };\n base: { ref: string };\n state: string;\n merged?: boolean;\n draft?: boolean;\n merge_commit_sha?: string | null;\n}): PullRequest {\n return {\n number: data.number,\n nodeId: data.node_id,\n url: data.html_url,\n title: data.title,\n body: data.body ?? \"\",\n headRefName: data.head.ref,\n baseRefName: data.base.ref,\n state:\n data.state === \"closed\" ? (data.merged ? \"MERGED\" : \"CLOSED\") : \"OPEN\",\n headRefOid: data.head.sha,\n mergeCommitSha: data.merge_commit_sha ?? undefined,\n };\n}\n\nfunction mapCheckRunStatus(status: string): CheckStatus[\"status\"] {\n const normalized = status.toUpperCase();\n\n if (\n normalized === \"QUEUED\" ||\n normalized === \"IN_PROGRESS\" ||\n normalized === \"COMPLETED\" ||\n normalized === \"WAITING\" ||\n normalized === \"PENDING\" ||\n normalized === \"REQUESTED\"\n ) {\n return normalized as CheckStatus[\"status\"];\n }\n\n return null;\n}\n\nfunction mapCheckConclusion(\n conclusion: string | null\n): CheckStatus[\"conclusion\"] {\n const normalized = conclusion?.toUpperCase();\n\n if (\n normalized === \"SUCCESS\" ||\n normalized === \"FAILURE\" ||\n normalized === \"NEUTRAL\" ||\n normalized === \"SKIPPED\" ||\n normalized === \"STALE\" ||\n normalized === \"STARTUP_FAILURE\" ||\n normalized === \"CANCELLED\" ||\n normalized === \"TIMED_OUT\" ||\n normalized === \"ACTION_REQUIRED\"\n ) {\n return normalized as CheckStatus[\"conclusion\"];\n }\n\n return null;\n}\n\nfunction mapCommitStatus(status: {\n context: string;\n state: string;\n}): CheckStatus {\n const normalized = status.state.toUpperCase();\n\n if (normalized === \"SUCCESS\") {\n return { name: status.context, status: \"COMPLETED\", conclusion: \"SUCCESS\" };\n }\n\n if (normalized === \"PENDING\") {\n return { name: status.context, status: \"PENDING\", conclusion: null };\n }\n\n return { name: status.context, status: \"COMPLETED\", conclusion: \"FAILURE\" };\n}\n\nfunction filterChecks(checks: CheckStatus[], requiredChecks: string[]) {\n return requiredChecks.length > 0\n ? checks.filter((check) => requiredChecks.includes(check.name))\n : checks;\n}\n\nfunction hasRequiredChecks(checks: CheckStatus[], requiredChecks: string[]) {\n return requiredChecks.length === 0\n ? checks.length > 0\n : requiredChecks.every((name) =>\n checks.some((check) => check.name === name)\n );\n}\n\nfunction secondsRemaining(deadline: number, observedAt: number) {\n return Math.max(0, Math.ceil((deadline - observedAt) / 1000));\n}\n\nfunction evaluateChecks(checks: CheckStatus[]) {\n const failed = checks.filter(\n (check) =>\n check.status === \"COMPLETED\" &&\n check.conclusion !== null &&\n !isSuccessfulConclusion(check.conclusion)\n );\n\n return {\n complete: checks.every((check) => check.status === \"COMPLETED\"),\n failed,\n };\n}\n\nfunction isSuccessfulConclusion(\n conclusion: NonNullable<CheckStatus[\"conclusion\"]>\n) {\n return (\n conclusion === \"SUCCESS\" ||\n conclusion === \"NEUTRAL\" ||\n conclusion === \"SKIPPED\"\n );\n}\n\nfunction formatChecks(checks: CheckStatus[]) {\n return checks\n .map((check) => `${check.name}=${check.conclusion ?? check.status}`)\n .join(\", \");\n}\n","import { Octokit } from \"octokit\";\n\nexport interface GitHubClient {\n octokit: Octokit;\n owner: string;\n repo: string;\n}\n\nexport interface GitHubClientOptions {\n cwd?: string;\n env?: NodeJS.ProcessEnv;\n repository?: string;\n}\n\nconst REMOTE_PATTERN = /github\\.com[:/]([^/]+)\\/([^/]+?)(?:\\.git)?$/;\n\nexport function resolveGitHubToken(env: NodeJS.ProcessEnv): string {\n const token = env.POURKIT_GITHUB_TOKEN ?? env.GH_TOKEN ?? env.GITHUB_TOKEN;\n if (!token) {\n throw new Error(\n \"GitHub token is required. Set POURKIT_GITHUB_TOKEN, GH_TOKEN, or GITHUB_TOKEN.\"\n );\n }\n return token;\n}\n\nexport async function resolveGitHubRepository(\n options?: GitHubClientOptions\n): Promise<{ owner: string; repo: string }> {\n if (options?.repository) {\n const parts = options.repository.split(\"/\");\n if (parts.length !== 2 || !parts[0] || !parts[1]) {\n throw new Error(\n `Invalid repository format: \"${options.repository}\". Expected \"owner/repo\".`\n );\n }\n return { owner: parts[0], repo: parts[1] };\n }\n\n const env = options?.env ?? process.env;\n const envRepo = env.GITHUB_REPOSITORY;\n if (envRepo) {\n const parts = envRepo.split(\"/\");\n if (parts.length === 2 && parts[0] && parts[1]) {\n return { owner: parts[0], repo: parts[1] };\n }\n throw new Error(\n `Invalid repository format: \"${envRepo}\". Expected \"owner/repo\".`\n );\n }\n\n const { execCapture } = await import(\"../shared/common\");\n const cwd = options?.cwd;\n try {\n const result = await execCapture(\"git\", [\"remote\", \"get-url\", \"origin\"], {\n cwd,\n });\n const remote = result.stdout.trim();\n const match = remote.match(REMOTE_PATTERN);\n if (match) {\n return { owner: match[1], repo: match[2] };\n }\n } catch {\n // fall through to error\n }\n\n throw new Error(\n \"Could not resolve GitHub repository. Set GITHUB_REPOSITORY env var or ensure a valid 'origin' remote exists.\"\n );\n}\n\nexport async function requireGitHubClient(\n options?: GitHubClientOptions\n): Promise<GitHubClient> {\n const env = options?.env ?? process.env;\n const token = resolveGitHubToken(env);\n const repo = await resolveGitHubRepository(options);\n\n const octokit = new Octokit({ auth: token });\n\n return { octokit, ...repo };\n}\n\nexport async function tryCreateGitHubClient(\n options?: GitHubClientOptions\n): Promise<\n | { ok: true; client: GitHubClient }\n | {\n ok: false;\n reason: \"missing-token\" | \"missing-repository\" | \"invalid-repository\";\n message: string;\n }\n> {\n const env = options?.env ?? process.env;\n\n let token: string;\n try {\n token = resolveGitHubToken(env);\n } catch {\n return {\n ok: false,\n reason: \"missing-token\",\n message: \"GitHub token is not configured.\",\n };\n }\n\n let repo: { owner: string; repo: string };\n try {\n repo = await resolveGitHubRepository(options);\n } catch (e) {\n const message = e instanceof Error ? e.message : String(e);\n if (message.includes(\"Invalid repository format\")) {\n return { ok: false, reason: \"invalid-repository\", message };\n }\n return { ok: false, reason: \"missing-repository\", message };\n }\n\n const octokit = new Octokit({ auth: token });\n\n return { ok: true, client: { octokit, ...repo } };\n}\n","import type {\n AgentProvider,\n AgentCommandOptions,\n PrintCommand,\n} from \"@ai-hero/sandcastle\";\nimport { createWorktree, run } from \"@ai-hero/sandcastle\";\nimport { docker } from \"@ai-hero/sandcastle/sandboxes/docker\";\nimport { ensureSandboxImageBuilt } from \"./sandbox-image-build\";\nimport { buildSandboxOptions } from \"./sandbox-options\";\n\ntype DeterministicParsedStreamEvent =\n | {\n type: \"text\";\n text: string;\n }\n | {\n type: \"result\";\n result: string;\n }\n | {\n type: \"tool_call\";\n name: string;\n args: string;\n }\n | {\n type: \"session_id\";\n sessionId: string;\n };\nimport type {\n ExecutionProvider,\n ExecutionProviderOptions,\n ExecutionResult,\n} from \"./execution-provider\";\nimport { writeExecutionArtifacts } from \"./execution-provider\";\n\ninterface DeterministicAgentOptions {\n env?: Record<string, string>;\n}\n\nclass DeterministicAgentProvider implements AgentProvider {\n readonly name = \"deterministic-agent\";\n readonly env: Record<string, string>;\n readonly captureSessions = false;\n\n constructor(options?: DeterministicAgentOptions) {\n this.env = options?.env ?? {};\n }\n\n buildPrintCommand(_options: AgentCommandOptions): PrintCommand {\n return {\n command: \"bash pourkit/execution/deterministic-agent.sh\",\n };\n }\n\n parseStreamLine(line: string): DeterministicParsedStreamEvent[] {\n const events: DeterministicParsedStreamEvent[] = [];\n\n if (line.includes(\"<promise>COMPLETE</promise>\")) {\n events.push({\n type: \"text\",\n text: line,\n });\n events.push({\n type: \"result\",\n result: \"COMPLETE\",\n });\n } else if (line.trim().length > 0) {\n events.push({\n type: \"text\",\n text: line,\n });\n }\n\n return events;\n }\n}\n\nfunction resolveSandboxProvider(provider: string) {\n if (provider === \"docker\") {\n return docker;\n }\n\n throw new Error(`Unsupported sandbox provider: ${provider}`);\n}\n\nfunction sanitizeBranch(branchName: string) {\n return branchName.replace(/[^A-Za-z0-9._-]/g, \"-\");\n}\n\nexport class DeterministicExecutionProvider implements ExecutionProvider {\n lastResult: ExecutionResult | null = null;\n lastOptions: ExecutionProviderOptions | null = null;\n\n async execute(options: ExecutionProviderOptions): Promise<ExecutionResult> {\n this.lastOptions = options;\n const {\n stage,\n iteration,\n repoRoot: root,\n branchName,\n worktreePath,\n sandbox,\n timeoutMs,\n artifacts = [],\n logger,\n } = options;\n\n const stageLabel =\n iteration !== undefined ? `${stage}:${iteration}` : stage;\n logger.step(\n \"deterministic\",\n `[${stageLabel}] running deterministic agent (no LLM tokens)`\n );\n\n try {\n const logPath = `${root}/.pourkit/logs/${sanitizeBranch(branchName)}-deterministic-${Date.now()}.log`;\n\n await ensureSandboxImageBuilt(root, { force: sandbox.forceRebuild });\n\n const env: Record<string, string> = {\n POURKIT_STAGE: stage,\n POURKIT_BRANCH_NAME: branchName,\n };\n if (options.artifactPath) {\n env.POURKIT_ARTIFACT_PATH = options.artifactPath;\n }\n if (iteration !== undefined) {\n env.POURKIT_REVIEW_ITERATION = String(iteration);\n }\n\n const agent = new DeterministicAgentProvider({ env });\n\n const sandboxOptions = buildSandboxOptions(root, sandbox);\n const sandboxProvider = resolveSandboxProvider(sandbox.provider);\n let createdWorktreePath: string | undefined;\n const result = worktreePath\n ? await (async () => {\n await writeExecutionArtifacts(worktreePath, artifacts);\n return run({\n agent,\n sandbox: sandboxProvider(sandboxOptions),\n cwd: worktreePath,\n branchStrategy: { type: \"head\" },\n prompt: options.prompt,\n maxIterations: 1,\n logging: {\n type: \"file\",\n path: logPath,\n },\n completionSignal: \"<promise>COMPLETE</promise>\",\n ...(timeoutMs ? { signal: AbortSignal.timeout(timeoutMs) } : {}),\n });\n })()\n : await (async () => {\n const worktree = await createWorktree({\n cwd: root,\n branchStrategy: {\n type: \"branch\",\n branch: branchName,\n baseBranch: options.baseRef ?? options.target.baseBranch,\n },\n });\n createdWorktreePath = worktree.worktreePath;\n await writeExecutionArtifacts(worktree.worktreePath, artifacts);\n return worktree.run({\n agent,\n sandbox: sandboxProvider(sandboxOptions),\n prompt: options.prompt,\n maxIterations: 1,\n logging: {\n type: \"file\",\n path: logPath,\n },\n completionSignal: \"<promise>COMPLETE</promise>\",\n ...(timeoutMs ? { signal: AbortSignal.timeout(timeoutMs) } : {}),\n });\n })();\n\n const commits = result.commits.map((c) => c.sha);\n\n logger.kv(\"SANDBOX_SUCCESS\", \"true\");\n logger.kv(\"COMMITS_CREATED\", String(commits.length));\n logger.kv(\"WORKTREE_BRANCH\", result.branch);\n if (result.logFilePath) {\n logger.kv(\"LOG_FILE\", result.logFilePath);\n }\n\n const artifactOnlyStage = stage === \"reviewer\" || stage === \"finalizer\";\n\n if (commits.length === 0 && !artifactOnlyStage) {\n this.lastResult = {\n success: false,\n branch: result.branch,\n worktreePath: worktreePath ?? createdWorktreePath ?? \"\",\n commits: [],\n logPath,\n error: \"Deterministic agent returned zero commits\",\n };\n return this.lastResult;\n }\n\n this.lastResult = {\n success: true,\n branch: result.branch,\n worktreePath: worktreePath ?? createdWorktreePath ?? \"\",\n commits,\n logPath,\n };\n return this.lastResult;\n } catch (error) {\n logger.step(\n \"error\",\n `Deterministic execution failed: ${error instanceof Error ? error.message : String(error)}`\n );\n this.lastResult = {\n success: false,\n branch: \"\",\n worktreePath: \"\",\n commits: [],\n logPath: null,\n error: error instanceof Error ? error.message : String(error),\n };\n return this.lastResult;\n }\n }\n}\n","import path from \"node:path\";\n\nimport { execCapture } from \"../shared/common\";\nimport { sandboxImageName } from \"./sandbox-image\";\n\nexport async function ensureSandboxImageBuilt(\n repoRoot: string,\n options?: { force?: boolean }\n) {\n const imageName = sandboxImageName(repoRoot);\n const dockerfilePath = path.join(repoRoot, \".sandcastle\", \"Dockerfile\");\n\n if (!options?.force) {\n try {\n await execCapture(\"docker\", [\"image\", \"inspect\", imageName]);\n return;\n } catch {\n // image missing, fall through to build\n }\n }\n\n const buildArgs = [\"build\", \"-t\", imageName, \"-f\", dockerfilePath];\n if (options?.force) {\n buildArgs.push(\"--pull\", \"--no-cache\");\n }\n buildArgs.push(repoRoot);\n\n await execCapture(\"docker\", buildArgs);\n}\n","import { createHash } from \"node:crypto\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport path from \"node:path\";\n\nexport function sandboxImageName(repoRoot: string): string {\n const dirName = path.basename(repoRoot.replace(/[\\\\/]+$/, \"\")) || \"local\";\n const sanitized = dirName.toLowerCase().replace(/[^a-z0-9_.-]/g, \"-\");\n const baseName = sanitized || \"local\";\n const dockerfilePath = path.join(repoRoot, \".sandcastle\", \"Dockerfile\");\n\n if (!existsSync(dockerfilePath)) {\n return `sandcastle:${baseName}`;\n }\n\n const fingerprint = createHash(\"sha256\")\n .update(readFileSync(dockerfilePath))\n .digest(\"hex\")\n .slice(0, 8);\n\n return `sandcastle:${baseName}-${fingerprint}`;\n}\n","import type { SandboxConfig, SandboxMountConfig } from \"../shared/config\";\nimport { sandboxImageName } from \"./sandbox-image\";\n\nexport interface SandcastleSandboxOptions {\n imageName: string;\n mounts?: SandboxConfig[\"mounts\"];\n env?: SandboxConfig[\"env\"];\n idleTimeoutSeconds?: number;\n}\n\nexport function buildSandboxOptions(\n repoRoot: string,\n sandbox: SandboxConfig\n): SandcastleSandboxOptions {\n const mounts: SandboxConfig[\"mounts\"] = [];\n if (sandbox.mounts !== undefined) {\n mounts.push(...sandbox.mounts);\n }\n\n return {\n imageName: sandboxImageName(repoRoot),\n ...(mounts.length > 0 ? { mounts } : {}),\n ...(sandbox.env !== undefined ? { env: sandbox.env } : {}),\n ...(sandbox.idleTimeoutSeconds !== undefined\n ? { idleTimeoutSeconds: sandbox.idleTimeoutSeconds }\n : {}),\n };\n}\n","import { mkdtempSync } from \"node:fs\";\nimport { writeFile } from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport { dirname, join } from \"path\";\nimport { ensureDir, execCapture, type PourkitLogger } from \"../shared/common\";\nimport type {\n SandboxConfig,\n Target,\n VerificationCommand,\n} from \"../shared/config\";\nimport type { ExecutionArtifact } from \"../shared/run-context\";\nimport type { SerenaExecutionContext } from \"./opencode-config\";\n\nexport interface ExecutionResult {\n success: boolean;\n branch: string;\n worktreePath: string;\n commits: string[];\n logPath: string | null;\n error?: string;\n}\n\nexport type PourkitStage =\n | \"builder\"\n | \"reviewer\"\n | \"refactor\"\n | \"finalizer\"\n | \"conflictResolution\"\n | \"failureResolution\"\n | \"issueFinalReview\"\n | \"prdFinalReview\";\n\nexport interface ExecutionProviderOptions {\n stage: PourkitStage;\n iteration?: number;\n artifactPath?: string;\n worktreePath?: string;\n agent: string;\n model: string;\n variant?: string;\n env?: Record<string, string>;\n prompt: string;\n target: Target;\n repoRoot: string;\n branchName: string;\n baseRef?: string;\n checkoutBase?: string;\n reviewBase?: string;\n sandbox: SandboxConfig;\n serena?: SerenaExecutionContext;\n autoApprove?: boolean;\n timeoutMs?: number;\n artifacts?: ExecutionArtifact[];\n logger: PourkitLogger;\n}\n\nexport interface ExecutionProvider {\n execute(options: ExecutionProviderOptions): Promise<ExecutionResult>;\n createSession?(): Promise<ExecutionSession>;\n}\n\nexport interface ExecutionSession extends ExecutionProvider {\n close(): Promise<void>;\n}\n\nasync function runSetupCommands(\n commands: VerificationCommand[],\n worktreePath: string,\n logger: PourkitLogger\n) {\n for (const command of commands) {\n await execCapture(\"bash\", [\"-lc\", command.command], {\n cwd: worktreePath,\n logger,\n label: command.label,\n });\n }\n}\n\nexport async function writeExecutionArtifacts(\n worktreePath: string,\n artifacts: ExecutionArtifact[]\n) {\n for (const artifact of artifacts) {\n const filePath = join(worktreePath, artifact.path);\n await ensureDir(dirname(filePath));\n await writeFile(filePath, artifact.content, \"utf-8\");\n }\n}\n\nexport class FakeExecutionProvider implements ExecutionProvider {\n private _result: ExecutionResult;\n lastOptions: ExecutionProviderOptions | null = null;\n calls: ExecutionProviderOptions[] = [];\n issueFinalReviewArtifactContent: string | null = null;\n finalReviewArtifactContent: string | null = null;\n\n constructor(result: ExecutionResult) {\n this._result = result;\n }\n\n async execute(_options: ExecutionProviderOptions): Promise<ExecutionResult> {\n this.lastOptions = _options;\n this.calls.push(_options);\n const resolvedWorktreePath =\n _options.worktreePath ??\n this._result.worktreePath ??\n mkdtempSync(join(tmpdir(), \"fake-provider-\"));\n if (_options.artifactPath) {\n const artifactPath = join(resolvedWorktreePath, _options.artifactPath);\n await ensureDir(dirname(artifactPath));\n if (_options.stage === \"reviewer\") {\n await writeFile(\n artifactPath,\n [\n \"## Findings\",\n \"\",\n \"| ID | Supersedes | Severity | File/Line | Issue | Recommendation |\",\n \"|----|------------|----------|-----------|-------|----------------|\",\n \"| none | n/a | n/a | n/a | No findings. | n/a |\",\n \"\",\n \"<verdict>PASS</verdict>\",\n ].join(\"\\n\"),\n \"utf-8\"\n );\n }\n if (_options.stage === \"finalizer\") {\n await writeFile(\n artifactPath,\n _options.prompt.includes(\"# Final Review Retouch PR Finalizer\")\n ? \"## PR Title\\n\\nchore: Final Review retouch\\n\\n## PR Body\\n\\nFinal Review retouch body.\"\n : \"## PR Title\\n\\nfix: Test issue\\n\\n## PR Body\\n\\nCloses #42\",\n \"utf-8\"\n );\n }\n if (_options.stage === \"issueFinalReview\") {\n const issueNumber = (() => {\n const branchMatch = _options.branchName?.match(/\\/(\\d+)\\//);\n return branchMatch ? parseInt(branchMatch[1], 10) : 42;\n })();\n const defaultContent = JSON.stringify({\n kind: \"issue-final-review\",\n issueNumber,\n branchName: _options.branchName ?? \"test-branch\",\n verdict: \"pass\",\n summary: \"Issue Final Review passed.\",\n changedPaths: [],\n selfRetouched: false,\n verification: {\n required: false,\n passed: false,\n commands: [],\n summary: \"\",\n },\n needsHumanReason: null,\n });\n const content = this.issueFinalReviewArtifactContent ?? defaultContent;\n await writeFile(artifactPath, content, \"utf-8\");\n }\n if (_options.stage === \"prdFinalReview\") {\n const defaultContent = (() => {\n const prdRefMatch = _options.prompt.match(\n /\"prdRef\":\\s*\"([A-Z]+-\\d+)\"/\n );\n const prdRef = prdRefMatch?.[1] ?? \"PRD-0000\";\n return JSON.stringify({\n prdRef,\n stage: \"prdFinalReview\",\n checkoutBase: _options.checkoutBase ?? prdRef,\n reviewBase: _options.reviewBase ?? _options.baseRef ?? \"\",\n verdict: \"pass_no_changes\",\n summary: \"Final review passed with no changes needed.\",\n });\n })();\n const content = this.finalReviewArtifactContent ?? defaultContent;\n await writeFile(artifactPath, content, \"utf-8\");\n if (content) {\n const parsed = JSON.parse(content);\n if (\n parsed.verdict === \"pass_with_retouch\" &&\n Array.isArray(parsed.retouchFiles)\n ) {\n for (const rf of parsed.retouchFiles) {\n const fullPath = join(resolvedWorktreePath, rf.path);\n await ensureDir(dirname(fullPath));\n await writeFile(fullPath, rf.content, \"utf-8\");\n }\n }\n }\n }\n }\n return {\n ...this._result,\n worktreePath: resolvedWorktreePath,\n };\n }\n\n get result(): ExecutionResult {\n return this._result;\n }\n\n set result(value: ExecutionResult) {\n this._result = value;\n }\n}\n","import type { VerificationCommand } from \"../shared/config\";\n\nexport type E2EVerificationProfile = \"fast\" | \"full-check\" | \"failure\";\n\nexport function getVerificationCommands(\n baseCommands: VerificationCommand[],\n profile: E2EVerificationProfile\n): VerificationCommand[] {\n if (profile === \"failure\") {\n return [{ command: \"exit 1\", label: \"fail-e2e\" }];\n }\n if (profile === \"full-check\") {\n return [\n { command: \"npm run prettier:check\", label: \"prettier:check\" },\n { command: \"npm run typecheck\", label: \"typecheck\" },\n { command: \"npm run test\", label: \"tests\" },\n { command: \"npm run build\", label: \"build\" },\n ];\n }\n return baseCommands;\n}\n\nexport function composeFailureWithProfile(\n baseCommands: VerificationCommand[],\n profile: E2EVerificationProfile\n): VerificationCommand[] {\n const commands = getVerificationCommands(baseCommands, profile);\n return [{ command: \"exit 1\", label: \"fail-e2e\" }, ...commands];\n}\n","import path from \"node:path\";\nimport {\n access,\n mkdir,\n readFile,\n readdir,\n rm,\n writeFile,\n} from \"node:fs/promises\";\nimport type {\n ExecutionProvider,\n ExecutionProviderOptions,\n ExecutionResult,\n} from \"../../execution/execution-provider\";\nimport type {\n BranchStatus,\n CheckStatus,\n EnableAutoMergeOptions,\n MergePrOptions,\n PRProvider,\n PullRequest,\n WaitForPrChecksOptions,\n} from \"../../providers/pr-provider\";\nimport {\n execCapture,\n parseWorktreeListPorcelain,\n type PourkitLogger,\n} from \"../../shared/common\";\nimport type { GitHubClient } from \"../../providers/github-client\";\n\nexport interface E2EResources {\n targetBranch?: string;\n issueNumber?: number;\n issueUrl?: string;\n agentBranch?: string;\n prNumber?: number;\n prUrl?: string;\n}\n\ntype ReviewVerdict = \"PASS\" | \"PASS_WITH_NOTES\" | \"NEEDS_REFACTOR\" | \"FAIL\";\n\nexport interface LabelAssertionOptions {\n present?: string[];\n absent?: string[];\n}\n\nexport interface ExecutionFailureInjection {\n error?: string;\n throwMessage?: string;\n}\n\nexport interface ReviewerInjection extends ExecutionFailureInjection {\n verdicts?: ReviewVerdict[];\n invalidProtocol?: boolean;\n}\n\nexport interface RefactorInjection extends ExecutionFailureInjection {\n failIterations?: number[];\n commits?: string[];\n}\n\nexport interface FinalizerInjection extends ExecutionFailureInjection {\n invalidProtocol?: boolean;\n title?: string;\n body?: string;\n}\n\nexport interface IssueFinalReviewInjection extends ExecutionFailureInjection {\n invalidProtocol?: boolean;\n verdict?: \"pass\" | \"needs_human_review\";\n humanReason?: string;\n selfRetouched?: boolean;\n changedPaths?: string[];\n verificationPassed?: boolean;\n}\n\nexport interface FailureResolutionInjection extends ExecutionFailureInjection {\n artifact?: string;\n resolve?: (options: ExecutionProviderOptions) => Promise<void> | void;\n}\n\nexport interface ScenarioExecutionInjections {\n builder?: ExecutionFailureInjection;\n reviewer?: ReviewerInjection;\n refactor?: RefactorInjection;\n issueFinalReview?: IssueFinalReviewInjection;\n finalizer?: FinalizerInjection;\n failureResolution?: FailureResolutionInjection;\n}\n\nexport interface ScenarioPrInjections {\n branchStatuses?: BranchStatus[];\n waitForChecksDelayMs?: number;\n waitForChecksError?: string;\n waitForChecksResult?: CheckStatus[];\n requireWaitForChecksBeforeMerge?: boolean;\n expectLabelBeforeMerge?: {\n issueNumber: number;\n label: string;\n };\n}\n\nfunction makeSyntheticExecutionResult(\n options: ExecutionProviderOptions,\n success: boolean,\n commits: string[] = [],\n error?: string\n): ExecutionResult {\n return {\n success,\n branch: options.branchName,\n worktreePath: options.worktreePath ?? \"\",\n commits,\n logPath: null,\n ...(error ? { error } : {}),\n };\n}\n\nasync function maybeThrowInjectedFailure(\n injection: ExecutionFailureInjection | undefined\n): Promise<void> {\n if (injection?.throwMessage) {\n throw new Error(injection.throwMessage);\n }\n}\n\nasync function writeScenarioArtifact(\n worktreePath: string,\n artifactPath: string,\n content: string\n): Promise<void> {\n const filePath = path.join(worktreePath, artifactPath);\n await mkdir(path.dirname(filePath), { recursive: true });\n await writeFile(filePath, content, \"utf-8\");\n}\n\nexport class ScenarioExecutionProvider implements ExecutionProvider {\n readonly stageCalls: string[] = [];\n readonly reviewIterations: number[] = [];\n readonly refactorIterations: number[] = [];\n readonly issueFinalReviewCalls: ExecutionProviderOptions[] = [];\n readonly prdFinalReviewCalls: ExecutionProviderOptions[] = [];\n\n constructor(\n private readonly baseProvider: ExecutionProvider,\n readonly injections: ScenarioExecutionInjections = {}\n ) {}\n\n // fallow-ignore-next-line unused-class-member\n resetRunTracking(): void {\n this.stageCalls.length = 0;\n this.reviewIterations.length = 0;\n this.refactorIterations.length = 0;\n }\n\n async execute(options: ExecutionProviderOptions): Promise<ExecutionResult> {\n this.stageCalls.push(options.stage);\n\n if (options.stage === \"builder\") {\n await maybeThrowInjectedFailure(this.injections.builder);\n if (this.injections.builder?.error) {\n return makeSyntheticExecutionResult(\n options,\n false,\n [],\n this.injections.builder.error\n );\n }\n return this.baseProvider.execute(options);\n }\n\n if (options.stage === \"reviewer\") {\n await maybeThrowInjectedFailure(this.injections.reviewer);\n if (this.injections.reviewer?.error) {\n return makeSyntheticExecutionResult(\n options,\n false,\n [],\n this.injections.reviewer.error\n );\n }\n\n this.reviewIterations.push(options.iteration ?? 1);\n const verdicts = this.injections.reviewer?.verdicts ?? [\"PASS\"];\n const verdict =\n verdicts[\n Math.min(this.reviewIterations.length - 1, verdicts.length - 1)\n ];\n const artifactPath =\n options.artifactPath ?? \".pourkit/.tmp/reviewers/iteration-1.md\";\n const content = this.injections.reviewer?.invalidProtocol\n ? \"invalid reviewer artifact\"\n : [\n \"## Findings\",\n \"\",\n \"| ID | Supersedes | Severity | File/Line | Issue | Recommendation |\",\n \"|----|------------|----------|-----------|-------|----------------|\",\n \"| none | n/a | n/a | n/a | No findings. | n/a |\",\n \"\",\n `<verdict>${verdict}</verdict>`,\n ].join(\"\\n\");\n\n await writeScenarioArtifact(\n options.worktreePath ?? \"\",\n artifactPath,\n content\n );\n return makeSyntheticExecutionResult(options, true);\n }\n\n if (options.stage === \"refactor\") {\n await maybeThrowInjectedFailure(this.injections.refactor);\n this.refactorIterations.push(options.iteration ?? 1);\n if (\n this.injections.refactor?.error &&\n this.injections.refactor.failIterations?.includes(\n options.iteration ?? 1\n )\n ) {\n return makeSyntheticExecutionResult(\n options,\n false,\n [],\n this.injections.refactor.error\n );\n }\n\n return makeSyntheticExecutionResult(\n options,\n true,\n this.injections.refactor?.commits ?? [\n `synthetic-refactor-${options.iteration ?? 1}`,\n ]\n );\n }\n\n if (options.stage === \"issueFinalReview\") {\n await maybeThrowInjectedFailure(this.injections.issueFinalReview);\n this.issueFinalReviewCalls.push(options);\n if (this.injections.issueFinalReview?.error) {\n return makeSyntheticExecutionResult(\n options,\n false,\n [],\n this.injections.issueFinalReview.error\n );\n }\n\n const artifactPath =\n options.artifactPath ??\n \".pourkit/.tmp/issue-final-review/agent-output.json\";\n const verdict = this.injections.issueFinalReview?.verdict ?? \"pass\";\n const selfRetouched =\n this.injections.issueFinalReview?.selfRetouched ?? false;\n const verificationPassed =\n this.injections.issueFinalReview?.verificationPassed ?? selfRetouched;\n const content = this.injections.issueFinalReview?.invalidProtocol\n ? \"invalid issue final review artifact\"\n : JSON.stringify({\n kind: \"issue-final-review\",\n issueNumber:\n Number(options.branchName.match(/\\/(\\d+)\\//)?.[1]) || 0,\n branchName: options.branchName,\n verdict,\n summary:\n verdict === \"pass\"\n ? \"Issue Final Review passed.\"\n : \"Issue Final Review needs human review.\",\n changedPaths: this.injections.issueFinalReview?.changedPaths ?? [],\n selfRetouched,\n verification: {\n required: selfRetouched,\n passed: verificationPassed,\n commands: selfRetouched\n ? [\"live e2e synthetic verification\"]\n : [],\n summary: selfRetouched\n ? verificationPassed\n ? \"Synthetic verification passed.\"\n : \"Synthetic verification failed.\"\n : \"No self-retouch verification required.\",\n },\n needsHumanReason:\n verdict === \"needs_human_review\"\n ? (this.injections.issueFinalReview?.humanReason ??\n \"Live E2E requested human review.\")\n : null,\n });\n\n await writeScenarioArtifact(\n options.worktreePath ?? \"\",\n artifactPath,\n content\n );\n return makeSyntheticExecutionResult(options, true);\n }\n\n if (options.stage === \"prdFinalReview\") {\n this.prdFinalReviewCalls.push(options);\n const artifactPath =\n options.artifactPath ?? \".pourkit/final-review-artifact.json\";\n const prdRefMatch = options.prompt.match(/\"prdRef\":\\s*\"([A-Z]+-\\d+)\"/);\n const prdRef = prdRefMatch?.[1] ?? options.branchName;\n const content = JSON.stringify({\n prdRef,\n stage: \"prdFinalReview\",\n checkoutBase: options.checkoutBase ?? options.branchName,\n reviewBase: options.reviewBase ?? options.baseRef ?? \"\",\n verdict: \"pass_no_changes\",\n summary: \"Final review passed with no changes needed.\",\n });\n const worktreePath = options.worktreePath ?? options.repoRoot;\n\n await writeScenarioArtifact(worktreePath, artifactPath, content);\n return {\n ...makeSyntheticExecutionResult(options, true),\n worktreePath,\n };\n }\n\n if (options.stage === \"failureResolution\") {\n await maybeThrowInjectedFailure(this.injections.failureResolution);\n if (this.injections.failureResolution?.error) {\n return makeSyntheticExecutionResult(\n options,\n false,\n [],\n this.injections.failureResolution.error\n );\n }\n\n if (this.injections.failureResolution?.resolve) {\n await this.injections.failureResolution.resolve(options);\n }\n\n const artifactPath =\n options.artifactPath ?? \".pourkit/.tmp/failure-resolution/attempt-1.md\";\n const content =\n this.injections.failureResolution?.artifact ??\n [\n \"# Recovery Report\",\n \"\",\n \"```json\",\n JSON.stringify({\n recoveryDecision: \"RETRY_STAGE\",\n summary: \"Resolved deterministic live E2E conflict.\",\n changedFiles: [],\n verificationSummary: \"Not run by deterministic live harness.\",\n verificationCommands: [],\n }),\n \"```\",\n ].join(\"\\n\");\n\n await writeScenarioArtifact(\n options.worktreePath ?? \"\",\n artifactPath,\n content\n );\n return makeSyntheticExecutionResult(options, true);\n }\n\n await maybeThrowInjectedFailure(this.injections.finalizer);\n if (this.injections.finalizer?.error) {\n return makeSyntheticExecutionResult(\n options,\n false,\n [],\n this.injections.finalizer.error\n );\n }\n\n const artifactPath =\n options.artifactPath ?? \".pourkit/.tmp/finalizer/agent-output.md\";\n const title = this.injections.finalizer?.title ?? \"Generated PR Title\";\n const body = this.injections.finalizer?.body ?? \"Generated PR body content\";\n const content = this.injections.finalizer?.invalidProtocol\n ? \"invalid finalizer artifact\"\n : `## PR Title\\n\\n${title}\\n\\n## PR Body\\n\\n${body}`;\n\n await writeScenarioArtifact(\n options.worktreePath ?? \"\",\n artifactPath,\n content\n );\n return makeSyntheticExecutionResult(options, true);\n }\n}\n\nexport class ScenarioPrProvider implements PRProvider {\n waitForPrChecksCalls = 0;\n mergeCalls = 0;\n branchStatusCalls = 0;\n\n constructor(\n private readonly baseProvider: PRProvider,\n private readonly client: GitHubClient,\n private readonly injections: ScenarioPrInjections = {}\n ) {}\n\n // fallow-ignore-next-line unused-class-member\n setExpectedLabelBeforeMerge(issueNumber: number, label: string): void {\n this.injections.expectLabelBeforeMerge = { issueNumber, label };\n }\n\n createPr(options: {\n title: string;\n body: string;\n head: string;\n base: string;\n }): Promise<PullRequest> {\n return this.baseProvider.createPr(options);\n }\n\n getPr(branchName: string): Promise<PullRequest | null> {\n return this.baseProvider.getPr(branchName);\n }\n\n getPrByNumber(prNumber: number): Promise<PullRequest | null> {\n if (!this.baseProvider.getPrByNumber) {\n return Promise.resolve(null);\n }\n return this.baseProvider.getPrByNumber(prNumber);\n }\n\n getCheckStatus(prNumber: number): Promise<CheckStatus[]> {\n return this.baseProvider.getCheckStatus(prNumber);\n }\n\n async enableAutoMerge(\n _pr: PullRequest,\n _options?: EnableAutoMergeOptions\n ): Promise<void> {\n return this.baseProvider.enableAutoMerge(_pr, _options);\n }\n\n async mergePr(prNumber: number, options?: MergePrOptions): Promise<void> {\n this.mergeCalls++;\n if (\n this.injections.requireWaitForChecksBeforeMerge &&\n this.waitForPrChecksCalls === 0\n ) {\n throw new Error(\"mergePr called before waitForPrChecks\");\n }\n\n if (this.injections.expectLabelBeforeMerge) {\n await assertIssueLabels(\n this.injections.expectLabelBeforeMerge.issueNumber,\n {\n present: [this.injections.expectLabelBeforeMerge.label],\n },\n this.client\n );\n }\n\n await this.baseProvider.mergePr(prNumber, options);\n }\n\n async waitForPrChecks(\n prNumber: number,\n options?: WaitForPrChecksOptions\n ): Promise<CheckStatus[]> {\n this.waitForPrChecksCalls++;\n\n if (this.injections.waitForChecksDelayMs) {\n await new Promise((resolve) =>\n setTimeout(resolve, this.injections.waitForChecksDelayMs)\n );\n }\n\n if (this.injections.waitForChecksError) {\n throw new Error(this.injections.waitForChecksError);\n }\n\n if (this.injections.waitForChecksResult) {\n return this.injections.waitForChecksResult;\n }\n\n return this.baseProvider.waitForPrChecks(prNumber, options);\n }\n\n async getBranchStatus(branchName: string): Promise<BranchStatus> {\n this.branchStatusCalls++;\n const statuses = this.injections.branchStatuses;\n if (statuses && statuses.length > 0) {\n return statuses[\n Math.min(this.branchStatusCalls - 1, statuses.length - 1)\n ];\n }\n return this.baseProvider.getBranchStatus(branchName);\n }\n}\n\ninterface E2EStateFile extends E2EResources {\n runId: string;\n}\n\nconst E2E_STATE_DIR = path.join(\".pourkit\", \".tmp\", \"e2e-runs\");\n\nexport function stateFilePath(root: string, runId: string): string {\n return path.join(root, E2E_STATE_DIR, `${runId}.json`);\n}\n\nexport async function persistResources(\n root: string,\n runId: string,\n resources: E2EResources\n): Promise<void> {\n const filePath = stateFilePath(root, runId);\n await mkdir(path.dirname(filePath), { recursive: true });\n const state: E2EStateFile = { runId, ...resources };\n await writeFile(filePath, `${JSON.stringify(state, null, 2)}\\n`, \"utf-8\");\n}\n\nexport async function localBranchExists(branchName: string): Promise<boolean> {\n try {\n await execCapture(\"git\", [\n \"show-ref\",\n \"--verify\",\n \"--quiet\",\n `refs/heads/${branchName}`,\n ]);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function removeWorktreeForBranch(\n branchName: string,\n logger: PourkitLogger\n): Promise<boolean> {\n try {\n const result = await execCapture(\"git\", [\n \"worktree\",\n \"list\",\n \"--porcelain\",\n ]);\n const worktreePath = parseWorktreeListPorcelain(result.stdout, branchName);\n\n if (!worktreePath) {\n return true;\n }\n\n logger.step(\"cleanup\", `Removing worktree for branch: ${branchName}...`);\n await execCapture(\"git\", [\"worktree\", \"remove\", \"--force\", worktreePath]);\n return true;\n } catch (error) {\n logger.step(\n \"warn\",\n `Failed to remove worktree for branch: ${error instanceof Error ? error.message : String(error)}`\n );\n return false;\n }\n}\n\nexport async function worktreeExistsForBranch(\n branchName: string\n): Promise<boolean> {\n try {\n const result = await execCapture(\"git\", [\n \"worktree\",\n \"list\",\n \"--porcelain\",\n ]);\n const worktreePath = parseWorktreeListPorcelain(result.stdout, branchName);\n return worktreePath !== null;\n } catch {\n return false;\n }\n}\n\nexport async function worktreePathForBranch(\n branchName: string\n): Promise<string | null> {\n try {\n const result = await execCapture(\"git\", [\n \"worktree\",\n \"list\",\n \"--porcelain\",\n ]);\n return parseWorktreeListPorcelain(result.stdout, branchName);\n } catch {\n return null;\n }\n}\n\nexport async function fileExists(filePath: string): Promise<boolean> {\n try {\n await access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function deleteLocalBranch(\n branchName: string,\n logger: PourkitLogger\n): Promise<boolean> {\n if (!(await localBranchExists(branchName))) {\n return true;\n }\n\n if (!(await removeWorktreeForBranch(branchName, logger))) {\n return false;\n }\n\n try {\n logger.step(\"cleanup\", `Deleting local branch: ${branchName}...`);\n await execCapture(\"git\", [\"branch\", \"-D\", branchName]);\n return true;\n } catch (error) {\n logger.step(\n \"warn\",\n `Failed to delete local branch: ${error instanceof Error ? error.message : String(error)}`\n );\n return false;\n }\n}\n\nasync function deleteRemoteBranch(\n branchName: string,\n logger: PourkitLogger\n): Promise<boolean> {\n if (!(await remoteBranchExists(branchName))) {\n return true;\n }\n\n try {\n logger.step(\"cleanup\", `Deleting remote branch: ${branchName}...`);\n await execCapture(\"git\", [\"push\", \"origin\", \"--delete\", branchName]);\n return true;\n } catch (error) {\n logger.step(\n \"warn\",\n `Failed to delete remote branch: ${error instanceof Error ? error.message : String(error)}`\n );\n return false;\n }\n}\n\nexport async function createE2EIssue(\n runId: string,\n targetBranch: string,\n logger: PourkitLogger,\n client: GitHubClient,\n title = `E2E Test Issue ${runId}`,\n body?: string\n): Promise<{ number: number; url: string }> {\n const issueBody =\n body ??\n [\n `This is an automatically created E2E test issue for run ${runId}.`,\n \"\",\n `Target branch: ${targetBranch}`,\n \"\",\n \"This issue should be processed by the deterministic agent and cleaned up after the test completes.\",\n ].join(\"\\n\");\n\n logger.step(\"issue\", `Creating GitHub issue: \"${title}\"`);\n\n const { data } = await client.octokit.rest.issues.create({\n owner: client.owner,\n repo: client.repo,\n title,\n body: issueBody,\n labels: [\"ready-for-agent\", \"type:infra\", \"pourkit-e2e\"],\n });\n\n logger.line(`Created issue #${data.number}`);\n return { number: data.number, url: data.html_url };\n}\n\nexport async function createLiveTargetBranch(\n runId: string,\n logger: PourkitLogger,\n baseBranch = \"main\"\n): Promise<string> {\n const targetBranch = `pourkit-e2e-target/${runId}`;\n logger.step(\"git\", `Creating target branch: ${targetBranch}`);\n await execCapture(\"git\", [\n \"fetch\",\n \"origin\",\n `${baseBranch}:refs/remotes/origin/${baseBranch}`,\n ]);\n await execCapture(\"git\", [\n \"branch\",\n \"--force\",\n targetBranch,\n `origin/${baseBranch}`,\n ]);\n await execCapture(\"git\", [\n \"push\",\n \"--no-verify\",\n \"-u\",\n \"origin\",\n targetBranch,\n ]);\n return targetBranch;\n}\n\nexport async function fetchIssueLabels(\n issueNumber: number,\n client: GitHubClient\n): Promise<string[]> {\n const { data } = await client.octokit.rest.issues.get({\n owner: client.owner,\n repo: client.repo,\n issue_number: issueNumber,\n });\n\n return data.labels.map((l) => (typeof l === \"string\" ? l : (l.name ?? \"\")));\n}\n\nexport async function assertIssueLabels(\n issueNumber: number,\n options: LabelAssertionOptions,\n client: GitHubClient\n): Promise<void> {\n const labels = await fetchIssueLabels(issueNumber, client);\n const missing = (options.present ?? []).filter(\n (label) => !labels.includes(label)\n );\n const unexpected = (options.absent ?? []).filter((label) =>\n labels.includes(label)\n );\n\n if (missing.length === 0 && unexpected.length === 0) {\n return;\n }\n\n const messages: string[] = [];\n if (missing.length > 0) {\n messages.push(`missing labels: ${missing.join(\", \")}`);\n }\n if (unexpected.length > 0) {\n messages.push(`unexpected labels: ${unexpected.join(\", \")}`);\n }\n\n throw new Error(\n `Issue #${issueNumber} label assertion failed (${messages.join(\"; \")}). Current labels: ${labels.join(\", \")}`\n );\n}\n\nexport async function lookupPrByBranch(\n branchName: string,\n client: GitHubClient\n): Promise<PullRequest | null> {\n const { data } = await client.octokit.rest.pulls.list({\n owner: client.owner,\n repo: client.repo,\n head: `${client.owner}:${branchName}`,\n state: \"all\",\n per_page: 1,\n });\n\n if (data.length === 0) return null;\n\n const pr = data[0];\n return {\n number: pr.number,\n nodeId: pr.node_id,\n url: pr.html_url,\n title: pr.title,\n body: pr.body ?? \"\",\n headRefName: pr.head.ref,\n baseRefName: pr.base.ref,\n state:\n pr.state === \"closed\" ? (pr.merged_at ? \"MERGED\" : \"CLOSED\") : \"OPEN\",\n headRefOid: pr.head.sha,\n };\n}\n\nexport async function remoteBranchExists(branchName: string): Promise<boolean> {\n const result = await execCapture(\"git\", [\n \"ls-remote\",\n \"--heads\",\n \"origin\",\n branchName,\n ]);\n return result.stdout.trim().length > 0;\n}\n\nexport async function getTargetBranchStatus(\n prProvider: PRProvider,\n targetBranch: string\n): Promise<BranchStatus> {\n return prProvider.getBranchStatus(targetBranch);\n}\n\nasync function recoverStateFile(\n filePath: string,\n logger: PourkitLogger\n): Promise<boolean> {\n try {\n const raw = await readFile(filePath, \"utf-8\");\n const state = JSON.parse(raw) as E2EStateFile;\n let cleanupSucceeded = true;\n\n if (state.agentBranch) {\n cleanupSucceeded =\n (await deleteLocalBranch(state.agentBranch, logger)) &&\n cleanupSucceeded;\n cleanupSucceeded =\n (await deleteRemoteBranch(state.agentBranch, logger)) &&\n cleanupSucceeded;\n }\n\n if (state.targetBranch) {\n cleanupSucceeded =\n (await deleteLocalBranch(state.targetBranch, logger)) &&\n cleanupSucceeded;\n cleanupSucceeded =\n (await deleteRemoteBranch(state.targetBranch, logger)) &&\n cleanupSucceeded;\n }\n\n if (cleanupSucceeded) {\n await rm(filePath, { force: true });\n return true;\n }\n\n logger.step(\n \"warn\",\n `Preserving stale E2E state ${path.basename(filePath)} for cleanup retry`\n );\n return false;\n } catch (error) {\n logger.step(\n \"warn\",\n `Failed to recover stale E2E state ${path.basename(filePath)}: ${error instanceof Error ? error.message : String(error)}`\n );\n return false;\n }\n}\n\nexport async function recoverStaleRuns(\n root: string,\n logger: PourkitLogger\n): Promise<void> {\n const dir = path.join(root, E2E_STATE_DIR);\n\n try {\n const entries = await readdir(dir, { withFileTypes: true });\n for (const entry of entries) {\n if (!entry.isFile() || !entry.name.endsWith(\".json\")) continue;\n await recoverStateFile(path.join(dir, entry.name), logger);\n }\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") {\n logger.step(\n \"warn\",\n `Failed to scan stale E2E state: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n}\n\nexport async function cleanupResources(\n resources: E2EResources,\n root: string,\n runId: string,\n keep: boolean,\n logger: PourkitLogger,\n client: GitHubClient\n): Promise<void> {\n if (keep) {\n logger.line(\"--keep flag set, preserving E2E resources:\");\n if (resources.issueNumber)\n logger.line(` Issue: #${resources.issueNumber}`);\n if (resources.issueUrl) logger.line(` Issue URL: ${resources.issueUrl}`);\n if (resources.targetBranch)\n logger.line(` Target branch: ${resources.targetBranch}`);\n if (resources.agentBranch)\n logger.line(` Agent branch: ${resources.agentBranch}`);\n if (resources.prNumber)\n logger.line(` PR: #${resources.prNumber} (${resources.prUrl})`);\n return;\n }\n\n logger.line(\"Cleaning up E2E resources...\");\n let cleanupSucceeded = true;\n\n if (resources.prNumber) {\n try {\n const { data } = await client.octokit.rest.pulls.get({\n owner: client.owner,\n repo: client.repo,\n pull_number: resources.prNumber,\n });\n if (data.merged) {\n logger.step(\n \"cleanup\",\n `PR #${resources.prNumber} is merged, skipping close`\n );\n } else {\n logger.step(\"cleanup\", `Closing PR #${resources.prNumber}...`);\n await client.octokit.rest.pulls.update({\n owner: client.owner,\n repo: client.repo,\n pull_number: resources.prNumber,\n state: \"closed\",\n });\n }\n } catch (error) {\n logger.step(\n \"warn\",\n `Failed to close PR: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n\n if (resources.issueNumber) {\n try {\n logger.step(\"cleanup\", `Closing issue #${resources.issueNumber}...`);\n await client.octokit.rest.issues.update({\n owner: client.owner,\n repo: client.repo,\n issue_number: resources.issueNumber,\n state: \"closed\",\n state_reason: \"completed\",\n });\n } catch (error) {\n logger.step(\n \"warn\",\n `Failed to close issue: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n\n if (resources.agentBranch) {\n cleanupSucceeded =\n (await deleteLocalBranch(resources.agentBranch, logger)) &&\n cleanupSucceeded;\n cleanupSucceeded =\n (await deleteRemoteBranch(resources.agentBranch, logger)) &&\n cleanupSucceeded;\n }\n\n if (resources.targetBranch) {\n cleanupSucceeded =\n (await deleteLocalBranch(resources.targetBranch, logger)) &&\n cleanupSucceeded;\n cleanupSucceeded =\n (await deleteRemoteBranch(resources.targetBranch, logger)) &&\n cleanupSucceeded;\n }\n\n if (cleanupSucceeded) {\n await rm(stateFilePath(root, runId), { force: true });\n } else {\n logger.step(\"warn\", \"Preserving E2E state for retry after cleanup failure\");\n }\n\n logger.line(\"Cleanup complete.\");\n}\n\nexport interface QueueLoopCleanupIssue {\n issueNumber: number;\n agentBranch?: string;\n prNumber?: number;\n}\n\nexport interface QueueLoopCleanupResources {\n targetBranch: string;\n issues: QueueLoopCleanupIssue[];\n}\n\nexport async function cleanupQueueLoopResources(\n resources: QueueLoopCleanupResources,\n root: string,\n runId: string,\n logger: PourkitLogger,\n client: GitHubClient\n): Promise<string[]> {\n const errors: string[] = [];\n\n logger.line(\"Cleaning up Queue Loop E2E resources...\");\n\n for (const issue of resources.issues) {\n let prNumber = issue.prNumber;\n\n if (!prNumber && issue.agentBranch) {\n try {\n const pr = await lookupPrByBranch(issue.agentBranch, client);\n if (pr) {\n prNumber = pr.number;\n }\n } catch {}\n }\n\n if (prNumber) {\n try {\n const { data } = await client.octokit.rest.pulls.get({\n owner: client.owner,\n repo: client.repo,\n pull_number: prNumber,\n });\n if (!data.merged) {\n logger.step(\"cleanup\", `Closing PR #${prNumber}...`);\n await client.octokit.rest.pulls.update({\n owner: client.owner,\n repo: client.repo,\n pull_number: prNumber,\n state: \"closed\",\n });\n }\n } catch (error) {\n errors.push(`Failed to close PR #${prNumber}`);\n logger.step(\n \"warn\",\n `Failed to close PR #${prNumber}: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n }\n\n for (const issue of resources.issues) {\n try {\n logger.step(\"cleanup\", `Closing issue #${issue.issueNumber}...`);\n await client.octokit.rest.issues.update({\n owner: client.owner,\n repo: client.repo,\n issue_number: issue.issueNumber,\n state: \"closed\",\n state_reason: \"completed\",\n });\n } catch (error) {\n errors.push(`Failed to close issue #${issue.issueNumber}`);\n logger.step(\n \"warn\",\n `Failed to close issue #${issue.issueNumber}: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n\n for (const issue of resources.issues) {\n if (issue.agentBranch) {\n if (!(await deleteLocalBranch(issue.agentBranch, logger))) {\n errors.push(`Failed to delete local branch ${issue.agentBranch}`);\n }\n if (!(await deleteRemoteBranch(issue.agentBranch, logger))) {\n errors.push(`Failed to delete remote branch ${issue.agentBranch}`);\n }\n }\n }\n\n if (!(await deleteLocalBranch(resources.targetBranch, logger))) {\n errors.push(\n `Failed to delete local target branch ${resources.targetBranch}`\n );\n }\n if (!(await deleteRemoteBranch(resources.targetBranch, logger))) {\n errors.push(\n `Failed to delete remote target branch ${resources.targetBranch}`\n );\n }\n\n try {\n await rm(stateFilePath(root, runId), { force: true });\n } catch (error) {\n errors.push(\"Failed to remove state file\");\n }\n\n logger.line(\"Queue Loop cleanup complete.\");\n return errors;\n}\n\nexport async function runCleanupOnly(\n root: string,\n logger: PourkitLogger,\n client: GitHubClient\n): Promise<void> {\n logger.line(\"Running cleanup-only mode: deleting stale e2e branches...\");\n\n const result = await execCapture(\"git\", [\"ls-remote\", \"--heads\", \"origin\"]);\n const lines = result.stdout\n .split(\"\\n\")\n .filter((line) => line.trim().length > 0);\n\n const e2eBranchPattern =\n /refs\\/heads\\/(pourkit-e2e-target\\/|pourkit\\/\\d+\\/(e2e-test-issue-|test-live-e2e-))/;\n const branchesToDelete = lines\n .map((line) => {\n const parts = line.split(/\\s+/);\n return parts[1];\n })\n .filter((ref) => e2eBranchPattern.test(ref))\n .map((ref) => ref.replace(\"refs/heads/\", \"\"));\n\n let deletedCount = 0;\n let failedCount = 0;\n\n for (const branch of branchesToDelete) {\n const localOk = await deleteLocalBranch(branch, logger);\n const remoteOk = await deleteRemoteBranch(branch, logger);\n if (localOk && remoteOk) {\n deletedCount++;\n } else {\n failedCount++;\n }\n }\n\n const issueLabel = \"pourkit-e2e\";\n let closedIssueCount = 0;\n let failedIssueCount = 0;\n\n const openIssues = await client.octokit.paginate(\n client.octokit.rest.issues.listForRepo,\n {\n owner: client.owner,\n repo: client.repo,\n state: \"open\",\n labels: issueLabel,\n per_page: 100,\n }\n );\n\n const issues = openIssues.filter((issue) => !issue.pull_request);\n\n for (const issue of issues) {\n try {\n logger.step(\"cleanup\", `Closing e2e issue #${issue.number}...`);\n await client.octokit.rest.issues.update({\n owner: client.owner,\n repo: client.repo,\n issue_number: issue.number,\n state: \"closed\",\n state_reason: \"completed\",\n });\n closedIssueCount++;\n } catch (error) {\n failedIssueCount++;\n logger.step(\n \"warn\",\n `Failed to close e2e issue #${issue.number}: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n\n const stateDir = path.join(root, E2E_STATE_DIR);\n try {\n const entries = await readdir(stateDir, { withFileTypes: true });\n for (const entry of entries) {\n if (!entry.isFile() || !entry.name.endsWith(\".json\")) continue;\n const filePath = path.join(stateDir, entry.name);\n await rm(filePath, { force: true });\n logger.step(\"cleanup\", `Removed state file: ${entry.name}`);\n }\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") {\n logger.step(\n \"warn\",\n `Failed to scan state directory: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n\n logger.line(\n `Cleanup-only complete: ${deletedCount} branch(es) deleted, ${closedIssueCount} issue(s) closed, ${failedCount + failedIssueCount} failure(s)`\n );\n}\n"],"mappings":"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","names":["resolve","path","resolve","path","mkdir","readFile","readdir","rm","writeFile","existsSync","readFileSync","isAbsolute","join","valid","path","repoRoot","existsSync","readFile","readFileSync","isAbsolute","join","resolve","repoRoot","readFileSync","path","isAbsolute","resolve","repoRelative","join","existsSync","mkdirSync","readFileSync","dirname","join","Effect","existsSync","mkdirSync","readFileSync","dirname","join","Effect","existsSync","readFileSync","join","existsSync","readdirSync","readFileSync","isAbsolute","join","resolve","existsSync","mkdirSync","readFileSync","readdirSync","writeFileSync","join","existsSync","mkdirSync","readFileSync","dirname","join","readArtifact","Effect","existsSync","mkdirSync","readFileSync","writeFileSync","rmSync","path","execCapture","Effect","Layer","existsSync","readFileSync","repoRoot","join","path","repoRoot","Effect","join","existsSync","readFileSync","writeFileSync","readdirSync","Layer","repoRoot","Effect","SECTION_HEADING_PATTERN","extractSections","contentAfter","existsSync","readFileSync","isAbsolute","resolve","CONFLICT_MARKER_PATTERN","join","readFileSync","Exit","path","mkdir","repoRoot","mkdir","path","path","mkdir","resolve","readFileSync","join","repoRoot","join","readFileSync","validation","join","readFileSync","join","Effect","Effect","join","Effect","Layer","bridgeExecutionProvider","Layer","Effect","join","readFileSync","repoRoot","execFileSync","existsSync","mkdirSync","readFileSync","writeFileSync","join","spawnSync","repoRoot","join","existsSync","readFileSync","execFileSync","mkdirSync","writeFileSync","readFile","stableForMs","Effect","UnknownException","unwrapError","existsSync","readFileSync","join","join","repoRoot","existsSync","readFileSync","repoRoot","isAbsolute","join","Exit","existsSync","readFileSync","childCloseSucceeded","baseRef","join","repoRoot","existsSync","readFileSync","run","secondsRemaining","formatChecks","execCapture","path","createHash","existsSync","readFileSync","path","repoRoot","repoRoot","path","repoRoot","dirname","join","join","dirname","getVerificationCommands","path","access","mkdir","readFile","writeFile","path","mkdir","writeFile","readFile","path","path","E2E_STATE_DIR","path","stateFilePath","localBranchExists","remoteBranchExists","removeWorktreeForBranch","deleteLocalBranch","deleteRemoteBranch","getVerificationCommands","deleteLocalBranch","deleteRemoteBranch","rm","stateFilePath","path"]}
|