# Pathrule Pattern: Git & Conventional Commits (1.0.0)
# ::pathrule:package:git-conventional-commits

### [RULE] Commit messages follow Conventional Commits v1.0.0  (path: /)
<!-- scope: project | priority: high | strict -->

Format every commit as `<type>[optional scope][!]: <description>` per Conventional Commits v1.0.0 so release-please can derive versions and generate changelogs automatically.

- Allowed types: `feat`, `fix`, `docs`, `style`, `refactor`, `perf`, `test`, `build`, `ci`, `chore`, `revert`.
- Subject in imperative mood, lowercase after the colon, no trailing period, at most 52 characters; wrap body at 72.
- `feat` maps to a MINOR semver bump and `fix` to a PATCH; signal breaking changes with `!` after the type or a `BREAKING CHANGE:` footer for a MAJOR bump.
- Add a scope in parentheses when it clarifies the area, for example `fix(auth): refresh token before expiry`.
- This is enforced by commitlint in a lefthook `commit-msg` hook and repeated on the PR title since squash merge turns the PR title into the landed commit.

---

### [RULE] Short-lived branches, squash merge, no rebase of pushed branches  (path: /)
<!-- scope: project | priority: high | advisory -->

Keep integration cheap and history linear by coupling short-lived branches with squash merge.

- Cut branches from `main` and merge them back within a day or two; PRs stay under ~400 changed lines.
- Squash merge every PR so it lands as a single Conventional Commit on `main`; the PR title becomes that commit and must pass commit linting.
- Rebase your local branch onto `main` to stay current before opening a PR, but never rebase a branch others have already pulled.
- One logical change per PR so reverts are a single `git revert` with no collateral damage.

---

### [MEMORY] Commit automation stack: commitlint + lefthook + release-please  (path: /.github)

Commit hygiene is enforced at three choke points: the local commit hook, the CI PR-title check, and the release pipeline.

- `@commitlint/cli` with `@commitlint/config-conventional` validates messages via a `lefthook` `commit-msg` hook, so a bad message is rejected before it is committed.
- Because we squash merge, the PR title becomes the final commit subject. A GitHub Actions workflow lints the PR title against the same rules using `amannn/action-semantic-pull-request`.
- `release-please` watches commits on `main`, computes the semver bump from the highest type (`feat` = MINOR, `fix` = PATCH, `!` or `BREAKING CHANGE` = MAJOR), opens a release PR with a generated `CHANGELOG.md`, and cuts the GitHub Release on merge.
- Keep `lefthook.yml` and `commitlint.config.ts` at the repo root; keep GitHub Actions workflows under `/.github/workflows`.
- A `feat!: description` commit, or any commit with a `BREAKING CHANGE:` footer, triggers a MAJOR bump and requires explicit team acknowledgment before merge.

---

### [SKILL] git-conventional-commits-review  (path: /)

---
name: git-conventional-commits-review
description: Checklist to run before committing and before opening a PR so commits follow Conventional Commits v1.0.0, branches stay short-lived, and PRs are small and reviewable. Use when writing a commit, opening a pull request, or auditing git history hygiene.
---

# Git & Conventional Commits review

## Commit message

- [ ] Subject matches `<type>[scope][!]: <description>` using an allowed type (`feat`, `fix`, `docs`, `style`, `refactor`, `perf`, `test`, `build`, `ci`, `chore`, `revert`).
- [ ] Subject is imperative mood, lowercase after the colon, no trailing period, and at most 52 characters.
- [ ] Body (if present) explains the why, wraps at 72 characters, and references issues in the footer.
- [ ] Breaking changes are flagged with `!` or a `BREAKING CHANGE:` footer so the MAJOR bump is computed correctly.

## Branch and PR hygiene

- [ ] Branch is short-lived and freshly rebased onto `main`; no rebase of commits already pushed to a shared branch.
- [ ] PR is under ~400 changed lines, or has a clear note explaining why it is larger.
- [ ] PR does one logical thing; unrelated changes are in separate branches.
- [ ] PR title is itself a valid Conventional Commit, since squash merge turns it into the landed commit on `main`.

## Automation

- [ ] `commitlint` passes locally (lefthook `commit-msg` hook ran without error).
- [ ] PR-title lint check is green in CI.
- [ ] If a `BREAKING CHANGE` or `feat!` is included, the team has explicitly acknowledged the MAJOR semver bump.
