Expand description
Copy-on-write immutable validator snapshot — the definitive fix for the
gap ticket validator-immutability-proof left open (and named in its
“Remaining gap” section): “read-only” validator sessions ran in the
mission’s REAL session checkout, so the tamper fingerprint
(crate::validator_integrity) could only catch writes at session
boundaries and never saw write-then-revert inside the window.
With this module the validator never sees the real checkout. Before each
validator session (the primary and the single retry — the same sites the
fingerprint wraps) the orchestrator builds a THROWAWAY snapshot of the
session checkout under the mission’s gitignored runs/ scratch:
git worktree add --detach <path> <head>— the tree at HEAD, sharing the object store (no clone cost).- The worker’s uncommitted state is replayed into it:
git diff --binary HEADcaptured in the real checkout andgit applyed in the snapshot (tracked edits, staged or not), plus a byte copy of every untracked non-ignored file. Validators judge exactly the tree the worker left. - The snapshot’s
target/is a COPY of the real checkout’s — the warm-target constraint. Contract commands (cargo test …) must not pay a cold full-workspace rebuild (~50 min in this repo): APFS clonefile (cp -c) when the filesystem supports it (instant, copy-on-write blocks), Linux reflink (cp --reflink=always) otherwise, a plain byte copy when the target is small enough, and — logged, naming the cost — a fresh empty target when no acceleration exists and the copy would be prohibitive. The realtarget/is NEVER shared or symlinked: a validator poisoning shared build artifacts would inject into the real deliverable build.
The session’s cwd, the validator’s contract-command cwd, and the
sandbox profile’s session_cwd all point at the snapshot, so where the
sandbox can express it the real checkout is not even in the writable
set. Only the verdict (PASS/FAIL/findings) crosses back; the snapshot is
discarded after the round regardless of outcome (RAII, mirroring
preflight.rs’s DisposableWorktree idiom). The deliverable gates and
the out-of-contract sweep keep running against the REAL checkout.
The snapshot is physical separation, NOT containment (13th-pass review,
P1 — ticket validator-mandatory-containment): the worktree sits
underneath the real repository hierarchy and references the shared git
directory, so an UNWRAPPED validator (enforce: off, the old default)
could still walk to the real checkout, modify tests, run them, and
restore the bytes — modify → use → restore leaves no drift for the
tripwire to catch. The mandatory validator wrap
(crate::sandbox::resolve_validator_containment) closes that: every
validator session runs under a Seatbelt/bwrap profile regardless of
sandbox.enforce, with the snapshot as the sole writable root, the
real checkout’s source tree read-denied, and the shared .git readable
but write-denied. Where the platform or backend cannot contain, the
resolution FAILS CLOSED by default (ticket
validator-containment-degrade-fail-closed); only the explicit
validatorAllowUncontainedDegrade opt-in runs the round anyway, with
the loud degradation decision recorded and the snapshot plus the
tripwire as the remaining layers.
Two honest limits, both covered by the fingerprint-turned-tripwire on the real checkout:
- The file tree is isolated; git REFS are not. Worktrees share the
common
.git, so a validatorgit branch -fin the snapshot still moves shared refs where no containment applies — which the tripwire’sfor-each-refhalf catches at session end. (Under the mandatory wrap the ref write is hard-denied by deny-default; the tripwire is the defense-in-depth for the degraded platforms.) A drift event now means the isolation itself failed. - Under an enforced sandbox the snapshot’s gitdir (
.git/worktrees/<n>) lives outside the writablesession_cwd, so validator git commands that try to refresh the index degrade (read-only git still works; commits fail — which validators should never need).
Structs§
- Validator
Snapshot - RAII guard for one validator session’s throwaway checkout. Drop removes
it best-effort —
git worktree remove --force(which also deletes the directory), a dir sweep for anything git declined, and a prune of stale administrative entries — so pass, fail, tamper-block, or error return can never leak it.
Enums§
- Target
Copy Tier - Which tier warmed the snapshot’s
target/— recorded on thevalidation.snapshotevent.