db-20 — Execution Plan

Stage 1 — Single replica, no replication

Implement Replica and apply() for Op::{NoOp, Put, Del} in Rust. Verify that a Cluster::new(1) (1-replica cluster — trivially has its own quorum) can propose(Put("a", b"v")) and the state machine sees a → b"v". Test cases 1 and 3 in the Rust suite.

Stage 2 — Five replicas, no failures

Add Cluster, propose, quorum = N/2 + 1. Verify that a single propose on a 5-replica cluster applies to all five state machines because all 5 follow the leader. Tests 2 and 6.

Stage 3 — Partitions

Add Cluster::partition(ids) and is_partitioned. Drop messages to and from partitioned replicas. Test that:

  • 3/5 reachable still commits (test 4),
  • 2/5 reachable does not commit (test 3),
  • partitioned followers have commit_index == 0 after one proposal (test 4).

Stage 4 — Heal + catchup

Implement Cluster::heal and Replica::truncate_and_replay. Verify that after a sequence of mutations on healthy replicas, calling heal() brings the partitioned ones back to byte-identical snapshots. Tests 5 and 13.

Stage 5 — Canonical snapshot

Decide the wire format (see CONCEPTS.md), implement dump_state, write the byte-format test that pins every field offset (test 8). The test fails loudly if a future refactor changes endianness or field order.

Stage 6 — Workload driver

Port splitmix64 (mix and stateful generator). Decode each r1 high-bit pair into Put/Del. Encode r3 % 10000 as a fixed 8-byte LE value so the byte width is independent of host word size. Tests 9, 10.

Stage 7 — Cross-language exam

Build the Rust binary, capture the actual hash for scenarios A and B, bake those hashes into src/go/dkv20_test.go, src/cpp/tests/test_dkv20.cc, and scripts/cross_test.sh. Port Go. Port C++. Run bash scripts/cross_test.sh and watch all three values align.

Stage 8 — Verification + docs

scripts/verify.sh runs all three test suites. scripts/cross_test.sh runs all three binaries on both scenarios. Doc trio (analysis, execution, observation, verification, broader-ideas) plus three steps/ study files.

Pitfalls to expect

SymptomLikely cause
Go scenario hash doesn't match Rustunsorted map iteration in DumpState
C++ scenario hash doesn't match Rustendian / size mismatch in put_u32_le / put_u64_le
C++ tests pass in Debug, fail in Releaseassert(side_effect) — Release strips it
Wrong commit_index after partition healsnapshot push not clearing state_machine
Build error: duplicate package declarationcreate_file leftover from a stub
Subagent left half-built portsresume manually, hash will tell you if it works