Sharpen the framing: our project doesn't ship, embed, supervise, or
even sit-next-to NATS. NATS is external infrastructure the operator
provides (their own server, Synadia Cloud, whatever) and we connect
to it the way an app connects to a database.
Changes:
- §4.2 process model: redraw the diagram showing NATS *outside* our
deployment boundary (with a dashed line for "external"), our two
services on one side, chat-server reaches out to the operator's
NATS via the auth callout.
- §4.3 docker-compose sketch: remove the nats container entirely.
Our compose ships chat-server + sig-server only. NATS_URL is an
environment variable the operator sets. We document the nats.conf
snippet the operator needs to add to their own NATS deployment.
- §6.4 NATS broker section rewritten as "external dependency" — what
we require from the operator's NATS (version, JetStream, callout
config), and why we don't bundle it (NATS is its own ops problem;
operators may already have one; we shouldn't lock them in).
- §11 sequenced plan step 3: developers spin up a local NATS for
testing via Appendix A, not "run nats-server in a sibling container."
- Decisions-locked row for NATS now explicit: "We don't ship, embed,
or supervise it. We connect to whatever broker NATS_URL points at."
- New Appendix A: "running a NATS broker locally for development" —
one-liner docker run for testing, with explicit "this is dev only,
not the production deployment recipe."
- §12 one-paragraph summary updated to reflect "our project ships two
services" (chat-server + sig-server), NATS is external.
Sweep through the design doc with all the open questions resolved:
- Microservices: chat-server does NOT bundle sigchain mirror — depends
on the existing kez-sig-server as a separate container.
- NATS: not embedded in the Rust server. nats-server (Go) runs as its
own container; chat-server provides an auth callout endpoint that
nats-server invokes on each client connection.
- No nostr in chat. KEZ is identity-only; nostr only participates as a
verifiable claim in someone's sigchain, not as transport.
- Global handle namespace for v0, federation-ready design (qualified
internal handles, HTTP-based lookups, WebFinger from day one).
- Paper-backup recovery (24-word BIP-39-style mnemonic shown at
account creation, user writes it down, app verifies recall). No
server-side recovery.
- No Iroh pinning in v0. Files transfer pure P2P; if sender is offline,
receiver waits. Chat-server doesn't run an Iroh node at all.
Concrete additions to the document:
- §3.4 Paper-backup recovery flow
- §3.5 Federation-ready design notes (qualified handle storage,
HTTP-based lookups, WebFinger)
- §4.1 Responsibility table now explicitly lists what's NOT in this
server (sigchain, NATS, Iroh, channel verification)
- §4.3 Sketch of docker-compose.yml showing the three-container
microservices layout
- §9 collapsed: only one open question remains (manifest format —
signed blob via sigchain op vs Iroh Doc). Recommended default: A.
- New "Decisions locked" table at the end of §9 summarizing all the
closed questions
- §5.4 file sharing flow notes "both peers online for v0"
- §6.5 explicitly states "chat-server doesn't run an Iroh node"
- §7 MVP scope trimmed (no Iroh pinning checkbox)
- §11 sequenced plan reflects microservices ordering
Ready to attack once the manifest format decision lands.
Pre-implementation planning document for kez-chat — a Keybase-class chat
and file sharing app built on the KEZ stack.
Architecture (no code yet, just the plan):
- Identity: KEZ ed25519 primary keys; handles look like
@username@kez.lat (placeholder default home server).
- Messaging: NATS broker, dumb relay, clients do E2E with
ChaCha20-Poly1305 over X25519-derived keys. nkeys-auth means the
user's KEZ primary key literally IS their NATS credential.
JetStream handles offline delivery.
- File transfer: Iroh peer-to-peer, content-addressed blobs.
On-demand fetch (no folder sync, no surprise downloads).
Shared-files manifest committed via a new sigchain `set_shared_files`
op; per-entry encryption for private shares.
Server: a single Rust binary `kez-chat-server` that bundles the
handle registry, NATS auth callout, optional sigchain mirror, and
optional Iroh pinning. NATS broker and Iroh node run alongside it.
Includes:
- End-to-end flows (account creation, add contact, send message,
share file, browse files)
- Proposed folder restructure: pull kez-core + kez-channels out into
a top-level `rust-lib/` workspace so downstream projects (sig-server,
chat-server, future) can path-depend cleanly without reaching into
each other's crate trees
- MVP scope and explicit out-of-scope list
- 7 open design questions with my recommended defaults
- Sequenced build plan (refactor first → server scaffold → NATS auth
→ CLI client → Iroh → manifest → deploy → GUI)