AtlatestRepositorycore-channel
core-channel / tree / scriptsgate-crosscheckout.sh
1
#!/bin/sh2
set -eu4
# PROPERTY UNDER TEST: everything needed to get from a BARE GIT CLONE to a5
# running program is either committed, or hash-pinned and fetchable. Nothing6
# may depend on the checkout it was authored in -- not an untracked file, not a7
# forgotten `git add`, not a warm store, not an absolute path. Hence: fresh8
# clone at a new path, fresh HOME, fresh store.9
#10
# WHY THE ASSERTIONS BELOW ARE ON OBSERVED OUTPUT, NOT EXIT STATUS.11
# This gate reported green from 2026-07-25 to 2026-07-30 while testing nothing.12
# It was not badly written: `set -eu`, no pipelines, and a success marker13
# printed only after the command are exactly the right shape, and the failure14
# did propagate. It was hollowed out from OUTSIDE -- the released sigil of the15
# day had no `env` subcommand and exited 0 for unknown subcommands, so the one16
# command that mattered never ran and never complained. Correct authorship was17
# not enough. A binary that does nothing successfully must not be able to pass18
# this gate, so the check below requires evidence the built program actually19
# ran: its own stdout.20
#21
# To confirm this gate still works, run it against a sigil older than 0.18.0.22
# It must FAIL. Before the hardening it passed.24
repo=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)25
sigil_bin=${SIGIL_BIN:?set SIGIL_BIN to a sigil binary with env support (0.18.0+)}26
registry=${SIGIL_REGISTRY_METADATA:?set SIGIL_REGISTRY_METADATA to root-signed registry metadata this binary accepts}28
# Assert each external dependency separately and loudly. Folded into an `&&`29
# chain, an absent tool short-circuits to a non-zero status indistinguishable30
# from the failure this gate exists to report. A missing `minisign` is the31
# sharp case: it surfaces as "root signature ... failed", which accuses the32
# trust chain rather than the environment.33
for tool in git minisign; do34
command -v "$tool" >/dev/null 2>&1 || {35
echo "cross-checkout gate: FATAL: $tool is not on PATH; the gate did not run" >&236
exit 137
}38
done40
scratch=$(mktemp -d /tmp/sigil-channel-clone.XXXXXX)41
trap 'rm -rf "$scratch"' EXIT HUP INT TERM42
git clone --quiet --no-hardlinks "$repo" "$scratch/core-channel"44
SIGIL_BOOTSTRAP_SEED_URL="${SIGIL_BOOTSTRAP_SEED_URL:-}" \45
SIGIL_BOOTSTRAP_ZIG_URL="${SIGIL_BOOTSTRAP_ZIG_URL:-}" \46
"$scratch/core-channel/bootstrap"48
# Authoring: resolve demo/env.sgl against the clone's signed catalogue and49
# realize it. `env shell` consumes an env.lock, never environment source, so50
# the lock step is separate and comes first.51
lock_status=052
SIGIL_REGISTRY_METADATA="$registry" \53
HOME="$scratch/home" SIGIL_CHANNEL="$scratch/core-channel" \54
"$sigil_bin" env --store "$scratch/store" lock \55
-f "$scratch/core-channel/demo/env.sgl" --lock-file "$scratch/env.lock" \56
>"$scratch/lock.out" 2>&1 || lock_status=$?58
if [ "$lock_status" -ne 0 ] || [ ! -s "$scratch/env.lock" ]; then59
echo "cross-checkout gate: FAILED at lock" >&260
echo " exit status: $lock_status; env.lock present and non-empty: no" >&261
sed 's/^/ | /' "$scratch/lock.out" >&262
exit 163
fi65
# Consumption: deliberately WITHOUT SIGIL_REGISTRY_METADATA and without66
# SIGIL_CHANNEL, which also holds the lock-only consumption boundary honest.67
#68
# PROVENANCE FIRST. `sigil env shell` does not isolate PATH, so a command the69
# environment does not provide resolves from the HOST. Observed directly: with70
# a profile that ships no hello, `-- hello` ran /gnu/store/...-profile/bin/hello71
# and printed "MD5('Hello, world!') = ...". So establish that the hello about72
# to run came out of THIS gate's store before believing anything it prints.73
which_status=074
HOME="$scratch/home" \75
"$sigil_bin" env --store "$scratch/store" shell \76
-f "$scratch/env.lock" -- sh -c 'command -v hello' \77
>"$scratch/hello.path" 2>&1 || which_status=$?79
hello_path=$(head -1 "$scratch/hello.path" 2>/dev/null || true)80
case "$hello_path" in81
"$scratch/store/"*) : ;;82
*)83
echo "cross-checkout gate: FAILED at provenance" >&284
echo " exit status: $which_status" >&285
echo " hello must resolve inside $scratch/store, got: ${hello_path:-<nothing>}" >&286
exit 187
;;88
esac90
run_status=091
HOME="$scratch/home" \92
"$sigil_bin" env --store "$scratch/store" shell \93
-f "$scratch/env.lock" -- hello >"$scratch/hello.out" 2>&1 || run_status=$?95
# Both conditions, because either alone can lie: a non-zero status with no96
# output, or a zero status from a binary that never ran the program at all.97
if [ "$run_status" -ne 0 ] || ! grep -q '^Hello, world!$' "$scratch/hello.out"; then98
echo "cross-checkout gate: FAILED at run" >&299
echo " exit status: $run_status" >&2100
echo " expected 'Hello, world!' on stdout; captured output follows" >&2101
sed 's/^/ | /' "$scratch/hello.out" >&2102
exit 1103
fi105
# Print the evidence, not just the verdict. A green that quotes what it106
# observed is auditable from a CI log; a bare "green" is what this gate107
# printed for five days while observing nothing.108
echo "cross-checkout gate: fresh clone bootstrapped, locked, and ran hello from the lock"109
echo "cross-checkout gate: ran $hello_path"110
echo "cross-checkout gate: observed program output: $(head -1 "$scratch/hello.out")"