@agentproto/worktree 0.8.1 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/salvage.ts","../src/services/proxy-server.ts","../src/forge.ts","../src/gc.ts"],"names":["netConnect","resolve","fetch","join"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Salvage-before-discard (PLAN.md §5.2 layer 4). `worktree archive` re-earns\n * its name by snapshotting a worktree's uncommitted state before it removes\n * anything: `git diff HEAD` → `changes.patch`, plus a byte-copy of every\n * unignored untracked file, into\n * `~/.agentproto/worktree-salvage/<repoName>/<slug>-<tipSha7>-<date>/` with a\n * `MANIFEST.json`. Every file is fsynced before this returns — only once the\n * snapshot is durable does the caller proceed to force-remove.\n *\n * Deliberately forge-independent: no PR lookup here. This writer's only job\n * is \"don't lose bytes before deletion,\" not classification — `ls --status`\n * (status.ts) already owns the forge-derived `integration` axis, and gc\n * (PR-D) is where a salvage manifest and a status entry would be cross-\n * referenced, not here.\n */\n\nimport { copyFile, mkdir, open, writeFile } from \"node:fs/promises\"\nimport { homedir } from \"node:os\"\nimport { dirname, join, resolve } from \"node:path\"\nimport { execArgv } from \"./exec.js\"\nimport { computeProvenance, type ProvenanceInfo } from \"./provenance.js\"\n\nexport const SALVAGE_ROOT = (): string => resolve(homedir(), \".agentproto\", \"worktree-salvage\")\n\nexport interface SalvageManifest {\n repo: string\n /** `null` for a detached HEAD. */\n branch: string | null\n tipSha: string\n createdAt: string\n /** Relative paths of every unignored untracked file that was copied in. */\n untrackedFiles: string[]\n /** Whether `changes.patch` has any content (tracked-file changes existed). */\n hasPatch: boolean\n provenance: ProvenanceInfo\n}\n\nexport interface SalvageWorktreeInput {\n /** The main repo root — the stable spawn anchor for this worktree's git reads (see `listUntrackedFiles`'s doc). */\n repoRoot: string\n repoName: string\n worktreePath: string\n branch: string | null\n tipSha: string\n /** Identifies this worktree in the salvage directory name, e.g. its slug or branch. */\n slug: string\n sessionsPath?: string\n /** Injectable clock so tests can freeze `createdAt` / the directory name. */\n now?: () => string\n /** Override for `~/.agentproto/worktree-salvage` — tests use a temp dir. */\n salvageRoot?: string\n}\n\nexport interface SalvageResult {\n dir: string\n manifest: SalvageManifest\n}\n\n/**\n * Untracked, non-ignored files in the worktree — the same class `git\n * worktree remove` refuses without `--force`. Spawn `cwd` is `repoRoot`, not\n * `worktreePath` — a linked worktree can be removed by a concurrent `gc`\n * reap (or a racing status read) while this call is in flight, and a spawn\n * whose `cwd` no longer exists fails `ENOENT` on the COMMAND itself (a\n * Node/libuv quirk), not the directory — see `exec.ts`'s `execGit`, which\n * anchors the same way.\n */\nasync function listUntrackedFiles(repoRoot: string, worktreePath: string): Promise<string[]> {\n const res = await execArgv(\"git\", [\"-C\", worktreePath, \"ls-files\", \"--others\", \"--exclude-standard\"], repoRoot)\n if (res.exitCode !== 0) {\n throw new Error(`git ls-files --others failed in ${worktreePath} (exit ${res.exitCode}): ${res.stderr.trim()}`)\n }\n return res.stdout.split(\"\\n\").filter(Boolean)\n}\n\n/** `git diff HEAD` — staged + unstaged changes to tracked files, uniformly.\n * Empty string on a clean tree. Spawn `cwd` is `repoRoot`, not\n * `worktreePath` — see `listUntrackedFiles`'s doc. */\nasync function diffHead(repoRoot: string, worktreePath: string): Promise<string> {\n const res = await execArgv(\"git\", [\"-C\", worktreePath, \"diff\", \"HEAD\"], repoRoot)\n if (res.exitCode !== 0) {\n throw new Error(`git diff HEAD failed in ${worktreePath} (exit ${res.exitCode}): ${res.stderr.trim()}`)\n }\n return res.stdout\n}\n\n/** Sanitize a path segment for use in the salvage directory name (no slashes, no leading dot-dot). */\nfunction sanitizeSegment(value: string): string {\n return value.replace(/[^a-zA-Z0-9._-]+/g, \"-\").replace(/^-+/, \"\") || \"worktree\"\n}\n\n/** fsync one file by path — the durability guarantee: only after this resolves is the byte \"saved\". */\nasync function fsyncFile(path: string): Promise<void> {\n const handle = await open(path, \"r+\")\n try {\n await handle.sync()\n } finally {\n await handle.close()\n }\n}\n\nasync function writeFileSynced(path: string, content: string): Promise<void> {\n await mkdir(dirname(path), { recursive: true })\n await writeFile(path, content, \"utf8\")\n await fsyncFile(path)\n}\n\n/**\n * Snapshot `worktreePath`'s uncommitted state into a fresh salvage\n * directory. Safe to call on a clean tree (writes an empty patch, no\n * untracked files, still a manifest) — every path this function returns is\n * fsynced before it resolves.\n */\nexport async function salvageWorktree(input: SalvageWorktreeInput): Promise<SalvageResult> {\n const now = input.now ?? (() => new Date().toISOString())\n const createdAt = now()\n const tipShort = input.tipSha.slice(0, 7)\n const dateStamp = createdAt.slice(0, 10)\n const dirName = `${sanitizeSegment(input.slug)}-${tipShort}-${dateStamp}`\n const dir = resolve(input.salvageRoot ?? SALVAGE_ROOT(), sanitizeSegment(input.repoName), dirName)\n await mkdir(dir, { recursive: true })\n\n const [patch, untrackedFiles, provenance] = await Promise.all([\n diffHead(input.repoRoot, input.worktreePath),\n listUntrackedFiles(input.repoRoot, input.worktreePath),\n computeProvenance(input.repoRoot, input.worktreePath, { sessionsPath: input.sessionsPath }),\n ])\n\n await writeFileSynced(join(dir, \"changes.patch\"), patch)\n\n for (const relPath of untrackedFiles) {\n const dest = join(dir, \"untracked\", relPath)\n await mkdir(dirname(dest), { recursive: true })\n await copyFile(join(input.worktreePath, relPath), dest)\n await fsyncFile(dest)\n }\n\n const manifest: SalvageManifest = {\n repo: input.repoName,\n branch: input.branch,\n tipSha: input.tipSha,\n createdAt,\n untrackedFiles,\n hasPatch: patch.length > 0,\n provenance,\n }\n await writeFileSynced(join(dir, \"MANIFEST.json\"), JSON.stringify(manifest, null, 2) + \"\\n\")\n\n return { dir, manifest }\n}\n","import http from \"node:http\"\nimport { connect as netConnect, type Socket } from \"node:net\"\nimport type { ProxyTable } from \"./proxy-table.js\"\n\n/**\n * A small HTTP reverse proxy over a {@link ProxyTable}. Routes\n * `http://<script>--<branch>--<repo>.localhost:<proxy-port>` to the matched\n * service's local port. Supports WebSocket (and any) `Upgrade` passthrough by\n * splicing raw sockets. Targets are always `127.0.0.1` — services bind\n * locally, the proxy is the only public-ish surface.\n */\n\nconst TARGET_HOST = \"127.0.0.1\"\n\nfunction notFound(table: ProxyTable, host: string | undefined): string {\n const known = table.entries().map(([h]) => h)\n return (\n `worktree-proxy: no service for host \"${host ?? \"(none)\"}\"\\n` +\n (known.length ? `known hosts:\\n${known.map((h) => ` ${h}`).join(\"\\n\")}\\n` : \"no services registered\\n\")\n )\n}\n\n/** Build (but don't start) the proxy HTTP server backed by `table`. */\nexport function createProxyServer(table: ProxyTable): http.Server {\n const server = http.createServer((req, res) => {\n const targetPort = table.lookup(req.headers.host)\n if (targetPort === undefined) {\n res.writeHead(502, { \"content-type\": \"text/plain\" })\n res.end(notFound(table, req.headers.host))\n return\n }\n\n const proxyReq = http.request(\n {\n host: TARGET_HOST,\n port: targetPort,\n method: req.method,\n path: req.url,\n headers: req.headers,\n },\n (proxyRes) => {\n res.writeHead(proxyRes.statusCode ?? 502, proxyRes.headers)\n proxyRes.pipe(res)\n },\n )\n proxyReq.on(\"error\", (err) => {\n if (!res.headersSent) res.writeHead(502, { \"content-type\": \"text/plain\" })\n res.end(`worktree-proxy: upstream error: ${err.message}\\n`)\n })\n req.pipe(proxyReq)\n })\n\n // WebSocket / generic Upgrade passthrough: splice the client socket to a\n // fresh TCP connection to the target, replaying the original request line\n // and headers so the upstream completes its own handshake.\n server.on(\"upgrade\", (req, clientSocket: Socket, head: Buffer) => {\n const targetPort = table.lookup(req.headers.host)\n if (targetPort === undefined) {\n clientSocket.end(\"HTTP/1.1 502 Bad Gateway\\r\\n\\r\\n\")\n return\n }\n\n const upstream = netConnect(targetPort, TARGET_HOST, () => {\n const headerLines = [`${req.method} ${req.url} HTTP/1.1`]\n for (let i = 0; i < req.rawHeaders.length; i += 2) {\n headerLines.push(`${req.rawHeaders[i]}: ${req.rawHeaders[i + 1]}`)\n }\n upstream.write(headerLines.join(\"\\r\\n\") + \"\\r\\n\\r\\n\")\n if (head && head.length) upstream.write(head)\n upstream.pipe(clientSocket)\n clientSocket.pipe(upstream)\n })\n\n const teardown = (): void => {\n clientSocket.destroy()\n upstream.destroy()\n }\n upstream.on(\"error\", teardown)\n clientSocket.on(\"error\", teardown)\n upstream.on(\"close\", () => clientSocket.destroy())\n clientSocket.on(\"close\", () => upstream.destroy())\n })\n\n return server\n}\n\nexport interface RunningProxy {\n /** The port the proxy is listening on. */\n port: number\n /** The underlying server. */\n server: http.Server\n /** Stop the proxy. */\n close(): Promise<void>\n}\n\n/** Start the proxy server on `port` (0 → OS-assigned). Resolves once listening. */\nexport function startProxy(table: ProxyTable, port = 0): Promise<RunningProxy> {\n const server = createProxyServer(table)\n // Track every accepted socket so shutdown can force-drop them. An upgraded\n // (WebSocket) connection is detached from the server's own tracking, so\n // `server.close()` alone would hang on it — we destroy them explicitly.\n const sockets = new Set<Socket>()\n server.on(\"connection\", (socket: Socket) => {\n sockets.add(socket)\n socket.once(\"close\", () => sockets.delete(socket))\n })\n return new Promise((resolve, reject) => {\n server.once(\"error\", reject)\n server.listen(port, () => {\n const address = server.address()\n const boundPort = address && typeof address === \"object\" ? address.port : port\n resolve({\n port: boundPort,\n server,\n close: () =>\n new Promise<void>((res) => {\n for (const socket of sockets) socket.destroy()\n sockets.clear()\n server.close(() => res())\n }),\n })\n })\n })\n}\n","/**\n * `ForgeClient` — the only network-facing surface the reconciliation rule\n * (`status.ts`) depends on. Kept as an interface (not a concrete `gh` call)\n * so:\n * 1. `status.ts` stays testable with a fake — the fixture-repo tests never\n * shell out to a real forge or touch the network.\n * 2. The shape is forge-portable by construction (PLAN.md §7.1): GitLab has\n * the same two facts — \"PRs/MRs whose head is this branch\" and \"PRs/MRs\n * that contain this commit\" — under different verbs\n * (`refs/merge-requests/<n>/head`, `GET /merge_requests?…`). Only\n * GitHub ships today; a `GitlabForgeClient` is a second implementation\n * of this same interface, not a redesign.\n *\n * Two implementations ship: `GhCliForgeClient` (shells out to the `gh` CLI,\n * inheriting the caller's own `gh auth` session — zero config) and\n * `RestForgeClient` (plain `fetch` against the GitHub REST API using\n * `GITHUB_TOKEN` — no new npm dependency). `createForgeClient` picks\n * whichever is usable; when neither is, callers get a client that always\n * reports itself unreachable, which the reconciliation rule already knows\n * how to fall back from (PLAN.md §1.3 step 5: memo, else `unknown(offline)`,\n * never a guess).\n */\n\nimport { z } from \"zod\"\nimport { execArgv } from \"./exec.js\"\n\n/** A pull/merge request as the reconciliation rule needs to see it. */\nexport interface ForgePullRequestRef {\n number: number\n state: \"open\" | \"closed\"\n merged: boolean\n mergedAt: string | null\n headRefName: string\n headRefOid: string\n}\n\n/**\n * Thrown by a `ForgeClient` method when the forge could not be reached or\n * queried at all (network failure, missing/unauthenticated CLI, non-2xx HTTP\n * response). Never thrown for a legitimate empty result (a branch/commit\n * with no PRs is a valid, resolvable answer — `[]`, not an error). Callers\n * treat this as PLAN.md §1.3 step 5: \"never guess.\"\n */\nexport class ForgeUnavailableError extends Error {\n constructor(message: string, options?: { cause?: unknown }) {\n super(message, options)\n this.name = \"ForgeUnavailableError\"\n }\n}\n\nexport interface ForgeClient {\n /** PRs/MRs (any state) whose head branch is exactly `branch`. */\n pullRequestsForBranch(branch: string): Promise<ForgePullRequestRef[]>\n /**\n * PRs/MRs associated with a specific commit SHA — the rename/retarget-proof\n * signal (PLAN.md §1.3 step 2b): finds the PR even if the branch was\n * renamed or deleted before merge.\n */\n pullRequestsForCommit(sha: string): Promise<ForgePullRequestRef[]>\n /**\n * Ensure `oid` (a PR's `headRefOid`) is present in the local object\n * database, fetching `refs/pull/<number>/head` if it isn't. Always\n * fetchable even after the head branch was deleted on the remote\n * (PLAN.md §1.3 step 2, verified for #273/#312/#325/#271).\n */\n ensurePullHeadFetched(prNumber: number, oid: string): Promise<void>\n}\n\n/** A client that always reports itself unreachable — the \"no gh, no token\" case. */\nexport class UnreachableForgeClient implements ForgeClient {\n constructor(private readonly reason: string) {}\n async pullRequestsForBranch(): Promise<ForgePullRequestRef[]> {\n throw new ForgeUnavailableError(this.reason)\n }\n async pullRequestsForCommit(): Promise<ForgePullRequestRef[]> {\n throw new ForgeUnavailableError(this.reason)\n }\n async ensurePullHeadFetched(): Promise<void> {\n throw new ForgeUnavailableError(this.reason)\n }\n}\n\n// ── gh CLI implementation ───────────────────────────────────────────────\n\nconst ghPrListItemSchema = z.object({\n number: z.number(),\n state: z.string(),\n headRefName: z.string(),\n headRefOid: z.string(),\n mergedAt: z.string().nullable(),\n})\ntype GhPrListItem = z.infer<typeof ghPrListItemSchema>\nconst ghPrListSchema = z.array(ghPrListItemSchema)\n\nfunction normalizeGhPrListItem(item: GhPrListItem): ForgePullRequestRef {\n const state = item.state.toUpperCase()\n return {\n number: item.number,\n state: state === \"OPEN\" ? \"open\" : \"closed\",\n merged: state === \"MERGED\" || item.mergedAt !== null,\n mergedAt: item.mergedAt,\n headRefName: item.headRefName,\n headRefOid: item.headRefOid,\n }\n}\n\nconst ghApiCommitPullSchema = z.object({\n number: z.number(),\n state: z.string(),\n merged_at: z.string().nullable(),\n head: z.object({ ref: z.string(), sha: z.string() }),\n})\ntype GhApiCommitPull = z.infer<typeof ghApiCommitPullSchema>\nconst ghApiCommitPullListSchema = z.array(ghApiCommitPullSchema)\n\nfunction normalizeGhApiCommitPull(item: GhApiCommitPull): ForgePullRequestRef {\n return {\n number: item.number,\n state: item.state === \"open\" ? \"open\" : \"closed\",\n merged: item.merged_at !== null,\n mergedAt: item.merged_at,\n headRefName: item.head.ref,\n headRefOid: item.head.sha,\n }\n}\n\n/**\n * GitHub's REST API answers \"commit unknown to this repo\" (e.g. a local\n * commit that was never pushed) with HTTP 422 on `commits/:sha/pulls` —\n * empirically verified against a real unpushed worktree commit, not the 404\n * the endpoint's own docs imply. `gh api` surfaces the status in its stderr\n * as `(HTTP nnn)`. Both 404 and 422 here mean the same legitimate thing:\n * zero associated PRs, not \"the forge is unreachable\" — never guess step 5\n * on a genuinely empty, well-formed answer.\n */\nfunction isCommitNotFoundError(output: string): boolean {\n return /\\(HTTP (404|422)\\)/.test(output)\n}\n\n/** Runs `gh` in `repoRoot` so it auto-detects owner/repo from the `origin` remote there. */\nexport class GhCliForgeClient implements ForgeClient {\n constructor(private readonly repoRoot: string) {}\n\n private async runRaw(args: readonly string[]): Promise<{ exitCode: number; stdout: string; stderr: string }> {\n try {\n return await execArgv(\"gh\", args, this.repoRoot)\n } catch (err) {\n throw new ForgeUnavailableError(\n `gh ${args.join(\" \")} could not be run: ${err instanceof Error ? err.message : String(err)}`,\n { cause: err },\n )\n }\n }\n\n private async run(args: readonly string[]): Promise<string> {\n const result = await this.runRaw(args)\n if (result.exitCode !== 0) {\n throw new ForgeUnavailableError(\n `gh ${args.join(\" \")} failed (exit ${result.exitCode}): ${result.stderr.trim() || result.stdout.trim()}`,\n )\n }\n return result.stdout\n }\n\n private parseOutput<T>(stdout: string, schema: z.ZodType<T[]>, args: readonly string[]): T[] {\n let parsed: unknown\n try {\n parsed = JSON.parse(stdout)\n } catch (err) {\n throw new ForgeUnavailableError(\n `gh ${args.join(\" \")} produced non-JSON output: ${err instanceof Error ? err.message : String(err)}`,\n )\n }\n const result = schema.safeParse(parsed)\n if (!result.success) {\n throw new ForgeUnavailableError(`gh ${args.join(\" \")} output did not match the expected shape`)\n }\n return result.data\n }\n\n async pullRequestsForBranch(branch: string): Promise<ForgePullRequestRef[]> {\n const args = [\n \"pr\",\n \"list\",\n \"--head\",\n branch,\n \"--state\",\n \"all\",\n \"--json\",\n \"number,state,headRefName,headRefOid,mergedAt\",\n ]\n const stdout = await this.run(args)\n return this.parseOutput(stdout, ghPrListSchema, args).map(normalizeGhPrListItem)\n }\n\n async pullRequestsForCommit(sha: string): Promise<ForgePullRequestRef[]> {\n const args = [\"api\", `repos/{owner}/{repo}/commits/${sha}/pulls`]\n const result = await this.runRaw(args)\n if (result.exitCode !== 0) {\n if (isCommitNotFoundError(result.stderr) || isCommitNotFoundError(result.stdout)) return []\n throw new ForgeUnavailableError(\n `gh ${args.join(\" \")} failed (exit ${result.exitCode}): ${result.stderr.trim() || result.stdout.trim()}`,\n )\n }\n return this.parseOutput(result.stdout, ghApiCommitPullListSchema, args).map(normalizeGhApiCommitPull)\n }\n\n async ensurePullHeadFetched(prNumber: number, oid: string): Promise<void> {\n const check = await execArgv(\"git\", [\"-C\", this.repoRoot, \"cat-file\", \"-e\", `${oid}^{commit}`], this.repoRoot)\n if (check.exitCode === 0) return\n const fetch = await execArgv(\n \"git\",\n [\"-C\", this.repoRoot, \"fetch\", \"origin\", `refs/pull/${prNumber}/head`],\n this.repoRoot,\n )\n if (fetch.exitCode !== 0) {\n throw new ForgeUnavailableError(\n `git fetch origin refs/pull/${prNumber}/head failed: ${fetch.stderr.trim() || fetch.stdout.trim()}`,\n )\n }\n }\n}\n\n// ── GITHUB_TOKEN REST fallback (no new npm dependency — global fetch) ───\n\nconst restPullRequestSchema = z.object({\n number: z.number(),\n state: z.string(),\n merged_at: z.string().nullable(),\n head: z.object({ ref: z.string(), sha: z.string() }),\n})\ntype RestPullRequest = z.infer<typeof restPullRequestSchema>\nconst restPullRequestListSchema = z.array(restPullRequestSchema)\n\nfunction normalizeRestPr(item: RestPullRequest): ForgePullRequestRef {\n return {\n number: item.number,\n state: item.state === \"open\" ? \"open\" : \"closed\",\n merged: item.merged_at !== null,\n mergedAt: item.merged_at,\n headRefName: item.head.ref,\n headRefOid: item.head.sha,\n }\n}\n\n/** Parse `owner/repo` out of a `git remote get-url origin` value (ssh or https form). */\nexport function parseGithubOwnerRepo(remoteUrl: string): { owner: string; repo: string } | null {\n const ssh = remoteUrl.match(/^git@github\\.com:([^/]+)\\/(.+?)(\\.git)?$/)\n if (ssh?.[1] && ssh[2]) return { owner: ssh[1], repo: ssh[2] }\n const https = remoteUrl.match(/^https:\\/\\/github\\.com\\/([^/]+)\\/(.+?)(\\.git)?\\/?$/)\n if (https?.[1] && https[2]) return { owner: https[1], repo: https[2] }\n return null\n}\n\nexport class RestForgeClient implements ForgeClient {\n constructor(\n private readonly owner: string,\n private readonly repo: string,\n private readonly repoRoot: string,\n private readonly token: string,\n private readonly fetchFn: typeof fetch = fetch,\n ) {}\n\n private headers(): Record<string, string> {\n return {\n Authorization: `Bearer ${this.token}`,\n Accept: \"application/vnd.github+json\",\n \"X-GitHub-Api-Version\": \"2022-11-28\",\n \"User-Agent\": \"agentproto-worktree-status\",\n }\n }\n\n private async get(path: string): Promise<Response> {\n try {\n return await this.fetchFn(`https://api.github.com${path}`, { headers: this.headers() })\n } catch (err) {\n throw new ForgeUnavailableError(\n `GitHub REST request to ${path} failed: ${err instanceof Error ? err.message : String(err)}`,\n { cause: err },\n )\n }\n }\n\n private async pullRequestList(res: Response): Promise<ForgePullRequestRef[]> {\n const body: unknown = await res.json()\n const result = restPullRequestListSchema.safeParse(body)\n if (!result.success) {\n throw new ForgeUnavailableError(`GitHub REST response did not match the expected PR list shape`)\n }\n return result.data.map(normalizeRestPr)\n }\n\n async pullRequestsForBranch(branch: string): Promise<ForgePullRequestRef[]> {\n const res = await this.get(\n `/repos/${this.owner}/${this.repo}/pulls?head=${this.owner}:${encodeURIComponent(branch)}&state=all&per_page=100`,\n )\n if (!res.ok) {\n throw new ForgeUnavailableError(`GitHub REST pulls?head= failed: ${res.status} ${res.statusText}`)\n }\n return this.pullRequestList(res)\n }\n\n async pullRequestsForCommit(sha: string): Promise<ForgePullRequestRef[]> {\n const res = await this.get(`/repos/${this.owner}/${this.repo}/commits/${sha}/pulls?per_page=100`)\n // 404 is what the endpoint's docs imply for an unknown commit; 422 is what\n // it empirically returns for one that was never pushed (verified live).\n // Both mean the same legitimate thing: zero associated PRs.\n if (res.status === 404 || res.status === 422) return []\n if (!res.ok) {\n throw new ForgeUnavailableError(`GitHub REST commits/:sha/pulls failed: ${res.status} ${res.statusText}`)\n }\n return this.pullRequestList(res)\n }\n\n async ensurePullHeadFetched(prNumber: number, oid: string): Promise<void> {\n const check = await execArgv(\"git\", [\"-C\", this.repoRoot, \"cat-file\", \"-e\", `${oid}^{commit}`], this.repoRoot)\n if (check.exitCode === 0) return\n const fetch2 = await execArgv(\n \"git\",\n [\"-C\", this.repoRoot, \"fetch\", \"origin\", `refs/pull/${prNumber}/head`],\n this.repoRoot,\n )\n if (fetch2.exitCode !== 0) {\n throw new ForgeUnavailableError(\n `git fetch origin refs/pull/${prNumber}/head failed: ${fetch2.stderr.trim() || fetch2.stdout.trim()}`,\n )\n }\n }\n}\n\n/**\n * Cheap \"is `gh` on PATH and authenticated\" probe — avoids a slow failure per\n * branch.\n *\n * Deliberately `gh auth token`, not `gh auth status`: `status` audits **every**\n * configured account and exits non-zero when *any* of them is broken, even\n * while the active credential works fine for real calls. A single stale keyring\n * entry for a second account is enough to make it exit 1 — and because a false\n * negative here lands on `UnreachableForgeClient`, every worktree's integration\n * silently degrades to `unknown(offline)` and `worktree gc` holds everything it\n * would otherwise reclaim. Observed exactly that: `gh auth status` exiting 1 on\n * a stale account while `gh pr list` and `gh api rate_limit` both answered\n * normally.\n *\n * `gh auth token` answers the question this probe actually asks — \"is gh on\n * PATH with a usable credential\" — and does it locally, with no network call.\n * It cannot prove the token is still valid server-side, but neither could\n * `status`: a token revoked upstream fails at call time either way, which is\n * exactly what `ForgeUnavailableError` and the memo/`unknown(offline)` fallback\n * already handle.\n */\nasync function ghIsUsable(repoRoot: string): Promise<boolean> {\n try {\n const res = await execArgv(\"gh\", [\"auth\", \"token\"], repoRoot)\n return res.exitCode === 0 && res.stdout.trim() !== \"\"\n } catch {\n return false\n }\n}\n\n/**\n * Pick the best available `ForgeClient` for `repoRoot`: `gh` CLI first (zero\n * config, inherits the caller's own auth), else `GITHUB_TOKEN` REST, else a\n * client that always reports unreachable — the reconciliation rule already\n * knows how to fall back from that (memo, else `unknown(offline)`).\n */\nexport async function createForgeClient(repoRoot: string): Promise<ForgeClient> {\n if (await ghIsUsable(repoRoot)) return new GhCliForgeClient(repoRoot)\n\n const token = process.env.GITHUB_TOKEN\n if (token) {\n const remote = await execArgv(\"git\", [\"-C\", repoRoot, \"remote\", \"get-url\", \"origin\"], repoRoot)\n const parsed = remote.exitCode === 0 ? parseGithubOwnerRepo(remote.stdout.trim()) : null\n if (parsed) return new RestForgeClient(parsed.owner, parsed.repo, repoRoot, token)\n }\n\n return new UnreachableForgeClient(\n \"no usable forge client: `gh` is not installed/authenticated and GITHUB_TOKEN is not set (or origin isn't a GitHub remote)\",\n )\n}\n","/**\n * `gc` (PLAN.md §5, PR-D): plan → apply → salvage over the status engine's\n * classification (`status.ts`, PR-A). This module owns no new git knowledge\n * — it reuses `listGitWorktrees` / `computeWorktreeStatus` / `classify` for\n * every fact and `salvageWorktree` / `worktree.cleanup` (PR-C) for every\n * mutation. Its only original logic is sequencing the four safety layers\n * (PLAN.md §5.2):\n *\n * 1. `planGc` is pure read: it classifies every worktree and returns a\n * plan. Nothing is mutated by calling it — the CLI's dry-run default\n * *is* just \"call planGc, print it, stop.\"\n * 2. `applyGc` re-derives each worktree's class from scratch immediately\n * before touching it (a fresh `listGitWorktrees` + `computeWorktreeStatus`,\n * not a reuse of the plan's stale snapshot) and refuses to act if the\n * class changed since the plan was made.\n * 3. The actual removal is `worktree.cleanup` with NO discard flags for a\n * reclaim-class entry — git's own non-`--force` refusal is the backstop\n * this module leans on, never a force flag \"just in case.\"\n * 4. A salvage-class entry is only ever touched via `salvageWorktree`\n * followed by `worktree.cleanup` with both discard flags — snapshot\n * first, removal only after the snapshot is durable (mirrors `worktree\n * archive`'s CLI verb, PR-C).\n *\n * The main worktree (`repoRoot` itself) is never part of the plan: `git\n * worktree list`'s first entry is always the main checkout, and a repo\n * sitting on an up-to-date default branch is trivially `fresh ∧ clean` —\n * exactly what `reclaim` looks for. Git itself refuses to remove\n * the main working tree (\"is a main working tree\", verified empirically),\n * but this module doesn't lean on that as the only guard: the main worktree\n * is filtered out before classification even runs, so it can never appear\n * in a plan, let alone be attempted.\n *\n * One reclassification on top of `classify`'s three classes:\n * `resolveGcClass` promotes a clean, `unpushed` worktree from `hold` to\n * `reclaim` when every commit ahead of the default branch is a mechanical\n * dependency bump (subject AND cumulative diff both checked — see that\n * function's doc). It's applied identically at plan time and re-verified at\n * apply time (layer 2), so a worktree that grew a real commit in between is\n * still caught.\n */\n\nimport { basename, isAbsolute, join, relative, resolve, sep } from \"node:path\"\nimport { readFile, readdir, realpath, rm, stat } from \"node:fs/promises\"\nimport { runTool } from \"@agentproto/driver\"\nimport { execArgv, execGit } from \"./exec.js\"\nimport { cleanupWorktreeTool } from \"./tools/index.js\"\nimport { worktreeProvider } from \"./provider/index.js\"\nimport { salvageWorktree } from \"./salvage.js\"\nimport type { ForgeClient } from \"./forge.js\"\nimport {\n classify,\n listGitWorktrees,\n computeWorktreeStatus,\n type GitWorktreeRef,\n type IntegrationState,\n type LivenessState,\n type TreeState,\n type VerdictMemoStore,\n} from \"./status.js\"\n\nconst candidates = [worktreeProvider]\n\n// ── classification (PLAN.md §5.1) ───────────────────────────────────────\n\nexport type GcClass = \"reclaim\" | \"salvage\" | \"hold\"\n\nexport interface ClassifyForGcOptions {\n /**\n * A clean, idle/daemon-unreachable DETACHED worktree moves from `hold` to\n * `reclaim` (PLAN.md §5.1). This is the only reclassification power any\n * flag has: every other hold reason — partial, open, unknown(offline),\n * gone-unexplained, diverged — is untouched by any flag, ever. Default\n * false.\n */\n includeDetached?: boolean\n /** Threaded straight through to `classify`'s `RECENT_WRITE_HOLD_WINDOW_MS` guard. Defaults to `Date.now()`. */\n nowMs?: number\n}\n\n/**\n * gc's own classifier, layered on top of `classify` (status.ts) rather than\n * reimplementing it — reuse first (AGENTS.md, PLAN.md §0.6). The one thing\n * `classify` cannot know is `--include-detached`, a gc-specific flag; that\n * override lives here, not in the read-only status engine `ls --status`\n * also depends on.\n */\nexport function classifyForGc(\n tree: TreeState,\n integration: IntegrationState,\n liveness: LivenessState,\n options: ClassifyForGcOptions = {},\n): GcClass {\n if (options.includeDetached && integration.state === \"detached\") {\n const idleOrUnreachable = liveness.state === \"idle\" || liveness.state === \"daemon-unreachable\"\n if (tree.state === \"clean\" && idleOrUnreachable) return \"reclaim\"\n }\n return classify(tree, integration, liveness, options.nowMs).class\n}\n\n// ── dep-bump reclaim exemption ──────────────────────────────────────────\n//\n// A worktree whose only unpushed commits are a mechanical dependency bump\n// (`chore(deps): weekly minor/patch bump`, re-run every week by every\n// session that happens to pick it up) is not \"unpushed work to protect\" —\n// it reproduces by re-running the routine, and 25 of these piling up as\n// permanent `hold`s is exactly what emptied a 102GB external SSD of gc\n// coverage. This is deliberately narrow and additive: it only ever promotes\n// a worktree that `classifyForGc` already put in `hold` for the single\n// reason `integration.state === \"unpushed\"` with a clean tree — every other\n// hold reason (partial, open, diverged, gone-unexplained, unknown(offline),\n// a dirty tree, `unpushed` while forge-unreachable — which can't happen, see\n// `reconcileIntegration`) is completely untouched by this and still holds.\n\n/**\n * The reclaim reasons this module can attach. `dep-bump` promotes a `hold`\n * to `reclaim` (see above). `orphan` and `prunable` are both different in\n * kind — neither ever starts from a `hold` verdict, because neither was\n * classified via `classify`'s three axes in the first place:\n * - `orphan`: a directory physically present under the repo's worktree\n * pool that `git worktree list` no longer knows about at all (see the\n * \"orphan reclaim\" section below).\n * - `prunable`: the mirror image — `git worktree list` still has a\n * registration, but git itself already reports it `prunable` because\n * the working directory is gone. Distinct from `orphan` on purpose: an\n * orphan's directory is still there to lose (it just failed removal),\n * so `reclaimOrphan` does `rm -rf`; a prunable entry's directory is\n * already gone, so there's nothing to inspect and nothing to `rm` — the\n * only irreversible thing history nearly did to it (deleting the branch)\n * must not happen either. See \"prunable reclaim\" below.\n */\nexport type GcReclaimReason = \"dep-bump\" | \"orphan\" | \"prunable\"\n\n// ── live-session-cwd protection ─────────────────────────────────────────\n//\n// `classify`'s liveness axis (`computeLiveness`, status.ts) already holds a\n// worktree that has a live session's cwd inside it — but only when that\n// session shows up in the sessions snapshot `computeWorktreeStatus` was\n// given. A caller with a stronger, more direct source of truth (the\n// daemon's own in-memory session registry, read at the exact instant gc\n// runs, rather than a possibly-stale/incomplete on-disk snapshot) can name\n// those cwds explicitly via `protectedPaths` — a belt-and-suspenders check\n// that wins unconditionally, independent of `classify`'s snapshot-based\n// verdict and computed BEFORE it (so a protected worktree never pays the\n// dep-bump exemption's extra git spawns either).\n\n/** The hold reasons this module can attach, distinct from `classify`'s snapshot-based holds. */\nexport type GcHoldReason = \"live-session-cwd\"\n\n/**\n * `true` iff `worktreePath` itself, or a subdirectory of it, is named by\n * `protectedPaths` — the same exact-or-subdirectory containment convention\n * as `sessionInWorktree` (provenance.ts), bounded by `sep` so a sibling like\n * `/a/bc` is never confused with `/a/b`. Plain string comparison, matching\n * `sessionInWorktree`'s own convention, rather than resolving symlinks —\n * callers that need realpath-stability should normalize before passing\n * `protectedPaths` in.\n */\nfunction isProtectedPath(worktreePath: string, protectedPaths: readonly string[] | undefined): boolean {\n if (!protectedPaths || protectedPaths.length === 0) return false\n return protectedPaths.some((p) => p === worktreePath || p.startsWith(worktreePath + sep))\n}\n\n/**\n * Mechanical dep-bump commit subjects: `chore(deps)` / `fix(deps)`, with or\n * without a scope (`chore(deps-dev)`, `fix(deps-optional)`, …). A commit\n * message is cheap to type and easy to lie in — this regex alone NEVER\n * licenses anything; `isMechanicalDepBumpRange` below only trusts it in\n * conjunction with the actual cumulative diff.\n */\nconst DEP_BUMP_SUBJECT_RE = /^(?:chore|fix)\\(deps[\\w-]*\\):\\s/\n\nfunction isDepBumpSubject(subject: string): boolean {\n return DEP_BUMP_SUBJECT_RE.test(subject)\n}\n\n/** The only paths a mechanical dep bump is allowed to touch, matched by basename so a nested package's `package.json` counts too. */\nconst DEP_BUMP_ALLOWED_BASENAMES = new Set([\"pnpm-lock.yaml\", \"package-lock.json\", \"yarn.lock\", \"package.json\"])\n\nfunction isDepBumpAllowedPath(path: string): boolean {\n return DEP_BUMP_ALLOWED_BASENAMES.has(basename(path))\n}\n\n/**\n * Layer 3+4 of the exemption: EVERY commit ahead of `baseRef` must have a\n * dep-bump subject (`git log --format=%s`, two-dot range — exactly the\n * commits `aheadBy` counts, PLAN-comment on `readUpstreamTrack`), AND the\n * cumulative diff of that whole range (`git diff`, three-dot/merge-base\n * range, so it isolates the branch's own changes from anything `baseRef`\n * did independently in the meantime) must touch nothing but lockfiles and\n * `package.json`. Both checks run unconditionally together — a subject that\n * lies is cheap, a diff cannot lie, so the diff is the one that actually\n * gates. Two extra git spawns, only ever paid for a worktree that would\n * otherwise be `hold` for exactly `clean ∧ unpushed` — every other class\n * pays nothing.\n */\nexport async function isMechanicalDepBumpRange(repoRoot: string, baseRef: string, tipSha: string): Promise<boolean> {\n const [subjectsRes, diffRes] = await Promise.all([\n execArgv(\"git\", [\"-C\", repoRoot, \"log\", \"--format=%s\", `${baseRef}..${tipSha}`], repoRoot),\n execArgv(\"git\", [\"-C\", repoRoot, \"diff\", \"--name-only\", `${baseRef}...${tipSha}`], repoRoot),\n ])\n if (subjectsRes.exitCode !== 0 || diffRes.exitCode !== 0) return false\n\n const subjects = subjectsRes.stdout.split(\"\\n\").filter((line) => line.length > 0)\n if (subjects.length === 0) return false\n if (!subjects.every(isDepBumpSubject)) return false\n\n const files = diffRes.stdout.split(\"\\n\").filter((line) => line.length > 0)\n if (files.length === 0) return false\n return files.every(isDepBumpAllowedPath)\n}\n\nexport interface ResolveGcClassOptions extends ClassifyForGcOptions {\n repoRoot: string\n /** The tip commit of the worktree being classified — `worktree.head`. */\n tipSha: string\n /** Default `\"origin/main\"` — matches `reconcileIntegration`'s own default. */\n defaultBranchRef?: string\n}\n\nexport interface ResolvedGcClass {\n class: GcClass\n /** Set only when `class === \"reclaim\"` via the dep-bump exemption rather than the ordinary merged/fresh path. */\n reclaimReason?: GcReclaimReason\n}\n\n/**\n * `classifyForGc` plus the one async, git-touching layer on top: a clean,\n * `unpushed` worktree whose entire ahead range is a mechanical dep bump is\n * promoted from `hold` to `reclaim`. Every other class classifyForGc\n * returns is passed through untouched — this never widens any other hold\n * reason, and never touches git for a worktree it wouldn't otherwise hold\n * on `unpushed` alone.\n */\nexport async function resolveGcClass(\n tree: TreeState,\n integration: IntegrationState,\n liveness: LivenessState,\n options: ResolveGcClassOptions,\n): Promise<ResolvedGcClass> {\n const baseClass = classifyForGc(tree, integration, liveness, options)\n if (baseClass !== \"hold\") return { class: baseClass }\n if (tree.state !== \"clean\" || integration.state !== \"unpushed\") return { class: \"hold\" }\n\n const baseRef = options.defaultBranchRef ?? \"origin/main\"\n const isDepBump = await isMechanicalDepBumpRange(options.repoRoot, baseRef, options.tipSha)\n if (!isDepBump) return { class: \"hold\" }\n return { class: \"reclaim\", reclaimReason: \"dep-bump\" }\n}\n\n// ── plan ─────────────────────────────────────────────────────────────\n\nexport interface GcPlanEntry {\n path: string\n branch: string | null\n head: string\n /**\n * Absent for an orphan entry (`orphan: true`) or a prunable entry\n * (`prunable: true`) — git itself cannot answer the tree/integration/\n * liveness questions for a directory it no longer recognizes as a\n * worktree (orphan) or whose working directory is simply gone (prunable),\n * so this module never fabricates a value for them rather than reporting\n * a fact it can't actually check.\n */\n tree?: TreeState\n integration?: IntegrationState\n liveness?: LivenessState\n /** Classification per PLAN.md §5.1, after `--include-detached` (if set). */\n class: GcClass\n /** Set only when `class === \"reclaim\"` via the dep-bump exemption, the orphan reclaim path, or the prunable reclaim path — see `resolveGcClass` / `scanOrphanWorktreePaths` / `toPlanEntry`. */\n reclaimReason?: GcReclaimReason\n /** Set only when `class === \"hold\"` via `protectedPaths` (`isProtectedPath`) — distinguishes this from an ordinary snapshot-based hold. */\n holdReason?: GcHoldReason\n /**\n * `true` only for a directory the orphan scan found: physically present\n * under the repo's worktree pool, but absent from `git worktree list`\n * (even after `git worktree prune`) — the interrupted-`worktree remove`\n * shape (module docblock's §5 note). Always paired with `class: \"reclaim\"`\n * and `reclaimReason: \"orphan\"`. Never set for a linked worktree, however\n * it classifies.\n */\n orphan?: boolean\n /**\n * `true` only for a linked worktree `git worktree list --porcelain` itself\n * already marked `prunable` — its working directory is gone, so none of\n * `classify`'s three axes were computed (no git command was ever run\n * against the dead path). Always paired with `class: \"reclaim\"` and\n * `reclaimReason: \"prunable\"` — see \"prunable reclaim\" below `toPlanEntry`.\n */\n prunable?: boolean\n}\n\nexport interface PlanGcInput {\n repoRoot: string\n repoName: string\n forge: ForgeClient\n memo: VerdictMemoStore\n defaultBranchRef?: string\n sessionsPath?: string\n includeDetached?: boolean\n now?: () => string\n /** See `ComputeWorktreeStatusInput.nowMs` (status.ts) — kept separate from `now`. Defaults to `Date.now()`. */\n nowMs?: number\n /**\n * The bucket directory this repo's worktrees are provisioned under — e.g.\n * `<worktrees.root>/<repoLabel>` (see `resolveWorktreesRoot` / `repoLabel`,\n * both resolved by the caller; this module does no root resolution of its\n * own, see the orphan-reclaim section below). When omitted, orphan\n * scanning is skipped entirely and `planGc`/`applyGc` behave exactly as\n * before — every existing caller that doesn't pass this sees zero change.\n */\n worktreesRoot?: string\n /**\n * Absolute paths (typically live session cwds) that must never be\n * classified `reclaim`/`salvage`, exact-or-subdirectory (`isProtectedPath`)\n * — see the \"live-session-cwd protection\" section above. Applies to both\n * linked worktrees and orphan-scan entries. Omitted ⇒ no additional\n * protection beyond `classify`'s own snapshot-based liveness axis.\n */\n protectedPaths?: string[]\n}\n\n/** Every linked worktree of `repoRoot` except the main checkout itself — see the module docblock. */\nasync function linkedWorktreesOf(repoRoot: string): Promise<GitWorktreeRef[]> {\n const worktrees = await listGitWorktrees(repoRoot)\n return worktrees.filter((w) => w.path !== repoRoot)\n}\n\n// ── orphan reclaim ───────────────────────────────────────────────────────\n//\n// `linkedWorktreesOf` (and therefore every axis `classify` depends on) can\n// only ever see what `git worktree list` reports — which is exactly the\n// blind spot behind the 8GB/day leak this section exists for. A worktree\n// removal interrupted mid-delete leaves the directory on disk but erases\n// `<repoRoot>/.git/worktrees/<name>`, so git no longer has ANY record of it:\n// `git worktree list` doesn't show it, `git status` inside it fails outright\n// (\"not a working tree\"), and it is therefore invisible to gc forever,\n// through no fault of the classify/reclaim/salvage engine above — that\n// engine is working exactly as designed on the set of worktrees git still\n// knows about.\n//\n// This section is deliberately narrow and conservative, matching the case\n// its ownership check can actually prove:\n// 1. A directory only ever counts as an orphan of THIS repo if its own\n// `.git` file's `gitdir:` pointer resolves inside `<repoRoot>`'s own\n// `.git/worktrees/` — `belongsToRepo` below. An unrelated directory\n// that happens to sit in the same pool (no `.git` pointer, or one that\n// points somewhere else entirely) is never touched, full stop.\n// 2. `git worktree prune` runs first — cheap and safe — so a directory\n// that's merely mid-registration (not actually orphaned) resolves\n// itself before the scan concludes anything.\n// 3. Once `git worktree list` still doesn't know about it after a prune,\n// there is nothing left that could \"reclassify\" it the way a linked\n// worktree can flip branches mid-session (`applyOne`'s layer 2): its\n// git identity is already gone, so nothing can merge it, push it, or\n// lose reachable history by removing it. The only thing at risk is\n// uncommitted working-tree state, and by definition git has already\n// lost the ability to act on that state through any of its own verbs —\n// the directory is no longer a working tree by git's own definition.\n// Because of (3), an orphan is unconditionally `reclaim` — there is no\n// `hold`/`salvage` axis to compute for it, and manufacturing one would be\n// reporting a fact this module cannot actually check (see `GcPlanEntry`'s\n// `tree`/`integration`/`liveness` doc).\n\n/**\n * Absolute path to this repo's own `.git/worktrees` directory — every\n * linked worktree's `.git` file points at a child of this. Resolved via\n * `git rev-parse --git-common-dir` rather than assuming `<repoRoot>/.git`\n * literally, so a bare/alternate git layout is still handled correctly.\n */\nasync function gitWorktreesDir(repoRoot: string): Promise<string> {\n const res = await execArgv(\"git\", [\"-C\", repoRoot, \"rev-parse\", \"--git-common-dir\"], repoRoot)\n if (res.exitCode !== 0) {\n throw new Error(\n `git rev-parse --git-common-dir failed in ${repoRoot} (exit ${res.exitCode}): ${res.stderr.trim()}`,\n )\n }\n return join(resolve(repoRoot, res.stdout.trim()), \"worktrees\")\n}\n\n/**\n * Reads a worktree directory's `.git` file (`gitdir: <path>`) and resolves\n * the target to an absolute path. `null` when the file is absent, unreadable,\n * or doesn't match the `gitdir:` pointer shape every linked worktree's `.git`\n * has (a plain directory with no `.git` at all is exactly the shape an\n * unrelated, not-ours directory has — see `belongsToRepo`).\n */\nasync function readGitdirPointer(worktreePath: string): Promise<string | null> {\n let raw: string\n try {\n raw = await readFile(join(worktreePath, \".git\"), \"utf8\")\n } catch {\n return null\n }\n const match = raw.match(/^gitdir:\\s*(.+?)\\s*$/m)\n const target = match?.[1]\n if (!target) return null\n return resolve(worktreePath, target)\n}\n\n/**\n * `true` only when `worktreePath`'s `.git` pointer resolves inside\n * `repoRoot`'s own `.git/worktrees/` — the one signal the orphan scan trusts\n * before ever touching a directory. This is deliberately a string-prefix\n * check, not an existence check: for a genuine orphan, the specific\n * `.git/worktrees/<name>` subdirectory the pointer names is exactly what's\n * gone (that's the orphan condition), so requiring it to still exist would\n * make this check unable to ever confirm the one case it exists for.\n */\nasync function belongsToRepo(repoRoot: string, worktreePath: string): Promise<boolean> {\n const pointer = await readGitdirPointer(worktreePath)\n if (!pointer) return false\n let worktreesDir: string\n try {\n worktreesDir = await gitWorktreesDir(repoRoot)\n } catch {\n return false\n }\n const rel = relative(worktreesDir, pointer)\n return rel === \"\" || (!rel.startsWith(\"..\") && !isAbsolute(rel))\n}\n\nasync function pathExists(path: string): Promise<boolean> {\n try {\n await stat(path)\n return true\n } catch {\n return false\n }\n}\n\n/**\n * Resolves symlinks (`realpath`) so a path git reports and the same path\n * built by hand from a config-supplied root compare equal even when some\n * component along the way is a symlink (e.g. macOS's `/tmp` →\n * `/private/tmp`, or a temp-dir-backed test fixture) — falls back to plain\n * `resolve` for a path that doesn't exist (yet) rather than throwing.\n */\nasync function realOrResolved(path: string): Promise<string> {\n try {\n return await realpath(path)\n } catch {\n return resolve(path)\n }\n}\n\n/**\n * Discovery (plan time): every directory physically present under\n * `worktreesRoot` that both (a) `git worktree list` doesn't know about, even\n * after a `worktree prune`, and (b) genuinely belongs to `repoRoot` per\n * `belongsToRepo`. A `worktreesRoot` that doesn't exist yet (nothing has\n * ever been provisioned there) yields no orphans, not an error.\n */\nasync function scanOrphanWorktreePaths(repoRoot: string, worktreesRoot: string): Promise<string[]> {\n await execArgv(\"git\", [\"-C\", repoRoot, \"worktree\", \"prune\"], repoRoot).catch(() => null)\n const linkedRefs = await linkedWorktreesOf(repoRoot)\n const linked = new Set(await Promise.all(linkedRefs.map((w) => realOrResolved(w.path))))\n const entries = await readdir(worktreesRoot, { withFileTypes: true }).catch(() => [])\n const orphans: string[] = []\n for (const entry of entries) {\n if (!entry.isDirectory()) continue\n const candidate = resolve(worktreesRoot, entry.name)\n if (linked.has(await realOrResolved(candidate))) continue\n if (await belongsToRepo(repoRoot, candidate)) orphans.push(candidate)\n }\n return orphans\n}\n\nfunction makeOrphanPlanEntry(path: string, protectedPaths: readonly string[] | undefined): GcPlanEntry {\n if (isProtectedPath(path, protectedPaths)) {\n return { path, branch: null, head: \"\", class: \"hold\", holdReason: \"live-session-cwd\" }\n }\n return { path, branch: null, head: \"\", class: \"reclaim\", reclaimReason: \"orphan\", orphan: true }\n}\n\n/**\n * Apply-time re-check (layer 2, mirrored from `applyOne`'s TOCTOU guard for\n * linked worktrees): re-derive from scratch, immediately before touching\n * anything, rather than trusting the plan's stale snapshot.\n * - `\"gone\"`: the directory no longer exists at all — a prior/concurrent\n * gc pass (or the plan itself racing a manual `rm`) already finished the\n * job. Reclaiming this is a no-op success, not a failure.\n * - `\"confirmed\"`: still on disk, still un-linked after a fresh prune,\n * `.git` pointer still resolves back to this repo — safe to remove.\n * - `\"not-orphan\"`: something changed since the plan was made (most\n * plausibly: it got re-registered, or the ownership check no longer\n * passes) — refuse, exactly like `applyOne`'s `aborted-reclassified`.\n */\nasync function verifyOrphan(repoRoot: string, worktreePath: string): Promise<\"gone\" | \"confirmed\" | \"not-orphan\"> {\n if (!(await pathExists(worktreePath))) return \"gone\"\n await execArgv(\"git\", [\"-C\", repoRoot, \"worktree\", \"prune\"], repoRoot).catch(() => null)\n const linked = await linkedWorktreesOf(repoRoot)\n const realWorktreePath = await realOrResolved(worktreePath)\n for (const w of linked) {\n if ((await realOrResolved(w.path)) === realWorktreePath) return \"not-orphan\"\n }\n return (await belongsToRepo(repoRoot, worktreePath)) ? \"confirmed\" : \"not-orphan\"\n}\n\n/**\n * Reclaim one orphan entry. No `worktree.cleanup` tool here — that tool\n * shells out to `git worktree remove`, which by definition refuses (or\n * simply doesn't know what to do with) a directory git has no record of;\n * plain recursive removal is the correct, and only, verb for something git\n * itself no longer considers a working tree. `{ recursive: true, force:\n * true }` is what makes this idempotent: a directory that's already gone,\n * or partially gone (the same half-deleted shape the orphan condition\n * itself comes from), is removed without error either way.\n */\nasync function reclaimOrphan(entry: GcPlanEntry, options: ApplyGcOptions): Promise<GcApplyOutcome> {\n const state = await verifyOrphan(options.repoRoot, entry.path)\n if (state === \"not-orphan\") {\n return { path: entry.path, branch: null, result: \"aborted-reclassified\", from: \"reclaim\", to: \"hold\" }\n }\n if (state === \"confirmed\") {\n try {\n await rm(entry.path, { recursive: true, force: true })\n } catch (err) {\n return {\n path: entry.path,\n branch: null,\n result: \"failed\",\n message: err instanceof Error ? err.message : String(err),\n }\n }\n }\n // state === \"gone\": already removed — idempotent success, nothing to do.\n return { path: entry.path, branch: null, result: \"reclaimed\", reclaimReason: \"orphan\" }\n}\n\n// ── prunable reclaim: a registration git already knows is dead ─────────────\n//\n// `git worktree list --porcelain` itself emits a `prunable <reason>` line\n// when a linked worktree's working directory is gone but its `.git/\n// worktrees/<name>` registration is still intact (the mirror image of the\n// orphan case above, where the registration is gone but the directory\n// isn't). Before this section, `linkedWorktreesOf` still handed this entry\n// to `computeWorktreeStatus`, which spawns `git status --porcelain=v2 -C\n// <dead path>` and throws — a throw that escaped `planGc`'s loop entirely\n// and took the whole plan down with it, for every worktree in the repo, not\n// just the dead one.\n//\n// Classification here never runs a single git command against the dead\n// path: git's own `prunable` line is trusted as-is (`GitWorktreeRef.prunable`,\n// status.ts), never re-derived with `existsSync` or any filesystem check of\n// our own. Reclaiming it is `git worktree prune` alone — no\n// `cleanupWorktreeTool`/`git worktree remove` (which needs a working\n// directory to operate on and would refuse or misbehave against one that's\n// already gone), and critically no branch deletion: there is nothing left to\n// inspect to decide a branch is safe to delete, so this path must never\n// reach `reclaimOne`'s `deleteBranch: true`.\n\nfunction makePrunablePlanEntry(worktree: GitWorktreeRef, protectedPaths: readonly string[] | undefined): GcPlanEntry {\n if (isProtectedPath(worktree.path, protectedPaths)) {\n return { path: worktree.path, branch: worktree.branch, head: worktree.head, class: \"hold\", holdReason: \"live-session-cwd\" }\n }\n return {\n path: worktree.path,\n branch: worktree.branch,\n head: worktree.head,\n class: \"reclaim\",\n reclaimReason: \"prunable\",\n prunable: true,\n }\n}\n\n/**\n * Apply-time re-check (layer 2, mirrored from `verifyOrphan`): re-list from\n * scratch immediately before touching anything, rather than trusting the\n * plan's stale snapshot.\n * - entry no longer listed at all: a prior/concurrent `gc` (or a plain\n * `git worktree prune` run by something else) already finished the job —\n * reclaiming this is a no-op success, not a failure.\n * - still listed, still `prunable`: safe to prune.\n * - still listed, no longer `prunable`: something changed since the plan\n * was made (most plausibly: a new worktree got registered at the exact\n * same path) — refuse, exactly like `applyOne`'s `aborted-reclassified`.\n */\nasync function reclaimPrunable(entry: GcPlanEntry, options: ApplyGcOptions): Promise<GcApplyOutcome> {\n const fresh = await listGitWorktrees(options.repoRoot)\n const stillThere = fresh.find((w) => w.path === entry.path)\n if (stillThere && !stillThere.prunable) {\n return { path: entry.path, branch: stillThere.branch, result: \"aborted-reclassified\", from: \"reclaim\", to: \"hold\" }\n }\n if (stillThere) {\n try {\n await execGit(options.repoRoot, [\"worktree\", \"prune\"])\n } catch (err) {\n return {\n path: entry.path,\n branch: entry.branch,\n result: \"failed\",\n message: err instanceof Error ? err.message : String(err),\n }\n }\n }\n // Either just pruned above, or already gone by the time we re-listed —\n // either way, the registration is now clear and the branch is untouched.\n return { path: entry.path, branch: entry.branch, result: \"reclaimed\", reclaimReason: \"prunable\" }\n}\n\nasync function toPlanEntry(\n repoRoot: string,\n defaultBranchRef: string | undefined,\n worktree: GitWorktreeRef,\n status: { tree: TreeState; integration: IntegrationState; liveness: LivenessState },\n includeDetached: boolean,\n nowMs: number,\n protectedPaths?: readonly string[],\n): Promise<GcPlanEntry> {\n if (isProtectedPath(worktree.path, protectedPaths)) {\n return {\n path: worktree.path,\n branch: worktree.branch,\n head: worktree.head,\n tree: status.tree,\n integration: status.integration,\n liveness: status.liveness,\n class: \"hold\",\n holdReason: \"live-session-cwd\",\n }\n }\n const resolved = await resolveGcClass(status.tree, status.integration, status.liveness, {\n repoRoot,\n tipSha: worktree.head,\n defaultBranchRef,\n includeDetached,\n nowMs,\n })\n return {\n path: worktree.path,\n branch: worktree.branch,\n head: worktree.head,\n tree: status.tree,\n integration: status.integration,\n liveness: status.liveness,\n class: resolved.class,\n ...(resolved.reclaimReason ? { reclaimReason: resolved.reclaimReason } : {}),\n }\n}\n\n/**\n * The dry-run plan (PLAN.md §5.2 layer 1): classify every linked worktree,\n * mutate nothing. This is the human's decision surface — `gc` with no flags\n * is exactly \"call this, print it, stop.\"\n */\nexport async function planGc(input: PlanGcInput): Promise<GcPlanEntry[]> {\n const includeDetached = Boolean(input.includeDetached)\n // One frozen instant for the whole plan's recent-write checks.\n const nowMs = input.nowMs ?? Date.now()\n const worktrees = await linkedWorktreesOf(input.repoRoot)\n const entries: GcPlanEntry[] = []\n for (const worktree of worktrees) {\n // git already told us this one is dead — classify it from that signal\n // alone, without spawning a single git command against its (nonexistent)\n // path. See the \"prunable reclaim\" section above `toPlanEntry`.\n if (worktree.prunable) {\n entries.push(makePrunablePlanEntry(worktree, input.protectedPaths))\n continue\n }\n const status = await computeWorktreeStatus({\n repoRoot: input.repoRoot,\n repoName: input.repoName,\n worktree,\n forge: input.forge,\n memo: input.memo,\n defaultBranchRef: input.defaultBranchRef,\n sessionsPath: input.sessionsPath,\n now: input.now,\n })\n entries.push(\n await toPlanEntry(\n input.repoRoot,\n input.defaultBranchRef,\n worktree,\n status,\n includeDetached,\n nowMs,\n input.protectedPaths,\n ),\n )\n }\n if (input.worktreesRoot) {\n const orphanPaths = await scanOrphanWorktreePaths(input.repoRoot, input.worktreesRoot)\n for (const path of orphanPaths) entries.push(makeOrphanPlanEntry(path, input.protectedPaths))\n }\n return entries\n}\n\n// ── apply ────────────────────────────────────────────────────────────\n\nexport interface ApplyGcOptions {\n repoRoot: string\n repoName: string\n forge: ForgeClient\n memo: VerdictMemoStore\n defaultBranchRef?: string\n sessionsPath?: string\n includeDetached?: boolean\n /** Archive (salvage-then-remove) every salvage-class entry. Default false — salvage entries are left untouched. */\n salvageDirty?: boolean\n now?: () => string\n /** See `ComputeWorktreeStatusInput.nowMs` (status.ts) — kept separate from `now`. Defaults to `Date.now()`. */\n nowMs?: number\n /** Override for `~/.agentproto/worktree-salvage` — tests use a temp dir. */\n salvageRoot?: string\n /** See `PlanGcInput.protectedPaths` — re-checked here at apply time (layer 2), independent of what the plan entry says, so a stale plan can never remove a now-protected path. */\n protectedPaths?: string[]\n}\n\nexport type GcApplyOutcome =\n | { path: string; branch: string | null; result: \"reclaimed\"; reclaimReason?: GcReclaimReason }\n | { path: string; branch: string | null; result: \"salvaged\"; salvageDir: string }\n | { path: string; branch: string | null; result: \"held\"; holdReason?: GcHoldReason }\n /** Salvage-class, but `--salvage-dirty` was not passed: left untouched by design. */\n | { path: string; branch: string | null; result: \"skipped-dirty\" }\n /** Layer 2: re-classified at apply time to something other than the plan said — refuses rather than acting on a stale plan. */\n | { path: string; branch: string | null; result: \"aborted-reclassified\"; from: GcClass; to: GcClass; holdReason?: GcHoldReason }\n /** The worktree named in the plan no longer exists (already removed by something else since the plan was made). */\n | { path: string; branch: string | null; result: \"aborted-vanished\" }\n /** git itself (or the salvage snapshot) refused — the TOCTOU backstop actually firing, or a real I/O failure. */\n | { path: string; branch: string | null; result: \"failed\"; message: string }\n\nasync function findWorktree(repoRoot: string, path: string): Promise<GitWorktreeRef | null> {\n const worktrees = await linkedWorktreesOf(repoRoot)\n return worktrees.find((w) => w.path === path) ?? null\n}\n\nasync function reclaimOne(\n options: ApplyGcOptions,\n worktree: GitWorktreeRef,\n reclaimReason?: GcReclaimReason,\n): Promise<GcApplyOutcome> {\n try {\n await runTool({\n tool: cleanupWorktreeTool,\n candidates,\n input: {\n repoRoot: options.repoRoot,\n cwd: worktree.path,\n ...(worktree.branch ? { branch: worktree.branch } : {}),\n // Branch deletion only ever runs for a `reclaim`-class entry, which by\n // construction requires `integration ∈ {merged(*), fresh}` and\n // `tree = clean` (PLAN.md's invariant: branch -D only when there's\n // nothing uncommitted to lose, never a hold class).\n deleteBranch: true,\n // No discardUntracked/discardModified, ever, on this path (PLAN.md\n // §5.2 layer 3): `reclaim` means `tree = clean`, so plain `git\n // worktree remove` should succeed on its own; if the tree turned\n // dirty in the instant between the re-check above and this call, git\n // itself refuses and that refusal surfaces below as `failed` — never\n // a force flag \"just in case.\"\n },\n })\n } catch (err) {\n return {\n path: worktree.path,\n branch: worktree.branch,\n result: \"failed\",\n message: err instanceof Error ? err.message : String(err),\n }\n }\n return {\n path: worktree.path,\n branch: worktree.branch,\n result: \"reclaimed\",\n ...(reclaimReason ? { reclaimReason } : {}),\n }\n}\n\nasync function salvageOne(options: ApplyGcOptions, worktree: GitWorktreeRef): Promise<GcApplyOutcome> {\n let salvageDir: string\n try {\n const result = await salvageWorktree({\n repoRoot: options.repoRoot,\n repoName: options.repoName,\n worktreePath: worktree.path,\n branch: worktree.branch,\n tipSha: worktree.head,\n slug: worktree.branch ?? basename(worktree.path),\n sessionsPath: options.sessionsPath,\n now: options.now,\n salvageRoot: options.salvageRoot,\n })\n salvageDir = result.dir\n } catch (err) {\n return {\n path: worktree.path,\n branch: worktree.branch,\n result: \"failed\",\n message: `salvage failed, nothing removed: ${err instanceof Error ? err.message : String(err)}`,\n }\n }\n\n try {\n await runTool({\n tool: cleanupWorktreeTool,\n candidates,\n input: {\n repoRoot: options.repoRoot,\n cwd: worktree.path,\n ...(worktree.branch ? { branch: worktree.branch } : {}),\n deleteBranch: true,\n // Both discard flags: the snapshot above is already durable (fsynced)\n // before this call, so nothing on disk is lost by discarding it here\n // (PLAN.md §5.2 layer 4 — salvage before discard).\n discardUntracked: true,\n discardModified: true,\n },\n })\n } catch (err) {\n return {\n path: worktree.path,\n branch: worktree.branch,\n result: \"failed\",\n message: `salvaged to ${salvageDir}, but removal failed: ${err instanceof Error ? err.message : String(err)}`,\n }\n }\n\n return { path: worktree.path, branch: worktree.branch, result: \"salvaged\", salvageDir }\n}\n\nasync function applyOne(entry: GcPlanEntry, options: ApplyGcOptions): Promise<GcApplyOutcome> {\n // Layer 2's own layer 2: re-checked first, ahead of every other branch\n // below (orphan or linked, whatever the plan's stale `class` says) — a\n // path named in `options.protectedPaths` is NEVER touched, even when the\n // plan itself was built before the path became protected (e.g. a session\n // started using this cwd after the plan was made but before apply ran).\n if (isProtectedPath(entry.path, options.protectedPaths)) {\n if (entry.class === \"hold\") {\n return { path: entry.path, branch: entry.branch, result: \"held\", holdReason: \"live-session-cwd\" }\n }\n return {\n path: entry.path,\n branch: entry.branch,\n result: \"aborted-reclassified\",\n from: entry.class,\n to: \"hold\",\n holdReason: \"live-session-cwd\",\n }\n }\n // Orphan entries never go through `findWorktree`/`computeWorktreeStatus`\n // below — those assume `git worktree list` still knows about the entry,\n // which is exactly what an orphan means it doesn't. See \"orphan reclaim\"\n // above `reclaimOrphan` for its own from-scratch TOCTOU re-check.\n if (entry.orphan) {\n return reclaimOrphan(entry, options)\n }\n // Prunable entries never go through `computeWorktreeStatus` below either —\n // that would spawn `git status` against a working directory that's gone,\n // the exact throw this whole path exists to avoid. See \"prunable reclaim\"\n // above `reclaimPrunable` for its own from-scratch TOCTOU re-check.\n if (entry.prunable) {\n return reclaimPrunable(entry, options)\n }\n if (entry.class === \"hold\") {\n return { path: entry.path, branch: entry.branch, result: \"held\" }\n }\n if (entry.class === \"salvage\" && !options.salvageDirty) {\n return { path: entry.path, branch: entry.branch, result: \"skipped-dirty\" }\n }\n\n // Layer 2 (PLAN.md §5.2): re-check immediately before touching anything.\n // Re-derive the worktree ref itself, not just its status — a branch can\n // flip between plan and apply (the rendezvous-deploy branch-flip mid-\n // session is the plan's own existence proof for this), so re-listing\n // `git worktree list` is required, not just recomputing against the\n // plan's stale (path, branch, head) tuple.\n const fresh = await findWorktree(options.repoRoot, entry.path)\n if (!fresh) {\n return { path: entry.path, branch: entry.branch, result: \"aborted-vanished\" }\n }\n const status = await computeWorktreeStatus({\n repoRoot: options.repoRoot,\n repoName: options.repoName,\n worktree: fresh,\n forge: options.forge,\n memo: options.memo,\n defaultBranchRef: options.defaultBranchRef,\n sessionsPath: options.sessionsPath,\n now: options.now,\n })\n // Re-resolved from scratch — including the dep-bump exemption, not just\n // `entry`'s stale plan-time verdict, so a worktree that picked up a real\n // (non-bump) commit between plan and apply is re-caught here, not just at\n // plan time.\n const resolved = await resolveGcClass(status.tree, status.integration, status.liveness, {\n repoRoot: options.repoRoot,\n tipSha: fresh.head,\n defaultBranchRef: options.defaultBranchRef,\n includeDetached: Boolean(options.includeDetached),\n nowMs: options.nowMs,\n })\n if (resolved.class !== entry.class) {\n return {\n path: entry.path,\n branch: fresh.branch,\n result: \"aborted-reclassified\",\n from: entry.class,\n to: resolved.class,\n }\n }\n\n if (resolved.class === \"reclaim\") return reclaimOne(options, fresh, resolved.reclaimReason)\n // The only other class that reaches this point is \"salvage\" with\n // `options.salvageDirty` true (both earlier guards above already returned\n // for \"hold\" and for \"salvage\" without the flag).\n return salvageOne(options, fresh)\n}\n\n/**\n * Execute a plan (PLAN.md §5.2 layers 2–4). Every entry is re-classified\n * from scratch immediately before it's touched; a `hold` entry is never\n * touched, a `salvage` entry is only touched when `salvageDirty` is true,\n * and every removal goes through `worktree.cleanup` — never a hand-rolled\n * `git worktree remove`.\n */\nexport async function applyGc(plan: readonly GcPlanEntry[], options: ApplyGcOptions): Promise<GcApplyOutcome[]> {\n const outcomes: GcApplyOutcome[] = []\n for (const entry of plan) {\n outcomes.push(await applyOne(entry, options))\n }\n return outcomes\n}\n\n// ── single-worktree reclaim (session exit-time auto-reclaim) ───────────────\n//\n// A policy-provisioned (implicit) worktree — one `decideWorktreeIsolation`'s\n// `\"always\"` branch minted for a caller who never asked to keep it (see that\n// module's `WorktreeDecision.provision.implicit`) — is a candidate for\n// reclaim the moment its own session exits, rather than sitting until the\n// next manual/scheduled `gc` sweep. This is deliberately scoped to ONE\n// worktree — a session's own exit must never sweep or touch any OTHER\n// worktree in the pool — and deliberately reuses `applyGc`'s existing\n// classify → re-verify → remove pipeline (a plan of size one) rather than\n// hand-rolling a second removal path with its own safety logic to keep in\n// sync.\n\n/**\n * Attempt to reclaim exactly one worktree by path — the exit-time auto-\n * reclaim primitive `sessions.ts` calls (via the injected\n * `WorktreeAutoReclaimer` port) when a policy-provisioned session reaches a\n * terminal state. Classifies it fresh (never trusts a caller-supplied\n * verdict) and only ever removes it when that classification is `reclaim`\n * (merged-or-fresh, clean, idle) — a dirty or held worktree is returned\n * as-is, exactly like any other `gc` outcome, still visible via\n * `worktree_status` and still manually reclaimable. Returns `null` when the\n * path no longer names a linked worktree at all (already removed by\n * something else — nothing to do, not an error).\n */\nexport async function reclaimOneWorktree(\n worktreePath: string,\n options: ApplyGcOptions & { includeDetached?: boolean },\n): Promise<GcApplyOutcome | null> {\n const worktree = await findWorktree(options.repoRoot, worktreePath)\n if (!worktree) return null\n if (worktree.prunable) {\n return applyOne(makePrunablePlanEntry(worktree, options.protectedPaths), options)\n }\n const status = await computeWorktreeStatus({\n repoRoot: options.repoRoot,\n repoName: options.repoName,\n worktree,\n forge: options.forge,\n memo: options.memo,\n defaultBranchRef: options.defaultBranchRef,\n sessionsPath: options.sessionsPath,\n now: options.now,\n })\n const entry = await toPlanEntry(\n options.repoRoot,\n options.defaultBranchRef,\n worktree,\n status,\n Boolean(options.includeDetached),\n options.nowMs ?? Date.now(),\n options.protectedPaths,\n )\n return applyOne(entry, options)\n}\n"]}
1
+ {"version":3,"sources":["../src/salvage.ts","../src/services/proxy-server.ts","../src/forge.ts","../src/branch-gc.ts","../src/gc.ts"],"names":["netConnect","resolve","fetch","homedir","mkdir","dirname","writeFile","join","z","readFile"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Salvage-before-discard (PLAN.md §5.2 layer 4). `worktree archive` re-earns\n * its name by snapshotting a worktree's uncommitted state before it removes\n * anything: `git diff HEAD` → `changes.patch`, plus a byte-copy of every\n * unignored untracked file, into\n * `~/.agentproto/worktree-salvage/<repoName>/<slug>-<tipSha7>-<date>/` with a\n * `MANIFEST.json`. Every file is fsynced before this returns — only once the\n * snapshot is durable does the caller proceed to force-remove.\n *\n * Deliberately forge-independent: no PR lookup here. This writer's only job\n * is \"don't lose bytes before deletion,\" not classification — `ls --status`\n * (status.ts) already owns the forge-derived `integration` axis, and gc\n * (PR-D) is where a salvage manifest and a status entry would be cross-\n * referenced, not here.\n */\n\nimport { copyFile, mkdir, open, writeFile } from \"node:fs/promises\"\nimport { homedir } from \"node:os\"\nimport { dirname, join, resolve } from \"node:path\"\nimport { execArgv } from \"./exec.js\"\nimport { computeProvenance, type ProvenanceInfo } from \"./provenance.js\"\n\nexport const SALVAGE_ROOT = (): string => resolve(homedir(), \".agentproto\", \"worktree-salvage\")\n\nexport interface SalvageManifest {\n repo: string\n /** `null` for a detached HEAD. */\n branch: string | null\n tipSha: string\n createdAt: string\n /** Relative paths of every unignored untracked file that was copied in. */\n untrackedFiles: string[]\n /** Whether `changes.patch` has any content (tracked-file changes existed). */\n hasPatch: boolean\n provenance: ProvenanceInfo\n}\n\nexport interface SalvageWorktreeInput {\n /** The main repo root — the stable spawn anchor for this worktree's git reads (see `listUntrackedFiles`'s doc). */\n repoRoot: string\n repoName: string\n worktreePath: string\n branch: string | null\n tipSha: string\n /** Identifies this worktree in the salvage directory name, e.g. its slug or branch. */\n slug: string\n sessionsPath?: string\n /** Injectable clock so tests can freeze `createdAt` / the directory name. */\n now?: () => string\n /** Override for `~/.agentproto/worktree-salvage` — tests use a temp dir. */\n salvageRoot?: string\n}\n\nexport interface SalvageResult {\n dir: string\n manifest: SalvageManifest\n}\n\n/**\n * Untracked, non-ignored files in the worktree — the same class `git\n * worktree remove` refuses without `--force`. Spawn `cwd` is `repoRoot`, not\n * `worktreePath` — a linked worktree can be removed by a concurrent `gc`\n * reap (or a racing status read) while this call is in flight, and a spawn\n * whose `cwd` no longer exists fails `ENOENT` on the COMMAND itself (a\n * Node/libuv quirk), not the directory — see `exec.ts`'s `execGit`, which\n * anchors the same way.\n */\nasync function listUntrackedFiles(repoRoot: string, worktreePath: string): Promise<string[]> {\n const res = await execArgv(\"git\", [\"-C\", worktreePath, \"ls-files\", \"--others\", \"--exclude-standard\"], repoRoot)\n if (res.exitCode !== 0) {\n throw new Error(`git ls-files --others failed in ${worktreePath} (exit ${res.exitCode}): ${res.stderr.trim()}`)\n }\n return res.stdout.split(\"\\n\").filter(Boolean)\n}\n\n/** `git diff HEAD` — staged + unstaged changes to tracked files, uniformly.\n * Empty string on a clean tree. Spawn `cwd` is `repoRoot`, not\n * `worktreePath` — see `listUntrackedFiles`'s doc. */\nasync function diffHead(repoRoot: string, worktreePath: string): Promise<string> {\n const res = await execArgv(\"git\", [\"-C\", worktreePath, \"diff\", \"HEAD\"], repoRoot)\n if (res.exitCode !== 0) {\n throw new Error(`git diff HEAD failed in ${worktreePath} (exit ${res.exitCode}): ${res.stderr.trim()}`)\n }\n return res.stdout\n}\n\n/** Sanitize a path segment for use in the salvage directory name (no slashes, no leading dot-dot). */\nfunction sanitizeSegment(value: string): string {\n return value.replace(/[^a-zA-Z0-9._-]+/g, \"-\").replace(/^-+/, \"\") || \"worktree\"\n}\n\n/** fsync one file by path — the durability guarantee: only after this resolves is the byte \"saved\". */\nasync function fsyncFile(path: string): Promise<void> {\n const handle = await open(path, \"r+\")\n try {\n await handle.sync()\n } finally {\n await handle.close()\n }\n}\n\nasync function writeFileSynced(path: string, content: string): Promise<void> {\n await mkdir(dirname(path), { recursive: true })\n await writeFile(path, content, \"utf8\")\n await fsyncFile(path)\n}\n\n/**\n * Snapshot `worktreePath`'s uncommitted state into a fresh salvage\n * directory. Safe to call on a clean tree (writes an empty patch, no\n * untracked files, still a manifest) — every path this function returns is\n * fsynced before it resolves.\n */\nexport async function salvageWorktree(input: SalvageWorktreeInput): Promise<SalvageResult> {\n const now = input.now ?? (() => new Date().toISOString())\n const createdAt = now()\n const tipShort = input.tipSha.slice(0, 7)\n const dateStamp = createdAt.slice(0, 10)\n const dirName = `${sanitizeSegment(input.slug)}-${tipShort}-${dateStamp}`\n const dir = resolve(input.salvageRoot ?? SALVAGE_ROOT(), sanitizeSegment(input.repoName), dirName)\n await mkdir(dir, { recursive: true })\n\n const [patch, untrackedFiles, provenance] = await Promise.all([\n diffHead(input.repoRoot, input.worktreePath),\n listUntrackedFiles(input.repoRoot, input.worktreePath),\n computeProvenance(input.repoRoot, input.worktreePath, { sessionsPath: input.sessionsPath }),\n ])\n\n await writeFileSynced(join(dir, \"changes.patch\"), patch)\n\n for (const relPath of untrackedFiles) {\n const dest = join(dir, \"untracked\", relPath)\n await mkdir(dirname(dest), { recursive: true })\n await copyFile(join(input.worktreePath, relPath), dest)\n await fsyncFile(dest)\n }\n\n const manifest: SalvageManifest = {\n repo: input.repoName,\n branch: input.branch,\n tipSha: input.tipSha,\n createdAt,\n untrackedFiles,\n hasPatch: patch.length > 0,\n provenance,\n }\n await writeFileSynced(join(dir, \"MANIFEST.json\"), JSON.stringify(manifest, null, 2) + \"\\n\")\n\n return { dir, manifest }\n}\n","import http from \"node:http\"\nimport { connect as netConnect, type Socket } from \"node:net\"\nimport type { ProxyTable } from \"./proxy-table.js\"\n\n/**\n * A small HTTP reverse proxy over a {@link ProxyTable}. Routes\n * `http://<script>--<branch>--<repo>.localhost:<proxy-port>` to the matched\n * service's local port. Supports WebSocket (and any) `Upgrade` passthrough by\n * splicing raw sockets. Targets are always `127.0.0.1` — services bind\n * locally, the proxy is the only public-ish surface.\n */\n\nconst TARGET_HOST = \"127.0.0.1\"\n\nfunction notFound(table: ProxyTable, host: string | undefined): string {\n const known = table.entries().map(([h]) => h)\n return (\n `worktree-proxy: no service for host \"${host ?? \"(none)\"}\"\\n` +\n (known.length ? `known hosts:\\n${known.map((h) => ` ${h}`).join(\"\\n\")}\\n` : \"no services registered\\n\")\n )\n}\n\n/** Build (but don't start) the proxy HTTP server backed by `table`. */\nexport function createProxyServer(table: ProxyTable): http.Server {\n const server = http.createServer((req, res) => {\n const targetPort = table.lookup(req.headers.host)\n if (targetPort === undefined) {\n res.writeHead(502, { \"content-type\": \"text/plain\" })\n res.end(notFound(table, req.headers.host))\n return\n }\n\n const proxyReq = http.request(\n {\n host: TARGET_HOST,\n port: targetPort,\n method: req.method,\n path: req.url,\n headers: req.headers,\n },\n (proxyRes) => {\n res.writeHead(proxyRes.statusCode ?? 502, proxyRes.headers)\n proxyRes.pipe(res)\n },\n )\n proxyReq.on(\"error\", (err) => {\n if (!res.headersSent) res.writeHead(502, { \"content-type\": \"text/plain\" })\n res.end(`worktree-proxy: upstream error: ${err.message}\\n`)\n })\n req.pipe(proxyReq)\n })\n\n // WebSocket / generic Upgrade passthrough: splice the client socket to a\n // fresh TCP connection to the target, replaying the original request line\n // and headers so the upstream completes its own handshake.\n server.on(\"upgrade\", (req, clientSocket: Socket, head: Buffer) => {\n const targetPort = table.lookup(req.headers.host)\n if (targetPort === undefined) {\n clientSocket.end(\"HTTP/1.1 502 Bad Gateway\\r\\n\\r\\n\")\n return\n }\n\n const upstream = netConnect(targetPort, TARGET_HOST, () => {\n const headerLines = [`${req.method} ${req.url} HTTP/1.1`]\n for (let i = 0; i < req.rawHeaders.length; i += 2) {\n headerLines.push(`${req.rawHeaders[i]}: ${req.rawHeaders[i + 1]}`)\n }\n upstream.write(headerLines.join(\"\\r\\n\") + \"\\r\\n\\r\\n\")\n if (head && head.length) upstream.write(head)\n upstream.pipe(clientSocket)\n clientSocket.pipe(upstream)\n })\n\n const teardown = (): void => {\n clientSocket.destroy()\n upstream.destroy()\n }\n upstream.on(\"error\", teardown)\n clientSocket.on(\"error\", teardown)\n upstream.on(\"close\", () => clientSocket.destroy())\n clientSocket.on(\"close\", () => upstream.destroy())\n })\n\n return server\n}\n\nexport interface RunningProxy {\n /** The port the proxy is listening on. */\n port: number\n /** The underlying server. */\n server: http.Server\n /** Stop the proxy. */\n close(): Promise<void>\n}\n\n/** Start the proxy server on `port` (0 → OS-assigned). Resolves once listening. */\nexport function startProxy(table: ProxyTable, port = 0): Promise<RunningProxy> {\n const server = createProxyServer(table)\n // Track every accepted socket so shutdown can force-drop them. An upgraded\n // (WebSocket) connection is detached from the server's own tracking, so\n // `server.close()` alone would hang on it — we destroy them explicitly.\n const sockets = new Set<Socket>()\n server.on(\"connection\", (socket: Socket) => {\n sockets.add(socket)\n socket.once(\"close\", () => sockets.delete(socket))\n })\n return new Promise((resolve, reject) => {\n server.once(\"error\", reject)\n server.listen(port, () => {\n const address = server.address()\n const boundPort = address && typeof address === \"object\" ? address.port : port\n resolve({\n port: boundPort,\n server,\n close: () =>\n new Promise<void>((res) => {\n for (const socket of sockets) socket.destroy()\n sockets.clear()\n server.close(() => res())\n }),\n })\n })\n })\n}\n","/**\n * `ForgeClient` — the only network-facing surface the reconciliation rule\n * (`status.ts`) depends on. Kept as an interface (not a concrete `gh` call)\n * so:\n * 1. `status.ts` stays testable with a fake — the fixture-repo tests never\n * shell out to a real forge or touch the network.\n * 2. The shape is forge-portable by construction (PLAN.md §7.1): GitLab has\n * the same two facts — \"PRs/MRs whose head is this branch\" and \"PRs/MRs\n * that contain this commit\" — under different verbs\n * (`refs/merge-requests/<n>/head`, `GET /merge_requests?…`). Only\n * GitHub ships today; a `GitlabForgeClient` is a second implementation\n * of this same interface, not a redesign.\n *\n * Two implementations ship: `GhCliForgeClient` (shells out to the `gh` CLI,\n * inheriting the caller's own `gh auth` session — zero config) and\n * `RestForgeClient` (plain `fetch` against the GitHub REST API using\n * `GITHUB_TOKEN` — no new npm dependency). `createForgeClient` picks\n * whichever is usable; when neither is, callers get a client that always\n * reports itself unreachable, which the reconciliation rule already knows\n * how to fall back from (PLAN.md §1.3 step 5: memo, else `unknown(offline)`,\n * never a guess).\n */\n\nimport { z } from \"zod\"\nimport { execArgv } from \"./exec.js\"\n\n/** A pull/merge request as the reconciliation rule needs to see it. */\nexport interface ForgePullRequestRef {\n number: number\n state: \"open\" | \"closed\"\n merged: boolean\n mergedAt: string | null\n headRefName: string\n headRefOid: string\n}\n\n/**\n * Thrown by a `ForgeClient` method when the forge could not be reached or\n * queried at all (network failure, missing/unauthenticated CLI, non-2xx HTTP\n * response). Never thrown for a legitimate empty result (a branch/commit\n * with no PRs is a valid, resolvable answer — `[]`, not an error). Callers\n * treat this as PLAN.md §1.3 step 5: \"never guess.\"\n */\nexport class ForgeUnavailableError extends Error {\n constructor(message: string, options?: { cause?: unknown }) {\n super(message, options)\n this.name = \"ForgeUnavailableError\"\n }\n}\n\nexport interface ForgeClient {\n /** PRs/MRs (any state) whose head branch is exactly `branch`. */\n pullRequestsForBranch(branch: string): Promise<ForgePullRequestRef[]>\n /**\n * PRs/MRs associated with a specific commit SHA — the rename/retarget-proof\n * signal (PLAN.md §1.3 step 2b): finds the PR even if the branch was\n * renamed or deleted before merge.\n */\n pullRequestsForCommit(sha: string): Promise<ForgePullRequestRef[]>\n /**\n * Ensure `oid` (a PR's `headRefOid`) is present in the local object\n * database, fetching `refs/pull/<number>/head` if it isn't. Always\n * fetchable even after the head branch was deleted on the remote\n * (PLAN.md §1.3 step 2, verified for #273/#312/#325/#271).\n */\n ensurePullHeadFetched(prNumber: number, oid: string): Promise<void>\n /**\n * Every OPEN PR/MR in the repo, in one round-trip — the bulk twin of\n * `pullRequestsForBranch` for callers that must protect hundreds of refs at\n * once (`branch-gc.ts`: one call per ref would be a forge request per\n * branch). Optional so existing test doubles keep compiling; a client that\n * doesn't implement it is treated as \"open-PR detection unavailable\" by\n * those callers, never as \"no open PRs\".\n */\n listOpenPullRequests?(): Promise<ForgePullRequestRef[]>\n /**\n * Every MERGED PR/MR in the repo, in one round-trip — the bulk twin of\n * `listOpenPullRequests` for the merged-head shortcut (`branch-gc.ts`): a\n * branch whose tip is EXACTLY a merged PR's head commit lost nothing (that\n * commit was reviewed and merged), so it is reclaimable without an LLM\n * review. Optional so existing test doubles keep compiling; a client that\n * doesn't implement it is treated as \"merged-PR detection unavailable\" by\n * those callers, never as \"no merged PRs\".\n */\n listMergedPullRequests?(): Promise<ForgePullRequestRef[]>\n}\n\n/** A client that always reports itself unreachable — the \"no gh, no token\" case. */\nexport class UnreachableForgeClient implements ForgeClient {\n constructor(private readonly reason: string) {}\n async pullRequestsForBranch(): Promise<ForgePullRequestRef[]> {\n throw new ForgeUnavailableError(this.reason)\n }\n async pullRequestsForCommit(): Promise<ForgePullRequestRef[]> {\n throw new ForgeUnavailableError(this.reason)\n }\n async ensurePullHeadFetched(): Promise<void> {\n throw new ForgeUnavailableError(this.reason)\n }\n async listOpenPullRequests(): Promise<ForgePullRequestRef[]> {\n throw new ForgeUnavailableError(this.reason)\n }\n async listMergedPullRequests(): Promise<ForgePullRequestRef[]> {\n throw new ForgeUnavailableError(this.reason)\n }\n}\n\n// ── gh CLI implementation ───────────────────────────────────────────────\n\nconst ghPrListItemSchema = z.object({\n number: z.number(),\n state: z.string(),\n headRefName: z.string(),\n headRefOid: z.string(),\n mergedAt: z.string().nullable(),\n})\ntype GhPrListItem = z.infer<typeof ghPrListItemSchema>\nconst ghPrListSchema = z.array(ghPrListItemSchema)\n\nfunction normalizeGhPrListItem(item: GhPrListItem): ForgePullRequestRef {\n const state = item.state.toUpperCase()\n return {\n number: item.number,\n state: state === \"OPEN\" ? \"open\" : \"closed\",\n merged: state === \"MERGED\" || item.mergedAt !== null,\n mergedAt: item.mergedAt,\n headRefName: item.headRefName,\n headRefOid: item.headRefOid,\n }\n}\n\nconst ghApiCommitPullSchema = z.object({\n number: z.number(),\n state: z.string(),\n merged_at: z.string().nullable(),\n head: z.object({ ref: z.string(), sha: z.string() }),\n})\ntype GhApiCommitPull = z.infer<typeof ghApiCommitPullSchema>\nconst ghApiCommitPullListSchema = z.array(ghApiCommitPullSchema)\n\nfunction normalizeGhApiCommitPull(item: GhApiCommitPull): ForgePullRequestRef {\n return {\n number: item.number,\n state: item.state === \"open\" ? \"open\" : \"closed\",\n merged: item.merged_at !== null,\n mergedAt: item.merged_at,\n headRefName: item.head.ref,\n headRefOid: item.head.sha,\n }\n}\n\n/**\n * GitHub's REST API answers \"commit unknown to this repo\" (e.g. a local\n * commit that was never pushed) with HTTP 422 on `commits/:sha/pulls` —\n * empirically verified against a real unpushed worktree commit, not the 404\n * the endpoint's own docs imply. `gh api` surfaces the status in its stderr\n * as `(HTTP nnn)`. Both 404 and 422 here mean the same legitimate thing:\n * zero associated PRs, not \"the forge is unreachable\" — never guess step 5\n * on a genuinely empty, well-formed answer.\n */\nfunction isCommitNotFoundError(output: string): boolean {\n return /\\(HTTP (404|422)\\)/.test(output)\n}\n\n/** Runs `gh` in `repoRoot` so it auto-detects owner/repo from the `origin` remote there. */\nexport class GhCliForgeClient implements ForgeClient {\n constructor(private readonly repoRoot: string) {}\n\n private async runRaw(args: readonly string[]): Promise<{ exitCode: number; stdout: string; stderr: string }> {\n try {\n return await execArgv(\"gh\", args, this.repoRoot)\n } catch (err) {\n throw new ForgeUnavailableError(\n `gh ${args.join(\" \")} could not be run: ${err instanceof Error ? err.message : String(err)}`,\n { cause: err },\n )\n }\n }\n\n private async run(args: readonly string[]): Promise<string> {\n const result = await this.runRaw(args)\n if (result.exitCode !== 0) {\n throw new ForgeUnavailableError(\n `gh ${args.join(\" \")} failed (exit ${result.exitCode}): ${result.stderr.trim() || result.stdout.trim()}`,\n )\n }\n return result.stdout\n }\n\n private parseOutput<T>(stdout: string, schema: z.ZodType<T[]>, args: readonly string[]): T[] {\n let parsed: unknown\n try {\n parsed = JSON.parse(stdout)\n } catch (err) {\n throw new ForgeUnavailableError(\n `gh ${args.join(\" \")} produced non-JSON output: ${err instanceof Error ? err.message : String(err)}`,\n )\n }\n const result = schema.safeParse(parsed)\n if (!result.success) {\n throw new ForgeUnavailableError(`gh ${args.join(\" \")} output did not match the expected shape`)\n }\n return result.data\n }\n\n async pullRequestsForBranch(branch: string): Promise<ForgePullRequestRef[]> {\n const args = [\n \"pr\",\n \"list\",\n \"--head\",\n branch,\n \"--state\",\n \"all\",\n \"--json\",\n \"number,state,headRefName,headRefOid,mergedAt\",\n ]\n const stdout = await this.run(args)\n return this.parseOutput(stdout, ghPrListSchema, args).map(normalizeGhPrListItem)\n }\n\n async pullRequestsForCommit(sha: string): Promise<ForgePullRequestRef[]> {\n const args = [\"api\", `repos/{owner}/{repo}/commits/${sha}/pulls`]\n const result = await this.runRaw(args)\n if (result.exitCode !== 0) {\n if (isCommitNotFoundError(result.stderr) || isCommitNotFoundError(result.stdout)) return []\n throw new ForgeUnavailableError(\n `gh ${args.join(\" \")} failed (exit ${result.exitCode}): ${result.stderr.trim() || result.stdout.trim()}`,\n )\n }\n return this.parseOutput(result.stdout, ghApiCommitPullListSchema, args).map(normalizeGhApiCommitPull)\n }\n\n async listOpenPullRequests(): Promise<ForgePullRequestRef[]> {\n const args = [\"pr\", \"list\", \"--state\", \"open\", \"--limit\", \"1000\", \"--json\", \"number,state,headRefName,headRefOid,mergedAt\"]\n const stdout = await this.run(args)\n return this.parseOutput(stdout, ghPrListSchema, args).map(normalizeGhPrListItem)\n }\n\n async listMergedPullRequests(): Promise<ForgePullRequestRef[]> {\n const args = [\"pr\", \"list\", \"--state\", \"merged\", \"--limit\", \"1000\", \"--json\", \"number,state,headRefName,headRefOid,mergedAt\"]\n const stdout = await this.run(args)\n return this.parseOutput(stdout, ghPrListSchema, args).map(normalizeGhPrListItem)\n }\n\n async ensurePullHeadFetched(prNumber: number, oid: string): Promise<void> {\n const check = await execArgv(\"git\", [\"-C\", this.repoRoot, \"cat-file\", \"-e\", `${oid}^{commit}`], this.repoRoot)\n if (check.exitCode === 0) return\n const fetch = await execArgv(\n \"git\",\n [\"-C\", this.repoRoot, \"fetch\", \"origin\", `refs/pull/${prNumber}/head`],\n this.repoRoot,\n )\n if (fetch.exitCode !== 0) {\n throw new ForgeUnavailableError(\n `git fetch origin refs/pull/${prNumber}/head failed: ${fetch.stderr.trim() || fetch.stdout.trim()}`,\n )\n }\n }\n}\n\n// ── GITHUB_TOKEN REST fallback (no new npm dependency — global fetch) ───\n\nconst restPullRequestSchema = z.object({\n number: z.number(),\n state: z.string(),\n merged_at: z.string().nullable(),\n head: z.object({ ref: z.string(), sha: z.string() }),\n})\ntype RestPullRequest = z.infer<typeof restPullRequestSchema>\nconst restPullRequestListSchema = z.array(restPullRequestSchema)\n\nfunction normalizeRestPr(item: RestPullRequest): ForgePullRequestRef {\n return {\n number: item.number,\n state: item.state === \"open\" ? \"open\" : \"closed\",\n merged: item.merged_at !== null,\n mergedAt: item.merged_at,\n headRefName: item.head.ref,\n headRefOid: item.head.sha,\n }\n}\n\n/**\n * Parse `owner/repo` out of a `git remote get-url origin` value (ssh or https\n * form). The ssh form also accepts the multi-account `~/.ssh/config` alias\n * convention, `git@github.com-<alias>:owner/repo` (a `Host github.com-work`\n * entry that picks a key but still points at github.com), which is what a\n * machine juggling two GitHub identities has as its origin.\n */\nexport function parseGithubOwnerRepo(remoteUrl: string): { owner: string; repo: string } | null {\n const ssh = remoteUrl.match(/^git@github\\.com(?:-[\\w.-]+)?:([^/]+)\\/(.+?)(\\.git)?$/)\n if (ssh?.[1] && ssh[2]) return { owner: ssh[1], repo: ssh[2] }\n const https = remoteUrl.match(/^https:\\/\\/github\\.com\\/([^/]+)\\/(.+?)(\\.git)?\\/?$/)\n if (https?.[1] && https[2]) return { owner: https[1], repo: https[2] }\n return null\n}\n\nexport class RestForgeClient implements ForgeClient {\n constructor(\n private readonly owner: string,\n private readonly repo: string,\n private readonly repoRoot: string,\n private readonly token: string,\n private readonly fetchFn: typeof fetch = fetch,\n ) {}\n\n private headers(): Record<string, string> {\n return {\n Authorization: `Bearer ${this.token}`,\n Accept: \"application/vnd.github+json\",\n \"X-GitHub-Api-Version\": \"2022-11-28\",\n \"User-Agent\": \"agentproto-worktree-status\",\n }\n }\n\n private async get(path: string): Promise<Response> {\n try {\n return await this.fetchFn(`https://api.github.com${path}`, { headers: this.headers() })\n } catch (err) {\n throw new ForgeUnavailableError(\n `GitHub REST request to ${path} failed: ${err instanceof Error ? err.message : String(err)}`,\n { cause: err },\n )\n }\n }\n\n private async pullRequestList(res: Response): Promise<ForgePullRequestRef[]> {\n const body: unknown = await res.json()\n const result = restPullRequestListSchema.safeParse(body)\n if (!result.success) {\n throw new ForgeUnavailableError(`GitHub REST response did not match the expected PR list shape`)\n }\n return result.data.map(normalizeRestPr)\n }\n\n async pullRequestsForBranch(branch: string): Promise<ForgePullRequestRef[]> {\n const res = await this.get(\n `/repos/${this.owner}/${this.repo}/pulls?head=${this.owner}:${encodeURIComponent(branch)}&state=all&per_page=100`,\n )\n if (!res.ok) {\n throw new ForgeUnavailableError(`GitHub REST pulls?head= failed: ${res.status} ${res.statusText}`)\n }\n return this.pullRequestList(res)\n }\n\n async pullRequestsForCommit(sha: string): Promise<ForgePullRequestRef[]> {\n const res = await this.get(`/repos/${this.owner}/${this.repo}/commits/${sha}/pulls?per_page=100`)\n // 404 is what the endpoint's docs imply for an unknown commit; 422 is what\n // it empirically returns for one that was never pushed (verified live).\n // Both mean the same legitimate thing: zero associated PRs.\n if (res.status === 404 || res.status === 422) return []\n if (!res.ok) {\n throw new ForgeUnavailableError(`GitHub REST commits/:sha/pulls failed: ${res.status} ${res.statusText}`)\n }\n return this.pullRequestList(res)\n }\n\n async listOpenPullRequests(): Promise<ForgePullRequestRef[]> {\n const all: ForgePullRequestRef[] = []\n for (let page = 1; page <= 10; page++) {\n const res = await this.get(`/repos/${this.owner}/${this.repo}/pulls?state=open&per_page=100&page=${page}`)\n if (!res.ok) {\n throw new ForgeUnavailableError(`GitHub REST pulls?state=open failed: ${res.status} ${res.statusText}`)\n }\n const batch = await this.pullRequestList(res)\n all.push(...batch)\n if (batch.length < 100) break\n }\n return all\n }\n\n async listMergedPullRequests(): Promise<ForgePullRequestRef[]> {\n const all: ForgePullRequestRef[] = []\n for (let page = 1; page <= 10; page++) {\n const res = await this.get(`/repos/${this.owner}/${this.repo}/pulls?state=closed&per_page=100&page=${page}`)\n if (!res.ok) {\n throw new ForgeUnavailableError(`GitHub REST pulls?state=closed failed: ${res.status} ${res.statusText}`)\n }\n const batch = await this.pullRequestList(res)\n all.push(...batch)\n if (batch.length < 100) break\n }\n return all.filter((pr) => pr.merged)\n }\n\n async ensurePullHeadFetched(prNumber: number, oid: string): Promise<void> {\n const check = await execArgv(\"git\", [\"-C\", this.repoRoot, \"cat-file\", \"-e\", `${oid}^{commit}`], this.repoRoot)\n if (check.exitCode === 0) return\n const fetch2 = await execArgv(\n \"git\",\n [\"-C\", this.repoRoot, \"fetch\", \"origin\", `refs/pull/${prNumber}/head`],\n this.repoRoot,\n )\n if (fetch2.exitCode !== 0) {\n throw new ForgeUnavailableError(\n `git fetch origin refs/pull/${prNumber}/head failed: ${fetch2.stderr.trim() || fetch2.stdout.trim()}`,\n )\n }\n }\n}\n\n/**\n * Cheap \"is `gh` on PATH and authenticated\" probe — avoids a slow failure per\n * branch.\n *\n * Deliberately `gh auth token`, not `gh auth status`: `status` audits **every**\n * configured account and exits non-zero when *any* of them is broken, even\n * while the active credential works fine for real calls. A single stale keyring\n * entry for a second account is enough to make it exit 1 — and because a false\n * negative here lands on `UnreachableForgeClient`, every worktree's integration\n * silently degrades to `unknown(offline)` and `worktree gc` holds everything it\n * would otherwise reclaim. Observed exactly that: `gh auth status` exiting 1 on\n * a stale account while `gh pr list` and `gh api rate_limit` both answered\n * normally.\n *\n * `gh auth token` answers the question this probe actually asks — \"is gh on\n * PATH with a usable credential\" — and does it locally, with no network call.\n * It cannot prove the token is still valid server-side, but neither could\n * `status`: a token revoked upstream fails at call time either way, which is\n * exactly what `ForgeUnavailableError` and the memo/`unknown(offline)` fallback\n * already handle.\n */\nasync function ghIsUsable(repoRoot: string): Promise<boolean> {\n try {\n const res = await execArgv(\"gh\", [\"auth\", \"token\"], repoRoot)\n return res.exitCode === 0 && res.stdout.trim() !== \"\"\n } catch {\n return false\n }\n}\n\n/**\n * Pick the best available `ForgeClient` for `repoRoot`: `gh` CLI first (zero\n * config, inherits the caller's own auth), else `GITHUB_TOKEN` REST, else a\n * client that always reports unreachable — the reconciliation rule already\n * knows how to fall back from that (memo, else `unknown(offline)`).\n */\nexport async function createForgeClient(repoRoot: string): Promise<ForgeClient> {\n if (await ghIsUsable(repoRoot)) return new GhCliForgeClient(repoRoot)\n\n const token = process.env.GITHUB_TOKEN\n if (token) {\n const remote = await execArgv(\"git\", [\"-C\", repoRoot, \"remote\", \"get-url\", \"origin\"], repoRoot)\n const parsed = remote.exitCode === 0 ? parseGithubOwnerRepo(remote.stdout.trim()) : null\n if (parsed) return new RestForgeClient(parsed.owner, parsed.repo, repoRoot, token)\n }\n\n return new UnreachableForgeClient(\n \"no usable forge client: `gh` is not installed/authenticated and GITHUB_TOKEN is not set (or origin isn't a GitHub remote)\",\n )\n}\n","/**\n * `branch gc`: the sibling of worktree `gc` (`gc.ts`) for refs instead of\n * worktrees — local branches (`refs/heads`), the base remote's tracking\n * branches (`refs/remotes/<remote>`), and ORPHAN tracking refs\n * (`refs/remotes/<ns>/*` whose `<ns>` is no longer a configured remote, which\n * nothing — not even `fetch --prune` — ever cleans up). Same contract as\n * worktree `gc`:\n *\n * 1. `planBranchGc` is pure read: every ref is classified `reclaim` /\n * `review` / `hold` and nothing is mutated. A dry run IS \"call this,\n * print it, stop.\"\n * 2. `applyBranchGc` re-lists the refs and re-classifies every entry from\n * scratch immediately before touching it; a tip that moved, vanished or\n * now classifies differently is refused, never acted on.\n * 3. `hold` is never touched and `review` is never touched — only\n * `reclaim`. A reviewed-unmerged ref only becomes `reclaim` via\n * `includeReviewed` + a stored gate verdict that agreed for the SAME tip\n * sha; this module stores and reads verdicts, it never decides them.\n * 4. Every deletion is written to a restore log (sha + exact re-create\n * command) BEFORE the delete runs, so every apply is undoable.\n *\n * `reclaim` means \"the work is provably in base\", by a ladder of increasingly\n * expensive checks (`classifyTip`), ported from the audited\n * `branch-hygiene.mjs` maintenance script that first cleaned a 460-ref repo:\n *\n * pr-merged the tip IS the head commit (`headRefOid`) of a MERGED PR\n * — that exact commit was reviewed and merged, so nothing\n * was lost (forge shortcut in `classifyRef`: the ladder\n * still runs, but an \"unmerged\" verdict is overridden\n * before any reclaim/hold decision, skipping the\n * push-state/verdict lookups below it)\n * merged tip is an ancestor of base\n * squash-merged `git merge-tree --write-tree base tip` == base's tree\n * (merging it changes nothing)\n * patch-merged `git cherry` reports every commit as already applied —\n * ONLY tried when merge-tree conflicts (cherry patch-ids\n * every base commit since the merge-base: seconds per\n * branch on a busy base, and a clean merge with a\n * non-empty residual is unmerged regardless)\n * content-merged every path the branch changed is, BY BLOB, somewhere in\n * base's tree (any path — survives moves/reorgs) or\n * gitignored there, with zero `evolved` (same basename in\n * base, other content), zero `unique`, zero `deletes`\n *\n * Anything else is `unmerged` and — once older than `minAgeDays` and not\n * protected — becomes `review`, carrying everything a reviewer needs (coverage\n * summary, the files NOT provably in base, push state).\n */\n\nimport { spawn } from \"node:child_process\"\nimport { mkdir, readFile, rename, writeFile } from \"node:fs/promises\"\nimport { homedir } from \"node:os\"\nimport { dirname, join, resolve } from \"node:path\"\nimport { z } from \"zod\"\nimport { execArgv, type ExecResult } from \"./exec.js\"\nimport type { ForgeClient } from \"./forge.js\"\nimport { listGitWorktrees } from \"./status.js\"\n\n// ── types ────────────────────────────────────────────────────────────\n\nexport const BRANCH_GC_SCOPES = [\"local\", \"remote\", \"orphan\"] as const\n/** `local` = refs/heads, `remote` = the base remote's tracking refs, `orphan` = refs/remotes/<ns>/* of a remote that no longer exists. */\nexport type BranchRefKind = (typeof BRANCH_GC_SCOPES)[number]\n\n/** The verdict for one tip, in order of increasing cost (`pr-merged` is the forge shortcut that overrides an \"unmerged\" ladder verdict, not a check that skips the ladder). */\nexport type BranchStatus = \"pr-merged\" | \"merged\" | \"squash-merged\" | \"patch-merged\" | \"content-merged\" | \"unmerged\"\n\n/**\n * `current`: the tip shares history with base. `pre-rewrite`: it doesn't, but\n * base was re-rooted and an anchor (the old-history twin of base's root)\n * answers for it. `unrelated`: no shared history and no anchor — unmerged by\n * definition, since nothing can prove it landed.\n */\nexport type BranchHistory = \"current\" | \"pre-rewrite\" | \"unrelated\"\n\nexport type BranchGcClass = \"reclaim\" | \"review\" | \"hold\"\n\n/** Why a `reclaim` entry is reclaimable: one of the ladder's proven tiers, or a stored gate verdict (`includeReviewed`). */\nexport type BranchGcReclaimReason = Exclude<BranchStatus, \"unmerged\"> | \"reviewed\"\n\n/**\n * Why an entry is `hold`:\n * - `protected`: base or a well-known protected name (main, master, …)\n * - `worktree`: checked out in a worktree — the local branch AND its remote\n * twin (a live worktree may still push to it)\n * - `open-pr`: the head of an open PR\n * - `pr-check-unavailable`: open-PR detection could not run, so every\n * local/remote ref is held rather than silently losing that protection\n * - `young`: unmerged and younger than `minAgeDays`\n */\nexport type BranchGcHoldReason = \"protected\" | \"worktree\" | \"open-pr\" | \"pr-check-unavailable\" | \"young\"\n\n/**\n * Where else an unmerged tip lives — matters because deleting the only copy\n * lets `git gc` destroy the commits. Local refs: `same-tip-on-remote` /\n * `contained-in-remote` / `diverged-from-remote` / `local-only`. Orphan refs:\n * `contained-elsewhere` / `only-copy`.\n */\nexport type BranchPushState =\n | \"same-tip-on-remote\"\n | \"contained-in-remote\"\n | \"diverged-from-remote\"\n | \"local-only\"\n | \"contained-elsewhere\"\n | \"only-copy\"\n\n/**\n * Content coverage of everything the branch changed (merge-base..tip), file\n * by file, against base's CONTENT rather than its history:\n * covered the exact blob exists somewhere in base (moved or copied)\n * ignored gitignored in the repo (generated output)\n * evolved a same-named file exists in base with other content\n * unique no trace in base\n * deletes the branch deletes a path base still has (an unlanded intent)\n * evolved + unique + deletes == 0 → nothing but history is lost by deleting.\n */\nexport interface BranchCoverage {\n residual: number\n covered: number\n ignored: number\n evolved: number\n unique: number\n deletes: number\n}\n\nexport interface TipClassification {\n status: BranchStatus\n history: BranchHistory\n /** Commits on the tip not in the compare base; `null` for an unrelated tip. */\n ahead: number | null\n /** Commits in the compare base not on the tip; `null` when not computed. */\n behind: number | null\n /** Set once merge-tree ran: `true` when merging into base conflicts. */\n conflicts?: boolean\n /** Base, or the anchor for a pre-rewrite tip — what ancestry/cherry ran against. Set for `unmerged`. */\n compareBase?: string\n mergeBase?: string\n /** Tree of base-with-the-branch-merged, `null` when the merge conflicts. Set for `unmerged`. */\n mergedTree?: string | null\n coverage?: BranchCoverage\n /** The files a reviewer must look at: unique, then evolved, then deletes. Capped at 200. */\n residualFiles?: string[]\n residualFileCount?: number\n}\n\nexport interface BranchRef {\n kind: BranchRefKind\n /** Short name: `feat/x` for local/remote, `<ns>/feat/x` for an orphan. */\n name: string\n /** Full ref, e.g. `refs/remotes/origin/feat/x`. */\n ref: string\n sha: string\n /** Committer date of the tip, ISO-8601. */\n date: string\n author: string\n subject: string\n /** The remote a `remote`-kind ref belongs to. */\n remote?: string\n}\n\n/** Summary of a stored verdict for this exact tip, when one exists. */\nexport interface BranchVerdictSummary {\n triage: BranchTriageVerdict\n agree: boolean | null\n reviewer: string\n}\n\nexport interface BranchGcPlanEntry extends BranchRef, TipClassification {\n ageDays: number\n class: BranchGcClass\n reclaimReason?: BranchGcReclaimReason\n holdReason?: BranchGcHoldReason\n /** Human detail for a hold: the worktree path, `PR #n`, or why the PR check failed. */\n holdDetail?: string\n /** Set when the status is `pr-merged`: the number of the merged PR whose head commit IS this tip. */\n mergedPr?: number\n /** Set for unmerged local and orphan refs. */\n pushed?: BranchPushState\n verdict?: BranchVerdictSummary\n}\n\nexport interface BranchGcPlan {\n repoRoot: string\n repoName: string\n base: string\n baseSha: string\n baseTree: string\n /** The remote whose tracking refs are `remote`-kind — the base's own remote. `null` when base isn't a remote ref and there is no `origin`. */\n remote: string | null\n /** Old-history twin of base's root for a re-rooted base, else `null`. */\n anchor: string | null\n prCheck: { available: boolean; reason?: string }\n scopes: BranchRefKind[]\n minAgeDays: number\n includeReviewed: boolean\n generatedAt: string\n /** Refs of OTHER configured remotes: never classified, never touched. */\n otherRemoteRefs: number\n entries: BranchGcPlanEntry[]\n}\n\n// ── git plumbing ─────────────────────────────────────────────────────\n\nfunction git(repoRoot: string, args: readonly string[], env?: Record<string, string>): Promise<ExecResult> {\n return execArgv(\"git\", [\"-C\", repoRoot, ...args], repoRoot, env ? { env } : {})\n}\n\nasync function gitOk(repoRoot: string, args: readonly string[]): Promise<string> {\n const res = await git(repoRoot, args)\n if (res.exitCode !== 0) {\n throw new Error(`git ${args.join(\" \")} failed (exit ${res.exitCode}): ${res.stderr.trim() || res.stdout.trim()}`)\n }\n return res.stdout\n}\n\nasync function pool<T, R>(items: readonly T[], n: number, fn: (item: T) => Promise<R>): Promise<R[]> {\n const results = new Array<R>(items.length)\n let next = 0\n const worker = async (): Promise<void> => {\n while (next < items.length) {\n const i = next++\n results[i] = await fn(items[i] as T)\n }\n }\n await Promise.all(Array.from({ length: Math.min(n, items.length) }, worker))\n return results\n}\n\nfunction chunk<T>(items: readonly T[], size: number): T[][] {\n const out: T[][] = []\n for (let i = 0; i < items.length; i += size) out.push(items.slice(i, i + size))\n return out\n}\n\nconst basenameOf = (p: string): string => p.slice(p.lastIndexOf(\"/\") + 1)\n\n// ── the ladder ───────────────────────────────────────────────────────\n\n/** Base content index, built once per base: path→blob, every blob, every basename. */\nexport interface TreeIndex {\n byPath: Map<string, string>\n blobs: Set<string>\n names: Set<string>\n}\n\nasync function indexTree(repoRoot: string, sha: string): Promise<TreeIndex> {\n const byPath = new Map<string, string>()\n for (const rec of (await gitOk(repoRoot, [\"ls-tree\", \"-r\", \"-z\", sha])).split(\"\\0\")) {\n const tab = rec.indexOf(\"\\t\")\n if (tab < 0) continue\n const blob = rec.slice(0, tab).split(\" \")[2]\n if (blob) byPath.set(rec.slice(tab + 1), blob)\n }\n const names = new Set([...byPath.keys()].map(basenameOf))\n return { byPath, blobs: new Set(byPath.values()), names }\n}\n\nexport interface LadderContext {\n repoRoot: string\n baseSha: string\n baseTree: string\n anchor: string | null\n /** Built lazily: only content coverage needs it. */\n index: () => Promise<TreeIndex>\n /** Tip sha → \"shares history with `baseSha`\", when already known (the\n * plan's anchor detection asks the same question of every tip) — saves\n * the ladder's first `merge-base` per tip. */\n related?: ReadonlyMap<string, boolean>\n}\n\nexport async function createLadderContext(\n repoRoot: string,\n baseRef: string,\n anchor: string | null,\n related?: ReadonlyMap<string, boolean>,\n): Promise<LadderContext> {\n const baseSha = (await gitOk(repoRoot, [\"rev-parse\", \"--verify\", `${baseRef}^{commit}`])).trim()\n const baseTree = (await gitOk(repoRoot, [\"rev-parse\", `${baseSha}^{tree}`])).trim()\n let idx: Promise<TreeIndex> | null = null\n return {\n repoRoot,\n baseSha,\n baseTree,\n anchor,\n index: () => (idx ??= indexTree(repoRoot, baseSha)),\n ...(related ? { related } : {}),\n }\n}\n\n/** Does `tip` share history with `baseSha`? (`git merge-base` exits 0.) */\nasync function sharesHistory(repoRoot: string, baseSha: string, tip: string): Promise<boolean> {\n return (await git(repoRoot, [\"merge-base\", baseSha, tip])).exitCode === 0\n}\n\nconst NULL_SHA_RE = /^0+$/\n\n/** Per changed path (merge-base..tip, no rename detection): the tip's blob, or `null` when the tip deletes it. */\nasync function changedBlobs(repoRoot: string, mergeBase: string, tip: string): Promise<Map<string, string | null>> {\n const out = await gitOk(repoRoot, [\"diff\", \"--raw\", \"-z\", \"--no-abbrev\", \"--no-renames\", mergeBase, tip])\n const parts = out.split(\"\\0\")\n const changed = new Map<string, string | null>()\n for (let i = 0; i + 1 < parts.length; i += 2) {\n const meta = parts[i] ?? \"\"\n const path = parts[i + 1] ?? \"\"\n if (!meta.startsWith(\":\") || !path) continue\n const dst = meta.slice(1).split(\" \")[3] ?? \"\"\n changed.set(path, NULL_SHA_RE.test(dst) ? null : dst)\n }\n return changed\n}\n\n/** `git <args>` with `input` on stdin (`execArgv` has no stdin). */\nfunction gitWithInput(repoRoot: string, args: readonly string[], input: string): Promise<ExecResult> {\n return new Promise((resolvePromise, reject) => {\n const child = spawn(\"git\", [\"-C\", repoRoot, ...args], { cwd: repoRoot, stdio: [\"pipe\", \"pipe\", \"pipe\"] })\n let stdout = \"\"\n let stderr = \"\"\n child.stdout.on(\"data\", (d: Buffer) => (stdout += d.toString(\"utf8\")))\n child.stderr.on(\"data\", (d: Buffer) => (stderr += d.toString(\"utf8\")))\n child.on(\"error\", reject)\n child.on(\"close\", (code) => resolvePromise({ exitCode: code ?? -1, stdout, stderr }))\n child.stdin.end(input)\n })\n}\n\n/** `git check-ignore --no-index` over a path list (NUL-delimited both ways, so odd filenames survive). */\nasync function ignoredPaths(repoRoot: string, paths: readonly string[]): Promise<Set<string>> {\n const res = await gitWithInput(repoRoot, [\"check-ignore\", \"--no-index\", \"--stdin\", \"-z\"], paths.join(\"\\0\") + \"\\0\")\n // exit 1 = none of these are ignored — a valid answer, not an error.\n if (res.exitCode !== 0 && res.exitCode !== 1) return new Set()\n return new Set(res.stdout.split(\"\\0\").filter(Boolean))\n}\n\ninterface CoverageDetail extends BranchCoverage {\n evolvedFiles: string[]\n uniqueFiles: string[]\n deletedFiles: string[]\n}\n\nasync function coverage(ctx: LadderContext, tip: string, mergeBase: string): Promise<CoverageDetail> {\n const idx = await ctx.index()\n const changed = await changedBlobs(ctx.repoRoot, mergeBase, tip)\n const c: CoverageDetail = { residual: 0, covered: 0, ignored: 0, evolved: 0, unique: 0, deletes: 0, evolvedFiles: [], uniqueFiles: [], deletedFiles: [] }\n const pending: string[] = []\n for (const [p, tipBlob] of changed) {\n const baseBlob = idx.byPath.get(p) ?? null\n if (tipBlob === baseBlob) continue\n c.residual++\n if (tipBlob === null) c.deletedFiles.push(p)\n else if (idx.blobs.has(tipBlob)) c.covered++\n else pending.push(p)\n }\n const ignored = pending.length ? await ignoredPaths(ctx.repoRoot, pending) : new Set<string>()\n for (const p of pending) {\n if (ignored.has(p)) c.ignored++\n else if (idx.names.has(basenameOf(p))) c.evolvedFiles.push(p)\n else c.uniqueFiles.push(p)\n }\n c.evolved = c.evolvedFiles.length\n c.unique = c.uniqueFiles.length\n c.deletes = c.deletedFiles.length\n return c\n}\n\n/**\n * Run the ladder for one tip against `ctx`'s base. Pure read. A tip with no\n * history in common with base is checked against the anchor when there is one\n * (ancestry/cherry against the anchor; merge-tree with\n * `--merge-base=merge-base(anchor, tip)`), else it is `unmerged`/`unrelated`.\n */\nexport async function classifyTip(ctx: LadderContext, tip: string): Promise<TipClassification> {\n const { repoRoot, baseSha, baseTree, anchor } = ctx\n const related = ctx.related?.get(tip) ?? (await sharesHistory(repoRoot, baseSha, tip))\n if (!related && !anchor) return { status: \"unmerged\", history: \"unrelated\", conflicts: true, ahead: null, behind: null }\n const history: BranchHistory = related ? \"current\" : \"pre-rewrite\"\n const cmp = related ? baseSha : (anchor as string)\n\n if ((await git(repoRoot, [\"merge-base\", \"--is-ancestor\", tip, cmp])).exitCode === 0) {\n return { status: \"merged\", history, ahead: 0, behind: null }\n }\n const counts = (await gitOk(repoRoot, [\"rev-list\", \"--left-right\", \"--count\", `${cmp}...${tip}`])).trim().split(/\\s+/)\n const behind = Number(counts[0])\n const ahead = Number(counts[1])\n const mergeBase = (await git(repoRoot, [\"merge-base\", cmp, tip])).stdout.trim()\n const mtArgs = related ? [baseSha, tip] : [`--merge-base=${mergeBase}`, baseSha, tip]\n const mt = await git(repoRoot, [\"merge-tree\", \"--write-tree\", \"--no-messages\", ...mtArgs])\n const mergedTree = (mt.stdout.split(\"\\n\")[0] ?? \"\").trim()\n const conflicts = mt.exitCode !== 0\n if (!conflicts && mergedTree === baseTree) return { status: \"squash-merged\", history, ahead, behind, conflicts }\n if (conflicts) {\n const cherry = await gitOk(repoRoot, [\"cherry\", cmp, tip])\n if (!cherry.split(\"\\n\").some((l) => l.startsWith(\"+\"))) return { status: \"patch-merged\", history, ahead, behind, conflicts }\n }\n const cov = await coverage(ctx, tip, mergeBase)\n const summary: BranchCoverage = {\n residual: cov.residual,\n covered: cov.covered,\n ignored: cov.ignored,\n evolved: cov.evolved,\n unique: cov.unique,\n deletes: cov.deletes,\n }\n if (cov.evolved + cov.unique + cov.deletes === 0) {\n return { status: \"content-merged\", history, ahead, behind, conflicts, coverage: summary }\n }\n const residualFiles = [...cov.uniqueFiles, ...cov.evolvedFiles, ...cov.deletedFiles]\n return {\n status: \"unmerged\",\n history,\n ahead,\n behind,\n conflicts,\n compareBase: cmp,\n mergeBase,\n mergedTree: conflicts ? null : mergedTree,\n coverage: summary,\n residualFiles: residualFiles.slice(0, 200),\n residualFileCount: residualFiles.length,\n }\n}\n\n/** Per-(repo, base sha) ladder contexts for `classifyTipAgainstBase` — the base index is the expensive part and is shared. */\nconst contextCache = new Map<string, Promise<LadderContext>>()\n\n/**\n * One-shot ladder for a caller that has a single tip and no plan (worktree\n * `gc`'s content-merged promotion). No anchor: a pre-rewrite tip reads\n * `unrelated`/`unmerged` here, which only ever errs toward keeping.\n */\nexport async function classifyTipAgainstBase(repoRoot: string, baseRef: string, tip: string): Promise<TipClassification> {\n const baseSha = (await gitOk(repoRoot, [\"rev-parse\", \"--verify\", `${baseRef}^{commit}`])).trim()\n const key = `${repoRoot}\\u0000${baseSha}`\n let ctx = contextCache.get(key)\n if (!ctx) {\n ctx = createLadderContext(repoRoot, baseSha, null)\n contextCache.set(key, ctx)\n ctx.catch(() => contextCache.delete(key))\n }\n return classifyTip(await ctx, tip)\n}\n\n// ── re-rooted base: anchor detection ───────────────────────────────────\n\n/**\n * A re-rooted base (history rewritten into a fresh snapshot commit) shares no\n * ancestor with branches cut before the rewrite. The ANCHOR is the\n * old-history commit whose tree the snapshot was taken from: searched in the\n * unrelated tips' history within 3 days before the root's date, closest tree\n * to the root wins, accepted only when fewer than 200 files apart.\n */\nexport async function detectAnchor(\n repoRoot: string,\n baseSha: string,\n tips: readonly string[],\n /** Filled with every tip's answer (`true` = shares history with base) for\n * the ladder to reuse — see {@link LadderContext.related}. */\n related?: Map<string, boolean>,\n): Promise<string | null> {\n const roots = (await gitOk(repoRoot, [\"rev-list\", \"--max-parents=0\", baseSha])).trim().split(\"\\n\").filter(Boolean)\n if (roots.length !== 1) return null\n const root = roots[0] as string\n // One `merge-base` per unique tip — pure reads, so run them in parallel\n // (sequential, this alone was ~2 min of a ~900-ref plan).\n const unique = [...new Set(tips)]\n const shares = await pool(unique, 8, (sha) => sharesHistory(repoRoot, baseSha, sha))\n const unrelated = unique.filter((_, i) => !shares[i])\n if (related) unique.forEach((sha, i) => related.set(sha, shares[i] as boolean))\n if (!unrelated.length) return null\n const rootDate = (await gitOk(repoRoot, [\"log\", \"-1\", \"--format=%cI\", root])).trim()\n const since = new Date(new Date(rootDate).getTime() - 3 * 86_400_000).toISOString()\n const cands = (await gitOk(repoRoot, [\"log\", \"--format=%H\", `--since=${since}`, `--until=${rootDate}`, ...unrelated]))\n .trim()\n .split(\"\\n\")\n .filter(Boolean)\n .slice(0, 60)\n let best: { sha: string; n: number } | null = null\n for (const c of cands) {\n const n = (await gitOk(repoRoot, [\"diff\", \"--numstat\", c, root])).trim().split(\"\\n\").filter(Boolean).length\n if (!best || n < best.n) best = { sha: c, n }\n }\n return best && best.n < 200 ? best.sha : null\n}\n\n// ── ref discovery ────────────────────────────────────────────────────\n\nconst PROTECTED_NAMES = new Set([\"main\", \"master\", \"develop\", \"HEAD\", \"gh-pages\"])\n\nasync function configuredRemotes(repoRoot: string): Promise<Set<string>> {\n return new Set((await gitOk(repoRoot, [\"remote\"])).trim().split(\"\\n\").filter(Boolean))\n}\n\n/** The remote whose tracking refs are `remote`-kind: base's own remote when base is `<remote>/…`, else `origin` if configured. */\nfunction baseRemoteOf(base: string, remotes: ReadonlySet<string>): string | null {\n const slash = base.indexOf(\"/\")\n if (slash > 0 && remotes.has(base.slice(0, slash))) return base.slice(0, slash)\n return remotes.has(\"origin\") ? \"origin\" : null\n}\n\ninterface RefListing {\n refs: BranchRef[]\n otherRemoteRefs: number\n}\n\nasync function listBranchRefs(repoRoot: string, remote: string | null, remotes: ReadonlySet<string>): Promise<RefListing> {\n const fmt = \"%(refname)%09%(objectname)%09%(committerdate:iso-strict)%09%(authorname)%09%(subject)\"\n const out = await gitOk(repoRoot, [\"for-each-ref\", `--format=${fmt}`, \"refs/heads\", \"refs/remotes\"])\n const refs: BranchRef[] = []\n let otherRemoteRefs = 0\n for (const line of out.split(\"\\n\")) {\n if (!line) continue\n const [ref = \"\", sha = \"\", date = \"\", author = \"\", ...subj] = line.split(\"\\t\")\n const rest = { ref, sha, date, author, subject: subj.join(\"\\t\") }\n let entry: BranchRef\n if (ref.startsWith(\"refs/heads/\")) {\n entry = { kind: \"local\", name: ref.slice(\"refs/heads/\".length), ...rest }\n } else {\n const ns = ref.split(\"/\")[2] ?? \"\"\n if (remote && ns === remote) {\n entry = { kind: \"remote\", name: ref.slice(`refs/remotes/${remote}/`.length), remote, ...rest }\n } else if (remotes.has(ns)) {\n otherRemoteRefs++\n continue\n } else {\n entry = { kind: \"orphan\", name: ref.slice(\"refs/remotes/\".length), ...rest }\n }\n }\n if (entry.name === \"HEAD\" || entry.name.endsWith(\"/HEAD\")) continue\n refs.push(entry)\n }\n return { refs, otherRemoteRefs }\n}\n\n/** branch name → worktree path, for every worktree (main checkout included — its branch is live too). */\nasync function worktreeBranches(repoRoot: string): Promise<Map<string, string>> {\n const map = new Map<string, string>()\n for (const w of await listGitWorktrees(repoRoot)) if (w.branch) map.set(w.branch, w.path)\n return map\n}\n\ninterface OpenPrHeads {\n available: boolean\n reason?: string\n heads: Map<string, number>\n}\n\nasync function openPrHeads(forge: ForgeClient | undefined): Promise<OpenPrHeads> {\n if (!forge) return { available: false, reason: \"no forge client\", heads: new Map() }\n if (!forge.listOpenPullRequests) {\n return { available: false, reason: \"forge client cannot list open PRs\", heads: new Map() }\n }\n try {\n const prs = await forge.listOpenPullRequests()\n const heads = new Map<string, number>()\n for (const pr of prs) if (pr.state === \"open\") heads.set(pr.headRefName, pr.number)\n return { available: true, heads }\n } catch (err) {\n const reason = (err instanceof Error ? err.message : String(err)).split(\"\\n\")[0] ?? \"forge error\"\n return { available: false, reason, heads: new Map() }\n }\n}\n\n/**\n * Merged PR head sha → PR number, for the `pr-merged` shortcut. On any error\n * or a forge without `listMergedPullRequests` this returns an empty map —\n * never throws: unavailable just means \"no shortcut\", not \"no merged PRs\",\n * and the ladder still classifies every ref on its own.\n */\nasync function mergedPrHeads(forge: ForgeClient | undefined): Promise<Map<string, number>> {\n if (!forge?.listMergedPullRequests) return new Map()\n try {\n const heads = new Map<string, number>()\n for (const pr of await forge.listMergedPullRequests()) heads.set(pr.headRefOid, pr.number)\n return heads\n } catch {\n return new Map()\n }\n}\n\n// ── classification of one ref ──────────────────────────────────────────\n\ninterface ClassifyEnv {\n ctx: LadderContext\n /** The ladder is a pure function of (ctx, tip sha): run it once per tip,\n * not once per ref — a local branch and its remote twin share one. */\n tips: Map<string, Promise<TipClassification>>\n remote: string | null\n baseName: string\n worktrees: Map<string, string>\n prs: OpenPrHeads\n /** Merged PR head sha → PR number (`pr-merged` shortcut). Empty = no shortcut available. */\n mergedPrShas: Map<string, number>\n remoteShas: Set<string>\n remoteNames: Set<string>\n minAgeDays: number\n includeReviewed: boolean\n verdicts?: BranchVerdictStore\n repoName: string\n nowMs: number\n}\n\nfunction holdFor(b: BranchRef, env: ClassifyEnv): { holdReason: BranchGcHoldReason; holdDetail?: string } | null {\n if (b.kind === \"orphan\") return null\n if (PROTECTED_NAMES.has(b.name) || b.name === env.baseName) return { holdReason: \"protected\" }\n const wt = env.worktrees.get(b.name)\n if (wt) return { holdReason: \"worktree\", holdDetail: wt }\n const pr = env.prs.heads.get(b.name)\n if (pr !== undefined) return { holdReason: \"open-pr\", holdDetail: `PR #${pr}` }\n if (!env.prs.available) return { holdReason: \"pr-check-unavailable\", holdDetail: env.prs.reason }\n return null\n}\n\nasync function pushStateOf(b: BranchRef, env: ClassifyEnv): Promise<BranchPushState | undefined> {\n const { repoRoot } = env.ctx\n if (b.kind === \"local\") {\n if (env.remoteShas.has(b.sha)) return \"same-tip-on-remote\"\n if (env.remote) {\n const contained = await git(repoRoot, [\"for-each-ref\", \"--contains\", b.sha, \"--format=x\", `refs/remotes/${env.remote}`])\n if (contained.stdout.trim()) return \"contained-in-remote\"\n }\n return env.remoteNames.has(b.name) ? \"diverged-from-remote\" : \"local-only\"\n }\n if (b.kind === \"orphan\") {\n const scopes = [\"refs/heads\", ...(env.remote ? [`refs/remotes/${env.remote}`] : [])]\n const contained = await git(repoRoot, [\"for-each-ref\", \"--contains\", b.sha, \"--format=x\", ...scopes])\n return contained.stdout.trim() ? \"contained-elsewhere\" : \"only-copy\"\n }\n return undefined\n}\n\nasync function classifyRef(b: BranchRef, env: ClassifyEnv): Promise<BranchGcPlanEntry> {\n let pending = env.tips.get(b.sha)\n if (!pending) {\n pending = classifyTip(env.ctx, b.sha)\n env.tips.set(b.sha, pending)\n }\n const tip = await pending\n const ageDays = Math.floor((env.nowMs - new Date(b.date).getTime()) / 86_400_000)\n const entry: BranchGcPlanEntry = { ...b, ...tip, ageDays, class: \"hold\" }\n // Merged-head shortcut: an \"unmerged\" tip that is EXACTLY the head commit of\n // a MERGED PR lost nothing — that commit was reviewed and merged. Override\n // the ladder's verdict (and skip its push-state/verdict work below) before\n // any reclaim/hold decision; holds further down still win.\n if (tip.status === \"unmerged\" && env.mergedPrShas.has(b.sha)) {\n const pr = env.mergedPrShas.get(b.sha) as number\n entry.status = \"pr-merged\"\n entry.mergedPr = pr\n }\n if (entry.status === \"unmerged\") {\n const pushed = await pushStateOf(b, env)\n if (pushed) entry.pushed = pushed\n const stored = env.verdicts ? await env.verdicts.get(env.repoName, b.sha) : null\n if (stored) {\n entry.verdict = { triage: stored.triage.verdict, agree: stored.gate ? stored.gate.agree : null, reviewer: stored.reviewer }\n }\n }\n const hold = holdFor(b, env)\n if (hold) {\n entry.holdReason = hold.holdReason\n if (hold.holdDetail) entry.holdDetail = hold.holdDetail\n return entry\n }\n if (entry.status !== \"unmerged\") {\n entry.class = \"reclaim\"\n entry.reclaimReason = entry.status\n return entry\n }\n if (ageDays < env.minAgeDays) {\n entry.holdReason = \"young\"\n entry.holdDetail = `${ageDays}d < ${env.minAgeDays}d`\n return entry\n }\n if (env.includeReviewed && entry.verdict?.agree === true) {\n entry.class = \"reclaim\"\n entry.reclaimReason = \"reviewed\"\n return entry\n }\n entry.class = \"review\"\n return entry\n}\n\ninterface Snapshot {\n env: ClassifyEnv\n refs: BranchRef[]\n otherRemoteRefs: number\n}\n\nasync function snapshot(input: {\n repoRoot: string\n repoName: string\n base: string\n anchor: string | null | \"auto\"\n forge?: ForgeClient\n verdicts?: BranchVerdictStore\n minAgeDays: number\n includeReviewed: boolean\n nowMs: number\n}): Promise<Snapshot> {\n const remotes = await configuredRemotes(input.repoRoot)\n const remote = baseRemoteOf(input.base, remotes)\n const [{ refs, otherRemoteRefs }, worktrees, prs, mergedPrs] = await Promise.all([\n listBranchRefs(input.repoRoot, remote, remotes),\n worktreeBranches(input.repoRoot),\n openPrHeads(input.forge),\n mergedPrHeads(input.forge),\n ])\n const baseSha = (await gitOk(input.repoRoot, [\"rev-parse\", \"--verify\", `${input.base}^{commit}`])).trim()\n let anchor: string | null\n const related = new Map<string, boolean>()\n if (input.anchor === \"auto\") anchor = await detectAnchor(input.repoRoot, baseSha, refs.map((r) => r.sha), related)\n else if (input.anchor) anchor = (await gitOk(input.repoRoot, [\"rev-parse\", \"--verify\", `${input.anchor}^{commit}`])).trim()\n else anchor = null\n const ctx = await createLadderContext(input.repoRoot, baseSha, anchor, related)\n const remoteRefs = refs.filter((r) => r.kind === \"remote\")\n return {\n refs,\n otherRemoteRefs,\n env: {\n ctx,\n tips: new Map(),\n remote,\n baseName: remote && input.base.startsWith(`${remote}/`) ? input.base.slice(remote.length + 1) : input.base,\n worktrees,\n prs,\n mergedPrShas: mergedPrs,\n remoteShas: new Set(remoteRefs.map((r) => r.sha)),\n remoteNames: new Set(remoteRefs.map((r) => r.name)),\n minAgeDays: input.minAgeDays,\n includeReviewed: input.includeReviewed,\n ...(input.verdicts ? { verdicts: input.verdicts } : {}),\n repoName: input.repoName,\n nowMs: input.nowMs,\n },\n }\n}\n\n// ── plan ─────────────────────────────────────────────────────────────\n\nexport const DEFAULT_BRANCH_GC_MIN_AGE_DAYS = 3\n\nexport interface PlanBranchGcInput {\n repoRoot: string\n repoName: string\n /** Default `origin/main`. */\n base?: string\n /** Subset of kinds to classify. Default all three. */\n scopes?: readonly BranchRefKind[]\n /** Unmerged refs younger than this are `hold`. Default 3. */\n minAgeDays?: number\n /** Promote a `review` ref whose stored verdict agreed for the same tip sha to `reclaim` (`reviewed`). Default false. */\n includeReviewed?: boolean\n /** Explicit anchor for a re-rooted base. Omitted → auto-detected. */\n anchor?: string\n /** Open-PR detection (`listOpenPullRequests`). Omitted or unable → every local/remote ref is `hold` (`pr-check-unavailable`). */\n forge?: ForgeClient\n verdicts?: BranchVerdictStore\n /** Clock for `ageDays`. Default `Date.now()`. */\n nowMs?: number\n /** Parallel ladder runs. Default 8. */\n concurrency?: number\n}\n\nfunction normalizeScopes(scopes: readonly BranchRefKind[] | undefined): BranchRefKind[] {\n if (!scopes || scopes.length === 0) return [...BRANCH_GC_SCOPES]\n for (const s of scopes) {\n if (!(BRANCH_GC_SCOPES as readonly string[]).includes(s)) {\n throw new Error(`branch gc: unknown scope \"${s}\" (expected ${BRANCH_GC_SCOPES.join(\", \")})`)\n }\n }\n return BRANCH_GC_SCOPES.filter((s) => scopes.includes(s))\n}\n\n/** The dry-run plan: classify every ref in `scopes`, mutate nothing. */\nexport async function planBranchGc(input: PlanBranchGcInput): Promise<BranchGcPlan> {\n const base = input.base ?? \"origin/main\"\n const scopes = normalizeScopes(input.scopes)\n const minAgeDays = input.minAgeDays ?? DEFAULT_BRANCH_GC_MIN_AGE_DAYS\n const includeReviewed = Boolean(input.includeReviewed)\n const nowMs = input.nowMs ?? Date.now()\n const snap = await snapshot({\n repoRoot: input.repoRoot,\n repoName: input.repoName,\n base,\n anchor: input.anchor ?? \"auto\",\n ...(input.forge ? { forge: input.forge } : {}),\n ...(input.verdicts ? { verdicts: input.verdicts } : {}),\n minAgeDays,\n includeReviewed,\n nowMs,\n })\n const inScope = snap.refs.filter((r) => scopes.includes(r.kind))\n const entries = await pool(inScope, input.concurrency ?? 8, (r) => classifyRef(r, snap.env))\n return {\n repoRoot: input.repoRoot,\n repoName: input.repoName,\n base,\n baseSha: snap.env.ctx.baseSha,\n baseTree: snap.env.ctx.baseTree,\n remote: snap.env.remote,\n anchor: snap.env.ctx.anchor,\n prCheck: snap.env.prs.available ? { available: true } : { available: false, ...(snap.env.prs.reason ? { reason: snap.env.prs.reason } : {}) },\n scopes,\n minAgeDays,\n includeReviewed,\n generatedAt: new Date(nowMs).toISOString(),\n otherRemoteRefs: snap.otherRemoteRefs,\n entries,\n }\n}\n\nexport interface BranchGcSummary {\n /** kind → class → count. */\n byClass: Record<BranchRefKind, Record<BranchGcClass, number>>\n /**\n * kind → (status | \"protected\") → count, where \"protected\" = held for\n * base/protected, worktree, or open PR. Same buckets as the reference\n * script's audit summary, so the two can be compared line for line.\n */\n byStatus: Record<BranchRefKind, Record<string, number>>\n}\n\nexport function summarizeBranchGcPlan(plan: BranchGcPlan): BranchGcSummary {\n const byClass = {} as BranchGcSummary[\"byClass\"]\n const byStatus = {} as BranchGcSummary[\"byStatus\"]\n for (const k of BRANCH_GC_SCOPES) {\n byClass[k] = { reclaim: 0, review: 0, hold: 0 }\n byStatus[k] = {}\n }\n for (const e of plan.entries) {\n byClass[e.kind][e.class]++\n const isProtected = e.holdReason === \"protected\" || e.holdReason === \"worktree\" || e.holdReason === \"open-pr\"\n const key = isProtected ? \"protected\" : e.status\n byStatus[e.kind][key] = (byStatus[e.kind][key] ?? 0) + 1\n }\n return { byClass, byStatus }\n}\n\n// ── review queue ──────────────────────────────────────────────────────\n\nexport interface BranchReviewCandidate {\n name: string\n kind: BranchRefKind\n sha: string\n ageDays: number\n author: string\n subject: string\n history: BranchHistory\n /** Base sha. */\n base: string\n compareBase?: string\n mergeBase?: string\n mergedTree?: string | null\n conflicts?: boolean\n ahead: number | null\n behind: number | null\n pushed?: BranchPushState\n coverage?: BranchCoverage\n residualFiles?: string[]\n residualFileCount?: number\n /** Every ref sharing this tip (a local branch and its remote twin share one review). */\n refs: string[]\n verdict?: BranchVerdictSummary\n}\n\nexport interface BranchReviewQueue {\n base: string\n baseSha: string\n anchor: string | null\n candidates: BranchReviewCandidate[]\n}\n\n/**\n * The `review` entries of a plan, one per unique tip sha, with everything a\n * reviewer needs. Tips that already carry a stored verdict are skipped unless\n * `all` — verdicts are keyed by sha, so only tips that moved get re-reviewed.\n */\nexport function branchReviewQueue(plan: BranchGcPlan, options: { all?: boolean } = {}): BranchReviewQueue {\n const bySha = new Map<string, BranchReviewCandidate>()\n for (const e of plan.entries) {\n if (e.class !== \"review\") continue\n if (e.verdict && !options.all) continue\n const seen = bySha.get(e.sha)\n if (seen) {\n seen.refs.push(e.ref)\n continue\n }\n bySha.set(e.sha, {\n name: e.name,\n kind: e.kind,\n sha: e.sha,\n ageDays: e.ageDays,\n author: e.author,\n subject: e.subject,\n history: e.history,\n base: plan.baseSha,\n ...(e.compareBase ? { compareBase: e.compareBase } : {}),\n ...(e.mergeBase ? { mergeBase: e.mergeBase } : {}),\n mergedTree: e.mergedTree ?? null,\n ...(e.conflicts !== undefined ? { conflicts: e.conflicts } : {}),\n ahead: e.ahead,\n behind: e.behind,\n ...(e.pushed ? { pushed: e.pushed } : {}),\n ...(e.coverage ? { coverage: e.coverage } : {}),\n ...(e.residualFiles ? { residualFiles: e.residualFiles } : {}),\n ...(e.residualFileCount !== undefined ? { residualFileCount: e.residualFileCount } : {}),\n refs: [e.ref],\n ...(e.verdict ? { verdict: e.verdict } : {}),\n })\n }\n return { base: plan.base, baseSha: plan.baseSha, anchor: plan.anchor, candidates: [...bySha.values()] }\n}\n\n// ── apply ────────────────────────────────────────────────────────────\n\nexport type BranchGcApplyOutcome =\n | { kind: BranchRefKind; name: string; sha: string; result: \"deleted\"; reclaimReason: BranchGcReclaimReason }\n | { kind: BranchRefKind; name: string; sha: string; result: \"held\"; holdReason?: BranchGcHoldReason }\n /** `review` class: never touched by apply — the review/approval path decides these. */\n | { kind: BranchRefKind; name: string; sha: string; result: \"skipped-review\" }\n /** The ref now points somewhere else than the plan saw — never delete what wasn't classified. */\n | { kind: BranchRefKind; name: string; sha: string; result: \"aborted-moved\"; currentSha: string }\n /** The ref no longer exists. */\n | { kind: BranchRefKind; name: string; sha: string; result: \"aborted-vanished\" }\n /** Re-classified from scratch and no longer `reclaim`. */\n | { kind: BranchRefKind; name: string; sha: string; result: \"aborted-reclassified\"; from: BranchGcClass; to: BranchGcClass; holdReason?: BranchGcHoldReason }\n | { kind: BranchRefKind; name: string; sha: string; result: \"failed\"; message: string }\n\nexport interface ApplyBranchGcOptions {\n /** REQUIRED and non-empty: which kinds apply may delete. Entries of other kinds are left out of the outcomes. */\n scopes: readonly BranchRefKind[]\n forge?: ForgeClient\n verdicts?: BranchVerdictStore\n /** Where restore logs go. Default `~/.agentproto/branch-gc`. */\n stateDir?: string\n nowMs?: number\n /** Remote refs per `git push --delete`. Default 50. */\n remoteBatchSize?: number\n}\n\nexport interface BranchGcApplyResult {\n outcomes: BranchGcApplyOutcome[]\n /** Restore log for this run, `null` when nothing was deleted. */\n restoreLog: string | null\n}\n\nexport const BRANCH_GC_STATE_DIR = (): string => resolve(homedir(), \".agentproto\", \"branch-gc\")\n\nexport interface BranchGcRestoreEntry {\n kind: BranchRefKind\n name: string\n ref: string\n sha: string\n remote?: string\n /** git arguments (no leading `git`) that re-create the ref, run with `-C repoRoot`. */\n argv: string[]\n /** The same, as a copy-pasteable shell command. */\n command: string\n /** Set once the delete ran. */\n deleted?: boolean\n}\n\nexport interface BranchGcRestoreLog {\n schema: \"branch-gc-restore/v1\"\n repoRoot: string\n base: string\n baseSha: string\n createdAt: string\n entries: BranchGcRestoreEntry[]\n}\n\nconst shellQuote = (s: string): string => (/^[\\w@%+=:,./-]+$/.test(s) ? s : `'${s.replace(/'/g, `'\\\\''`)}'`)\n\nfunction restoreEntry(repoRoot: string, e: BranchGcPlanEntry): BranchGcRestoreEntry {\n const argv =\n e.kind === \"local\"\n ? [\"branch\", e.name, e.sha]\n : e.kind === \"remote\"\n ? [\"push\", e.remote as string, `${e.sha}:refs/heads/${e.name}`]\n : [\"update-ref\", e.ref, e.sha]\n return {\n kind: e.kind,\n name: e.name,\n ref: e.ref,\n sha: e.sha,\n ...(e.remote ? { remote: e.remote } : {}),\n argv,\n command: [\"git\", \"-C\", repoRoot, ...argv].map(shellQuote).join(\" \"),\n }\n}\n\nasync function writeJsonAtomic(path: string, value: unknown): Promise<void> {\n await mkdir(dirname(path), { recursive: true })\n const tmp = `${path}.${process.pid}.tmp`\n await writeFile(tmp, JSON.stringify(value, null, 2) + \"\\n\", \"utf8\")\n await rename(tmp, path)\n}\n\n/**\n * Execute a plan. Only `reclaim` entries whose kind is in `options.scopes`\n * are touched, and each is first re-derived from scratch: the ref is\n * re-listed (moved → `aborted-moved`, gone → `aborted-vanished`) and fully\n * re-classified against fresh worktree / open-PR / verdict state (anything but\n * `reclaim` → `aborted-reclassified`). The restore log is written before the\n * first delete runs.\n */\nexport async function applyBranchGc(plan: BranchGcPlan, options: ApplyBranchGcOptions): Promise<BranchGcApplyResult> {\n if (!options.scopes || options.scopes.length === 0) {\n throw new Error(\"branch gc apply: `scopes` is required (any of local, remote, orphan) — apply never defaults to every kind\")\n }\n const scopes = normalizeScopes(options.scopes)\n const { repoRoot } = plan\n const snap = await snapshot({\n repoRoot,\n repoName: plan.repoName,\n base: plan.base,\n anchor: plan.anchor,\n ...(options.forge ? { forge: options.forge } : {}),\n ...(options.verdicts ? { verdicts: options.verdicts } : {}),\n minAgeDays: plan.minAgeDays,\n includeReviewed: plan.includeReviewed,\n nowMs: options.nowMs ?? Date.now(),\n })\n const current = new Map(snap.refs.map((r) => [r.ref, r]))\n\n const outcomes: BranchGcApplyOutcome[] = []\n const confirmed: BranchGcPlanEntry[] = []\n for (const e of plan.entries) {\n if (!scopes.includes(e.kind)) continue\n const id = { kind: e.kind, name: e.name, sha: e.sha }\n if (e.class === \"hold\") {\n outcomes.push({ ...id, result: \"held\", ...(e.holdReason ? { holdReason: e.holdReason } : {}) })\n continue\n }\n if (e.class === \"review\") {\n outcomes.push({ ...id, result: \"skipped-review\" })\n continue\n }\n const fresh = current.get(e.ref)\n if (!fresh) {\n outcomes.push({ ...id, result: \"aborted-vanished\" })\n continue\n }\n if (fresh.sha !== e.sha) {\n outcomes.push({ ...id, result: \"aborted-moved\", currentSha: fresh.sha })\n continue\n }\n const now = await classifyRef(fresh, snap.env)\n if (now.class !== \"reclaim\") {\n outcomes.push({\n ...id,\n result: \"aborted-reclassified\",\n from: e.class,\n to: now.class,\n ...(now.holdReason ? { holdReason: now.holdReason } : {}),\n })\n continue\n }\n confirmed.push(now)\n }\n if (confirmed.length === 0) return { outcomes, restoreLog: null }\n\n const createdAt = new Date().toISOString()\n const log: BranchGcRestoreLog = {\n schema: \"branch-gc-restore/v1\",\n repoRoot,\n base: plan.base,\n baseSha: snap.env.ctx.baseSha,\n createdAt,\n entries: confirmed.map((e) => restoreEntry(repoRoot, e)),\n }\n const logPath = join(options.stateDir ?? BRANCH_GC_STATE_DIR(), plan.repoName, `restore-${createdAt.replace(/[:.]/g, \"-\")}.json`)\n await writeJsonAtomic(logPath, log)\n\n const results = new Map<string, { ok: true } | { ok: false; message: string }>()\n const fail = (res: ExecResult): { ok: false; message: string } => ({ ok: false, message: (res.stderr || res.stdout).trim() || `exit ${res.exitCode}` })\n\n for (const e of confirmed.filter((c) => c.kind === \"local\")) {\n const res = await git(repoRoot, [\"branch\", \"-D\", e.name])\n results.set(e.ref, res.exitCode === 0 ? { ok: true } : fail(res))\n }\n const remoteEntries = confirmed.filter((c) => c.kind === \"remote\")\n const byRemote = new Map<string, BranchGcPlanEntry[]>()\n for (const e of remoteEntries) byRemote.set(e.remote as string, [...(byRemote.get(e.remote as string) ?? []), e])\n for (const [remote, list] of byRemote) {\n const failedBatches: Array<{ batch: BranchGcPlanEntry[]; res: ExecResult }> = []\n for (const batch of chunk(list, options.remoteBatchSize ?? 50)) {\n const res = await git(repoRoot, [\"push\", remote, \"--delete\", ...batch.map((e) => e.name)])\n if (res.exitCode === 0) for (const e of batch) results.set(e.ref, { ok: true })\n else failedBatches.push({ batch, res })\n }\n // `push --delete` did not reliably drop the local tracking refs in practice.\n await git(repoRoot, [\"fetch\", \"--prune\", \"--quiet\", remote])\n // A non-atomic push deletes what it can and exits non-zero for the rest\n // (e.g. one branch already gone upstream): judge each ref by whether its\n // tracking ref survived the prune, not by the batch's exit code.\n // git can also refuse the whole batch client-side over one bad ref, so\n // anything still present is retried on its own before being reported.\n let retried = false\n for (const { batch } of failedBatches) {\n for (const e of batch) {\n if ((await git(repoRoot, [\"rev-parse\", \"--verify\", \"--quiet\", e.ref])).exitCode !== 0) {\n results.set(e.ref, { ok: true })\n continue\n }\n const one = await git(repoRoot, [\"push\", remote, \"--delete\", e.name])\n results.set(e.ref, one.exitCode === 0 ? { ok: true } : fail(one))\n retried = true\n }\n }\n if (retried) await git(repoRoot, [\"fetch\", \"--prune\", \"--quiet\", remote])\n }\n for (const e of confirmed.filter((c) => c.kind === \"orphan\")) {\n const res = await git(repoRoot, [\"update-ref\", \"-d\", e.ref, e.sha])\n results.set(e.ref, res.exitCode === 0 ? { ok: true } : fail(res))\n }\n\n for (const entry of log.entries) entry.deleted = results.get(entry.ref)?.ok === true\n await writeJsonAtomic(logPath, log)\n\n for (const e of confirmed) {\n const r = results.get(e.ref)\n const id = { kind: e.kind, name: e.name, sha: e.sha }\n if (r?.ok) outcomes.push({ ...id, result: \"deleted\", reclaimReason: e.reclaimReason as BranchGcReclaimReason })\n else outcomes.push({ ...id, result: \"failed\", message: r && !r.ok ? r.message : \"not attempted\" })\n }\n return { outcomes, restoreLog: logPath }\n}\n\n/** Read a restore log written by `applyBranchGc`. */\nexport async function readBranchGcRestoreLog(path: string): Promise<BranchGcRestoreLog> {\n return JSON.parse(await readFile(path, \"utf8\")) as BranchGcRestoreLog\n}\n\n// ── verdict store ────────────────────────────────────────────────────\n\nexport const BRANCH_TRIAGE_VERDICTS = [\"obsolete\", \"superseded\", \"salvage\", \"in-progress\", \"unclear\"] as const\nexport type BranchTriageVerdict = (typeof BRANCH_TRIAGE_VERDICTS)[number]\n\n/**\n * One reviewer verdict for one branch tip. `gate` is the second opinion that\n * actually licenses deletion (`agree: true`); a triage-only verdict (no\n * `gate`) records the review but never makes a ref reclaimable. An agreeing\n * gate must cite evidence.\n */\nexport const branchVerdictSchema = z\n .object({\n name: z.string().min(1),\n sha: z.string().regex(/^[0-9a-f]{40}(?:[0-9a-f]{24})?$/, \"sha must be a full 40- or 64-char lowercase hex object id\"),\n triage: z.object({\n verdict: z.enum(BRANCH_TRIAGE_VERDICTS),\n confidence: z.number().min(0).max(1),\n reason: z.string().min(1),\n salvage: z.string().optional(),\n }),\n gate: z\n .object({\n agree: z.boolean(),\n verdict: z.enum(BRANCH_TRIAGE_VERDICTS),\n reason: z.string().min(1),\n evidence: z.array(z.string().min(1)),\n })\n .optional(),\n reviewer: z.string().min(1),\n })\n .superRefine((v, ctx) => {\n if (v.gate?.agree && v.gate.evidence.length === 0) {\n ctx.addIssue({ code: \"custom\", path: [\"gate\", \"evidence\"], message: \"gate.agree=true requires at least one evidence entry\" })\n }\n })\n\nexport type BranchVerdict = z.infer<typeof branchVerdictSchema>\n\nexport interface BranchVerdictRecord extends BranchVerdict {\n repo: string\n recordedAt: string\n}\n\nexport interface BranchVerdictStore {\n /** The verdict for this exact tip, or `null`. A ref whose tip moved simply finds nothing. */\n get(repo: string, sha: string): Promise<BranchVerdictRecord | null>\n set(record: BranchVerdictRecord): Promise<void>\n}\n\n/** NUL-joined like the worktree verdict memo — cannot occur in a repo label or a sha. */\nconst verdictKey = (repo: string, sha: string): string => `${repo}\\u0000${sha}`\n\nexport const BRANCH_VERDICTS_PATH = (): string => resolve(homedir(), \".agentproto\", \"branch-gc-verdicts.json\")\n\nconst verdictRecordSchema = z.intersection(branchVerdictSchema, z.object({ repo: z.string(), recordedAt: z.string() }))\nconst verdictFileSchema = z.object({ entries: z.array(z.unknown()) })\n\n/** `~/.agentproto/branch-gc-verdicts.json`, keyed by (repo, tip sha). */\nexport class FileBranchVerdictStore implements BranchVerdictStore {\n private cache: Map<string, BranchVerdictRecord> | null = null\n\n constructor(private readonly path: string = BRANCH_VERDICTS_PATH()) {}\n\n private async load(): Promise<Map<string, BranchVerdictRecord>> {\n if (this.cache) return this.cache\n const map = new Map<string, BranchVerdictRecord>()\n this.cache = map\n let parsed: unknown\n try {\n parsed = JSON.parse(await readFile(this.path, \"utf8\"))\n } catch {\n return map\n }\n const file = verdictFileSchema.safeParse(parsed)\n if (!file.success) return map\n for (const raw of file.data.entries) {\n const rec = verdictRecordSchema.safeParse(raw)\n if (rec.success) map.set(verdictKey(rec.data.repo, rec.data.sha), rec.data)\n }\n return map\n }\n\n async get(repo: string, sha: string): Promise<BranchVerdictRecord | null> {\n return (await this.load()).get(verdictKey(repo, sha)) ?? null\n }\n\n async set(record: BranchVerdictRecord): Promise<void> {\n const map = await this.load()\n map.set(verdictKey(record.repo, record.sha), record)\n await writeJsonAtomic(this.path, { entries: [...map.values()] })\n }\n}\n\nexport class InMemoryBranchVerdictStore implements BranchVerdictStore {\n private readonly map = new Map<string, BranchVerdictRecord>()\n async get(repo: string, sha: string): Promise<BranchVerdictRecord | null> {\n return this.map.get(verdictKey(repo, sha)) ?? null\n }\n async set(record: BranchVerdictRecord): Promise<void> {\n this.map.set(verdictKey(record.repo, record.sha), record)\n }\n}\n\nexport class BranchVerdictError extends Error {\n constructor(message: string) {\n super(message)\n this.name = \"BranchVerdictError\"\n }\n}\n\n/**\n * Validate and store one verdict. Rejects a malformed verdict, an agreeing\n * gate with no evidence, and a sha that isn't a commit in this repo.\n */\nexport async function recordBranchVerdict(input: {\n repoRoot: string\n repoName: string\n verdict: unknown\n store: BranchVerdictStore\n now?: () => string\n}): Promise<BranchVerdictRecord> {\n const parsed = branchVerdictSchema.safeParse(input.verdict)\n if (!parsed.success) {\n const issues = parsed.error.issues.map((i) => `${i.path.join(\".\") || \"<root>\"}: ${i.message}`).join(\"; \")\n throw new BranchVerdictError(`invalid branch verdict: ${issues}`)\n }\n const exists = await git(input.repoRoot, [\"cat-file\", \"-e\", `${parsed.data.sha}^{commit}`])\n if (exists.exitCode !== 0) {\n throw new BranchVerdictError(`invalid branch verdict: ${parsed.data.sha} is not a commit in ${input.repoRoot}`)\n }\n const record: BranchVerdictRecord = {\n ...parsed.data,\n repo: input.repoName,\n recordedAt: (input.now ?? (() => new Date().toISOString()))(),\n }\n await input.store.set(record)\n return record\n}\n","/**\n * `gc` (PLAN.md §5, PR-D): plan → apply → salvage over the status engine's\n * classification (`status.ts`, PR-A). This module owns no new git knowledge\n * — it reuses `listGitWorktrees` / `computeWorktreeStatus` / `classify` for\n * every fact and `salvageWorktree` / `worktree.cleanup` (PR-C) for every\n * mutation. Its only original logic is sequencing the four safety layers\n * (PLAN.md §5.2):\n *\n * 1. `planGc` is pure read: it classifies every worktree and returns a\n * plan. Nothing is mutated by calling it — the CLI's dry-run default\n * *is* just \"call planGc, print it, stop.\"\n * 2. `applyGc` re-derives each worktree's class from scratch immediately\n * before touching it (a fresh `listGitWorktrees` + `computeWorktreeStatus`,\n * not a reuse of the plan's stale snapshot) and refuses to act if the\n * class changed since the plan was made.\n * 3. The actual removal is `worktree.cleanup` with NO discard flags for a\n * reclaim-class entry — git's own non-`--force` refusal is the backstop\n * this module leans on, never a force flag \"just in case.\"\n * 4. A salvage-class entry is only ever touched via `salvageWorktree`\n * followed by `worktree.cleanup` with both discard flags — snapshot\n * first, removal only after the snapshot is durable (mirrors `worktree\n * archive`'s CLI verb, PR-C).\n *\n * The main worktree (`repoRoot` itself) is never part of the plan: `git\n * worktree list`'s first entry is always the main checkout, and a repo\n * sitting on an up-to-date default branch is trivially `fresh ∧ clean` —\n * exactly what `reclaim` looks for. Git itself refuses to remove\n * the main working tree (\"is a main working tree\", verified empirically),\n * but this module doesn't lean on that as the only guard: the main worktree\n * is filtered out before classification even runs, so it can never appear\n * in a plan, let alone be attempted.\n *\n * One reclassification on top of `classify`'s three classes:\n * `resolveGcClass` promotes a clean, `unpushed` worktree from `hold` to\n * `reclaim` when every commit ahead of the default branch is a mechanical\n * dependency bump (subject AND cumulative diff both checked — see that\n * function's doc). It's applied identically at plan time and re-verified at\n * apply time (layer 2), so a worktree that grew a real commit in between is\n * still caught.\n */\n\nimport { basename, isAbsolute, join, relative, resolve, sep } from \"node:path\"\nimport { readFile, readdir, realpath, rm, stat } from \"node:fs/promises\"\nimport { runTool } from \"@agentproto/driver\"\nimport { classifyTipAgainstBase } from \"./branch-gc.js\"\nimport { execArgv, execGit } from \"./exec.js\"\nimport { cleanupWorktreeTool } from \"./tools/index.js\"\nimport { worktreeProvider } from \"./provider/index.js\"\nimport { salvageWorktree } from \"./salvage.js\"\nimport type { ForgeClient } from \"./forge.js\"\nimport {\n classify,\n listGitWorktrees,\n computeWorktreeStatus,\n type GitWorktreeRef,\n type IntegrationState,\n type LivenessState,\n type TreeState,\n type VerdictMemoStore,\n} from \"./status.js\"\n\nconst candidates = [worktreeProvider]\n\n// ── classification (PLAN.md §5.1) ───────────────────────────────────────\n\nexport type GcClass = \"reclaim\" | \"salvage\" | \"hold\"\n\nexport interface ClassifyForGcOptions {\n /**\n * A clean, idle/daemon-unreachable DETACHED worktree moves from `hold` to\n * `reclaim` (PLAN.md §5.1). This is the only reclassification power any\n * flag has: every other hold reason — partial, open, unknown(offline),\n * gone-unexplained, diverged — is untouched by any flag, ever. Default\n * false.\n */\n includeDetached?: boolean\n /** Threaded straight through to `classify`'s `RECENT_WRITE_HOLD_WINDOW_MS` guard. Defaults to `Date.now()`. */\n nowMs?: number\n}\n\n/**\n * gc's own classifier, layered on top of `classify` (status.ts) rather than\n * reimplementing it — reuse first (AGENTS.md, PLAN.md §0.6). The one thing\n * `classify` cannot know is `--include-detached`, a gc-specific flag; that\n * override lives here, not in the read-only status engine `ls --status`\n * also depends on.\n */\nexport function classifyForGc(\n tree: TreeState,\n integration: IntegrationState,\n liveness: LivenessState,\n options: ClassifyForGcOptions = {},\n): GcClass {\n if (options.includeDetached && integration.state === \"detached\") {\n const idleOrUnreachable = liveness.state === \"idle\" || liveness.state === \"daemon-unreachable\"\n if (tree.state === \"clean\" && idleOrUnreachable) return \"reclaim\"\n }\n return classify(tree, integration, liveness, options.nowMs).class\n}\n\n// ── dep-bump reclaim exemption ──────────────────────────────────────────\n//\n// A worktree whose only unpushed commits are a mechanical dependency bump\n// (`chore(deps): weekly minor/patch bump`, re-run every week by every\n// session that happens to pick it up) is not \"unpushed work to protect\" —\n// it reproduces by re-running the routine, and 25 of these piling up as\n// permanent `hold`s is exactly what emptied a 102GB external SSD of gc\n// coverage. This is deliberately narrow and additive: it only ever promotes\n// a worktree that `classifyForGc` already put in `hold` for the single\n// reason `integration.state === \"unpushed\"` with a clean tree — every other\n// hold reason (partial, open, diverged, gone-unexplained, unknown(offline),\n// a dirty tree, `unpushed` while forge-unreachable — which can't happen, see\n// `reconcileIntegration`) is completely untouched by this and still holds.\n\n/**\n * The reclaim reasons this module can attach. `dep-bump` promotes a `hold`\n * to `reclaim` (see above). `orphan` and `prunable` are both different in\n * kind — neither ever starts from a `hold` verdict, because neither was\n * classified via `classify`'s three axes in the first place:\n * - `orphan`: a directory physically present under the repo's worktree\n * pool that `git worktree list` no longer knows about at all (see the\n * \"orphan reclaim\" section below).\n * - `prunable`: the mirror image — `git worktree list` still has a\n * registration, but git itself already reports it `prunable` because\n * the working directory is gone. Distinct from `orphan` on purpose: an\n * orphan's directory is still there to lose (it just failed removal),\n * so `reclaimOrphan` does `rm -rf`; a prunable entry's directory is\n * already gone, so there's nothing to inspect and nothing to `rm` — the\n * only irreversible thing history nearly did to it (deleting the branch)\n * must not happen either. See \"prunable reclaim\" below.\n */\nexport type GcReclaimReason = \"dep-bump\" | \"orphan\" | \"prunable\" | InBaseReclaimReason\n\n/**\n * `branch gc`'s proof tiers (`classifyTip`, branch-gc.ts) that promote a\n * clean, idle worktree out of `hold` when the forge can't: its branch's\n * CONTENT is provably in base even though no merged PR contains its tip (a\n * squash that went through another PR, a cherry-pick, a later reorg). See\n * \"in-base promotion\" below.\n */\nexport type InBaseReclaimReason = \"squash-merged\" | \"patch-merged\" | \"content-merged\"\n\n// ── noise allowlist ─────────────────────────────────────────────────────\n//\n// Some dirt is not work: `.opencode/package-lock.json` churn shows up in\n// almost every agent worktree. A worktree whose ONLY dirt is on this list\n// reads `clean` to gc (`computeTreeState`'s `noisePaths`), so a merged one\n// reclaims instead of sitting in `salvage` forever. Removal stays non-force:\n// `reclaimOne` restores/deletes exactly the noise paths first, then plain\n// `git worktree remove` — if anything else turned dirty in between, git still\n// refuses.\n\n/** gc's default noise allowlist — overridable per call via `noisePaths` (`[]` disables it). */\nexport const DEFAULT_GC_NOISE_PATHS: readonly string[] = [\".opencode/package-lock.json\"]\n\n// ── live-session-cwd protection ─────────────────────────────────────────\n//\n// `classify`'s liveness axis (`computeLiveness`, status.ts) already holds a\n// worktree that has a live session's cwd inside it — but only when that\n// session shows up in the sessions snapshot `computeWorktreeStatus` was\n// given. A caller with a stronger, more direct source of truth (the\n// daemon's own in-memory session registry, read at the exact instant gc\n// runs, rather than a possibly-stale/incomplete on-disk snapshot) can name\n// those cwds explicitly via `protectedPaths` — a belt-and-suspenders check\n// that wins unconditionally, independent of `classify`'s snapshot-based\n// verdict and computed BEFORE it (so a protected worktree never pays the\n// dep-bump exemption's extra git spawns either).\n\n/** The hold reasons this module can attach, distinct from `classify`'s snapshot-based holds. */\nexport type GcHoldReason = \"live-session-cwd\"\n\n/**\n * `true` iff `worktreePath` itself, or a subdirectory of it, is named by\n * `protectedPaths` — the same exact-or-subdirectory containment convention\n * as `sessionInWorktree` (provenance.ts), bounded by `sep` so a sibling like\n * `/a/bc` is never confused with `/a/b`. Plain string comparison, matching\n * `sessionInWorktree`'s own convention, rather than resolving symlinks —\n * callers that need realpath-stability should normalize before passing\n * `protectedPaths` in.\n */\nfunction isProtectedPath(worktreePath: string, protectedPaths: readonly string[] | undefined): boolean {\n if (!protectedPaths || protectedPaths.length === 0) return false\n return protectedPaths.some((p) => p === worktreePath || p.startsWith(worktreePath + sep))\n}\n\n/**\n * Mechanical dep-bump commit subjects: `chore(deps)` / `fix(deps)`, with or\n * without a scope (`chore(deps-dev)`, `fix(deps-optional)`, …). A commit\n * message is cheap to type and easy to lie in — this regex alone NEVER\n * licenses anything; `isMechanicalDepBumpRange` below only trusts it in\n * conjunction with the actual cumulative diff.\n */\nconst DEP_BUMP_SUBJECT_RE = /^(?:chore|fix)\\(deps[\\w-]*\\):\\s/\n\nfunction isDepBumpSubject(subject: string): boolean {\n return DEP_BUMP_SUBJECT_RE.test(subject)\n}\n\n/** The only paths a mechanical dep bump is allowed to touch, matched by basename so a nested package's `package.json` counts too. */\nconst DEP_BUMP_ALLOWED_BASENAMES = new Set([\"pnpm-lock.yaml\", \"package-lock.json\", \"yarn.lock\", \"package.json\"])\n\nfunction isDepBumpAllowedPath(path: string): boolean {\n return DEP_BUMP_ALLOWED_BASENAMES.has(basename(path))\n}\n\n/**\n * Layer 3+4 of the exemption: EVERY commit ahead of `baseRef` must have a\n * dep-bump subject (`git log --format=%s`, two-dot range — exactly the\n * commits `aheadBy` counts, PLAN-comment on `readUpstreamTrack`), AND the\n * cumulative diff of that whole range (`git diff`, three-dot/merge-base\n * range, so it isolates the branch's own changes from anything `baseRef`\n * did independently in the meantime) must touch nothing but lockfiles and\n * `package.json`. Both checks run unconditionally together — a subject that\n * lies is cheap, a diff cannot lie, so the diff is the one that actually\n * gates. Two extra git spawns, only ever paid for a worktree that would\n * otherwise be `hold` for exactly `clean ∧ unpushed` — every other class\n * pays nothing.\n */\nexport async function isMechanicalDepBumpRange(repoRoot: string, baseRef: string, tipSha: string): Promise<boolean> {\n const [subjectsRes, diffRes] = await Promise.all([\n execArgv(\"git\", [\"-C\", repoRoot, \"log\", \"--format=%s\", `${baseRef}..${tipSha}`], repoRoot),\n execArgv(\"git\", [\"-C\", repoRoot, \"diff\", \"--name-only\", `${baseRef}...${tipSha}`], repoRoot),\n ])\n if (subjectsRes.exitCode !== 0 || diffRes.exitCode !== 0) return false\n\n const subjects = subjectsRes.stdout.split(\"\\n\").filter((line) => line.length > 0)\n if (subjects.length === 0) return false\n if (!subjects.every(isDepBumpSubject)) return false\n\n const files = diffRes.stdout.split(\"\\n\").filter((line) => line.length > 0)\n if (files.length === 0) return false\n return files.every(isDepBumpAllowedPath)\n}\n\nexport interface ResolveGcClassOptions extends ClassifyForGcOptions {\n repoRoot: string\n /**\n * Run `branch gc`'s content ladder for a clean, idle worktree still in\n * `hold` (see \"in-base promotion\"). Default true.\n */\n inBaseCheck?: boolean\n /** The tip commit of the worktree being classified — `worktree.head`. */\n tipSha: string\n /** Default `\"origin/main\"` — matches `reconcileIntegration`'s own default. */\n defaultBranchRef?: string\n}\n\nexport interface ResolvedGcClass {\n class: GcClass\n /** Set only when `class === \"reclaim\"` via the dep-bump exemption rather than the ordinary merged/fresh path. */\n reclaimReason?: GcReclaimReason\n}\n\n/**\n * `classifyForGc` plus the one async, git-touching layer on top: a clean,\n * `unpushed` worktree whose entire ahead range is a mechanical dep bump is\n * promoted from `hold` to `reclaim`. Every other class classifyForGc\n * returns is passed through untouched — this never widens any other hold\n * reason, and never touches git for a worktree it wouldn't otherwise hold\n * on `unpushed` alone.\n */\nexport async function resolveGcClass(\n tree: TreeState,\n integration: IntegrationState,\n liveness: LivenessState,\n options: ResolveGcClassOptions,\n): Promise<ResolvedGcClass> {\n const baseClass = classifyForGc(tree, integration, liveness, options)\n if (baseClass !== \"hold\") return { class: baseClass }\n if (tree.state !== \"clean\") return { class: \"hold\" }\n\n const baseRef = options.defaultBranchRef ?? \"origin/main\"\n if (integration.state === \"unpushed\" && (await isMechanicalDepBumpRange(options.repoRoot, baseRef, options.tipSha))) {\n return { class: \"reclaim\", reclaimReason: \"dep-bump\" }\n }\n if (options.inBaseCheck !== false) {\n const inBase = await provenInBase(integration, liveness, options.repoRoot, baseRef, options.tipSha)\n if (inBase) return { class: \"reclaim\", reclaimReason: inBase }\n }\n return { class: \"hold\" }\n}\n\n// ── in-base promotion ───────────────────────────────────────────────────\n//\n// `reconcileIntegration` only calls a branch `merged` when a merged PR's head\n// contains its tip. Work that reached base any other way — squashed into a\n// different PR, cherry-picked, moved by a later reorg — stays `diverged` /\n// `local-only` / `pushed-no-pr` / … and holds forever. `branch gc`'s ladder\n// proves those by content instead. Deliberately narrow:\n// - only a CLEAN tree (so nothing uncommitted can be lost; this never\n// licenses salvage — only a forge-confirmed `merged` does, see\n// `classify`'s 2026-07-15 note);\n// - only an idle/daemon-unreachable liveness (a live session still holds);\n// - never `open` (an open PR is always hold), never `unknown(offline)`\n// (can't rule out an open PR), never `detached` (no branch to reason\n// about).\n\nconst IN_BASE_PROMOTABLE: ReadonlySet<IntegrationState[\"state\"]> = new Set([\n \"partial\",\n \"diverged\",\n \"pushed-no-pr\",\n \"unpushed\",\n \"local-only\",\n \"gone-unexplained\",\n])\n\nasync function provenInBase(\n integration: IntegrationState,\n liveness: LivenessState,\n repoRoot: string,\n baseRef: string,\n tipSha: string,\n): Promise<InBaseReclaimReason | null> {\n if (!IN_BASE_PROMOTABLE.has(integration.state)) return null\n if (liveness.state !== \"idle\" && liveness.state !== \"daemon-unreachable\") return null\n try {\n const tip = await classifyTipAgainstBase(repoRoot, baseRef, tipSha)\n if (tip.status === \"squash-merged\" || tip.status === \"patch-merged\" || tip.status === \"content-merged\") return tip.status\n return null\n } catch {\n // An unresolvable base or a git error proves nothing — keep holding.\n return null\n }\n}\n\n// ── plan ─────────────────────────────────────────────────────────────\n\nexport interface GcPlanEntry {\n path: string\n branch: string | null\n head: string\n /**\n * Absent for an orphan entry (`orphan: true`) or a prunable entry\n * (`prunable: true`) — git itself cannot answer the tree/integration/\n * liveness questions for a directory it no longer recognizes as a\n * worktree (orphan) or whose working directory is simply gone (prunable),\n * so this module never fabricates a value for them rather than reporting\n * a fact it can't actually check.\n */\n tree?: TreeState\n integration?: IntegrationState\n liveness?: LivenessState\n /** Classification per PLAN.md §5.1, after `--include-detached` (if set). */\n class: GcClass\n /** Set only when `class === \"reclaim\"` via the dep-bump exemption, the orphan reclaim path, or the prunable reclaim path — see `resolveGcClass` / `scanOrphanWorktreePaths` / `toPlanEntry`. */\n reclaimReason?: GcReclaimReason\n /** Set only when `class === \"hold\"` via `protectedPaths` (`isProtectedPath`) — distinguishes this from an ordinary snapshot-based hold. */\n holdReason?: GcHoldReason\n /**\n * `true` only for a directory the orphan scan found: physically present\n * under the repo's worktree pool, but absent from `git worktree list`\n * (even after `git worktree prune`) — the interrupted-`worktree remove`\n * shape (module docblock's §5 note). Always paired with `class: \"reclaim\"`\n * and `reclaimReason: \"orphan\"`. Never set for a linked worktree, however\n * it classifies.\n */\n orphan?: boolean\n /**\n * `true` only for a linked worktree `git worktree list --porcelain` itself\n * already marked `prunable` — its working directory is gone, so none of\n * `classify`'s three axes were computed (no git command was ever run\n * against the dead path). Always paired with `class: \"reclaim\"` and\n * `reclaimReason: \"prunable\"` — see \"prunable reclaim\" below `toPlanEntry`.\n */\n prunable?: boolean\n}\n\nexport interface PlanGcInput {\n repoRoot: string\n repoName: string\n forge: ForgeClient\n memo: VerdictMemoStore\n defaultBranchRef?: string\n sessionsPath?: string\n includeDetached?: boolean\n now?: () => string\n /** See `ComputeWorktreeStatusInput.nowMs` (status.ts) — kept separate from `now`. Defaults to `Date.now()`. */\n nowMs?: number\n /**\n * The bucket directory this repo's worktrees are provisioned under — e.g.\n * `<worktrees.root>/<repoLabel>` (see `resolveWorktreesRoot` / `repoLabel`,\n * both resolved by the caller; this module does no root resolution of its\n * own, see the orphan-reclaim section below). When omitted, orphan\n * scanning is skipped entirely and `planGc`/`applyGc` behave exactly as\n * before — every existing caller that doesn't pass this sees zero change.\n */\n worktreesRoot?: string\n /**\n * Absolute paths (typically live session cwds) that must never be\n * classified `reclaim`/`salvage`, exact-or-subdirectory (`isProtectedPath`)\n * — see the \"live-session-cwd protection\" section above. Applies to both\n * linked worktrees and orphan-scan entries. Omitted ⇒ no additional\n * protection beyond `classify`'s own snapshot-based liveness axis.\n */\n protectedPaths?: string[]\n /** Noise allowlist (see \"noise allowlist\" above). Default `DEFAULT_GC_NOISE_PATHS`; `[]` disables it. */\n noisePaths?: readonly string[]\n}\n\n/** Every linked worktree of `repoRoot` except the main checkout itself — see the module docblock. */\nasync function linkedWorktreesOf(repoRoot: string): Promise<GitWorktreeRef[]> {\n const worktrees = await listGitWorktrees(repoRoot)\n return worktrees.filter((w) => w.path !== repoRoot)\n}\n\n// ── orphan reclaim ───────────────────────────────────────────────────────\n//\n// `linkedWorktreesOf` (and therefore every axis `classify` depends on) can\n// only ever see what `git worktree list` reports — which is exactly the\n// blind spot behind the 8GB/day leak this section exists for. A worktree\n// removal interrupted mid-delete leaves the directory on disk but erases\n// `<repoRoot>/.git/worktrees/<name>`, so git no longer has ANY record of it:\n// `git worktree list` doesn't show it, `git status` inside it fails outright\n// (\"not a working tree\"), and it is therefore invisible to gc forever,\n// through no fault of the classify/reclaim/salvage engine above — that\n// engine is working exactly as designed on the set of worktrees git still\n// knows about.\n//\n// This section is deliberately narrow and conservative, matching the case\n// its ownership check can actually prove:\n// 1. A directory only ever counts as an orphan of THIS repo if its own\n// `.git` file's `gitdir:` pointer resolves inside `<repoRoot>`'s own\n// `.git/worktrees/` — `belongsToRepo` below. An unrelated directory\n// that happens to sit in the same pool (no `.git` pointer, or one that\n// points somewhere else entirely) is never touched, full stop.\n// 2. `git worktree prune` runs first — cheap and safe — so a directory\n// that's merely mid-registration (not actually orphaned) resolves\n// itself before the scan concludes anything.\n// 3. Once `git worktree list` still doesn't know about it after a prune,\n// there is nothing left that could \"reclassify\" it the way a linked\n// worktree can flip branches mid-session (`applyOne`'s layer 2): its\n// git identity is already gone, so nothing can merge it, push it, or\n// lose reachable history by removing it. The only thing at risk is\n// uncommitted working-tree state, and by definition git has already\n// lost the ability to act on that state through any of its own verbs —\n// the directory is no longer a working tree by git's own definition.\n// Because of (3), an orphan is unconditionally `reclaim` — there is no\n// `hold`/`salvage` axis to compute for it, and manufacturing one would be\n// reporting a fact this module cannot actually check (see `GcPlanEntry`'s\n// `tree`/`integration`/`liveness` doc).\n\n/**\n * Absolute path to this repo's own `.git/worktrees` directory — every\n * linked worktree's `.git` file points at a child of this. Resolved via\n * `git rev-parse --git-common-dir` rather than assuming `<repoRoot>/.git`\n * literally, so a bare/alternate git layout is still handled correctly.\n */\nasync function gitWorktreesDir(repoRoot: string): Promise<string> {\n const res = await execArgv(\"git\", [\"-C\", repoRoot, \"rev-parse\", \"--git-common-dir\"], repoRoot)\n if (res.exitCode !== 0) {\n throw new Error(\n `git rev-parse --git-common-dir failed in ${repoRoot} (exit ${res.exitCode}): ${res.stderr.trim()}`,\n )\n }\n return join(resolve(repoRoot, res.stdout.trim()), \"worktrees\")\n}\n\n/**\n * Reads a worktree directory's `.git` file (`gitdir: <path>`) and resolves\n * the target to an absolute path. `null` when the file is absent, unreadable,\n * or doesn't match the `gitdir:` pointer shape every linked worktree's `.git`\n * has (a plain directory with no `.git` at all is exactly the shape an\n * unrelated, not-ours directory has — see `belongsToRepo`).\n */\nasync function readGitdirPointer(worktreePath: string): Promise<string | null> {\n let raw: string\n try {\n raw = await readFile(join(worktreePath, \".git\"), \"utf8\")\n } catch {\n return null\n }\n const match = raw.match(/^gitdir:\\s*(.+?)\\s*$/m)\n const target = match?.[1]\n if (!target) return null\n return resolve(worktreePath, target)\n}\n\n/**\n * `true` only when `worktreePath`'s `.git` pointer resolves inside\n * `repoRoot`'s own `.git/worktrees/` — the one signal the orphan scan trusts\n * before ever touching a directory. This is deliberately a string-prefix\n * check, not an existence check: for a genuine orphan, the specific\n * `.git/worktrees/<name>` subdirectory the pointer names is exactly what's\n * gone (that's the orphan condition), so requiring it to still exist would\n * make this check unable to ever confirm the one case it exists for.\n */\nasync function belongsToRepo(repoRoot: string, worktreePath: string): Promise<boolean> {\n const pointer = await readGitdirPointer(worktreePath)\n if (!pointer) return false\n let worktreesDir: string\n try {\n worktreesDir = await gitWorktreesDir(repoRoot)\n } catch {\n return false\n }\n const rel = relative(worktreesDir, pointer)\n return rel === \"\" || (!rel.startsWith(\"..\") && !isAbsolute(rel))\n}\n\nasync function pathExists(path: string): Promise<boolean> {\n try {\n await stat(path)\n return true\n } catch {\n return false\n }\n}\n\n/**\n * Resolves symlinks (`realpath`) so a path git reports and the same path\n * built by hand from a config-supplied root compare equal even when some\n * component along the way is a symlink (e.g. macOS's `/tmp` →\n * `/private/tmp`, or a temp-dir-backed test fixture) — falls back to plain\n * `resolve` for a path that doesn't exist (yet) rather than throwing.\n */\nasync function realOrResolved(path: string): Promise<string> {\n try {\n return await realpath(path)\n } catch {\n return resolve(path)\n }\n}\n\n/**\n * Discovery (plan time): every directory physically present under\n * `worktreesRoot` that both (a) `git worktree list` doesn't know about, even\n * after a `worktree prune`, and (b) genuinely belongs to `repoRoot` per\n * `belongsToRepo`. A `worktreesRoot` that doesn't exist yet (nothing has\n * ever been provisioned there) yields no orphans, not an error.\n */\nasync function scanOrphanWorktreePaths(repoRoot: string, worktreesRoot: string): Promise<string[]> {\n await execArgv(\"git\", [\"-C\", repoRoot, \"worktree\", \"prune\"], repoRoot).catch(() => null)\n const linkedRefs = await linkedWorktreesOf(repoRoot)\n const linked = new Set(await Promise.all(linkedRefs.map((w) => realOrResolved(w.path))))\n const entries = await readdir(worktreesRoot, { withFileTypes: true }).catch(() => [])\n const orphans: string[] = []\n for (const entry of entries) {\n if (!entry.isDirectory()) continue\n const candidate = resolve(worktreesRoot, entry.name)\n if (linked.has(await realOrResolved(candidate))) continue\n if (await belongsToRepo(repoRoot, candidate)) orphans.push(candidate)\n }\n return orphans\n}\n\nfunction makeOrphanPlanEntry(path: string, protectedPaths: readonly string[] | undefined): GcPlanEntry {\n if (isProtectedPath(path, protectedPaths)) {\n return { path, branch: null, head: \"\", class: \"hold\", holdReason: \"live-session-cwd\" }\n }\n return { path, branch: null, head: \"\", class: \"reclaim\", reclaimReason: \"orphan\", orphan: true }\n}\n\n/**\n * Apply-time re-check (layer 2, mirrored from `applyOne`'s TOCTOU guard for\n * linked worktrees): re-derive from scratch, immediately before touching\n * anything, rather than trusting the plan's stale snapshot.\n * - `\"gone\"`: the directory no longer exists at all — a prior/concurrent\n * gc pass (or the plan itself racing a manual `rm`) already finished the\n * job. Reclaiming this is a no-op success, not a failure.\n * - `\"confirmed\"`: still on disk, still un-linked after a fresh prune,\n * `.git` pointer still resolves back to this repo — safe to remove.\n * - `\"not-orphan\"`: something changed since the plan was made (most\n * plausibly: it got re-registered, or the ownership check no longer\n * passes) — refuse, exactly like `applyOne`'s `aborted-reclassified`.\n */\nasync function verifyOrphan(repoRoot: string, worktreePath: string): Promise<\"gone\" | \"confirmed\" | \"not-orphan\"> {\n if (!(await pathExists(worktreePath))) return \"gone\"\n await execArgv(\"git\", [\"-C\", repoRoot, \"worktree\", \"prune\"], repoRoot).catch(() => null)\n const linked = await linkedWorktreesOf(repoRoot)\n const realWorktreePath = await realOrResolved(worktreePath)\n for (const w of linked) {\n if ((await realOrResolved(w.path)) === realWorktreePath) return \"not-orphan\"\n }\n return (await belongsToRepo(repoRoot, worktreePath)) ? \"confirmed\" : \"not-orphan\"\n}\n\n/**\n * Reclaim one orphan entry. No `worktree.cleanup` tool here — that tool\n * shells out to `git worktree remove`, which by definition refuses (or\n * simply doesn't know what to do with) a directory git has no record of;\n * plain recursive removal is the correct, and only, verb for something git\n * itself no longer considers a working tree. `{ recursive: true, force:\n * true }` is what makes this idempotent: a directory that's already gone,\n * or partially gone (the same half-deleted shape the orphan condition\n * itself comes from), is removed without error either way.\n */\nasync function reclaimOrphan(entry: GcPlanEntry, options: ApplyGcOptions): Promise<GcApplyOutcome> {\n const state = await verifyOrphan(options.repoRoot, entry.path)\n if (state === \"not-orphan\") {\n return { path: entry.path, branch: null, result: \"aborted-reclassified\", from: \"reclaim\", to: \"hold\" }\n }\n if (state === \"confirmed\") {\n try {\n await rm(entry.path, { recursive: true, force: true })\n } catch (err) {\n return {\n path: entry.path,\n branch: null,\n result: \"failed\",\n message: err instanceof Error ? err.message : String(err),\n }\n }\n }\n // state === \"gone\": already removed — idempotent success, nothing to do.\n return { path: entry.path, branch: null, result: \"reclaimed\", reclaimReason: \"orphan\" }\n}\n\n// ── prunable reclaim: a registration git already knows is dead ─────────────\n//\n// `git worktree list --porcelain` itself emits a `prunable <reason>` line\n// when a linked worktree's working directory is gone but its `.git/\n// worktrees/<name>` registration is still intact (the mirror image of the\n// orphan case above, where the registration is gone but the directory\n// isn't). Before this section, `linkedWorktreesOf` still handed this entry\n// to `computeWorktreeStatus`, which spawns `git status --porcelain=v2 -C\n// <dead path>` and throws — a throw that escaped `planGc`'s loop entirely\n// and took the whole plan down with it, for every worktree in the repo, not\n// just the dead one.\n//\n// Classification here never runs a single git command against the dead\n// path: git's own `prunable` line is trusted as-is (`GitWorktreeRef.prunable`,\n// status.ts), never re-derived with `existsSync` or any filesystem check of\n// our own. Reclaiming it is `git worktree prune` alone — no\n// `cleanupWorktreeTool`/`git worktree remove` (which needs a working\n// directory to operate on and would refuse or misbehave against one that's\n// already gone), and critically no branch deletion: there is nothing left to\n// inspect to decide a branch is safe to delete, so this path must never\n// reach `reclaimOne`'s `deleteBranch: true`.\n\nfunction makePrunablePlanEntry(worktree: GitWorktreeRef, protectedPaths: readonly string[] | undefined): GcPlanEntry {\n if (isProtectedPath(worktree.path, protectedPaths)) {\n return { path: worktree.path, branch: worktree.branch, head: worktree.head, class: \"hold\", holdReason: \"live-session-cwd\" }\n }\n return {\n path: worktree.path,\n branch: worktree.branch,\n head: worktree.head,\n class: \"reclaim\",\n reclaimReason: \"prunable\",\n prunable: true,\n }\n}\n\n/**\n * Apply-time re-check (layer 2, mirrored from `verifyOrphan`): re-list from\n * scratch immediately before touching anything, rather than trusting the\n * plan's stale snapshot.\n * - entry no longer listed at all: a prior/concurrent `gc` (or a plain\n * `git worktree prune` run by something else) already finished the job —\n * reclaiming this is a no-op success, not a failure.\n * - still listed, still `prunable`: safe to prune.\n * - still listed, no longer `prunable`: something changed since the plan\n * was made (most plausibly: a new worktree got registered at the exact\n * same path) — refuse, exactly like `applyOne`'s `aborted-reclassified`.\n */\nasync function reclaimPrunable(entry: GcPlanEntry, options: ApplyGcOptions): Promise<GcApplyOutcome> {\n const fresh = await listGitWorktrees(options.repoRoot)\n const stillThere = fresh.find((w) => w.path === entry.path)\n if (stillThere && !stillThere.prunable) {\n return { path: entry.path, branch: stillThere.branch, result: \"aborted-reclassified\", from: \"reclaim\", to: \"hold\" }\n }\n if (stillThere) {\n try {\n await execGit(options.repoRoot, [\"worktree\", \"prune\"])\n } catch (err) {\n return {\n path: entry.path,\n branch: entry.branch,\n result: \"failed\",\n message: err instanceof Error ? err.message : String(err),\n }\n }\n }\n // Either just pruned above, or already gone by the time we re-listed —\n // either way, the registration is now clear and the branch is untouched.\n return { path: entry.path, branch: entry.branch, result: \"reclaimed\", reclaimReason: \"prunable\" }\n}\n\nasync function toPlanEntry(\n repoRoot: string,\n defaultBranchRef: string | undefined,\n worktree: GitWorktreeRef,\n status: { tree: TreeState; integration: IntegrationState; liveness: LivenessState },\n includeDetached: boolean,\n nowMs: number,\n protectedPaths?: readonly string[],\n): Promise<GcPlanEntry> {\n if (isProtectedPath(worktree.path, protectedPaths)) {\n return {\n path: worktree.path,\n branch: worktree.branch,\n head: worktree.head,\n tree: status.tree,\n integration: status.integration,\n liveness: status.liveness,\n class: \"hold\",\n holdReason: \"live-session-cwd\",\n }\n }\n const resolved = await resolveGcClass(status.tree, status.integration, status.liveness, {\n repoRoot,\n tipSha: worktree.head,\n defaultBranchRef,\n includeDetached,\n nowMs,\n })\n return {\n path: worktree.path,\n branch: worktree.branch,\n head: worktree.head,\n tree: status.tree,\n integration: status.integration,\n liveness: status.liveness,\n class: resolved.class,\n ...(resolved.reclaimReason ? { reclaimReason: resolved.reclaimReason } : {}),\n }\n}\n\n/**\n * The dry-run plan (PLAN.md §5.2 layer 1): classify every linked worktree,\n * mutate nothing. This is the human's decision surface — `gc` with no flags\n * is exactly \"call this, print it, stop.\"\n */\nexport async function planGc(input: PlanGcInput): Promise<GcPlanEntry[]> {\n const includeDetached = Boolean(input.includeDetached)\n // One frozen instant for the whole plan's recent-write checks.\n const nowMs = input.nowMs ?? Date.now()\n const worktrees = await linkedWorktreesOf(input.repoRoot)\n const entries: GcPlanEntry[] = []\n for (const worktree of worktrees) {\n // git already told us this one is dead — classify it from that signal\n // alone, without spawning a single git command against its (nonexistent)\n // path. See the \"prunable reclaim\" section above `toPlanEntry`.\n if (worktree.prunable) {\n entries.push(makePrunablePlanEntry(worktree, input.protectedPaths))\n continue\n }\n const status = await computeWorktreeStatus({\n repoRoot: input.repoRoot,\n repoName: input.repoName,\n worktree,\n forge: input.forge,\n memo: input.memo,\n defaultBranchRef: input.defaultBranchRef,\n sessionsPath: input.sessionsPath,\n now: input.now,\n noisePaths: input.noisePaths ?? DEFAULT_GC_NOISE_PATHS,\n })\n entries.push(\n await toPlanEntry(\n input.repoRoot,\n input.defaultBranchRef,\n worktree,\n status,\n includeDetached,\n nowMs,\n input.protectedPaths,\n ),\n )\n }\n if (input.worktreesRoot) {\n const orphanPaths = await scanOrphanWorktreePaths(input.repoRoot, input.worktreesRoot)\n for (const path of orphanPaths) entries.push(makeOrphanPlanEntry(path, input.protectedPaths))\n }\n return entries\n}\n\n// ── apply ────────────────────────────────────────────────────────────\n\nexport interface ApplyGcOptions {\n repoRoot: string\n repoName: string\n forge: ForgeClient\n memo: VerdictMemoStore\n defaultBranchRef?: string\n sessionsPath?: string\n includeDetached?: boolean\n /** Archive (salvage-then-remove) every salvage-class entry. Default false — salvage entries are left untouched. */\n salvageDirty?: boolean\n now?: () => string\n /** See `ComputeWorktreeStatusInput.nowMs` (status.ts) — kept separate from `now`. Defaults to `Date.now()`. */\n nowMs?: number\n /** Override for `~/.agentproto/worktree-salvage` — tests use a temp dir. */\n salvageRoot?: string\n /** See `PlanGcInput.protectedPaths` — re-checked here at apply time (layer 2), independent of what the plan entry says, so a stale plan can never remove a now-protected path. */\n protectedPaths?: string[]\n /** See `PlanGcInput.noisePaths`. */\n noisePaths?: readonly string[]\n}\n\nexport type GcApplyOutcome =\n | { path: string; branch: string | null; result: \"reclaimed\"; reclaimReason?: GcReclaimReason }\n | { path: string; branch: string | null; result: \"salvaged\"; salvageDir: string }\n | { path: string; branch: string | null; result: \"held\"; holdReason?: GcHoldReason }\n /** Salvage-class, but `--salvage-dirty` was not passed: left untouched by design. */\n | { path: string; branch: string | null; result: \"skipped-dirty\" }\n /** Layer 2: re-classified at apply time to something other than the plan said — refuses rather than acting on a stale plan. */\n | { path: string; branch: string | null; result: \"aborted-reclassified\"; from: GcClass; to: GcClass; holdReason?: GcHoldReason }\n /** The worktree named in the plan no longer exists (already removed by something else since the plan was made). */\n | { path: string; branch: string | null; result: \"aborted-vanished\" }\n /** git itself (or the salvage snapshot) refused — the TOCTOU backstop actually firing, or a real I/O failure. */\n | { path: string; branch: string | null; result: \"failed\"; message: string }\n\nasync function findWorktree(repoRoot: string, path: string): Promise<GitWorktreeRef | null> {\n const worktrees = await linkedWorktreesOf(repoRoot)\n return worktrees.find((w) => w.path === path) ?? null\n}\n\n/**\n * Put every noise path back the way git's non-force removal needs it: a\n * tracked one restored to HEAD (index and working tree), an untracked one\n * deleted. Only ever the exact paths the fresh re-check reported as noise.\n */\nasync function discardNoise(repoRoot: string, worktreePath: string, noise: readonly string[]): Promise<void> {\n for (const path of noise) {\n const tracked = await execArgv(\"git\", [\"-C\", worktreePath, \"ls-files\", \"--error-unmatch\", \"--\", path], repoRoot)\n if (tracked.exitCode === 0) {\n await execGit(repoRoot, [\"-C\", worktreePath, \"checkout\", \"HEAD\", \"--\", path])\n } else {\n await rm(join(worktreePath, path), { force: true })\n }\n }\n}\n\nasync function reclaimOne(\n options: ApplyGcOptions,\n worktree: GitWorktreeRef,\n reclaimReason?: GcReclaimReason,\n tree?: TreeState,\n): Promise<GcApplyOutcome> {\n try {\n if (tree?.state === \"clean\" && tree.noise?.length) await discardNoise(options.repoRoot, worktree.path, tree.noise)\n await runTool({\n tool: cleanupWorktreeTool,\n candidates,\n input: {\n repoRoot: options.repoRoot,\n cwd: worktree.path,\n ...(worktree.branch ? { branch: worktree.branch } : {}),\n // Branch deletion only ever runs for a `reclaim`-class entry, which by\n // construction requires `integration ∈ {merged(*), fresh}` and\n // `tree = clean` (PLAN.md's invariant: branch -D only when there's\n // nothing uncommitted to lose, never a hold class).\n deleteBranch: true,\n // No discardUntracked/discardModified, ever, on this path (PLAN.md\n // §5.2 layer 3): `reclaim` means `tree = clean`, so plain `git\n // worktree remove` should succeed on its own; if the tree turned\n // dirty in the instant between the re-check above and this call, git\n // itself refuses and that refusal surfaces below as `failed` — never\n // a force flag \"just in case.\"\n },\n })\n } catch (err) {\n return {\n path: worktree.path,\n branch: worktree.branch,\n result: \"failed\",\n message: err instanceof Error ? err.message : String(err),\n }\n }\n return {\n path: worktree.path,\n branch: worktree.branch,\n result: \"reclaimed\",\n ...(reclaimReason ? { reclaimReason } : {}),\n }\n}\n\nasync function salvageOne(options: ApplyGcOptions, worktree: GitWorktreeRef): Promise<GcApplyOutcome> {\n let salvageDir: string\n try {\n const result = await salvageWorktree({\n repoRoot: options.repoRoot,\n repoName: options.repoName,\n worktreePath: worktree.path,\n branch: worktree.branch,\n tipSha: worktree.head,\n slug: worktree.branch ?? basename(worktree.path),\n sessionsPath: options.sessionsPath,\n now: options.now,\n salvageRoot: options.salvageRoot,\n })\n salvageDir = result.dir\n } catch (err) {\n return {\n path: worktree.path,\n branch: worktree.branch,\n result: \"failed\",\n message: `salvage failed, nothing removed: ${err instanceof Error ? err.message : String(err)}`,\n }\n }\n\n try {\n await runTool({\n tool: cleanupWorktreeTool,\n candidates,\n input: {\n repoRoot: options.repoRoot,\n cwd: worktree.path,\n ...(worktree.branch ? { branch: worktree.branch } : {}),\n deleteBranch: true,\n // Both discard flags: the snapshot above is already durable (fsynced)\n // before this call, so nothing on disk is lost by discarding it here\n // (PLAN.md §5.2 layer 4 — salvage before discard).\n discardUntracked: true,\n discardModified: true,\n },\n })\n } catch (err) {\n return {\n path: worktree.path,\n branch: worktree.branch,\n result: \"failed\",\n message: `salvaged to ${salvageDir}, but removal failed: ${err instanceof Error ? err.message : String(err)}`,\n }\n }\n\n return { path: worktree.path, branch: worktree.branch, result: \"salvaged\", salvageDir }\n}\n\nasync function applyOne(entry: GcPlanEntry, options: ApplyGcOptions): Promise<GcApplyOutcome> {\n // Layer 2's own layer 2: re-checked first, ahead of every other branch\n // below (orphan or linked, whatever the plan's stale `class` says) — a\n // path named in `options.protectedPaths` is NEVER touched, even when the\n // plan itself was built before the path became protected (e.g. a session\n // started using this cwd after the plan was made but before apply ran).\n if (isProtectedPath(entry.path, options.protectedPaths)) {\n if (entry.class === \"hold\") {\n return { path: entry.path, branch: entry.branch, result: \"held\", holdReason: \"live-session-cwd\" }\n }\n return {\n path: entry.path,\n branch: entry.branch,\n result: \"aborted-reclassified\",\n from: entry.class,\n to: \"hold\",\n holdReason: \"live-session-cwd\",\n }\n }\n // Orphan entries never go through `findWorktree`/`computeWorktreeStatus`\n // below — those assume `git worktree list` still knows about the entry,\n // which is exactly what an orphan means it doesn't. See \"orphan reclaim\"\n // above `reclaimOrphan` for its own from-scratch TOCTOU re-check.\n if (entry.orphan) {\n return reclaimOrphan(entry, options)\n }\n // Prunable entries never go through `computeWorktreeStatus` below either —\n // that would spawn `git status` against a working directory that's gone,\n // the exact throw this whole path exists to avoid. See \"prunable reclaim\"\n // above `reclaimPrunable` for its own from-scratch TOCTOU re-check.\n if (entry.prunable) {\n return reclaimPrunable(entry, options)\n }\n if (entry.class === \"hold\") {\n return { path: entry.path, branch: entry.branch, result: \"held\" }\n }\n if (entry.class === \"salvage\" && !options.salvageDirty) {\n return { path: entry.path, branch: entry.branch, result: \"skipped-dirty\" }\n }\n\n // Layer 2 (PLAN.md §5.2): re-check immediately before touching anything.\n // Re-derive the worktree ref itself, not just its status — a branch can\n // flip between plan and apply (the rendezvous-deploy branch-flip mid-\n // session is the plan's own existence proof for this), so re-listing\n // `git worktree list` is required, not just recomputing against the\n // plan's stale (path, branch, head) tuple.\n const fresh = await findWorktree(options.repoRoot, entry.path)\n if (!fresh) {\n return { path: entry.path, branch: entry.branch, result: \"aborted-vanished\" }\n }\n const status = await computeWorktreeStatus({\n repoRoot: options.repoRoot,\n repoName: options.repoName,\n worktree: fresh,\n forge: options.forge,\n memo: options.memo,\n defaultBranchRef: options.defaultBranchRef,\n sessionsPath: options.sessionsPath,\n now: options.now,\n noisePaths: options.noisePaths ?? DEFAULT_GC_NOISE_PATHS,\n })\n // Re-resolved from scratch — including the dep-bump exemption, not just\n // `entry`'s stale plan-time verdict, so a worktree that picked up a real\n // (non-bump) commit between plan and apply is re-caught here, not just at\n // plan time.\n const resolved = await resolveGcClass(status.tree, status.integration, status.liveness, {\n repoRoot: options.repoRoot,\n tipSha: fresh.head,\n defaultBranchRef: options.defaultBranchRef,\n includeDetached: Boolean(options.includeDetached),\n nowMs: options.nowMs,\n })\n if (resolved.class !== entry.class) {\n return {\n path: entry.path,\n branch: fresh.branch,\n result: \"aborted-reclassified\",\n from: entry.class,\n to: resolved.class,\n }\n }\n\n if (resolved.class === \"reclaim\") return reclaimOne(options, fresh, resolved.reclaimReason, status.tree)\n // The only other class that reaches this point is \"salvage\" with\n // `options.salvageDirty` true (both earlier guards above already returned\n // for \"hold\" and for \"salvage\" without the flag).\n return salvageOne(options, fresh)\n}\n\n/**\n * Execute a plan (PLAN.md §5.2 layers 2–4). Every entry is re-classified\n * from scratch immediately before it's touched; a `hold` entry is never\n * touched, a `salvage` entry is only touched when `salvageDirty` is true,\n * and every removal goes through `worktree.cleanup` — never a hand-rolled\n * `git worktree remove`.\n */\nexport async function applyGc(plan: readonly GcPlanEntry[], options: ApplyGcOptions): Promise<GcApplyOutcome[]> {\n const outcomes: GcApplyOutcome[] = []\n for (const entry of plan) {\n outcomes.push(await applyOne(entry, options))\n }\n return outcomes\n}\n\n// ── single-worktree reclaim (session exit-time auto-reclaim) ───────────────\n//\n// A policy-provisioned (implicit) worktree — one `decideWorktreeIsolation`'s\n// `\"always\"` branch minted for a caller who never asked to keep it (see that\n// module's `WorktreeDecision.provision.implicit`) — is a candidate for\n// reclaim the moment its own session exits, rather than sitting until the\n// next manual/scheduled `gc` sweep. This is deliberately scoped to ONE\n// worktree — a session's own exit must never sweep or touch any OTHER\n// worktree in the pool — and deliberately reuses `applyGc`'s existing\n// classify → re-verify → remove pipeline (a plan of size one) rather than\n// hand-rolling a second removal path with its own safety logic to keep in\n// sync.\n\n/**\n * Attempt to reclaim exactly one worktree by path — the exit-time auto-\n * reclaim primitive `sessions.ts` calls (via the injected\n * `WorktreeAutoReclaimer` port) when a policy-provisioned session reaches a\n * terminal state. Classifies it fresh (never trusts a caller-supplied\n * verdict) and only ever removes it when that classification is `reclaim`\n * (merged-or-fresh, clean, idle) — a dirty or held worktree is returned\n * as-is, exactly like any other `gc` outcome, still visible via\n * `worktree_status` and still manually reclaimable. Returns `null` when the\n * path no longer names a linked worktree at all (already removed by\n * something else — nothing to do, not an error).\n */\nexport async function reclaimOneWorktree(\n worktreePath: string,\n options: ApplyGcOptions & { includeDetached?: boolean },\n): Promise<GcApplyOutcome | null> {\n const worktree = await findWorktree(options.repoRoot, worktreePath)\n if (!worktree) return null\n if (worktree.prunable) {\n return applyOne(makePrunablePlanEntry(worktree, options.protectedPaths), options)\n }\n const status = await computeWorktreeStatus({\n repoRoot: options.repoRoot,\n repoName: options.repoName,\n worktree,\n forge: options.forge,\n memo: options.memo,\n defaultBranchRef: options.defaultBranchRef,\n sessionsPath: options.sessionsPath,\n now: options.now,\n noisePaths: options.noisePaths ?? DEFAULT_GC_NOISE_PATHS,\n })\n const entry = await toPlanEntry(\n options.repoRoot,\n options.defaultBranchRef,\n worktree,\n status,\n Boolean(options.includeDetached),\n options.nowMs ?? Date.now(),\n options.protectedPaths,\n )\n return applyOne(entry, options)\n}\n"]}