import type { CampaignStatus, Clock, KernelPaths, RunRecord, TaskRecord } from "./types.js"; import type { StopAdapter } from "./result-service.js"; export interface UnboundLaunchStopInput { readonly operation_id: string; readonly identity_digest: string; readonly task_id: string; readonly attempt: number; readonly pane_id?: string; readonly session_id: string; readonly launch_operation_id: string; readonly launch_effect_operation_id: string; readonly launch_identity_digest: string; readonly physical_nonce: string; readonly launch_source_operation_id: string; } /** * Recovery-only physical stop for a pane whose launch receipt exists before * the task binding, or whose deterministic launch window exists after intent. */ export interface UnboundLaunchStopAdapter { readonly inspectUnboundLaunchExact: (input: UnboundLaunchStopInput) => { readonly ok: true; } | { readonly ok: false; readonly reason: string; readonly absent?: boolean; readonly ambiguous?: boolean; }; readonly createUnboundLaunchExact: (input: UnboundLaunchStopInput) => { readonly ok: true; } | { readonly ok: false; readonly reason: string; readonly ambiguous?: boolean; }; } export interface StopCampaignOptions { readonly paths: KernelPaths; readonly clock: Clock; readonly reason: string; readonly removeWatchdog?: boolean; readonly workspaceRoot?: string; /** * Optional durable binding (conductor MCP must supply its bound session). * Checked under the kernel lock against the journal-authoritative run. */ readonly expectedConductorSessionId?: string | null; readonly expectedRunId?: string; /** Injected for tests: simulate critical-section wait. */ readonly waitMs?: number; readonly sleeper?: (ms: number) => void; /** * Production physical boundary. When supplied, every launch-bound worker is * stopped by exact tmux identity and confirmed before the run terminalizes. */ readonly stopAdapter?: StopAdapter & Partial; } export interface StopCampaignResult { readonly run: RunRecord; readonly alreadyTerminal: boolean; /** Exact launch-bound workers physically stopped and confirmed. */ readonly workersStopped: number; } /** * Terminal, idempotent, non-destructive campaign stop. * Preserves worktrees, journal, branches, draft PRs, and ambiguous side-effect records. * * Initial decision uses the journal-authoritative run under the kernel lock. * Both stopping and terminal transitions carry the same expected run/session binding. */ export declare function stopCampaign(options: StopCampaignOptions): StopCampaignResult; export declare function confirmExactWorkerStopped(options: { readonly paths: KernelPaths; readonly clock: Clock; readonly expectedRunId: string; readonly expectedRunVersion: number; readonly expectedRunStatus: CampaignStatus; readonly task: TaskRecord; readonly stopAdapter?: StopAdapter; }): { readonly launchBound: boolean; }; export declare function expireDeadline(paths: KernelPaths, clock: Clock, reason?: string, expected?: { readonly runId: string; readonly runVersion: number; }, stopAdapter?: StopAdapter & Partial): RunRecord;