2d56824834
feat(web): add browser web client with IndexedDB, Service Worker, and PWA
...
Create sdks/web/ with a vanilla TypeScript web client:
- IndexedDB local store for conversations, messages, and identity
- WebSocket transport connecting to the server bridge
- Service Worker with cache-first strategy for offline support
- PWA manifest for installable web app
- Dark-themed responsive UI with sidebar, messages, and input bar
- Connection status badge and MLS epoch indicator in header
- Unread message count badges on conversations
2026-03-04 20:55:05 +01:00
496f83067a
feat(delivery): add server-signed delivery proof on enqueue
...
The server now produces a 96-byte Ed25519-signed delivery proof for
every enqueued message: SHA-256(seq || recipient_key || timestamp_ms)
followed by the server's Ed25519 signature. Clients can verify the
proof using verify_delivery_proof() in quicproquo-core to get
cryptographic evidence the server accepted their message.
2026-03-04 20:54:55 +01:00
1768f85258
feat(kt): add key revocation and Merkle-log audit support
...
Add RevocationLog with domain-separated leaf hashes (0x02 prefix) for
tracking revoked identity keys alongside the KT MerkleLog. Includes:
- RevocationLog with O(1) lookup, serialization, and double-revoke guard
- MerkleLog.append_raw() for pre-computed hashes
- MerkleLog.audit_log(start, end) for paginated log retrieval
- RevokeKey (510), CheckRevocation (511), AuditKeyTransparency (520) RPCs
- Server domain logic + v2 handlers + FileBackedStore/SqlStore persistence
- 4 new revocation tests + all 21 KT tests + 65 server tests passing
2026-03-04 20:53:41 +01:00
f667281831
feat(tui): add MLS epoch indicator, online/offline status, and 9 rendering tests
...
Enhance v2 TUI with connected/mls_epoch state fields, colored connection
indicator in status bar, MLS epoch display, and wildcard match for new
SDK event variants. Add 9 tests using ratatui TestBackend covering
rendering, navigation, scroll bounds, status bar content, and unread
count display. Also fix rand 0.8 compat issue in v2_repl.rs.
2026-03-04 20:52:27 +01:00
372dd67a3b
feat: add OpenWrt cross-compilation and packaging (Phase F7)
...
- packaging/openwrt/: opkg Makefile, procd init script, uci config
- scripts/cross-compile.sh: build for musl targets with size checks
- .github/workflows/openwrt.yml: CI cross-compile + 5 MB size gate
- docs/openwrt.md: installation and configuration guide
- Targets: x86_64-musl, armv7-musleabihf, aarch64-musl
- Uses cargo-zigbuild for Docker-free cross-compilation
2026-03-04 20:52:15 +01:00
49e8e066d7
feat(sdk): add Python SDK with QUIC and FFI transport backends
...
Implements quicproquo-py with two transport backends:
- Async QUIC transport via aioquic with v2 protobuf wire format
- Synchronous Rust FFI transport via CFFI wrapping libquicproquo_ffi
Includes manual protobuf encode/decode (no codegen), full RPC coverage
(auth, delivery, channels, users, keys, health), PyPI-ready packaging,
async echo bot and FFI demo examples, and 15 passing unit tests.
2026-03-04 20:52:02 +01:00
f4621b3425
feat: add traffic analysis resistance (Phase 7.7 + F8)
...
- Core: add pad_uniform/unpad_uniform for configurable boundary padding
and generate_decoy for indistinguishable decoy messages
- Server: add traffic_resistance module with payload padding, timing
jitter, and background decoy traffic generator (feature-gated)
- P2P: add mesh traffic_resistance module with padded envelopes and
mesh decoy injection (feature-gated)
- All gated behind --features traffic-resistance
- 22 new tests across core (8), server (4), and P2P (5)
2026-03-04 20:50:19 +01:00
c401caec60
feat(bench): add safety number & epoch rotation benchmarks, CI workflow
...
Add safety_number benchmark to crypto_benchmarks.rs, epoch rotation
(propose_self_update + commit) benchmark to mls_operations.rs, expand
add_member group sizes to include 100, and add .github/workflows/bench.yml
that runs Criterion benchmarks and uploads HTML reports as artifacts.
2026-03-04 20:49:42 +01:00
885cce0d7d
feat: add multi-node horizontal scaling foundations
...
NotificationBus for cross-node message delivery fan-out:
- NotificationBus trait: publish(topic) + subscribe(topic) -> Notify
- InMemoryNotificationBus: single-node default via tokio::sync::Notify
- Designed for Redis pub/sub or NATS replacement in multi-node deploys
- 3 async tests: publish wakes, timeout without publish, independent topics
Health endpoint enhancements for load balancer awareness:
- HealthResponse proto: add node_id, version, uptime_secs, storage_backend
- ServerState: add node_id, start_time, storage_backend fields
- Health handler returns full node identity for multi-node monitoring
2026-03-04 20:38:59 +01:00
913f6faaf3
feat: add distributed rate limiting with sliding window algorithm
...
- RateLimiter trait with check_rate(key, config) -> RateResult
- InMemoryRateLimiter: DashMap-based sliding window log per key
- RateLimitConfig: configurable max_requests and window duration
- RateResult: allowed/remaining/retry_after_secs for Retry-After headers
- Lazy GC of expired entries (every 60s)
- Thread-safe concurrent access via DashMap
- 5 unit tests: limit enforcement, independent keys, remaining counter, concurrency
2026-03-04 20:35:45 +01:00
e93a38243f
feat: add graceful shutdown with drain timeout and per-RPC timeouts
...
Graceful shutdown (Phase 6.4):
- Listen for SIGTERM + SIGINT via tokio::signal
- Configurable drain timeout (--drain-timeout / QPQ_DRAIN_TIMEOUT, default 30s)
- Health endpoint returns "draining" during shutdown for load balancer awareness
- ServerState carries atomic draining flag
- Add RpcStatus::Unavailable (9) for shutdown-related rejections
Per-RPC timeouts (Phase 6.5):
- Add RpcStatus::DeadlineExceeded (8) for server-side timeouts
- MethodRegistry supports default_timeout and per-method timeout overrides
- RPC dispatch wraps handler invocation with tokio::time::timeout
- RequestContext carries optional deadline (Instant) for handlers
- Health: 5s timeout, blob upload/download: 120s timeout, default: 30s
- Config: --rpc-timeout / QPQ_RPC_TIMEOUT, --storage-timeout / QPQ_STORAGE_TIMEOUT
2026-03-04 20:33:26 +01:00
91c5495ab7
docs: add operational runbook, Grafana dashboard, and production docker-compose
...
Add comprehensive operational documentation:
- docs/operations/backup-restore.md: SQLCipher, file backend, blob backup/restore
- docs/operations/key-rotation.md: auth token, TLS, federation, DB key, OPAQUE rotation
- docs/operations/incident-response.md: playbook for common incidents
- docs/operations/scaling-guide.md: resource sizing, scaling triggers, capacity planning
- docs/operations/monitoring.md: Prometheus metrics, alert rules, log monitoring
- docs/operations/dashboards/qpq-overview.json: Grafana dashboard template
- docs/operations/prometheus.yml + alerts: Prometheus scrape and alert config
- docs/operations/grafana-provisioning/: auto-provisioning for datasources and dashboards
- docker-compose.prod.yml: production stack (server + Prometheus + Grafana)
- .env.example: documented environment variable template
2026-03-04 20:30:57 +01:00
b94248b3b6
feat: implement MLS lifecycle and multi-device support
...
Phase 5.3 (MLS lifecycle):
- Add group.proto with RemoveMember, UpdateGroupMetadata, ListGroupMembers, RotateKeys RPCs
- Add GroupService domain logic with metadata and membership persistence
- Add v2 RPC handlers for all 4 group management endpoints (method IDs 410-413)
- Add SDK functions: remove_member_from_group, leave_group, rotate_group_keys, set_group_metadata, get_group_members
- Add REPL commands: /group remove, /group rename, /group rotate-keys, /group leave
- Add 5 unit tests for GroupService (metadata CRUD, membership add/list/remove)
Phase 5.1 (multi-device):
- Wire device_id through SDK fetch/ack functions (fetch_for_device, ack)
- Add /devices list|add|remove REPL commands with tab completion
- Add clear_failed_outbox to ConversationStore
- Fix missing message_id/device_id fields in SDK proto struct initializers
2026-03-04 20:20:55 +01:00
a90020fe89
fix(e2e): serialize all init_auth tests behind AUTH_LOCK to prevent race
...
Every test that calls init_auth() now holds AUTH_LOCK for its full
duration, preventing the global AUTH_CONTEXT from being overwritten
by concurrent tests. The e2e_auth_failure_wrong_token test additionally
resets auth back to "devtoken" after its assertion. Tests now pass
reliably with default parallelism (no --test-threads 1 required).
2026-03-04 20:20:03 +01:00
fd1accc6dd
feat(sdk): wire device_id through messaging and client APIs
...
Add device_id parameter to fetch, fetch_wait, ack, receive_messages,
and receive_messages_wait SDK functions. QpqClient gains device_id
field with register_device/list_devices/revoke_device convenience
methods. Client REPL passes empty device_id for backwards compat.
2026-03-04 20:19:30 +01:00
799aab68fe
feat(server): wire device_id through delivery proto and v2 handlers
...
Add device_id field to FetchRequest, FetchWaitRequest, PeekRequest,
and AckRequest proto messages. V2 handlers now build composite
queue keys (identity_key + device_id) when device_id is provided,
enabling per-device fetch/ack scoping.
2026-03-04 20:16:41 +01:00
eaca24397b
feat(server): add multi-device delivery fan-out
...
Enqueue now resolves all registered devices for a recipient identity
and fans out the message to each device-scoped queue. Single-device
clients remain backwards compatible (bare identity_key queue).
Also adds FileBackedStore::ephemeral() test helper.
2026-03-04 20:15:26 +01:00
12b19b6931
feat: implement account recovery with encrypted backup bundles
...
Add recovery code generation (8 codes per setup), Argon2id key derivation,
ChaCha20-Poly1305 encrypted bundles, and server-side zero-knowledge storage.
Each code independently recovers the account. Includes core crypto module,
protobuf service (method IDs 750-752), server domain + handlers, SDK methods,
SQL migration, and CLI commands (/recovery setup, /recovery restore).
2026-03-04 20:12:20 +01:00
5b6d8209f0
feat: add abuse prevention and moderation (Phase 5.6)
...
Add server-side moderation service with report submission, user
banning/unbanning, and admin listing endpoints. Add client-side
user blocking with message filtering in ConversationStore.
Server:
- ModerationService domain logic (report, ban, unban, list)
- Storage trait methods + FileBackedStore + SqlStore implementations
- SQL migration 012_moderation.sql (reports + bans tables)
- Error codes E031-E033 for moderation
- Domain types for all moderation request/response pairs
- 10 new tests (6 domain + 4 storage)
SDK:
- blocked_users table in ConversationStore
- block_user, unblock_user, is_blocked, list_blocked methods
- load_recent_messages_filtered excludes blocked senders
- QpqClient moderation convenience methods
- 4 new tests for block/unblock/filter
2026-03-04 20:11:20 +01:00
a1f0dbc514
docs: mark Phases 1, 2, and 4.4 complete in ROADMAP
...
Phase 1 (production hardening): all 5 items done
Phase 2 (test & CI maturity): all 4 items done
Phase 4.4 (PQ-MLS): already implemented — hybrid KEM in OpenMLS provider
2026-03-04 15:28:03 +01:00
5a66c2e954
chore: fix all clippy warnings across workspace
2026-03-04 14:13:58 +01:00
4013b223ff
test(e2e): add auth failure, message ordering, OPAQUE flow, key exhaustion, and rate limit tests
2026-03-04 13:33:21 +01:00
3a42130518
chore(ci): enforce clippy -D warnings, add v2 branch trigger
2026-03-04 13:31:32 +01:00
c8c5f96ecd
chore: uncomment CODEOWNERS entries with crate-specific paths
2026-03-04 13:31:29 +01:00
e5329ee8e5
test: add unit tests for ConversationStore CRUD, outbox, and ConversationId
2026-03-04 13:31:25 +01:00
e3dfc43e2c
test: add unit tests for token cache round-trip and edge cases
2026-03-04 13:31:22 +01:00
7bcfbf175c
test: add unit tests for v2 REPL split_cmd parsing
2026-03-04 13:31:19 +01:00
75f11cb76b
test: add unit tests for retry logic and retriable classifier
2026-03-04 13:31:16 +01:00
a3f67aca45
feat(tls): add certificate expiry validation and self-signed warning
2026-03-04 13:30:46 +01:00
950f477842
fix(docker): sync Dockerfile with v2 workspace, add production env and volume docs
2026-03-04 13:30:20 +01:00
3393514911
fix: tighten production config validation with token length and db path checks
2026-03-04 13:29:50 +01:00
a8ed3c4356
fix: replace unwrap/expect in production paths with fallible alternatives
2026-03-04 13:29:33 +01:00
cab03bd3f7
feat(client): v2 REPL over SDK with categorized help and tab-completion
...
925-line REPL replacing the 3317-line monolith — delegates all crypto,
MLS, and RPC to quicproquo-sdk. 20 commands across 6 categories
(messaging, groups, account, keys, utility, debug), rustyline tab
completion, background event listener, auto-server-launch.
Also adds SDK accessor methods (server_addr_string, config_state_path),
WS bridge register handler, and README table formatting cleanup.
2026-03-04 13:02:54 +01:00
99f9abe9ed
feat(client): ratatui TUI subscribing to SDK events
...
Single-file v2 TUI (v2_tui.rs, ~580 lines) gated behind
cfg(all(feature = "v2", feature = "tui")).
Layout: conversations sidebar, scrollable messages panel,
input bar with cursor editing, status line. Help overlay
on /help. Subscribes to SDK broadcast::Receiver<ClientEvent>
for real-time updates. TerminalGuard ensures terminal restore
on panic. Commands: /login, /register, /logout, /dm, /group,
/quit, /help.
Build: cargo build -p quicproquo-client --features v2,tui
2026-03-04 12:47:15 +01:00
029c701780
feat(client): v2 CLI binary over SDK with simplified commands
...
Add v2_main.rs and v2_commands.rs as thin wrappers over QpqClient from
quicproquo-sdk. Activated via --features v2 (feature-gated so v1 main.rs
remains the default). Includes auto-server-launch, clap-based command
surface (register-user, login, whoami, health, resolve, dm, group,
devices), and ClientConfig-based connection setup. MLS-dependent commands
(send, recv, group create/invite) print stubs pointing to the REPL.
2026-03-04 12:46:42 +01:00
4d62a837a5
feat(sdk): conversation management — DM/group lifecycle, outbox
2026-03-04 12:39:48 +01:00
67983c7a40
feat(sdk): OPAQUE auth module with state persistence
2026-03-04 12:39:33 +01:00
011ff541bb
feat(sdk): messaging pipeline — send/receive with MLS, sealed sender, hybrid KEM
...
Full send pipeline: serialize_chat → MLS encrypt → sealed sender → per-recipient
hybrid wrap → batch/individual enqueue via v2 RPC.
Full receive pipeline: fetch/fetch_wait → sort by seq → hybrid unwrap → MLS decrypt
→ unseal → parse AppMessage. Includes retry loop for multi-epoch batches.
2026-03-04 12:39:15 +01:00
918da0c23d
feat(sdk): key management, user resolution, device management
...
Add three new SDK modules wrapping v2 protobuf RPC calls:
- keys.rs: upload/fetch KeyPackages and hybrid public keys (5 methods)
- users.rs: resolve username <-> identity key (2 methods)
- devices.rs: register/list/revoke devices (3 methods)
2026-03-04 12:37:01 +01:00
6b757f8d65
fix(sdk): add missing session_token field to RpcClientConfig
...
The middleware-dev agent added session_token to RpcClientConfig
but the SDK client initializer was not updated, breaking the build.
2026-03-04 12:31:32 +01:00
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