/**
 * `withRetry` (design/61 §9, core thin helper) — the consumer side of the typed-retryable error contract
 * (`remote-env.ts`). Retries a Result-returning op, but **only** on a whitelisted typed-retryable code, up to
 * `maxAttempts`, with optional backoff. All remote adapters (E2B / SSH / ADB) reuse it so they don't each
 * re-implement "retry by typed code + backoff" (and risk getting the contract wrong).
 *
 * 🔴 **Apply ONLY to IDEMPOTENT establishment ops** — `connect` / `reconnect` (design/61 §2(A)). The error
 * contract is "the caller decides retry per idempotency; the adapter MUST NOT blind-retry"; this helper IS that
 * caller-side decision, scoped to the safe (idempotent) layer. **Never wrap a side-effecting operation** — and
 * never put a permanent code (`"auth_failed"`, `"unsupported"`) in `retryableCodes` (retrying a rejected key
 * burns the budget / can lock the account).
 *
 * Determinism / fault injection (council §9 F): the `op(attempt)` closure is the injection point (a test
 * scripts a per-attempt error sequence), and `opts.sleep` overrides the real backoff delay — so
 * "first attempt fails, second succeeds" is tested deterministically without a real device/network.
 */
export type RetryResult<T, E> = {
    ok: true;
    value: T;
} | {
    ok: false;
    error: E;
};
export interface RetryPolicy {
    /** Error codes that warrant a retry (a typed-retryable whitelist). A code not in this list returns immediately. */
    retryableCodes: readonly string[];
    /** Total attempts, `>= 1`. (e.g. ADB first-auth = 2; SSH connect-drop = a few.) */
    maxAttempts: number;
    /** Backoff before attempt N (1-based; called with the attempt that just FAILED, so N≥1). Default: no wait. */
    backoffMs?: (failedAttempt: number) => number;
}
/**
 * Run `op` until it succeeds, a non-retryable error surfaces, or `maxAttempts` is exhausted. `op` receives the
 * 1-based attempt number. Returns the success, or the LAST failure (so an exhausted-but-still-failing op surfaces
 * its final typed error to the caller).
 */
export declare function withRetry<T, E extends {
    code: string;
}>(op: (attempt: number) => Promise<RetryResult<T, E>>, policy: RetryPolicy, opts?: {
    sleep?: (ms: number) => Promise<void>;
    signal?: AbortSignal;
}): Promise<RetryResult<T, E>>;
