Files
quicproquo/docs/src/roadmap/milestones.md
Christian Nennemann 6b8b61c6ae feat: add delivery sequence numbers + major server/client refactor
Delivery sequence numbers (MLS epoch ordering fix):
- schemas/node.capnp: add Envelope{seq,data} struct; enqueue returns seq:UInt64;
  fetch/fetchWait return List(Envelope) instead of List(Data)
- storage.rs: Store trait enqueue returns u64; fetch/fetch_limited return
  Vec<(u64, Vec<u8>)>; FileBackedStore gains QueueMapV3 with per-inbox seq
  counters and V2→V3 on-disk migration
- migrations/002_add_seq.sql: seq column, delivery_seq_counters table, index
- sql_store.rs: atomic UPSERT counter via RETURNING, ORDER BY seq, SCHEMA_VERSION→3
- node_service/delivery.rs: builds Envelope list; returns seq from enqueue
- client/rpc.rs: enqueue→u64, fetch_all/fetch_wait→Vec<(u64,Vec<u8>)>
- client/commands.rs: sort-by-seq before MLS processing; retry loop in cmd_recv
  and receive_pending_plaintexts for correct epoch ordering

Server refactor:
- Split monolithic main.rs into node_service/{mod,delivery,auth_ops,key_ops,p2p_ops}
- Add auth.rs (token validation, rate limiting), config.rs, metrics.rs, tls.rs
- Add SQL migrations runner (001_initial.sql, 002_add_seq.sql)
- OPAQUE PAKE login/registration, sealed-sender mode, queue depth limit (1000)

Client refactor:
- Split lib.rs into client/{commands,rpc,state,retry,hex,mod}
- Add cmd_whoami, cmd_health, cmd_check_key, cmd_ping subcommands
- Add cmd_register_user, cmd_login (OPAQUE), cmd_refresh_keypackage
- Hybrid PQ envelope (X25519 + ML-KEM-768) on all send/recv paths
- E2E test suite expanded

Other:
- quicnprotochat-gui: Tauri 2 desktop GUI skeleton (backend + HTML UI)
- quicnprotochat-p2p: iroh-based P2P transport stub
- quicnprotochat-core: app_message, hybrid_crypto modules; GroupMember API updates
- .github/workflows/size-lint.yml: binary size regression check
- docs: protocol comparison, roadmap updates, fully-operational checklist
2026-02-22 20:40:12 +01:00

6.7 KiB

Milestone Tracker

This page tracks the project milestones for quicnprotochat, from initial transport layer through post-quantum cryptography. Each milestone produces production-ready, tested, deployable code -- see Coding Standards for what that means in practice.


Milestone Summary

# Name Status What it adds
M1 QUIC/TLS Transport Complete QUIC + TLS 1.3 endpoint, length-prefixed framing, Ping/Pong
M2 Authentication Service Complete Ed25519 identity, KeyPackage generation, AS upload/fetch
M3 Delivery Service + MLS Groups Complete DS relay, GroupMember create/join/add/send/recv
M4 Group CLI Subcommands Complete Persistent CLI (create-group, invite, join, send, recv), OPAQUE login
M5 Multi-party Groups Complete N > 2 members, Commit fan-out, send --all, epoch sync
M6 Persistence Complete SQLite/SQLCipher, migrations, durable server + client state
M7 Post-quantum Next PQ hybrid for MLS/HPKE (X25519 + ML-KEM-768)

M1 -- QUIC/TLS Transport (Complete)

Goal: Two processes establish a QUIC connection over TLS 1.3 and exchange typed Cap'n Proto frames.

Deliverables:

  • schemas/envelope.capnp: Envelope struct with MsgType enum (Ping/Pong at this stage)
  • quicnprotochat-proto: build.rs invoking capnpc, generated type re-exports, canonical serialisation helpers
  • quicnprotochat-core: Ed25519 identity keypair generation, Cap'n Proto frame codec (Tokio Encoder/Decoder)
  • quicnprotochat-server: QUIC listener with TLS 1.3 (quinn/rustls), Ping to Pong handler, one tokio task per connection
  • quicnprotochat-client: connects over QUIC, sends Ping, receives Pong, exits 0
  • Integration test: server and client in same test binary using tokio::spawn
  • docker-compose.yml running the server

