Core concepts · 32 / 42
Architecture
How Northsun is built — the worker, the storage tiers, the validation gate's status, and where the recall path spends its time. Northsun is designed for sub-300ms voice recall.
One worker, one public hostname
All public traffic lands on a single Cloudflare Worker at the public API hostname mcp.northsun.ai. Earlier hostnames are compatibility aliases served by the same Worker with no cutoff. REST v1 routes and the MCP transport (/mcp) answer identically on all of them. A request enters Cloudflare's network at a location near the caller; the Worker is configured with a placement hint for the database's region.
caller / agent / MCP client
│
▼
┌──────────────────────────────────┐
│ Main Worker — mcp.northsun.ai │ live
│ · REST v1 (recall, calls/end, │
│ caller) │
│ · MCP transport at /mcp │
│ · auth (hashed API keys) │
│ · token-bucket rate limiting │
│ · validation gate (Stage 1+2) │ in development
└──────┬─────────┬─────────┬───────┘
│ │ │
Hyperdrive Redis QStash
│ (cache + (async jobs:
▼ ratelimit) enrichment,
Postgres summaries)
(+ pgvector,
RLS, ranges)Storage tiers
| Tier | Technology | Role | Status |
|---|---|---|---|
| HOT | Upstash Redis | Read-through contact cache, token buckets, dispatch claims | live |
| WARM | Supabase Postgres via Cloudflare Hyperdrive | Source of truth: contacts, interactions, memory, audit | live |
| WARM (substrate) | evidence_refs and locked_facts in Postgres | The bi-temporal substrate (see Evidence references and Locked facts) | in source |
| WARM (vector) | pgvector in Postgres | In-Postgres semantic slice for tenant-scale retrieval | in source |
| COLD | Qdrant cluster | Episodic ANN at large scale (payload-filtered, quantized) | target |
Today, memory reads come from Postgres; the Qdrant tier is a target, not serving traffic.
Hyperdrive matters more than it sounds: Workers can't hold long-lived database pools, and Hyperdrive's edge pooling removes the multi-round-trip connection handshake that kills cold serverless queries.
Tenant isolation
Northsun scopes tenant data at two complementary layers. Application queries filter explicitly by tenant, and Postgres row-level security acts as the backstop beneath them: the tables holding customer memory carry policies that match rows only against a tenant identifier set on the connection, so a query that arrives without that context returns nothing rather than everything. The database role serving API traffic holds neither superuser nor BYPASSRLS.
Not every table is tenant-scoped, and the exceptions are deliberate: the tenant and API-key registries must be addressable before a request can be attributed to a tenant, and a shared enrichment cache of third-party lookup results is keyed by phone number. See Security for the full statement of what is and is not enforced.
The bi-temporal substrate
In source, evidence_refs carries generated tstzrange columns (valid_range, tx_range) with GiST indexes, and locked_facts stores valid_range and tx_range as range columns with a GiST exclusion on tx_range; both are designed for as-of reconstruction. Writes are designed to go through supersession-safe procedures (assert_fact, evolve_fact) rather than raw updates. Memory objects are deliberately not bi-temporal (locked decision D3); they're the recall layer the substrate governs.
The gate
The validation gate is a design for a server-owned checkpoint between an agent's proposed action and an external effect. A deterministic Stage-1 evaluator exists in source; the complete gate is in development and is not part of the frozen public contract. Its stages, grader, verdict mapping and retry behavior are design-stage and not public: see Validation gate.
The hot path, end to end
A voice recall has a conversational budget, so everything on the path is parallel, cached, or deferred:
- Auth + rate limit — hashed-key lookup and a Redis token bucket (fails open: if Redis is down, traffic serves rather than blocks).
- Memory — read-through cache first; Postgres (via Hyperdrive) only on a miss.
- Enrichment — Trestle and Twilio Lookup race in parallel against a hard deadline; whatever resolves in budget ships in the response, the rest completes asynchronously via QStash jobs and writes back for next time.
- Write-back —
calls/endcommits the interaction durably before it returns, with a bounded, best-effort write-through to the cache the next recall reads from; a durable queue also receives the event as a retry net for reprocessing.
Every successful recall response carries measured timing_ms; the architecture is judged by real per-request numbers, not published averages.
Where it's heading
The locked direction: the COLD Qdrant tier for large-scale episodic recall, the gate contract graduating to the public API, and retrieval fusion (signal-weighted reranking across tiers) — all spec-locked, all labeled here as they ship.