9.2 KiB
9.2 KiB
Phase 2: P2P Networking Mesh & Schema Extension
Status: Ready for Agent Execution
Phase Goal: Implement the libp2p P2P networking stack in chronogrid_net, extend the database schema with all missing entities, scaffold the headless daemon binary, and harden the verification pipeline.
Prerequisites: Phase 1 complete ✅
Estimated Complexity: High
Blocking: Phase 3 (Flutter UI requires sync events), Phase 4 (AI requires ingestion schema)
Task 2.1 — Extend Schema with Missing Entities
- Task 2.1: Extend
docs/API_CONTRACTS/schema.sqlwith the following new tables:time_blocks— Calendar time-blocking entries linked to tasksattachments— Binary/file attachments linked to notes or ingestion logscalendar_feeds— CalDAV external feed configuration per namespacenode_peers— P2P peer registry (NodeId, public key, last seen, swarm membership)automation_rules— Local trigger/action rule definitionsingestion_configs— IMAP account and file-watcher configuration per namespace- Add
crdt_docsentries fortime_blockentity type - Add indexes for all new foreign keys and query patterns
- Verify
db.rsEXPECTED_TABLESlist is updated to include all new tables - All new tables must include
hlc_timestamp TEXT NOT NULLfor CRDT compatibility - Run
cargo test --package chronogrid_core— all existing tests must still pass
Task 2.2 — Implement chronogrid_net: Node Identity & Swarm Key
- Task 2.2: Implement node identity and swarm key management in
crates/chronogrid_net/:- Add dependencies:
libp2p = { version = "0.54", features = ["noise", "quic", "mdns", "gossipsub", "kad", "identify", "relay"] },tokio = { version = "1", features = ["full"] },ed25519-dalek = "2",rand = "0.8" - Implement
NodeIdentitystruct: Ed25519 keypair generation, serialization, andNodeId(public key hash) - Implement
SwarmKeystruct: 256-bit random key generation, serialization, and validation - Implement
identity::generate_node_identity() -> NodeIdentity - Implement
identity::load_or_create_identity(path: &Path) -> Result<NodeIdentity>— persists keypair to encrypted file - Unit tests: keypair generation, serialization round-trip, NodeId derivation, SwarmKey validation
- Run
cargo test --package chronogrid_net
- Add dependencies:
Task 2.3 — Implement chronogrid_net: Transport & Discovery Layer
- Task 2.3: Implement the libp2p transport stack and peer discovery in
crates/chronogrid_net/:- Implement
transport::build_transport(identity: &NodeIdentity, swarm_key: &SwarmKey) -> Result<Boxed<(PeerId, StreamMuxerBox)>>- QUIC over UDP as primary transport
- Noise XK handshake (Noise_XK_25519_ChaChaPoly_BLAKE2s) for authentication
- Swarm Key pre-shared authentication layer
- Implement
discovery::MdnsDiscovery— zero-config LAN peer discovery - Implement
discovery::KademliaDht— WAN peer discovery via Kademlia DHT - Implement
PeerEventenum:PeerDiscovered { peer_id, addrs },PeerExpired { peer_id },PeerConnected { peer_id },PeerDisconnected { peer_id } - Unit tests: transport construction, mDNS event handling, DHT routing table operations
- Run
cargo test --package chronogrid_net
- Implement
Task 2.4 — Implement chronogrid_net: CRDT Delta Sync Protocol
- Task 2.4: Implement the CRDT delta exchange protocol over libp2p in
crates/chronogrid_net/:- Implement
sync::VectorClock— tracks per-entity HLC head state for delta computation - Implement
sync::DeltaPacket— serializable struct containing compressed CRDT changesets - Implement
sync::SyncProtocol— custom libp2pNetworkBehaviour:- On peer connect: exchange vector clocks via request/response protocol
- Compute missing deltas by comparing remote vs. local vector clock
- Compress delta bytes (LZ4 or zstd), encrypt with ChaCha20-Poly1305, stream over QUIC channel
- On receive: decrypt, decompress, and return
Vec<DeltaPacket>for core to merge
- Implement
sync::GossipsubBroadcast— real-time state change notifications via Gossipsub - Implement
NetEventenum:DeltasReceived { from_peer, deltas },SyncComplete { peer_id },SyncError { peer_id, reason } - Unit tests: vector clock comparison, delta packet serialization, gossipsub message routing
- Run
cargo test --package chronogrid_net
- Implement
Task 2.5 — Implement chronogrid_net: P2P Swarm Manager
- Task 2.5: Implement the top-level
SwarmManagerincrates/chronogrid_net/:- Implement
SwarmManagerstruct: owns the libp2pSwarm, runs the event loop in a dedicated Tokio task - Public API:
SwarmManager::start(identity, swarm_key, listen_addrs) -> Result<SwarmHandle>SwarmHandle::trigger_sync() -> Result<()>— initiates delta sync with all connected peersSwarmHandle::broadcast_event(event: GossipEvent) -> Result<()>SwarmHandle::subscribe_events() -> tokio::sync::broadcast::Receiver<NetEvent>SwarmHandle::shutdown() -> Result<()>
- Integrate
MdnsDiscovery,KademliaDht,SyncProtocol, andGossipsubBroadcastinto a singleNetworkBehaviourcomposite - Implement NAT hole-punching via libp2p Circuit Relay v2 (relay client mode)
- Unit tests: swarm startup/shutdown, peer connection lifecycle, event subscription
- Integration test: two in-process swarms exchange a CRDT delta and verify convergence
- Run
cargo test --package chronogrid_net
- Implement
Task 2.6 — Integrate chronogrid_net into chronogrid_core
- Task 2.6: Wire the P2P sync layer into
chronogrid_core:- Add
chronogrid_netas an optional dependency inchronogrid_core/Cargo.toml(feature:"p2p") - Implement
core::sync::SyncEngine— bridgesSwarmHandleevents toDatabaseCRDT merges:- On
NetEvent::DeltasReceived: deserialize Automerge changesets, merge into localcrdt_docs, update SQL rows - On local CRDT mutation: compute delta vs. last-synced state, broadcast via
SwarmHandle
- On
- Implement
core::sync::SyncEngine::merge_remote_deltas(deltas: Vec<DeltaPacket>) -> Result<Vec<String>>— returns list of affected entity IDs - Unit tests: delta merge into in-memory database, conflict resolution with concurrent edits
- Run
cargo test --package chronogrid_core --features p2p
- Add
Task 2.7 — Scaffold chronogrid_daemon Binary
- Task 2.7: Create the
apps/chronogrid_daemon/headless binary crate:- Create
apps/chronogrid_daemon/Cargo.tomlwith[[bin]]targetchronogrid-daemon - Add
apps/chronogrid_daemonto workspaceCargo.tomlmembers list - Dependencies:
chronogrid_core,chronogrid_crypto,chronogrid_net,tokio,clap,serde,toml,tracing,tracing-subscriber - Create
apps/chronogrid_daemon/src/main.rs:- CLI argument parsing via
clap:--config <path>,--db <path>,--log-level <level> - Config file loading from TOML (
/etc/chronogrid/config.tomlor--configpath) - Initialize
chronogrid_cryptokey derivation and keychain retrieval - Initialize
chronogrid_coredatabase engine - Start
chronogrid_netSwarmManager - Structured logging via
tracing - Graceful shutdown on SIGTERM/SIGINT
- CLI argument parsing via
- Create
apps/chronogrid_daemon/config.example.toml— documented example configuration - Create
docs/DEPLOYMENT/01-headless-daemon-setup.md— systemd service setup guide - Run
cargo build --package chronogrid_daemon
- Create
Task 2.8 — Expand Verification Pipeline
- Task 2.8: Expand
scripts/verify_agent_work.ps1to cover all crates and run full test suite:- Add
cargo test --package chronogrid_cryptostep - Add
cargo test --package chronogrid_corestep - Add
cargo test --package chronogrid_ffistep - Add
cargo test --package chronogrid_netstep - Add
cargo check --package chronogrid_daemonstep - Add schema table count validation (query SQLite in-memory and count tables)
- Add check that
docs/API_CONTRACTS/schema.sqlcontains all required table names - Improve error reporting with per-step timing and failure context
- Run the expanded script and confirm all checks pass
- Add
Task 2.9 — Update FFI Bridge Spec & Fix Type Inconsistency
- Task 2.9: Update API contracts and fix the
due_datetype mismatch:- Fix
crates/chronogrid_ffi/src/api/types.rs: changedue_date: Option<i64>toOption<u64>andcompleted_at: Option<i64>toOption<u64> - Update
docs/API_CONTRACTS/ffi_bridge_spec.jsonto document all 38 FFI functions across the 5 API modules (engine, database, crypto, task_crdt, note_crdt) - Add P2P sync FFI functions to the spec:
init_p2p_swarm,trigger_sync,subscribe_sync_events,get_connected_peers - Run
cargo test --package chronogrid_ffi— all tests must pass
- Fix
Phase 2 Completion Criteria
- All 9 tasks above marked
[x] cargo test --workspacepasses with zero failuresscripts/verify_agent_work.ps1exits with code 0chronogrid_daemonbinary compiles forx86_64-pc-windows-msvcandx86_64-unknown-linux-gnudocs/API_CONTRACTS/schema.sqlcontains all 13 tables (7 original + 6 new)- ADR created for P2P networking decisions (
docs/ARCHITECTURE/ADR/0006-p2p-libp2p-networking.md) DECISION_LOG.mdupdated with Phase 2 decisions