docs: record final local pre-production verification

This commit is contained in:
SimpleTest 2026-07-19 20:32:26 +03:00
parent c6aa3d1ed2
commit 1dda417a94

View File

@ -16,26 +16,27 @@ results from product limits and unknown production properties.
| Consent-driven live tracking | Implemented and cross-client verified | On API 37, Android started `TrackingService` as a location foreground service with a persistent Stop notification. After Home minimized the Activity, an emulator coordinate change reached PostGIS. Notification Stop removed the service, notification, active session, and raw position. | Browsers stop with the page. Android has no `ACCESS_BACKGROUND_LOCATION`, unattended start, or route history. | | Consent-driven live tracking | Implemented and cross-client verified | On API 37, Android started `TrackingService` as a location foreground service with a persistent Stop notification. After Home minimized the Activity, an emulator coordinate change reached PostGIS. Notification Stop removed the service, notification, active session, and raw position. | Browsers stop with the page. Android has no `ACCESS_BACKGROUND_LOCATION`, unattended start, or route history. |
| Privacy settings | Implemented and browser-verified | The profile exposed hidden, approximate public, exact for active match, and explicit exact-public options. Blocking and current-position cleanup have automated tests. | Exact public location remains a user opt-in; legal privacy and retention text still requires jurisdiction-specific review before launch. | | Privacy settings | Implemented and browser-verified | The profile exposed hidden, approximate public, exact for active match, and explicit exact-public options. Blocking and current-position cleanup have automated tests. | Exact public location remains a user opt-in; legal privacy and retention text still requires jurisdiction-specific review before launch. |
| Reputation and anti-abuse | Implemented at MVP level | Handover codes, two-party completion, double-blind reviews, unique-counterpart ranking, optional movement/proximity evidence, reports, blocks, abuse signals, and moderator audit paths have automated tests. | The system is not bot-proof and does not claim identity verification. No punitive numeric policy is enabled without measured and approved thresholds. | | Reputation and anti-abuse | Implemented at MVP level | Handover codes, two-party completion, double-blind reviews, unique-counterpart ranking, optional movement/proximity evidence, reports, blocks, abuse signals, and moderator audit paths have automated tests. | The system is not bot-proof and does not claim identity verification. No punitive numeric policy is enabled without measured and approved thresholds. |
| Social profiles | Manual links implemented; GitHub verification implemented and automated-tested | Manual links cannot set verification fields. The optional GitHub flow uses state, PKCE, a user-bound one-time session, unique provider ownership, and an audit record; 171 tests pass, including callback replay/state checks. The local protocol drill also performs real HTTP token/user exchanges without returning an access token to the application. | The staging operator has not supplied GitHub OAuth credentials, so the real external provider redirect/callback remains disabled and has not been browser-verified. Other providers remain manual/unverified. | | Social profiles | Manual links implemented; optional GitHub verification implemented and automated-tested | Manual links cannot set verification fields. The optional GitHub flow uses state, PKCE, a user-bound one-time session, unique provider ownership, and an audit record; the final 172-test suite includes callback replay/state checks. The local protocol drill also performs real HTTP token/user exchanges without returning an access token to the application. | GitHub OAuth credentials are intentionally absent and are not required for registration or the help flow. The real external provider redirect/callback remains disabled and unverified; other providers remain manual/unverified. |
| Voluntary thanks | Implemented as an external optional link | A helper can expose an optional link after completion; the UI states that the platform does not process the payment. | The platform does not provide payments, escrow, refunds, tax reporting, or payment guarantees. | | Voluntary thanks | Implemented as an external optional link | A helper can expose an optional link after completion; the UI states that the platform does not process the payment. | The platform does not provide payments, escrow, refunds, tax reporting, or payment guarantees. |
| Android client | Local and public-staging clients implemented and emulator-verified | The native packages `org.whoneedhelp.mobile.debug` and `org.whoneedhelp.mobile.staging` launch the same authenticated LiveView app. Public HTTPS login, map, two-way chat, permission prompts, minimized foreground-service location updates, notification Stop, deep-link routing, and server cleanup were exercised on API 37. | Production signing, Play Store publication, verified Android App Links, unattended/background-permission tracking, and iOS are not implemented. | | Android client | Local and public-staging clients implemented and emulator-verified | The native packages `org.whoneedhelp.mobile.debug` and `org.whoneedhelp.mobile.staging` launch the same authenticated LiveView app. Six lifecycle, permission, deep-link, foreground tracking, network-failure, notification-Stop, and Activity-destruction tests passed on each of API 30, 34, and 37. The API 37 staging smoke loaded the public home and Safety routes over HTTPS with zero observed load/TLS errors. | Production signing, Play Store publication, verified Android App Links, unattended/background-permission tracking, and iOS are not implemented. |
| Multiple web/worker instances | Implemented and locally failure/rollout-verified | The isolated Compose profile passed BEAM crashes and sequential replacement with 3 web/2 worker replicas, all five nodes joined, PubSub passed, and 758/758 readiness requests succeeded. The project-owned kind cluster replaced all 2 web/2 worker pod UIDs under `maxUnavailable=0`; all four replacement pods joined and PubSub passed. | Local PostGIS is a single instance. Production database HA, backups, and recovery are operator work and are not claimed complete. | | Multiple web/worker instances | Implemented and locally failure/rollout-verified | The final isolated Compose drill passed BEAM crashes and sequential replacement with 3 web/2 worker replicas: all five nodes joined, PubSub passed, and 744/744 readiness requests succeeded. The project-owned kind cluster replaced all 2 web/2 worker pod UIDs under `maxUnavailable=0`; all four replacement pods joined, PubSub passed, and 363/363 samples ultimately succeeded. | Local PostGIS is a single instance. Production database HA, backups, and recovery are operator work and are not claimed complete. |
| Local observability | Implemented and protocol-verified | Pinned Prometheus scraped all 3 direct load web targets with a file Bearer credential; Grafana provisioned a healthy datasource and four-panel dashboard; Alertmanager delivered firing and resolved webhooks for an induced scoped replica stop. | Local delivery does not establish production retention, notification-provider reliability, on-call policy, or measured alert thresholds. | | Local observability | Implemented and protocol-verified | Pinned Prometheus scraped all 3 direct load web targets with a file Bearer credential; Grafana provisioned a healthy datasource and four-panel dashboard; Alertmanager delivered firing and resolved webhooks for an induced scoped replica stop. | Local delivery does not establish production retention, notification-provider reliability, on-call policy, or measured alert thresholds. |
| Encrypted local backup | Implemented and failure-verified | Pinned Restic streamed PostgreSQL custom format into pinned local MinIO with no host plaintext dump, passed full-data checking and a fresh-database restore, rejected a corrupted repository, and published no snapshot for an interrupted upload. | The retained MinIO volume is on the same workstation; this is not off-site storage, database HA, or a production RPO/RTO/retention claim. | | Encrypted local backup | Implemented and failure-verified | Pinned Restic streamed PostgreSQL custom format into pinned local MinIO with no host plaintext dump, passed full-data checking and a fresh-database restore, rejected a corrupted repository, and published no snapshot for an interrupted upload. The one-run MinIO project and volume were removed after retaining the non-secret evidence. | The drill proves the local mechanism, not off-site durability, database HA, or a production RPO/RTO/retention policy. |
| External protocol boundaries | Implemented and locally failure-verified | The production release used its configured Assent/Req and Swoosh/gen_smtp clients against an internal-only mock; OAuth and SMTP success/rejection/retry/replay/timeout paths passed. The HTTP push boundary passed disabled, retry, rejection, timeout, and idempotency paths. Request acceptance and new-chat transactions created durable jobs processed by two Oban worker replicas; the chat event completed on Oban attempt 2 after an injected temporary failure. | This does not verify external provider availability or device delivery. FCM/APNs token registration and provider selection remain external work; SMTP exactly-once delivery is not claimed. | | External protocol boundaries | Implemented and locally failure-verified | The production release used its configured Assent/Req and Swoosh/gen_smtp clients against an internal-only mock; OAuth and SMTP success/rejection/retry/replay/timeout paths passed. The HTTP push boundary passed disabled, retry, rejection, timeout, and idempotency paths. Request acceptance and new-chat transactions created durable jobs processed by two Oban worker replicas; the chat event completed on Oban attempt 2 after an injected temporary failure. | This does not verify external provider availability or device delivery. FCM/APNs token registration and provider selection remain external work; SMTP exactly-once delivery is not claimed. |
## Reproducible checks ## Reproducible checks
- The isolated Phoenix suite completed on 2026-07-19 with 171 - The isolated Phoenix suite completed on 2026-07-19 with 172
tests and 0 failures after cursor pagination, database aggregation, and the tests and 0 failures after cursor pagination, database aggregation, and the
full localization changes full localization changes
on Elixir 1.20.2 and Erlang/OTP 29.0.3. on Elixir 1.20.2 and Erlang/OTP 29.0.3.
- `mix compile --force --warnings-as-errors` and - `mix compile --force --warnings-as-errors` and
`mix format --check-formatted`: passed against the same final source. `mix format --check-formatted`: passed against the same final source.
- `./scripts/quality.sh` passed ShellCheck 0.11.0, Hadolint 2.14.0 at warning - `./scripts/quality.sh` passed ShellCheck 0.11.0, Hadolint 2.14.0 at warning
threshold, actionlint 1.7.12, all eight Compose renders, Helm lint, Trivy threshold, actionlint 1.7.12, every configured Compose profile render, Helm
source/rendered-manifest scanning, xref, Credo high-priority checks, Sobelow lint, Trivy source/rendered-manifest scanning, xref, Credo high-priority
strict/private checks, Hex audit, 167 Phoenix tests, both npm audits, and the checks, Sobelow strict/private checks, Hex audit, 172 Phoenix tests, both npm
audits, and the
backup/MinIO/mc/external-mock/release-image vulnerability scans. The rendered backup/MinIO/mc/external-mock/release-image vulnerability scans. The rendered
Helm manifest reported zero HIGH/CRITICAL misconfigurations; the Alpine Helm manifest reported zero HIGH/CRITICAL misconfigurations; the Alpine
backup, MinIO, mc, and external-mock images and the Debian 13.6 release image backup, MinIO, mc, and external-mock images and the Debian 13.6 release image
@ -56,14 +57,18 @@ results from product limits and unknown production properties.
observed database constraint changed from exactly one of 3 urgent-help observed database constraint changed from exactly one of 3 urgent-help
targets to exactly one of 5 urgent-help/Activity targets. targets to exactly one of 5 urgent-help/Activity targets.
- `mix format --check-formatted`: passed in the final run. - `mix format --check-formatted`: passed in the final run.
- Android local Docker build target: `testDebugUnitTest`, `lintDebug`, - Android local Docker build targets `testDebugUnitTest`, `lintDebug`,
`assembleDebug`, and `assembleDebugAndroidTest` passed. The isolated API 37 `assembleDebug`, and `assembleDebugAndroidTest` passed. The isolated runners
runner then passed 5/5 instrumentation tests for denied/granted location then passed 6/6 instrumentation tests on API 30, API 34, and API 37. The
permission, deep-link lifecycle, foreground location upload, notification sixth test verifies that the foreground service survives Home plus Activity
Stop, and disconnected-Stop retry state. The public-staging target ran the destruction and remains user-stoppable. The public-staging target passed
unit tests plus `lintStaging` and `assembleStaging`; both final artifacts unit tests, `lintStaging`, and `assembleStaging`; the API 37 staging smoke
retain the documented hashes. Evidence for the final device run is loaded `/` and `/safety` from the temporary HTTPS origin with no observed
`output/android-instrumentation/20260719053610-2122819`. load/TLS errors. Evidence is retained at
`output/android-instrumentation/api30/20260719162757-2877617`,
`output/android-instrumentation/api34/20260719163525-3053597`,
`output/android-instrumentation/api37-0/20260719164309-3237374`, and
`output/android-staging-smoke/20260719171121-3924350`.
- Release Android guard: a staging/release build with a non-HTTPS - Release Android guard: a staging/release build with a non-HTTPS
`WNH_BASE_URL` failed at its dedicated preflight; the successful staging `WNH_BASE_URL` failed at its dedicated preflight; the successful staging
build used the explicit temporary HTTPS origin. build used the explicit temporary HTTPS origin.
@ -76,44 +81,42 @@ results from product limits and unknown production properties.
containers also used read-only root filesystems and dropped capabilities. containers also used read-only root filesystems and dropped capabilities.
The cross-node probe observed all four BEAM nodes, and live/readiness returned The cross-node probe observed all four BEAM nodes, and live/readiness returned
`ok`/`ready`. Database counts remained `0 users / 0 help requests`. `ok`/`ready`. Database counts remained `0 users / 0 help requests`.
- The isolated Compose resilience drill observed a restart count increase for - The final isolated Compose resilience drill observed a restart count increase
one crashed web and worker BEAM process, replaced every replica sequentially, for one crashed web and worker BEAM process, replaced every replica
observed all 5 cluster nodes, passed PubSub, and completed a real Oban retry sequentially, observed all 5 cluster nodes, passed PubSub, and completed a
on attempt 2 after one recorded error. Its exact job row and all fixture real Oban retry on attempt 2 after one recorded error. Its exact job row and
domain rows were absent afterward; 758 readiness samples had no final all fixture domain rows were absent afterward; all 744 readiness samples
failure. succeeded.
- The reproducible kind rolling drill advanced both Deployments from revision - The final reproducible kind rolling drill replaced all four pod UIDs,
19 to 20, replaced all four pod UIDs, observed all 4 BEAM nodes, passed observed all 4 BEAM nodes, passed PubSub, and left the database-count diff
PubSub, and left the database-count diff empty. All 362 readiness samples empty. All 363 readiness samples ultimately returned 200; two samples needed
ultimately returned 200; two samples needed one reconnect attempt each one reconnect attempt each during local single-node NodePort endpoint
during local single-node NodePort endpoint replacement. replacement.
- The canonical local observability drill matched all 3 generated/active - The final local observability drill matched all 3 generated/active
Prometheus instance targets, checked the provisioned Grafana datasource and Prometheus instance targets, checked the provisioned Grafana datasource and
four-panel dashboard, received firing and resolved Alertmanager webhooks for four-panel dashboard, received firing and resolved Alertmanager webhooks for
the exact stopped/recovered web replica, restored every target to `up`, and the exact stopped/recovered web replica, restored every target to `up`, and
left the application-table count diff empty. Its retained evidence contains left the application-table count diff empty. Its retained evidence contains
neither the metrics token nor the random Grafana password. Final evidence is neither the metrics token nor the random Grafana password. Final evidence is
retained at retained at
`output/observability/final-observability-20260719a`. `output/observability/final-observability-current-20260719`.
- The observability stop command changed only the four scoped monitoring - The observability stop command changed only the four scoped monitoring
container states. All app/database/worker container IDs stayed unchanged and container states. All app/database/worker container IDs stayed unchanged and
running, and the checked user/request/message counts were identical before running, and the checked user/request/message counts were identical before
and after. A subsequent full drill returned all monitoring services to and after. A subsequent full drill returned all monitoring services to
healthy. healthy.
- The encrypted S3 canonical drill restored 23 public application tables, all - The final encrypted S3 drill restored 23 public application tables, all
10 current migrations, 14 categories, and PostGIS 3.6.4 into a fresh 10 current migrations, 14 categories, and PostGIS 3.6.4 into a fresh
temporary database. `restic check --read-data` passed for the retained temporary database. `restic check --read-data` passed before cleanup.
repository. Flipping the first byte of an isolated cloned repository made Flipping the first byte of an isolated cloned repository made
both `check` and `dump` exit nonzero. Stopping the exact backup container both `check` and `dump` exit nonzero. Stopping the exact backup container
after uploaded encrypted objects produced exit 130 and zero snapshots; after uploaded encrypted objects produced exit 130 and zero snapshots;
Restic identified and pruned 32.809 MiB of unreferenced packs, then passed a Restic identified and pruned 32.809 MiB of unreferenced packs, then passed a
second full-data check. Only the retained canonical bucket remained, the second full-data check. The source database count diff was empty and no
restore database and interruption container were absent, no configured configured secret appeared in retained evidence. The scoped MinIO project,
secret appeared in retained evidence, and the source database count diff was repository volume, and runtime directories were subsequently removed; the
empty. The obsolete successful-run bucket was then removed; only the final evidence remains at
canonical bucket remains. Evidence is retained at `output/backups-s3/final-backup-current-20260719`.
`output/backups-s3/final-backup-20260719a`; the retained MinIO bucket is
`wnh-backup-final-backup-20260719a`.
- The latest external-boundary drill passed real client-side OAuth token and - The latest external-boundary drill passed real client-side OAuth token and
user HTTP exchanges, PKCE/state checks, provider denial, one-time-code replay, user HTTP exchanges, PKCE/state checks, provider denial, one-time-code replay,
a fresh flow after a temporary token error, and timeout failure. It also a fresh flow after a temporary token error, and timeout failure. It also
@ -127,18 +130,19 @@ results from product limits and unknown production properties.
payload. Every retained file is mode `0600`, no generated credential was payload. Every retained file is mode `0600`, no generated credential was
retained, no host port was published, and the exact project, volume, network, retained, no host port was published, and the exact project, volume, network,
and one-run images were absent after cleanup. Evidence is retained at and one-run images were absent after cleanup. Evidence is retained at
`output/external-boundaries/push-product-pass3-20260719`. `output/external-boundaries/final-boundaries-20260719`.
- The committed browser suite passed its 1/1 bootstrap and all 8/8 Chromium - The committed browser suite passed its 1/1 bootstrap and all 27/27 scenarios:
specs against a fresh PostGIS volume with two web and two worker replicas on 9 each in Chromium, Firefox, and WebKit, against a fresh PostGIS volume with
2026-07-19. The retained successful-run artifact directory is two web and two worker replicas on 2026-07-19. The retained successful-run
`output/e2e/20260719053436-2083768`. artifact directory is `output/e2e/20260719162432-2790071`.
It covered axe checks across four pages and two themes, keyboard navigation, It covered axe checks across four pages and two themes, keyboard navigation,
three responsive widths, Activity/moderation/privacy, the two-user medicine three responsive widths, Activity/moderation/privacy, the two-user medicine
handover and blind reviews, public boundaries, local raster maps, and an handover and blind reviews, public boundaries, local raster maps, and an
offline LiveSocket transport failure/reconnect. It also verified persistent offline LiveSocket transport failure/reconnect. Each browser also recovered
Russian/Ukrainian public language selection and the selected Ukrainian active chat and tracking after its serving BEAM node stopped. It verified
locale inside an authenticated LiveView. The uniquely named Compose volume persistent Russian/Ukrainian public language selection and the selected
and networks were removed. Ukrainian locale inside an authenticated LiveView. The uniquely named
Compose volume and networks were removed.
- The default localization domain contains 508 current messages and the errors - The default localization domain contains 508 current messages and the errors
domain contains 40. Russian and Ukrainian catalogs have no empty or fuzzy domain contains 40. Russian and Ukrainian catalogs have no empty or fuzzy
current entries. Category names, descriptions, structured-field labels and current entries. Category names, descriptions, structured-field labels and
@ -153,9 +157,11 @@ results from product limits and unknown production properties.
two consecutive request pages matched the first 50 ordered rows with no gap two consecutive request pages matched the first 50 ordered rows with no gap
or duplicate. Exact observations and their non-SLO limitations are recorded or duplicate. Exact observations and their non-SLO limitations are recorded
in `docs/performance.md`. in `docs/performance.md`.
- Browser verification used headed Chrome. The authenticated matched-request - Browser verification used the required headed Chrome wrapper. The final
page rendered its chat, MapLibre marker, and live-location controls with no public homepage rendered its account/language controls, urgent-medicine hero,
console errors or warnings after the foreground-service rollout. help steps, Safety link, and three language choices. The browser reported
zero console errors or warnings; the document, fingerprinted CSS/JS, and logo
requests all returned HTTP 200. The browser was left open.
Local generated evidence (ignored by Git): Local generated evidence (ignored by Git):
@ -274,16 +280,15 @@ Certbot renewal timer were active. This verifies the current staging path; it
does not make the workstation or gateway a production availability does not make the workstation or gateway a production availability
environment. environment.
On 2026-07-19 a new read-only check resolved the origin to `77.110.101.144`; Earlier on 2026-07-19 a read-only check resolved the origin to `77.110.101.144`;
HTTP redirected to HTTPS, and the homepage, Safety page, and readiness endpoint HTTP redirected to HTTPS, and the homepage, Safety page, and readiness endpoint
returned HTTP 200 with successful TLS verification. The certificate still had returned HTTP 200 with successful TLS verification. The certificate still had
the exact SAN and the same expiry. The backing ordinary Compose project was the exact SAN and the same expiry. The backing ordinary Compose project was
healthy and its four-node PubSub probe passed. It contained 2 users, 1 help healthy and its four-node PubSub probe passed. It contained 2 users, 1 help
request, 7 messages, and 8 applied migrations. Because that public-facing data request, 7 messages, and 8 applied migrations. At that checkpoint no mutation
cannot be assumed disposable, the final local regression did not migrate or was performed before a validated backup/restore and explicit authorization.
replace that project without separate operator approval; current source was The later authorized rollout is recorded below; this paragraph is historical,
instead rebuilt and exercised in the isolated Compose profiles and the not the current deployment state.
project-owned kind cluster.
A mode-`0600` custom-format backup of that exact database was then created at A mode-`0600` custom-format backup of that exact database was then created at
`output/backups/compose-20260719-060810.dump` with SHA-256 `output/backups/compose-20260719-060810.dump` with SHA-256
@ -374,10 +379,13 @@ Local ignored browser evidence:
The public-staging APK was built with the explicit ignored `.env` The public-staging APK was built with the explicit ignored `.env`
`WNH_BASE_URL`, installed on the API 37 emulator, and connected to `WNH_BASE_URL`, installed on the API 37 emulator, and connected to
`https://whoneedhelp.imalto.site`. Android package inspection found exactly one `https://whoneedhelp.imalto.site`. Android package inspection found the exact
matching Activity for the configured HTTPS host and no matching Activity for configured HTTPS authority and no filter for `attacker.example`. Because the
`attacker.example`. A standard implicit `ACTION_VIEW` launch of `/safety` manifest intentionally does not claim App Link verification, a normal same-host
opened the native `MainActivity` and displayed the public Safety rules. implicit `ACTION_VIEW` may show Android's resolver. Selecting the application
opened its native `MainActivity`; both `/` and `/safety` loaded from the public
origin with no observed WebView load or TLS errors. The external origin
resolved to the browser rather than the app.
The manifest intentionally sets `android:autoVerify="false"`: this is a The manifest intentionally sets `android:autoVerify="false"`: this is a
same-origin HTTPS deep link, not a claimed verified Android App Link. Enabling same-origin HTTPS deep link, not a claimed verified Android App Link. Enabling
@ -452,57 +460,125 @@ this verification window.
## Final full-stack regression ## Final full-stack regression
The complete local regression was repeated against application commit The final application source under test was commit `c6aa3d1`; the later
`0ad71f6` on 2026-07-19: documentation-only commit does not alter the tested runtime.
- `./scripts/quality.sh` passed the full static/security/dependency gate and - `./scripts/quality.sh` passed the complete static, formatting, compiler,
167/167 Phoenix tests. The isolated external-service drill also passed on the xref, Credo, Sobelow, Dialyzer, dependency-audit, manifest, secret, and image
same source and removed its exact one-run project and images. gates. ExUnit reported 172 passed. The final log is
- The fresh browser project passed its 1/1 bootstrap and all 8/8 Chromium `output/regression/final-20260719/quality-current.log`.
scenarios, then removed its containers, two networks, and PostgreSQL volume. - The isolated browser project passed its bootstrap 1/1 and 27/27 scenarios:
- Android debug and public-staging builds repeated unit tests, lint, and APK 9 in each of Chromium, Firefox, and WebKit, with no skipped, flaky, or
assembly. The network-isolated API 37 emulator passed 5/5 device tests and unexpected result. The suite includes accessibility, responsive navigation,
was removed with its one-run image. A non-HTTPS staging/release origin failed medicine handover, blind reviews, Activity privacy/moderation, localization,
at the dedicated Gradle guard. reconnect, and active chat/tracking recovery after the serving BEAM node
- The database-scale project measured 50,000 rows per large table before and stops. Evidence is `output/e2e/20260719162432-2790071`.
after the cursor-index migration, verified consecutive cursor pages, and - Android debug and staging unit/lint/build gates passed. Six instrumentation
removed its database volume and image. tests passed independently on API 30, 34, and 37, including the foreground
- The 3-web/2-worker load run passed 35,316/35,316 public checks, 39,108 HTTP tracking service surviving Home plus Activity destruction. The separate API
requests with zero failures, 1,888 authenticated write/tracking chains, and 37 public-staging smoke loaded home and Safety over the exact temporary HTTPS
240 heartbeat WebSockets. Exact fixture cleanup restored the pre-run origin, matched no external-origin app filter, and observed zero load/TLS
application-table counts and PubSub passed. errors.
- The Compose failure drill observed both BEAM container restarts, replaced all - A real public Chromium two-user scenario registered isolated requester/helper
five replicas, passed 758 readiness samples, and completed and removed the fixtures, completed medicine discovery, acceptance, realtime chat, consent
one-failure/second-attempt Oban probe. The current-image kind rollout replaced tracking, handover, both confirmations, and blind reviews. It passed 1/1 in
all four pod UIDs under `maxUnavailable=0`, passed all 362 readiness samples, 12.8 seconds. Exact fixture cleanup removed its users and domain rows; the
cluster/PubSub, and an empty database-count diff. before/after public database diff was empty. Evidence is
- Prometheus matched all three current web targets; Grafana provisioning passed; `output/staging-e2e/20260719170530-3787963`.
Alertmanager delivered firing and resolved webhooks around one exact replica - The 600.5-second authenticated soak completed 271,072 iterations and 767,225
stop/recovery; the database-count diff was empty. HTTP requests with zero failed HTTP requests. All 703,995 public checks
- Restic/MinIO passed encrypted stream backup, full-data check, fresh-database passed; expected-response latency was 2.337 ms average, 5.705 ms p95, and
restore, corrupted-repository rejection, and interruption without a snapshot. 175.955 ms maximum in this local run. Eight authenticated sessions completed
Temporary buckets/databases/containers were absent afterward, the obsolete 31,607 request-page/LiveView/chat/tracking start-update-stop chains and 4,800
retained bucket was removed, and only the final canonical bucket remains. heartbeat WebSockets without an authenticated or WebSocket error. The
- The ordinary public-facing Compose project first passed read-only database observed zero rollbacks, deadlocks, conflicts, or temporary files
live/readiness, cluster/PubSub, public HTTPS, DNS, TLS, backup/restore, and during the measured interval. Exact fixture cleanup restored every tracked
isolated upgrade rehearsal checks. After explicit approval, it was backed up table count. These are observations, not production SLOs or capacity limits;
again, migrated from 8 to 10 migrations, and replaced with the current evidence is `output/performance/authenticated-soak-10m-20260719`.
2-web/2-worker release. Its application-table count diff remained empty; - The final isolated Compose failure/replacement drill used 3 web and 2 worker
schema, health, cluster/PubSub, public HTTP/TLS/WebSocket, logs, localization, replicas. All five nodes rejoined, PubSub passed, 744/744 readiness samples
and the protected-route browser flow passed after rollout. succeeded, and the injected Oban job completed on attempt 2 after exactly one
recorded error. Evidence is
`output/resilience/final-resilience-current-20260719`.
- The final project-owned kind rolling drill replaced all four web/worker pod
UIDs, left all four replacements Ready with zero restarts, passed PubSub and
an empty database diff, and completed 363/363 readiness samples; two needed
one retry during the local single-node endpoint change. The current retained
kind release is Helm revision 13 with 2/2 web, 2/2 worker, and PostGIS 1/1
Ready. Evidence is `output/resilience/final-kind-current-20260719`.
- Prometheus matched all three direct web targets before and after the scoped
failure; Grafana provisioning passed; Alertmanager delivered both firing and
resolved webhooks for `who_need_help_load-web-19`; the database diff was
empty. Evidence is
`output/observability/final-observability-current-20260719`.
- Restic/MinIO passed encrypted streaming backup, full-data repository check,
fresh-database restore, corrupted-repository fail-closed checks, and
interruption after uploaded objects with zero published snapshots. The
source database diff was empty. Evidence is
`output/backups-s3/final-backup-current-20260719`; the one-run MinIO project
and volume were removed after the drill.
- The database-scale harness used 50,000 configured rows per large table,
captured 16 before/after plans, selected every asserted cursor index, and
verified consecutive request pages without a gap or duplicate. The exact
observations and limits are in
`output/db-scale/20260719164620-3314314` and `docs/performance.md`.
- OAuth, SMTP, and HTTP-push boundaries passed success, rejection, timeout,
retry, replay, and deduplication checks against local internal-only
counterparts. Product acceptance and chat events produced durable jobs
consumed by two worker replicas; message content was excluded from push.
GitHub OAuth remains optional and disabled without credentials. Evidence is
`output/external-boundaries/final-boundaries-20260719`.
- A clean tracked-archive deployment at `c6aa3d1` applied all 10 migrations,
repeated migration idempotently, seeded 14 categories without duplication,
started 2 web and 2 worker replicas, passed HTTP/Mailpit/cluster/PubSub, and
left its project, image, volume, and extracted workspace absent after
cleanup. Evidence is
`output/portability/20260719171321-3973031-61769f`.
- The ordinary public Compose database was backed up to mode-`0600`
`output/backups/compose-20260719-165722.dump` with SHA-256
`5b4d8a78665c5d47863af8e1e885684b110d94c278474e37c8465e0814f7000f`.
The archive passed catalog validation and an isolated restore before rollout.
The current public image ID is
`sha256:009f6754fb57a410f16252205bbfa1467a08b82a733de59c3c80e431afa8fc42`
on 2 healthy web and 2 running worker replicas. The deployment diff was
empty; the final read-only observation remains 2 users, 1 request, 7
messages, 4 ended tracking sessions, and 10 migrations.
- After the workstation restart, the public route initially timed out because
its existing OpenVPN connection was down. Inspection confirmed Nginx still
targeted the assigned client address `10.8.0.14`; reactivating the existing
`client1` NetworkManager profile restored that address and the public path.
The final observation returned HTTPS 200, HTTP 301 to HTTPS, and the correct
`77.110.101.144` endpoint. Headed Chrome then rendered the homepage with zero
console errors or warnings; its document, CSS, JS, and logo requests returned
200. The visible browser was left open.
- Scoped cleanup left zero containers, volumes, and networks for the
`who_need_help_load` project and removed its ignored observability/backup-S3
runtime directories. The reusable ordinary public Compose project and the
project-owned kind cluster intentionally remain running.
## Known work before a public production launch ## Known work before a public production launch
- Replace the temporary staging origin with the production-owned domain and - Replace the temporary staging origin with the production-owned domain and
production-sign the Android app. production infrastructure. The temporary origin is available only while the
- Operate PostgreSQL/PostGIS with backups, recovery testing, and the required workstation, Compose stack, VPN path, gateway, and their networks are up.
availability model. - Create a production Android signing identity, publish
`/.well-known/assetlinks.json` for the final application ID/fingerprint if
verified App Links are wanted, and complete store policy/release work.
- Operate PostgreSQL/PostGIS with off-site backups, recovery testing, monitoring,
and the availability model selected for real usage.
- Configure a real transactional email provider before public registration.
The current Compose mail path terminates at local Mailpit.
- Configure and verify a real mobile push provider and device-token lifecycle
if native push is required. The provider-neutral HTTP boundary and product
jobs are tested; FCM/APNs device delivery is not.
- Load-test representative data and traffic, then set measured pool, resource, - Load-test representative data and traffic, then set measured pool, resource,
autoscaling, and action-limit policies. autoscaling, and action-limit policies.
- Repeat representative authenticated write, chat, tracking, and reconnect
load scenarios before deriving production capacity or autoscaling policy.
- Publish jurisdiction-specific emergency contacts, privacy, retention, - Publish jurisdiction-specific emergency contacts, privacy, retention,
prohibited-items, and voluntary-payment guidance after legal review. prohibited-items, and voluntary-payment guidance after legal review.
- Create and configure a GitHub OAuth App, then exercise the real external - Establish moderation/support operations and incident response for real users.
provider redirect/callback in a headed browser. Until then staging keeps the - If verified GitHub identity is desired, create and configure its OAuth App and
provider disabled and manual links remain unverified. exercise the external redirect/callback. This is an optional enhancement, not
a registration or launch blocker.
- Production capacity, minimum CPU/RAM, database HA topology, and autoscaling
thresholds remain unknown until representative target-environment
measurements exist.