// types.ts — shared event/result shapes for the orchestrator lifecycle. // The engine (core.ts), verdict parsing (verdict.ts) and run-id collection // (run-ids.ts) all speak these types; keeping them here avoids import cycles. // --------------------------------------------------------------------------- // Types // --------------------------------------------------------------------------- export type TickReason = "dispatch" | "intake" | "review" | "failure" | "budget"; // reason semantics: // dispatch/intake — queue-capacity nudges (decideTick) // review — reviewer/verdict routing + stuck-review nudges // failure — a worker run FAILED (budget-capped or verdict) — the // operator must see it and re-dispatch / recover // budget — an ACTIVE run has consumed ~75%+ of its recorded // wall-clock budget (timeoutMs) — proactive cap warning export interface Tick { reason: TickReason; /** Human/LLM-readable tick message (the orchestrator consumes this). */ message: string; /** Machine-readable facts the orchestrator can use without re-deriving. */ facts: Record; } export interface CompletionEvent { runId?: string; id?: string; agent?: string | null; success?: boolean; status?: string; // "completed" | "failed" | "stopped" | "detached" | ... timedOut?: boolean; stopped?: boolean; summary?: string; sessionFile?: string; results?: Array>; /** AUTOPILOT-85: the branch the RUNNER reports this run wrote to, when it * knows one (the managed-worktree branch the backend checked out for this * run) — named explicitly because worktree-preservation's own live-repo * discovery (parallelBranches: path-matched worktree + legacy ref-prefix) * can find NOTHING for a run whose worktree/branch the runtime already * deleted by the time the completion event arrives (documented in * worktree-preservation.ts's header — cleanup runs in the runtime's own * finally-block, BEFORE this event). Passing the name through here lets * preserveRunWorktree attempt it directly (still fails closed — gone is * gone — but covers the race where the ref is still resolvable and the * discovery patterns simply never matched the name). Absent/null = the * runner has no branch to report; discovery is the only path. */ branch?: string | null; /** KEY: AUTOPILOT-104 — the queue item KEY the run's OWN task names (the * `KEY: ` line every harness task starts with, read from the run record * when the backend can). Used as a FALLBACK attribution for a reviewer * completion whose dispatch-time `reviewerRunId` link is missing — a * reviewer dispatched before its item reached `ai-review` has that ref * cleared by the entering-ai-review stamp, and requiring it alone dropped a * genuine PASS silently. Absent when the backend cannot read the task. */ itemKey?: string; [k: string]: unknown; } export interface DomainEvent { name: string; data: Record; } export interface AutopilotResult { tick: Tick | null; /** Structured domain events (orch:item-completed, orch:verdict, ...) — the * only machine channel; the adapter publishes them on the platform bus. */ domainEvents: DomainEvent[]; /** true when the completion was attributed to a store item and flipped. */ flipped: boolean; /** true when the completed run freed a worker slot (flipped or ledger-tracked). */ freedSlot: boolean; /** true when the completed run was a REVIEWER (its verdict needs routing). */ reviewerCompleted: boolean; }