The set of paths a hardlink clone has to real-copy — dep-info,
build-script metadata, linked outputs, the pruned directories that hold
them — was spelled out inline in unshare_mutable_paths, in four find
invocations. Nothing else needed it, so one spelling was enough.
Something else needs it now: the prune has to know what a clone will
cost before it happens, and a sizer with its own copy of the predicates
would drift from the copier silently and in the dangerous direction — an
under-measured clone is one that starts and runs out of disk halfway
through unsharing. So the directory names become one array and the file
rules one dispatcher, applied by a callback per side, with each rule's
rationale moved to the rule rather than left at the old call site.
mutable_set_kb measures that set off a snapshot, skipping the subtrees
already measured whole so nothing is counted twice; clone_headroom_kb
scales it by a hand-written margin and floor for what the measurement
cannot see (cp -al materialising every directory for real, and the
unshare holding one subtree twice at its peak). Both residuals are named
where the function is, in both directions.
seed_source_candidates moves the seed's source-preference list into
cache-lib for the same reason: the prune ahead of it has to resolve the
same source the seed will clone, and two agreeing derivations are one
edit away from disagreeing.
No behaviour change — the copier applies the same rules to the same
tree, verified by the hardlink-clone suite's inode partition in both
directions.
Refs #20.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JXMQCJ5Eg5f9G9cfYzyh4Z