Repository-level map for agents. Read README.md first for the human-facing overview.
This repo owns the Rust implementation workspace for Marmot:
- shared traits and cross-boundary types,
- OpenMLS-backed engine implementation,
- production-shaped account-device session wrapper,
- account orchestration,
- app runtime bridge,
- SQLCipher-backed storage backend,
- Nostr transport adapter and peeler,
- raw QUIC agent text stream preview transport and memory-only broker,
- agent control protocol, stream composition, and the
wn-agentconnector daemon, - app message Markdown display parser,
- shared JSONL forensic audit schema,
- UniFFI bindings for the app runtime,
- C ABI bindings for the app runtime,
- CLI surface, daemon, and TUI,
- conformance simulator and vector fixtures,
- Goggles-incident replay adapter (agent-state export parse + classify),
- Tamarin models for distributed convergence,
- architecture notes and CGKA contracts.
The canonical protocol specification lives in
github.com/marmot-protocol/marmot. Keep implementation architecture and diagnostics in this repo.
| Task | Start here |
|---|---|
| Engine behavior | crates/cgka-engine/AGENTS.md |
| Engine integration tests | crates/cgka-engine/tests/AGENTS.md |
| Account-device session lifecycle | crates/cgka-session/AGENTS.md |
| Account orchestration / app-core shell | crates/marmot-account/AGENTS.md |
| App runtime bridge | crates/marmot-app/AGENTS.md |
| App message Markdown display parsing | crates/marmot-markdown/AGENTS.md |
| Storage traits and shared types | crates/traits/AGENTS.md |
| Private file/dir/socket creation helpers | crates/fs-private/AGENTS.md |
| SQLite storage | crates/storage-sqlite/AGENTS.md |
| Nostr transport adapter | crates/transport-nostr-adapter/AGENTS.md |
| Nostr transport peeler | crates/transport-nostr-peeler/AGENTS.md |
| QUIC agent text stream previews | crates/transport-quic-stream/AGENTS.md |
| QUIC preview broker | crates/transport-quic-broker/AGENTS.md |
| Agent control protocol DTOs / framing | crates/agent-control/AGENTS.md |
| Agent stream composition | crates/agent-stream-compose/AGENTS.md |
wn-agent connector daemon |
crates/agent-connector/AGENTS.md |
| Host integrations / connector coexistence | integrations/AGENTS.md |
| Codex terminal harness | integrations/codex/marmot/AGENTS.md |
| Forensic audit schema | crates/marmot-forensics/AGENTS.md |
| App runtime UniFFI bindings | crates/marmot-uniffi/AGENTS.md |
| App runtime C ABI bindings | crates/marmot-c/AGENTS.md |
| CLI / daemon / TUI surface | crates/cli/AGENTS.md |
| Multi-client harness / vectors | crates/cgka-conformance-simulator/AGENTS.md |
| Container/VM convergence campaigns | crates/convergence-campaign-runner/AGENTS.md |
| Goggles incident replay adapter | crates/incident-replay/AGENTS.md |
| Architecture docs | docs/AGENTS.md and docs/marmot-architecture/AGENTS.md |
| Formal model | formal/tamarin/AGENTS.md |
- Keep the engine generic over
S: cgka_traits::StorageProvider. - Keep transport-specific code out of
crates/cgka-engine,crates/traits, and storage crates. - Keep SQLite persistence one database per Marmot account-device identity.
- Keep Tamarin model names, Rust test names, and vector names easy to grep across layers.
- Keep protocol principles and app-component documents implementation-neutral in
marmot-protocol/marmot. Local engine, storage, queue, and diagnostic notes belong in architecture docs or crate docs here. - Keep MLS group ids distinct from transport routing ids.
GroupIdis opaque MLS group id bytes; OpenMLS-generated ids are 16 bytes today, but spec surfaces that bind raw MLS group ids length-prefix them because they are variable-length.nostr_group_id/transport_group_idis the 32-byte Nostr routing handle. Do not apply the 32-byte Nostr route-id rule toGroupIdvalidation, FFI parsing, storage lookups, or CLI/app group-id filters. - Keep tracing/logging privacy-safe: explicit crate/module
targetandmethodfields, aggregate values only, and no account ids, group ids, message ids, relay URLs, pubkeys, payloads, ciphertext, plaintext, or key material. Seedocs/marmot-architecture/overview/observability.md. - Create local files, sockets, and databases restrictive-by-construction via
crates/fs-private(or equivalent posture with an on-disk mode test), and release their file locks explicitly before a host suspends (MarmotAppRuntime::shutdown_and_close); seedocs/marmot-architecture/overview/local-artifact-safety.md. - Route every outbound connection through the host-safety dial discipline: validate each resolved address with
cgka_traits::app_components::reject_non_public_ip, pin the validated address, choose TLS trust from config (never a resolved IP), apply a connect timeout, and gate loopback behind an explicit dev flag. Seedocs/marmot-architecture/overview/dial-safety.md. - Never dial or adopt hosts on the centralized retired-relay denylist. Retired relays must not be used for discovery, bootstrap, examples, or runtime traffic; keep exact endpoint literals confined to the denylist and rejection regression tests.
- Keep multi-step state changes torn-write-free: validate before mutating, compensate every applied step on the error
path, record intent before external side effects, and never confirm work that reached no one. See
docs/marmot-architecture/overview/multi-step-state-changes.md. - Treat workspace and conformance-fixture version bumps as manual release operations. Never change the root workspace
version, workspace package versions in
Cargo.lock, or vectorconformance_versionvalues during feature, fix, binding, or review-feedback work unless the user explicitly requests that version bump. - Title GitHub Releases with the version first so release lists group by cohort: whole-workspace
v<version> - MDK, WN Agentv<version> - wn-agent, and MarmotKitv<version> - MarmotKit. - Prefer
just release-all <version>for a full MDK/WN Agent/MarmotKit cohort release, orjust release-all-draft <version>when releases should stay draft for manual publication. - Sign every commit before pushing. This repository accepts only cryptographically signed commits; configure Git SSH signing (or another accepted signing method) and verify the signature locally.
- When adding an
AGENTS.md, create a siblingCLAUDE.mdsymlink to it.
Run just fast-ci before pushing; let GitHub CI run the full just ci test matrix.
just fast-ci covers formatting, compile-time checks, and clippy across the workspace (including OTLP feature builds).
It intentionally skips just test, which is the slow part of CI.
For crate-local changes, add targeted tests on top of just fast-ci:
just fast-ci
cargo test -p <crate-you-touched>Full local parity with GitHub CI (slow):
just ciIndividual gates:
just fmt-check
just check
just clippy
just test
just install-example-sha256-gateThe install-example gate renders all five installer --help surfaces and checks
release guidance plus workflow-generated notes for download, sibling .sha256
verification (shasum or sha256sum), then local execution. It also rejects
new download-to-shell examples in tracked Markdown, shell, and workflow files.
For formal-model changes:
just tamarin