#!/usr/bin/env bash # Enforce Invariant I1: no upstream-tracked file is ever edited. # Exits 0 on clean state, 1 on violation. # # Catches BOTH committed drift (commits unique to HEAD vs upstream/master) # AND working-tree drift (uncommitted local edits to tracked files). # # Spec: sethlabels-docs/specs/2026-04-29-packaging-design.md §5.5 (I1, F1) set -euo pipefail # Allowlist: files/dirs sethLabels is permitted to add or modify. # `.gitignore` is the one upstream-file exception (called out in spec §2). allowed_pattern='^\.gitignore$|^\.claude/|^scripts/|^packaging/|^sethlabels-docs/|^tests-impl/|^README\.sethlabels\.md$|^CLAUDE\.md$|^IDEA\.md$|^DECISIONS\.md$' committed=$(git diff --name-only upstream/master..HEAD 2>/dev/null || true) working=$(git diff --name-only HEAD 2>/dev/null || true) all_changes=$(printf "%s\n%s\n" "$committed" "$working" | sort -u | sed '/^$/d') if [ -z "$all_changes" ]; then exit 0 fi violations=$(echo "$all_changes" | grep -vE "$allowed_pattern" || true) if [ -n "$violations" ]; then echo "ERROR: strict-zero policy violated. The following upstream files have been modified:" echo "$violations" echo "" echo "See sethlabels-docs/specs/2026-04-29-packaging-design.md §I1." exit 1 fi exit 0