#!/bin/sh # The zone pre-commit fragment of frontend/. Run by the dispatcher .git/hooks/pre-commit, which is # put in place by scripts/githooks/install.mjs (automatically on npm install). # For commits with no frontend paths it works in milliseconds and stays silent. # The last-resort bypass (deliberate, and it lands in no log): git commit --no-verify. staged=$(git diff --cached --name-only) [ -z "$staged" ] && exit 0 # 1) Files from the "never commit" list (CLAUDE.md, the guardrails): the owner's live brief and the # personal settings of permissions. START_PROMT.MD is tracked and often modified — a bare # `git commit -a` would carry it away in silence. forbidden=$(printf '%s\n' "$staged" | grep -E '^START_PROMT\.MD$|(^|/)\.claude/settings\.local\.json$') if [ -n "$forbidden" ]; then echo 'pre-commit: the commit holds a file from the "never commit" list (CLAUDE.md, guardrails):' >&2 printf ' %s\n' "$forbidden" >&2 echo 'Commit in the pathspec form without it: git commit -m "..." -- ' >&2 exit 1 fi # 2) A mixture of frontend/ and somebody else's zone in one commit — the picture of both incidents # of 02.08 (a bare `git commit` carried away another zone's index, D39.88). The front commits ONLY # frontend/, the other zones do not commit frontend/ — a legitimate mixture does not exist. front=$(printf '%s\n' "$staged" | grep -c '^frontend/') other=$(printf '%s\n' "$staged" | grep -cv '^frontend/') if [ "$front" -gt 0 ] && [ "$other" -gt 0 ]; then echo 'pre-commit: the commit mixes frontend/ with another zone — this is how the index of others rides away (D39.88).' >&2 echo 'Split it: git commit -m "..." -- ' >&2 printf '%s\n' "$staged" | sed 's/^/ /' >&2 exit 1 fi [ "$front" -eq 0 ] && exit 0 # 3) The quality gate of the zone: the same npm run check that the sessions run by hand — one list # of tools and not a duplicate (STACK_DECISIONS §3 "one command of checking"). if [ ! -d frontend/node_modules ]; then echo 'pre-commit: no frontend/node_modules — run npm ci in frontend/ and repeat.' >&2 exit 1 fi if ! git diff --quiet -- frontend/; then echo 'pre-commit: frontend/ has uncommitted edits outside the index; check goes over the working tree.' >&2 fi echo 'pre-commit: npm run check (frontend), ~10 s...' >&2 if ! npm --prefix frontend run check; then echo 'pre-commit: check is red — the commit is stopped. Fix it, do not go around it.' >&2 exit 1 fi