CASTLE — Commit via Atomic Swap, Table-scoped, Leaderless Engine — is a coordinator-free segment commit engine: a Rust library that lets independent, non-communicating writers converge on one agreed history of a keyspace using nothing but the backing object store's own conditional-write primitive — no leader election, no lock service, no consensus round.
Castle is deliberately write-side only. It has no query surface and never will — reading committed history back out is a separate concern for a consuming crate to own, not something Castle specifies or implements. Castle covers exactly four operations:
- Write — commit a new segment via one conditional write, correct against contention, partial failure, and retry.
- Merge / Compact — combine or retire existing segments under a caller-supplied strategy.
- Retain — decide how long a superseded state descriptor must wait before it becomes eligible for deletion.
- Reclaim — physically delete what's eligible, under a two-independent-proof guarantee (never a single check) covering both the ordinary paths that exist today: a staged write that lost its commit race, and a state descriptor that aged out past its retention window.
Both Reclaim paths name a state descriptor, never a segment: Castle has no primitive that deletes segment bytes. Sweeping the segments a merge retired — and the ones an attempt wrote before losing its commit race — is the consuming crate's own pass, driven off the reachability set Castle publishes and sized against the same retention policy.
What a segment's bytes actually contain, how segments combine, how the address space is partitioned, and what a writer computes on each attempt are all extension points (ports) — Castle stays blind to the domain-specific decisions a consumer makes through them, with exactly one deliberate, bounded exception.
That exception: Castle commits timeseries data on summarizable segments, so every segment must expose a statistics value carrying the time extent its data covers, and Castle persists that extent per segment in the state descriptor — which is what lets retention and compaction reason about when data falls without ever opening a segment. It is the whole of what Castle knows about segment content. It learns that a segment covers a set of time cells, at a granularity the consumer declares; it learns nothing about encoding, schema, signal type, or any other lane a consumer's statistics carry.
Durability and replication are the backing store's own, within one region. Castle adds neither a write-ahead log nor replication of its own: its durability boundary is a successful commit, and whatever an ingest tier buffered before that is that tier's to lose. Cross-region replication is out of scope, structurally rather than for lack of effort — replicating a compare-and-swap register across regions needs agreement about which region's write won, and that agreement is the consensus a leaderless engine exists to avoid needing. A multi-region deployment runs independent Castles and reconciles above them.
That boundary and three others — the durability window, table lifecycle, and
schema evolution — are stated in
docs/port-contracts.md §10.
Castle builds on Rust 1.87 or newer (rust-version in the workspace
manifest). What a consumer may rely on — the public Rust API, the state
descriptor's and topology record's on-the-wire encodings, the register key
layout, and the three tracing events an operator is told to alarm off —
what counts as a break in each, and how a break is communicated while the
crate is unpublished, is stated in
docs/compatibility.md. The rest of the
castle.* tracing vocabulary is enumerated in
docs/tracing-vocabulary.md and is
deliberately not covered.
Early. The commit-loop logic carries a two-tier formal-verification story — a bounded-exhaustive TLA+ model and real-trace conformance checking. Reclamation carries the first tier today. Governance is deliberately narrow: scoped to what's actually load-bearing.
There is no roadmap document in this repository. The plan lives entirely in GitHub milestones and issues on this repo.
Apache-2.0. See LICENSE.