# Commit Rules — Work-Unit Commits

> Applied by `prompt-builders.ts` (`buildGroupingPrompt` / `buildSingleMessagePrompt`)
> when `prompt_rules_path` points at this file. These rules shape how commit
> messages and commit grouping are produced. They do not change staging.

## Core principle

A commit is a **reviewable work unit**, not a bucket of files. Every commit must
represent one deliverable behavior, fix, migration, or docs change that a reviewer
can understand and reason about on its own.

## Rules

1. **Commit by work unit, never by file type.**
   Do not split into `models`, then `services`, then `tests` if none of them works
   alone. Group by the behavior they combine to deliver.

2. **Keep tests with the behavior they verify.**
   Tests for a change belong in the same commit as the change, not in a trailing
   "add tests" commit.

3. **Keep docs with the user-visible change.**
   Docs that explain a feature or workflow ship with that feature, not separately.

4. **One purpose per commit.**
   If a commit needs an "and also" to justify itself, split it.

5. **The repo must make sense after each commit.**
   Applying only this commit (on top of its parent) must leave the tree coherent.
   Rollback of one commit must not revert unrelated work.

6. **Conventional Commit format, scope = the work unit.**
   - Header: `<type>(<scope>): <imperative summary>`
   - Types: `feat`, `fix`, `docs`, `refactor`, `perf`, `test`, `build`, `ci`, `chore`, `revert`.
   - `<scope>` names the work unit or domain, not a single file.
   - Body explains the **why** and the outcome, not the file list.

7. **Tell a story.**
   A reviewer should understand why each commit exists from its diff and message
   alone — without reading the PR description.

## Grouping (when many files change)

When producing multiple commits from one staging set:

- Order commits so each builds on the previous one (dependency-safe).
- Prefer fewer, coherent units over many tiny ones; prefer many small units over
  one giant commit.
- If the total change is large, each commit should be a candidate for a chained PR.

## Anti-patterns

- `chore: add models` / `chore: add services` / `test: add tests` — splits by layer.
- A commit whose body only lists files.
- A commit that bundles an unrelated refactor with a feature.
- A commit that leaves the tree broken for a later commit to "finish".
