Admin release: real service and container verification
September 12, 2026, updated after the authorized local VM correction. Continues the earlier local verification. All data and credentials used in this pass are disposable fixtures. No production deployment, policy activation, announcement, Neon restart, replication change, credential rotation or cloud configuration change occurred.
Results
| Check | Result | Scope |
|---|---|---|
| Web Linux image | Built and executed | Node 22.23.2, including the startup-race fix below. Existing frontend size and Docker build-argument warnings remain. |
| Analytics Linux image | Built and executed | Default non-root node user; compiled worker; bundled SQL migrations. |
| PostgreSQL | Passed on Windows and in Linux | Real PostgreSQL 17.11 with pgvector and pgcrypto, two compiled Node 22 app processes, independent connection pools, shared Redis 7.4.11. The final Linux run communicates directly inside the guest. |
| Normal web startup command | Passed in Linux | The unchanged Docker command starts within a 512 MiB limit and chooses a 384 MiB Node heap. PostgreSQL/Redis health passes, compiled frontend/assets serve, and anonymous admin requests return 401 with private no-store. |
| Deferred startup maintenance | Passed in Linux | Kept the normal container running past its 90-second startup delay. Both bundled scheduled SQL scripts installed and schema self-heal completed on its first attempt. |
| Simultaneous initialization and check-ins | Passed | 16 concurrent wallet initializations and 16 claims distributed across both app instances: one initial grant and one check-in receipt. |
| Gifts and referrals | Passed | Twelve competing gifts honored the monthly cap; duplicate transfers/redeems did not issue twice; disclosed expiry followed the transfer; combined wallet value was conserved. |
| Recovery SQL | Passed | Six concurrent schedulers produced one receipt per eligible wallet. Frozen new Free / legacy Free / Gold floors remained 100 / 200 / 500; new Free recovery stopped at 500 per cycle. A separately locked grant committed while recovery waited was preserved, without a stale recovery receipt. |
| Additive migration | Passed on PostgreSQL | Current managed schema followed by the real Bonus installer twice, plus the real recovery-function installer. This validates repeatability and pgcrypto, not a production migration. |
| Worker reports | Passed in Linux container | All 21 report/period combinations published to real Redis from local ClickHouse 26.3.33.24. Fixture accounts, activity, time, tokens, Stripe net receipts and provider billed cost matched expected values. |
| Worker cache replacement | Passed in Linux container | Removed fixture report keys, retained a competing worker lease, and reran the compiled worker. All 21 durable reports restored exactly; the other worker's lease remained intact. |
| Analytics tests | 26 passed; zero skips | Includes both warehouse/CDC query fixtures and real Redis reconnect, report retention, period isolation, lease renewal and ownership-loss cancellation. |
| Typecheck | Eight tasks passed | Includes the new integration test. Application source is unchanged from the image builds. |
| Embedded database fallback | Passed again after startup fix | Compiled Windows Node 22 / PGlite wallet and endpoint rehearsal. |
The earlier Windows-to-VM PostgreSQL run needed a connection-establishment bridge. The final Linux container run removed that forwarding path and passed the same concurrent operations on direct connections. These remain transaction-correctness checks, not a production latency benchmark. The query fixtures validate CDC view semantics, not a running Neon ClickPipe.
Web-container startup completed
The temporary QEMU machine initially exposed an older CPU profile that sharp rejected. The owner explicitly authorized correcting/restarting this local test VM. It now exposes the required CPU capabilities; the web image starts and passes the full two-replica rehearsal. No application dependency downgrade or production machine change was needed.
That rehearsal exposed a separate application startup race: simultaneous CREATE TABLE IF NOT EXISTS calls can collide in PostgreSQL's type catalog on a fresh database. The legacy analytics-table initializer now runs in one transaction with a transaction-scoped advisory lock. The new rehearsal assertion fails on that startup error. Rebuilt Linux images pass without the catalog race, and PGlite still starts successfully.
The temporary VM, its disk, fixture transfer listener and loopback bridge are local test resources. The guest was not installed into WSL and no Windows reboot or feature change occurred. Test services and helpers are cleaned up at the end of verification; ignored image/log artifacts are retained for review.
Repeatable service fixtures
compose.admin-release.yml pins the three service images used in this verification. Ports bind to loopback; no deployment environment is loaded. The Compose manifest was validated with docker compose config --quiet; this pass started equivalent individual containers inside QEMU, rather than running a second Compose stack.
Run only on a local test host with those ports available:
docker compose -f compose.admin-release.yml up -d --wait
docker compose -f compose.admin-release.yml exec -T redis redis-cli -n 13 SET yumina:release:fixture isolated-admin-release
docker compose -f compose.admin-release.yml exec -T redis redis-cli -n 14 SET yumina:release:fixture isolated-admin-release
docker compose -f compose.admin-release.yml exec -T redis redis-cli -n 15 SET yumina:release:fixture isolated-admin-releaseThe markers protect against accidentally clearing an unrelated local cache. Database 13 is reserved for the Redis integration test; 14 for worker restoration; 15 for authenticated app endpoints. The PostgreSQL runner generates its own yumina_release_* database and drops it after success. Failed fixture databases are retained for diagnosis. Both runners reject arbitrary deployment URLs and use only explicit loopback ports and public fixture credentials.
Export the schema and run the compiled app rehearsal using Node 22:
mkdir -p packages/server/scripts/admin-release.local
pnpm --filter @yumina/server exec drizzle-kit export --dialect postgresql --schema ./src/db/schema.ts > packages/server/scripts/admin-release.local/schema.sql
node packages/server/scripts/verify-admin-release.mjs --schema packages/server/scripts/admin-release.local/schema.sql --postgres-port 55432 --redis-port 56379Run the compiled worker locally, or use the same script mounted into its built image:
node packages/server/scripts/verify-analytics-release.mjs --clickhouse-port 62375 --redis-port 56379For a Linux Docker host, this runs the worker as the image's normal non-root user. The output directory is under /tmp so the rehearsal does not require writes to application directories:
docker run --rm --network host --entrypoint node \
--mount type=bind,source="$PWD/packages/server/scripts/verify-analytics-release.mjs",target=/app/packages/server/scripts/verify-analytics-release.mjs,readonly \
yumina-admin-release:analytics scripts/verify-analytics-release.mjs \
--clickhouse-port 62375 --redis-port 56379 --output /tmp/release-checkFor the optional external integration tests, set only these fixture variables in that test process:
ANALYTICS_TEST_CLICKHOUSE_URL=http://127.0.0.1:62375 \
ANALYTICS_TEST_CLICKHOUSE_USERNAME=fixture \
ANALYTICS_TEST_CLICKHOUSE_PASSWORD=local-release-fixture-only \
ANALYTICS_TEST_REDIS_URL=redis://127.0.0.1:56379/13 \
pnpm --filter @yumina/server analytics:testUse docker compose -f compose.admin-release.yml down -v only for the named disposable Compose project when its verification is finished. It does not manage the separately created QEMU fixtures.
Remaining release boundaries
The remaining local container gate is complete. The following live steps remain deliberately deferred:
- At the owner's later agreed live step, apply the reviewed additive schema/recovery sequence, verify compatible replicas before issuing Bonus, and handle the separately coordinated Neon replication/reconnect and credential transition. No such window is scheduled here.
- Verify the real ClickPipe snapshot, deletes, lag and report completeness, then reconcile vendor totals at matching closed UTC cutoffs. Fixture success does not establish historical source coverage.
- The owner publishes the announcement and chooses activation timestamps with the agreed notice period. Paid benefits remain unchanged. Never roll back to a binary that treats issued Bonus as permanently Saved.
Evidence is local and ignored under packages/server/scripts/admin-release.local/: postgres-rehearsal.log, results.json, analytics-full.log, typecheck.log, and the vm/ image-build and worker-rehearsal logs. The earlier UI evidence remains in the preceding verification record.
