/** * `runStartupRetry` — envelope around a Promise-returning startup task that * survives transient failures and exits distinctively on permanent ones. * Replaces the doorbell's silent `exit(2)` on first-hiccup failure. * * Contract: `specs/980-summary-978-shipped-working/contracts/startup-retry.md`. */ import type { RateLimitScheduler } from '@generacy-ai/cockpit'; export type GhErrorClass = { kind: 'retriable'; hint: string; } | { kind: 'permanent'; reason: string; }; export type StartupRetryLabel = 'acquireEpicBus' | 'resolveEpic'; export interface StartupRetryOptions { task: () => Promise; label: StartupRetryLabel; rateLimitScheduler: RateLimitScheduler; abortSignal: AbortSignal; stderr: { write(chunk: string): boolean | void; }; logger: { warn: (msg: string) => void; info?: (msg: string) => void; }; now?: () => number; sleep?: (ms: number, signal: AbortSignal) => Promise; classify?: (err: unknown) => GhErrorClass; initialWindowMs?: number; lateWindowIntervalMs?: number; } export type StartupRetryOutcome = { kind: 'success'; value: T; } | { kind: 'permanent'; reason: string; } | { kind: 'aborted'; }; /** * Deterministic mapping from a raw `gh`-call error to `GhErrorClass`. * * Retriable rules are evaluated first (node error codes → socket-hang-up → * HTTP 429/5xx). Permanent rules follow (401/Bad credentials → 403 SAML/ * scope → 404 not-found → JSON-parse failure). Default: permanent/unknown. * * See `contracts/startup-retry.md § Error classifier` for full rationale. */ export declare function classifyGhError(err: unknown): GhErrorClass; export declare function runStartupRetry(opts: StartupRetryOptions): Promise>; //# sourceMappingURL=startup-retry.d.ts.map