diff --git a/docs/verification.md b/docs/verification.md index 502957f..e87886b 100644 --- a/docs/verification.md +++ b/docs/verification.md @@ -921,6 +921,67 @@ The existing helper account was restored to role `user`, no password, and no blocks. Post-cleanup counts retained two users plus one unrelated request and assignment; those unrelated rows were not changed. +## Production-handoff replay on 2026-07-20 + +Commit `14987bb` adds a first-deployment Compose path without inventing the +unknown server topology. `scripts/init-production-env.sh` generated independent +database, Phoenix, handover, BEAM-cookie and metrics values without printing +them, wrote mode `0600`, and refused to overwrite its destination. +`scripts/validate-production-env.sh` accepted the fully supplied fixture and +rejected the unresolved proxy/SMTP fixture. The configurable +`HTTP_BIND_ADDRESS` rendered as both `0.0.0.0` and `127.0.0.1`. +`compose.production.yaml` kept Mailpit inactive unless its explicit local +profile was enabled. + +- The complete isolated quality/security gate passed after these changes: + 244/244 ExUnit tests, format and warnings-as-errors compilation, xref, Credo, + Sobelow, Dialyzer, Hex/npm audits, ShellCheck, actionlint, all Compose/Helm + renders, observability validation, tracked-source secret/misconfiguration + scanning, and all configured production/infrastructure image scans. The + configured-threshold vulnerability count was zero. +- The deployed Compose stack applied all 12 migrations and reported two + healthy web plus two healthy worker replicas. A repeated cluster probe + observed all four BEAM nodes and passed cross-node PubSub. Fresh cgroup + observations were approximately 210-221 MB per application replica; this is + not a future server minimum or capacity promise. +- Public HTTPS returned ready/live success, HSTS, secure HttpOnly SameSite + cookies and the expected security headers. The scheme-specific CSP contained + `wss://whoneedhelp.imalto.site` and no plaintext WebSocket origin. +- A headed Chrome registration used a unique run-scoped address, received its + confirmation message in Mailpit, required explicit confirmation, and created + an authenticated session. The profile exposed location-visibility choices, + manually added unverified social-link semantics, reputation, blocks and an + optional external thank-you link. Sensitive settings correctly required + email reauthentication after the sudo window. The password form's browser + accessibility warning was fixed by associating its username; the fresh + deployed settings tab reported zero errors and zero warnings. +- A full public staging replay passed 3/3 registration/settings, mutual-aid and + activity/moderation scenarios. Its database cleanup diff was empty. Evidence + is `output/staging-full-e2e/20260720184356-3858682`. +- The public PWA install/cache-update/offline-fallback replay passed 1/1. + Evidence is `output/staging-pwa-e2e/20260720184450-3875584`. +- The current staging APK/test APK were rebuilt for the configured HTTPS + origin. The Android 37/browser replay passed magic login, bidirectional + realtime chat, foreground location sharing, a PostGIS-backed position and + notification Stop cleanup; it retained zero raw positions and its database + cleanup diff was empty. Evidence is + `output/android-browser-staging-e2e/20260720184520-3885007`. +- Backup `output/backups/compose-20260720-182338.dump` has SHA-256 + `ac19d5dbb3c1b797269003d6b302a2ae3d8d9634be6ad31ea2468d7f5a837a3b`. + Its fresh-database restore drill found 23 public tables, 1,489 rows, all 12 + migrations and PostGIS 3.6.4. The upgrade rehearsal passed with an empty + application-table diff, four cluster nodes, PubSub and HTTP; evidence is + `output/upgrade-rehearsal/20260720182353-3474703`. + +The final manual registration account had no request, assignment, message, +activity, review, report, block, social-identity or tracking references. It and +its two session tokens were removed in one exact transaction; its two exact +Mailpit message IDs were also removed. Final domain counts returned to two +users, one unrelated request, one unrelated assignment and seven unrelated +messages. One PostgreSQL error in the audit window came from an incorrect +column name in a read-only operator query; PostgreSQL aborted that transaction. +The subsequent log window contained no matched error/warning entry. + ## Known work before a public production launch - Replace the temporary staging origin with the production-owned domain and @@ -940,6 +1001,9 @@ assignment; those unrelated rows were not changed. autoscaling, and action-limit policies. - Publish jurisdiction-specific emergency contacts, privacy, retention, prohibited-items, and voluntary-payment guidance after legal review. +- The current UI has no self-service account deletion or data-export flow. + Decide the retention/anonymization behavior, implement the selected control, + and verify it before promising that capability to users. - Establish moderation/support operations and incident response for real users. - If verified GitHub identity is desired, create and configure its OAuth App and exercise the external redirect/callback. This is an optional enhancement, not