diff --git a/docs/changelog.md b/docs/changelog.md index 9e48953..f3e0144 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -11,6 +11,7 @@ below and to the page that documents the feature properly. | Version | What changed | Documented in | |---|---|---| +| [2.20.1](#v2201) | `--ai-only` checks a pull request description against the AI rules; JSON reports `ai_tools`; Warp, Crush, credit trailers and agent run links recognised | [Checking a pull request description](guides/policies.md#checking-a-pull-request-description) · [CC013](rules.md#cc013) | | [2.20.0](#v2200) | A commit authored by an AI tool rejected (CC017); Continue, Mistral Vibe and Qwen Code recognised; subject length `0` turns the rule off; Python 3.10 dropped | [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) | | [2.19.4](#v2194) | `agents/` branches accepted by default; Cursor's `Made-with: Cursor` trailer recognised | [CC201](rules.md#cc201) · [CC013](rules.md#cc013) | @@ -37,6 +38,36 @@ below and to the page that documents the feature properly. | [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.1 (2026-11-08) { #v2201 } + +### Added + +* **`--ai-only` checks text that is not a commit message** — it runs only the + AI rules ([CC013](rules.md#cc013)–[CC016](rules.md#cc016)) on what you pipe + in, so a pull request description can be held to the same `ai_attribution` + policy as the commits without being judged as a Conventional Commit. See + [Checking a pull request description](guides/policies.md#checking-a-pull-request-description). + See PR [#673](https://github.com/commit-check/commit-check/pull/673). + +* **JSON output names the AI tools it found** — whenever a message is checked, + `--format json` adds `ai_tools`, the tools recognised in the message and, for + a commit, in its author. It is filled under every `ai_attribution` policy, + `ignore` included, so a workflow can label a pull request without failing + it. See [Reading the JSON](example.md#reading-the-json). + See PR [#673](https://github.com/commit-check/commit-check/pull/673). + +* **[CC013](rules.md#cc013)–[CC016](rules.md#cc016) recognise more AI marks** — + `Reviewed-by`, `Suggested-by`, `Helped-by`, `Tested-by` and `Reported-by` + naming a known tool; the Claude Code notice without the robot emoji, in + italics, or as a lone `https://claude.ai/code/session_...` line; Warp's + cloud agent `Warp `; Crush (`💘 Generated with Crush`, + `crush@charm.land`); and the run links agents leave in pull request + descriptions: Codex task, Devin session, Jules task and Cursor agent links. + A person named in a credit trailer, or a sentence that merely mentions a + tool, still passes. + See PRs [#672](https://github.com/commit-check/commit-check/pull/672) and + [#673](https://github.com/commit-check/commit-check/pull/673). + ## v2.20.0 (2026-11-08) { #v2200 } ### Added diff --git a/docs/compare/tools.md b/docs/compare/tools.md index fd57038..5d0ae6f 100644 --- a/docs/compare/tools.md +++ b/docs/compare/tools.md @@ -65,7 +65,7 @@ Replace the hook: ```yaml title=".pre-commit-config.yaml" repos: - repo: https://github.com/commit-check/commit-check - rev: v2.20.0 + rev: v2.20.1 hooks: - id: check-message ``` diff --git a/docs/configuration.md b/docs/configuration.md index 7370bbf..46e3d10 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -274,7 +274,7 @@ Used from a hook definition, with no config file anywhere in the repository: ```yaml title=".pre-commit-config.yaml" repos: - repo: https://github.com/commit-check/commit-check - rev: v2.20.0 + rev: v2.20.1 hooks: - id: check-message args: diff --git a/docs/example.md b/docs/example.md index db0ef23..7fa022f 100644 --- a/docs/example.md +++ b/docs/example.md @@ -162,7 +162,7 @@ pushed: ```yaml title=".pre-commit-config.yaml" repos: - repo: https://github.com/commit-check/commit-check - rev: v2.20.0 + rev: v2.20.1 hooks: - id: check-no-force-push stages: [pre-push] @@ -372,5 +372,20 @@ $ commit-check -m -b --format json | jq '{status, warnings}' } ``` +When a message is checked, the JSON also carries `ai_tools`: the AI tools +recognised by their known marks in the message and, for a commit, by its +author. It is filled under every `ai_attribution` policy, the default +`ignore` included, so a script can act on the attribution without failing +the commit: + +```console +$ commit-check -m --rev HEAD --format json | jq -c '.ai_tools' +["Claude Code"] +``` + +It reports attribution, not authorship: a sentence that merely mentions a +tool adds nothing, an empty list does not mean no AI was used, and a listed +tool may only have assisted. + From Python, [`commit_check.api`](guides/python-api.md) returns the same result as a `dict`, without a subprocess. diff --git a/docs/guides/policies.md b/docs/guides/policies.md index 8b3fc3f..fdc3516 100644 --- a/docs/guides/policies.md +++ b/docs/guides/policies.md @@ -141,11 +141,13 @@ Docs: https://commit-check.com/rules/#cc013 Recognised signatures are co-author and sign-off lines naming Claude Code, GitHub Copilot, Codex, Gemini, Cursor, Devin, Aider, Windsurf, Tabby, Amp, -OpenHands, Factory Droid, Jules, Continue, Mistral Vibe and Qwen Code, the -disclosure trailers `Assisted-by:` and +OpenHands, Factory Droid, Jules, Continue, Mistral Vibe, Qwen Code, Warp and +Crush, credit trailers such as `Reviewed-by:` or `Suggested-by:` naming one of +those tools, the disclosure trailers `Assisted-by:` and `Generated-by:`, vendor marks such as `🤖 Generated with Claude Code`, Amp's `Amp-Thread-ID:`, the Copilot coding agent's `Agent-Logs-Url:` and Cursor's -`Made-with: Cursor`, and generic AI model names. This is the +`Made-with: Cursor`, agent run links on their own line, and generic AI model +names; [CC013](../rules.md#cc013) has the full list. This is the position [Kubernetes](https://www.kubernetes.dev/docs/guide/pull-requests/) takes — no AI trailers in the history, disclosure in the pull request instead. @@ -201,6 +203,29 @@ bots write long ones: Renovate's `Update dependency com.googlecode.owasp-java-html-sanitizer:owasp-java-html-sanitizer to v20261103` is 95 characters. +### Checking a pull request description + +Agents leave their mark in the pull request description as often as in the +commits: `🤖 Generated with Claude Code`, `Link to Devin run: https://app.devin.ai/sessions/...`, +a Codex task or Cursor agent link. `--ai-only` holds any text to the AI rules +alone, so the description is not judged as a Conventional Commit: + +```console +$ set -o pipefail # a failed `gh` must not pass as an empty description +$ gh pr view 42 --json body -q .body | commit-check --ai-only +``` + +Under `ai_attribution = "forbid"` a description with an agent's mark fails +[CC013](../rules.md#cc013); under `"disclose"` it has to disclose the tool, +like a commit. Under the default `"ignore"` no rule runs and the check +passes; `--format json` still lists what it found in `ai_tools`, which is +enough to label the pull request: + +```console +$ gh pr view 42 --json body -q .body | commit-check --ai-only --format json | jq -c '.ai_tools' +["Devin"] +``` + ### Asking for disclosure instead Most projects that allow AI assistance ask to be told about it. diff --git a/docs/guides/pre-commit.md b/docs/guides/pre-commit.md index 5960d6b..9141f42 100644 --- a/docs/guides/pre-commit.md +++ b/docs/guides/pre-commit.md @@ -8,7 +8,7 @@ Add Commit Check to `.pre-commit-config.yaml`: ```yaml title=".pre-commit-config.yaml" repos: - repo: https://github.com/commit-check/commit-check - rev: v2.20.0 + rev: v2.20.1 hooks: - id: check-message - id: check-branch @@ -68,7 +68,7 @@ Options can be passed as hook arguments, which keeps everything in one file: ```yaml title=".pre-commit-config.yaml" repos: - repo: https://github.com/commit-check/commit-check - rev: v2.20.0 + rev: v2.20.1 hooks: - id: check-message args: @@ -90,7 +90,7 @@ colon, and lets the commit through: ```yaml title=".pre-commit-config.yaml" repos: - repo: https://github.com/commit-check/commit-check - rev: v2.20.0 + rev: v2.20.1 hooks: - id: check-message args: [--fix] diff --git a/docs/rules.md b/docs/rules.md index 7692f68..39cb179 100644 --- a/docs/rules.md +++ b/docs/rules.md @@ -565,11 +565,15 @@ git commit --amend --signoff Rejects a commit whose message carries any AI attribution: a co-author or sign-off line naming Claude Code, Copilot, Codex, Gemini, Cursor, Devin, Aider, Windsurf, Tabby, Amp, OpenHands, Factory Droid, Jules, Continue, -Mistral Vibe or Qwen Code, a disclosure -trailer such as `Assisted-by:` or `Generated-by:`, a vendor's own mark such -as `🤖 Generated with Claude Code`, Amp's `Amp-Thread-ID:` trailer, the +Mistral Vibe, Qwen Code, Warp or Crush, a disclosure +trailer such as `Assisted-by:` or `Generated-by:`, a credit trailer such as +`Reviewed-by:` or `Suggested-by:` naming one of those tools, a vendor's own +mark such as `🤖 Generated with Claude Code` (with or without the emoji), +Amp's `Amp-Thread-ID:` trailer, the `Agent-Logs-Url:` trailer the Copilot coding agent adds or Cursor's -`Made-with: Cursor`, and generic AI model names. Copilot is also recognised by its account's +`Made-with: Cursor`, a run link an agent leaves on its own line (a Claude +Code session, Codex task, Devin session, Jules task or Cursor agent link), +and generic AI model names. Copilot is also recognised by its account's `N+Copilot@users.noreply.github.com` address, so the coding agent's `copilot-swe-agent[bot]` co-author line counts under any display name.