Terminal map

Ten code-backed maps of Tort Terminal, drawn from the code on November 8, 2026.

The short version

  1. Meta spend reaches Neon hourly; Google and TikTok still ride Hevo and BigQuery twice a day.
  2. A case is born only by a signing; its status never changes, timestamps do the excluding.
  3. Prod migrations need two signatures in code; the release rule lives only in docs.
  4. Links between schemas are plain joins with no constraint, so a broken mapping moves money quietly.

System map

Tort Terminal: ad spend buys leads, leads become cases, firms read CPSC An architecture diagram generated by Archify. Meta Graph API v22 · ad accounts, insights, demographics · Architecture component · Meta Meta Graph API v22 ad accounts, insights, demographics AppLovin Reporting API · advertiser report, trailing 45 days · Architecture component AppLovin Reporting API advertiser report, trailing 45 days BigQuery levy-law-jdc · Hevo-landed Google + TikTok, transport only · Architecture component BigQuery levy-law-jdc Hevo-landed Google + TikTok, transport only Schema migrations · 758 files to 852; prod needs two signatures · GitHub Actions (.github/workflows): the deploy boundary Schema migrations 758 files to 852; prod needs two signatures GitHub Actions · PR gate; Release ships Vercel, image, Terraform · GitHub Actions (.github/workflows): the deploy boundary · GitHub Actions GitHub Actions PR gate; Release ships Vercel, image, Terraform Direct spend ingest jobs · meta :07 hourly + 02:37 restatement; applovin :13 · GCP project zenith-jobs, us-east4 (Terraform infra/) › Cloud Run Jobs, one cron-jobs image Direct spend ingest jobs meta :07 hourly + 02:37 restatement; applovin :13 BQ mirror jobs (Google, TikTok) · twice daily, __hevo__loaded_at watermark · GCP project zenith-jobs, us-east4 (Terraform infra/) › Cloud Run Jobs, one cron-jobs image BQ mirror jobs (Google, TikTok) twice daily, __hevo__loaded_at watermark refresh-campaign-daily-spend · hourly :25, REFRESH MATVIEW CONCURRENTLY · GCP project zenith-jobs, us-east4 (Terraform infra/) › Cloud Run Jobs, one cron-jobs image refresh-campaign-daily-spend hourly :25, REFRESH MATVIEW CONCURRENTLY ghl-sync + ghl-*-sync jobs · poll every 15 min, 10 shards, token keeper · GCP project zenith-jobs, us-east4 (Terraform infra/) › Cloud Run Jobs, one cron-jobs image ghl-sync + ghl-*-sync jobs poll every 15 min, 10 shards, token keeper Cloud Run Jobs runner · entrypoint -> jobs/<name>; Slack alert on failure · GCP project zenith-jobs, us-east4 (Terraform infra/) › Cloud Run Jobs, one cron-jobs image · Google Cloud Cloud Run Jobs runner entrypoint -> jobs/<name>; Slack alert on failure Cloud Scheduler · POST :run per job · GCP project zenith-jobs, us-east4 (Terraform infra/) Cloud Scheduler POST :run per job Secret Manager · DATABASE_URL + tokens · GCP project zenith-jobs, us-east4 (Terraform infra/) Secret Manager DATABASE_URL + tokens ad_spend.* raw mirrors · meta_*, applovin_* direct; google_*, tiktok_* via BQ · Neon Postgres: zenith DB (@neondatabase/serverless) ad_spend.* raw mirrors meta_*, applovin_* direct; google_*, tiktok_* via BQ ops.* canonical (ADR-007) · campaigns, lead_submissions, cases, campaign_daily_spend · Neon Postgres: zenith DB (@neondatabase/serverless) · Neon ops.* canonical (ADR-007) campaigns, lead_submissions, cases, campaign_daily_spend ghl.* CRM mirror · contacts, opportunities, messages, tasks · Neon Postgres: zenith DB (@neondatabase/serverless) ghl.* CRM mirror contacts, opportunities, messages, tasks GoHighLevel CRM · services.leadconnectorhq.com, OAuth · Architecture component GoHighLevel CRM services.leadconnectorhq.com, OAuth Public + partner routes · /api/forms public; /api/partner LK pull keys · Vercel: tortterminal.com (prod, Release only) and tortterminal-dev.com (beta), root app/ Public + partner routes /api/forms public; /api/partner LK pull keys Clerk + authorize() ADR-016 · pillar, role, permission, resource · Vercel: tortterminal.com (prod, Release only) and tortterminal-dev.com (beta), root app/ Clerk + authorize() ADR-016 pillar, role, permission, resource API routes (546 route.ts) · audit:acl gate; repositoryHandler; Neon SQL · Vercel: tortterminal.com (prod, Release only) and tortterminal-dev.com (beta), root app/ API routes (546 route.ts) audit:acl gate; repositoryHandler; Neon SQL Webhook receivers · OIDC Pub/Sub, Clerk, Trulioo, Twilio status · Vercel: tortterminal.com (prod, Release only) and tortterminal-dev.com (beta), root app/ Webhook receivers OIDC Pub/Sub, Clerk, Trulioo, Twilio status Integration clients (ADR-018) · GHL, R2, SendGrid, Slack, Twilio, Trulioo · Vercel: tortterminal.com (prod, Release only) and tortterminal-dev.com (beta), root app/ Integration clients (ADR-018) GHL, R2, SendGrid, Slack, Twilio, Trulioo Tort Terminal web (Next.js 16) · capital, ops, claimant, intel pillar hosts · Vercel: tortterminal.com (prod, Release only) and tortterminal-dev.com (beta), root app/ · Next.js Tort Terminal web (Next.js 16) capital, ops, claimant, intel pillar hosts Metrics: signed cases + CPSC · active, not excluded; all-in cost / signed · Vercel: tortterminal.com (prod, Release only) and tortterminal-dev.com (beta), root app/ Metrics: signed cases + CPSC active, not excluded; all-in cost / signed Claimant · intake.levylaw.com page · Architecture component Claimant intake.levylaw.com page tt-agent-mcp · separate repo · Architecture component tt-agent-mcp separate repo Law firm investors + Zenith staff · browser, Clerk session · Architecture component Law firm investors + Zenith staff browser, Clerk session zenith-events (GCP, separate repo) · events.tortterminal.com; Pub/Sub push + OIDC · Architecture component zenith-events (GCP, separate repo) events.tortterminal.com; Pub/Sub push + OIDC Cloudflare R2 · documents · Architecture component · Cloudflare Cloudflare R2 documents Vendor APIs · SendGrid Slack Twilio Trulioo · Architecture component Vendor APIs SendGrid Slack Twilio Trulioo verify-page service · /v/:token government-ID upload · GCP zenith-jobs: Cloud Run services (same image) verify-page service /v/:token government-ID upload lk-pull-api service · api.tortterminal.com; same LK handlers · GCP zenith-jobs: Cloud Run services (same image) lk-pull-api service api.tortterminal.com; same LK handlers LK partner systems · per-org bearer key · Architecture component LK partner systems per-org bearer key Graph insights, 3-day lookback advertiser report SELECT since watermark upsert meta_*, applovin_* upsert google_*, tiktok_* REFRESH campaign_daily_spend poll contacts shadow rows leads, claimants POST :run mounted env image + terraform on Release form_submissions; LK reads SQL over HTTP, withTransaction signings -> ops.cases authorize() Clerk session cpsc(), signed predicate clients + outbox REST writes: fields, tags, upserts presigned URLs email, alerts, SMS, KYC HTTPS, CPSC dashboards intake form posts API keys, service accounts Pub/Sub push, OIDC SMS link /v/:token GET cases, government IDs GitHub Actions (.github/workflows): the deploy boundary GCP project zenith-jobs, us-east4 (Terraform infra/) Cloud Run Jobs, one cron-jobs image Neon Postgres: zenith DB (@neondatabase/serverless) Vercel: tortterminal.com (prod, Release only) and tortterminal-dev.com (beta), root app/ GCP zenith-jobs: Cloud Run services (same image)
Open the full system map: tap any box there for the file and lines behind it.

