Skip to content

feat(inception-mount): owned FUSE-free FS seam + Linux btrfs versioning substrate - #11

Open
mdheller wants to merge 4 commits into
mainfrom
feat/inception-mount
Open

feat(inception-mount): owned FUSE-free FS seam + Linux btrfs versioning substrate#11
mdheller wants to merge 4 commits into
mainfrom
feat/inception-mount

Conversation

@mdheller

@mdheller mdheller commented Aug 3, 2026

Copy link
Copy Markdown
Member

Homes inception-mount in SourceOS as src/inception-mount/ — it is an OS + managed-network concern, not a platform concern: the privileged snapshot/replication layer is OS-resident.

What this is

One owned go-billy FileSystem seam (fs.InceptionFS) that decorates any backend with fail-closed capability leases + hash-chained receipts + warrant-typed content, served two ways with no macFUSE / no FUSE:

Face Transport Privilege
Agent / pod in-process VFS (no mount() syscall) none — legal in a restricted-PSA pod
Human / userland userspace NFSv3 on loopback (willscott/go-nfs), OS-native mount; FSKit (macOS 26+) successor serving unprivileged; the human's own sudo mount grants it

The pod face is the answer to "mount unprivileged inside our isolation contract": you don't mount — you serve the VFS in-process.

Linux btrfs substrate (ADR-0002)

backend.Snapshotter: a governed Commit freezes an immutable, receipt-pinned Version.

  • BtrfsSnapshotter (//go:build linux) — btrfs subvolume snapshot -r, id = UUID:generation. The privileged op lives in the owned OS mounter daemon, not the pod (that's why this is a SourceOS concern). Managed-network replication = btrfs send -p | receive. Cross-compiles linux/amd64 + linux/arm64.
  • DevSnapshotter (portable) — content-hash + read-only tree copy; identical contract so the seam/receipts/tests run on macOS/CI.
  • Owned Go path: dennwc/btrfs (Apache-2.0) replaces the btrfs shell-out. Snapshots pin provenance (bind-at-capture).

Validated

go vet clean; go test ./... green on macOS:

  • agent face — read allowed, write fail-closed denied, no-lease/cross-space denied, receipt chain verified;
  • versioning — distinct immutable versions, receipt-pinned, read-only lease cannot commit;
  • userland face — governed NFSv3 server stands up unprivileged on loopback;
  • full NFS-client wire read + denied write — root-gated (client lib dials portmap :111; the kernel mount_nfs -o port= path needs no privileged server), skipped otherwise.

btrfs runtime proof runs on a Linux/btrfs node (can't run btrfs on the macOS dev host); the path is cross-compiled here.

Notes for review

  • Nested Go module under src/inception-mount/isolated from the COSA/nix OS image build, no root go.mod.
  • Deps: go-git/go-billy (Apache-2.0), willscott/go-nfs + go-nfs-client (Apache-2.0), x/net (BSD-3) — all within the MIT/Apache(+cataloged-BSD) gate; re-verify at pin.
  • go get floated the module's go directive to 1.25 — pin deliberately before first release.
  • ADRs: src/inception-mount/docs/ADR-0001 (seam) and ADR-0002 (btrfs).

Next

Swap btrfs shell-out for dennwc/btrfs; wire send/receive replication + snapshot retention (bounded fail-closed loop); real backends over trit-pack / HellGraph / zot; FSKit Swift module; runtime proof on a Linux/btrfs node.

mdheller added 4 commits August 3, 2026 05:56
…ng substrate

inception-mount lives in SourceOS because it is an OS + managed-network concern,
not a platform concern: the privileged snapshot/replication layer is OS-resident.

One owned go-billy FileSystem seam (fs.InceptionFS) with fail-closed capability
leases + hash-chained receipts, served two ways, macFUSE-free:
  - agent/pod face: in-process VFS — no mount() syscall, no CAP_SYS_ADMIN, legal
    inside a restricted-PSA pod.
  - human/userland face: userspace NFSv3 on loopback (willscott/go-nfs), mounted
    by the OS-native client; FSKit (macOS 26+) is the native successor.

Versioning substrate (backend.Snapshotter): a governed Commit freezes an
immutable, receipt-pinned Version.
  - BtrfsSnapshotter (linux): `btrfs subvolume snapshot -r`, id = UUID:generation;
    the privileged op belongs in the OS mounter daemon. Cross-compiles amd64+arm64.
  - DevSnapshotter (portable): content-hash + read-only tree copy, same contract,
    runs on macOS/CI.

Validated (ADR-0001 seam, ADR-0002 btrfs): both faces + fail-closed governance +
receipt chain + distinct immutable versions green on macOS; btrfs path cross-
compiles for Linux; full NFS-client wire round-trip is root-gated. Nested Go
module under src/, isolated from the OS image build.
…receive

Replace the btrfs shell-out with the owned pure-Go library (dennwc/btrfs,
Apache-2.0) and add the two OS-daemon capabilities the managed-network face needs:

- Snapshotter (linux): SnapshotSubVolume(ro), id = UUID:generation via
  SubvolumeByPath — no distro-binary dependency.
- RetentionPolicy: pure, fail-safe (zero policy prunes nothing) keep-last +
  keep-since planner; Pruner (BtrfsPruner=DeleteSubVolume / DevPruner=RemoveAll);
  Apply is fail-closed on first delete error.
- Replicator: BtrfsReplicator (Send -p parent / Receive) = the managed-network
  face; DevReplicator (tar) for portable round-trip.

All btrfs impls are //go:build linux (privileged, OS-daemon only) with non-linux
stubs; cross-compile linux/amd64 + linux/arm64. Portable dev impls + pure
retention logic tested green on macOS (keep-last/keep-since/zero, prune apply,
replicate round-trip). go pinned 1.25.0 — required by go-git/go-billy v5.9.1.
…/prune

Runtime proof of the Linux substrate against a real btrfs mount: create
subvolume, seed, BtrfsSnapshotter.Snapshot (asserts read-only + UUID:generation
id), BtrfsReplicator send/receive (asserts replicated content), BtrfsPruner
delete (asserts gone). Self-skips unless INCEPTION_BTRFS_ROOT points at a btrfs
mount and euid==0, so 'go test ./...' stays portable.

PASSED on Fedora kernel 7.1.3 / btrfs-progs v6.14 (podman rootful, loopback btrfs):
snapshot id=68e27515-...:10, send/receive verified, prune confirmed.
…l-closed)

Add the retention daemon loop over the Snapshotter/Pruner substrate — a GOVERNED
loop, not a DAG (loops-vs-DAGs doctrine):
- VersionStore.List() — DevSnapshotter (store dir, Created=mtime) and
  BtrfsSnapshotter (snapDir subvolumes, id=UUID:generation, Created=btrfs OTime).
- Retainer.Tick — bounded (<= MaxPrunePerTick), never past the policy plan,
  FAIL-CLOSED (List error prunes nothing; Prune error stops); zero policy prunes
  nothing. Retainer.Converge runs to within-policy under an explicit tick bound.

Tested green on macOS (bounded, convergent, zero-policy-safe, list-error fail-
closed); btrfs List cross-compiles linux amd64+arm64.
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.

1 participant