Skip to content

Latest commit

 

History

History
86 lines (62 loc) · 4.47 KB

File metadata and controls

86 lines (62 loc) · 4.47 KB

cgka-engine

OpenMLS-backed implementation of the CgkaEngine trait.

This crate owns the local group state machine. It sits above OpenMLS, governs commit sequencing, enforces MIP-03 admin rules, and returns typed outcomes for every ingest path.

What this crate does

  • Wraps MlsGroup for each joined group and manages its EpochState lifecycle (Stable, PendingPublish, Merging, Recovering, Unrecoverable).
  • Translates SendIntents (app-message, invite, remove-members, leave, update-app-components, update-group-data) into MLS commits — group creation and capability upgrade are separate trait calls (create_group, upgrade_group_capabilities); translates inbound TransportEnvelopes into typed IngestOutcomes and GroupEvents.
  • Stores inbound payloads as typed raw-transport or peeled-OpenMLS records so peel-deferred messages can be retried without polluting convergence replay.
  • Retains a small, configurable OpenMLS past-epoch window for delayed application messages.
  • Maintains a per-leaf capability cache so feature_status lookups do not walk the ratchet tree.
  • Stages SelfRemove-only commits for eligible remaining members and returns that work as publish-before-apply obligations; keeps durable local leave requests gated and re-proposes stale SelfRemove proposals for newer epochs.

What it does not do

  • No transport (no Nostr, no relays). Plug in a TransportPeeler impl.
  • No persistence beyond what StorageProvider exposes. Pair with storage-sqlite for SQLCipher-backed persistence; tests can use its in-memory SQLite mode.
  • No CLI, no FFI, no application logic.

Run the tests

cargo test -p cgka-engine

These tests cover the engine boundary directly. They use one or a few Engine<SqliteAccountStorage> instances with in-memory SQLite storage and a mock peeler. They are the right place for local rules: command validation, snapshot persistence, processed-message idempotency, restart behavior, and the exact outputs from a single engine call.

Run the simulator when you change convergence, delivery, branch selection, group data, or anything that depends on more than one client:

cargo test -p cgka-conformance-simulator
cargo test -p cgka-conformance-simulator --features conformance-slow

The simulator is the integration and conformance layer for this engine. It wraps real engine instances with the Nostr peeler, drives them through an in-memory transport bus, and checks that clients converge after realistic delivery weirdness. Its README explains the scenario format, vector fixtures, generated families, reports, and property tests:

Use this crate's tests to prove that an engine method does the right thing. Use the simulator to prove that many engines still agree after the world gets messy.

See tests/AGENTS.md for the test file map.

Promoting state-bearing app components

upgrade_group_capabilities only promotes state-bearing app components whose optional state already exists in the GroupContext. Use two published commits:

  1. send SendIntent::UpdateAppComponents to install the optional component state, then confirm that commit was published;
  2. call upgrade_group_capabilities, then publish and confirm its promotion commit.

The upgrade fails closed without staging a commit when required state is missing. MDK does not currently expose an atomic require-and-populate API.

Reading order for a new contributor

  1. Target architecture: ../../docs/marmot-architecture/overview/target-architecture.md
  2. ../../docs/marmot-architecture/cgka-engine-spec.md — the current engine spec
  3. Detailed post-peeling contract: ../../docs/marmot-architecture/cgka-engine-canonicalization-contract.md
  4. Branch-selection and convergence model: ../../docs/marmot-architecture/distributed-convergence.md
  5. AGENTS.md — module-by-module map of this crate, design deviations, where to look for what

For the Marmot app-component model now used by new groups, see marmot-protocol/marmot and src/app_components.rs.

Status

0.9.0, single internal consumer, not semver-stable. For current readiness and open production work, start with ../../docs/marmot-architecture/overview/current-state.md.