One file (AGENTS.md) that bootstraps the rest: rules, the file map to create, what belongs in each file, the first-session interview order, and the list of anti-patterns that killed the previous map (1,308-line guide, 63 task files, narrative history inline, sessions skimming 56k tokens of context). Separates four kinds of content by read frequency: rules/invariants -> AGENTS.md (every session) subsystem truth -> docs/ai/<topic>.md (only the matching one) lookups -> environment.md (grepped, never read) retired decisions -> decisions.md (only when re-opening one) Caps are enforced, not promised: scripts/verify.sh checks doc budgets before the build, so a commit that pads a capped file fails. Proven both ways — it passes clean and exits 1 on an over-cap file. scripts/scope-check.sh blocks edits outside the declared file list. templates/ holds fill-in skeletons for the seven files a project must create. CC0: copy it, rename it, sell it, no attribution needed.
58 lines
1.5 KiB
Bash
58 lines
1.5 KiB
Bash
#!/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
|