#!/usr/bin/env bash # Focused fixtures for the shared local/CI design-amendment gate. set -euo pipefail root=$(cd "$(dirname "$0")/.." && pwd) gate="$root/tools/design_amendment_gate.sh" tmp=$(mktemp -d) trap 'rm -rf "$tmp"' EXIT mkdir -p "$tmp/tools" "$tmp/crates/game" "$tmp/wiki/process" cp "$gate" "$tmp/tools/design_amendment_gate.sh" cat > "$tmp/crates/game/lib.rs" <<'EOF' pub fn live() {} EOF cat > "$tmp/wiki/process/law.md" <<'EOF' # Law Type: law EOF cat > "$tmp/wiki/process/knowledge.md" <<'EOF' # Notes Type: knowledge EOF git -C "$tmp" init -q git -C "$tmp" add tools crates wiki git -C "$tmp" -c user.email=fixture@example.invalid -c user.name=Fixture commit -qm base expect_pass() { local name="$1" paths="$2" mode="${3:---worktree}" if ! printf '%s\n' "$paths" | (cd "$tmp" && bash tools/design_amendment_gate.sh "$mode") >/dev/null 2>&1; then echo "FAIL: $name" exit 1 fi echo " ok passes: $name" } expect_fail() { local name="$1" paths="$2" mode="${3:---worktree}" if printf '%s\n' "$paths" | (cd "$tmp" && bash tools/design_amendment_gate.sh "$mode") >/dev/null 2>&1; then echo "FAIL: $name" exit 1 fi echo " ok rejects: $name" } expect_pass "non-source change" "README.md" expect_pass "source with binding amendment" $'crates/game/lib.rs\nwiki/process/law.md' expect_fail "source without amendment" "crates/game/lib.rs" expect_fail "knowledge page does not count" $'crates/game/lib.rs\nwiki/process/knowledge.md' expect_fail "root doorway does not count" $'src/lib.rs\nDESIGN.md' # The index mode must read the staged snapshot. An unstaged rewrite of the law # into knowledge must not make a correctly staged binding amendment fail. printf '\nAmendment.\n' >> "$tmp/wiki/process/law.md" git -C "$tmp" add wiki/process/law.md cat > "$tmp/wiki/process/law.md" <<'EOF' # Unstaged replacement Type: knowledge EOF expect_pass "index reads staged binding type" $'crates/game/lib.rs\nwiki/process/law.md' --index # A large binding page with its Type header near the top must not fail under # `set -o pipefail` when the matcher exits before a staged blob finishes # streaming. This reproduces the old `git show | grep -q` SIGPIPE boundary. { printf '# Large spec\nType: spec\n' for ((i = 0; i < 20000; i++)); do printf 'binding detail %05d\n' "$i" done } > "$tmp/wiki/process/large.md" git -C "$tmp" add wiki/process/large.md expect_pass "large staged binding page" $'crates/game/lib.rs\nwiki/process/large.md' --index # Conversely, a staged deletion is not an amendment merely because an # unstaged file with the same path exists in the worktree. git -C "$tmp" rm --cached -fq wiki/process/law.md expect_fail "staged binding deletion does not count" $'crates/game/lib.rs\nwiki/process/law.md' --index expect_fail "source deletion still requires amendment" "crates/game/lib.rs" echo "Design amendment gate fixtures: OK"