# vfs

- `vfs` is generic filesystem infrastructure only. Do not add secure-exec sidecar, bridge, S3, SQLite, host-disk, or registry coupling here.
- The crate intentionally contains separate filesystem type universes under explicit modules while the consolidation is in progress. Do not glob-merge names that would confuse those boundaries.
- Concrete environment-bound backends belong in `secure-exec-vfs`.
- The `chunked` engine deliberately decouples the `MetadataStore` from the `BlockStore`: blocks are content-addressed, opaque, and self-describing only as a set, while the directory tree, inode table, chunk map, and refcounts live entirely in the metadata store. The engine makes **no self-containment promise** about either half. Pairing a block store with a metadata store, and ensuring the metadata store is durable and co-located with whatever lifecycle the blocks need, is the **caller's responsibility** (the sidecar plugin / client config that wires the backends), not the engine's. So e.g. an `S3BlockStore` backed by a local `SqliteMetadataStore` is a valid, intended configuration; the engine does not assume blocks carry enough information to reconstruct the tree, and "the metadata lives elsewhere than the blocks" is by design, not a defect. If a deployment needs the tree to survive loss of the local metadata, it must choose a durable metadata store (e.g. the callback backend) — that is a wiring decision, not an engine concern.
- The engine data plane (`chunked`/`object` engines, `MetadataStore`/`BlockStore`/`ObjectBackend` impls, `CachedMetadataStore`, and the `MountedEngineFileSystem` adapter) assumes **single-writer semantics**: one writer owns a given filesystem/mount at a time. Block refcounting, cache invalidation, and read-modify-write chunk edits are correct only under that assumption. There is no cross-process coordination, locking, or conflict resolution; concurrent writers against the same metadata/block backing store (e.g. two sidecars sharing one S3 prefix + SQLite file, or a shared callback store) can corrupt refcounts and orphan or double-free blocks. Do not rely on these engines for multi-writer/shared-storage scenarios without adding an external coordination layer.
- `MetadataStore::snapshot`/`fork` are intentionally not production-GC-ready yet. There is no snapshot deletion API, so snapshot-pinned block refs are permanent for now. Do not wire snapshot/fork into plugins that need block reclamation until snapshot lifecycle and persistent snapshot rows are implemented.
