Files
gramps b5e3dbe614 Seed an AI-legible project memory map that stays small
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.
2026-10-30 06:51:19 -07:00

82 lines
2.9 KiB
Bash

#!/usr/bin/env bash
# verify.sh — the one gate before committing: doc budgets + clean build + tests + scope check.
# Usage: ./scripts/verify.sh "path/changed1" "path/changed2" ...
#
# Why a CLEAN build? An incremental build skips recompiling, so a "0 warnings" report can be a lie
# — a nullable warning slipped past exactly that way once. Clean first, then build.
#
# CONFIGURE the three commands below for the project. Empty means "skip with a warning", so a
# docs-only repo works out of the box.
set -euo pipefail
CLEAN_CMD="" # e.g. 'dotnet clean App.csproj'
BUILD_CMD="" # e.g. 'dotnet build App.csproj'
TEST_CMD="" # e.g. 'dotnet test Tests/Tests.csproj'
WARN_PATTERN=": warning" # what a compiler warning looks like in BUILD_CMD output
KNOWN_FLAKY="" # regex of pre-existing flaky test names; anything else fails the gate
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
cd "$ROOT"
echo "══ 1/4 DOC BUDGETS ══"
# The map stays cheap to read. A commit that PADS a capped file instead of moving detail out
# fails here (see AGENTS.md -> Reading budget).
check_budget() {
local rel="$1" cap="$2" lines
[ -f "$ROOT/$rel" ] || { echo " ⚠ $rel not built yet — skipped"; return 0; }
lines=$(wc -l < "$ROOT/$rel")
if [ "$lines" -gt "$cap" ]; then
echo "✗ $rel is $lines lines (cap $cap)."
echo " Move the detail to docs/ai/<topic>.md, MyMistakes.md, decisions.md or git log."
return 1
fi
printf " ✓ %-12s %3s/%s lines\n" "$rel" "$lines" "$cap"
}
budget_failed=0
check_budget "AGENTS.md" 210 || budget_failed=1
check_budget "ai.md" 100 || budget_failed=1
check_budget "HANDOFF.md" 40 || budget_failed=1
check_budget "TASKS.md" 120 || budget_failed=1
[ "$budget_failed" -eq 0 ] || exit 1
echo "══ 2/4 CLEAN BUILD (expect 0 warnings) ══"
if [ -z "$BUILD_CMD" ]; then
echo "⚠ BUILD_CMD not configured — build step skipped."
else
[ -z "$CLEAN_CMD" ] || eval "$CLEAN_CMD" > /dev/null
OUT="$(eval "$BUILD_CMD" 2>&1)"
if echo "$OUT" | grep -qI "$WARN_PATTERN"; then
echo "✗ WARNINGS FOUND:"
echo "$OUT" | grep -i "$WARN_PATTERN" | sort -u
exit 1
fi
echo "$OUT" | tail -3
echo "✓ Build clean."
fi
echo "══ 3/4 TEST SUITE ══"
if [ -z "$TEST_CMD" ]; then
echo "⚠ TEST_CMD not configured — test step skipped."
else
set +e
RUN="$(eval "$TEST_CMD" 2>&1)"
EXIT=$?
set -e
echo "$RUN" | tail -5
if [ "$EXIT" -ne 0 ]; then
if [ -n "$KNOWN_FLAKY" ] && ! echo "$RUN" | grep -iE "fail" | grep -qvE "$KNOWN_FLAKY"; then
echo "⚠ Failures, but all match the known-flaky whitelist (OK)."
else
echo "✗ TEST FAILURES — investigate."
exit 1
fi
fi
fi
echo "══ 4/4 SCOPE CHECK ══"
"$ROOT/scripts/scope-check.sh" "$@"
echo ""
echo "✓ All gates passed — safe to commit."