Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

AD-0029: Capture qualified destination evidence

Implemented with local APFS and hosted Linux evidence, plus hosted Windows unsupported-boundary checks. Windows qualification remains pending.

Context

AD-0028 pins one scope and coordinates cooperating writers. The pure mixed planner still trusts supplied observations and exact lexical locations. Before execution can use them, filesystem observation must bind reads to directory identities and reject aliases and unsafe paths without making preview write.

Filename comparison differs across local filesystems and directory settings. Two absent spellings cannot be proved distinct by inspecting only their absence. Reproducing every versioned Unicode comparison table is outside the binary and dependency budget.

Options

Ambient path canonicalization followed by ordinary reads does not bind later accesses to the inspected directory chain. Creating temporary comparison probes would violate preview’s no-write contract. Exact emulation of every filesystem’s Unicode comparison would require version-dependent tables without qualifying unknown filesystems. Descriptor-relative traversal with retained identities and conservative overlap rejection preserves the selected boundary within the existing dependency budget.

Decision

Implement the inactive snapshot boundary in the qualified destination design. Use descriptor-relative no-follow traversal, retained handles and exact revalidation. Accept APFS and Linux ext-family/tmpfs profiles only when mount evidence is available; reject cross-mount traversal and other profiles. Reuse rustix 1.1.4 with no new dependencies or async runtime.

Conservatively reject candidate path pairs whose components may alias: ASCII case variants and any differing non-ASCII component are treated as potentially matching. Also reject potential ancestor/descendant pairs, stored-spelling aliases and hard-linked final files. This deliberately rejects some otherwise valid batches. The API describes rejection, not exact filesystem equivalence.

Return exact optional file values with an opaque, non-Clone snapshot borrowing the qualified scope. Verification detects relevant identity/content/binding changes and never refreshes stale evidence. The caller remains responsible for complete lifecycle inputs, writer-lock lifetime and future effect checks.

Consequences

Preview creates no probe files, directories or persistent state. Recoverable filesystem, read and descriptor-exhaustion failures return contextual errors, including allocation errors reported by a fallible read. This is not a guarantee of recoverable memory exhaustion: ordinary Rust infallible allocations, including captured-byte cloning, may abort, and the operating system may terminate the process instead of returning Err. Linux requires statx mount-ID support; unknown filesystems and Windows are explicit pending qualification boundaries. Retained handles and sampled checks do not exclude external editors or provide a security sandbox against hostile namespace relocation.

Source stabilization, permission policy, schema-2 persistence, apply/recovery and CLI activation remain separate gates. Completion requires acceptance RED, independent semantic controls, real APFS and hosted Linux evidence, unsupported Windows checks, Rust 1.85, full repository verification and matched live-API size measurements. Local APFS acceptance, private evidence tests and independent semantic controls now cover the implemented boundary. Linux profile, absent mount-ID mask and same-device/different-mount-ID validators are tested separately with synthetic metadata. On 2026-10-13, Actions run 38330080515 passed Linux runtime qualification with returned statx mount IDs and Windows compilation/unsupported-boundary checks for PR head 765e70b9b7ce5386530ffea1fe9814b228724428 (merge checkout 242930ef9107aff6eff432484f474e47157983f2). This is historical evidence for that head; later local timestamp and special-bit assertion controls are separate. A qualified Windows backend remains pending. Privileged mounts, device nodes and hostile namespace relocation remain unexercised. The issue #270 regression implementation now independently pins fractional mtime, acquisition-read stamp/size and call wiring, native profile rejection, retained mount comparison, existing-file overlap and repeated stale verification. Local APFS passes 28 public and 22 private destination cases; 14 independent production omissions produce assertion failures, with exact source restoration and focused green checks. Restored full repository verification passes without warnings. On 2026-10-13, Actions run 38334882688 passed for PR #273 head 2a50ca6a5163e11912cbcee7987593c68e0a4197. Ubuntu job 115092610337 passed 28 public destination cases and the native missing returned mount-ID mask case. Four profile/mask check and production-call omissions failed their intended assertions; each restored qualification.rs to SHA-256 1c5b288ed575ae1ccdd99a10170c13aa9054f92004a0927a64fb1587bac40bd5, followed by 22 restored private cases GREEN. All 13 head checks succeeded, including Windows unsupported-boundary job 115092610428. This dated evidence covers that head; hosted CI for the final head after temporary harness removal remains required before merge. It establishes neither a qualified Windows backend nor real privileged mount or fault behavior. See the durable design for evidence scope, counts and limits.

Local full verification, warning-denying all-target Clippy and Rust 1.85 all-target checks passed. Matching Rust 1.97.1 macOS release probes measure 33,888 additional bytes when snapshot capture and verification are live; the inactive CLI remains 3,215,120 bytes at both baseline 8298386 and candidate. This measures local binary size; it does not measure runtime cost.

Satisfies: specification §4.8. Related: AD-0028.