Peregrine is five cooperating programs organized into three planes: a data plane that stores and serves objects, a control plane that deploys and operates the cluster, and a test plane that proves it under load and fault.
The current gate state is kept separately in the 2026-08-31 status snapshot. Architecture descriptions are not evidence that the current release line has passed G3, G7, or production acceptance. G6 is tracked separately and is GREEN on the dated W070 record.
The design constraint: format fidelity
Each implemented Swift format is treated as a compatibility contract. Peregrine verifies specific paths with golden fixtures generated by the real Python implementation:
| Contract | Where it lives |
|---|---|
| Ring file v1/v2 | ring load / build, get_nodes, handoffs |
| Object on-disk layout | diskfile, EC fragment naming, hashes.pkl (pickle in xattrs) |
| Account / container DBs | SQLite schema + pickled pending files |
| Replication protocols | REPLICATE verb, rsync, ssync |
| Crypto & signatures | crypto-meta, HMAC etag, TempURL/formpost sigs |
| Erasure-coded fragments | byte-identical to PyECLib |
These proofs are evidence-scoped and do not establish complete fleet-wide interchangeability. The strict parity matrix controls rollout claims.
The data plane — swift-rust
A 16-crate workspace mirroring Swift’s module boundaries. The path a request travels: client → proxy → object / container / account servers → container-update side channel → container server. Object bodies stream end to end through 64 KB buffers, so a multi-GB PUT/GET never materializes in memory.
| Crate | Swift analogue | Holds |
|---|---|---|
swift-core |
swift.common.* |
timestamps, ring hashing, storage-policy parsing, pickle, config, statsd/syslog/recon, constraints |
swift-ring |
swift.common.ring |
ring load/build, get_nodes, handoffs, per-policy rings |
swift-http |
swob + WSGI serving semantics | Hyper/Tokio HTTP/1.1, IncomingBody, streaming bodies, multipart-MIME, and native async socket hand-offs |
swift-runtime |
Eventlet concurrency semantics, not Eventlet implementation | admission budgets, deadlines, bounded blocking domains, storage/DB executors, structured task scopes, and durability barriers |
swift-diskfile |
swift.obj.diskfile |
on-disk object format, DiskFile lifecycle, EC fragment naming |
swift-db |
account/container backends | SQLite backends, broker, sharding |
swift-{account,container,object}-server |
the servers | REST + REPLICATE + the consistency daemons |
swift-proxy-server |
swift.proxy.* |
node iteration, quorum, controllers, EC controller |
swift-middleware |
swift.common.middleware.* |
tempauth, copy, SLO/DLO, versioned_writes, quotas, … |
swift-crypto / swift-memcache / swift-s3api |
supporting data-plane crates | AES-256-CTR, memcache client, S3 signing and request translation |
swift-cli |
swift-* scripts |
ring-builder, recon, get-nodes, info tools, ring-sim |
swift-ec |
pyeclib / liberasurecode | the erasure-coding codec (Linux, ec feature) |
Storage policies
- Replication — N replicas placed by the ring, kept whole by the object replicator (rsync / rsync-over-ssh) and the DB replicator.
- Erasure coding (
ecfeature, Linux) — fragments byte-identical to PyECLib, a streaming multipart-MIME + multiphase-commit PUT, segment-wise decode on GET, ranged GET over the covered span, and a reconstructor that heals a lost fragment from its peers.
The control plane — swift-deploy-rs
A bounded executor for the upstream Swift Ansible v3 plan with no Python or
Ansible at runtime. It expands plays, roles, includes, loops, handlers and
run_once into a deterministic JSON plan, seals it with SHA-256, and
re-verifies plan, bundle, inventory and digests before apply. Disk wipes,
firewall changes, and SSH reconfiguration each require separate authorization.
The test plane — cosbench-rs, autocos, and the console Lab
cosbench-rs generates S3/Swift load (prepare / main / cleanup, hash-integrity
checks, JSON/CSV reports); autocos scripts the run lifecycle over it; the
swift-console Lab injects faults (fragment loss, node down)
and verifies read-back integrity.
Cross-component invariants
Evidence-scoped compatibility. Only formats and paths covered by golden or live interop evidence are claimable as byte-compatible.
No runtime Python. Every component is a self-contained Rust binary.
Sealed deploys. A plan that changed after it was sealed does not apply.
The oracle is Python. Correctness is checked against the real Python implementation, not against Peregrine’s own expectations.
Concurrency contract
Source 17adf0b contains the Hyper/Tokio serve path, AsyncService /
IncomingBody, native async SSYNC and object-MIME hand-offs, and the dedicated
swift-runtime crate. The older Phase-0 ADR that says the async serve path is
unimplemented is historical baseline material, not the current code state.
Streaming request and response bodies use bounded buffers, and fan-out/quorum
work is explicit in the proxy controllers. A migrated route must not hide a
synchronous handle() call, block_in_place, or an unbounded blocking wait
inside the async executor.
G3 is therefore route-specific: counters and runtime observation must show the declared async path was exercised. Reload/signal preservation and the G7 load harness are implementation and test infrastructure; they do not become a G7 pass until the ordered concurrency/fault evidence is captured. W070 closes G6, but implementation in a clean candidate is not production acceptance: G3 remains route-specific and G7 is not accepted.