Rust · zero dependencies · deterministic simulation
Archipelago is a distributed file system written from scratch in Rust with zero dependencies: content-addressed chunking, rendezvous placement, quorum writes, and self-healing re-replication. The unusual part is that the whole cluster, including the network, runs inside one seeded deterministic simulation. Write a file, crash a node, partition the network, and watch quorum and SHA-256 content-hash checks decide every read. A read returns the exact bytes or fails loudly, never silent corruption.
The concepts the simulation is built on, in plain terms, each one a small module you can read in an afternoon.
A metadata service maps every file path to its ordered list of chunk hashes and tracks the directory tree. A set of storage nodes hold the chunks themselves. A client talks to both. It asks metadata where a file's chunks live, then reads or writes those chunks on the storage nodes directly.
Nothing here needs a second machine. The metadata service, the nodes, and the message scheduler all run inside one process.
A file is split into fixed-size chunks. Each chunk is named by the SHA-256 hash of its own bytes, so identical content is stored once and every reference to a chunk carries a built-in integrity check.
The metadata for a file is just the ordered list of those hashes. To rebuild the file you fetch each chunk by hash and concatenate them back in order.
Every chunk is copied onto R storage nodes chosen by rendezvous hashing. Each node scores the chunk, and the top R scorers hold it. Losing one node moves only that node's chunks, not the whole placement.
A write is durable once a quorum of replicas acknowledge. Reads assemble the file from any live replica of each chunk, so a single slow or dead node never blocks a read.
There is no data loss with fewer than R node failures. Lose one or two nodes with R at three and every chunk still has a live copy. Under-replicated chunks re-replicate automatically once healthy capacity is available, restoring the full replica count.
Only when all R replicas of a specific chunk are gone is that file reported unavailable. It is never silently returned as corrupt bytes.
The cluster runs on a seeded message scheduler that can delay, reorder, drop, and partition messages. The same seed produces the same run every time.
That is what makes failures testable. A partition or a dropped acknowledgement is not a flaky accident here. It is a reproducible event you can replay and reason about.
Instead of replicating each chunk R times, each chunk can be Reed Solomon encoded over GF(2^8) into k data plus m parity shards spread over distinct nodes. A read needs any k of the k+m shards, so up to m holders can be lost and the file still reads.
A fetched shard is verified against its content address, so a corrupt shard just counts as missing, and lost shard positions are re-encoded onto live nodes as repair.
Archipelago is not a production replacement for a real cluster file system. It is the readable, deterministic version of the same ideas, built so the failure modes are reproducible instead of flaky.
Production distributed file systems, battle-tested across many machines, with POSIX access, rebalancing, and huge real clusters. They need real hardware and real networks to run, and their most interesting bugs live in timing that is slow and flaky to reproduce on that hardware.
The same core ideas, chunking, rendezvous placement, quorum, replication, self-healing, and Reed Solomon erasure coding, in code small enough to read in an afternoon with zero external dependencies. The whole cluster and network run inside one process as a seeded deterministic simulation, so a partition or a dropped acknowledgement is a reproducible event you can replay from its seed and check against an in-memory oracle.
Honest non-goals: a single process rather than real machines, a simulated scheduler rather than real RPC, no POSIX mount, and no tuning for production scale. The point is provable correctness you can read, not throughput. This is the FoundationDB and TigerBeetle style of deterministic simulation testing, applied to a file system.
Archipelago turns the cluster into a pure function of a seed and an operation script, then holds it to hard properties. Each gate proves one, and they all run under cargo test.
# the whole suite is pure and dependency-free; one command runs every gate $ cargo test test result: ok. 51 passed; 0 failed # src/lib.rs unit tests test result: ok. 1 passed; 0 failed # differential: random ops vs an in-memory oracle test result: ok. 5 passed; 0 failed # faults: durability under crash and partition test result: ok. 6 passed; 0 failed # erasure: Reed Solomon over GF(2^8) test result: ok. 2 passed; 0 failed # determinism: same seed, identical run test result: ok. 7 passed; 0 failed # boundaries: empty files, renames, edge sizes test result: ok. 1 passed; 0 failed # fault_differential: faults interleaved with the oracle test result: ok. 2 passed; 0 failed # roundtrip: chunking and content addressing test result: ok. 3 passed; 0 failed # stress: samples the Options space under faults # turn the fuzz knobs up for a longer adversarial run $ ARCH_FUZZ_OPS=5000 cargo test --test differential test result: ok. 1 passed; 0 failed; finished in 55.40s $ ARCH_FAULT_FILES=400 cargo test --test faults test result: ok. 5 passed; 0 failed; finished in 17.95s
A read returns exactly the oracle bytes, or the file is reported unavailable. A committed file that vanishes or comes back wrong is a hard failure. That is the FoundationDB and TigerBeetle style of deterministic simulation testing, applied to a file system small enough to hold in your head.
# build and test the whole system (Rust, zero dependencies) cargo build cargo test # the demo: write files, spread chunks over five nodes, kill one, # re-replicate onto the survivors, then read every file back verified cargo run --bin arch -- demo # the interactive session cargo run --bin arch arch> mkdir /docs arch> put /docs/hello hello archipelago arch> fail 0 arch> get /docs/hello arch> stabilize arch> status