AtlatestRepositorycore-channel

core-channel / tree / scriptsgate-crosscheckout.sh

1#!/bin/sh
2set -eu
3
4# PROPERTY UNDER TEST: everything needed to get from a BARE GIT CLONE to a
5# running program is either committed, or hash-pinned and fetchable. Nothing
6# may depend on the checkout it was authored in -- not an untracked file, not a
7# forgotten `git add`, not a warm store, not an absolute path. Hence: fresh
8# 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 marker
13# printed only after the command are exactly the right shape, and the failure
14# did propagate. It was hollowed out from OUTSIDE -- the released sigil of the
15# day had no `env` subcommand and exited 0 for unknown subcommands, so the one
16# command that mattered never ran and never complained. Correct authorship was
17# not enough. A binary that does nothing successfully must not be able to pass
18# this gate, so the check below requires evidence the built program actually
19# ran: its own stdout.
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.
24repo=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)
25sigil_bin=${SIGIL_BIN:?set SIGIL_BIN to a sigil binary with env support (0.18.0+)}
26registry=${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 indistinguishable
30# from the failure this gate exists to report. A missing `minisign` is the
31# sharp case: it surfaces as "root signature ... failed", which accuses the
32# trust chain rather than the environment.
33for tool in git minisign; do
34 command -v "$tool" >/dev/null 2>&1 || {
35 echo "cross-checkout gate: FATAL: $tool is not on PATH; the gate did not run" >&2
36 exit 1
37 }
38done
40scratch=$(mktemp -d /tmp/sigil-channel-clone.XXXXXX)
41trap 'rm -rf "$scratch"' EXIT HUP INT TERM
42git clone --quiet --no-hardlinks "$repo" "$scratch/core-channel"
44SIGIL_BOOTSTRAP_SEED_URL="${SIGIL_BOOTSTRAP_SEED_URL:-}" \
45SIGIL_BOOTSTRAP_ZIG_URL="${SIGIL_BOOTSTRAP_ZIG_URL:-}" \
46 "$scratch/core-channel/bootstrap"
48# Authoring: resolve demo/env.sgl against the clone's signed catalogue and
49# realize it. `env shell` consumes an env.lock, never environment source, so
50# the lock step is separate and comes first.
51lock_status=0
52SIGIL_REGISTRY_METADATA="$registry" \
53HOME="$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=$?
58if [ "$lock_status" -ne 0 ] || [ ! -s "$scratch/env.lock" ]; then
59 echo "cross-checkout gate: FAILED at lock" >&2
60 echo " exit status: $lock_status; env.lock present and non-empty: no" >&2
61 sed 's/^/ | /' "$scratch/lock.out" >&2
62 exit 1
63fi
65# Consumption: deliberately WITHOUT SIGIL_REGISTRY_METADATA and without
66# SIGIL_CHANNEL, which also holds the lock-only consumption boundary honest.
68# PROVENANCE FIRST. `sigil env shell` does not isolate PATH, so a command the
69# environment does not provide resolves from the HOST. Observed directly: with
70# a profile that ships no hello, `-- hello` ran /gnu/store/...-profile/bin/hello
71# and printed "MD5('Hello, world!') = ...". So establish that the hello about
72# to run came out of THIS gate's store before believing anything it prints.
73which_status=0
74HOME="$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=$?
79hello_path=$(head -1 "$scratch/hello.path" 2>/dev/null || true)
80case "$hello_path" in
81 "$scratch/store/"*) : ;;
82 *)
83 echo "cross-checkout gate: FAILED at provenance" >&2
84 echo " exit status: $which_status" >&2
85 echo " hello must resolve inside $scratch/store, got: ${hello_path:-<nothing>}" >&2
86 exit 1
87 ;;
88esac
90run_status=0
91HOME="$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 no
96# output, or a zero status from a binary that never ran the program at all.
97if [ "$run_status" -ne 0 ] || ! grep -q '^Hello, world!$' "$scratch/hello.out"; then
98 echo "cross-checkout gate: FAILED at run" >&2
99 echo " exit status: $run_status" >&2
100 echo " expected 'Hello, world!' on stdout; captured output follows" >&2
101 sed 's/^/ | /' "$scratch/hello.out" >&2
102 exit 1
103fi
105# Print the evidence, not just the verdict. A green that quotes what it
106# observed is auditable from a CI log; a bare "green" is what this gate
107# printed for five days while observing nothing.
108echo "cross-checkout gate: fresh clone bootstrapped, locked, and ran hello from the lock"
109echo "cross-checkout gate: ran $hello_path"
110echo "cross-checkout gate: observed program output: $(head -1 "$scratch/hello.out")"