Unphish v2 Docs

Release gates

What must be green before a deployment is promoted to staging or production.

A change moves through three deployment targets: preview (every PR), staging (merge to main), and production (manual promotion). Each gate is more selective than the last.

Preview deployment

Created automatically by Vercel for every pull request. Required to be green for merge:

  • Lint passespnpm lint.
  • TypeScript typecheck passespnpm typecheck. TypeScript build errors must not be ignored for production-bound code.
  • Build succeedspnpm build.
  • Unit tests passpnpm test.
  • Worker config tests pass if workers/ was touched.
  • Workbench tests pass if lib/workbench/ was touched.
  • Migration tests pass if scripts/audit-v1-dump.js or migration code was touched.
  • Route smoke passes against the preview URL.
  • Frontend hub & team QA checklist signed off if Hub or team surfaces were touched.
  • Affected parity rows updated with new source-status / QA-status as appropriate.

Promotion to staging

When a PR merges to main, Vercel deploys to staging automatically. Before staging is considered "good", the following must be checked — usually by the next-on-rotation engineer:

  • Authentik sign-in works in staging.
  • Dashboard loads with explicit source labels (live / imported / unavailable) for the staging environment.
  • No production route silently shows demo data. This is the single most common regression and it must not ship.
  • Worker heartbeat is green in /hub/readiness.
  • Provider mode is fixture or sandbox for staging (never live for non-production providers).
  • Recent migrations applied cleanly/admin/imports shows no failed batches.

If any of these fail, the merge is reverted or hotfixed before further work proceeds.

Promotion to production

Production promotion is manual and gated. The promoting engineer (or release manager) must satisfy all of the following:

Build and CI

  • CI green on the commit being promoted.
  • No TypeScript errors suppressed.
  • No skipped tests without justification in the parity matrix.

Parity matrix

  • All P0 rows for affected surfaces are green (Implemented + Pass + Updated docs).
  • No P0 row is Missing or Blocked for any surface in the release.
  • No P0 row passes via fixture fallback (source-state assertion is honest).

QA

  • Frontend hub & team QA checklist signed off if Hub/team is in the release.
  • Local parity smoke passes (pnpm test:local-parity-smoke).
  • Playwright e2e passes for the highest-value journeys (sign-in, invite, threat-feed-to-enforcement, client approval, watchlist promotion, verification).
  • Dark mode QA passes for any of: dashboard, threat feed, case detail, client review, partner queue, watchlist, whitelist, scan centre.
  • Responsive QA passes for dense tables and drawers at the supported breakpoints.

Migration

  • Migration report approved if the release includes a migration.
  • Row counts validated against v1 source.
  • No orphan records introduced.
  • legacy_v1_* fields populated for traceability.

Auth and secrets

  • Authentik configuration confirmed for production (AUTH_AUTHENTIK_* env vars present, recovery URL set, admin token valid).
  • Provider secrets in Vercel/Render production environment are populated and recently health-checked.
  • Provider modes for production are live for ready providers and fixture/unconfigured for everything else, with the difference clearly intentional.

Audit and rollback

  • Audit log writes verified for any new sensitive flow in this release.
  • Rollback documented in the deploy annotation: how to revert, what to do if a migration is irreversible, who to page.
  • Production cutover plan referenced if the release is part of the v1 cutover.

Post-promotion verification

After promoting:

  • /hub/readiness green within 5 minutes.
  • First real user sign-in succeeds end-to-end.
  • Verification queue shows expected scheduled checks running on time.
  • No spike in /api/audit errors or worker DLQ counts.
  • Customer-facing surfaces show correct source labels (live for live data, imported for migrated data, no silent fixture fallback).

If any post-promotion check fails, roll back per the documented procedure.

Release-blocking review findings (always tested)

These four findings from earlier reviews are permanently represented as tests. A release that breaks any of them is blocked, regardless of other state:

FindingRequired test
Invite acceptance used a mismatched auth/session modelInvite acceptance must never write neon_auth.account rows; must use Authentik OIDC session path.
Team management used mixed schemas and invalid role valuesTeam list / invite / edit / delete / resend / revoke use one canonical table family; every role is normalized.
Production tenants were blocked from live data by POC flagsDashboard always attempts live org/client stats; POC/demo flags only affect onboarding messaging.
Cases / intelligence could fall back to demo silentlyProduction APIs return live / imported / unavailable source metadata and never silently substitute demo.

Things that are not gates

  • A green TypeScript build is not signoff. Compile checks shape, not behavior.
  • Manual click-through with DEV_AUTH_BYPASS is not signoff. Real cookies only.
  • A passing unit test is not signoff for a UI flow. Real browser only.
  • "Tested in workbench" is not staging signoff. Workbench has same contracts but different transport; staging is the closest production proxy.

Pilot cutover gate (one-time)

The pilot cutover — first real customer in production — has additional requirements layered on top of the standard production gate:

  • Pilot epic 1 (Hub Team) all P0 rows green.
  • Pilot epic 2 (Real Data Foundation) all P0 rows green.
  • Pilot epic 3 (Pilot Workflow) all P0 rows green end-to-end.
  • Pilot epic 4 (Legacy Parity) all P0 rows green for the surfaces the pilot client uses.
  • Pilot epic 5 (Workbench ↔ Production) the five replay scenarios (happy path, ambiguous, provider rejection, resurrection, false-positive) execute correctly.
  • Pilot client UAT signoff documented.
  • Live Authentik production tenant configured and tested.
  • Live provider credentials in production with at least one successful real-call health check.
  • Pilot rollback plan — specifically, how we put the pilot client back on v1 if v2 fails.

The pilot cutover is the single most consequential release. Treat it as the highest-stakes gate.

On this page