Seal ignored-workspace routing at Domain startup
This commit is contained in:
parent
b114e3514b
commit
1ad3b84db2
1 changed files with 720 additions and 285 deletions
|
|
@ -720,24 +720,34 @@ repositories, and `core.ignoreCase`. Non-UTF-8 path components are supported as
|
|||
opaque bytes; NUL and `/` retain their ordinary pathname meaning and cannot be
|
||||
components.
|
||||
|
||||
Each pathname operation uses one immutable classification snapshot. Publication
|
||||
of a changed index or ignore input serializes against new pathname operations and
|
||||
either installs one complete new snapshot or leaves the prior snapshot active.
|
||||
There is no partially updated matcher. Existing file descriptions, mappings,
|
||||
locks, and directory streams remain pinned to the backing object and snapshot
|
||||
under which they were opened. A subsequent lookup or open uses the current
|
||||
snapshot. Writes, flushes, locks, and mapping writeback through an old handle
|
||||
affect only its original backing object; a transition never rebinds a handle or
|
||||
copies its content to the other backing.
|
||||
Domain initialization reads and seals one complete classification snapshot before
|
||||
router readiness. Every pathname operation in that Domain generation uses the
|
||||
sealed snapshot. Changes to an ignore file, repository configuration, global
|
||||
excludes, nested-repository boundary, or Git index remain ordinary shared host
|
||||
mutations but do not change routing in the running generation. There is no live
|
||||
matcher publication and no partially updated matcher. File descriptions,
|
||||
mappings, locks, and directory streams remain pinned to their original backing
|
||||
objects for their lifetimes.
|
||||
|
||||
Directory lookup and enumeration expose only the entry selected by the current
|
||||
snapshot. An ignored host entry is hidden even when no isolated entry exists. A
|
||||
stale isolated entry is retained but hidden while its pathname is host-backed.
|
||||
On a non-ignored-to-ignored transition, subsequent lookups expose the retained
|
||||
isolated entry or absence and hide the host entry. On an
|
||||
ignored-to-non-ignored transition, subsequent lookups expose the host entry or
|
||||
absence and retain the isolated entry hidden. Neither transition imports,
|
||||
exports, merges, deletes, or otherwise copies content between backings.
|
||||
The router persists the admitted classification inputs in private Domain state.
|
||||
Before admitting a later generation it compares the prior and candidate
|
||||
classifiers across the host and isolated namespaces. A path ignored on first
|
||||
admission starts absent in isolated state; corresponding host material is never
|
||||
imported. A path that remains ignored preserves its isolated state. A path that
|
||||
changes from host-backed to ignored is cloned from the current host object into
|
||||
isolated state, replacing stale isolated state, while the host object remains
|
||||
unchanged. A path that changes from ignored to host-backed has its isolated object
|
||||
deleted before the host object or absence is exposed. Structural isolated
|
||||
directories may remain only where required to reach descendants that are still
|
||||
ignored.
|
||||
|
||||
Reconciliation completes before router readiness and publishes the candidate
|
||||
policy only after the host inputs copied by the transition remain stable. A
|
||||
failure or concurrent host mutation leaves the prior policy authoritative and
|
||||
the generation unadmitted; a later initialization retries from that policy.
|
||||
Recovery may repeat a clone or deletion, but never exports isolated bytes to the
|
||||
host. No open handle spans a policy transition because transitions occur only
|
||||
between Domain generations.
|
||||
|
||||
A same-backing `rename` or hard link has the backing filesystem's atomicity and
|
||||
error behavior. An isolated-to-host rename, cross-backing hard link,
|
||||
|
|
@ -792,17 +802,15 @@ 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
|
||||
router then selects that host object and retains the isolated object hidden; it
|
||||
does not compare, merge, or copy isolated bytes. A guest index-lock rename that
|
||||
would instead create a tracked path with only an isolated object returns `EBUSY`
|
||||
before replacing the index. If an unmediated host index change creates that
|
||||
state, pathname access to the inconsistent path fails with `EIO` until the host
|
||||
index/worktree tuple is made consistent or reverted. The isolated object remains
|
||||
recoverable Domain state. Consequently, ordinary add and commit are
|
||||
supported for host-backed paths, while force-adding an isolated-only path is an
|
||||
explicitly unsupported Git operation rather than implicit host copy-back or
|
||||
An index publication in a running generation that newly tracks any path routed to
|
||||
isolated state returns `EBUSY` before replacing the index, even when a
|
||||
type-compatible host worktree object exists. Accepting it would change the
|
||||
meaning of the shared index without changing the sealed route. Unmediated host
|
||||
index changes likewise do not change routing in the running generation. On the
|
||||
next initialization they participate in the candidate classifier and the same
|
||||
between-generation reconciliation rules apply. Consequently, ordinary add and
|
||||
commit are supported for host-backed paths, while force-adding a path routed to
|
||||
isolated state is explicitly unsupported rather than implicit host copy-back or
|
||||
silent disappearance.
|
||||
|
||||
The v1 operation contract supports lookup, bytewise directory enumeration,
|
||||
|
|
@ -829,9 +837,9 @@ promises.
|
|||
|
||||
The repository `lazaret-ignored-workspace-contract-v1` corpus is a
|
||||
non-authoritative executable test inventory derived from these semantics. It
|
||||
covers ignore precedence and live changes, non-UTF-8 and case-folded matching,
|
||||
covers ignore precedence and startup-sealed changes, non-UTF-8 and case-folded matching,
|
||||
linked worktrees and nested repositories, every operation class above,
|
||||
open-handle transitions, concurrent host and sandbox mutation, router loss, and
|
||||
generation transitions, concurrent host and sandbox mutation, router loss, and
|
||||
absence of silent loss or copy-back.
|
||||
Its benchmark protocol compares direct-host and routed placements using identical
|
||||
fresh fixture materialization and reports metadata, Git, offline package
|
||||
|
|
|
|||
Loading…
Reference in a new issue