Every boundary: systems, code, keys, money, trust, environments · content/separation.md
Separation — every boundary in the QALS system
Date: 2026-09-08 · Purpose: a dedicated account of what is separated from what, and why. Separation is the security model, the compliance story, and the engineering discipline in one document.
1. System separation (subsystems)
Each box is independently runnable, independently testable, and talks to the others only through defined interfaces. No box trusts another further than its interface allows.
| # | System | Responsibility | Does NOT do | Interface out |
|---|---|---|---|---|
| 1 | Qalnet (chain) | consensus, DataAnchors, (soon) on-chain credit | no business logic, no secrets beyond validator keys | JSON-RPC :9000, gRPC :19200 |
| 2 | loopd (money rails) | accounts, caps, holds, settle, transfers, receipts | no chat, no jobs, no chain writes | HTTP :8823 + HMAC |
| 3 | qmarket (compute) | provider registry, jobs, stakes, disputes | never holds keys; money only via loopd | HTTP :8824 |
| 4 | provider.py | executes work, attests metrics | never sees buyer funds | HTTP :8850 |
| 5 | qalchat (messaging) | encryption, envelopes, in-chat payments | relay is ciphertext-blind | HTTP :8830 + CLI |
| 6 | qalpipe (accountability) | hash→chain anchoring, verification | never moves money | CLI |
| 7 | wallet-app (Tauri) | UI composition of 2–6 | holds no secrets beyond local identity files; delegates crypto | invokes services |
Kill any one box and the others degrade gracefully (chat without market, market without chat, everything without chain except anchoring).
2. Code separation
- Upstream fork (
qalnet/) — IOTA's Apache-2.0 code, unmodified; we track upstream rebases monthly. - qal overlay (
qalnet/qal/) — all qalarc logic asqal_*Move packages. Our changes NEVER touch upstream files → merge conflicts ≈ zero. - Services (
loopd/ qmarket/ qalpipe/ qalchat/) — zero-dependency Python, separate repos-worth of logic kept small and testable. - Reference only (
repos/) — 16 cloned upstream repos for study; never built, never executed (supply-chain firewall). - Generated artifacts (
wiki/ dist/) — always regenerable fromscripts/build_docs.py; never hand-edited. - Creation code (
scripts/,agents/specs/,brand/scripts/) — every generated asset has its generator preserved.
3. Key & identity separation
| Key class | Where it lives | Blast radius if stolen |
|---|---|---|
| Validator/consensus keys | qalnet/devnet keystore (dev: plaintext /tmp-style; prod: Stronghold, 0700) | one validator's vote (needs >⅓ to halt, >⅔ to forge) |
| loopd agent secrets | loopd/data/keys.json (HMAC) | that agent's daily cap |
| qalchat identities | qalchat/data/identities/*.json (X25519+ed25519, 0600) | that handle's conversations + its chat-payment agent |
| Wallet app | no keys of its own — delegates to the above | none beyond the services' |
| Reserve oracle keys | (design) 3-of-5 multisig, machines + external | false attestations only — provably false on redemption |
No master key exists anywhere. No seed phrase yet — that's the honest gap: identity files are the current recovery unit; BIP-39-style seeds + login layer are the next build phase (documented in wallet strategy).
4. Money separation (the layered value stack)
AUD (bank/PSP) ← exists today only as design + paper demo
└─ Reserve (segregated) ← Phase 2, partner-held
└─ B-QALS ledger ← today: loopd paper cents (1 cent = 0.01 B-QALS)
├─ agent caps (chain/loopd-enforced)
├─ holds/escrow (petrol-card)
└─ transfers (loopd /transfer — tested)
G-QALS ← allocation design only, not minted
Devnet gas coins ← test-only IOTA-denominated gas; NOT QALS
Nothing in any running service is real money. The separation between "paper phase" and "value phase" is itself a hard gate: publishing qal_credit on-chain + reserve + legal sign-off must ALL complete before a single real cent enters.
5. Trust separation (who trusts whom for what)
- Buyer trusts: the hold mechanics (not the provider's honesty)
- Provider trusts: the escrow + dispute/slash rules (not the buyer's promise to pay)
- Both trust: the chain's tamper-evidence (not each other's logs)
- Apps trust: the gateway interfaces (not each other's databases)
- qalarc retains: validator operation + reserve custody (by design, private phase) — externalised later via public-IOTA anchoring + open validator set + audits
- Remaining centralized trust points (tracked): gateway-as-verifier in disputes (fix: second-provider sampling), TOFU key exchange in chat (fix: QR invites → on-chain DIDs)
6. Environment separation
| Env | What | Value at risk |
|---|---|---|
qalnet-dev-1 (now) |
single validator, in-memory swarm, custom ports | zero (test gas only) |
| Fleet devnet (Phase 1) | 4 validators across machines + cloud | zero-to-small |
| Doofnet public testnet | faucet, public RPC | zero, reputation only |
| Qalnet main (Phase 2+) | licensed gates passed | real — full security stack applies |
Config separation is literal: qalnet/devnet/genesis.toml ≠ future mainnet config; devnet secrets never migrate.
7. Data separation
- On-chain: hashes, anchors, receipts, (soon) credit objects — public-within-network, tamper-evident
- Off-chain: payloads (MinIO/Tailscale), chat ciphertext only at the relay, plaintext never leaves the two endpoints
- Local runtime: ledgers/receipts JSONL per service (loopd ≠ qmarket ≠ qalchat stores)
- Deployed public site: documentation only — no keys, no runtime data, no customer data ever (wiki is static markdown)
8. Documentation separation (the reading map)
| Audience | Set | Where |
|---|---|---|
| Everyone | Layperson guide, FAQ, explorer | wiki Start + interactive |
| Business | Business review, money & uses, conclusions | wiki + PDFs |
| Engineers | Architecture, separation (this), structure, runbooks, impl plan | wiki + repo |
| Security | Threat model, backing design | wiki |
| Legal/finance | Bank/exchange, token supply, reserve design | wiki + PDFs |
Each set is self-contained; no audience needs to read another's.