Skip to content

Add content-addressed filesystem snapshots with labels and reflog#169

Open
r33drichards wants to merge 17 commits into
mainfrom
claude/dreamy-lovelace-hqfbt4
Open

Add content-addressed filesystem snapshots with labels and reflog#169
r33drichards wants to merge 17 commits into
mainfrom
claude/dreamy-lovelace-hqfbt4

Conversation

@r33drichards

Copy link
Copy Markdown
Owner

Summary

This PR introduces a complete filesystem snapshot system enabling content-addressed, versioned virtual filesystems mounted by human-readable labels. The system is independent of the heap snapshot mechanism and includes immutable content storage, mutable pointer management with reflog history, and garbage collection.

Key Changes

Core Filesystem Snapshot Infrastructure

  • fs_store.rs: Content-addressed object store for filesystem snapshots with two object types:

    • Chunks: plaintext-hashed file content with optional zstd compression
    • Manifests: immutable directory trees keyed by canonical bincode encoding
    • Hybrid storage: small files inlined in manifest entries, large files split via FastCDC content-defined chunking
  • fs_labels.rs: Mutable pointer plane managing human-readable labels:

    • Per-label append-only reflog enabling rollback to any prior snapshot
    • Linearizable compare-and-set (CAS) operations via in-process mutex (single-node) or Raft leader coordination (cluster mode)
    • Persistence via sled database mirroring heap_tags.rs pattern
  • fs_mount.rs: Userspace overlay mount implementation:

    • Read-only pinned base manifest plus mutable upper write layer
    • pull() pins a base CA id at mount time so concurrent label moves don't shift running sessions
    • push() flushes upper layer over base into new pure manifest, returning its CA id
  • fs_chunker.rs: Content-defined chunking with FastCDC:

    • Files ≤64KB inlined directly in manifest (no blob round-trip)
    • Larger files split into content-defined chunks with plaintext-based dedup
    • Configurable chunk parameters (256KB min, 1MB avg, 4MB max)
  • fs_gc.rs: Mark-and-sweep garbage collection:

    • Roots: current label heads plus reflog entries within retention window
    • Configurable retention: KeepAll or KeepLast(n) per label
    • Safety: reset snapshots remain reachable through reflog until pruned

API & Integration

  • HTTP API (/api/fs/labels, /api/fs/push, /api/fs/reset, etc.):

    • List labels with head CA ids
    • Resolve labels to current CA ids
    • Push with reject-and-rebase (default) or force semantics
    • Reset with reflog validation
    • View per-label reflog history
  • MCP Tools: fs_ls, fs_pull, fs_label, fs_log, fs_push, fs_reset

  • CLI Commands: fs ls, fs pull, fs label, fs log, fs push, fs reset

  • Execution Integration:

    • ExecRequest.fs parameter (label name or 64-hex CA id)
    • ExecutionInfo.fs field for resulting snapshot CA id
    • ExecutionConfig.fs_mount for session overlay mount
    • FsMountHandle injected into OpState for fs ops delegation

Engine & Storage

  • engine/mod.rs:

    • New modules: fs_chunker, fs_gc, fs_labels, fs_mount, fs_store
    • Helper functions: parse_ca_hex(), ca_to_hex(), refop_str()
    • Response types: FsLabelView, FsRefLogView, FsPushOutcome
  • heap_storage.rs: Extended trait with list() and delete() methods for GC support; added MemoryHeapStorage for tests

  • fs.rs: Modified to support overlay mount delegation via FsMountHandle in OpState

  • Cluster support (cluster.rs): Added CasRequest/CasResponse for linearizable compare-and-set through Raft leader

Configuration & CLI

  • --enable-fs-snapshots: Enable the feature
  • --fs-store-dir: Override blob store

https://claude.ai/code/session_01HBS599o4kykxLfNTWojNVw

@github-actions

Copy link
Copy Markdown

🦀 mcp-v8-client Built Successfully

Package: mcp-v8-client
Version: 0.1.0-beta.169.05d17da

Add as dependency

[dependencies]
mcp-v8-client = { git = "https://github.com/r33drichards/mcp-js", branch = "claude/dreamy-lovelace-hqfbt4" }

CLI (from this branch)

cargo install --git https://github.com/r33drichards/mcp-js --branch claude/dreamy-lovelace-hqfbt4 mcp-v8-client

