/** * Transient network-failure classification for the sync runner. * * The auto-sync watcher runs an unattended poll loop. At the top of every pass * it calls `GET /membership/me` to resolve which companies to sync, then it * runs a per-company fanout. When the machine is briefly offline (wifi drop, * waking from sleep, a DNS blip, the vault API or a vault S3 endpoint * momentarily unreachable), either boundary can fail at the transport layer — * Node's `fetch` throws `TypeError: fetch failed` with the real cause (an * `ECONNREFUSED` / `ENOTFOUND` / `ETIMEDOUT` / … Error) on `.cause`. * * This is NOT a crash: the next poll (~30s later) succeeds once the network is * back. But the runner used to `return 1` for it, the watch loop propagated * that non-zero exit, the process exited, and the menubar supervisor reported * "auto-sync watcher exited unexpectedly (code=Some(1))" for every blip — the * HQ-SYNC-1W cluster. A company-leg failure was also previously counted as an * exit-2 partial sync, producing the HQ-SYNC-X symptom even though it was just * retryable DNS/transport loss. We classify both boundaries so the watch loop * can stay alive and retry instead of surfacing a false crash, while a one-shot * `hq sync` still exits non-zero so a human running it by hand sees the failure. */ /** * Distinct runner exit code for a transient network failure. The watch loop * treats it as "stay alive, retry next tick" (never a crash); a one-shot run * still exits non-zero so the failure is visible to a human/script. Value 75 = * `EX_TEMPFAIL` from sysexits.h ("temporary failure; retry"). Kept off the * codes already in use by the runner (0 ok, 1 error, 2 partial, 17 op-locked). */ export declare const TRANSIENT_NETWORK_EXIT = 75; /** * `AbortSignal.timeout` and AWS SDK abort of a stalled HTTPS request. * Distinct from a caller-cancelled signal only in that these names are how * Node/undici/SDK surface a deadline — treat them as transport failure. */ export declare function isAbortOrTimeoutError(err: unknown): boolean; /** * True when `err` is (or wraps) a transient network-transport failure. Walks the * `.cause` chain and `AggregateError.errors` (undici's happy-eyeballs raises the * latter), matching either undici's canonical `TypeError: fetch failed` message * or a known transient `.code`. Conservative by design: an arbitrary * `new Error("network down")` with no code and a non-canonical message is NOT * treated as transient, so only real transport-failure shapes qualify. */ export declare function isTransientNetworkError(err: unknown, depth?: number): boolean; /** * Pull an HTTP status off a vault/S3-shaped error. Conservative: only fields * callers already stamp (`statusCode`, AWS `$metadata.httpStatusCode`) plus * the entity-lookup message `context.ts` emits on a non-OK `/entity/{uid}`. */ export declare function httpStatusFromError(err: unknown): number | undefined; /** * True when `err` is an HTTP 429/502/503/504. Used by the company fanout so a * vault throttle on entity lookup is a retryable company outcome (exit 75), * not an exit-2 `errored` partial — the 2026-09-18 Odin incident. */ export declare function isTransientHttpStatusError(err: unknown): boolean; /** * True when a vault GET/HEAD failed because the object is already gone. * * Short-lived inbox files (for example `inbox/pending/jobrun-*.json`) are * listed, then consumed and deleted before the follow-up GET. The transports * surface that as S3 `NoSuchKey` / `NotFound` or HTTP 404 (`statusCode`, * `$metadata.httpStatusCode`, or a `http=404` token in the message). This is * NOT a retryable throttle — 404 stays out of {@link TRANSIENT_HTTP_STATUSES} * so other callers keep treating it as a hard failure. Callers that hit the * LIST→GET race downgrade it to a deliberate skip instead. */ export declare function isRemoteObjectGoneError(err: unknown): boolean; //# sourceMappingURL=net-errors.d.ts.map