* fix(relay): wait out a cold proxy at boot instead of exiting the cell
A cell container starts its relay process beside a cloud-sql-proxy that is
itself still dialling. The first pool acquire therefore competes with a proxy
cold start, and the 2s connect timeout that protects the request path fires
before the proxy is listening. `openRelayDatabase` rejects out of the region
backfill, the top-level await rejects, and the process exits; COS restarts the
container and the next boot succeeds 1-3s later. The 2026-09-18 fleet roll saw
0-7 of these per cell, including on cells with zero hosts, so it is a property
of the boot sequence rather than of database load.
The boot open now retries on transient errors only, inside a 45s wall-clock
window with exponential backoff from 250ms to 4s. The classifier is the one the
request path already uses, so a rejected credential or a bad URL still exits on
the first attempt. Each wait logs `orca_relay_boot_database_retry` and a
give-up logs `orca_relay_boot_database_failed`, both with the bounded error
category, so a rollout can tell a slow boot from a stuck one without reading
container exit codes.
The bounded startup retry is lifted out of `reconcileCellAdmissionAtStartup`,
which had the same loop; its attempt budget, flat delay, and both log events are
unchanged (a flat delay is a cap equal to the base).
* fix(relay): retry the boot open only when Postgres is unreachable
The boot open re-runs the schema apply, and applyPostgresSchema refuses to
repeat a DDL lock timeout on purpose: relation locks are granted in queue order,
so a repeat parks every writer behind the same statement again. Gating the boot
retry on the full request-path classifier would have re-queued it up to 16 times
in 45s on sustained 55P03 - the mechanism behind the 2026-09-16 outage.
The boot call site now has its own predicate: pool connect failures (both
connect-timeout messages and an acquire-marked early-ended socket) plus 08001
and 08006. Lock and overload SQLSTATEs - 55P03, 57014, 53300 - exit on the first
attempt. The retry predicate moves onto the policy because what a step re-runs,
not the request path, decides what it may repeat; the startup reconcile keeps
the full classifier, which is what lets it wait out 55P03.