Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

A-26004: Hook Stage Assignment Rationale


title: Hook Stage Assignment Rationale date: 2026-03-07 tags:


A-26004: Hook Stage Assignment Rationale

Problem Statement

The project uses three Git hook stages (pre-commit, commit-msg, post-commit) with different hooks assigned to each. The rationale for why each hook runs at its particular stage has never been explicitly documented. Source S-26003 (a Gemini 3 Flash dialogue) raises the question: is post-commit ever appropriate for validation, or should all validation move to blocking stages?

This analysis codifies the stage assignment rationale and validates that the current hook architecture is sound.

Key Insights

The Three-Stage Model

Git hooks form a pipeline with fundamentally different failure semantics:

StageTimingOn failureAppropriate for
pre-commitBefore commit message editor opensAborts — no commit createdContent validation (links, sync, secrets)
commit-msgAfter message written, before commit finalizedAborts — no commit createdMessage format validation
post-commitAfter commit hash exists in historyCannot abort — commit already existsNotifications, previews, informational output

The critical distinction: pre-commit and commit-msg are blocking (exit non-zero = commit aborted), while post-commit is non-blocking (exit non-zero = warning only, commit persists).

Current Hook Assignments

Hook IDStageBlocking?Rationale
check-broken-linkspre-commitYesContent must be valid before message is written
check-link-formatpre-commitYesLink syntax is a content concern
jupytext-syncpre-commitYesNotebook pairs must be synchronized before commit
jupytext-verifypre-commitYesVerifies sync succeeded
detect-api-keyspre-commitYesSecurity gate — must block before secrets enter history
validate-jsonpre-commitYesStructural validity of data files
test-scriptspre-commitYesScripts must pass their tests
validate-commit-msgcommit-msgYesMessage format is a message-stage concern
changelog-previewpost-commitNoInformational — shows what CHANGELOG entry the commit will produce

Validation of Current Architecture

S-26003 warns against using post-commit for validation because:

  1. Failed validation cannot undo the commit

  2. Attempted fixes (e.g., --amend) create new hashes and potential loops

  3. The developer sees errors after the damage is done

The current architecture correctly follows this principle:

Conclusion: No architecture change is needed. The stage assignments are sound.

References