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>
This commit is contained in:
anthonyrawlins
2026-03-23 20:49:44 +11:00
commit f2d62fa03d
21 changed files with 5272 additions and 0 deletions

414
PROJECT_CONSTITUTION.md Normal file
View File

@@ -0,0 +1,414 @@
# 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)