Rename project to quicnprotochat

This commit is contained in:
2026-02-21 23:37:40 +01:00
parent c9d295c510
commit 3bf3ab23e2
32 changed files with 3370 additions and 1132 deletions

View File

@@ -1,6 +1,6 @@
# M3 Implementation Status
**Last updated:** 2026-02-19
**Last updated:** 2026-02-20
**Branch:** feat/m1-noise-transport (all milestones on this branch so far)
---
@@ -18,13 +18,13 @@ M3 adds:
### `schemas/delivery.capnp` ✅
Simple DS schema: `enqueue(recipientKey, payload)` + `fetch(recipientKey) → List(Data)`.
### `noiseml-proto/build.rs` ✅
### `quicnprotochat-proto/build.rs` ✅
Compiles `delivery.capnp` alongside `envelope.capnp` and `auth.capnp`.
### `noiseml-proto/src/lib.rs` ✅
### `quicnprotochat-proto/src/lib.rs` ✅
Exposes `pub mod delivery_capnp`.
### `noiseml-core/src/group.rs` ✅ (FULLY FIXED, ALL TESTS PASS)
### `quicnprotochat-core/src/group.rs` ✅ (FULLY FIXED, ALL TESTS PASS)
`GroupMember` struct with methods:
- `new(identity: Arc<IdentityKeypair>) -> Self`
- `generate_key_package() -> Result<Vec<u8>, CoreError>` — TLS-encoded KeyPackage bytes
@@ -43,70 +43,27 @@ Exposes `pub mod delivery_capnp`.
- `From<MlsMessageIn> for ProtocolMessage` is also feature-gated
- Must use `OpenMlsCryptoProvider` trait in scope for `backend.crypto()`
### `noiseml-core/src/lib.rs` ✅
### `quicnprotochat-core/src/lib.rs` ✅
Exposes `pub use group::GroupMember`.
### `noiseml-server/src/main.rs` ✅
### `quicnprotochat-server/src/main.rs` ✅
Two listeners on one `LocalSet`:
- Port 7000 (AS): `AuthServiceImpl` — unchanged from M2
- Port 7001 (DS): `DeliveryServiceImpl` — new; uses `DashMap<Vec<u8>, VecDeque<Vec<u8>>>` keyed by Ed25519 public key
New CLI flag: `--ds-listen` (default `0.0.0.0:7001`, env `NOISEML_DS_LISTEN`).
New CLI flag: `--ds-listen` (default `0.0.0.0:7001`, env `QUICNPROTOCHAT_DS_LISTEN`).
### `quicnprotochat-client/src/main.rs` ✅
Added `demo-group` subcommand to exercise the full Alice↔Bob MLS flow against live AS (7000) and DS (7001): uploads both KeyPackages, delivers Welcome via DS, and exchanges application messages.
### `quicnprotochat-client/tests` ✅
`cargo test -p quicnprotochat-client --tests` passes, including the MLS round-trip integration test.
---
## NOT YET DONE (continue tomorrow)
## Notes
### 1. `noiseml-client/src/main.rs` — Group subcommands
Add these subcommands (note: need state persistence or a `demo` command approach):
**Recommended approach:** Add a `demo-group` subcommand that runs the full Alice-Bob MLS round-trip in a single process invocation against a live server. This avoids the `MlsGroup` serialization problem (openmls 0.5 MlsGroup state is hard to persist without the `serde` feature).
**Alternatively (with state file):** Enable `serde` feature on openmls in `Cargo.toml` and store `MlsGroup` state to disk. The workspace Cargo.toml uses `features = ["crypto-subtle"]` for openmls — add `"serde"` to that list.
Subcommands needed:
- `create-group --as-server --ds-server --group-id <NAME>` — creates group, saves state
- `invite --as-server --ds-server --peer-key <HEX>` — fetches peer KP from AS, creates Welcome, enqueues to DS
- `join --ds-server` — fetches Welcome from DS, joins group, saves state
- `send --ds-server --peer-key <HEX> --msg <TEXT>` — sends application message to DS
- `recv --ds-server` — fetches and decrypts messages from DS
OR: just add `demo-group --server --ds-server` that does the whole flow.
### 2. `noiseml-client/tests/mls_group.rs` — Integration test
This is the PRIORITY for testing. The integration test should:
```rust
// 1. Spawn server (AS on port X, DS on port Y) with tokio::process::Command
// or by directly calling the server's accept loop in a LocalSet
// 2. Alice: GroupMember::new, generate_key_package, upload to AS
// 3. Bob: GroupMember::new, generate_key_package, upload to AS
// 4. Alice: create_group, fetch Bob's KP from AS, add_member → (commit, welcome)
// Alice: enqueue welcome for Bob via DS (recipient = bob's identity.public_key_bytes())
// 5. Bob: fetch from DS, join_group(welcome)
// 6. Alice: send_message(b"hello bob"), enqueue to DS
// 7. Bob: fetch from DS, receive_message → assert plaintext == b"hello bob"
// 8. Bob: send_message(b"hello alice"), enqueue to DS
// 9. Alice: fetch from DS, receive_message → assert plaintext == b"hello alice"
```
**Important:** For the integration test, you can bypass the CLI and use `GroupMember` + capnp-rpc client helpers directly.
Connect to DS (port 7001):
```rust
async fn connect_ds(server: &str, keypair: &NoiseKeypair) -> anyhow::Result<delivery_service::Client> {
let stream = TcpStream::connect(server).await?;
let transport = handshake_initiator(stream, keypair).await?;
let (reader, writer) = transport.into_capnp_io();
let network = twoparty::VatNetwork::new(reader.compat(), writer.compat_write(), Side::Client, Default::default());
let mut rpc = RpcSystem::new(Box::new(network), None);
let ds: delivery_service::Client = rpc.bootstrap(Side::Server);
tokio::task::spawn_local(rpc);
Ok(ds)
}
```
Open question (future work): if we need persistent groups instead of ephemeral demo runs, enable openmls `serde` feature and add statefile-backed subcommands (`create-group`, `invite`, `join`, `send`, `recv`). For M3, the demo path is sufficient.
---
@@ -141,13 +98,13 @@ test group::tests::group_id_lifecycle ... ok
```bash
cd /home/c/projects/poc-mes
git log --oneline -5 # see where we are
cargo test -p noiseml-core # verify green
cargo test -p quicnprotochat-core # verify green
```
Then:
1. Write `crates/noiseml-client/tests/mls_group.rs` (integration test) — highest priority
2. Add group subcommands to `crates/noiseml-client/src/main.rs`
1. Write `crates/quicnprotochat-client/tests/mls_group.rs` (integration test) — highest priority
2. Add group subcommands to `crates/quicnprotochat-client/src/main.rs`
The integration test is the most important piece — it proves the full M3 stack works end-to-end.
For the test, see the pattern in `crates/noiseml-client/tests/auth_service.rs` (M2 test) for how to spin up the server and connect clients.
For the test, see the pattern in `crates/quicnprotochat-client/tests/auth_service.rs` (M2 test) for how to spin up the server and connect clients.