Support durable host-to-isolated workspace migration

This commit is contained in:
ms2k 2026-07-26 00:43:30 +09:00
commit 0dda65fc2e

View file

@ -725,12 +725,41 @@ absence and retain the isolated entry hidden. Neither transition imports,
exports, merges, deletes, or otherwise copies content between backings.
A same-backing `rename` or hard link has the backing filesystem's atomicity and
error behavior. If the source and destination route to different backings,
`rename`, `RENAME_NOREPLACE`, `RENAME_EXCHANGE`, and hard link return `EXDEV`
before either backing is changed. `RENAME_WHITEOUT` returns `EOPNOTSUPP` without
mutation. Lazaret never reports a copy-and-unlink sequence as a successful
rename or a copied file as a hard link. Applications may react to `EXDEV` with
their own visible copy and unlink operations.
error behavior. An isolated-to-host rename, cross-backing hard link,
`RENAME_EXCHANGE`, or cross-backing rename outside the qualified
host-to-isolated class returns `EXDEV` before either backing is changed.
`RENAME_WHITEOUT` returns `EOPNOTSUPP` without mutation.
A plain or `RENAME_NOREPLACE` host-to-isolated directory rename is qualified
only when the destination is absent and the complete source tree was created
through the current router instance. Every retained source identity must still
match, and every descendant must be a regular file or directory with supported
metadata. A writable description beneath the source must be read-only or
quiesced by a completed flush; any later mutation clears quiescence. Pinned
read-only file and directory descriptions remain attached to their original
host objects. Host mutation detected before quarantine refuses the rename.
A qualified rename is a durable migration transaction rather than a
cross-filesystem `rename(2)`. The router records and synchronizes intent before
renaming the source to a reserved same-backing host quarantine. It synchronizes
that parent, copies through descriptor-confined traversal into a reserved
isolated staging tree, verifies the staged tree and quarantined source, and
synchronizes the isolated tree before publishing it with a same-backing rename.
Only a qualified isolated destination permits deletion of the exact
quarantined tree. The router synchronizes the host parent before clearing
intent.
The affected paths do not admit new observations while the transaction is
unresolved. Startup reconciles every retained intent before publishing router
readiness. Recovery exposes either the complete host source or the qualified
isolated destination; partial staging and changed quarantine remain
unpublished and fail closed. The transaction never copies isolated bytes into
the host backing. Its success refines the sandbox namespace to one complete
endpoint but does not promise cross-filesystem inode identity or atomic
observation by host processes that bypass FUSE.
All other cross-backing renames retain `EXDEV` behavior. Applications may react
to `EXDEV` with their own visible copy and unlink operations.
An index publication that would make an isolated object tracked is accepted only
when a type-compatible host worktree object already exists independently. The
@ -763,8 +792,9 @@ worktree-local index locking, linked worktrees, and nested repositories. These
operations retain Git's ordinary conflict and concurrent-writer behavior. Git
Sentry still makes host `.git/config` read-only and replaces default
`.git/hooks` with sandbox-local transient storage. Force-adding an isolated-only
path, cross-policy atomic rename, and device-node creation are refused as defined
above and are not compatibility promises.
path, cross-policy rename outside the qualified host-to-isolated class, and
device-node creation are refused as defined above and are not compatibility
promises.
The repository `lazaret-ignored-workspace-contract-v1` corpus is a
non-authoritative executable test inventory derived from these semantics. It