import { type EventV3ControlState } from "./control.js"; export interface InitializeEventLedgerV3Input { coordRoot: string; harneryBuild: string; hostBuild: string; configDigest: `sha256:${string}`; approvalRecordId: string; forceNewEpoch?: boolean; /** * Activate a candidate epoch that was already created for this root. * * Unset, this activates a candidate that carries this initializer's producer * identity and refuses every other one. Creation and activation are one * locked step here, so such a candidate is the residue of a crash or a * failed activation, never work in progress; a candidate from another * producer is a deliberate cutover state. Set it explicitly to force either * answer. */ resumeCandidate?: boolean; now?: () => Date; } export interface InitializeEventLedgerV3Result { state: "active"; initialized: boolean; archived_epoch?: string; control: Extract; } export interface RefreshIncompatibleEventLedgerV3Result { state: "current" | "refreshed"; archived_epoch?: string; control: Extract; } /** * Ensure programmatic Harnery entry points have the same universal V3 * boundary as `harn init`. Only a genuinely absent control pair is created; * candidate, damaged, or incompatible state still fails closed. */ export declare function ensureEventLedgerV3(coordRoot: string, approvalRecordId?: string): Extract; /** * Ensure a root has one current V3 epoch. An incompatible or explicitly * replaced epoch is moved intact to the V3 archive before the new control * pair is published. No historical ledger bytes are rewritten or deleted. */ export declare function initializeEventLedgerV3(input: InitializeEventLedgerV3Input): InitializeEventLedgerV3Result; /** * Replace only a runtime-incompatible epoch that the current code can name * exactly. Corruption and ambiguous control failures remain closed for the * explicit recovery command. */ export declare function refreshIncompatibleEventLedgerV3(coordRoot: string): RefreshIncompatibleEventLedgerV3Result; export interface RepairStrandedEventLedgerV3CandidateResult { state: "repaired" | "not_stranded" | "unavailable"; reason?: string; control: EventV3ControlState; } /** The approval record every automatic stranded-candidate repair is bound to. */ export declare const EVENT_V3_STRANDED_CANDIDATE_APPROVAL_RECORD_ID: "harnery-runtime-v3-stranded-candidate"; /** * Complete an epoch that was created but never activated. * * This initializer creates a candidate and activates it inside one lease, so a * candidate carrying its producer identity is residue: some process published * the genesis and died or failed before publishing the activation, and every * hook afterwards served that half-built epoch with a candidate-only write * gate. Finishing it is a repair, not a decision, and it is exactly as safe as * the creation it completes: the same lease serializes it, the activation is * derived from the immutable candidate packet, and no ledger row is edited or * synthesized. * * A candidate from any other producer is a deliberate cutover state and is * left untouched. A live bootstrap lease makes this a no-op rather than a * failure, so the next boundary retries. */ export declare function repairStrandedEventLedgerV3Candidate(coordRoot: string): RepairStrandedEventLedgerV3CandidateResult; export interface RotateOversizedEventLedgerV3Result { state: "rotated" | "not_oversized" | "not_active" | "disabled"; active_bytes: number; threshold_bytes: number; archived_epoch?: string; control?: Extract; } /** * Archive a valid oversized epoch intact and start a fresh one. * * Every canonical read validates the complete epoch, and hook producers are * one-shot processes, so an unbounded active segment makes every hook's cold * read scale with all history. Rotation bounds that cost: the replaced epoch * (events, spool, producer states, manifests) moves whole into the V3 * archive, live sessions re-onboard into the new epoch on their next signal, * and the writer's epoch fence keeps in-flight producers of the old epoch * from ever committing into the new one. A candidate epoch rotates on the same * terms as an active one: its control pair is valid, every reader still * validates all of its history, and refusing to bound it is how a stranded * epoch grew to 100 MB. Integrity failures stay closed for the explicit * recovery command. The threshold comes from the isolated Event V3 config * resolver unless the caller pins one; a non-positive threshold disables * rotation. */ export declare function rotateOversizedEventLedgerV3(coordRoot: string, options?: { thresholdBytes?: number; }): RotateOversizedEventLedgerV3Result; //# sourceMappingURL=bootstrap.d.ts.map