Seal ignored-workspace routing at Domain startup

This commit is contained in:
ms2k 2026-07-30 00:52:58 +09:00
commit 1ad3b84db2

View file

@ -179,14 +179,17 @@ class IgnoredWorkspaceContractTests(unittest.TestCase):
self.assertEqual(transitions["cross-route-hard-link"]["result"], "EXDEV")
self.assertEqual(transitions["rename-whiteout"]["result"], "EOPNOTSUPP")
def test_transitions_never_copy_or_rebind_open_handles(self) -> None:
def test_transitions_copy_only_toward_isolated_state_between_generations(self) -> None:
transitions = load("contract.json")["transition_contracts"]
copying = [
transition["id"]
for transition in transitions
if "copy" in transition and transition["copy"] != "none"
]
self.assertEqual(copying, ["qualified-host-to-isolated-rename"])
self.assertEqual(
copying,
["qualified-host-to-isolated-rename", "host-to-ignored-policy"],
)
handle_transitions = {
transition["id"]: transition["open_handles"]
for transition in transitions
@ -194,11 +197,7 @@ class IgnoredWorkspaceContractTests(unittest.TestCase):
}
self.assertEqual(
handle_transitions,
{
"ignored-to-host-policy": "remain-isolated",
"host-to-ignored-policy": "remain-host",
"isolated-to-tracked-host-established": "remain-isolated",
},
{},
)
def test_isolated_only_force_add_is_explicitly_refused(self) -> None:
@ -251,19 +250,18 @@ class IgnoredWorkspaceContractTests(unittest.TestCase):
},
{
"id": "ignored-to-host-policy",
"trigger": "path becomes non-ignored without becoming tracked",
"trigger": "next Domain initialization classifies an isolated path as host-backed",
"new_lookups": "host-or-absent",
"open_handles": "remain-isolated",
"isolated_state": "retained-hidden",
"isolated_state": "deleted-before-readiness",
"copy": "none",
},
{
"id": "host-to-ignored-policy",
"trigger": "untracked path becomes ignored",
"new_lookups": "retained-isolated-or-absent",
"open_handles": "remain-host",
"host_state": "retained-hidden",
"copy": "none",
"trigger": "next Domain initialization classifies a host-backed path as ignored",
"new_lookups": "host-clone-or-absent",
"host_state": "retained-unchanged",
"isolated_state": "host-clone-replaces-stale-state",
"copy": "host-to-isolated-only",
},
{
"id": "isolated-to-tracked-guest-publication",
@ -273,22 +271,6 @@ class IgnoredWorkspaceContractTests(unittest.TestCase):
"isolated_state": "retained-visible",
"copy": "none",
},
{
"id": "isolated-to-tracked-host-established",
"trigger": "published index and type-compatible host object both exist",
"new_lookups": "host",
"open_handles": "remain-isolated",
"isolated_state": "retained-hidden",
"copy": "none",
},
{
"id": "isolated-to-tracked-unmediated-inconsistent",
"trigger": "unmediated index publication tracks a path without a host object",
"result": "EIO",
"path_state": "fail-closed-until-consistent",
"isolated_state": "retained-hidden-recoverable",
"copy": "none",
},
],
)
@ -372,7 +354,9 @@ class IgnoredWorkspaceContractTests(unittest.TestCase):
"concurrent-mutation",
"cross-policy-rename",
"ignored-to-tracked-transition",
"open-handle-transition",
"startup-sealed-policy",
"startup-policy-transition",
"host-to-isolated-copy",
"no-silent-loss",
"no-copy-back",
}
@ -384,7 +368,7 @@ class IgnoredWorkspaceContractTests(unittest.TestCase):
cases["cross-route-file-rename"]["expect"],
["EXDEV", "source-unchanged", "destination-absent"],
)
self.assertIn("isolated-object-recoverable", cases["unmediated-inconsistent-index"]["expect"])
self.assertIn("isolated-object-deleted", cases["unmediated-inconsistent-index"]["expect"])
self.assertIn("access-error-not-host-fallback", cases["router-loss-fails-closed"]["expect"])
self.assertIn("host-sentinel-unchanged", cases["router-loss-fails-closed"]["expect"])