# Riftri architecture ## Objective Riftri makes ordinary Git linked worktrees copy-on-write. It is not a source control system and it does not introduce a second workspace abstraction. The central rule is: > Riftri participates in setup and cleanup; the native filesystem handles the > normal read/write path. ## Opt-in modes Riftri is never a global Git replacement by default. 1. Explicit operation: `riftri worktree add ...` 2. Repository opt-in plus process-scoped activation: `riftri enable`, then `riftri exec -- claude`, optionally with `--worktree ` 3. Repository opt-in plus explicit shell activation: evaluate `riftri shell hook zsh` or `riftri shell hook powershell`, then use normal `git` commands The process-scoped mode places a small Git shim at the front of `PATH` only for the selected process and its children. Repository consent is stored in local Git configuration as `riftri.enabled=true`. Normal Git commands and all commands in repositories without that marker are immediately delegated to the exact real Git executable resolved before the shim is installed. Supported worktree adds in enabled repositories are routed through Riftri. `RIFTRI_BYPASS=1` provides an explicit escape hatch to ordinary Git without disabling the repository. `riftri exec --worktree -- ` is an agent-neutral convenience for binding the child process to an existing worktree. Riftri canonicalizes the path, requires it to equal the repository root, and confirms that root is a live entry in Git's structured worktree inventory before launching the command. The binding does not imply repository enablement and does not create a new workspace abstraction. The shell hook installs a versioned shim in the user's cache and prints environment assignments for sh/bash/zsh or PowerShell. Unix uses an executable link; Windows atomically installs a real `git.exe` copy so child processes do not depend on command-wrapper semantics. Evaluating those assignments puts the shim first on `PATH` for that shell and its descendants. The hook is never evaluated automatically and Riftri never edits shell startup files. Once it is active, `riftri enable` and `riftri disable` are the repository-specific switch; disabled repositories and commands outside repositories still delegate to the real Git executable captured before `PATH` changes. A user may deliberately put the hook evaluation in a shell profile, which globally activates the shim for that user's new shells, but this does not globally enable optimization: repository-local consent is still required. `riftri shell status` reports the two independent activation layers and whether they combine into effective optimized interception for a selected repository. `riftri shell deactivate ` prints code that removes every Riftri shim-directory occurrence from `PATH` — the durable cached shim and any process-scoped `riftri exec` shim entries — and unsets Riftri's shim environment in the current shell when explicitly evaluated. It does not change repository configuration or edit a shell profile, so persistent global activation remains under the user's direct control. The shim accepts optimized `worktree add` with an existing local branch, `-b `, or `--detach` and routes the ordinary no-option `worktree remove ` and `worktree move ` forms through Riftri when the target has an active Riftri add journal. A no-option `worktree prune` first verifies that every managed view is present and registered. Move and prune progress is durable and recoverable. Unsupported add forms fail before mutation instead of silently falling back to a full checkout. Lifecycle options continue to use Git for unmanaged worktrees but fail closed when they could mutate managed Riftri state outside a supported journal. ## Components ### CLI and Git shim The CLI exposes diagnostics and explicit operations. The optional shim preserves the `git worktree` user experience inside an activated process or shell while repository-local configuration controls whether an add is optimized. `riftri worktree list` derives its read-only managed inventory from validated active add journals and Git's NUL-delimited worktree inventory. Its JSON schema includes readable paths and refs plus exact native-path and raw-ref hexadecimal encodings, so machine output does not discard non-UTF-8 identities. The npm distribution layer does not implement product behavior. Its launcher selects an exact platform package, executes the Rust CLI, and preserves the native process result. Platform packages are optional dependencies so npm only installs the applicable binary. Missing or unsupported native packages fail visibly; the launcher never substitutes an ordinary JavaScript implementation. ### Git coordinator The coordinator invokes the installed Git executable. Git remains responsible for linked-worktree metadata, per-worktree `HEAD` and index files, branch rules, configuration, filters, and hooks. ### Immutable base cache A base represents the checked-out files for an exact Git tree and checkout profile. Bases are immutable and shared by compatible worktrees. They are keyed by repository identity, tree object ID, checkout profile, and filesystem volume. Repository identity is the platform-native path to Git's common directory, so a main worktree and all linked worktrees resolve to the same repository. Object IDs are validated as SHA-1 or SHA-256 hex values returned by the real Git process. The checkout profile is a versioned, canonical sequence of raw byte key/value inputs. The collector must account for every external input that can change checkout results, including line-ending configuration, external attributes, filter drivers, and sparse-checkout configuration. In-tree attributes are already covered by the exact tree ID. If Riftri cannot account for an active external input, it must reject optimized creation rather than reuse an ambiguous base. Optimized creation suppresses Git's checkout, which also suppresses its `post-checkout` hook. Until hook execution has a recoverable transaction design, Riftri refuses creation before mutation when an executable default `post-checkout` hook is present. Custom `core.hooksPath` configurations are also refused: relative paths can refer to hooks in the destination tree rather than the invoking worktree. Doctor reports the same blocker. Use ordinary `git worktree add` when checkout hooks are required; Riftri never silently skips them or automatically falls back to a full checkout. The current native COW policy asks Git to resolve attributes from the exact requested tree through an isolated temporary index. Built-in `text`, `eol`, and `binary` checkout semantics are allowlisted; `diff` and `merge` records emitted by the built-in binary macro are checkout-neutral. A narrow Git LFS profile is also supported when each affected path resolves to the canonical `filter=lfs diff=lfs merge=lfs -text` quartet, the installed filter configuration is standard, and the strict v1 pointer names an exact object in the repository's default local LFS store. Repository-local, global, and system attribute sources remain unsupported because they are mutable outside the tree identity. An explicit `riftri worktree add --sparse-dir` request selects a cone-mode sparse view. The canonical directory list — sorted, deduplicated, and with nested cones collapsed into their ancestors — is an additional checkout-profile input, so different sparse selections at one tree, or a sparse and a full request, always key different bases. Git's own `sparse-checkout set --cone` runs inside the isolated materialization directory to compute the patterns and skip-worktree bits, `checkout-index` writes only the active entries, and the new linked worktree receives real worktree-scoped sparse configuration before its clean state is verified. Anything outside that subset — patterns, nonexistent directories, repository-configured sparse checkout, sparse requests through Git interception, sparse plus Git LFS, or compaction of a sparse view — fails closed before durable state exists (see [sparse-checkout.md](sparse-checkout.md)). Git materializes the exact pointer tree inside Riftri's isolated administrative directory, where inherited filters are intentionally disabled. Riftri then opens each validated local LFS object without following links, checks its exact size and SHA-256 while streaming it into the base staging tree, and only then allows the immutable base rename and completion marker. Riftri never downloads an LFS object during a worktree transaction. The checkout profile includes the Git LFS version, standard filter configuration, native path, object ID, and size, so older or semantically different bases cannot be reused. ### Storage engine The storage engine selects the fastest supported native primitive: - macOS: APFS clones. - Linux: reflinks where supported, otherwise kernel OverlayFS. - Windows: ReFS block cloning where supported, with later native alternatives. - Unsupported configuration: explicit ordinary-worktree fallback. FUSE and network filesystems are not part of the default hot path. Capability results have three meanings: - `supported`: conservative inspection or an artifact-clean active probe establishes that the destination supplies the primitive; - `unsupported`: the inspected destination is incompatible; and - `unavailable`: Riftri cannot establish a reliable answer without a later active probe or because inspection failed. The destination itself may not exist. Probing uses its nearest existing ancestor to identify the volume. A full-copy result is always marked as requiring an explicit fallback policy, even when the volume could hold an ordinary Git worktree. ### State and recovery Versioned JSON add-operation journals are written atomically and preserve native path units. They are the current recovery authority for APFS, Linux reflink, Linux OverlayFS, and Windows ReFS views. The version 1 format has a backward-compatible OverlayFS extension that is valid only when the selected backend is OverlayFS. It records the exact `overlays/v1/` private-layer root, a 256-bit hexadecimal recovery token before mount mutation, and the boot/namespace/mount identity after a mount succeeds. Older journals omit this extension and continue to decode with their existing backend semantics. The journals and immutable-base completion markers are the current durable registry for bases, views, and mounts. Reference counts and storage accounting are derived from them. Any future indexed registry must be rebuildable from this state rather than becoming a competing recovery authority. The default state directory remains `/riftri`. When an explicit operation places state elsewhere, Riftri records the canonical absolute path as a multi-valued `riftri.stateDirectory` entry in repository-local Git configuration before recording operation intent. The Git shim consults the default and every registered state directory when routing remove, move, and prune operations. Missing or malformed registered locations fail closed. Bases and mutation journals remain on the destination's COW-capable volume; the Git configuration entry is only a small discovery locator. ## Worktree-add transaction For an enabled `git worktree add ` operation, the intended sequence is: 1. Resolve the requested revision and Git tree using real Git. 2. Validate potential exact-tree case and Unicode aliases at the destination, then probe its filesystem capabilities. 3. Create the real linked-worktree metadata with checkout suppressed. 4. Find or build an immutable base for the exact Git tree. 5. Create a private writable layer or native clone at the requested path. 6. Restore the linked worktree's `.git` pointer in the visible view. 7. Populate or refresh the per-worktree index. 8. Verify that `git status` reports the expected clean state. 9. Atomically record the operation as active. Existing-branch requests resolve and validate the exact local branch before mutation. Git attaches that branch while holding Riftri's repository metadata lock, and Riftri verifies the attached HEAD still equals the preflight commit before materializing its tree. A moved or already-checked-out branch therefore fails through Git's normal safety rules and the journaled rollback path; Riftri never deletes a branch it did not create. Failures are rolled back from an operation journal. Riftri must not silently fall back to a full copy unless the user explicitly allows that policy. An in-memory scan first identifies paths or directory prefixes that differ only by ASCII case, or any path containing non-ASCII native units. For those trees, Riftri uses an artifact-clean, metadata-only probe in the destination's existing parent. It creates the tree's directory and leaf names inside a unique temporary directory without materializing file contents, so the actual filesystem decides whether the aliases coexist. A collision is rejected before Riftri creates state, a journal, a branch, or linked-worktree metadata. Successful probes are removed before backend selection, and ASCII-only trees without case aliases pay no per-file probe I/O. Non-ASCII trees incur the name-only probe because filesystem Unicode comparison rules cannot safely be approximated by language-level case folding or normalization. Unix names are never decoded lossily. Calls that mutate Git's shared linked-worktree administration are serialized by a repository-local Riftri lock. Base construction and native view cloning stay outside that critical section, so parallel adds share immutable preparation without racing Git's `worktrees/` metadata. ## Add-operation journal state machine An add holds an exclusive `operations/.lock` from before its first journal write through activation or rollback. Repair tries this lock without waiting, reports busy adds as skipped, and reloads the journal after acquiring ownership. This distinguishes a live creator from an interrupted operation and serializes competing add-recovery attempts. The lock file remains beside its journal to avoid replacing an inode another process has opened; closing the handle or process termination releases ownership. Legacy idle journals obtain the same lock on first repair. Concurrent coordinators must all use the lock-aware protocol; an older running binary cannot honor a new lock. The version 1 add journal advances through these durable states: ```text intent-recorded -> git-metadata-created -> base-ready -> view-created -> git-pointer-restored -> index-synchronized -> clean-verified -> active ``` Every incomplete forward state may transition to `rollback-pending`, followed by `rolled-back`. `active` and `rolled-back` are terminal for an add operation. Rollback checks staged index changes separately from working-file bytes, including intent-to-add and conflicted entries. An existing index is never reset to make a failed creation appear clean. If the index is absent and the view still matches its exact base, real Git builds a replacement index in a temporary file; installation cannot overwrite an index created concurrently. This also covers a crash after Git initialized the index but before the `index-synchronized` journal transition was persisted. ## Removal-operation journal state machine Removal uses separate journals under `removals/`: ```text intent-recorded -> clean-verified -> worktree-removed -> base-released -> complete ``` Clean removal validates cleanliness before recording intent and rechecks it when resuming before Git removes a still-registered view. Git performs that path without `--force`, so a concurrent dirtying write is also rejected. An explicit forced removal snapshots the complete native view, or the complete OverlayFS private layer, before recording durable intent. The journal records both the force choice and snapshot. The snapshot includes Git HEAD, its symbolic branch, and structured staged index contents (including intent-to-add state). Index stat-cache refreshes do not change this consent. OverlayFS reads Git metadata through its private upper-layer pointer while the merged view is unmounted. Legacy content-only force snapshots cannot prove this Git state and are preserved for manual inspection rather than automatically completing a pending deletion. Riftri revalidates the combined snapshot at the final delete boundary and during recovery; any later change stops the operation and is preserved. Only a still-present native view whose snapshot matches reaches Git's force removal. Missing-path metadata cleanup continues through ordinary Git safety checks, so recreating the destination cannot turn old force consent into deletion of a new path. A missing view plus missing Git registration is treated as an idempotently completed removal step. Inconsistent or changed paths are preserved for manual attention. Snapshot comparison is a final revalidation boundary, not a write lock against a process already holding an open file descriptor. ## Move-operation journal state machine Managed moves use separate journals under `moves/`: ```text intent-recorded -> worktree-moved -> add-journal-updated -> complete ``` Git performs the directory and administrative-metadata move. Recovery accepts only an intact registered source or an intact registered destination, preserves all inconsistent states, and atomically relocates the active add-journal reference. The source and destination must be on the same native COW-capable volume. If a move journal is incomplete, Riftri rejects removal, forced removal, compaction, and another move of that managed worktree. This keeps the worktree intact for `riftri repair`, including after Git rejects a locked worktree move. ## Compaction-operation journal state machine Explicit compaction of a pristine native-COW view uses a separate journal under `compactions/`: ```text intent-recorded -> replacement-ready -> replacement-activated -> add-journal-updated -> complete ``` Before recording intent, Riftri requires an active managed Git registration, the expected HEAD, and an empty structured status including ignored paths. It snapshots names, kinds, bytes, modes, symlink targets, Unix extended attributes, and Windows file attributes across the complete view. Unix setuid, setgid, and sticky bits are not represented by Git trees; compaction refuses entries carrying these special bits, including during recovery, rather than dropping them. Ordinary-mode snapshot compatibility is unchanged. macOS extended ACLs and ACL-wide inheritance flags also fail closed: Git cannot reconstruct them and they are not visible through xattr enumeration. Native ACL inspection does not follow symlink targets; unreadable ACLs stop the operation. This guard also preserves a quarantined view if an ACL appears before recovery cleanup, including for older compaction journals. Windows alternate data streams fail closed. Riftri then prepares or reuses the exact current-tree base, creates a fresh native COW replacement, and copies the real linked-worktree pointer into it. Immediately before the same-parent directory swap, Riftri revalidates registration, HEAD, strict cleanliness, and the snapshot. The old view is quarantined until the active add journal points at the new base; its snapshot is checked again before deletion. Recovery cancels intent-only work and restores a quarantined original when the replacement was not activated. Once activation occurred it moves forward, updates the add journal idempotently, and removes only the exact journaled quarantine. Pending compactions protect both old and new bases from garbage collection. OverlayFS compaction remains separate future work because resetting a mounted private upper requires mount-identity-aware handling rather than a native directory clone and rename. ## Prune-operation journal state machine Managed-state pruning uses separate journals under `prunes/`: ```text intent-recorded -> git-metadata-pruned -> complete ``` Before invoking Git, Riftri verifies that every active managed view exists and is registered and that no add, removal, move, or compaction is incomplete. Repeating Git's prune after an interruption is safe because managed registrations are revalidated first. ## Base-collection journal state machine Garbage collection is read-only unless the user passes `--apply`. Each selected zero-reference base then uses a separate journal under `collections/`: ```text intent-recorded -> marker-removed -> base-quarantined -> complete ``` An operation may instead become `cancelled` if reference revalidation finds a live or incomplete add. Collection takes the same per-base lock as construction, reloads add and removal journals under that lock, and treats every non-rolled-back add without a completed removal as a reference. The completion marker is removed before the base is made writable for atomic quarantine, preventing another add from reusing a base once collection starts. Recovery deletes only the exact journaled quarantine path and leaves a newly rebuilt base untouched. Before Milestone 2 performs its first mutation, journal persistence must write the intent first and replace each state atomically using a temporary file, `fsync`, rename, and parent-directory `fsync` where the platform supports them. The persisted path encoding must round-trip platform-native paths, including non-UTF-8 Unix bytes. Recovery may repeat the cleanup associated with a recorded state, so every rollback action must be idempotent and validate its exact target. The per-operation journal remains the crash-recovery authority while an add is incomplete and the durable lifecycle record after activation. The APFS prototype builds bases only from exact Git objects through an isolated temporary index. A SHA-256 repository bucket, tree object ID, restricted checkout profile version, and same-volume state placement implement the base-key boundaries. A per-base file lock serializes construction, atomic rename exposes the finished tree, and a synced completion marker prevents reuse of a partially prepared base. Existing-base verification uses shared ownership of that same stable per-base lock. Each reader still recomputes the integrity digest, but concurrent cache hits no longer serialize their reads. A missing or incomplete base releases the read lock, obtains exclusive ownership, and revalidates all state before reuse or rebuilding. It never upgrades a held read lock in place. Collection remains exclusive and rechecks durable references, which protect live and incomplete adds after the preparation lock is released. No cache format, integrity check, or journal durability step changes. Native `clonefile` is used for every regular file in an APFS view. An error is returned if APFS cannot clone; there is no byte-copy path. Directory structure, symlinks, and executable modes are preserved. The base is made read-only and the cloned view restores owner write permission before Git index synchronization. On APFS, permission restoration is part of the per-entry clone traversal rather than a second directory walk. It reads each cloned file's actual mode before adding owner write permission, leaves symlink targets alone, and uses the same directory mode policy and failure cleanup. Linux and ReFS retain their existing two-pass implementation. Immutable-base integrity verification, journal transitions, Git index initialization, and final clean-state checks are unchanged. On Linux, Riftri accepts Btrfs and reflink-enabled XFS only after an active `FICLONE` check succeeds on two unnamed files in the destination volume. The unnamed probe cannot leave a path behind after interruption. Every regular file in the view is then created with `FICLONE`; an unsupported ioctl aborts and rolls back instead of copying bytes. Linux uses the same immutable-base lock, add and removal journals, clean-state verification, recovery, accounting, and explicit garbage collection as APFS. OverlayFS capability probing creates lower, upper, work, and merged directories on the destination volume, then forks a short-lived child into a private mount namespace. Before probing, the child closes every inherited descriptor except its result pipe and immutable lower payload, including standard streams. The fork-only child cannot rely on close-on-exec flags: unrelated descriptors can pin another thread's mount or lock. It uses `close_range` where available and a raw, allocation-free `/proc/self/fd` scan otherwise; inability to isolate the descriptor table fails the probe before any mount. Parent descriptors remain untouched. The child mounts OverlayFS with explicit rootless-compatible options, verifies lower reads and private copy-up writes, unmounts, and reports the exact failing stage and operating-system error. After namespace isolation, the child resolves the private probe root as a native byte path in the new namespace and mounts fixed relative layer names. Commas, colons, spaces, long paths, and non-UTF-8 bytes in the destination therefore never become mount-option syntax. The caller's mount namespace is never changed and the parent removes the probe directory. A separate caller-namespace probe performs the same read, copy-up, isolation, and cleanup checks without namespace isolation. Core must require that stricter result before selecting a persistent backend, because success in an isolated child does not prove that ordinary Git processes can see a durable mount. Both persistent probe paths protect the lower test file first. A rootless mapped-root path must write through that mode directly; the ordinary helper path must restore normal checkout permissions through metadata-only copy-up before testing a data write. Neither probe activates a persistent worktree. The persistent storage primitive places `upper` and `work` under one journal-owned `overlays/v1/` directory and mounts the immutable base directly at the requested merged worktree path. Layer mount options use already-open `/proc/self/fd` directory references, so user-controlled commas, colons, spaces, long paths, and non-UTF-8 bytes never enter OverlayFS's option grammar. A successful mount returns its Linux boot ID, mount-namespace device and inode, and kernel mount ID. Recovery unmounts or deletes private layers only when that full identity is absent or matches; a different namespace or foreign mount is preserved for manual attention. This primitive deliberately mounts only in the caller's current namespace. Before mounting, the journal can retain the current boot and namespace context and the upper layer can contain a token-bound recovery marker. If the process exits after `mount(2)` but before the kernel mount ID reaches the journal, recovery accepts only an OverlayFS mount at the exact destination that exposes the same private marker. A different namespace or any marker mismatch remains foreign. Core selects OverlayFS only after the caller-namespace probe succeeds and reflink probing does not. Add moves the real linked-worktree pointer into the private upper, arms recovery, mounts the immutable base, persists exact mount identity, clears the marker, synchronizes Git's index, and verifies cleanliness. Removal rechecks Git cleanliness, unmounts only that identity, restores the pointer to the underlying destination, removes journal-owned private layers, and lets real Git remove the linked worktree. A crash at any persisted add or removal phase is recoverable in the same namespace, including the gap after `mount(2)` and before identity persistence. Explicit repair handles a missing active mount by first replacing stale boot/namespace identity with durable remount intent, then reusing the token marker around the new mount and identity write. Private upper contents survive this remount, including dirty user edits. A mount already occupying the destination remains foreign. Mounted moves fail before mutation. Ordinary unprivileged shells may cross a narrow, explicitly installed helper boundary. Riftri first tries the direct caller-namespace operation. If that is permission-denied, it accepts only an absolute helper path whose executable and every ancestor are root-owned, non-writable by group/others, and whose binary has the set-user-ID bit. The elevated executable cannot enter the normal CLI: it accepts only mount, exact identity-checked unmount, and journal-owned disposable work-directory reset requests, clears its environment, and revalidates that the lower, upper, work, layout, and merged directories are real paths owned by the requesting UID. Probe setup and copy-up verification remain in the unprivileged parent. Mounts use `nodev,nosuid`. Rootless namespaces store OverlayFS metadata in `user.overlay.*` with metacopy disabled; the elevated helper deliberately uses `trusted.overlay.*`, which the requesting user cannot forge, and enables metadata-only copy-up. The selected profile is part of the durable mount context and identity. On helper mounts, metadata-only copy-up restores checkout write modes while unchanged file data remains shared with the read-only base. Git, checkout materialization, agent processes, and ordinary reads and writes remain unprivileged. The helper is available system-wide once installed, but repository-local `riftri.enabled` consent still controls Git interception. If the direct path and helper are both unavailable, selection fails before journal or Git mutation and never falls back to a full copy. On Windows, Riftri accepts ReFS only after an active `FSCTL_DUPLICATE_EXTENTS_TO_FILE` check succeeds on two delete-on-close files in the destination volume and a private write leaves the source unchanged. The destination is temporarily sparse while it is sized so the operation does not allocate zero-backed clusters before cloning. Matching sparse and integrity-stream settings are restored, and aligned regions are cloned in requests below the ReFS 4 GiB limit. The final unaligned tail—at most one filesystem cluster—is copied because the Windows API requires cluster-aligned extents. Any aligned block-clone failure aborts and rolls back; it never triggers a full-file copy. The same immutable bases, locks, journals, recovery, clean removal, move/prune, and garbage-collection rules apply. Recovery validates every recorded cleanup path. Before removing a materialized incomplete view, it requires a complete byte/mode/symlink and directory-entry comparison with the immutable base, even when Git calls the worktree clean. Ignored files and unexpected empty directories count as private changes and are preserved. Native rollback repeats this check at the final removal boundary; OverlayFS checks the merged view before unmounting and revalidates its private layer afterward. Otherwise it retains the view and journal for manual attention. This stronger automatic-rollback rule does not change explicit removal's ordinary Git semantics. Storage accounting is derived from add/removal journals and completion markers. It reports active views, retained bases, per-base reference counts, logical bytes, and filesystem-allocated bytes. Allocated bytes can include shared native COW blocks and are not an exclusive-space measurement; the volume-delta benchmark remains the authoritative sharing check. Bases reaching zero references remain cached until the explicit garbage collector independently proves deletion is safe and records its intent. The collector is never part of normal worktree file access or Git command passthrough. `riftri repair` resolves the repository's state directory by default or accepts `--state-dir ` to select one explicitly. Both forms apply the same conservative journal recovery and do not infer or delete unjournaled paths. Status also inventories the state layout itself. Valid journals explain their temporary, staging, and quarantine paths; completion markers explain retained immutable bases; object-ID lock files explain coordination metadata. Anything else is reported as a state issue, as are active journals whose worktree, base, or completion marker is missing or unsafe. This diagnostic pass is read-only: neither repair nor garbage collection guesses that an unexplained path is safe to delete. ## Fast path Once a worktree is ready, Riftri is absent from ordinary file operations: ```text agent -> native filesystem -> shared base/private changes ``` It must not become: ```text agent -> userspace Riftri callback -> filesystem ``` For normal Git commands, the shim should directly execute the real Git process without opening Riftri state. Cached bases are built once and reused by concurrent worktree requests. ## Safety constraints - Never use a mutable working directory as a shared lower layer. - Never delete a worktree without respecting Git's dirty-worktree safeguards. - Never silently create a full copy when the selected policy requires COW. - Never run the complete Riftri process as root. - Never place writable Riftri lifecycle state on a network filesystem. - Treat submodules, sparse checkout, custom filters, and broader Git LFS forms as explicit compatibility features with safe fallback behavior. ## Initial delivery sequence 1. Read-only diagnostics and storage capability model. (complete) 2. Explicit APFS worktree creation on macOS. (complete) 3. Removal, recovery inventory, and disk accounting. (complete) 4. Process-scoped Git shim. (complete) 5. Linux reflink and OverlayFS backends. (complete) 6. Compaction and compatibility expansion. 7. Windows ReFS block cloning. (initial slice complete)