/** SDK-owned platform module. This implementation is maintained in goodvibes-sdk. */ import type { PhaseRunnerAgentManagerLike, WrfcWorktreeOps } from './phase-runner.js'; import { type EdgeAddResult, type WorkstreamGraphSnapshot } from './graph-dynamics.js'; import { type FleetCapacityFn } from './elastic-pool.js'; import { type BudgetCeiling, type OrchestrationEventListener, type Phase, type PhaseResult, type PhaseSpec, type PriceProvenanceFn, type WorkItemSpec, type WorkItemUsage, type Workstream, type WorkstreamIsolation, type WorkstreamProvenance, type ReleasePolicy, type AttemptJudge, type AttemptJudgment, type AttemptPickResult, type HeldMergeGroup } from './types.js'; import type { ConfigManager } from '../config/manager.js'; import type { RuntimeEventBus } from '../runtime/events/index.js'; export interface OrchestrationEngineDeps { readonly agentManager: PhaseRunnerAgentManagerLike; readonly configManager: Pick; readonly runtimeBus: RuntimeEventBus; readonly projectRoot: string; readonly sessionId?: string | undefined; readonly createWorktree?: (() => WrfcWorktreeOps) | undefined; readonly priceUsage?: ((model: string | undefined, usage: WorkItemUsage) => number | null) | undefined; /** Provenance for the same resolution priceUsage prices with, stamped onto committed usage records at pricing time. */ readonly priceProvenance?: PriceProvenanceFn | undefined; readonly skipClaimVerification?: boolean | undefined; /** Bounds re-review cycles through a dynamically-inserted fix phase. Default 5. */ readonly maxPhaseVisits?: number | undefined; readonly now?: (() => number) | undefined; /** Set false to skip wiring the debounced disk writer (tests that don't want filesystem side effects). Default true. */ readonly persist?: boolean | undefined; /** Kept-worktree retention bound before oldest-first eviction (worktree mode). Default 20. */ readonly keptWorktreeCap?: number | undefined; /** Cold-start worktree setup hook (deps install, .env carry-over); wired by the composition root; a failing setup never fails creation. */ readonly runWorktreeSetup?: ((worktreePath: string) => Promise | void) | undefined; /** Optional best-of-N judge (PROPOSES a winner; never auto-picks unless the item opted in). Injectable, provider-agnostic. */ readonly judgeAttempts?: AttemptJudge | undefined; /** Live probe of the ONE fleet ceiling (fleet.maxSize) for elastic workstreams; absent = ungated (legacy). */ readonly fleetCapacity?: FleetCapacityFn | undefined; /** Bounded per-task auto-retries before hard-fail (elastic fix graphs). Default 0 = off (legacy). */ readonly maxItemRetries?: number | undefined; /** In-phase items with no observed activity past this window carry the stalled tell. Default 10 minutes. */ readonly stallAfterMs?: number | undefined; } export interface CreateWorkstreamInput { readonly id?: string | undefined; readonly title: string; readonly phases: readonly PhaseSpec[]; readonly items: readonly WorkItemSpec[]; readonly budget?: BudgetCeiling | undefined; /** * Where this workstream's item phases run their file changes. Omitted * (the default) ⇒ `'shared'`, every existing caller's behavior is * unchanged. See {@link WorkstreamIsolation} (types.ts) for the full * contrast with `'worktree'` mode. */ readonly isolation?: WorkstreamIsolation | undefined; /** Workstream provenance (set by fromPlanProposal; omitted by compat callers). */ readonly provenance?: WorkstreamProvenance | undefined; /** Edge-release policy; 'reviewed-and-merged' also engages the elastic pool. Absent = 'passed' (legacy). */ readonly releasePolicy?: ReleasePolicy | undefined; } export interface OrchestrationEngine { createWorkstream(input: CreateWorkstreamInput): Workstream; getWorkstream(id: string): Workstream | null; listWorkstreams(): Workstream[]; insertPhase(workstreamId: string, afterOrdinal: number, spec: PhaseSpec): Phase | null; /** Begin (or resume ticking) a workstream's pipeline. Idempotent. */ start(workstreamId: string): void; /** Abort an item's in-flight agent and mark it terminally failed (siblings untouched). */ kill(itemId: string): boolean; /** Replace/clear a workstream's budget ceiling and re-tick (the 'blocked-budget' recovery path). */ updateBudget(workstreamId: string, ceiling: BudgetCeiling | undefined): boolean; /** Reset a terminally-FAILED item to re-run from its first phase (the failed-dependency recovery path); re-ticks immediately. */ retryItem(itemId: string): boolean; getPhaseResults(workstreamId: string): readonly PhaseResult[]; /** Best-of-N: held-merge groups awaiting a winner pick. */ listHeldMergeGroups(workstreamId?: string): Promise; /** Best-of-N: accept a winner (merges through the lane; losers cleaned). */ pickAttemptWinner(groupId: string, winnerItemId: string): Promise; /** Best-of-N: judge the candidates and PROPOSE a winner (never auto-picks). */ proposeAttemptWinner(groupId: string): Promise; /** Stamp the conflict-resolution session id onto a conflicted item. */ stampConflictSession(itemId: string, sessionId: string): boolean; /** Re-attempt a conflicted item's merge through the same lane. */ retryItemIntegration(itemId: string): Promise<'merged' | 'conflict' | 'not-conflicted'>; /** Add a dependency edge LIVE (a discovered missed dependency / manual serialization). Cycles are refused with a structured graph-cycle outcome. */ addDependency(itemId: string, dependsOnId: string, reason: string): EdgeAddResult | null; /** Re-queue a non-terminal item to its first phase (the discovering task's "may re-queue"); cancels its in-flight agent. */ requeueItem(itemId: string, reason: string): boolean; /** The surface-facing task graph: nodes, edges, states, elastic-pool state, stalled tells. */ getGraphSnapshot(workstreamId: string): WorkstreamGraphSnapshot | null; serializeWorkstream(workstreamId: string): string | null; /** Import a serialized snapshot; refuses to clobber a non-terminal workstream unless forced. */ importWorkstream(snapshotJson: string, force?: boolean): boolean; /** Import + start from the on-disk snapshot for one workstream id. */ resumeWorkstream(workstreamId: string): boolean; /** Import + start every on-disk snapshot; returns the count resumed. */ resumeAllFromDisk(): number; on(listener: OrchestrationEventListener): () => void; dispose(): void; } export declare function createOrchestrationEngine(deps: OrchestrationEngineDeps): OrchestrationEngine; //# sourceMappingURL=engine.d.ts.map