Files
ersatztv/.husky/pre-commit
T
timothyandClaude Opus 4.8 b1e7e08884 feat(521): rework decisions guard — lifecycle validator + narrow [decisions-edit]; header + CI rewrite [decisions-edit]
Retire the line-level append-only mechanic (ersatztv#303 H9) in favor of the lifecycle validator
built in Tasks 1-5. .claude/hooks/decisions-guard.sh is now a thin fail-open shim around
scripts/decisions_validate.py; .husky/pre-commit calls it for the structural (working-tree) checks,
.husky/commit-msg drops the old staged/[decisions-edit]-deletion block and keeps only the
Co-Authored-By check. The Gitea decisions-guard job is renamed "decisions lifecycle" and now runs
decisions_validate.py --base/--head (structural + body-diff + no-vanish) and
build_decisions_catalog.py --check (active catalog drift), with actions/setup-python@v5 added since
the bare `small` lane doesn't guarantee python3; the old 1800-line consolidation-floor step is
removed (replaced by the validator's aggregate active-corpus budget). docs/decisions.md's header is
rewritten from append-only to lifecycle framing (metadata schema, statuses, generated catalog,
archive, same-PR supersession); [decisions-edit] is re-scoped (not removed) to rationale-prose
edits/factual corrections only. docs/ci-cd.md's release ritual and hook/job descriptions are
rewritten to match.

Also fixes a pre-existing validator false-positive surfaced while sanity-checking against
origin/main: Task 6's #303 H9/H3 split (commit d09be57e) renamed the archived record's heading
away from the pre-split original, which the validator's heading-based relocation check reads as
"removed without an archive copy." Restored the archived heading to match the original text
(functionally unchanged — still status: superseded, same key) and updated the two prose
cross-references (migration-map.md, release-ci-governance.md) that pointed at the old anchor.

PR1 scope only (per brief): does NOT wire the kickoff-guard CI step or touch the
kickoff/README/select-queue docs — that's Task 8/PR2.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 03:00:15 +02:00

34 lines
1.9 KiB
Plaintext
Executable File

cd web && npx lint-staged || exit 1
cd ..
# ersatztv#521 — decision-record lifecycle structural validator (replaces the old H9 append-only
# line guard). Runs the same validator the CI `decisions lifecycle` job uses, over the working
# tree (no base/head here, so only structural checks run; the body-diff/no-vanish checks run in
# CI where a base ref exists). Fail-open shim — see .claude/hooks/decisions-guard.sh.
./.claude/hooks/decisions-guard.sh || exit 1
# H3 (ersatztv#303) — never commit a screenshot dropped at the repo root. Belt-and-suspenders with
# .gitignore (catches a forced `git add -f`). Root-level *.png only; nested paths are legit assets.
root_png=$(git diff --cached --name-only --diff-filter=ACM | grep -iE '^[^/]+\.png$' || true)
if [ -n "$root_png" ]; then
echo "husky - refusing to commit root-level screenshot(s):"
printf ' %s\n' $root_png
echo " Move it out of the repo root or drop it (root *.png are review/debug artifacts; see .gitignore)."
exit 1
fi
# dotnet format on staged .cs files (repo root). Uses `whitespace . --folder` — same recipe as
# the CI `format` job (ersatztv#469): folder mode checks .editorconfig whitespace + charset (BOM)
# without the MSBuild/Roslyn workspace load, so it runs in ~0.5s instead of the old ~20-40s sln
# load. Keeping this identical to CI avoids a local hook that blocks on rules CI no longer enforces.
# Skip entirely when no .cs is staged (avoids any cost for web-only commits).
cs_files=$(git diff --cached --name-only --diff-filter=ACM -- '*.cs')
if [ -n "$cs_files" ]; then
echo "husky - dotnet format (whitespace verify) on staged .cs files"
# shellcheck disable=SC2086
dotnet format whitespace . --folder --verify-no-changes --include $cs_files || {
echo "husky - dotnet format found whitespace/BOM issues in staged .cs files; run 'dotnet format whitespace . --folder --include <files>' to fix"
exit 1
}
fi