Production credential cutover — September 12, 2026
Completed and verified at 23:05 UTC. The owner authorized the live credential switch separately from the admin/pricing release. The application login is now yumina_mycelium; the previous password is rejected on both computes, and no old-role sessions remain. This operation did not activate the prepared admin or free-credit changes, enable logical replication, or restart Neon.
Completed checks and changes
- Preserved the previous service connection settings and deployment IDs in the existing ignored Windows-DPAPI store before changing production. Credentials are never recorded in this document.
- Applied the reviewed shared-ownership transaction at approximately 22:58 UTC: 237 named application relations and 16 routines in
public/drizzle, withyumina_schema_owneras the stable NOLOGIN owner. Database, extension and provider-owned objects were left intact. Copied the existing login's three timeout settings and installed default grants for both logins. - Verified primary and replica authentication, table/sequence/ownership permissions, and primary/replica identity. A real primary write/serial-sequence/DDL probe used its own test table and rolled back completely.
- Updated Railway
yuminaDATABASE_URLandDATABASE_READ_URL, andamiable-truthDATABASE_URL, using stdin and without automatic deploys. Updated the repository'sPROD_DATABASE_URLsecret at 22:58:52 UTC. - Redeployed the same code revisions that were already running. No branch was pushed and no new admin/pricing code was deployed.
- Verified both running web replicas over Railway SSH, including actual
current_userqueries against primary and read replica. Verified the runtime's process credential and health; its startup logs confirm persistence is enabled. The runtime's standalone health route does not independently query PostgreSQL. - Railway reports the former web/runtime deployment instances removed. All four admin/capture/bonus/free-policy feature flags are unset in the running services.
- The existing hourly recovery workflow was inspected on
mainand manually run once with its existing idempotent policy to verify the new GitHub secret. Run 34724358239 passed. No renewal-reminder or announcement workflow was dispatched. - Checked all eight Railway services: only the two updated services have PostgreSQL URL variables. Cloudflare has no Hyperdrive configurations; the three Workers have no database bindings, and the two Pages projects have no production environment variables. The analytics worker has no production PostgreSQL URL; its CDC flag remains false. No ClickPipe exists yet.
| Service | Previous deployment | Replacement deployment | Unchanged code revision |
|---|---|---|---|
| Web | 71edb00e-722c-4700-8e68-81def9b37d12 | f52725e3-0347-44ee-be52-094a00cbaac8 | 4c362c546fdab7c166fde67f1e3051dfc2a0f769 |
| Game runtime | ab2ed5b7-7d44-4209-a789-c3822efdf633 | 5293da6a-0bc9-4873-8939-29f8814c11f7 | 1c1d92cb03b3c6fd942671117d54560dfb0800be |
Issues found during the switch
The first ownership transaction failed on a named function argument in the to_regprocedure identity check and rolled back. The generator now uses catalog input types for identity lookup and retains named/mode arguments for ALTER statements. Added and passed isolated regression cases for named, overloaded, OUT and variadic functions, including apply/replay/rollback. The corrected transaction then committed successfully.
The existing deployed code has an independent startup race: both web replicas can attempt to create posts_clear_reply_snapshot. One completed maintenance on its first attempt; the other's 180-second retry completed successfully at 23:04:37 UTC. Credential retirement waited for that completion. This turn did not ship the prepared startup-serialization improvements. Observed logs also contain existing slow-query warnings and provider rate-limit/content-filter responses; no PostgreSQL authentication or ownership failures were observed in the new deployments.
Retirement and next step
The former owning role was retained because it still owns the database and extensions. Its password was replaced with a cryptographically random value protected in DPAPI. Fresh connections using the old password failed with PostgreSQL 28P01 on all four primary/read pooled/direct endpoints. The protected replacement maintenance password also authenticated successfully; the role itself was not deleted or disabled.
Closed 12 idle old-role sessions on primary and 11 on the replica. No old-role active transaction was observed before rotation. After closing maintenance connections, a fresh audit at 23:05 UTC counted zero old-role sessions on either compute. Rechecked both web replicas and the game runtime after retirement; both public health routes returned HTTP 200, with primary/read/Redis healthy on the web service.
Logical replication remains disabled. The owner will coordinate its enable/restart separately after credential verification. Then verify compute recovery, configure the restricted CDC source role/publication, create and validate the ClickPipe, and finish the separate admin/pricing release gates. User-facing functional flows were not manually exercised through a browser during this credential-only switch.
Recovery
Before old-password retirement, the DPAPI snapshot can restore the original consumer credentials if necessary. After retirement, never restore the exposed password: retain the working new application login or use the separately protected owner maintenance credential. Keep the current code revisions until a separate release is authorized. Prepared SQL rollback files restore listed application ownership only; regenerate them if startup or other migrations have changed the inventory.
