Gate: a --ci run outside GitHub Actions builds the site in the temporary copy like the hook (the in-place build rewrote four tracked site files in the running worktree; the horizon lane, 7 Oct 2026); in place only inside Actions; self-test that the tree is unchanged after a site build

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
igneum-labs 2026-10-07 14:23:05 +00:00
parent cbf57294a9
commit 317b2556b2

View file

@ -41,8 +41,13 @@ run() {
}
run_quiet() { "$@" >/dev/null 2>&1; }
# In place ONLY inside GitHub Actions (a disposable checkout); a `--ci` run on a lane's Mac builds in the temporary copy like the hook,
# because the in-place build rewrote four tracked site files (bench.html, index.html, journey.html, journey.json) in the running
# worktree and every lane had to discard them before a merge (the horizon lane, 7 October 2026). --self-test proves the tree is
# unchanged after a site build outside Actions.
site_in_place() { [ "$MODE" = ci ] && [ "${GITHUB_ACTIONS:-}" = true ]; }
site_build() {
if [ "$MODE" = ci ]; then node site/build.mjs; return; fi
if site_in_place; then node site/build.mjs; return; fi
SITE_TMP="$(mktemp -d)"; cp -R site "$SITE_TMP/site"
(cd "$SITE_TMP/site" && SITE_DOWNLOADS_OFFLINE=1 node build.mjs)
}
@ -61,7 +66,7 @@ never_push_checks() {
}
tree_checks() {
run "site build (in a temporary copy locally, in place in CI)" site_build
run "site build (in a temporary copy here, in place only inside GitHub Actions)" site_build
run "internal link check of site/*.html" node tools/ci/link-check.mjs
run "every served page carries the slim bar (mark, Mine, Network, Learn, Download) with every route in its panels and the sheet (self-test, then the tree)" bash -c 'node tools/ci/site-nav-check.mjs --self-test && node tools/ci/site-nav-check.mjs'
run "vendor marks: site/lib/marks.mjs is brand/marks/vendor-marks.mjs byte for byte (the app and the site draw one set)" cmp brand/marks/vendor-marks.mjs site/lib/marks.mjs
@ -183,8 +188,13 @@ case "$MODE" in
touch -t 202001010000 "$(cd "$fx" && stamp_dir)/$B"; case "$(deferred_merge "$M" "$A" "$fx")" in "full the stamp for ${B:0:8} is "*) ;; *) echo "self-test failed: a stale stamp was honoured"; fails=1 ;; esac
( cd "$fx" && echo x > dirty && git add dirty && git -c user.name=t -c user.email=t@t commit -q -m d && echo y > dirty && stamp_green . | grep -q recorded ) && { echo "self-test failed: a dirty tree was stamped"; fails=1; }
rm -rf "$fx"
# a --ci site build outside GitHub Actions leaves the tracked site files as they are (the horizon lane's four rewritten files)
before=$(git status --porcelain -- site | sort); ( MODE=ci GITHUB_ACTIONS= site_build >/dev/null 2>&1 ); after=$(git status --porcelain -- site | sort)
[ "$before" = "$after" ] || { echo "self-test failed: a --ci site build outside GitHub Actions changed tracked site files: $(git status --porcelain -- site | tr '\n' ' ')"; fails=1; }
MODE=ci GITHUB_ACTIONS= site_in_place && { echo "self-test failed: --ci outside GitHub Actions chose the in-place build"; fails=1; }
MODE=ci GITHUB_ACTIONS=true site_in_place || { echo "self-test failed: --ci inside GitHub Actions did not choose the in-place build"; fails=1; }
declare -f tree_checks | grep -q 'never_push_checks' || { echo "self-test failed: the full gate does not run the never-push checks"; fails=1; }
[ "$fails" = 0 ] && echo "self-test passed: a failing check is RED and fails the gate, a passing one is ok; master and release-* select the full gate, other refs the light one; a merge of a green-stamped branch onto the remote tip defers to CI, every other shape takes the full gate (structural checks, no-secrets, identity grep)"
[ "$fails" = 0 ] && echo "self-test passed: a failing check is RED and fails the gate, a passing one is ok; master and release-* select the full gate, other refs the light one; a merge of a green-stamped branch onto the remote tip defers to CI, every other shape takes the full gate; a --ci site build outside GitHub Actions leaves the tree unchanged (structural checks, no-secrets, identity grep)"
exit $fails ;;
list)
grep -E '^\s+run "' "$0" | sed -E 's/^\s+run "([^"]+)".*/\1/' ;;