Four domains. One pod. Your machine.

Mazemaker runs across four URLs but lives on one host: yours. The hosted domains are renderers and registries; the data plane is loopback. Memory content never crosses the network. The hosted backend knows your license, your fingerprint, your billing — never a single byte of what you remember. This page is the map.

The four domains.

Each domain has exactly one job. None of them duplicates the other. Three live on Cloudflare (static or tunnel-fronted); one lives in your kernel.

Domain Role Runs on Can see memory content?
mazemaker.online Marketing site, install bootstrap, install.sh download Cloudflare Pages (static) No — never receives a request after page load.
mazemaker.dev Dev console: passkey login, mzm-* API keys, billing, license rotation, fingerprint registry Cloudflare Pages → api.mazemaker.dev No — only operates on key metadata, never recall payloads.
api.mazemaker.dev Hosted backend: license issuance, onboard handoff, quota counter, Stripe webhooks Hetzner via Cloudflare Tunnel (no public ingress) No — never receives memory content; only fingerprint + license events.
architect.mazemaker.dev The 12-monitor cockpit SPA, rendered in your browser, talking to your local pod Cloudflare Pages (static) → 127.0.0.1:8765 No — SPA fetches loopback-only; the origin only serves static assets.
127.0.0.1
(your pod)
The actual engine: pgvector, wonderland, embedding-worker, dream-worker, MCP, optional Hermes bridge Your kernel, Quadlet units under systemd --user Yes — this is the only place memory exists.

The split is the architecture. None of the hosted domains has the credentials, the schema, or the network path to read your pod — even if they wanted to. Pulling memory out of your machine requires a privileged process on your machine — same as any other Postgres on your local, cloud, or dedicated hardware.

Where every request actually goes.

Five concrete examples. The pattern is consistent: anything that touches memory content stays on loopback; anything that touches your license or billing crosses to api.mazemaker.dev; nothing crosses both.

// flow 1 — you run install.sh

curl mazemaker.online/install.sh hits Cloudflare Pages (static). The script starts, opens mazemaker.dev/onboard?fp=… in your browser. Browser tab posts to api.mazemaker.dev/api/onboard/install-session. CLI polls the same path; receives a ready flag; calls api.mazemaker.dev/api/license/issue once; writes the JWT to disk. Three crossings, all for license — zero memory content involved.

// flow 2 — Claude Code calls neural_recall

MCP socket on your machine, served by wonderland on 127.0.0.1:8765. wonderland forwards to the engine over a local UDS, engine queries pgvector on 127.0.0.1:5432, returns hits. Result back through wonderland to the MCP client. Zero network crossings. Your license is verified once per pod boot, not per recall.

// flow 3 — you open architect.mazemaker.dev

Cloudflare Pages serves the static SPA bundle. The SPA loads, then stops talking to Cloudflare entirely. Every panel polls 127.0.0.1:8765/stats, 127.0.0.1:8765/graph, 127.0.0.1:8769/hermes/skills/index. CF Pages origin sees the asset fetch, nothing else — because the SPA never POSTs back to it. Hosted UI, local data, zero leakage.

// flow 4 — you rotate your API key on mazemaker.dev

Passkey login on mazemaker.dev, posts to api.mazemaker.dev/api/keys/rotate, receives new mzm-*. Your pod next call hits a 401, fetches its embedded key cache from disk, sees the new key when you paste it into your env. Key metadata flows; recall payloads do not.

// flow 5 — you hit your monthly quota

Pod increments a local counter, periodically reports the counter (only the integer, not the payloads) to api.mazemaker.dev/api/quota/usage. Backend enforces plan limit, returns a soft block on the next recall if exceeded. The number 412 is what crosses — never the content of the 412 recalls.

Data segregation, by layer.

The hard line is not at a firewall, it's at the schema. The hosted backend's database has tables for licenses, fingerprints, plans, billing events — and nothing else. There is no memories table in api.mazemaker.dev's Postgres because there is no path for it to be written to. Your pod's memories, edges, dream_cycles tables exist only on your disk.

Data class Where it lives Who can read it
Memory content (text, embeddings) Your pod's pgvector at 127.0.0.1:5432 You. Anything on your machine with file access.
Knowledge graph edges Your pod's pgvector, edges table You. Anything on your machine with file access.
Dream cycle artefacts (NREM, REM, AFE outputs) Your pod's pgvector, dream_* tables You. Anything on your machine with file access.
Hermes skill index entries Your pod's memories with skill:* labels — unencrypted (public-prefix list) You. Designed for cross-skill recall, not secrecy.
License JWT Disk: ~/.local/share/mazemaker/license.jwt You. The backend issued it but doesn't store a copy beyond an issuance log.
Device fingerprint Disk: ~/.local/share/mazemaker/.fingerprint/ + backend registry (HMAC only, not raw salts) Backend sees the HMAC, never the underlying hardware salts.
API keys (mzm-*) Backend (hashed); pod env or ~/.config/mazemaker/keys.toml (plaintext) on your disk Backend never sees plaintext after issuance.
Quota counter Pod local counter; periodic integer-only report to backend Backend sees the integer, never the recall content.
Billing events Backend Postgres + Stripe You + Anthropic-Stripe-style billing pipeline. No memory data.

