/** * The two construction-time capability gates described in * [ADR 0002 § Construction-time capability gates](../../../documentation/contributing/architecture-decisions/0002-multiengine-per-workflow-ownership.md#construction-time-capability-gates): * * - **Gate 1 — storage capability.** Fails fast when the configured storage * backend does not support `conditionalBatch`, naming the *configured* * fencing mode in the diagnostic rather than a hardcoded one, so an operator * troubleshooting the shipped `ownership: 'lease'` is not sent chasing * `workflow-lease`, which is unimplemented until a later stage. * - **Gate 2 — ownership-mode marker.** Stamps or verifies the store-wide * `ownership-mode-marker` singleton so `ownership: 'lease'` and * `ownership: 'workflow-lease'` remain mutually exclusive across engine * *processes*, not merely within one process. * * Both gates fire only for the two fencing modes (`'lease'` and * `'workflow-lease'`); `ownership: 'none'` never touches the marker or checks * the capability. {@link bootstrapOwnershipGates} runs them in the ADR's * required order (Gate 1 then Gate 2) and is the unit later wired in front of * claim acquisition, recovery scanning, scheduler polling, and task polling — * that wiring is a later stage and is deliberately not done here. * * @module core/engine/ownership-mode-marker */ import { type Storage } from '../../storage/interface.ts'; import { type FencingOwnershipMode } from './workflow-claim-codec.ts'; /** * Mirrors the full `ownership` discriminant (`EngineConstructorOptions.ownership` * / `ResolvedOptions.ownershipMode`). Duplicated here as a literal union rather * than imported, because neither call site exports a standalone name for it — * importing `ResolvedOptions` would pull in the whole engine-internal-types * surface for one field's type. */ export type EngineOwnershipMode = 'none' | 'lease' | 'workflow-lease'; /** * Gate 1 — storage capability. Fires for `ownership: 'lease'` or * `ownership: 'workflow-lease'`; reuses the existing, untyped `Error` that * {@link requireStorageCapability} already throws. The diagnostic names the * mode that is actually configured — hardcoding `'workflow-lease'` into the * message would misdirect an operator troubleshooting the shipped global * lease toward an unimplemented feature. */ export declare function assertOwnershipStorageCapability(storage: Storage, configuredMode: FencingOwnershipMode): void; /** Input to {@link assertOwnershipModeMarker}. */ export type AssertOwnershipModeMarkerInput = { storage: Storage; /** This engine's configured fencing mode. */ configuredMode: FencingOwnershipMode; /** Engine-clock source (ms), injected so tests can control `establishedAt` deterministically. */ getNow: () => number; }; /** * Gate 2 — ownership-mode marker. Fires immediately after Gate 1 passes, for * the same trigger (`ownership: 'lease'` or `ownership: 'workflow-lease'`; * `ownership: 'none'` never calls this). * * Reads `KEYS.ownershipModeMarker()`. If absent, `conditionalBatch`-puts * `{ mode: configuredMode, establishedAt: now() }` with an expected value of * `null` — the first fencing-mode engine against a fresh store establishes * the mode every later one must agree with. On a CAS loss (another engine won * the race to stamp it), re-reads and compares against that engine's mode * instead, since it is now authoritative. If the stored mode — from either * the initial read or the post-CAS-loss re-read — differs from this engine's * configured mode, throws {@link OwnershipModeMismatchError} before any * further construction proceeds. */ export declare function assertOwnershipModeMarker(input: AssertOwnershipModeMarkerInput): Promise; /** Input to {@link bootstrapOwnershipGates}. */ export type BootstrapOwnershipGatesInput = { storage: Storage; ownershipMode: EngineOwnershipMode; /** Engine-clock source (ms), injected so tests can control `establishedAt` deterministically. */ getNow: () => number; }; /** * Run Gate 1 then Gate 2, in that order, as ADR 0002 requires. No-op for * `ownership: 'none'`, which never touches storage-capability enforcement or * the mode marker. Both gates must complete successfully before any claim * acquisition, recovery scan, scheduler poll, or task poll proceeds — but * wiring this into `Engine` construction or any of those call sites is a * later stage; this function is the standalone, testable unit only. */ export declare function bootstrapOwnershipGates(input: BootstrapOwnershipGatesInput): Promise;