Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ page that documents it.

| Version | What changed | Documented in |
|---|---|---|
| [2.20.3](#v2203) | Failures print a one-line header and an indented block per check, in place of the ASCII banner; an agent skill for coding agents | [Getting started](getting-started.md#2-watch-it-reject-something) · [With AI coding agents](guides/ai-agents.md#tell-the-agent) |
| [2.20.1](#v2201) | `--ai-attribution-only` checks a pull request description against your AI policy; JSON lists the AI tools found; more AI marks recognised | [Checking a pull request description](guides/policies.md#checking-a-pull-request-description) · [CC013](rules.md#cc013) |
| [2.20.0](#v2200) | Commits authored by an AI tool rejected; subject length `0` turns the rule off; Python 3.11+ required | [CC017](rules.md#cc017) · [CC013](rules.md#cc013) · [CC004](rules.md#cc004) |
| [2.19.5](#v2195) | GitHub merge queue branches accepted by default; aider's default co-author trailer recognised; exit 2 when git cannot read the repository | [CC201](rules.md#cc201) · [CC013](rules.md#cc013) · [Exit codes](troubleshoot.md#exit-codes) |
Expand Down Expand Up @@ -38,6 +39,29 @@ page that documents it.
| [2.5.0](#v250) | Organization-wide config with `inherit_from` | [Across an organization](guides/organization.md) |
| [2.0.0](#v200) | Configuration moved from YAML to TOML — breaking | [Migrating from v1](migration.md) |

## v2.20.4 (2026-11-10) { #v2204 }

### Fixed

* `require_body` no longer takes trailers alone, such as the `Signed-off-by:` line from `git commit -s`, for a body. ([CC011](rules.md#cc011), [#689](https://github.com/commit-check/commit-check/pull/689))
* `ignore_authors` written as one string is split on commas, instead of skipping any author whose name is part of it. ([Every option](configuration.md#every-option), [#689](https://github.com/commit-check/commit-check/pull/689))
* `--author-name` and `--author-email` honour `git commit --author` and the `author.name` and `author.email` settings. ([Checking the committer](example.md#checking-the-committer), [#689](https://github.com/commit-check/commit-check/pull/689))

## v2.20.3 (2026-11-10) { #v2203 }

### Added

* An agent skill teaches coding agents to check a message before they commit. ([With AI coding agents](guides/ai-agents.md#tell-the-agent), [#679](https://github.com/commit-check/commit-check/pull/679), [#686](https://github.com/commit-check/commit-check/pull/686))

### Changed

* A failure prints a one-line header and an indented block per check, in place of the ASCII banner. ([Getting started](getting-started.md#2-watch-it-reject-something), [#682](https://github.com/commit-check/commit-check/pull/682))

### Fixed

* CC017 on a message that is not committed yet suggests setting your own `user.name` and `user.email`, not amending. ([CC017](rules.md#cc017), [#685](https://github.com/commit-check/commit-check/pull/685))
* `--ai-attribution-only` with no text piped in passes, instead of judging `HEAD`. ([Guide](guides/policies.md#checking-a-pull-request-description), [#684](https://github.com/commit-check/commit-check/pull/684))

## v2.20.2 (2026-11-08) { #v2202 }

### Changed
Expand Down
2 changes: 1 addition & 1 deletion docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ conventional_branch = true
```

A warned rule prints the same block as a failure with `warning` in place of
`failed`, no rejection banner, and one closing line saying the run is not
`failed`, no rejection header, and one closing line saying the run is not
failed by it; with `--compact` it is one `[WARN]` line. A one-line notice on
stderr names the warned rules, so a hook that exits `0` after red-looking
output is not mistaken for a broken hook. The exit code counts only enforced
Expand Down
15 changes: 10 additions & 5 deletions docs/example.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,12 @@ revision.

```console
$ echo "updated the parser" | commit-check -m
CC001 message check failed ==> updated the parser
The commit message should follow Conventional Commits. See https://www.conventionalcommits.org
Suggest: Use <type>(<scope>): <description>, where <type> is one of: feat, fix, ...
Docs: https://commit-check.com/rules/#cc001
✖ Commit rejected by Commit Check · 1 check failed

✖ CC001 message failed: updated the parser
The commit message should follow Conventional Commits. See https://www.conventionalcommits.org
Suggest: Use <type>(<scope>): <description>, where <type> is one of: feat, fix, docs, style, refactor, test, chore, perf, build, ci
Docs: https://commit-check.com/rules/#cc001
```

Fix it and it goes quiet:
Expand Down Expand Up @@ -140,6 +142,9 @@ tighten them.

Without `--rev`, these validate the *local git config* — whoever is about to
commit — falling back to `HEAD`'s author only when no identity is configured.
The identity is read in git's order: `GIT_AUTHOR_NAME` and
`GIT_AUTHOR_EMAIL` when set, then `author.name` and `author.email`, then
`user.name` and `user.email`.
That is the right subject for a hook and the wrong one for CI: an existing
commit's identity is a fact about the commit, not about the operator running
the check. Add `--rev` and both checks read that commit's recorded author, and
Expand Down Expand Up @@ -206,7 +211,7 @@ and how CLI, environment and file settings override each other.

=== "No banner"

Plain text without the ASCII art, which is noise in a CI log.
Plain text without the one-line header that counts the failed checks.

```console
$ commit-check -m --no-banner
Expand Down
25 changes: 15 additions & 10 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,18 +67,21 @@ $ commit-check --message
```

```text
CC001 message check failed ==> updated the parser
The commit message should follow Conventional Commits. See https://www.conventionalcommits.org
Suggest: Use <type>(<scope>): <description>, where <type> is one of: feat, fix, docs, ...
Docs: https://commit-check.com/rules/#cc001
✖ Commit rejected by Commit Check · 1 check failed

✖ CC001 message failed: updated the parser
The commit message should follow Conventional Commits. See https://www.conventionalcommits.org
Suggest: Use <type>(<scope>): <description>, where <type> is one of: feat, fix, docs, style, refactor, test, chore, perf, build, ci
Docs: https://commit-check.com/rules/#cc001
```

Four things are happening in that output, and each is deliberate:
The first line counts the failed checks. Each failure under it carries four
things, and each is deliberate:

| Part | What it gives you |
|---|---|
| `CC001` | A stable rule ID. It will mean the same thing in five years. |
| `==> updated the parser` | The exact value that failed, not just "invalid message". |
| `updated the parser` | The exact value that failed, not just "invalid message". |
| `Suggest:` | What to do about it. |
| `Docs:` | Why the rule exists, and how to configure or disable it. |

Expand All @@ -99,10 +102,12 @@ $ commit-check --branch
```

```text
CC201 branch check failed ==> my-changes
The branch should follow Conventional Branch. See https://conventionalbranch.org
Suggest: Use <type>/<description> with an allowed type, or add the branch to allow_branch_names in config
Docs: https://commit-check.com/rules/#cc201
✖ Branch rejected by Commit Check · 1 check failed

✖ CC201 branch failed: my-changes
The branch should follow Conventional Branch. See https://conventionalbranch.org
Suggest: Use <type>/<description> with an allowed type, or add the branch to allow_branch_names in config
Docs: https://commit-check.com/rules/#cc201
```

Rename it to something structured and it passes:
Expand Down
49 changes: 28 additions & 21 deletions docs/guides/policies.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,10 +133,12 @@ ai_attribution = "forbid"
Commits carrying a recognised AI signature now fail:

```text
CC013 ai-attribution check failed ==> Claude Code
AI attribution is forbidden in this project — detected: Claude Code
Suggest: This project does not accept AI attribution in commit messages. Remove the AI trailer lines and re-commit.
Docs: https://commit-check.com/rules/#cc013
✖ Commit rejected by Commit Check · 1 check failed

✖ CC013 ai-attribution failed: Claude Code
AI attribution is forbidden in this project — detected: Claude Code
Suggest: This project does not accept AI attribution in commit messages. Remove the AI trailer lines and re-commit.
Docs: https://commit-check.com/rules/#cc013
```

Recognised signatures are co-author and sign-off lines naming Claude Code,
Expand Down Expand Up @@ -255,15 +257,17 @@ A commit that a vendor stamped and nobody disclosed fails the first two, and
the failure carries the disclosure already written:

```text
CC014 ai-disclosure check failed ==> Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
AI assistance is not disclosed with Assisted-by or Generated-by — detected: Claude Code
Suggest: Disclose the tool with "Assisted-by: Claude Opus 5"
Docs: https://commit-check.com/rules/#cc014

CC015 ai-co-author check failed ==> Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
An AI tool is credited as a co-author: Claude Code
Suggest: Use "Assisted-by: Claude Opus 5" in place of the co-author line
Docs: https://commit-check.com/rules/#cc015
✖ Commit rejected by Commit Check · 2 checks failed

✖ CC014 ai-disclosure failed: Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
AI assistance is not disclosed with Assisted-by or Generated-by — detected: Claude Code
Suggest: Disclose the tool with "Assisted-by: Claude Opus 5"
Docs: https://commit-check.com/rules/#cc014

✖ CC015 ai-co-author failed: Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
An AI tool is credited as a co-author: Claude Code
Suggest: Use "Assisted-by: Claude Opus 5" in place of the co-author line
Docs: https://commit-check.com/rules/#cc015
```

Both carry the same correction in `--format json`: the co-author line rewritten
Expand Down Expand Up @@ -306,9 +310,12 @@ ai_disclosure_pattern = '^\S+/\S+$'
```

```text
CC014 ai-disclosure check failed ==> Assisted-by: Claude Code
The Assisted-by value does not match the required pattern: ^\S+/\S+$
Suggest: Write the Assisted-by value so that it matches ^\S+/\S+$ (set by ai_disclosure_pattern in the [commit] config)
✖ Commit rejected by Commit Check · 1 check failed

✖ CC014 ai-disclosure failed: Assisted-by: Claude Code
The Assisted-by value does not match the required pattern: ^\S+/\S+$
Suggest: Write the Assisted-by value so that it matches ^\S+/\S+$ (set by ai_disclosure_pattern in the [commit] config)
Docs: https://commit-check.com/rules/#cc014
```

That failure carries no correction, because the tool should not guess which
Expand All @@ -330,11 +337,11 @@ ai_attribution = "disclose"
```

```text
CC014 ai-disclosure check warning ==> 🤖 Generated with [Claude
AI assistance is not disclosed with Assisted-by or Generated-by — detected: Claude Code
Suggest: Disclose the tool with "Assisted-by: Claude Code"
Docs: https://commit-check.com/rules/#cc014
This rule is set to warn in the config; it does not fail the run.
▲ CC014 ai-disclosure warning: 🤖 Generated with [Claude
AI assistance is not disclosed with Assisted-by or Generated-by — detected: Claude Code
Suggest: Disclose the tool with "Assisted-by: Claude Code"
Docs: https://commit-check.com/rules/#cc014
This rule is set to warn in the config; it does not fail the run.
```

The run still passes. The warning still suggests a disclosure that pip and
Expand Down
22 changes: 11 additions & 11 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ description: Commit policy as code for teams and AI agents. Messages, branches,
</div>
</div>
<!--
A transcript of a real run: commit-check 2.18.0 as a pre-commit
commit-msg hook. The hook also prints an ASCII-art banner between
"exit code: 1" and the CC001 line; it is left out, nothing else is.
A transcript of a real run: commit-check 2.20.4 as a pre-commit
commit-msg hook. Git's own "1 file changed" summary after the last
line is left out, nothing else is.
-->
<figure class="cc-term" aria-label="A commit-msg hook rejects a commit message, suggests the fix, then accepts the corrected message">
<div class="cc-term__bar" aria-hidden="true"><span class="cc-dots"><i></i><i></i><i></i></span><span>~/app · feature/streaming · commit-msg hook</span></div>
Expand All @@ -50,14 +50,14 @@ description: Commit policy as code for teams and AI agents. Messages, branches,
<div class="cc-line cc-row" data-on="2500"><span>check commit message</span><span class="cc-leader" aria-hidden="true"></span><span class="cc-t-fail">Failed</span></div>
<div class="cc-line cc-t-dim" data-on="2650">- hook id: check-message</div>
<div class="cc-line cc-t-dim" data-on="2750">- exit code: 1</div>
<div class="cc-line cc-gap" data-on="2900">Commit rejected by Commit-Check.</div>
<div class="cc-line" data-on="3100"><span class="cc-t-fail cc-b">CC001</span> message check failed ==&gt; Fix: add streaming support</div>
<div class="cc-line cc-t-dim" data-on="3250">The commit message should follow Conventional Commits. See https://www.conventionalcommits.org</div>
<div class="cc-line" data-on="3400"><span class="cc-t-blue">Suggest:</span> Use "<span class="cc-t-pass cc-b">fix: add streaming support</span>"</div>
<div class="cc-line cc-t-dim" data-on="3500">Docs: https://commit-check.com/rules/#cc001</div>
<div class="cc-line cc-gap" data-on="2900"><span class="cc-t-fail cc-b">✖ Commit rejected by Commit Check</span><span class="cc-t-dim"> · 1 check failed</span></div>
<div class="cc-line cc-gap" data-on="3100"><span class="cc-t-fail cc-b">✖ CC001</span> message failed: Fix: add streaming support</div>
<div class="cc-line cc-t-dim" data-on="3250"> The commit message should follow Conventional Commits. See https://www.conventionalcommits.org</div>
<div class="cc-line" data-on="3400"> <span class="cc-t-blue">Suggest:</span> Use "<span class="cc-t-pass cc-b">fix: add streaming support</span>"</div>
<div class="cc-line cc-t-dim" data-on="3500"> Docs: https://commit-check.com/rules/#cc001</div>
<div class="cc-line cc-gap" data-on="5200"><span class="cc-sigil">❯ </span><span data-type="5600" data-speed="42">git commit -m "fix: add streaming support"</span><i class="cc-caret" data-from="5200" data-until="7700"></i></div>
<div class="cc-line cc-row" data-on="7700"><span>check commit message</span><span class="cc-leader" aria-hidden="true"></span><span class="cc-t-pass">Passed</span></div>
<div class="cc-line cc-t-dim" data-on="7900">[feature/streaming 77663ff] fix: add streaming support</div>
<div class="cc-line cc-t-dim" data-on="7900">[feature/streaming 276fd07] fix: add streaming support</div>
</div>
</figure>
</div>
Expand Down Expand Up @@ -409,10 +409,10 @@ conventional_branch = <span class="cc-t-pass">true</span></div>
<li><span><b>A fix you can paste</b>, whenever the correction is unambiguous.</span></li>
</ol>
</div>
<!-- Real output of commit-check 2.19.2; the ASCII-art banner it prints first is left out. -->
<!-- Real output of commit-check 2.20.4, laid out in numbered rows; the one-line header it prints first is left out. -->
<div class="cc-diag">
<p class="cc-t-dim">$ echo "Fix: add streaming support" | commit-check -m</p>
<p><span class="cc-mark">1</span><span><span class="cc-t-fail cc-b">CC001</span> message check failed ==&gt;</span></p>
<p><span class="cc-mark">1</span><span><span class="cc-t-fail cc-b">✖ CC001</span> message failed:</span></p>
<p><span class="cc-mark">2</span><span class="cc-t-white">Fix: add streaming support</span></p>
<p><span class="cc-mark">3</span><span class="cc-t-dim">The commit message should follow Conventional Commits. See https://www.conventionalcommits.org</span></p>
<p><span class="cc-mark">4</span><span><span class="cc-t-blue">Suggest:</span> Use "<span class="cc-t-pass cc-b">fix: add streaming support</span>"</span></p>
Expand Down
Loading