import type { RemoteExecutionEnv, RemoteExecutionError, SnapshotId, VmLifecycleOptions } from "../remote-env.js";
import type { RemoteEnvFailureNote } from "../types.js";
/**
 * Project one failed remote lifecycle call onto the caller-facing note. ONE builder for all
 * three ops so the `retryable` classification can never drift between the lane that reports a `suspendVM`
 * refusal and the lane that reports a failed restore.
 */
export declare function remoteEnvFailureNote(op: RemoteEnvFailureNote["op"], error: RemoteExecutionError, attempts: number): RemoteEnvFailureNote;
/**
 * `resumeVM` with a bounded retry on the TRANSIENT codes, plus the attempt count for the
 * caller-facing note.
 *
 * Why this op and no other: `resumeVM` is the one lifecycle call the seam documents as "idempotent +
 * re-entrant" (a replica that crashed mid-suspend can be superseded by another resuming the SAME
 * snapshot), which is exactly `withRetry`'s red line — retry idempotent establishment, never a
 * side-effecting op. `suspendVM` TAKES a snapshot and `postResumeInit` re-injects secrets under an
 * ordering red line; neither is retried here, they are disclosed with `retryable` instead so the caller
 * decides. A code outside the retryable family (`unsupported`, `auth_failed`) returns on the first
 * attempt — `withRetry` will not spend a second call on a permanent refusal.
 */
export declare function restoreWorkspaceWithRetry(env: RemoteExecutionEnv, snapshotId: SnapshotId, options: VmLifecycleOptions, 
/** Observe each attempt AS IT STARTS. The returned `attempts` is
 *  only readable after settlement, and a caller whose wait on this promise is BOUNDED (the park
 *  compensation) must report the live attempt count when its bound fires mid-call — without this
 *  seat a deaf second attempt was reported as `attempts: 1`. */
onAttempt?: (attempt: number) => void): Promise<{
    outcome: Awaited<ReturnType<RemoteExecutionEnv["resumeVM"]>>;
    attempts: number;
}>;
