Rename all project references from quicproquo/qpq to quicprochat/qpc across documentation, Docker configuration, CI workflows, packaging scripts, operational configs, and build tooling. - Docker: crate paths, binary names, user/group, data dirs, env vars - CI: workflow crate references, binary names, artifact names - Docs: all markdown files under docs/, SDK READMEs, book.toml - Packaging: OpenWrt Makefile, init script, UCI config (file renames) - Scripts: justfile, dev-shell, screenshot, cross-compile, ai_team - Operations: Prometheus config, alert rules, Grafana dashboard - Config: .env.example (QPQ_* → QPC_*), CODEOWNERS paths - Top-level: README, CONTRIBUTING, ROADMAP, CLAUDE.md
4.6 KiB
ADR-006: SDK-First Adoption — Native QUIC + Cap'n Proto, No REST Gateway
Status
Accepted (supersedes earlier REST gateway proposal)
Context
quicprochat uses QUIC + Cap'n Proto RPC as its native protocol. This combination delivers zero-copy serialization, multiplexed streams, and sub-RTT connection establishment — ideal for high-performance clients.
Cap'n Proto has limited language support compared to Protocol Buffers or JSON. Adding an HTTP/JSON REST gateway was considered to lower the barrier to entry. However, this would:
- Contradict the project identity. The name is literally quicnprotochat. An HTTP gateway undermines the protocol-native philosophy.
- Add base64 overhead (~33%) for binary payloads (MLS ciphertext, key packages) that are already optimal in Cap'n Proto's wire format.
- Create a second code path to maintain, test, and secure.
- Lose QUIC transport benefits (0-RTT, multiplexing, congestion control) for clients that use the HTTP path.
Decision
No REST/HTTP gateway. Instead, invest in native QUIC + Cap'n Proto SDKs for every viable language, plus WASM/FFI for the crypto layer.
The .capnp schema files ARE the interface definition — they serve the
same role as an OpenAPI spec, but for the native protocol.
SDK strategy
| Language | QUIC | Cap'n Proto | Approach |
|---|---|---|---|
| Rust | quinn | capnp-rpc | Existing reference client |
| Go | quic-go | go-capnp | Native SDK, high confidence |
| Python | aioquic | pycapnp | Native QUIC, manual RPC framing |
| C/C++ | msquic/ngtcp2 | capnproto | Reference impl, full RPC |
| Browser | WebTransport | WASM bridge | QUIC transport via HTTP/3 |
Browser access via WebTransport
Browsers cannot open raw QUIC connections, but they can use WebTransport — which runs over HTTP/3 (which runs over QUIC). The server adds a WebTransport listener alongside the Cap'n Proto QUIC listener. Cap'n Proto RPC is framed over WebTransport bidirectional streams, identical to the native path.
Browser → WebTransport (HTTP/3 over QUIC) → Cap'n Proto RPC → Server
Native → QUIC → Cap'n Proto RPC → Server
Both paths use QUIC transport. The project name stays honest.
Crypto layer distribution
MLS encryption/decryption must happen client-side. The quicprochat-core
crate is compiled to:
- WASM — for browsers, Node.js, Deno
- C FFI (
libquicprochat) — for Swift, Kotlin, Python, Go (via cgo) - Native Rust — for Rust clients (existing)
Why not REST?
- Protocol purity. One protocol, one code path, one mental model.
- No serialization tax. No base64, no JSON parsing, no HTTP headers.
- QUIC everywhere. WebTransport gives browsers QUIC access without HTTP semantics leaking into the protocol.
- Schema-driven.
.capnpfiles generate type-safe stubs in every supported language — the same developer experience as protobuf/gRPC.
Why not gRPC?
- We already have Cap'n Proto with zero-copy deserialization.
- Adding protobuf would mean three serialization formats in one project.
- Cap'n Proto's time-travel RPC (promise pipelining) is architecturally superior to gRPC's request-response model for chained operations.
gRPC may be reconsidered for server-to-server federation (Phase 7.3).
Consequences
Positive
- Protocol coherence. Every client speaks the same wire format.
- Performance. No translation layer, no base64 overhead, no HTTP framing.
- Identity. The project name accurately describes the protocol stack.
- Security. One code path to audit, not two.
- WebTransport. Browsers get native QUIC with the same RPC interface.
Negative
- Higher SDK effort. Each language needs a QUIC + Cap'n Proto integration, not just an HTTP client.
- Cap'n Proto ecosystem gaps. JavaScript and Swift lack mature Cap'n Proto RPC libraries; these languages rely on WASM bridges.
- WebTransport maturity. Browser support is good (Chrome, Edge, Firefox) but not universal; Safari support is emerging.
Neutral
- SDKs live in separate repositories (e.g.,
quicprochat-go,quicprochat-py) to avoid bloating the core workspace. - The C FFI crate (
quicprochat-ffi) bundles both crypto and transport, so language bindings only need to call C functions.
Related
- ADR-002: Cap'n Proto over MessagePack — why Cap'n Proto was chosen
- ROADMAP Phase 3 — SDK implementation plan
- FUTURE-IMPROVEMENTS § 6.2 — WebTransport research