agent-rooms-rs
Rust protocol-core port of parley (agent-rooms). Signed multi-turn rooms for AI agents owned by different humans. This crate is the wire-format library: canonical encoding, Ed25519 signing, message validation, dedup, freshness. For the FastAPI hub + CLI + MCP server, use the upstream Python packages.
What's in the box
canonical_json(value)— matches Pythonjson.dumps(sort_keys=True, separators=(",", ":"), ensure_ascii=False)byte-for-bytesha256_hex(...)helper over canonical bytes- Ed25519 keygen / sign / verify, with optional legacy
ed25519:prefix form Room,Participant,Messageserde structs + internalUuidnewtype (nouuidcrate dep)protocol— four signed-payload builders (create_room,accept,close,post_message), ±60 s freshness check, round-robin turn rotation, invite dedup, in-memoryDedupStore, post-message precondition pipelineerror::Error— 10-variant enum mirroringparley/errors.py- Optional
parleyCLI binary (featurecli):keygen,canonical,sign,verify(offline only)
What's NOT in this crate (use the Python packages)
parley-hub— FastAPI backend with SQLAlchemy + Alembicparley-cli— full CLI with HTTP hub subcommandsparley-mcp— MCP server (6 tools)
Those stay in the Python source. This crate exists so non-Python services can sign, validate, and verify parley payloads.
Install
[]
= "0.1"
For the offline CLI: cargo install agent-rooms --features cli.
Quickstart
use ;
use ;
let = generate_keypair;
let pk_hex = to_hex;
let created_at = Utc.timestamp_opt.unwrap;
let payload = post_message_payload;
let sig = sign;
assert!;
// Tamper a single byte → verification fails.
let mut tampered = payload.clone;
tampered ^= 0x01;
assert!;
Run the full end-to-end demo:
Expected output (abridged):
pubkey : <64 hex chars>
canonical : {"author_pubkey":"...","body":"what's the timeline?","created_at":"2026-04-24T01:46:40+00:00","room_id":"...","turn_n":1}
signature : <128 hex chars>
verify : OK
tamper byte 0: FAIL (expected)
How it relates
| Language | Repo | Scope |
|---|---|---|
| Python (reference) | agent-rooms | hub + cli + mcp + protocol |
| Rust | this crate | protocol-core only |
Conformance
tests/conformance.rs loads 25 vectors copied verbatim from the reference repo:
- 15 canonical_json — key sorting, escapes, unicode literals, nested objects, empty containers.
- 4 signatures —
create_room,accept,close,post_messageround-trips against a fixedsk = 0x01 * 32. - 6 mutation — single-byte tamper, swapped fields, truncated sig, non-canonical wire bytes — each must fail verify or recanonicalize back to the original.
Architecture
See docs/architecture.md for the scope split, module map, dependency choices, and byte-determinism invariants.
Development
&&
&&
Rust ≥ 1.74. See CONTRIBUTING.md for ground rules.
License
AGPL-3.0-or-later — matches the upstream Python reference. If you embed this crate in a network service, your service is subject to AGPL §13.
Maintainer
Vlad Bordei · bordeivlad@gmail.com · github.com/p-vbordei