Skip to content

DrainService

Defined in: src/drain.ts:177

Side-effect harness for the self-draining work queue. It assembles a DrainRepoState per repo, calls the pure computeNext core, and applies the returned decision (spawn / retire / hold), looping until the core holds. Driven by pr-poller events (onGit/onStatus), the archive event (onArchived), and a periodic tick().

The drain NEVER merges PRs. A ready session is retired (session archived, pane stopped, worktree removed) and its open, issue-linked PR is left for a human to merge. Archiving frees the concurrency slot so the next backlog item can spawn. When the human merges, the Closes #N link auto-closes the issue, preventing re-spawn.

new DrainService(deps): DrainService

Defined in: src/drain.ts:210

DrainDeps

DrainService

approveEpicNext(repoPath): void

Defined in: src/drain.ts:216

Operator approves the next epic-attended spawn for the given repo.

string

void


buildEpic(repoPath, run): Promise<Epic | null>

Defined in: src/drain.ts:257

Assemble the live Epic for this repo’s running epic (used by buildState + server).

string

EpicRun

Promise<Epic | null>


onArchived(id): Promise<void>

Defined in: src/drain.ts:1342

A session was archived (retired auto session, or a manual archive). The single advance step: a freed slot lets the next candidate spawn. Skips drain-disabled repos so a manual archive there doesn’t pump/emit.

string

Promise<void>


onGit(id, git): Promise<void>

Defined in: src/drain.ts:1311

pr-poller observed a new git state for a session.

string

GitState

Promise<void>


onReview(id): Promise<void>

Defined in: src/drain.ts:1389

A critic verdict landed for a session. A clean verdict for the current head may now unblock the retire gate — pump promptly rather than waiting for the tick.

string

Promise<void>


onStatus(id): Promise<void>

Defined in: src/drain.ts:1378

A session’s status changed. Pump its repo, skipping drain-disabled repos.

string

Promise<void>


pump(repoPath): Promise<void>

Defined in: src/drain.ts:970

Drain repoPath: build state → computeNext → apply, until the core holds. Re-entrant-safe via the per-repo pumping lock.

string

Promise<void>


queue(repoPath): Promise<QueuedItem[]>

Defined in: src/drain.ts:1441

The actual backlog issues behind DrainStatus.queued: the not-yet- mapped candidates, in drain order (priority-first per selectCandidates). No side effects. Empty for drain-disabled repos (buildState yields no candidates there — and the forge is never hit).

string

Promise<QueuedItem[]>


retainClaim(id): void

Defined in: src/drain.ts:1383

Used by the merge train: a merge whose closeIssue failed keeps the claim (issue still open).

string

void


snapshot(): Promise<DrainStatus[]>

Defined in: src/drain.ts:1425

Client bootstrap: a status per drain-enabled or epic-running repo, WITHOUT applying side effects (no spawn/retire). Disabled repos with no active epic are skipped.

Promise<DrainStatus[]>


tick(): Promise<void>

Defined in: src/drain.ts:1411

Periodic sweep (~30s): catches newly-labeled issues + resumed usage windows.

Promise<void>