From you

Open the system map first; tell me which box you want drawn deeper.

Each map stops at the box; a deeper drawing opens the code paths inside the one you pick.

Default if you do not pick: the ad-to-campaign join every platform's spend passes through on the way to CPSC.

At a glance

The ten maps

MapWhat it shows
System mapSpend in, leads and cases through, CPSC out
Spend to CPSCA dollar from ad platform to CPSC
Lead to caseA GHL lead to a signed case
Case statusWhere a case's status can move
Diligence statusA diligence case, received to sent
Money schema28 tables, 485 columns, standard density
Migration gateHow a migration reaches prod
Release pathHow a change reaches prod
Repository treeWhat lives where in the repo
2026 timelineReleases, decisions and schema in 2026

Findings

Details

The ten maps
The findings in full
  • ops.cases.status has one writer, the birth INSERT that sets active, and no code ever changes it; the signed count is really three timestamp columns (quarantined_at, operator_excluded_at, archived_at) that a CI gate must police on every read.
  • RELEASE-GO appears only in CLAUDE.md and release-process.md, no workflow or script reads it, and both agent apps sit on the tag bypass list; either Jean or Brick can publish a release alone, while prod migrations refuse without two non-author signatures.
  • Meta spend lands in Neon straight from Graph (hourly with a 3-day lookback, nightly with a 28-day restatement), but Google and TikTok still go Hevo to BigQuery to a twice-daily mirror, and the TikTok mirror header says it has been dry since 2025-12-30; every platform then funnels through one join, ops.campaign_ads.external_ad_id, into the hourly matview.
  • GHL inbound is a 15-minute poll, not webhooks, and a signing reaches ops.cases only through zenith-events (a separate repo) and the document-events webhook; case freshness depends on two systems outside this repo.
  • The schema overview doc stops near migration 498 while the live chain is at 852, and intelligence.tortterminal.com is not in source (the code's intel host is intel.tortterminal.com, marked future); the map shows what the code says, and those two gaps are the first fixes.
What the code corrects in the rig's memory

A migration file with no history on origin/main is refused outright (both agents count as authors), not "needs a human co-signer". A zero-signature operator path (db:migrate:prod:operator, a human types APPLY) exists, and the audit accepts the row as operator. release-process.md line 141 still says prod needs a human's approval while the section above it accepts Jean plus Brick alone.

Dry and divergent

The Targets surface reads ops.ad_spend_per_ad, and its own source comment records an $834,499 disagreement with the campaign_daily_spend matview. The formulas/cpsc.ts module built to force an aligned window has no production importer; the services divide inline and resolveRanges aligns the window.

Case Diligence side doors

The two KYC-phase moves the cron makes most often (kyc_queued to kyc_processing, and the no-session kyc_failed) are inline UPDATEs outside the state machine and never reach audit.events.

Schema caveats

Raw Hevo mirrors are trimmed to money and join columns (counts on the page). ops.campaigns and ghl.contacts predate app/migrations, so their columns come from the sandbox bootstrap and later ALTERs. 13 real foreign keys, 22 logical joins. Schemas: ops and ghl predate app/migrations; twelve more are created in migrations (ad_spend, audit, case_diligence, deel, kyc, lead_resolution, ledger, media_desk, public_intel, system, usage, zenith); nerve and migration were created and later dropped, so 14 are live.

How it was built

Archify 3.2.0 (Apache-2.0) with its update check off, read-only on the Terminal checkout (git status unchanged before and after), every box and step citing its file and lines at main 2afb20a, Chrome browser-check on every page; the desk look is a post-process (deskify) that leaves each Archify file and its receipts untouched.