Implement the 006-pre-commit-gate feature that enforces a pre-commit quality gate using Lefthook to run pnpm check before every commit
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
88
specs/006-pre-commit-gate/spec.md
Normal file
88
specs/006-pre-commit-gate/spec.md
Normal file
@@ -0,0 +1,88 @@
|
||||
# Feature Specification: Pre-Commit Gate
|
||||
|
||||
**Feature Branch**: `006-pre-commit-gate`
|
||||
**Created**: 2026-03-05
|
||||
**Status**: Draft
|
||||
**Input**: User description: "Enforce a pre-commit gate: block commits unless `pnpm check` passes."
|
||||
|
||||
## User Scenarios & Testing *(mandatory)*
|
||||
|
||||
### User Story 1 - Blocked Commit on Failing Checks (Priority: P1)
|
||||
|
||||
A developer attempts to commit code that does not pass `pnpm check` (format, lint, typecheck, or test failures). The commit is automatically rejected with a clear message indicating what failed, preventing broken code from entering the repository.
|
||||
|
||||
**Why this priority**: This is the core purpose of the feature -- preventing commits that violate project quality standards.
|
||||
|
||||
**Independent Test**: Can be tested by introducing a deliberate lint or type error, attempting to commit, and verifying the commit is blocked with an informative error message.
|
||||
|
||||
**Acceptance Scenarios**:
|
||||
|
||||
1. **Given** a developer has staged changes that fail formatting, **When** they run `git commit`, **Then** the commit is rejected and the output shows the formatting errors.
|
||||
2. **Given** a developer has staged changes that fail linting, **When** they run `git commit`, **Then** the commit is rejected and the output shows the lint errors.
|
||||
3. **Given** a developer has staged changes that fail typechecking, **When** they run `git commit`, **Then** the commit is rejected and the output shows the typecheck errors.
|
||||
4. **Given** a developer has staged changes that fail tests, **When** they run `git commit`, **Then** the commit is rejected and the output shows the test failures.
|
||||
|
||||
---
|
||||
|
||||
### User Story 2 - Successful Commit on Passing Checks (Priority: P1)
|
||||
|
||||
A developer commits code that passes all checks. The pre-commit gate runs `pnpm check`, all checks pass, and the commit proceeds normally without extra friction.
|
||||
|
||||
**Why this priority**: Equally critical -- the gate must not block valid commits. A gate that only blocks but never allows is useless.
|
||||
|
||||
**Independent Test**: Can be tested by making a valid code change, committing, and verifying the commit succeeds after checks pass.
|
||||
|
||||
**Acceptance Scenarios**:
|
||||
|
||||
1. **Given** a developer has staged changes that pass all checks, **When** they run `git commit`, **Then** `pnpm check` runs and the commit completes successfully.
|
||||
|
||||
---
|
||||
|
||||
### User Story 3 - Bypass Gate in Emergencies (Priority: P2)
|
||||
|
||||
A developer needs to bypass the pre-commit gate in an emergency situation (e.g., a hotfix where the existing codebase already has a known issue). They can use the standard Git `--no-verify` flag to skip the hook.
|
||||
|
||||
**Why this priority**: Important escape hatch, but not the primary use case. Standard Git behavior should be preserved.
|
||||
|
||||
**Independent Test**: Can be tested by attempting `git commit --no-verify` with failing checks and verifying the commit succeeds.
|
||||
|
||||
**Acceptance Scenarios**:
|
||||
|
||||
1. **Given** a developer has staged changes that fail checks, **When** they run `git commit --no-verify`, **Then** the commit proceeds without running the pre-commit gate.
|
||||
|
||||
---
|
||||
|
||||
### Edge Cases
|
||||
|
||||
- What happens when `pnpm` is not installed or not in PATH? The hook should fail with a clear error message.
|
||||
- What happens when `node_modules` are not installed? The hook should fail with a clear error message suggesting `pnpm install`.
|
||||
- What happens when the hook is run outside the project root? The hook should resolve the project root correctly.
|
||||
- What happens on a fresh clone? The hook must be automatically available after `pnpm install` without additional manual steps.
|
||||
|
||||
## Requirements *(mandatory)*
|
||||
|
||||
### Functional Requirements
|
||||
|
||||
- **FR-001**: The repository MUST include a Git pre-commit hook that runs `pnpm check` before every commit.
|
||||
- **FR-002**: The hook MUST block the commit (exit non-zero) if `pnpm check` fails.
|
||||
- **FR-003**: The hook MUST allow the commit (exit zero) if `pnpm check` succeeds.
|
||||
- **FR-004**: The hook MUST display the output from `pnpm check` so the developer can see what failed.
|
||||
- **FR-005**: The hook MUST be automatically available to all developers after cloning and running `pnpm install` (no manual hook installation steps).
|
||||
- **FR-006**: The hook MUST be bypassable using the standard `git commit --no-verify` flag.
|
||||
- **FR-007**: The hook MUST provide a clear error message if `pnpm` is not available.
|
||||
|
||||
## Success Criteria *(mandatory)*
|
||||
|
||||
### Measurable Outcomes
|
||||
|
||||
- **SC-001**: 100% of commits made without `--no-verify` are validated by `pnpm check` before being accepted.
|
||||
- **SC-002**: Developers see check results within the normal `pnpm check` execution time -- the hook adds no meaningful overhead beyond running the checks themselves.
|
||||
- **SC-003**: New contributors can clone the repository, run `pnpm install`, and have the pre-commit gate active without any additional setup steps.
|
||||
- **SC-004**: Developers can identify the specific failing check (format, lint, typecheck, or test) from the hook output alone.
|
||||
|
||||
## Assumptions
|
||||
|
||||
- The project already has a working `pnpm check` command that runs format, lint, typecheck, and test checks.
|
||||
- All developers use Git for version control.
|
||||
- The hook management approach uses Lefthook, a lightweight Git hooks manager distributed as an npm package, with a `prepare` script for auto-installation.
|
||||
- MVP baseline does not include partial/staged-only checking (e.g., lint-staged). The full `pnpm check` runs on the entire project.
|
||||
Reference in New Issue
Block a user