diff --git a/benchmarks/push/freeze_source.sh b/benchmarks/push/freeze_source.sh index a1802ee..d6c9b92 100755 --- a/benchmarks/push/freeze_source.sh +++ b/benchmarks/push/freeze_source.sh @@ -1,20 +1,31 @@ #!/usr/bin/env bash -# Export the COMMITTED source for a long measurement run, and prove the export is whole. +# Export the COMMITTED source into a FRESH immutable directory, and prove the export is whole. # # Every long run here mounts src into a container. Mounting the working tree is a live mount: edits # made during a multi-hour run are picked up mid-run, and a measurement whose code changed underneath # it is not a measurement of anything -- the failure looks exactly like the thing being measured # failing. A five-hour PHP transfer replay was lost that way on 2026-09-22. # -# And the export has to be checked. `git archive | tar -x` once produced a tree missing the whole -# ontology (every tracked file after `groovy` alphabetically) and reported success, because tar's -# status in a pipeline was never read. Every scan on that tree died at its first fact load and looked -# like a slow run for fourteen minutes. So: archive to a file, extract, count against git. +# The path is MINTED here, never taken from the caller, so a second freeze can never rm -rf a +# directory a running container is mounting -- which happened once, deleting taint.sc out from under +# a live scan and printing "no such cpg query" for every request after. Reuse is impossible by +# construction: each call gets its own /frozen---. # -# Usage: benchmarks/push/freeze_source.sh -> prints the frozen commit on success +# The export is checked too. `git archive | tar -x` once produced a tree missing the whole ontology +# (every tracked file after `groovy` alphabetically) and reported success, because tar's status in a +# pipeline was never read. So: archive to a file, extract, count against git, require the ontology. +# +# Usage: DEST=$(benchmarks/push/freeze_source.sh ) -> prints the minted path on success set -euo pipefail -dest="${1:?destination directory}" -rm -rf "$dest" && mkdir -p "$dest" +base="${1:?base directory}" +mkdir -p "$base" +commit=$(git rev-parse --short HEAD) +n=0 +while :; do + dest="$base/frozen-$commit-$$-$n" + if mkdir "$dest" 2>/dev/null; then break; fi + n=$((n + 1)) +done git archive HEAD src benchmarks > "$dest.tar" tar -xf "$dest.tar" -C "$dest" rm -f "$dest.tar" @@ -25,4 +36,4 @@ if [ "$want" -ne "$have" ]; then exit 1 fi test -d "$dest/src/openultrasast/ruleset/semantic" || { echo "export lacks the ontology" >&2; exit 1; } -echo "$(git rev-parse --short HEAD) $have files" +echo "$dest"