From 45ccdd494a497df9363d10ead3305317ff3d6ff9 Mon Sep 17 00:00:00 2001 From: SimpleTest Date: Fri, 28 Aug 2026 18:07:13 +0300 Subject: [PATCH] Document active Dev Test Prod workflow --- .env.example | 6 ++--- android/play-store/store-presence-runbook.md | 6 ++--- docs/google-provider-inventory.md | 21 ++++++++++++--- docs/operations.md | 12 ++++----- docs/verification.md | 27 ++++++++++++++------ scripts/production-android-fcm-smoke.sh | 4 +-- scripts/production-release.sh | 2 +- scripts/production-web-push-smoke.sh | 4 +-- 8 files changed, 53 insertions(+), 29 deletions(-) diff --git a/.env.example b/.env.example index 59d3c56..ef9f55b 100644 --- a/.env.example +++ b/.env.example @@ -36,9 +36,9 @@ PUBLIC_UPSTREAM_NAME=who-need-help-local PUBLIC_UPSTREAM_PORT=4000 PUBLIC_HEALTH_PATH=/healthz/ready PUBLIC_WWW_REDIRECT=false -# Legacy shared-edge settings remain while the submitted test deployment is -# frozen. New application releases do not build or restart Caddy. After the -# judging freeze, migrate these routes to the independent server_edge project. +# Compatibility settings for the separately managed shared edge. Application +# releases do not build or restart Caddy; route changes belong to the +# independent server_edge project. EDGE_COMPOSE_PROJECT_NAME=who_need_help_edge CADDY_IMAGE=who-need-help:caddy-local EDGE_BIND_ADDRESS=0.0.0.0 diff --git a/android/play-store/store-presence-runbook.md b/android/play-store/store-presence-runbook.md index a91a054..9a50732 100644 --- a/android/play-store/store-presence-runbook.md +++ b/android/play-store/store-presence-runbook.md @@ -34,7 +34,7 @@ does not authorize saving fields in Play Console or publishing a release. sharing**, the final unlisted video URL, and the saved-change confirmation. This was a read-only observation. No Console value, track, release, production -deployment, frozen test deployment, or public Git remote was changed. +deployment, Test deployment, or public Git remote was changed. ## Read-only recheck on 2026-08-20 @@ -49,7 +49,7 @@ deployment, frozen test deployment, or public Git remote was changed. days. This recheck was read-only. No Console field, release, track, deployment, -frozen test environment, or public Git remote was changed. +Test environment, or public Git remote was changed. ## Read-only recheck on 2026-08-25 @@ -66,7 +66,7 @@ frozen test environment, or public Git remote was changed. forwarding route, not a standalone mailbox or reply-from identity. This recheck was read-only. No Console field, release, track, deployment, -frozen test environment, or public Git remote was changed. +Test environment, or public Git remote was changed. ## Read-only recheck on 2026-08-28 diff --git a/docs/google-provider-inventory.md b/docs/google-provider-inventory.md index 168543e..bf22a7a 100644 --- a/docs/google-provider-inventory.md +++ b/docs/google-provider-inventory.md @@ -20,6 +20,18 @@ label for **Test**. It is not a fourth environment. Reuse the three project IDs above; do not create another Google Cloud or Firebase project for these environments. +The active promotion workflow is: + +1. Develop and verify on Dev (`whoneedhelp.imalto.site`). +2. Promote the exact candidate to Test (`test.whoneedhelp.com`) and repeat the + application, provider, and browser checks there. +3. Promote that exact verified candidate to Prod only after explicit operator + approval. + +The previous Build Week restriction on changing Test has ended. Test is the +normal pre-production verification environment; Prod is never updated as an +implicit consequence of a Dev or Test deployment. + The repository enforces this mapping in [`scripts/validate-android-environment.sh`](../scripts/validate-android-environment.sh). @@ -65,10 +77,11 @@ Test has its own Web OAuth client while all Firebase/FCM values remain empty. - The Google Cloud project has a billing account linked. The console showed `$0.00` estimated charges for 2026-08-01 through 2026-08-28; this observation is not a pricing guarantee. -- The Web OAuth client also contains the old callback - `https://staging.whoneedhelp.com/auth/google/callback`. It is not part of the - three-environment contract. Do not rely on or remove it until the owner - explicitly chooses the cleanup. +- The only supported Test callback is + `https://test.whoneedhelp.com/auth/google/callback`. +- The 2026-08-28 read-only check also found one callback for a retired public + hostname. It is not part of the environment contract and remains pending + external provider cleanup. Do not recreate or use it. ### Prod diff --git a/docs/operations.md b/docs/operations.md index 381cb54..7874c24 100644 --- a/docs/operations.md +++ b/docs/operations.md @@ -457,11 +457,11 @@ Only then check out that exact tested SHA in production. Start the application with `./scripts/deploy-up.sh .env`. The application command joins the external public network but does not own or restart Caddy. -The legacy `./scripts/edge-up.sh .env` command exists only for the currently -frozen submitted deployment. Do not use it from an ordinary application -release. After judging, render and validate each route through the independent -`server_edge` workflow, transfer certificate-volume ownership in a reviewed -maintenance window, and only then retire the legacy edge container. +The compatibility `./scripts/edge-up.sh .env` command is not part of an +ordinary application release. Render and validate route changes through the +independent `server_edge` workflow, transfer certificate-volume ownership in a +reviewed maintenance window, and only then retire the compatibility edge +container. The authoritative A records for `whoneedhelp.com`, `www.whoneedhelp.com`, and `test.whoneedhelp.com` must point to the verified server address before Caddy @@ -1339,7 +1339,7 @@ database transaction. Its mode-`0600` manifest is exclusive-created inside the same transaction and contains a unique ownership token; a manifest failure rolls the database transaction back, and failure cleanup never removes a file that lacks that exact token. The smoke does not enqueue email, target Web Push, -change the frozen test deployment, update Caddy, or push Git. +change the Test deployment, update Caddy, or push Git. The local state records the exact application container. If that container is recreated between phases, the wrapper refuses to continue instead of silently diff --git a/docs/verification.md b/docs/verification.md index c2526a4..d627b8a 100644 --- a/docs/verification.md +++ b/docs/verification.md @@ -3,6 +3,17 @@ Observed through 2026-08-28 in the local workspace. This report separates observed results from product limits and unknown production properties. +## Active promotion workflow after Build Week + +- Development changes are verified first on `https://whoneedhelp.imalto.site`. +- The exact verified candidate is then released to `https://test.whoneedhelp.com` + and checked there. The previous Build Week restriction on changing this Test + deployment has ended. +- Production at `https://whoneedhelp.com` is updated only after the Test checks + pass and the user explicitly authorizes that exact production release. +- Historical entries below retain the restrictions and environment names that + applied when each check ran. They are evidence, not current release policy. + ## Production operations, browser E2E, and Play recheck on 2026-08-28 - The production backup timer was loaded, enabled, and waiting for its next @@ -192,7 +203,7 @@ results from product limits and unknown production properties. `success` with readiness, aggregate metrics, and restore-verified backup freshness all `up`. The backup age was 35,362 seconds against the configured 129,600-second alert threshold. -- The frozen test, shared Caddy, Google Play Console, and the public remote +- The Test, shared Caddy, Google Play Console, and the public remote repository were not changed by this work. ## Current local candidate and production operations recheck on 2026-08-14 @@ -355,7 +366,7 @@ results from product limits and unknown production properties. about 2.47 GiB. BEAM attributed about 2.45 GiB of the frozen-test VM to ETS; table `prometheus_metrics_dist` contained 10,748,076 pending raw histogram samples and occupied 290,222,909 machine words at the first sample. -- The frozen test runs commit +- The Test runs commit `cf7bacdf61ffb171ebac85e32dfcf12bc6972d59`, which predates the supervised ten-second Prometheus distribution drain added in commit `882df25`. A second read-only sample 13.071 seconds later contained 144 more rows. This directly @@ -877,7 +888,7 @@ The production verifier first confirmed the exact target as detached commit `who_need_help_production`, database `who_need_help_production`, and the single healthy compact application container with zero restarts. The run did not deploy source, reset or migrate the database, change real-user roles, send -email, edit Caddy, touch the frozen test project, or push Git. +email, edit Caddy, touch the Test project, or push Git. - Chromium passed both production scenarios in 46.0 seconds. The mutual-aid scenario exercised two users, medicine discovery and acceptance, private @@ -3516,7 +3527,7 @@ promoted. - The direct-production-domain action-URL gate remains open. Resolving it requires an explicit provider/account decision followed by a newly delivered authentication message whose actual href is inspected; no provider setting, - application email format, production deployment, frozen test deployment, or + application email format, production deployment, Test deployment, or public Git remote was changed by this recheck. # 2026-08-25 production authentication-email recheck @@ -3596,7 +3607,7 @@ promoted. - Exact post-run inspection found no container, network, volume, temporary quality/security image, or gettext-generation image from the run. These last controller, test, catalog, and quality-script changes remain local at the - time of this record; the public remote and frozen test were not changed. + time of this record; the public remote and Test were not changed. # 2026-08-21 connected-device Play delivery recheck @@ -3681,7 +3692,7 @@ promoted. that the direct application URL remains visible as text. - This does not prove that Brevo leaves the action button unchanged. The provider tracking limitation remains open until a newly delivered production - message is inspected. No production or frozen test deployment was changed by + message is inspected. No production or Test deployment was changed by this local check. # 2026-08-21 post-fallback full local quality recheck @@ -4080,7 +4091,7 @@ promoted. `02abdaa8345ef5feb563282366c067384a208330d89fe4dfb4804647f357d758`, and `4e848e44ccd4f5b8c4ed39d90b033dae34e0efacee68a81c8e023087b5f2cb8c`. - Final read-only inspection found production healthy on image - `who-need-help:production-305bdebdd191`, frozen test healthy on + `who-need-help:production-305bdebdd191`, Test healthy on `who-need-help:test-cf7bacdf61ff`, shared Caddy healthy on `who-need-help:caddy-production-a7412c65b51a`, and public Git main unchanged at `921e04b3608007675e22e7e26e0beb3975dbba58`. @@ -4095,7 +4106,7 @@ promoted. and one browser Web Push job for `simpletestxxx@gmail.com` in database `who_need_help_production` on image `who-need-help:production-305bdebdd191`. It excluded email, Android FCM, the - frozen test deployment, shared Caddy, and the published repository. + Test deployment, shared Caddy, and the published repository. - Run `20260825222014-56db5679a12d` created job `51535`. Provider verification recorded a completed job on attempt 1 and an active target device. The production service worker then returned one persistent notification with diff --git a/scripts/production-android-fcm-smoke.sh b/scripts/production-android-fcm-smoke.sh index d4dd8f4..d091d96 100755 --- a/scripts/production-android-fcm-smoke.sh +++ b/scripts/production-android-fcm-smoke.sh @@ -22,7 +22,7 @@ prepare sends one privacy-safe production notification to the exact active Andro FCM device. verify proves the exact Oban delivery completed on its first attempt. cleanup removes only the run-scoped notification, job, manifest, and temporary script. The separate phases leave time to inspect the notification on the phone. -No email worker, Web Push device, frozen test project, Caddy, or public Git is used. +No email worker, Web Push device, Test project, Caddy, or public Git is used. EOF exit 1 } @@ -112,7 +112,7 @@ if [[ "$ACTION" == plan ]]; then printf 'scope=one production notification and one exact Android FCM delivery job\n' printf 'device_id=%s\ndatabase=%s\nimage=%s\ncontainer=%s\n' \ "$DEVICE_ID" "$ACTUAL_DATABASE" "$OBSERVED_IMAGE" "$CONTAINER" - printf 'excluded=email delivery, Web Push, frozen test project, Caddy, public Git\n' + printf 'excluded=email delivery, Web Push, Test project, Caddy, public Git\n' printf 'cleanup=exact run-scoped notification, job, manifest, and temporary script\n' exit 0 fi diff --git a/scripts/production-release.sh b/scripts/production-release.sh index 4888c10..b32bc33 100755 --- a/scripts/production-release.sh +++ b/scripts/production-release.sh @@ -97,7 +97,7 @@ legacy_edge_paths=( if ! git -C "$ROOT" diff --quiet \ "$remote_commit" "$local_commit" -- "${legacy_edge_paths[@]}"; then echo "The application release contains shared edge routing changes." >&2 - echo "The legacy edge serves both production and the frozen test domain." >&2 + echo "The shared edge serves both production and the test domain." >&2 echo "Move the approved route change through the independent server-edge workflow." >&2 exit 2 fi diff --git a/scripts/production-web-push-smoke.sh b/scripts/production-web-push-smoke.sh index aface33..dc0ec50 100755 --- a/scripts/production-web-push-smoke.sh +++ b/scripts/production-web-push-smoke.sh @@ -23,7 +23,7 @@ active Web Push device for USER_EMAIL. verify proves the exact Oban delivery completed on its first attempt. cleanup removes only the run-scoped notification, job, manifest, and temporary script. The separate phases leave time to inspect and click the operating-system notification. No email worker, Android FCM device, -frozen test project, Caddy, or public Git is used. +Test project, Caddy, or public Git is used. EOF exit 1 } @@ -129,7 +129,7 @@ if [[ "$ACTION" == plan ]]; then printf 'scope=one production notification and one browser-only Web Push delivery job\n' printf 'target=%s\ndatabase=%s\nimage=%s\ncontainer=%s\n' \ "$USER_EMAIL" "$ACTUAL_DATABASE" "$OBSERVED_IMAGE" "$CONTAINER" - printf 'excluded=email delivery, Android FCM, frozen test project, Caddy, public Git\n' + printf 'excluded=email delivery, Android FCM, Test project, Caddy, public Git\n' printf 'cleanup=exact run-scoped notification, job, manifest, and temporary script\n' exit 0 fi