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

415 lines
20 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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<AccountState>
- [ ] `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)