Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions docs/MOUNT_TAXONOMY.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,15 @@ Mellumwork ternary / conflict-resolution-faithfulness machinery is paid *only* o
Add `reference mount (no copy)` as a fourth column on the intermittent-link box with the availability
precondition on the edge, and the two diagrams are one.

**The Needs firewall prunes the lattice first.** `backend_for` now takes `needs` +
`offline_tolerant` + `store_locality`, and two Needs forbid the cheap reference-mount *before* link
availability is even consulted: a **`no_egress`** Need on a **remote** store (a remote reference-mount
*is* egress → forced to a local copy), and **offline-tolerance** (a reference-mount has zero offline
capability → must cache locally even over a reliable link). A `no_egress` Need on a *local* store is
fine — a local mount is not egress. So the real signature is
`intent × link × durability × needs → backend`, and the Needs firewall and the mount lattice are one
plane, not two.

## The honest counterexample

The sandbox's root ext4 is simultaneously runtime image, scratch, cache, and working directory — the
Expand Down
24 changes: 20 additions & 4 deletions tools/data_sphere.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,13 +85,29 @@ def check_egress_invariant(mounts: list) -> dict:
else f"{len(egress)} egress mounts ({egress}); the invariant is at most one, named")}


def backend_for(*, intent: str, link_availability: str, durability: str) -> dict:
"""intent x link_availability x durability -> backend. The reconciliation burden is a function of
this product, not a property of the data. Over a reliable link: REFERENCE-mount (no copy)."""
def backend_for(*, intent: str, link_availability: str, durability: str, needs: dict | None = None,
offline_tolerant: bool = False, store_locality: str = "remote") -> dict:
"""intent x link_availability x durability x NEEDS -> backend. The reconciliation burden is a
function of this product, not a property of the data.

The Needs firewall prunes the lattice BEFORE link availability, because two Needs forbid the
cheap reference-mount outright:
* a `no_egress` Need on a REMOTE store — a remote reference-mount *is* egress, so it's
forbidden; the data must be copied local.
* offline-tolerance — a reference-mount has zero offline capability (cut the link, it fails),
so a workload that must survive link loss has to cache locally even over a reliable link.
Only after those prunes does link availability pick reference-mount vs copy+reconcile.
"""
needs = needs or {}
if needs.get("no_egress") and store_locality == "remote":
return {"backend": "local-copy", "copy": True, "reconciliation": durability == "canonical",
"note": "no_egress Need forbids a remote reference-mount (which IS egress) -> local copy"}
if offline_tolerant:
return {"backend": "local-cache", "copy": True, "reconciliation": durability == "canonical",
"note": "offline-tolerant: a reference-mount fails on link loss -> local cache"}
if link_availability == "reliable":
return {"backend": "reference-mount", "copy": False, "reconciliation": False,
"note": "mount it, don't sync it — no second copy, no divergence, no CRF machinery"}
# intermittent link -> forced into copy semantics
if durability == "canonical":
return {"backend": "copy+reconcile", "copy": True, "reconciliation": True,
"note": "intermittent + canonical: copy forces divergence -> conflict-resolution (SP-EVAL-CRF-001)"}
Expand Down
15 changes: 15 additions & 0 deletions tools/test_data_sphere.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,21 @@ def test_backend_lattice_reference_mounts_over_reliable_links():
assert derived["copy"] is True and derived["reconciliation"] is False


def test_needs_prune_the_lattice_before_link_availability():
# a no_egress Need on a REMOTE store: a remote reference-mount IS egress -> forbidden -> local copy
remote = ds.backend_for(intent="canonical", link_availability="reliable", durability="canonical",
needs={"no_egress": True}, store_locality="remote")
assert remote["backend"] == "local-copy" and remote["copy"] is True
# but a LOCAL store may still be reference-mounted under no_egress (a local mount is not egress)
local = ds.backend_for(intent="canonical", link_availability="reliable", durability="canonical",
needs={"no_egress": True}, store_locality="local")
assert local["backend"] == "reference-mount"
# offline-tolerance forbids reference-mount even over a reliable link (it fails on link loss)
off = ds.backend_for(intent="canonical", link_availability="reliable", durability="canonical",
offline_tolerant=True)
assert off["backend"] == "local-cache" and off["copy"] is True


if __name__ == "__main__":
import sys
fns = [v for k, v in sorted(globals().items()) if k.startswith("test_")]
Expand Down
Loading