Files
MESH2/PROJECT_CONSTITUTION.md
anthonyrawlins f2d62fa03d Initial workspace: scaffold + constitution + spec documents
Rust workspace with 5 crates (mesh-types, mesh-crypto, mesh-network,
mesh-validator, mesh-wallet), PROJECT_CONSTITUTION.md for CHORUS
automated ingestion, and the full MESH protocol specification suite.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 20:49:44 +11:00

20 KiB
Raw Blame History

Project: MESH

Repository: https://gitea.reset.org/tony/mesh (TBC) Language: Rust (edition 2024, toolchain 1.85.0) License: Apache 2.0 Created: 2026-03-23 Status: Constitution Phase

Overview

MESH (Minimal-Exchange Settlement Hypergraph) is a decentralised payment protocol that settles retail transactions in under 300ms using Byzantine Consistent Broadcast — without a blockchain, without a native token, and with confidential amounts via Pedersen commitments and Bulletproofs+ range proofs. This constitution covers the Tier 1 MVP: a 4-validator local testnet with a CLI wallet that can send and receive confidential payments.

Constraints

  • Single model: All agents run the same LLM backend. No role-to-model mapping is available.
  • MVP scope only: Tier 1 (consensusless settlement) only. No Tier 2 DAG-BFT, no Tier 3 aBFT, no multi-currency routing, no connectors, no stealth addresses. These are specified but deferred.
  • No external network: Agents work against a local Gitea repo. No public APIs, no npm/PyPI fetches during agent sessions.
  • Deterministic serialisation: No serde. All encode/decode is hand-written per SPEC-002 §2.8. This is a hard constraint from the spec — agents must not introduce serde-based serialisation.
  • Constant-time crypto: All secret-dependent operations must use constant-time implementations. Agents must use the dalek crate family, not roll their own.
  • Pinned dependencies: Exact crate versions are specified in the Dev Environment Specification. Agents must not upgrade or substitute crates without a gate approval.

Councils

Council: types

