/** * File Durable Mission Store (2.4.0). * * Concrete local implementation of the DurableMissionStore port. Records are * written atomically (unique temp + fsync + rename) so a process exit never * leaves a partially-written authoritative record. On load, records are * schema-validated and corruption is surfaced structurally — never silently * dropped and never fabricated into a default success. * * File naming is derived only from the stable `missionId` (a safe path * component), never from untrusted objective text. * * Concurrency model (cross-process): * - Each write uses a per-write unique temp path (never shared), so two * writers cannot truncate/rename one another's temp file. * - Every mutation (`create`, `save`, `mutate`) is serialized by a * per-(root, missionId) cross-process file lock (proper-lockfile, atomic * exclusive lock-directory creation). Two independent OS processes cannot * interleave a read-check-write critical section. * - The optimistic `revision` compare-and-save therefore is atomic across * processes: exactly one writer wins, the stale writer receives a * structural `{ status: "stale" }`. * - Execution-authoritative saves may additionally carry a `leaseProof`; * the store verifies the current durable lease under the same critical * section and rejects stale owners (see `ExecutionLease`). * * Durability policy: * - The temp file is fsynced, then atomically renamed over the target. * - The containing directory is NOT fsynced after rename, matching the * strongest existing Jensen convention (MissionFileStore and MissionStore * also omit directory fsync). On POSIX this means the file CONTENT is * durable and the rename is atomic, but a sudden power loss could in * theory lose the directory entry. This is the same guarantee the rest of * the Jensen durability layer provides; it is not weakened or strengthened * here. */ import { type DurableMissionCreateResult, type DurableMissionLoadResult, type DurableMissionMutateResult, type DurableMissionMutation, type DurableMissionRecord, type DurableMissionSaveOptions, type DurableMissionSaveResult, type DurableMissionStore } from "../mission-domain/durable-store.js"; export interface FileDurableMissionStoreOptions { root: string; /** Store identity (defaults to "file"). */ storeId?: string; /** Cross-process mutation lock staleness window. */ lockStaleMs?: number; lockRetries?: number; lockMinTimeoutMs?: number; lockMaxTimeoutMs?: number; } export declare function defaultDurableMissionRoot(): string; export declare class FileDurableMissionStore implements DurableMissionStore { readonly storeId: string; private readonly root; private readonly lockStaleMs; private readonly lockRetries; private readonly lockMinTimeoutMs; private readonly lockMaxTimeoutMs; constructor(options: FileDurableMissionStoreOptions); private resolve; private assertMissionId; private writeAtomic; private readRaw; private withFileLock; private readParsed; create(record: DurableMissionRecord): Promise; load(missionId: string): Promise; save(record: DurableMissionRecord, options?: DurableMissionSaveOptions): Promise; mutate(missionId: string, mutation: (current: DurableMissionRecord) => DurableMissionMutation): Promise>; listMissions(): Promise; listNonterminalMissions(): Promise; listChildren(parentMissionId: string): Promise; } /** * Convenience factory using the default Jensen state directory. */ export declare function createFileDurableMissionStore(root?: string): FileDurableMissionStore; //# sourceMappingURL=file-durable-mission-store.d.ts.map