import { type NoFollowPathIdentity } from "./no-follow-file.js"; export declare const WORKFLOW_LIFECYCLE_STATE_FILES: readonly ["workflow-loop-state.json", "ralph-loop-state.json"]; export type WorkflowLifecycleStateFileName = typeof WORKFLOW_LIFECYCLE_STATE_FILES[number]; export type WorkflowLifecycleStateToken = NoFollowPathIdentity | null; export type WorkflowLifecycleStateRead = { readonly kind: "absent"; } | { readonly kind: "blocked"; } | { readonly kind: "ready"; readonly value: { readonly bytes: Buffer; readonly token: NoFollowPathIdentity; }; }; export declare class WorkflowLifecycleStateError extends Error { constructor(); } export declare class WorkflowLifecycleStateConflictError extends Error { constructor(); } export declare function readWorkflowLifecycleStateFile(projectDir: string, name: WorkflowLifecycleStateFileName, maxBytes: number): WorkflowLifecycleStateRead; export declare function writeWorkflowLifecycleStateFile(projectDir: string, name: WorkflowLifecycleStateFileName, expectedToken: WorkflowLifecycleStateToken, text: string): WorkflowLifecycleStateToken; export type WorkflowLifecycleGuardMode = "no-follow-open" | "lstat-verified"; /** * Reports how the workflow directory is guarded on this platform. * * `no-follow-open` is the POSIX path: `O_DIRECTORY | O_NOFOLLOW` makes the open * itself refuse a symlink or a non-directory, atomically. * * `lstat-verified` is the Windows path. Neither flag exists there, so the open * cannot carry the guarantee. The caller has already rejected symlinks and * non-directories with `lstat` before opening, and re-verifies the descriptor's * identity against that `lstat` afterwards, so a swapped directory is still * caught. What is lost is the atomicity of the open — a same-UID race, which * this program's threat model already declines to claim resistance against. */ export declare function workflowLifecycleGuardMode(): WorkflowLifecycleGuardMode;