Scope Lock: pre-task declaration, git history scan, pre-commit audit script
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
#!/usr/bin/env bash
|
||||
# scope-check.sh — Validate that git diff only touches declared files.
|
||||
# Usage: ./scripts/scope-check.sh "file1.cs" "file2.cs" ...
|
||||
# Exit 0 if all changed files are in scope, 1 if any are outside.
|
||||
#
|
||||
# Checks staged, unstaged, and untracked changes against the allowed list.
|
||||
# Supports glob patterns in the allowed list (e.g. "ytLive.Tests/*").
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
echo "Usage: $0 \"file1.cs\" \"file2.cs\" ..."
|
||||
echo " Pass the declared file list as arguments."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Collect allowed patterns into an array
|
||||
allowed=("$@")
|
||||
|
||||
# Gather all changed files: working tree vs HEAD (tracked) + staged + untracked
|
||||
changed=$({
|
||||
git diff --name-only HEAD 2>/dev/null || true
|
||||
git diff --name-only --cached 2>/dev/null || true
|
||||
git ls-files --others --exclude-standard 2>/dev/null || true
|
||||
} | sort -u)
|
||||
|
||||
if [ -z "$changed" ]; then
|
||||
echo "✓ No changes detected."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
violations=()
|
||||
while IFS= read -r file; do
|
||||
matched=false
|
||||
for pattern in "${allowed[@]}"; do
|
||||
if [[ "$file" == $pattern ]]; then
|
||||
matched=true
|
||||
break
|
||||
fi
|
||||
done
|
||||
if [ "$matched" = false ]; then
|
||||
violations+=("$file")
|
||||
fi
|
||||
done <<< "$changed"
|
||||
|
||||
if [ ${#violations[@]} -eq 0 ]; then
|
||||
echo "✓ Scope check passed — all changed files are in scope."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "✗ SCOPE VIOLATION — the following files are outside the declared scope:"
|
||||
for f in "${violations[@]}"; do
|
||||
echo " - $f"
|
||||
done
|
||||
echo ""
|
||||
echo "Either justify the edit or revert the change."
|
||||
exit 1
|
||||
Reference in New Issue
Block a user