74b1f1dd0b
Two P1s from cubic, both in the commit before this one. `INSFORGE_NO_GIT=1` with `INSFORGE_REF` set — the combination the header documents — failed with "fatal: not a git repository". Moving checkout_ref after the guard put it on the HTTPS path too, where there is nothing to fetch into and the files were already retrieved at that ref. It returns early when NO_GIT is set. Pinning to v2.2.9 over HTTPS now lands that release's files, which is verifiable: its compose file still names postgres-all. The working-tree guard tested `-d "$TARGET/.git"`. In a linked worktree .git is a file, so the guard read as "no repository here" for exactly the tree it most needs to catch — and this is the second time in this series that a .git test had to change from -d to -e. deploy/setup.sh also comes out of FILES. The script belongs in the checkout so it travels with it for the update procedure, which is a git-path concern; on the HTTPS path the caller already holds the script, and any ref older than this file 404s on it and fails the whole fetch. The sparse patterns add it, FILES does not. And scripts/check-setup-sh.sh, run in CI, asserts the structure. Every rule in it guards an invariant that was broken after being established: secrets written with set_var rather than gen_secret (twice), an operation inserted ahead of the guard, a .git test narrowed to -d, a git call left on the no-git path. None of those show up in a diff review or a happy-path run. The checks are mutation-tested: each of the seven rules was verified to fail when the corresponding bug is reintroduced into a copy of the tree, and to pass on the tree as it stands. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>