Hosting
Spectral runs its API/workers runtime on a single Cloudflare app container and its human-facing surfaces on Cloudflare Pages, all against a locked Supabase substrate behind the Cloudflare edge. The workload is I/O-bound end to end — the only heavy compute is LLM inference, which runs at the provider on the authoring path, never on the synchronous decision path. Decision lineage in ADR-109 (hosting topology) and ADR-110 (provisioning); operational detail in docs/runbooks/hosting.md.
Substrate layers
Section titled “Substrate layers”- Compute — one Cloudflare Container for API/workers. Built from
infra/docker/app.Dockerfileand launched byapp_supervisor.py, the container runs both entrypoints as sibling processes: the FastAPI API (port 8000) and the background workers runtime. A thin Cloudflare Worker fronts the container and proxies every request to the API port. The predicate/decision tier executes in-process inside the container for alpha — the sandbox (ADR-083) already bounds the blast radius. The API and workers stay separately-launchable entrypoints, so splitting a tier onto its own host later is a deploy-manifest change, not a rewrite. - Human-facing surfaces — Cloudflare Pages.
app.,ops.,docs., andcodex.are separate Pages projects. Dashboard and Operations are Vite SPA builds; Pages Functions provide same-origin API proxying, and Operations/Codex carry JWKS-local staff gates. - Edge — Cloudflare. Authoritative DNS, edge TLS, every product hostname proxied (including
api.), per-key rate limiting + WAF posture, the codex Pages-Function JWKS gate, and cookie discipline, per ADR-052. - Data / event substrate (locked) — Supabase. Managed Postgres + Auth + pgvector + Realtime. The source of truth for
core.outbox, generation stamping,LISTEN/NOTIFY, andcore.event_handledper ADR-044. The container and the deploy’s migration step both connect over the session pooler (session mode supportsLISTEN/NOTIFY, so the outbox consumer keeps its listen path). The substrate does not move.
Subdomain layout
Section titled “Subdomain layout”| Hostname | Audience | Edge posture |
|---|---|---|
app.runspectral.com | Customer dashboard (spectral-dashboard Pages) | Proxied edge + /api/* proxy Function |
ops.runspectral.com | Staff Operations app (spectral-operations Pages) | Proxied edge + JWKS gate + /operator/* proxy Function |
api.runspectral.com | Programmatic | Proxied edge |
docs.runspectral.com | Public docs | Proxied edge |
codex.runspectral.com | Staff Codex (JWKS-gated) | Proxied edge + Pages Function |
Cookie scope: Domain=runspectral.com eTLD+1 — cross-subdomain session sharing.
Disaster recovery
Section titled “Disaster recovery”Disaster recovery is Supabase-native managed backups + point-in-time recovery (ADR-040), adopted before customer data lands. There is no self-run backup pipeline, no nightly-dump cron, and no separate backup bucket — the managed backup tree is isolated from the application runtime by the provider, and PITR covers the recovery window.
Configuration placement
Section titled “Configuration placement”Two classes of runtime configuration, placed differently:
- Rotating key material — Supabase keys, provider API tokens, OAuth secrets — is resolved by
tools/provision/provision.shfrominfra/environments.toml+ 1Password into the GitHub Environment (ADR-110), and applied to the container or Pages deploy at deploy time. - Code-coupled values —
SPECTRAL_GENERATION, handler concurrency limits — are set as per-service container vars at deploy time, never in the shared environment. Correctness depends on the running image, so the value moves with the image.
Compute split triggers
Section titled “Compute split triggers”One shared container today. The separately-launchable entrypoints are the re-split seam; the documented triggers (ADR-109):
- Supabase-locality latency materially degrades the closed loop.
- A Cloudflare control-plane outage exceeds tolerance.
- Cost exceeds the modeled envelope at dogfood scale.
The mitigation is the same seam: re-split the DB-chatty tier onto its own host via the deploy manifest, no code rewrite.
See also
Section titled “See also”- ADR-109 — hosting topology
- ADR-110 — provisioning + the runtime secret hop
- ADR-052 — the Cloudflare edge
- ADR-040 — Supabase-native DR
- Deployment topology — the one-container runtime + generation cutover
- CD pipeline overview — deployment orchestration
- Frontend architecture — frontend topology + cookie scope
docs/runbooks/hosting.md,docs/runbooks/edge.md— operational runbooks