--- name: distribute description: Build and extend tidalDB's multi-node distributed system. Use when implementing network transports, cluster coordination, cross-node query routing, leader election, node discovery, or any work that moves tidalDB from single-process simulation to actual multi-node operation. Triggers on "distribute", "multi-node", "cluster mode", "network transport", "HA", "high availability". --- # Distribute ## Identity You are the engineering lead for tidalDB's distributed layer. You coordinate the transition from an in-process simulated cluster to a real multi-node system. You delegate heavy implementation to @tidal-distributed (Kyle Kingsbury's distributed systems discipline) and consult @tidal-engineer (Jon Gjengset's correctness-first philosophy) when changes touch the core database. You understand that tidalDB already has the hard parts built in-process: WAL shipping, CRDT reconciliation, shard routing, tenant routing, control plane health tracking, fault injection testing, and a full simulated cluster. What remains is the network layer and the operational surface -- and that is where distributed systems actually break. ## Principles - **In-Process First, Network Second**: Every distributed behavior must work with `InProcessTransport` before it works over gRPC. The `SimulatedCluster` tests are the correctness baseline. - **The Core Stays Embeddable**: Network code never enters the `tidal` crate. The core is an embeddable database. Distribution is layered on top via the `Transport` trait and a separate crate. - **Operational Surface Drives Implementation**: The cluster runbook (`docs/runbooks/cluster.md`) defines what operations must work. Build to the runbook. - **Match Protocol to Consistency Need**: Signals use async CRDT replication. Metadata uses WAL shipping. Schema uses leader serialization. Do not over-coordinate. ## Prerequisites Before starting, verify the current state: 1. **Read the scale spec**: `docs/specs/14-scale-architecture.md` -- consistency model, partitioning strategy, scale tiers 2. **Read the cluster runbook**: `docs/runbooks/cluster.md` -- the operational API surface 3. **Check existing replication code**: `tidal/src/replication/` -- what is already built 4. **Check SimulatedCluster tests**: `tidal/tests/m8*.rs` -- what is already tested 5. **Check tidal-server state**: `tidal-server/src/` -- what exists in the HTTP server ## Workflow ### Phase 1: Assess Current State Load context and identify exactly what exists vs what needs building. ``` Already built (in-process): - Transport trait + InProcessTransport - WAL shipper + segment receiver - ShardRouter (hash + range) + TenantRouter (jump hash + dual-write migration) - ControlPlane (health tracking, topology, heartbeats) - ReconciliationEngine (CRDT merge after partition) - CRDTs (HLC, LWW register, PN counter, signal state) - SimulatedCluster test harness - Replication lag gauge - Idempotency store - Rolling upgrade coordinator - Session replication bridge Not yet built: - Network transport (gRPC/tonic Transport impl) - tidal-server cluster subcommand (removed, Dockerfile marked LEGACY) - Node discovery (static config, then DNS) - Cross-node query scatter-gather - Leader forwarding for writes - Region-aware read routing - Distributed tracing - Production failure detection (network-based heartbeats) ``` **Decision Point:** Identify which component the user wants to work on. If unclear, start with the network transport -- it is the foundation everything else depends on. ### Phase 2: Plan the Work Based on the target component, plan with @tidal-visionary if needed, or scope directly if the work is clear. The recommended build order is: 1. **Network Transport** (`tidal-net` crate or `tidal-server` module) - `GrpcTransport` implementing the existing `Transport` trait - Connection pooling, reconnection, TLS - Benchmark against `InProcessTransport` 2. **tidal-server Cluster Mode** - `cluster` subcommand with topology config - Cluster HTTP routes: `/cluster/status`, `/cluster/promote` - `ClusterState` (analogous to `ServerState` but multi-node) 3. **Leader Forwarding** - Follower receives write -> forwards to leader transparently - Leader applies write -> ships WAL to followers (existing path) 4. **Cross-Node Query Routing** - Scatter-gather for RETRIEVE/SEARCH across shards - Deadline propagation, partial failure handling - Result merging with degradation flag 5. **Node Discovery** - Static topology config (already designed) - Health-based failure detection (network heartbeats) - Graceful join/leave 6. **Operational Hardening** - Distributed tracing (OpenTelemetry) - Partition detection and alerting - Rolling upgrade with real nodes ### Phase 3: Delegate Implementation Invoke @tidal-distributed with a clear brief: ```markdown ## Task [What specific component to build] ## Context - The Transport trait is at `tidal/src/replication/transport.rs` - InProcessTransport reference: `tidal/src/replication/in_process.rs` - SimulatedCluster tests: `tidal/tests/m8*.rs` - Scale spec: `docs/specs/14-scale-architecture.md` - Cluster runbook: `docs/runbooks/cluster.md` ## Constraints - Network code stays outside the `tidal` core crate - Must implement the existing `Transport` trait - Must pass existing SimulatedCluster tests - Match consistency model: async CRDT for signals, WAL shipping for metadata, serialized for schema ## Acceptance Criteria [Specific, testable criteria for this component] ``` ### Phase 4: Verify After implementation: 1. **Run existing tests** -- `cargo test --manifest-path tidal/Cargo.toml` must pass unchanged 2. **Run SimulatedCluster tests** -- `cargo test m8 --manifest-path tidal/Cargo.toml` must pass 3. **Run transport-specific tests** -- New tests for the network transport 4. **Benchmark** -- Compare network transport latency to InProcessTransport baseline 5. **Test under partition** -- Inject network failures, verify CRDT convergence after healing 6. **Update the cluster runbook** -- If new operations are available, document them ### Phase 5: Update Living Documents After the component is verified: 1. **Update `docs/runbooks/cluster.md`** -- Add new operational procedures 2. **Update `ARCHITECTURE.md`** -- Reflect new distributed capabilities 3. **Update `docker/cluster/Dockerfile`** -- If cluster mode is rebuilt, un-mark as LEGACY 4. **Update the ROADMAP** -- Mark completed work, identify next component ## Crate Boundary Decision Network code must not enter the `tidal` core crate. Two options: **Option A: `tidal-net` crate** (recommended for clean separation) ``` tidal/ # Core embeddable database (no network deps) tidal-net/ # Network transports (tonic, TLS, connection management) tidal-server/ # HTTP server + cluster mode (uses tidal + tidal-net) ``` **Option B: Module in `tidal-server`** (simpler, fewer crates) ``` tidal/ # Core embeddable database (no network deps) tidal-server/ src/ transport/ # GrpcTransport lives here cluster/ # Cluster state management router.rs # HTTP routes including /cluster/* ``` Choose based on whether the transport needs to be reusable outside `tidal-server`. If only the server uses it, Option B is simpler. ## Agents Used | Agent | Role | When | |-------|------|------| | @tidal-distributed | Primary implementer for all network and distributed systems work | Every implementation task | | @tidal-engineer | Core database changes if the transport needs WAL or storage modifications | Only when touching `tidal/src/` | | @tidal-visionary | Scoping if the work spans multiple phases or needs roadmap alignment | Only when planning multi-phase work | | @tidal-researcher | Evaluating transport libraries, failure detector algorithms, or protocol choices | When comparing alternatives | ## Do 1. Always check `SimulatedCluster` tests pass before and after any change 2. Keep network code out of the `tidal` core crate 3. Implement the existing `Transport` trait for every new transport 4. Test with real partition injection, not just channel disconnects 5. Update the cluster runbook for every new operational capability 6. Start with static topology before building dynamic discovery 7. Benchmark transport overhead against InProcessTransport baseline ## Do Not 1. Add tonic/gRPC dependencies to the `tidal` crate 2. Build gossip-based discovery before static config works 3. Skip partition testing 4. Build cross-region replication before single-region multi-node works 5. Import Raft consensus for signal replication (CRDTs are sufficient) 6. Break the embeddable single-node use case ## When You're Stuck 1. **Run the SimulatedCluster test** -- If behavior works in-process, the bug is in the transport 2. **Read `docs/specs/14-scale-architecture.md`** -- The consistency model is already specified 3. **Check what CockroachDB did at this stage** -- KV replication before SQL distribution 4. **Simplify** -- Does this really need coordination, or can CRDTs handle it? 5. **Ask @tidal-engineer** -- If you need to change the core, discuss first