/** * Durable Delegation (2.5.0). * * Production orchestration seam that turns a delegated child into a durable * first-class mission BEFORE external execution begins. This module composes * the canonical mission domain (DurableMissionCoordinator + MissionExecutor) * with a shared DurableMissionStore; it does not import process, provider, * CLI, or UI machinery — the execution mechanism arrives behind the * MissionExecutor seam. * * Invariants: * - A child mission exists durably at CREATED before any executor.launch. * - The coordinator owns every authoritative lifecycle transition * (CREATED → QUEUED → LAUNCHING + attemptId → RUNNING + executionId → * terminal); the caller never drives the executor directly. * - Parent identity is structured (`missionId` + `depth`), never PID-derived. * - Recovery (restart reconciliation) never auto-runs child work; it is a * read-only store pass that marks lost ownership INTERRUPTED. */ import { type DurableRecoveryReport } from "../mission-domain/durable-coordinator.js"; import type { DurableMissionRecord, DurableMissionStore } from "../mission-domain/durable-store.js"; import type { HeartbeatScheduler, HeartbeatTelemetry } from "../mission-domain/execution-heartbeat.js"; import { type ExecutionLease, type ExecutionLeaseProof } from "../mission-domain/execution-lease.js"; import type { MissionExecutor } from "../mission-domain/mission-executor.js"; import { type MissionRequest } from "../mission-domain/mission-request.js"; import type { MissionResult } from "../mission-domain/mission-result.js"; /** Structured parent mission identity (never PID-derived). */ export interface DelegationParentIdentity { missionId: string; depth: number; } /** The durable + canonical outcome of one delegated child. */ export interface DurableDelegationChildOutcome { missionId: string; parentMissionId?: string; depth: number; /** Terminal durable record (authoritative lifecycle history). */ record: DurableMissionRecord; /** Canonical terminal result (the parent consumes this, not prose). */ result: MissionResult; /** Durable attempt identity allocated before launch. */ attemptId: string; /** Executor execution identity attached after launch (when launch succeeded). */ executionId?: string; /** Fencing epoch of the winning execution (ownership authority epoch). */ fencingToken: number; /** Latest heartbeat telemetry for this execution (observability). */ heartbeatTelemetry?: HeartbeatTelemetry; } export interface DurableMissionDelegatorOptions { store: DurableMissionStore; /** Now override for deterministic construction (tests). */ now?: () => number; /** Attempt identity factory (tests). */ attemptIdFactory?: () => string; /** Executor owner identity (defaults to a fresh host+UUID identity). */ ownerId?: string; /** Execution lease lifetime override. */ leaseDurationMs?: number; /** Lease identity factory (tests). */ leaseIdFactory?: () => string; /** Heartbeat renewal cadence override (defaults to leaseDurationMs / 3). */ heartbeatIntervalMs?: number; /** Heartbeat safety margin override (defaults to leaseDurationMs / 6). */ renewalSafetyMarginMs?: number; /** Injectable timer scheduler for deterministic heartbeat tests. */ heartbeatScheduler?: HeartbeatScheduler; } /** * Deterministic, session-scoped, non-PID identity for the transitional * root-delegation anchor used when no active first-class/reliability mission * exists. It is a safe path component and never derived from process state. */ export declare function rootDelegationMissionId(sessionId: string): string; /** * Resolve the delegation parent identity from the active reliability mission * id when present; otherwise fall back to the deterministic session-scoped * root-delegation anchor. Depth is always 0 for the root parent. */ export declare function parentIdentityFor(activeMissionId: string | undefined, sessionId: string): DelegationParentIdentity; export declare class DurableMissionDelegator { private readonly _store; private readonly _coordinatorOptions; private readonly _ownerId; constructor(options: DurableMissionDelegatorOptions); /** The underlying persistence port (tests/load paths). */ get store(): DurableMissionStore; /** Stable executor owner identity used for lease acquisition. */ get ownerId(): string; /** Build a coordinator bound to one child's execution mechanism. */ private coordinator; /** * Ensure the transitional root-delegation anchor exists durably at CREATED. * Idempotent across calls (the request is fully deterministic so a re-create * with the same identity is recognized, never a conflict). */ ensureRootDelegationMission(sessionId: string): Promise; /** * Persist a child mission at CREATED. Does not launch anything. The caller * supplies the execution mechanism so launch can never precede durable * creation — the coordinator persists first and only then invokes it. */ createChild(request: MissionRequest, executor: MissionExecutor): Promise; /** * Create + run one child to a terminal durable state. The child is persisted * at CREATED before `executor.launch`; then QUEUED, LAUNCHING (attemptId), * RUNNING (executionId) and finally a terminal result are persisted around * the executor call. The caller never drives the executor directly. */ executeChild(request: MissionRequest, executor: MissionExecutor, options?: { signal?: AbortSignal; }): Promise; /** * Explicitly resume an interrupted child to terminal state. Does NOT create * the mission (it must already exist durably). Allocates a NEW execution * attempt while preserving the prior attempt history and the immutable * mission/session identity. */ resumeMission(missionId: string, executor: MissionExecutor, options?: { signal?: AbortSignal; }): Promise; private _outcome; /** Load a mission record, or `undefined` when missing. Corrupt records throw. */ getMission(missionId: string): Promise; listMissions(): Promise; listNonterminalMissions(): Promise; listChildren(parentMissionId: string): Promise; /** * Restart reconciliation: mark lost executor ownership INTERRUPTED. Never * launches work and never fabricates success. See DurableMissionCoordinator. */ recover(options?: { now?: number; }): Promise; /** Atomically acquire execution ownership without invoking the executor. */ acquireOwnership(missionId: string): Promise<{ record: DurableMissionRecord; lease: ExecutionLease; }>; /** Renew a live lease (heartbeat). Does not change the fencing token. */ renewOwnership(missionId: string, proof: ExecutionLeaseProof, options?: { now?: number; }): Promise<{ lease: ExecutionLease; record: DurableMissionRecord; }>; /** Release a live lease without reaching a terminal state. */ releaseOwnership(missionId: string, proof: ExecutionLeaseProof, options?: { now?: number; }): Promise; } //# sourceMappingURL=durable-delegation.d.ts.map