/** SDK-owned platform module. This implementation is maintained in goodvibes-sdk. */ /** * attempts.ts, best-of-N sibling attempts for the orchestration engine. * * A work item declared with `attempts: N` is expanded into N sibling items that * run the SAME pipeline INDEPENDENTLY, each in its own isolated worktree. When a * sibling passes, the engine does NOT auto-merge it: it parks the sibling in the * 'held-merge' state (worktree kept, diff inspectable) and, once EVERY sibling in * the group is terminal, exposes the group's candidates for a winner pick. A * winner is accepted explicitly (fleet.attempts.pick), or PROPOSED by an * optional judge model (fleet.attempts.judge), which only auto-picks when the * source item opted into `autoAcceptWinner`. Picking merges the winner's branch * through the existing sequential integration lane and cleans the losers' * worktrees. * * This coordinator owns the group registry and the pick/judge orchestration; the * engine keeps only thin hooks (expand at create, hold-vs-merge at terminal-pass, * a readiness nudge at terminal-fail) and delegates its public best-of-N methods * here, so engine.ts stays small. */ import { type AttemptJudge, type AttemptJudgment, type AttemptPickResult, type HeldMergeGroup, type OrchestrationEvent, type WorkItem, type WorkItemSpec, type Workstream, type WorkstreamIsolation } from './types.js'; /** Thrown for an honest caller error against the best-of-N surface (unknown group, not-ready, bad winner). */ export declare class AttemptError extends Error { constructor(message: string); } export interface AttemptsCoordinatorDeps { readonly emit: (event: OrchestrationEvent) => void; readonly getWorkstream: (id: string) => Workstream | null; /** Route a (non-attempt terminal-passed item, or a picked winner) onto the sequential integration lane. */ readonly enqueueIntegration: (workstream: Workstream, item: WorkItem) => void; /** Remove a loser's worktree (clean → removed; dirty → kept, the existing cleanup rule). Never throws. */ readonly cleanupWorktree: (workstream: Workstream, item: WorkItem) => Promise; /** The diff a candidate's worktree branch introduced over base, or null if it has no live worktree. */ readonly diffItem: (item: WorkItem) => Promise<{ files: string[]; unifiedDiff: string; stat: string; } | null>; /** Optional model judge. Absent → fleet.attempts.judge honestly reports no judge is configured. */ readonly judge?: AttemptJudge | undefined; } export interface AttemptsCoordinator { /** Expand any `attempts:N` spec into N sibling items (worktree isolation only); pass others through unchanged. */ expandItems(workstreamId: string, isolation: WorkstreamIsolation | undefined, specs: readonly WorkItemSpec[], build: (spec: WorkItemSpec) => WorkItem): WorkItem[]; /** Rebuild the in-memory group registry from an imported workstream's items (resume path). */ reconcileGroups(workstream: Workstream): void; /** At an item's terminal PASS: hold it as a best-of-N candidate, or (non-attempt) enqueue its integration. */ onItemPassedTerminal(workstream: Workstream, item: WorkItem): void; /** At an attempt sibling's terminal FAIL: re-check whether its group is now fully resolved. No-op for non-attempt items. */ onItemFailedTerminal(workstream: Workstream, item: WorkItem): void; /** The held-merge groups (optionally filtered by workstream), each with its candidates' diffs. */ listGroups(workstreamId?: string): Promise; /** Accept a winner: merge it through the integration lane, clean the losers. */ pickWinner(groupId: string, winnerItemId: string): Promise; /** Run the judge over a group's candidates and PROPOSE a winner (never auto-picks here). */ proposeWinner(groupId: string): Promise; } export declare function createAttemptsCoordinator(deps: AttemptsCoordinatorDeps): AttemptsCoordinator; //# sourceMappingURL=attempts.d.ts.map