| name | conventional-commits |
| description | Commit message format rules. Use whenever staging, committing, or describing changes -- including when the user asks to commit, when preparing a PR, or when writing a changelog entry. NOTE: Never commit autonomously. Always prepare a message and ask for user approval before committing. |
Conventional Commits -- Message Format
Iron Laws
- Never commit autonomously. Show the staged diff and the proposed message; wait for explicit user approval before executing the commit. Reformatting hooks may modify files mid-commit -- that is not approval to keep going on a different commit.
- Every commit gets a type. No untyped commits. Subject line is
<type>[optional scope]: <description>.
- One logical change per commit. Don't bundle a feature with a refactor; don't sweep unrelated files in with
git add -u. Stage the specific paths you intend to ship.
feat and fix are the only version-bumping types. Mark breaking changes with ! after the type/scope or a BREAKING CHANGE: footer (equivalent; both trigger a major bump).
- Subject line is imperative, lowercase after the colon, no trailing period, ≤72 chars. Body wraps at 72 and explains what and why, not how.
- Re-stage after auto-formatting hooks; reuse the original message. Hook reformat → reject → re-stage → retry is the normal workflow, not a new commit.
When This Skill Applies
Whenever writing a commit message, PR title, or changelog entry. This includes interactive commits, automated commits, and squash-merge titles.
This skill defines message format only. For how to execute git operations (staging, committing, pushing), follow tool-usage -- it determines whether to use GitKraken MCP tools, GitHub MCP tools, or terminal commands based on what is available.
Format
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]
Types
| Type | Meaning | Version bump |
|---|
feat | New feature or capability | minor (0.1.0 → 0.2.0) |
fix | Bug fix | patch (0.1.0 → 0.1.1) |
docs | Documentation only | none |
style | Formatting, whitespace, semicolons | none |
refactor | Code change that neither fixes nor adds | none |
perf | Performance improvement | none |
test | Adding or correcting tests | none |
build | Build system, dependencies, CI config | none |
ci | CI pipeline changes | none |
chore | Maintenance tasks (tooling, config) | none |
revert | Reverts a previous commit | depends on reverted type |
Scope
Optional. Narrows the area of change to a module or subsystem name (auth, api, models, cli, config, deps, release). Scopes should be short, stable, and map to subsystems or directories.
Description
Imperative mood ("add", "fix", "remove" -- not "added", "fixes", "removed"). Lowercase first letter after the colon. No trailing period. ≤72 chars including type and scope.
Body
Optional. Wrap at 72. Explain what and why, not how.
Footers
BREAKING CHANGE: <description> -- triggers major bump
Refs: #123 -- links to an issue
Co-authored-by: Name <email> -- attribution
Squash-merge PRs
The PR title becomes the squash commit message and must follow the same format.
For worked examples, read references/examples.md.
Pre-Commit Quality Gate
Before every commit, the agent must run the project's quality gate and verify it passes. Do not commit with a failing gate.
- Lint/format/type: Run
pre-commit run or task check (whichever the project uses). All checks must pass.
- Coverage: Run
task cov and verify 100% line + branch coverage on new/modified code. See the bdd-testing skill for coverage requirements and remediation procedure.
If either step fails, fix the issues and re-run before attempting the commit. Do not skip coverage because lint passed.
Pre-Commit Hooks
Pre-commit hooks (or equivalent staged-file checks) may run before a commit is accepted. Commits can fail at the hook stage until staged files satisfy the configured quality gates.
Auto-formatting and re-staging
Many hooks reformat staged files in place (Ruff, Black, Prettier, google-java-format). When this happens:
- The hook modifies the working-tree copy of the file.
- The commit is rejected because the staged content no longer matches.
- Re-stage the modified files and retry with the same message.
This is normal workflow, not an error. Iron Law 6.
Formatting a file on demand
To get a file formatted without making a real change:
- Make a trivial edit (e.g., add a blank line).
- Stage the file.
- Attempt a commit -- the hooks reformat it.
- Re-stage the reformatted file and commit (or reset the commit if the only purpose was formatting).
Useful when a file predates the hooks or was edited outside the project's toolchain.
Persistent failures after re-staging
If the commit still fails after re-staging the auto-formatted output, the remaining violations are not auto-fixable -- typically lint or type-check errors requiring manual intervention. Read the hook output, fix each reported issue, re-stage, and retry.
Activating hooks
Activation depends on the project's toolchain. Python projects using the canonical setup use:
pre-commit install
This only needs to be run once per clone. See the language-specific standards skill for your active stack (e.g., python-code-standards).
On Invocation
Emit skill.invoked when this skill is first read:
~/.agents/bin/emit-telemetry skill.invoked conventional-commits
- Stage exactly the files you intend to ship (Iron Law 3).
- Draft the commit message in the format above.
- Show the user the staged diff and the proposed message. Wait for explicit approval.
~/.agents/bin/emit-telemetry compliance.check conventional-commits 0 "commit" commit_approval_received pass "Staged diff and proposed message shown; explicit user approval received before committing."
- Execute the commit per
tool-usage.
- If a hook reformats files, re-stage and retry with the same message (Iron Law 6).
- If the hook reports non-auto-fixable violations, fix them, re-stage, retry.
~/.agents/bin/emit-telemetry skill.completed conventional-commits success "Commit executed with user approval."
Why This Exists
Semantic release tools (semantic-release, python-semantic-release, release-please) read commit messages to determine version bumps automatically. Without consistent conventional commits, the automation cannot tell whether a change is a feature, fix, or breaking change -- and either bumps incorrectly or not at all.