# Git hooks ``` Status: Current Owner: Last reviewed: Governs: docs/architecture/githooks/** and the .githooks/ a project installs Review trigger: A new guard the repository wants run before a commit; any change to what a commit message must contain. ``` Three hooks, and the reason they live in the repository rather than in `.git/hooks`: that directory is not versioned, so a hook living there protects exactly one clone on exactly one machine. These are committed, and one command points git at them. ## Install ```bash mkdir -p .githooks cp docs/architecture/githooks/{pre-commit,commit-msg,post-commit} .githooks/ chmod +x .githooks/* git config core.hooksPath .githooks ``` `core.hooksPath` is per-clone, so every checkout runs that last line once. Say so in the project README — an uninstalled hook fails silently, which is the same class of problem the hooks exist to prevent. ## What each one does | Hook | Guard | | --- | --- | | `pre-commit` | typecheck, then the test suite, when `.ts`/`.tsx` is staged | | `commit-msg` | refuses a message with no conventional type | | `post-commit` | pushes to the remote, so a guarded commit does not sit locally | ## Two settings worth making before you rely on them **`pre-commit` will use a local test database if you tell it where one is.** Set `TEST_DB_PORT` and `TEST_DB_URL` together. Leave them unset and the database suites skip, which is the right default on a machine with no Postgres — but it means the hook is running a fraction of the suite, so `release.sh` is deliberately stricter and refuses rather than warns. **`post-commit` pushes.** That is the intent — the commit that first added a pre-commit hook to the reference project sat unpushed for a day, guarded and invisible — but it is a surprise if you were not expecting it. Read it before installing it on a repository with a protected branch. It has a second consequence worth knowing about: the push is what the Command Center reads, so **whatever documentation was not in that commit is now behind the code by one push**. That is the mechanical reason `docs/WORK_CYCLE.md` asks for doc edits in the same commit as the change rather than in a tidy-up afterwards — with this hook installed, "I will document it next commit" means the site has already published the version without it. ## Why a hook and not CI Both. These are the guards that must run before the artifact exists: a hook that fires after a push, or a CI job that fires after a publish, catches the problem once it is already somewhere it cannot be taken back from. CI is the second opinion; this is the one that runs first.