Selective encryption: secrecy where you need it, semantics where you don't.

Inside your pod, the wonderland daemon AES-encrypts memory content at the storage boundary by default. The key never leaves your machine. But some memory has to stay semantically searchable in cleartext — like the Hermes skill index, where the whole point is that the embedding fingerprints "what this skill does" and stays recallable by intent.

The compromise is a label-prefix gate. Memories whose labels start with one of the public prefixes skip AES; everything else is encrypted at rest. The list is hard-coded in wonderland/daemon.py and shipped under version control, so you can audit it.

PrefixIntent
skill:Hermes skill descriptors — needs semantic recall.
auto:Auto-generated meta (heuristics, scratch labels).
decision:Operator decisions you want findable across sessions.
bug:Diagnoses tied to symptoms, recallable by symptom phrase.
ops:Phased operational state (migrations, cutovers).
reference:External pointers (dashboards, channels, repos).
invariant:Project-level rules and constraints.
commit:The why behind a commit, indexed by SHA.
project:Project-state facts, ongoing initiatives.
signal:Strong user reactions worth replaying later.
feedback:Operator preferences that should shape future work.
index:Catalog entries pointing at other memory clusters.
public:Explicit opt-out from AES — for content you want shareable.

The default is encrypted. The public-prefix list is a positive opt-in by label — you can't accidentally skip encryption by misspelling, and the prefixes are short, audited, and stable. You can run the engine fully encrypted and lose nothing operational; the public-prefix concept is purely for semantic-recall use cases.

Your pod is yours.

The hardest property to claim convincingly and the easiest one to break. Here's what we did to make sure we can't break it accidentally.

01

No remote-control channel

There is no inbound socket from the backend to your pod. No SSH key installed, no MQTT subscription, no reverse-tunnel. The backend cannot reach your pod even if it wanted to. Quota usage is reported outbound by the pod on its own schedule.

02

No model-shipped logs

The pod's logs (recall queries, errors, dream cycle timings) go to journalctl --user on your machine. Nothing is forwarded. Operator debug bundles are explicit-opt-in via installer/linux/debug.sh; you read the tarball before sending it.

03

Offline-tolerant license

The license JWT is verified against an embedded public key on every pod boot; the pod runs fine without internet for up to 30 days before nudging you to renew. You can air-gap the host indefinitely if you accept the renewal lapse.

04

Source-available pod side

Everything that runs inside your pod is published — engine, wonderland, embedding-worker, dream-worker, MCP, Hermes bridge. AGPLv3 + PolyForm-NC. You audit; you patch; you fork.

Federation. Shipped. On your terms.

The four-domain split is what makes federation tractable: every pod is sovereign, every recall is local, every cross-pod transfer is a deliberate outbound. There is no shared backend tier that holds memory — so a federated network is just pods talking to pods, with the backend as a fingerprint registry. As of 2026-05-20 federation is live. The full federation page covers the protocol, the three topologies, and how it scales to the WWW →

// what federation is

A pod publishes a public-prefix slice (anything labeled public:*, auto:*, decision:*, …) via POST /peer/sync. Other pods that hold the matching Bearer key pull deltas every five minutes. Opt-in on both sides; encryption stays at the wonderland boundary; the backend brokers identity, never content.

// what it is NOT

Not a shared corpus. Not a "Mazemaker Cloud" that ingests memories. Not silent cross-pod indexing. Federation requires an explicit paste of the peer's handshake URL into the Architect's M06 PEERS panel, and visible peer:<peer-id>: label prefixes on every imported memory so you always see which pod a hit came from.

// how it scales

Two pods on Tailscale: same model. Hub-and-spoke across your own machines: same model. Five-operator research team on Cloudflare Tunnels: same model. The wire protocol does not change with N; the rate limit is the operator's willingness to maintain key pairs. A future rendezvous relay at rendezvous.mazemaker.dev will handle the NAT-punching for operators without a reachable mesh — without ever seeing the payload.

// why the architecture survives

Because we never put a "shared memory layer" in the backend in the first place. Federation is additive to the existing split; no phase required moving memory off your machine. The four-domain map you're looking at is the same map that will hold in 2030 — and the federation map is N copies of it.

Four domains.
One pod. Yours.

The map is the architecture. The architecture is the privacy guarantee. The privacy guarantee is the product.