From a960c8f91b1d0b47b6339628b751e15fcb9112bc Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 7 Sep 2026 00:20:45 -0500 Subject: [PATCH 1/4] refactor(cache): name the mutable set once, and measure it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Claude-Session: https://claude.ai/code/session_01JXMQCJ5Eg5f9G9cfYzyh4Z --- scripts/cache-lib.sh | 227 ++++++++++++++++++++++++++++++------- scripts/seed-target-dir.sh | 9 +- 2 files changed, 192 insertions(+), 44 deletions(-) diff --git a/scripts/cache-lib.sh b/scripts/cache-lib.sh index d24ac4c..d195a5e 100755 --- a/scripts/cache-lib.sh +++ b/scripts/cache-lib.sh @@ -330,6 +330,62 @@ _holds_compiled_artifact() { return 1 } +# The directory names that select a mutable subtree, as one find predicate. +# +# Named once because THREE readers have to agree on it: the selection in +# _mutable_dirs, the prune that skips those subtrees when it sizes the file +# rules, and anything later that measures what a clone will cost. Two +# spellings of this list would size a different tree than the one copied, and +# the direction that fails is silent — an under-measured clone runs out of +# disk mid-unshare, which is gitdan-actions#20. +_MUTABLE_DIR_NAMES=( -name .fingerprint -o -name fingerprint -o -name run -o -name out ) + +# _mutable_file_rules +# +# The FILE half of the mutable set, applied one rule at a time: +# +#