ci/woodpecker/pr/ci Pipeline was successful
Authored by installer-7; committed by mos-claude (no credential for this remote). push-guard.sh and test-push-guard.sh are BYTE-IDENTICAL to the previously cleared versions — every change this round is in the harness, confirming the reviewer's framing that none of the three blockers was in the guard itself. B1 verify-clean-clone.sh could not verify the artifact in its real monorepo location: it resolved ROOT but kept artifacts as bare basenames, so running it in place reported all artifacts NOT TRACKED. Its own suite missed this because every fixture installed artifacts at fixture ROOT — a fixture encoding a layout the real subject does not have. PREFIX now comes from 'git rev-parse --show-prefix' and is threaded through the ls-tree pathspec, the cloned stat, and the suite cwd; the verifier PRINTS the prefix. Three needles: nested-layout pass, prefix-reported (else a green only means the prefix was ignored harmlessly), and mode-needle-still- bites-nested (a prefix threaded into the clone but not ls-tree would silently stop checking modes). B2 the generator reported full coverage and exited 0 on a RED baseline — any pre-existing failure marked every mutant killed. Now refuses unless baseline is exit 0 with zero failures, prints the actual tally on refusal, emits no table, and scores kills by NAMED DELTA rather than a raw red count. B3 the generator mutated the reviewed source in place; SIGKILL stranded a mutant and contaminated a following run. Guard and suite are now copied into a temp dir and mutations apply to that copy — no restore step to fail. The author's first control for this was itself vacuous (a 3s kill lands during baseline, before any mutation, so it passed against the unfixed mechanism too); the real control drives the kill from inside the run on the second suite invocation, plus a needle proving the reconstructed pre-fix mechanism DOES strand. Corrections: 'shellcheck clean' had been measured at -S warning and published unqualified — a filtered measurement stated as an unfiltered claim. Now clean at DEFAULT severity across six files with one scoped, documented SC2016 disable. ARTIFACTS extended five -> six so the test files no longer omit themselves. Verified before commit: six files sha256-matched to the author's hashes; shellcheck exit 0 at default severity; push-guard 46/46 and verifier 9/9 run directly; the in-place verifier resolved the real nested prefix against this tree. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01YKj59Qadrb2WBLaePvkM7H
148 lines
6.6 KiB
Bash
Executable File
148 lines
6.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# verify-clean-clone.sh -- prove the COMMITTED artifact runs, from a clean clone.
|
|
#
|
|
# ================== THIS FILE IS THE SECOND VERSION. THE FIRST HAD B1. ========
|
|
# B1 was: the delivered scripts were committed mode 100644, so the artifact
|
|
# returned 126 Permission denied for anyone who cloned it. Two of us ran 32/32
|
|
# because our local working copies had the exec bit set by hand at creation.
|
|
#
|
|
# I wrote v1 of this file to prevent exactly that. V1 COPIED THE WORKING-TREE
|
|
# FILES INTO A SCRATCH REPOSITORY AND ASSERTED THE SCRATCH REPOSITORY'S INDEX.
|
|
# cp preserves the local exec bit, so `git add` in the scratch repo recorded
|
|
# 100755 NO MATTER WHAT THE REAL REPOSITORY STORED. Reviewer reproduction:
|
|
# git update-index --chmod=-x push-guard.sh test-push-guard.sh
|
|
# ./verify-clean-clone.sh -> EXIT 0, "CLEAN CLONE: suite ran and passed"
|
|
# while the real index read 100644 -- the precise contaminated state B1 was.
|
|
#
|
|
# THE CONTROL FOR THE DEFECT INHERITED THE DEFECT, BECAUSE IT MEASURED A COPY
|
|
# INSTEAD OF THE SUBJECT. cp LAUNDERS MODE.
|
|
#
|
|
# Both of v1's mechanisms were right -- assert the INDEX not the disk, execute
|
|
# DIRECTLY not via `bash script`. They were applied to the wrong repository.
|
|
# So v2 changes what is measured, not how:
|
|
# * mode is read from the SOURCE repository's COMMITTED TREE (git ls-tree),
|
|
# which no local chmod can influence;
|
|
# * the tree under test is produced by CLONING THAT COMMIT, so every mode
|
|
# comes out of the object store rather than off my filesystem.
|
|
# There is no cp anywhere in this file, and that is deliberate.
|
|
#
|
|
# It also REFUSES rather than passes when the artifacts are untracked: an
|
|
# artifact that is not committed has no mode to verify, and a verifier that
|
|
# silently succeeds on nothing is the vacuous-absence failure all over again.
|
|
|
|
set -euo pipefail
|
|
|
|
readonly EX_FAIL=1
|
|
readonly EX_USAGE=64
|
|
|
|
REPO=""
|
|
REV="HEAD"
|
|
|
|
die() { printf 'usage error: %s\n' "$1" >&2; exit "$EX_USAGE"; }
|
|
|
|
while (( $# )); do
|
|
case "$1" in
|
|
--repo) REPO="${2:-}"; shift 2 ;;
|
|
--rev) REV="${2:-}"; shift 2 ;;
|
|
*) die "unknown argument: $1" ;;
|
|
esac
|
|
done
|
|
|
|
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
[[ -n "$REPO" ]] || REPO="$HERE"
|
|
|
|
ARTIFACTS=(push-guard.sh test-push-guard.sh verify-clean-clone.sh mutate-push-guard.sh
|
|
test-mutate-push-guard.sh
|
|
test-verify-clean-clone.sh)
|
|
SUITE="test-push-guard.sh"
|
|
|
|
# --- the subject must be a real repository, or there is nothing to verify -----
|
|
if ! ROOT="$(git -C "$REPO" rev-parse --show-toplevel 2>/dev/null)"; then
|
|
printf 'REFUSING: %s is not inside a git repository.\n' "$REPO" >&2
|
|
printf 'This verifier checks the COMMITTED mode of the artifact. An uncommitted\n' >&2
|
|
printf 'artifact has no committed mode, and passing here would prove nothing.\n' >&2
|
|
exit "$EX_FAIL"
|
|
fi
|
|
if ! REV_SHA="$(git -C "$ROOT" rev-parse --verify --quiet "${REV}^{commit}")"; then
|
|
printf 'REFUSING: %s does not resolve to a commit in %s\n' "$REV" "$ROOT" >&2
|
|
exit "$EX_FAIL"
|
|
fi
|
|
|
|
# --- THE ARTIFACT'S COMMITTED PATH, NOT ITS BASENAME -------------------------
|
|
# v2 asserted `git ls-tree HEAD -- push-guard.sh`, which is a ROOT-RELATIVE
|
|
# pathspec. These files really live several directories down. Run in place and
|
|
# every artifact came back "NOT TRACKED" -- the verifier built to stop packaging
|
|
# false-greens could not verify the tree that ships it.
|
|
#
|
|
# The tests missed it because EVERY FIXTURE INSTALLED THE ARTIFACTS AT THE
|
|
# FIXTURE ROOT. 6/6 green proved flat-layout operation and nothing about the
|
|
# deployed path. THAT IS THE THIRD TIME ON THIS TOOL THAT A CONTROL VALIDATED A
|
|
# MODEL INSTEAD OF THE SUBJECT: v1 measured a cp'd scratch repo, and then v2's
|
|
# own tests measured a layout that does not exist. A fixture is a claim about
|
|
# the world, and an untested fixture is an unreviewed one.
|
|
#
|
|
# --show-prefix answers "where is this directory inside its repository", so the
|
|
# same prefix drives ls-tree, the cloned stat, and the suite's working dir.
|
|
PREFIX="$(git -C "$REPO" rev-parse --show-prefix)"
|
|
|
|
printf '=== subject ===\n'
|
|
printf ' repo %s\n rev %s (%s)\n prefix %s\n\n' \
|
|
"$ROOT" "$REV" "$REV_SHA" "${PREFIX:-<repository root>}"
|
|
|
|
# --- 1. MODE, FROM THE COMMITTED TREE OF THE SUBJECT -------------------------
|
|
# git ls-tree reports what the COMMIT records. Nothing on my filesystem can
|
|
# move this number -- which is the whole point, and what v1 got wrong.
|
|
printf '=== committed modes (git ls-tree %s) ===\n' "$REV"
|
|
rc=0
|
|
for f in "${ARTIFACTS[@]}"; do
|
|
entry="$(git -C "$ROOT" ls-tree "$REV_SHA" -- "${PREFIX}${f}")"
|
|
if [[ -z "$entry" ]]; then
|
|
printf ' FAIL %s is NOT TRACKED at %s -- nothing committed to verify\n' "$f" "$REV"
|
|
rc=1; continue
|
|
fi
|
|
mode="${entry%% *}"; rest="${entry#* }"; type="${rest%% *}"
|
|
if [[ "$type" != blob ]]; then
|
|
printf ' FAIL %s is a %s at %s, not a regular file\n' "$f" "$type" "$REV"
|
|
rc=1; continue
|
|
fi
|
|
case "$mode" in
|
|
100755) printf ' ok %s committed %s\n' "$f" "$mode" ;;
|
|
120000) printf ' FAIL %s is a SYMLINK (%s) -- the reviewed blob is a path, not the code\n' "$f" "$mode"; rc=1 ;;
|
|
*) printf ' FAIL %s committed %s, needs 100755\n' "$f" "$mode"
|
|
printf ' fix with: git update-index --chmod=+x %s && commit\n' "$f"
|
|
rc=1 ;;
|
|
esac
|
|
done
|
|
if (( rc != 0 )); then
|
|
printf '\nREFUSING TO CONTINUE: the COMMITTED modes are wrong, whatever the disk says.\n'
|
|
printf 'A clone of this commit would exit 126 for the next person.\n'
|
|
exit "$EX_FAIL"
|
|
fi
|
|
|
|
# --- 2. RUN FROM A CLONE OF THAT COMMIT --------------------------------------
|
|
# Cloning materialises every file from the object store, so the modes on disk
|
|
# are the COMMITTED modes by construction. No cp, no local state, nothing this
|
|
# machine can contribute.
|
|
WORK="$(mktemp -d)"
|
|
trap 'rm -rf "$WORK"' EXIT
|
|
|
|
printf '\n=== cloning %s (no local mode bits survive this) ===\n' "$REV_SHA"
|
|
git clone -q --no-local --no-hardlinks "$ROOT" "$WORK/clone"
|
|
git -C "$WORK/clone" -c advice.detachedHead=false checkout -q "$REV_SHA"
|
|
|
|
for f in "${ARTIFACTS[@]}"; do
|
|
printf ' clone disk mode: %s %s\n' "$(stat -c '%a' "$WORK/clone/${PREFIX}${f}")" "${PREFIX}${f}"
|
|
done
|
|
|
|
printf '\n=== executing DIRECTLY (./%s), not via "bash %s" ===\n' "$SUITE" "$SUITE"
|
|
# Invoking the interpreter explicitly masks a missing exec bit completely -- it
|
|
# is how the original green was obtained. Direct execution is the thing under
|
|
# test, so the mode has to be real for this line to succeed.
|
|
cd "$WORK/clone/${PREFIX}"
|
|
if ! "./$SUITE"; then
|
|
printf '\nCLEAN-CLONE RUN FAILED.\n'
|
|
exit "$EX_FAIL"
|
|
fi
|
|
|
|
printf '\n=== CLEAN CLONE: the COMMITTED artifact ran and passed ===\n'
|