Scope: Core data structures and deterministic binary serialisation (SPEC-002) Agents: 2 builders, 1 reviewer File area: crates/mesh-types/** Depends on: none Spec refs: SPEC-002 §2.22.8 (primitive types, AccountState, Transition, Recipient, SettlementCertificate, ValidatorVote, EquivocationProof, Value Semiring, serialisation rules)

Task: Define primitive types and enums

Implement all primitive types from SPEC-002 §2.2: u8, u32, u64, u128, Hash (32-byte SHA3-256 output), PublicKey (32-byte Ed25519), Signature (64-byte Ed25519), Commitment (32-byte compressed Edwards point), AssetID (32-byte hash). Define enums: TransitionType (Send, Receive, Exchange, OnRamp, OffRamp), NodeType (Validator, Client, Connector). File area: crates/mesh-types/src/primitives.rs

  • All types defined with correct byte sizes
  • AssetID computed as SHA3-256(asset_name || issuer_pubkey || precision)
  • No floating-point types anywhere in the crate

Task: Implement AccountState and Transition structures

Define AccountState (owner, sequence, balances map, state_hash, last_cert, created_at) and Transition (version, type, sender, sequence, recipients, asset_id, amount, range_proof, fee, fee_proof, causal_deps, expiry, memo, signature) per SPEC-002 §2.32.4. File area: crates/mesh-types/src/structures.rs

  • AccountState struct with Map<AssetID, Commitment> for balances
  • Transition struct with all 14 fields from SPEC-002 §2.4.1
  • Recipient struct (address, amount commitment, range_proof)
  • SettlementCertificate struct (transition_hash, epoch, votes)
  • ValidatorVote struct (validator_id, signature)
  • EquivocationProof struct (two conflicting transitions + votes)

Task: Deterministic binary serialisation

Hand-write encode/decode functions for every type. Rules per SPEC-002 §2.8: little-endian integers, length-prefixed Vec, presence-flag optionals, declaration-order struct fields, sorted-key maps. No serde. File area: crates/mesh-types/src/codec.rs

  • encode() and decode() for every struct
  • Round-trip property tests (encode then decode = identity) for every type
  • Canonical form: identical data always produces identical bytes
  • Malformed input returns errors, never panics

Task: Value Semiring implementation

Implement the Value Semiring from SPEC-002 §2.7: aggregation (⊕) for same-asset addition, exchange (⊗) for currency conversion with floor-division and remainder per Security Addendum AV-005. All arithmetic in u128, no floating point. File area: crates/mesh-types/src/value.rs

  • aggregation for same-AssetID values
  • exchange with floor division, remainder returned to sender
  • Overflow checked: ERR_OVERFLOW on u128 overflow in multiplication
  • ValueSet type for multi-asset aggregation

Council: crypto

Scope: Cryptographic operations — keys, signatures, commitments, range proofs (SPEC-006, SPEC-007) Agents: 2 builders, 1 reviewer File area: crates/mesh-crypto/** Depends on: types Spec refs: SPEC-006 §6.4.1 (key derivation), SPEC-007 §7.27.3 (Pedersen commitments, Bulletproofs+), Security Addendum AV-002 (fee range proofs), AV-007 (ephemeral key handling)

Task: Key generation and domain-separated hashing

Ed25519 key pair generation via ed25519-dalek. Derive view key per SPEC-006 §6.4.1. Domain-separated SHA3-256 hashing (each usage context gets a unique prefix to prevent cross-domain collisions). File area: crates/mesh-crypto/src/keys.rs

  • generate_keypair() from CSPRNG
  • derive_view_key() per SPEC-006 §6.4.1
  • Domain-separated hash function with context tags
  • All secret keys implement Zeroize on drop

Task: Pedersen commitments

Implement Commit(value, blinding) = value·G + blinding·H using curve25519-dalek Ristretto operations. Generator H from nothing-up-my-sleeve construction per SPEC-007 §7.2. Homomorphic verification: Σ(C_recipient_i) + C_fee = C_amount. File area: crates/mesh-crypto/src/pedersen.rs

  • commit(value, blinding) returns Commitment
  • Generator H derived from hash-to-point (nothing-up-my-sleeve)
  • verify_conservation(inputs, outputs) using point arithmetic
  • Blinding factor addition/subtraction for balance updates

Task: Bulletproofs+ range proofs

Generate and verify range proofs for values in [0, 2^64) using dalek bulletproofs with Merlin transcripts. Proofs must bind to transaction hash per SPEC-007 §7.3.2. Fee commitments MUST have range proofs per Security Addendum AV-002. File area: crates/mesh-crypto/src/rangeproof.rs

  • prove_range(value, blinding, transcript) returns RangeProof
  • verify_range(commitment, proof, transcript) returns bool
  • Proof bound to transaction hash via Merlin transcript
  • Zero-value commitments produce valid range proofs
  • Negative/overflow values produce proofs that fail verification

Task: Transaction construction and validation

Build complete Transition with committed amounts and range proofs. Implement all 9 validation rules from SPEC-002 §2.4.3 with Security Addendum amendments (AV-002 fee range proofs, AV-003 causal dependency relevance check). File area: crates/mesh-crypto/src/validation.rs

  • build_transition() constructs a fully signed Transition
  • All 9 validation rules implemented in order
  • Each rule returns the specified error code on failure
  • AV-002: fee range proof required (including zero-fee)
  • AV-003: causal deps checked for existence AND relevance
  • Test vectors for each validation rule (valid + each failure mode)

Gate: Cryptographic implementation review — verify Pedersen generator derivation, Bulletproofs+ transcript binding, and constant-time properties before downstream councils consume mesh-crypto.

Council: network

Scope: QUIC transport layer, message framing, handshake protocol (SPEC-009) Agents: 2 builders, 1 reviewer File area: crates/mesh-network/** Depends on: types Spec refs: SPEC-009 §9.29.5, §9.89.9 (QUIC transport, framing, handshake, stream multiplexing, rate limiting, keepalive)

Task: QUIC server and client

QUIC transport using quinn with TLS 1.3 via rustls. Self-signed certificates for testnet. Server accepts connections on configurable address. Client connects with ALPN identifier "mesh/0". File area: crates/mesh-network/src/transport.rs

  • QUIC server binds and accepts connections
  • QUIC client connects with ALPN "mesh/0"
  • TLS 1.3 with self-signed certs (via rcgen)
  • Connection errors handled gracefully (no panics)

Task: Message framing and dispatch

Length-prefixed message framing: [length: u32][type: u8][payload] per SPEC-009 §9.4. Maximum frame size 4MB. Message type dispatch to handlers. Implement all message type IDs from SPEC-009 §9.4.1 (MVP subset: 0x010x04, 0x400x42, 0xF00xF1, 0xFF). File area: crates/mesh-network/src/framing.rs

  • Encode/decode framed messages
  • Reject frames exceeding 4MB
  • Dispatch by message type to handler callbacks
  • Malformed frames rejected (tested with fuzzy input)

Task: Handshake protocol

MESH HandshakeMessage exchange per SPEC-009 §9.3: protocol version, cipher suites, node type, public key, epoch, signature proof of key ownership. Verify remote node's identity. File area: crates/mesh-network/src/handshake.rs

  • HandshakeMessage struct with all fields from SPEC-009 §9.3.2
  • Signature verification of remote node's public key
  • Validator nodes checked against current epoch's validator set
  • Connection closed on any handshake failure

Task: Stream multiplexing and keepalive

Dedicated QUIC streams per message category per SPEC-009 §9.5: streams 03 for handshake/keepalive, 47 for Tier 1, 2023 for queries. PING/PONG keepalive every 30s per SPEC-009 §9.9. File area: crates/mesh-network/src/streams.rs

  • Stream ID ranges assigned per SPEC-009 §9.5
  • PING sent every 30s if no other traffic
  • PONG response within 5s
  • Connection closed after 3 missed PINGs

Council: validator

Scope: Validator node binary — state store, vote handling, equivocation detection, certificate processing (SPEC-003) Agents: 3 builders, 1 reviewer File area: crates/mesh-validator/** Depends on: types, crypto, network Spec refs: SPEC-003 §3.3 (vote/certificate protocol), SPEC-002 §2.4.3 (validation rules), Security Addendum AV-003 (causal deps), AV-004 (sharding), AV-006 (epoch boundary)

Task: Account state store

Embedded key-value store using sled for AccountState keyed by PublicKey. CRUD operations. Certificate store keyed by transition hash. Equivocation record store keyed by (sender, sequence). File area: crates/mesh-validator/src/store.rs

  • get_account(pubkey) returns Option
  • put_account(pubkey, state) persists atomically
  • get_certificate(hash) for causal dependency lookups
  • put_equivocation(sender, seq, proof) for detection records

Task: VOTE_REQUEST handler

Receive a Transition, run all 9 validation rules from SPEC-002 §2.4.3 (with Security Addendum amendments). If valid, sign a vote per SPEC-003 §3.3.1. If invalid, return VOTE_REJECT with error code. Record (sender, sequence, hash) for equivocation detection. File area: crates/mesh-validator/src/vote.rs

  • All 9 validation rules applied in order
  • Vote signature: Sign(validator_key, transition_hash || epoch)
  • VOTE_RESPONSE sent on success, VOTE_REJECT on failure
  • Equivocation lock: reject second transition for same (sender, seq)

Task: Equivocation detection and proof

Maintain map of (sender, sequence) → transition_hash. On conflict, produce EquivocationProof containing both conflicting transitions and their votes. Broadcast proof to all connected validators. File area: crates/mesh-validator/src/equivocation.rs

  • Detect conflicting transitions for same (sender, sequence)
  • Produce EquivocationProof with both transitions
  • Broadcast proof to peers
  • Reject both transitions once equivocation detected

Task: SETTLEMENT_CERTIFICATE handler

Receive a certificate. Verify ≥ 2f+1 valid votes from current epoch's validator set (with one-epoch grace period per Security Addendum AV-006). Apply state transition: debit sender, credit recipients. Store certificate. File area: crates/mesh-validator/src/certificate.rs

  • Verify vote count ≥ 2f+1
  • Verify all vote signatures against correct epoch's validator set
  • AV-006: accept current epoch and epoch-1, reject epoch-2 and future
  • Apply state transition atomically (debit + credit + sequence bump)
  • Store certificate in permanent record

Task: Account query handler and validator config

Respond to QUERY_ACCOUNT with current account state. TOML configuration file for validator: listen address, peer addresses, validator set (public keys), epoch number, shard assignment. File area: crates/mesh-validator/src/query.rs, crates/mesh-validator/src/config.rs

  • QUERY_ACCOUNT returns current AccountState
  • TOML config loaded at startup
  • Validator key loaded from file (generated on first run)

Council: wallet

Scope: CLI wallet binary — key management, payment flow, balance tracking (SPEC-003 client side) Agents: 2 builders, 1 reviewer File area: crates/mesh-wallet/** Depends on: types, crypto, network Spec refs: SPEC-003 §3.3 (client-side protocol), SPEC-007 §7.2 (balance decryption via blinding factors), MVP Roadmap §Milestone 4

Task: Key management

mesh-wallet keygen generates Ed25519 key pair + derives view key. Saves to encrypted file. mesh-wallet show-address prints public key. Blinding factor store (sled DB keyed by transaction hash) — this is the wallet's most sensitive data. File area: crates/mesh-wallet/src/keys.rs

  • keygen command generates and saves key pair
  • show-address prints public key in hex
  • Blinding factors stored locally per transaction
  • Secret keys zeroized on drop

Task: Send payment flow

mesh-wallet send --to <pubkey> --amount <value> --asset <id>. Constructs a Transition with Pedersen-committed amount and Bulletproofs+ range proof. Broadcasts VOTE_REQUEST to all configured validators. Collects 2f+1 votes. Assembles SettlementCertificate. Broadcasts certificate. Prints certificate hash. File area: crates/mesh-wallet/src/send.rs

  • Constructs valid Transition with committed amounts
  • Sends VOTE_REQUEST to all validators
  • Collects 2f+1 votes (tolerates slow/failed validators)
  • Assembles and broadcasts SettlementCertificate
  • Stores blinding factors for sent transaction

Task: Receive and balance commands

mesh-wallet receive --cert <hash> submits a Receive transition referencing the certificate. mesh-wallet balance queries a validator and decrypts committed balance using stored blinding factors. mesh-wallet history lists all settlements with certificate hashes. File area: crates/mesh-wallet/src/receive.rs, crates/mesh-wallet/src/balance.rs

  • receive command submits Receive transition with causal dep
  • balance command queries validator, decrypts locally
  • history lists sent and received settlements
  • Handles case where blinding factors are missing (display "encrypted")

Council: testnet

Scope: 4-validator testnet orchestration, crash recovery, end-to-end integration (MVP Roadmap §Milestone 5) Agents: 1 builder, 1 reviewer File area: config/, docker-compose.yml, Dockerfile, tests/integration/ Depends on: validator, wallet Spec refs: MVP Roadmap §Milestone 5, Dev Environment Specification §5

Task: Docker Compose testnet

docker-compose.yml starting 4 validators on a bridge network. Per-validator TOML config. Shared volume for validator key distribution. Genesis validator credits initial test accounts. File area: docker-compose.yml, Dockerfile, config/**

  • docker compose up starts 4 validators
  • Each validator has unique config (listen addr, peers, keys)
  • Genesis mechanism credits initial accounts with test tokens
  • docker compose down -v cleanly wipes all state

Task: End-to-end integration test

Automated test: Alice creates account, receives genesis credit, sends 500 tokens to Bob, Bob receives, both check balances. Confidential amounts throughout — validators never see plaintext. Run as cargo test in the workspace root. File area: tests/integration/**

  • Alice→Bob send/receive completes successfully
  • Balances correct after transfer (Alice: 9500, Bob: 500)
  • All amounts are Pedersen-committed (no plaintext in validator logs)
  • Test passes against 4-validator docker testnet

Task: Crash recovery test

Kill one validator. Verify system continues (3/4 = 2f+1). Restart killed validator. It catches up by requesting missed certificates. All 4 validators converge to identical state. File area: tests/integration/**

  • Transactions succeed with 3/4 validators
  • Restarted validator syncs missed certificates
  • All 4 validators have identical account state after sync

Council: infra

Scope: Project scaffolding, CI pipeline, build configuration, benchmarks (MVP Roadmap §Milestone 0, §Milestone 6) Agents: 1 builder, 1 reviewer File area: Cargo.toml, .cargo/, .github/, rust-toolchain.toml, benches/**, deny.toml Depends on: none Spec refs: Dev Environment Specification §2.32.4 (Rust toolchain, cargo config), §6 (CI pipeline), §7 (crate dependencies)

Task: Workspace scaffolding

Cargo workspace with crates: mesh-types, mesh-crypto, mesh-network, mesh-validator, mesh-wallet. Root Cargo.toml. rust-toolchain.toml pinned to 1.85.0. .cargo/config.toml with mold linker. deny.toml for license compliance (Apache 2.0 compatible only, no GPL). File area: Cargo.toml, .cargo/config.toml, rust-toolchain.toml, deny.toml

  • cargo build succeeds on empty workspace
  • Rust 1.85.0 pinned via rust-toolchain.toml
  • mold linker configured in .cargo/config.toml
  • cargo deny check licenses passes

Task: CI pipeline

GitHub Actions workflow: format check (rustfmt), lint (clippy -D warnings), build all targets, test all targets, audit dependencies (cargo-audit), license compliance (cargo-deny). Runs on push and PR. File area: .github/workflows/ci.yml

  • CI runs on every push and PR
  • rustfmt, clippy, build, test, audit, deny all pass
  • Uses rust:1.85.0-bookworm container image
  • Cargo registry cached across runs

Task: Benchmarks

Criterion benchmarks for: Bulletproofs+ prove/verify time, Ed25519 sign/verify, Pedersen commit, serialisation round-trips, end-to-end Tier 1 latency. File area: benches/**

  • cargo bench runs all benchmarks
  • Range proof generation and verification benchmarked
  • Signature operations benchmarked
  • Results written to stdout in criterion format

Cross-Cutting Concerns

Coding standards:

  • cargo fmt --all enforced. Unformatted code is rejected by CI.
  • cargo clippy -- -D warnings enforced. All warnings are errors.
  • No unsafe code without a // SAFETY: comment explaining why.
  • No unwrap() or expect() in library code. Use Result types.
  • All public functions have doc comments.

Error handling:

  • Every validation failure returns the specific error code from SPEC-002 §2.4.3 (ERR_UNSUPPORTED_VERSION, ERR_INVALID_SIGNATURE, etc.).
  • Network errors are logged and retried with backoff, never panicked.

Security:

  • All secret key material uses zeroize crate for secure erasure.
  • Constant-time operations for all secret-dependent code paths (use subtle crate for comparisons where needed).
  • No logging of secret keys, blinding factors, or plaintext amounts.
  • Security Addendum amendments (AV-001 through AV-007) are mandatory for all relevant code paths.

Testing:

  • Property-based tests via proptest for serialisation round-trips.
  • Every validation rule has a positive test and a negative test.
  • Integration tests run against the 4-validator docker testnet.

Acceptance Criteria

The coordinator evaluates these as exit triggers via ov coordinator check-complete:

  • All 5 crates compile with zero warnings (cargo clippy -- -D warnings)
  • All unit tests pass (cargo test --all-targets)
  • Serialisation round-trip property tests pass for every type
  • Cryptographic test vectors pass (key gen, sign/verify, commit, range proof)
  • 4-validator testnet starts via docker compose up
  • End-to-end confidential payment: Alice sends 500 tokens to Bob through 4 validators, both balances correct
  • Crash recovery: kill 1 validator, transact, restart, state converges
  • Benchmarks run and produce results (range proof < 500ms, verify < 10ms target)
  • cargo audit reports no known vulnerabilities
  • cargo deny check licenses passes (Apache 2.0 compatible only)