/** * v3 state — materialize the journal into a run snapshot + STATE checkpoint. * * Two-layer truth (codex v1-review blocker #1): * - `journal.ndjson` (journal.ts) = append-only audit truth * - `STATE` (this file) = materialized checkpoint, derived by replaying the * journal. Cheap to grep, fast for the dashboard / a human to read, and * re-derivable at any time so it never becomes an independent source of * truth that can drift from the journal. * * Resume after a daemon restart replays the journal through `materialize` * (correctness first); the on-disk STATE file is an observability artifact and * a fast-path the runtime refreshes after every event. */ import type { StoredEvent, V3RunFailureReason, V3UncertainHostEffect } from './journal.js'; import type { V3EdgeRunState, V3LoopRunState, V3RunState } from './orchestrator.js'; export type V3RunStatus = 'running' | 'cancelling' | 'cancelled' | 'succeeded' | 'failed' | 'blocked'; export interface V3RunSnapshot { runStatus: V3RunStatus; /** First-wins durable cancellation boundary. Once present, later ordinary * dispatch/settle events are audit-only and cannot revive the run. */ cancelRequestId?: string; cancelRequestedBy?: string; /** External effects that may have been applied even though the run reached * cancellation. Safe, bounded identities only — never provider payloads. */ uncertainHostEffects?: V3UncertainHostEffect[]; /** Set once `runFailed` is observed — the node that triggered fail-fast. */ failedNodeId?: string; /** Workflow-level failure reason; ordinary node failures keep using * `failedNodeId`. */ failureReason?: V3RunFailureReason; /** Human-readable detail for workflow-level failures. */ failureDetail?: string; /** Set once `runBlocked` is observed — the blocked node (cleared back to * running by a subsequent `nodeRetryRequested` on replay). */ blockedNodeId?: string; /** nodeId → current node state (the input `decideNext` consumes). For a * node with runtime instances, `.effectiveInstanceId` points at its live * instance. */ nodes: V3RunState; /** instanceId (`A#001`) → that runtime instance's state (incl. `superseded`). * Empty for runs that never used the instance layer (plain nodeId events). */ instances: V3RunState; /** nodeId → the attemptId of its latest dispatch — or, after a * `nodeRetryRequested`, the reserved `nextAttemptId` the retry will use. */ attempts: Map; /** loopId → composite loop state (iteration cursor / decision / grants). */ loops: V3LoopRunState; /** `${from}->${to}` → conditional edge verdicts folded from edgeResolved. */ edges: V3EdgeRunState; } /** * Fold the journal into a snapshot. Pure — same events always yield the same * snapshot, which is what makes STATE safe to throw away and re-derive. * * Node status transitions: * nodeDispatched → running (preserve gateCleared across the transition) * nodeSucceeded → done * nodeFailed → failed * nodeBlocked → blocked * nodeRetryRequested → pending (+ attempt reservation; run blocked→running) * gateDispatched → gateWaiting * gateResolved/ok → pending + gateCleared (next tick dispatches work) * gateResolved/no → failed * edgeResolved → edges[first `${from}->${to}`] (first-wins) * nodeSkipped → skipped * nodeCancelled → cancelled (settle-wins; late same-attempt settle ignored) * nodeAttemptDrained → pending only when the exact current attempt was * still running; otherwise resource-audit only */ export declare function materialize(events: StoredEvent[]): V3RunSnapshot; /** * Write the snapshot to `statePath` atomically: write a sibling `.tmp` then * `rename` over the target (rename is atomic on the same filesystem), so a * crash mid-write never leaves a half-written STATE — readers see either the * old or the new file, never a torn one. */ export declare function writeState(statePath: string, snap: V3RunSnapshot): void; /** Read a previously-written STATE checkpoint back into a snapshot. Returns * `undefined` when absent. Resume normally prefers `materialize(readJournal)` * (the journal is authoritative); this is for fast reads / observability. */ export declare function readState(statePath: string): V3RunSnapshot | undefined; //# sourceMappingURL=state.d.ts.map