Tests: codec (7 unit tests), keypair (3 unit tests), QUIC transport integration.

Branch: feat/m1-noise-transport


M2 -- Authentication Service (Complete)

Goal: Clients register an Ed25519 identity and publish/fetch MLS KeyPackages via Cap'n Proto RPC.

Deliverables:

  • schemas/auth.capnp: AuthenticationService interface (uploadKeyPackage, fetchKeyPackage)
  • quicnprotochat-core: Ed25519 identity keypair generation, MLS KeyPackage generation via openmls
  • quicnprotochat-server: AS RPC server with DashMap store, atomic consume-on-fetch
  • quicnprotochat-client: register-state and fetch-key CLI subcommands
  • Integration test: Alice uploads KeyPackage, Bob fetches it, fingerprints match

Tests: auth_service.rs integration tests (upload, fetch, consume semantics).


M3 -- Delivery Service + MLS Groups (Complete)

Goal: Alice creates a group and adds Bob via MLS Welcome. Both exchange encrypted application messages through the Delivery Service.

Deliverables:

  • Unified NodeService on port 7000 combining Authentication Service and Delivery Service into a single Cap'n Proto RPC interface
  • GroupMember struct with full MLS lifecycle: create_group, add_member, join_from_welcome, send_message, receive_message
  • DS relay with enqueue, fetch, and fetchWait (long-polling) operations
  • demo-group subcommand exercising the complete Alice/Bob flow in one process
  • Channel-aware delivery: messages routed by (channelId, recipientKey)

Tests: All passing -- codec (5+ tests), keypair (3 tests), group round-trip, group_id lifecycle, MLS integration.

Key design decisions from M3:

  1. OpenMlsRustCrypto backend holds the HPKE init key in memory. The same GroupMember instance that generated the KeyPackage must process the corresponding Welcome. If the process exits in between, the init private key is lost. This is by design for M3; persistence comes at M6.

  2. KeyPackage wire format: raw TLS-encoded bytes. KeyPackages are serialised using tls_serialize_detached() rather than wrapped in MlsMessageOut. This avoids an extra layer of indirection and matches what openmls expects on the receive side via KeyPackageIn::tls_deserialize_exact().

  3. openmls 0.5 API gotchas. Several openmls methods changed signatures between 0.4 and 0.5 (e.g., MlsGroup::new vs MlsGroup::new_with_group_id, BasicCredential::new taking Vec<u8> directly). These differences are documented inline in quicnprotochat-core/src/group.rs.

Branch: feat/m1-noise-transport


M4 -- Group CLI Subcommands (Complete)

Goal: Persistent, composable CLI subcommands for group operations, replacing the monolithic demo-group proof-of-concept.

Deliverables: create-group, invite, join, send, recv, chat; OPAQUE register-user and login; demo-group remains for single-command demo.


M5 -- Multi-party Groups (Complete)

Goal: Support groups with N > 2 members, including Commit fan-out and epoch synchronisation.

Deliverables: Commit fan-out to existing members on invite; send --all; cmd_join processes all queued payloads (Welcome + Commits); three-party E2E passing. Proposal handling (Remove, Update) and Criterion benchmarks are optional follow-ups.


M6 -- Persistence (Complete)

Goal: Server survives restart. Client state persists across sessions.

Deliverables: SQLite/SQLCipher via rusqlite, migrations/ directory and migration runner; client state file and DiskKeyStore (encrypted QPCE optional). See Future Research: SQLCipher for encrypted-at-rest options.


M7 -- Post-quantum (Next)

Goal: Replace the MLS crypto backend with a hybrid X25519 + ML-KEM-768 KEM, providing post-quantum confidentiality for all group key material.

Deliverables:

  • Custom OpenMlsCryptoProvider with hybrid KEM in quicnprotochat-core

  • Hybrid shared secret derivation:

    SharedSecret = HKDF-SHA256(
      ikm  = X25519_ss || ML-KEM-768_ss,
      info = "quicnprotochat-hybrid-v1",
      len  = 32
    )
    
  • All M3/M4/M5 tests pass unchanged with the new ciphersuite

  • Follows the combiner approach from draft-ietf-tls-hybrid-design

The ml-kem crate is already vendored in the workspace. See Hybrid KEM for the detailed design.


Cross-references