# Verification - 2026-10-06

V2 is the base. Original V1/V2 ZIPs, real `.env`, existing running Docker project, database and uploads were not replaced or reset. Tests used the separate `justice-choice-final-verify` Docker project and explicitly disposable `justice_choice_verify_<12 hex>` / security/enquiry regression databases. Fresh fixture secrets were generated privately and excluded from the release.

## Actual local results

| Check | Result |
| --- | --- |
| Packages (types/ranking/SEO/database/search), Nest API and all four worker builds | Passed, clean Node 22 Docker builds |
| Public and admin Next.js production builds, lint/type validation | Passed; final admin rebuilt after confirmation wording changes |
| Workspace type checking | Passed |
| Unit tests | 54 passed, 0 failed: ranking 12, SEO 8, API/security 34 |
| Disposable database integration regressions | 39 checks passed across five scripts |
| Fresh migrations and V2-to-final upgrade | Passed; existing fixture record preserved; repeat migration safe |
| HTTP smoke | 24 passed, including score decomposition, payment separation, RBAC, search, thin-page SEO, sitemap/robots/public routes |
| HTTP E2E accounts | 45 passed, 0 failed |
| HTTP E2E firms/claims/files/credentials/team | 61 passed, 0 failed |
| HTTP E2E enquiry routing/lifecycle/webhook SSRF | 33 passed, 0 failed |
| HTTP E2E Stripe test configuration | 34 passed, 0 failed |
| HTTP E2E clients/compare/alerts/export/deletion/analytics | 45 passed, 0 failed |
| Actual worker jobs | Import + repeat-payload dedup, ranking + SEO, sitemap XML, verification expiry passed; all four durable success/heartbeat rows checked |
| Production image | Build passed; nonroot UID, seed/test exclusions and production data-action/config refusal asserted |
| Production-mode API fixture | Started and queried only the disposable database; required scanner setting enforced |
| Redis URL isolation | TLS/auth/database selection unit coverage; final production QueueService connected to selected Redis DB 15 |
| Development/production Compose | Parsed; private DB/cache/scanner, enforced production image/mode, migration-only startup, loopback ports and local 4002/3002/3003 URL invariants asserted |
| Dependency advisory audit | 0 reported vulnerabilities in current lockfile; valid audit JSON is docs/DEPENDENCY-AUDIT.json |
| Drizzle schema metadata | Fresh 0008 snapshot generated; migration generation reports zero schema drift |

The final clean harness run rebuilt current sources and completed all five HTTP suites, all integration scripts, unit/type checks, smoke tests and actual worker jobs in one fresh invocation. The harness and checks container exited with code 0 and removed only the disposable verification stack. Machine-readable sanitized results are in docs/VERIFICATION-RESULTS.json. Raw fixture logs are excluded because test mailbox/SQL failures can include disposable credentials.

## Reproduce

`powershell -ExecutionPolicy Bypass -File scripts/verify-docker.ps1` builds fresh images, uses private fixture secrets, starts disposable PostgreSQL/Redis, typechecks/tests, creates isolated regression databases, applies migrations and explicitly seeds its test database, then exercises HTTP suites and real worker jobs. It tears down only its own project and never deletes real volumes.

Database-only: `NODE_ENV=test` and a disposable `DATABASE_URL` with database name `justice_choice_verify_<12 hex>`, then `npm run test:integration` after building packages/API. SMTP interception is test-only and requires opt-in plus that database naming guard. ClamAV INSTREAM fixtures exercise clean, malware, malformed reply and scanner outage rejection.

Compose: `python scripts/verify-compose.py <private-production-env-file>` validates without emitting rendered secrets. Schema metadata generation was performed only in temporary container directories; no generated SQL was applied to real data. Packaging: `python scripts/package-release.py` generates a fresh SHA-256 manifest and validates archive CRC and every shipped file hash.

## Findings resolved during verification

Initial attempts exposed an existing/new trigram index-name collision, an old maximum token length that rejected nonce-bearing MFA JWTs, optional privileged invitation confirmation, Linux shell line endings and test startup readiness races. Each was fixed and relevant checks rerun. A transient npm registry reset and Docker Desktop container-inspection 500 were retried; the final clean run succeeded. A production fixture initially competed with the test mail consumer because Redis URL database selection was not retained; database selection is now supported and verified, and that fixture was stopped before final client checks.

Host workspace links prevented the initial native build; authoritative results use clean Docker npm installs. No native-host build pass is claimed.

## External and operator acceptance

Implementation verified locally; live external integration requires production credentials.

SMTP delivery/authentication was intercepted for automated tests. Stripe uses signed local test fixtures, not a real charge. Real private S3/IAM/object persistence, a running ClamAV engine/signature update and EICAR acceptance, real SMTP inbox/spam/DMARC, live Stripe checkout/refunds/webhooks, Google Search Console authentication, DNS/TLS/reverse proxy, backup scheduling/offsite encryption/restore and real-source licensing must be configured and validated by the deploying operator. No working live integration or backup is claimed without those checks.

Automated HTTP tests do not constitute a browser visual audit of every screen or production load/penetration testing. New-browser alerts use bounded user-agent comparison, not device fingerprinting. Review jurisdiction-specific Terms/Privacy/retention before launch. Consult DEPLOYMENT.md and SECURITY.md for actual production steps and boundaries.
