Scope 6.6 deliverables 1-3, partial. This is evidence, not a freeze: no
Wave B deliverable set is complete and the throughput figure below is not
a publishable bundle.
The revert-and-observe-red acceptance for cd37f8b's two generators was
never actually performed -- the tests asserted it in their doc comments,
which is a claim. It is performed now, in a throwaway copy, one mutation
at a time, and each reddens exactly one test for the right reason. With
segment frame validation reverted to pushing footer offsets straight into
the adopted set, the store still opens and recovery still completes: it
reports recovery_ok=true and adopts the corrupted frame as authority, so
the red is exit 0 where 65 is required rather than a store that failed to
open. With the shard-index check removed from journal binding, the moved
journal is adopted whole and root_uuid alone does not catch it -- the Wave
A blocker reproduced.
The eight Wave B failpoint rows now drive StoreEngine::submit in-process
with the full six-field expectation asserted against the frozen oracle,
field by field rather than by struct comparison. No pending-wave-b row
remains. The four fields Wave A could not reach come from four independent
observations: the store naming itself poisoned, the two-root status read,
a receipt obtainable at all, and a different transaction submitted to the
same shard before any reopen. The last two are not the same question -- a
shard can be unpoisoned and still refuse a later append because its writer
thread died, which is exactly what phase-aware panic ownership fixed and
what this now checks from outside. AfterRootCasBeforeWaiterWake is
observed as a genuinely hung submit whose receipt is still retrievable,
so a waiter that never wakes is proved to be a hung request rather than an
absent transaction. Every row also asserts its group's fence count against
the public durability snapshot.
Two flake campaigns were measured rather than rerun: 4 failures in 40, then
7 in 40, from two distinct causes. One is a finding -- publishing a group
adds an index delta layer and none are sealed, so submit refuses after
exactly max_index_runs publications for the life of an engine. Both fixed
structurally; 200/200 and 40/40 after.
store-bench emit-skeleton now defaults to the submit path, with the journal
seam retained under --path drive for comparison. The signer is real, the
ref CAS is evaluated by the sequencer, and objects_new is summed from the
store's own receipts rather than multiplied out of the transaction count.
Explicit blockers, retained rather than worked around:
- StoreEngine::open still refuses startup state 1, so the benchmark seeds
its root by a non-production path. Seeding a store off the production
path in order to measure the production path is the charter item 8
smell; the disclosure is recorded in the fixture, a const doc, and the
module docs, and a test asserts open still refuses so it cannot go
stale in the safe direction.
- P2 is blocked three ways -- checkpointing disabled, no steady state
under the index-run ceiling, and no warmup/repetition/trim protocol.
The rate emitted is a debug build on tmpfs, marked preliminary.
- The 100 SIGKILL cycles still drive the journal seam, so kill -9 never
lands inside a real publication.
- Four schema claims became earnable and are requested, not emitted;
bench/result-schema.json is lead-owned.
- Reopen after close needs a bounded, measured, reported wait, because
the root LOCK outlives StoreEngine::drop. Diagnosed since as fork/exec
inheritance of the lock file description; the fix belongs in the lock
primitive, and this wait is removed when it lands.
scripts/check-phase1.sh GATE_EXIT=0; verify-store-recovery.sh 100 cycles,
recovery_failures=0, acknowledged_loss=0, torn_transactions=0,
repeated_adoptions=0, bundle=schema-valid.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|---|---|---|
| .github/workflows | ||
| bench | ||
| crates | ||
| deploy | ||
| doc | ||
| scripts | ||
| .gitignore | ||
| Cargo.lock | ||
| Cargo.toml | ||
| LICENSE | ||
| README.md | ||
README.md
LeVCS
A distributed version control system with first-class federation, signed authority chains, and a cascading merge engine. Content-addressed by BLAKE3, signed with Ed25519, and built to fix what git can't.
Status: v0.1.0 — protocol substrate complete, workflow surface deferred. The object model, federation API, merge cascade, and instance server all work end-to-end. There is no PR review surface, issue tracker, or web UI yet — those are the next layer up. See
doc/technical-report.mdfor a full framing of where this project is and why.
What's different from git
- Identity is in the protocol. A repo's membership is a versioned, signed authority object with explicit roles (Reader/Contributor/Maintainer/Owner). Force-push enforcement and push authorization are protocol-level, not server policy.
- Federation is first-class. Every repo has a global
repo_id(BLAKE3 of its genesis authority); instances mirror each other in three storage modes (full / release-only / metadata-only). - Merge is a cascade, not a line-level diff. Per-file dispatch to a handler ranked by aggressiveness: textual fallback, format-aware (JSON / YAML / TOML / XML / Markdown / prose), tree-sitter for source code (Rust, Python, JS/TS, Go, C/C++, Java, Ruby, Bash), and wasm-sandboxed plugins for the long tail.
- BLAKE3, not SHA-1. Tree-hashed, ~5 GiB/s on a laptop, 32-byte IDs everywhere.
- Releases are signed objects, not mutable name pointers.
For a deeper comparison and context, see the technical report.
Building
LeVCS is a Rust workspace. You'll need a recent stable toolchain (workspace MSRV is 1.75) and a C compiler for the tree-sitter grammars.
cargo build --release
Two binaries land in target/release/:
levcs— the user-facing CLI.levcs-instance— the federation HTTP server.
Install them somewhere on PATH:
sudo install -m 0755 \
target/release/levcs target/release/levcs-instance \
/usr/local/bin/
Quick start (single user, local only)
# Generate an identity key (stored in $XDG_CONFIG_HOME/levcs/keys.toml).
levcs key generate --label me
# Create a repository wherever you have files to track.
mkdir /tmp/demo && cd /tmp/demo
echo "hello" > a.txt
levcs init --key me
levcs track --all
levcs commit -m "first commit"
levcs log
That's a fully working LeVCS repo. Branch and merge:
levcs branch feature/x
echo "more" >> a.txt
levcs commit -m "wip"
levcs branch main
levcs merge feature/x
If a merge produces conflicts, drop into the resolution TUI:
levcs merge --resolve
Cut a release:
levcs release v0.1.0 --notes "first release"
Hosting an instance
To dogfood the federation surface, run levcs-instance on a VPS behind
nginx or Caddy. The full walkthrough is in
deploy/README.md: build, systemd unit, reverse
proxy templates, firewall, and the laptop-side bootstrap.
The compressed version:
sudo cp deploy/levcs-instance.service /etc/systemd/system/
sudo cp deploy/instance.toml.example /etc/levcs/instance.toml
sudo $EDITOR /etc/levcs/instance.toml
sudo systemctl enable --now levcs-instance
# ... then drop deploy/Caddyfile.example into /etc/caddy/Caddyfile
From your laptop, point the local repo at the instance and push:
levcs instance --set https://levcs.example.com/levcs/v1
levcs push refs/branches/main
The first push to a fresh instance auto-inits the repo with your genesis authority. Subsequent pushes are role-checked against the authority chain.
Repository layout
crates/
levcs-core/ Object model (Blob/Tree/Commit/Release/Authority),
hash, store, refs, repository abstractions.
levcs-identity/ Authority objects, Ed25519 keys, signing/verify.
levcs-merge/ Cascade engine, format and tree-sitter handlers,
plugin runtime, merge records.
levcs-protocol/ Pack codec, wire types, request signing, P2P.
levcs-client/ Thin HTTP client over the federation API.
levcs-instance/ Axum HTTP server (the federation peer).
levcs-cli/ The `levcs` user-facing CLI.
levcs-tui/ Conflict-resolution terminal UI.
deploy/ Production deployment artifacts (systemd, Caddy, nginx).
scripts/ Reproducible benchmark and ops scripts.
doc/ Technical report and architecture docs.
.github/workflows/ CI configuration.
Testing
cargo test --workspace
Runs the full suite — unit tests, integration tests, federation end-to-end tests including the three-instance "dogfood" scenario, the merge conformance corpus, and property-based fuzz tests. ~194 tests at v0.1.0; full run is well under a minute on a modern laptop.
Useful subsets:
# A single crate's tests
cargo test -p levcs-merge
# A specific integration test
cargo test -p levcs-instance --test dogfood
# Property tests only
cargo test -p levcs-merge --test proptest_textual
Benchmarks
Microbenchmarks live in each crate's benches/ directory and use
criterion. A reproducible runner with metadata capture and optional
flamegraph generation is at scripts/bench.sh:
scripts/bench.sh --quick # smoke test (~ a minute total)
scripts/bench.sh # full criterion run (~ a few minutes)
scripts/bench.sh --flamegraph # generate per-bench SVG flamegraphs
scripts/bench.sh --bench pack_codec # one bench only
Output goes to bench-results/<host>-<UTC-timestamp>/ with a parsed
summary.txt, criterion's HTML reports, and a metadata.txt capturing
rustc version, kernel, CPU, and git rev for run-to-run comparison.
Headline numbers on a Ryzen 7 laptop:
- Pack decode at 10 × 1 MiB entries: ~2.3 ms (4.3 GiB/s).
- Blob serialize + BLAKE3 at 1 MiB: ~190 µs (5.1 GiB/s).
- Textual three-way merge of a 100 KiB document: ~4.6 ms.
Pack encoding is the throughput floor at ~380 MiB/s — bottlenecked by zstd level 3 on incompressible data.
Documentation
doc/technical-report.md— Distribution document. What LeVCS is, how to use it, and how it differs from / improves upon git. Targets technical evaluators and the workflow-spec reader.deploy/README.md— Comprehensive VPS deployment walkthrough.spec/— The protocol specification and trust-root revision. Currently kept private; ask the maintainer for a copy.
Contributing
This is a young project. The most useful contributions right now are:
- Trying it. Run
levcs initon a real project, push to a local instance, and report friction. - Workflow design. The next major piece of work is the workflow spec — PR/review surface, issues, CI conventions. Discussion welcome.
- Plugin handlers. The wasm plugin protocol exists; concrete handlers (e.g. protobuf, SQL migrations) are needed to validate it.
- Tightening CI. The
fmtandclippyGitHub jobs are informational; flipping them to gating would close a small but real quality gap.
Please open an issue or reach out before starting non-trivial work so we can coordinate.
License
Released under the Apache License 2.0 — see LICENSE for the
full text.
Citation
If LeVCS supports academic work, please cite the v0.1.0 release. A formal citation entry will land with the workflow spec; in the meantime a repository-URL reference is fine.