claude added 2 commits June 14, 2026 11:05
Add fs_merge: a flat per-path 3-way merge of two snapshot manifests
(à la Mercurial manifestmerge, since our manifest is a flat content-
addressed map). A clean merge yields a new snapshot CA id; divergent
paths are reported as a structured base/ours/theirs conflict list.
An optional common base makes it 3-way (only paths both sides changed
conflict); without it the merge is 2-way. prefer=ours|theirs opts into
auto-resolution. Exposed as the fs_merge MCP tool, POST /api/fs/merge,
and mcp-v8-cli fs merge.

Renames, chunk-level/line content merge, and CRDT semantics are out of
scope (documented), matching how git/Mercurial/Irmin model tree merge.
@github-actions

Copy link
Copy Markdown

🦀 mcp-v8-client Built Successfully

Package: mcp-v8-client
Version: 0.1.0-beta.169.244e063

Add as dependency

[dependencies]
mcp-v8-client = { git = "https://github.com/r33drichards/mcp-js", branch = "claude/dreamy-lovelace-hqfbt4" }

CLI (from this branch)

cargo install --git https://github.com/r33drichards/mcp-js --branch claude/dreamy-lovelace-hqfbt4 mcp-v8-client

@github-actions

Copy link
Copy Markdown

🦀 mcp-v8-client Built Successfully

Package: mcp-v8-client
Version: 0.1.0-beta.169.95508fe

Add as dependency

[dependencies]
mcp-v8-client = { git = "https://github.com/r33drichards/mcp-js", branch = "claude/dreamy-lovelace-hqfbt4" }

CLI (from this branch)

cargo install --git https://github.com/r33drichards/mcp-js --branch claude/dreamy-lovelace-hqfbt4 mcp-v8-client

When a path conflicts structurally, dispatch on detected content type
(Irmin-style mergeable types): text files get a line-level 3-way merge
via diffy, so edits to different lines of the same file auto-merge
cleanly. Genuine same-line clashes are reported with kind, diff3
conflict markers, and unified diff_ours/diff_theirs for line-level
resolution. Binary and SQLite content are detected and reported as
whole-file conflicts behind a pluggable ContentMerger registry — the
extension point where a SQLite changeset driver can later plug in.

fs_merge now content-merges conflicts before reporting them; the pure
merge core returns (merged, conflicts) so the store-aware pass can
reconcile bytes. Surfaces (MCP/HTTP/CLI) and docs updated.
@github-actions

Copy link
Copy Markdown

🦀 mcp-v8-client Built Successfully

Package: mcp-v8-client
Version: 0.1.0-beta.169.b327618

Add as dependency

[dependencies]
mcp-v8-client = { git = "https://github.com/r33drichards/mcp-js", branch = "claude/dreamy-lovelace-hqfbt4" }

CLI (from this branch)

cargo install --git https://github.com/r33drichards/mcp-js --branch claude/dreamy-lovelace-hqfbt4 mcp-v8-client

The Nix docs build vendors crates from server/Cargo.lock in offline
mode; it lacked the fs-snapshot deps (fastcdc/zstd/blake3/bincode/diffy),
failing with 'no matching package named blake3'. Regenerate the
standalone lock (also drops the now-unused native-tls/openssl stack,
since reqwest uses rustls-tls). Vendor hash is a placeholder pending the
real value from CI.
@github-actions

Copy link
Copy Markdown

🦀 mcp-v8-client Built Successfully

Package: mcp-v8-client
Version: 0.1.0-beta.169.9cb0f94

Add as dependency

[dependencies]
mcp-v8-client = { git = "https://github.com/r33drichards/mcp-js", branch = "claude/dreamy-lovelace-hqfbt4" }

CLI (from this branch)

cargo install --git https://github.com/r33drichards/mcp-js --branch claude/dreamy-lovelace-hqfbt4 mcp-v8-client

@github-actions

Copy link
Copy Markdown

🦀 mcp-v8-client Built Successfully

Package: mcp-v8-client
Version: 0.1.0-beta.169.df3ba3b

Add as dependency

[dependencies]
mcp-v8-client = { git = "https://github.com/r33drichards/mcp-js", branch = "claude/dreamy-lovelace-hqfbt4" }

CLI (from this branch)

cargo install --git https://github.com/r33drichards/mcp-js --branch claude/dreamy-lovelace-hqfbt4 mcp-v8-client

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants