d118fdbddf
feat(server): v2 RPC handler dispatch for all 33 methods
...
Add v2_handlers module with ServerState, build_registry(), require_auth()
helper, and 33 protobuf handlers across 10 files:
- auth: 4 OPAQUE handlers (register start/finish, login start/finish)
- delivery: 6 handlers (enqueue, fetch, fetch_wait, peek, ack, batch)
- keys: 5 handlers (upload/fetch key package, upload/fetch hybrid key/keys)
- channel: create_channel
- user: resolve_user, resolve_identity
- blob: upload_blob, download_blob
- device: register, list, revoke
- p2p: publish_endpoint, resolve_endpoint, health
- federation: 6 stubs (Unimplemented)
- account: delete_account
All handlers decode protobuf, call domain services, encode response.
Auth handlers use full OPAQUE flow with session creation.
Delivery handlers include rate limiting and long-poll (fetch_wait).
2026-03-04 12:10:33 +01:00
6273ab668d
feat(server): connection pool, session persistence, blob storage in SqlStore
...
- Replace Mutex<Connection> with Vec<Mutex<Connection>> pool (default 4)
with try_lock fast-path and blocking fallback
- Add SessionRecord struct and session CRUD to Store trait (default no-ops)
- Implement session persistence in SqlStore (sessions table, migration 009)
- Add blob upload/download with SHA-256 verified staging assembly
(blobs + blob_staging tables, migration 010)
- All 35 server tests pass, FileBackedStore unaffected
2026-03-04 12:09:03 +01:00
f09dbe10ce
feat(rpc): auth handshake, server-push broker, audit logging
...
- auth_handshake.rs: connection-init protocol (magic 0x01, token, ack)
- push.rs: PushBroker manages per-identity push connections with gc
- server.rs: ConnectionState, auth handshake on first bi-stream, pass
identity_key/session_token to RequestContext per stream
- client.rs: session_token in RpcClientConfig, auto auth handshake on connect
- middleware.rs: log_rpc_call with SHA-256 redaction, hex_prefix helper
- lib.rs: export auth_handshake and push modules
2026-03-04 12:08:20 +01:00
ff93275dc1
feat(server): complete domain service modules (keys, channels, users, blobs, devices, p2p, account)
2026-03-04 12:07:00 +01:00
a5864127d1
feat: v2 Phase 1 — foundation, proto schemas, RPC framework, SDK skeleton
...
New workspace structure with 9 crates. Adds:
- proto/qpq/v1/*.proto: 11 protobuf schemas covering all 33 RPC methods
- quicproquo-proto: dual codegen (capnp legacy + prost v2)
- quicproquo-rpc: QUIC RPC framework (framing, server, client, middleware)
- quicproquo-sdk: client SDK (QpqClient, events, conversation store)
- quicproquo-server/domain/: protocol-agnostic domain types and services
- justfile: build commands
Wire format: [method_id:u16][req_id:u32][len:u32][protobuf] per QUIC stream.
All 151 existing tests pass. Backward compatible with v1 capnp code.
2026-03-04 12:02:07 +01:00
394199b19b
fix: security hardening — 40 findings from full codebase review
...
Full codebase review by 4 independent agents (security, architecture,
code quality, correctness) identified ~80 findings. This commit fixes 40
of them across all workspace crates.
Critical fixes:
- Federation service: validate origin against mTLS cert CN/SAN (C1)
- WS bridge: add DM channel auth, size limits, rate limiting (C2)
- hpke_seal: panic on error instead of silent empty ciphertext (C3)
- hpke_setup_sender_and_export: error on parse fail, no PQ downgrade (C7)
Security fixes:
- Zeroize: seed_bytes() returns Zeroizing<[u8;32]>, private_to_bytes()
returns Zeroizing<Vec<u8>>, ClientAuth.access_token, SessionState.password,
conversation hex_key all wrapped in Zeroizing
- Keystore: 0o600 file permissions on Unix
- MeshIdentity: 0o600 file permissions on Unix
- Timing floors: resolveIdentity + WS bridge resolve_user get 5ms floor
- Mobile: TLS verification gated behind insecure-dev feature flag
- Proto: from_bytes default limit tightened from 64 MiB to 8 MiB
Correctness fixes:
- fetch_wait: register waiter before fetch to close TOCTOU window
- MeshEnvelope: exclude hop_count from signature (forwarding no longer
invalidates sender signature)
- BroadcastChannel: encrypt returns Result instead of panicking
- transcript: rename verify_transcript_chain → validate_transcript_structure
- group.rs: extract shared process_incoming() for receive_message variants
- auth_ops: remove spurious RegistrationRequest deserialization
- MeshStore.seen: bounded to 100K with FIFO eviction
Quality fixes:
- FFI error classification: typed downcast instead of string matching
- Plugin HookVTable: SAFETY documentation for unsafe Send+Sync
- clippy::unwrap_used: warn → deny workspace-wide
- Various .unwrap_or("") → proper error returns
Review report: docs/REVIEW-2026-03-04.md
152 tests passing (72 core + 35 server + 14 E2E + 1 doctest + 30 P2P)
2026-03-04 07:52:12 +01:00
4694a3098b
docs: comprehensive update for sprints 1-9
...
Update README, ROADMAP, and mdBook to reflect all sprint deliverables:
rich messaging, file transfer, disappearing messages, Go/TypeScript SDKs,
C FFI, mesh networking (identity, store-and-forward, broadcast), and
security hardening. Add 6 new mdBook guides (REPL reference, Go SDK,
TypeScript SDK + browser demo, rich messaging, file transfer, mesh
networking). Check off 16 completed ROADMAP items across phases 3-9.
2026-03-04 02:10:20 +01:00
4454458e38
docs: expand sprint candidates to 24 features (A-X)
...
Added 12 more feature candidates: M) message threading, N) cross-signing,
O) offline queue priorities, P) audit log/compliance, Q) bot framework,
R) Tor/I2P transport, S) plugin marketplace, T) stress testing,
U) view-once media, V) emoji presence, W) rich text, X) invite links.
Updated selection guide with 6 priority tracks.
2026-03-04 02:07:28 +01:00
5a6d9ae7f4
docs: next sprint planning — 12 feature candidates for selection
...
Sprint plan for cycles 12-19. Pick 8 of 12 features:
A) Federation wiring, B) Contacts/blocking, C) Voice/video signaling,
D) Encrypted backup, E) Group roles, F) KT audit client, G) Message
search, H) Server clustering, I) Protocol compliance, J) User profiles,
K) Notification framework, L) Mobile app shell.
2026-03-04 02:02:01 +01:00
9244e80ec7
feat: Sprint 10+11 — privacy hardening and multi-device support
...
Privacy Hardening (Sprint 10):
- Server --redact-logs flag: SHA-256 hashed identity prefixes in audit
logs, payload_len omitted when enabled
- Client /privacy command suite: redact-keys on|off, auto-clear with
duration parsing, padding on|off for traffic analysis resistance
- Forward secrecy: /verify-fs checks MLS epoch advancement,
/rotate-all-keys rotates MLS leaf + hybrid KEM keypair
- Dummy message type (0x09): constant-rate traffic padding every 30s,
silently discarded by recipients, serialize_dummy() + parse support
- delete_messages_before() for auto-clear in ConversationStore
Multi-Device Support (Sprint 11):
- Device registry: registerDevice @24, listDevices @25, revokeDevice @26
RPCs with Device struct (deviceId, deviceName, registeredAt)
- Server storage: devices table (migration 008), max 5 per identity,
E029_DEVICE_LIMIT and E030_DEVICE_NOT_FOUND error codes
- Device cleanup integrated into deleteAccount transaction
- Client REPL: /devices, /register-device <name>, /revoke-device <id>
72 core + 35 server tests pass.
2026-03-04 01:55:23 +01:00
1b61b7ee8f
feat: Sprint 9 — mesh identity, store-and-forward, broadcast channels
...
Self-sovereign mesh networking for offline-capable Freifunk deployments.
- MeshIdentity: Ed25519 keypair-based identity without AS registration,
JSON-persisted seed + known peers directory, sign/verify
- MeshEnvelope: signed store-and-forward envelope with TTL, hop_count,
max_hops, SHA-256 dedup ID, Ed25519 signature verification
- MeshStore: in-memory message queue with dedup, per-recipient capacity
limits, TTL-based garbage collection
- BroadcastChannel: symmetric ChaCha20-Poly1305 encrypted topic-based
pub/sub for mesh announcements, no MLS overhead
- BroadcastManager: subscribe/unsubscribe/create channels by topic
- P2pNode integration: send_mesh(), receive_mesh(), forward_stored(),
subscribe(), create_broadcast(), broadcast()
- Extended mesh REPL: /mesh send, /mesh broadcast, /mesh subscribe,
/mesh route, /mesh identity, /mesh store (feature-gated)
28 P2P tests pass (21 existing + 7 broadcast). All builds clean.
2026-03-04 01:42:09 +01:00
28ceaaf072
feat: Sprint 8 — TypeScript SDK with WASM crypto and browser demo
...
- WASM crypto bundle (175KB): 13 wasm_bindgen functions wrapping
quicproquo-core's Ed25519 identity, X25519+ML-KEM-768 hybrid KEM,
safety numbers, sealed sender, and message padding
- @quicproquo/client TypeScript SDK: QpqClient class with connect,
health, resolveUser, createChannel, send/sendWithTTL, receive,
deleteAccount; WebSocket transport with request/response correlation
and reconnection; ergonomic crypto.ts wrapper over WASM functions
- Browser demo: vanilla HTML page with interactive crypto operations
(identity gen, safety numbers, sign/verify, hybrid encrypt/decrypt,
sealed sender, padding) and chat UI for server connectivity
- Offline mode: crypto operations work without server connection
TypeScript strict mode, 0 errors. WASM bundle size optimized (lto + opt-level=s).
2026-03-04 01:28:38 +01:00
65ff26235e
feat: Sprint 7 — Go SDK with QUIC transport and Cap'n Proto RPC
...
First non-Rust client SDK for quicproquo ecosystem.
- Cap'n Proto codegen: generated 6487-line Go types from node.capnp
with all 24 RPC methods (NodeService, Auth, Envelope)
- QUIC transport: quic-go + TLS 1.3, ALPN "capnp", single bidi stream,
300s idle timeout, InsecureSkipVerify for dev, custom CA cert support
- High-level qpq package: Connect, Health, ResolveUser, CreateChannel,
Send/SendWithTTL, Receive/ReceiveWait, DeleteAccount, OPAQUE wrappers
- Auth management: session token storage, version/token/deviceID on all RPCs
- Example program and README with API reference
All tests pass: go test ./..., go vet, go build
2026-03-04 01:03:02 +01:00
fd21ea625c
feat: Sprint 6 — disappearing messages, group info, account deletion
...
- Disappearing messages: ttlSecs param on enqueue/batchEnqueue RPCs,
expires_at column (migration 007), server GC deletes expired messages,
/disappear command with human-friendly duration parsing (30m, 1h, 1d)
- Group info: /group-info shows type, members, MLS epoch; /rename
renames conversations; /members resolves usernames via resolveIdentity
- Account deletion: deleteAccount @23 RPC with transactional purge of
all user data (deliveries, keys, channels), session invalidation,
KT log preserved for auditability; /delete-account with confirmation
- Added epoch() accessor to GroupMember, enqueue_with_ttl client helper
All 35 server + 71 core + 14 E2E tests pass.
2026-03-04 00:39:05 +01:00
3350d765e5
feat: Sprint 5 — encrypted file transfer with chunked upload/download
...
- Add uploadBlob (@21) and downloadBlob (@22) RPCs to Cap'n Proto
schema with SHA-256 content addressing and chunked transfer
- Server blob handler: 256KB chunks, SHA-256 verification on finalize,
.meta JSON sidecar, 50MB size limit, content-addressable storage
- Add FileRef (0x08) AppMessage variant with blob_id, filename,
file_size, mime_type
- /send-file command: read file, compute hash, upload in chunks with
progress display, send FileRef via MLS, MIME auto-detection
- /download command: fetch blob in chunks with progress, verify hash,
save to disk with collision avoidance
- 2 new E2E tests: upload/download round-trip with partial reads,
hash mismatch rejection (14 E2E tests total)
- New error codes: E024-E027 for blob operations
2026-03-04 00:27:18 +01:00
81d5e2e590
feat: Sprint 4 — rich messaging: receipts, typing, reactions, edit/delete
...
- Auto-send read receipts on Chat/Reply receive, display "✓ read"
notification (loop-safe: only Chat/Reply trigger receipts)
- Typing indicators with /typing command, 10s timeout expiry,
/typing-notify toggle, ephemeral (not stored in DB)
- /react <emoji> [index] command for message reactions, display
inline with sender name
- Add Edit (0x06) and Delete (0x07) AppMessage variants with
serialize/parse, /edit and /delete REPL commands (own messages
only), incoming edit/delete handling with DB updates
- 3 new roundtrip tests for Edit/Delete serialization (70 core tests)
2026-03-04 00:12:06 +01:00
db46b72f58
feat: Sprint 3 — C FFI bindings, WASM compilation, Python example, SDK docs
...
- Create quicproquo-ffi crate with 7 extern "C" functions: connect,
login, send, receive, disconnect, last_error, free_string
(produces libquicproquo_ffi.so and .a)
- Feature-gate quicproquo-core for WASM: identity, hybrid_kem,
safety_numbers, sealed_sender, app_message, padding, transcript
all compile to wasm32-unknown-unknown
- Add Python ctypes example (examples/python/qpq_client.py) with
QpqClient wrapper class and CLI
- Add SDK documentation: FFI reference, WASM guide, qpq-gen generators
- Update Dockerfile for quicproquo-ffi workspace member
2026-03-03 23:47:40 +01:00
9ab306d891
feat: Sprint 2 — security hardening, MLS key rotation, E2E tests
...
- DS sender identity binding (Phase 4.3): explicit audit logging of
sender_prefix in enqueue/batch_enqueue, documenting that sender
identity is always derived from authenticated session
- Username enumeration mitigation (Phase 4.5): 5ms timing floor on
resolveUser responses + rate limiting to prevent bulk enumeration
- Add /update-key REPL command for MLS leaf key rotation via
propose_self_update + auto-commit + fan-out to group members
- Add 4 new E2E tests: message delivery round-trip, key rotation
update path, oversized payload rejection, multi-party group (12 total)
2026-03-03 23:37:24 +01:00
612b06aa8e
feat: Sprint 1 — production hardening, TLS lifecycle, CI coverage, lint cleanup
...
- Fix 3 client panics: replace .unwrap()/.expect() with proper error
handling in rpc.rs (AUTH_CONTEXT lock), repl.rs (pending_member),
and retry.rs (last_err)
- Add --danger-accept-invalid-certs flag with InsecureServerCertVerifier
for development TLS bypass, plus mdBook TLS documentation
- Add CI coverage job (cargo-tarpaulin) and Docker build validation
to GitHub Actions workflow, plus README CI badge
- Add [workspace.lints] config, fix 46 clippy warnings across 8 crates,
zero warnings on all buildable crates
- Update Dockerfile for all 11 workspace members
2026-03-03 23:19:11 +01:00
dc4e4e49a0
feat: Phase 9 — developer experience, extensibility, and community growth
...
New crates:
- quicproquo-bot: Bot SDK with polling API + JSON pipe mode
- quicproquo-kt: Key Transparency Merkle log (RFC 9162 subset)
- quicproquo-plugin-api: no_std C-compatible plugin vtable API
- quicproquo-gen: scaffolding tool (qpq-gen plugin/bot/rpc/hook)
Server features:
- ServerHooks trait wired into all RPC handlers (enqueue, fetch, auth,
channel, registration) with plugin rejection support
- Dynamic plugin loader (libloading) with --plugin-dir config
- Delivery proof canary tokens (Ed25519 server signatures on enqueue)
- Key Transparency Merkle log with inclusion proofs on resolveUser
Core library:
- Safety numbers (60-digit HMAC-SHA256 key verification codes)
- Verifiable transcript archive (CBOR + ChaCha20-Poly1305 + hash chain)
- Delivery proof verification utility
- Criterion benchmarks (hybrid KEM, MLS, identity, sealed sender, padding)
Client:
- /verify REPL command for out-of-band key verification
- Full-screen TUI via Ratatui (feature-gated --features tui)
- qpq export / qpq export-verify CLI subcommands
- KT inclusion proof verification on user resolution
Also: ROADMAP Phase 9 added, bot SDK docs, server hooks docs,
crate-responsibilities updated, example plugins (rate_limit, logging).
2026-03-03 22:47:38 +01:00
b6483dedbc
chore: ROADMAP Phase 8, parallel AI team script, docker and infra updates
...
- ROADMAP.md: add Phase 8 — Freifunk / Community Mesh Networking with
F0-F8 checkboxes; F0-F2 marked complete
- scripts/ai_team.py: rewrite to support asyncio.gather parallel agent
runs; add --sprint flag with predefined work packages (audit,
phase1-hardening, phase2-tests, phase1-infra, status); add --parallel
for ad-hoc concurrent agent invocations; output written to
logs/ai_team/<sprint>_<timestamp>/<agent>.md
- scripts/dev-shell.sh: convenience development shell helper
- docker: update Dockerfiles for quicproquo rename and new server flags
- .gitignore: add qpq-state artifacts (*.bin, *.session, *.pending.ks,
*.convdb*)
2026-03-03 14:42:21 +01:00
d7e530435f
fix: auto-derive state file path from --username
...
qpq --username alice now automatically uses qpq-alice.bin instead of the
shared qpq-state.bin default, preventing identity collisions in multi-user
local test setups without requiring an explicit --state flag.
2026-03-03 14:42:11 +01:00
c8398d6cb7
feat: DM epoch fix, federation relay, and mDNS mesh discovery
...
- schema: createChannel returns wasNew :Bool to elect the MLS initiator
unambiguously; prevents duplicate group creation on concurrent /dm calls
- core: group helpers for epoch tracking and key-package lifecycle
- server: federation subsystem — mTLS QUIC server-to-server relay with
Cap'n Proto RPC; enqueue/batchEnqueue relay unknown recipients to their
home domain via FederationClient
- server: mDNS _quicproquo._udp.local. service announcement on startup
- server: storage + sql_store — identity_exists, peek/ack, federation
home-server lookup helpers
- client: /mesh peers REPL command (mDNS discovery, feature = "mesh")
- client: MeshDiscovery — background mDNS browse with ServiceDaemon
- client: was_new=false path in cmd_dm waits for peer Welcome instead of
creating a duplicate initiator group
- p2p: fix ALPN from quicnprotochat/p2p/1 → quicproquo/p2p/1
- workspace: re-include quicproquo-p2p in members
2026-03-03 14:41:56 +01:00
e24497bf90
feat: auto-start local server from REPL
...
When no server is reachable, the REPL now automatically spawns a
qpq-server child process with dev defaults (--allow-insecure-auth,
matching TLS cert paths). The server is killed on REPL exit via a
Drop guard. Use --no-server to opt out (e.g. for remote servers).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com >
2026-03-01 23:03:31 +01:00
c2762f93f6
chore: fix compiler warnings in quicproquo-core
...
Remove unused LeafNodeIndex import and dead StoreCrypto struct.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com >
2026-03-01 22:19:30 +01:00
5b9df61194
feat: make repl the default subcommand
...
Running `qpq --username alice --password secretA` now launches the
REPL directly instead of requiring `qpq repl ...`. The explicit
`repl` subcommand still works for backwards compatibility.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com >
2026-03-01 22:06:57 +01:00
9525a3c565
docs: add project logo to README
...
Move logo.png into assets/ and display it centered at the top of the README.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com >
2026-03-01 21:40:13 +01:00
853ca4fec0
chore: rename project quicnprotochat -> quicproquo (binaries: qpq)
...
Rename the entire workspace:
- Crate packages: quicnprotochat-{core,proto,server,client,gui,p2p,mobile} -> quicproquo-*
- Binary names: quicnprotochat -> qpq, quicnprotochat-server -> qpq-server,
quicnprotochat-gui -> qpq-gui
- Default files: *-state.bin -> qpq-state.bin, *-server.toml -> qpq-server.toml,
*.db -> qpq.db
- Environment variable prefix: QUICNPROTOCHAT_* -> QPQ_*
- App identifier: chat.quicnproto.gui -> chat.quicproquo.gui
- Proto package: quicnprotochat.bench -> quicproquo.bench
- All documentation, Docker, CI, and script references updated
HKDF domain-separation strings and P2P ALPN remain unchanged for
backward compatibility with existing encrypted state and wire protocol.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com >
2026-03-01 20:11:51 +01:00
553de3a2b7
feat: interactive REPL with auto-setup, auto-join, encrypted local storage
...
REPL auto-setup (zero-friction startup):
- OnceLock → RwLock for CLIENT_AUTH to allow delayed init after OPAQUE login
- Extract opaque_register/opaque_login helpers from one-shot commands
- Token cache (.session file) with QPCE encryption when password provided
- Add --username/--password/--state-password to repl subcommand
- resolve_access_token: auto-register + login, cache token, prompt interactively
- rpassword for secure password input (no echo)
Interactive REPL (multi-conversation):
- SessionState: identity, hybrid key, ConversationStore, per-conversation GroupMembers
- ConversationStore: SQLite-backed conversations + messages with full CRUD
- Slash commands: /dm, /group, /invite, /join, /switch, /list, /members, /history, /whoami
- Background polling (1s interval) with auto-join from MLS Welcome messages
- pending_member pattern: persistent keystore for HPKE init key, replenish after join
- Self-DM handled as local-only notepad (no MLS/server channel)
- ANSI display module for colored prompts, incoming messages, status/error output
Username resolution:
- resolveIdentity RPC (@20 in node.capnp): look up username by identity key
- Server: resolve_identity_key in Store trait, FileBackedStore, SqlStore
- Client: resolve_identity in rpc.rs, used in auto-join for peer display names
- resolveUser: bidirectional lookup (username → identity key)
Encrypted local storage (nothing in cleartext):
- ConversationStore uses SQLCipher when --state-password is provided
- Argon2id key derivation with per-database random salt (.convdb-salt, mode 0600)
- Transparent migration of existing unencrypted databases via sqlcipher_export
- Token cache encrypted with QPCE format (Argon2id + ChaCha20Poly1305)
Server changes:
- resolveIdentity + resolveUser RPC handlers with auth + validation
- Auth: sealed-sender identity binding on enqueue, channel member authorization
- Delivery: hybrid decrypt attempts, identity key validation on enqueue
- Config: --allow-sealed-sender flag for anonymous delivery mode
- zeroize added to server dependencies
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com >
2026-02-26 22:45:34 +01:00
4c1e4683e3
chore: exclude p2p crate from workspace, slim tokio features
...
Move quicnprotochat-p2p to workspace.exclude so ~90 iroh-only
dependencies are not compiled in the default build. Narrow tokio
features from "full" to the subset actually used. The p2p crate
now pins its own dependency versions since it is outside the workspace.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com >
2026-02-23 23:10:23 +01:00
750b794342
DM channels (createChannel), channel authz, security/docs, future improvements
...
- Add createChannel RPC (node.capnp @18): create 1:1 channel, returns 16-byte channelId
- Store: create_channel(member_a, member_b), get_channel_members(channel_id)
- FileBackedStore: channels.bin; SqlStore: migration 003_channels, schema v4
- channel_ops: handle_create_channel (auth + identity, peerKey 32 bytes)
- Delivery authz: when channel_id.len() == 16, require caller and recipient are channel members (E022/E023)
- Error codes E022 CHANNEL_ACCESS_DENIED, E023 CHANNEL_NOT_FOUND
- SUMMARY: link Certificate lifecycle; security audit, future improvements, multi-agent plan docs
- Certificate lifecycle doc, SECURITY-AUDIT, FUTURE-IMPROVEMENTS, MULTI-AGENT-WORK-PLAN
- Client/core/tls/auth/server main: assorted fixes and updates from review and audit
Co-authored-by: Cursor <cursoragent@cursor.com >
2026-02-23 22:54:28 +01:00
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
b5b361e2ff
chore: move Python/Ruby/bindings crates to quicnprotochat-lang-clients repo
...
The three crates (quicnprotochat-bindings, quicnprotochat-python,
quicnprotochat-ruby) are developed in a separate feature repository
at git.xorwell.de:c/quicnprotochat-lang-clients.
2026-02-22 18:58:45 +01:00
96f4128b32
fix: remove stale Noise_XX reference and --ds-server flag from README
...
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com >
2026-02-22 12:51:51 +01:00
230205a152
feat: add whoami, health, and check-key CLI subcommands
...
Three new subcommands for M4 CLI groundwork:
- whoami: show local identity key, fingerprint, hybrid key and group status
- health: check server connectivity via health RPC
- check-key: non-consuming lookup of a peer hybrid public key
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com >
2026-02-22 12:50:40 +01:00
00b0aa92a1
feat: add protocol comparison docs, P2P crate, production audit, and design fixes
...
Add comprehensive documentation comparing quicnprotochat against classical
chat protocols (IRC+SSL, XMPP, Telegram) with diagrams and attack scenarios.
Promote comparison pages to top-level sidebar section. Include P2P transport
crate (iroh), production readiness audit, CI workflows, dependency policy,
and continued architecture improvements across all crates.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com >
2026-02-22 12:15:44 +01:00
0bdc222724
fix: address 16 architecture design flaws across all crates
...
Phase 1 — Foundation:
- Constant-time token comparison via subtle::ConstantTimeEq (Fix 11)
- Structured error codes E001–E020 in new error_codes.rs (Fix 15)
- Remove dead envelope.capnp code and related types (Fix 16)
Phase 2 — Auth Hardening:
- Registration collision check via has_user_record() (Fix 5)
- Auth required on uploadHybridKey/fetchHybridKey RPCs (Fix 1)
- Identity-token binding at registration and login (Fix 2)
- Session token expiry with 24h TTL and background reaper (Fix 3)
- Bounded pending logins with 5-minute timeout (Fix 4)
Phase 3 — Resource Limits:
- Rate limiting: 100 enqueues/60s per token (Fix 6)
- Queue depth cap at 1000 + 7-day message TTL/GC (Fix 7)
- Partial queue drain via limit param on fetch/fetchWait (Fix 8)
Phase 4 — Crypto Fixes:
- OPAQUE KSF switched from Identity to Argon2id (Fix 10)
- Random AEAD nonce in hybrid KEM instead of HKDF-derived (Fix 12)
- Zeroize secret fields in HybridKeypairBytes (Fix 13)
- Encrypted client state files via QPCE format (Fix 9)
Phase 5 — Protocol:
- Commit fan-out to all existing members on invite (Fix 14)
- Add member_identities() to GroupMember
Breaking: existing OPAQUE registrations invalidated (Argon2 KSF).
Schema: added auth to hybrid key ops, identityKey to OPAQUE finish
RPCs, limit to fetch/fetchWait.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com >
2026-02-22 10:51:09 +01:00
8d5c1b3b9b
WIP: add OPAQUE password-authenticated key exchange
...
Add opaque-ke (v4, ristretto255) for password-based registration and
login. Extend NodeService schema with opaqueRegisterStart/Finish and
opaqueLoginStart/Finish RPCs. Add Store trait methods for OPAQUE server
setup and user records. Initial e2e integration test scaffolding.
Note: FileBackedStore does not yet implement the new Store trait
methods — server compilation is temporarily broken.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com >
2026-02-22 08:25:34 +01:00
9fdb37876a
Remove Noise protocol references from wiki docs and tests
...
Delete 8 Noise-specific documentation pages (noise-xx.md,
transport-keys.md, adr-001/003/006, framing-codec.md) and update
~30 remaining wiki pages to reflect QUIC+TLS as the sole transport.
Remove obsolete Noise-based integration tests (auth_service.rs,
mls_group.rs). Code-side Noise removal was done in f334ed3 .
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com >
2026-02-22 08:25:23 +01:00
f334ed3d43
feat: add post-quantum hybrid KEM + SQLCipher persistence
...
Feature 1 — Post-Quantum Hybrid KEM (X25519 + ML-KEM-768):
- Create hybrid_kem.rs with keygen, encrypt, decrypt + 11 unit tests
- Wire format: version(1) | x25519_eph_pk(32) | mlkem_ct(1088) | nonce(12) | ct
- Add uploadHybridKey/fetchHybridKey RPCs to node.capnp schema
- Server: hybrid key storage in FileBackedStore + RPC handlers
- Client: hybrid keypair in StoredState, auto-wrap/unwrap in send/recv/invite/join
- demo-group runs full hybrid PQ envelope round-trip
Feature 2 — SQLCipher Persistence:
- Extract Store trait from FileBackedStore API
- Create SqlStore (rusqlite + bundled-sqlcipher) with encrypted-at-rest SQLite
- Schema: key_packages, deliveries, hybrid_keys tables with indexes
- Server CLI: --store-backend=sql, --db-path, --db-key flags
- 5 unit tests for SqlStore (FIFO, round-trip, upsert, channel isolation)
Also includes: client lib.rs refactor, auth config, TOML config file support,
mdBook documentation, and various cleanups by user.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com >
2026-02-22 08:07:48 +01:00
d1ddef4cea
Add channel-aware delivery and update roadmap
2026-02-22 06:31:16 +01:00
9a3fa94858
Remove secret gitea config and ignore file
2026-02-21 23:44:00 +01:00
01b0d8db24
Add gitea-mcp config
2026-02-21 23:43:00 +01:00
3bf3ab23e2
Rename project to quicnprotochat
2026-02-21 23:37:40 +01:00
c9d295c510
docs: add README with protocol stack, architecture, and milestone table
2026-02-19 23:44:04 +01:00
9a0b02a012
feat: M2 + M3 — AuthService, MLS group lifecycle, Delivery Service
...
M2:
- schemas/auth.capnp: AuthenticationService (upload/fetch KeyPackage)
- noiseml-core: IdentityKeypair (Ed25519), generate_key_package, NoiseTransport
with send_envelope/recv_envelope, Noise_XX handshake (initiator + responder)
- noiseml-proto: auth_capnp module, ParsedEnvelope helpers
- noiseml-server: AuthServiceImpl backed by DashMap queue (single-use KPs)
- noiseml-client: register + fetch-key subcommands, ping over Noise_XX
- tests: auth_service integration test (upload → fetch round-trip)
M3:
- schemas/delivery.capnp: DeliveryService (enqueue/fetch opaque payloads)
- noiseml-core/group.rs: GroupMember — MLS group lifecycle
create_group, add_member (→ Commit+Welcome), join_group, send_message,
receive_message; uses openmls 0.5 public API (extract() not into_welcome,
KeyPackageIn::validate() not From<KeyPackageIn>)
- noiseml-server: DeliveryServiceImpl on port 7001 alongside AS on 7000
- noiseml-proto: delivery_capnp module
TODO (see M3_STATUS.md):
- noiseml-client: group subcommands (create-group, invite, join, send, recv)
- noiseml-client/tests/mls_group.rs: full MLS round-trip integration test
2026-02-19 23:39:49 +01:00
9fa3873bd7
feat: M1 — Noise transport, Cap'n Proto framing, Ping/Pong
...
Establishes the foundational transport layer for noiseml:
- Noise_XX_25519_ChaChaPoly_BLAKE2s handshake (initiator + responder)
via `snow`; mutual authentication of static X25519 keys guaranteed
before any application data flows.
- Length-prefixed frame codec (4-byte LE u32, max 65 535 B per Noise
spec) implemented as a Tokio Encoder/Decoder pair.
- Cap'n Proto Envelope schema with MsgType enum (Ping, Pong, and
future MLS message types defined but not yet dispatched).
- Server: TCP listener, one Tokio task per connection, Ping→Pong
handler, fresh X25519 keypair logged at startup.
- Client: `ping` subcommand — handshake, send Ping, receive Pong,
print RTT, exit 0.
- Integration tests: bidirectional Ping/Pong with mutual-auth
verification; server keypair reuse across sequential connections.
- Docker multi-stage build (rust:bookworm → debian:bookworm-slim,
non-root) and docker-compose with TCP healthcheck.
No MLS group state, no AS/DS, no persistence — out of scope for M1.
2026-02-19 21:58:51 +01:00