From eb3a5dbd43c0fcda82799e7165e3818e99739b05 Mon Sep 17 00:00:00 2001 From: Xianpeng Shen <3353385+shenxianpeng@users.noreply.github.com> Date: Mon, 19 Oct 2026 08:09:28 +0000 Subject: [PATCH] docs: add the v2.19.2 changes and the kernel's Assisted-by decision The changelog gets a v2.19.2 entry and a Highlights row. CC013 and the policy guide name the Copilot coding agent's Agent-Logs-Url trailer and its copilot-swe-agent[bot] co-author line. CC202 documents the skip when the rebase target does not resolve, and CC401 the remote tag name a pre-push line creates. The options reference and the exit-code table describe the wrong-type config errors, and the output section says commit text is printed inert. The Linux kernel's maintainers decided in October 2026 to drop the Assisted-by tag, so the AI-attribution article, CC014 and the policy guide no longer list the kernel as asking for it. Its rule against AI sign-offs stays. --- .../posts/ai-commit-attribution-policy.md | 5 +- docs/changelog.md | 54 +++++++++++++++++++ docs/configuration.md | 21 +++++++- docs/example.md | 6 +++ docs/guides/policies.md | 22 ++++---- docs/rules.md | 23 ++++++-- docs/troubleshoot.md | 3 +- 7 files changed, 116 insertions(+), 18 deletions(-) diff --git a/docs/blog/posts/ai-commit-attribution-policy.md b/docs/blog/posts/ai-commit-attribution-policy.md index d90a86c..4ba1a58 100644 --- a/docs/blog/posts/ai-commit-attribution-policy.md +++ b/docs/blog/posts/ai-commit-attribution-policy.md @@ -36,7 +36,7 @@ source has already given three different answers. | Position | Who takes it | |---|---| | No AI trailers in the history; disclose in the pull request instead | [Kubernetes](https://www.kubernetes.dev/docs/guide/pull-requests/) | -| AI is welcome, but say so with a trailer, and never credit the tool as a person | [Linux kernel](https://docs.kernel.org/process/coding-assistants.html) and [Fedora](https://docs.fedoraproject.org/en-US/council/policy/ai-policy/) (`Assisted-by:`) | +| AI is welcome, but say so with a trailer, and never credit the tool as a person | [Fedora](https://docs.fedoraproject.org/en-US/council/policy/ai-policy/) (`Assisted-by:`), and the [Linux kernel](https://docs.kernel.org/process/coding-assistants.html) until its maintainers decided in October 2026 to drop the tag | | The tool can be credited as a co-author | [pytest](https://docs.pytest.org/en/stable/contributing.html) (`Co-authored-by:`) and the [ASF](https://www.apache.org/legal/generative-tooling.html) (`Generated-by:` or `Co-authored-by:`) | The kernel adds one hard rule on top: an AI agent must never add a @@ -99,7 +99,8 @@ The detection covers co-author and sign-off lines that name Claude Code, GitHub Copilot, Codex, Gemini, Cursor, Devin, Aider, Windsurf, Tabby or a model, and vendor marks such as "Generated with Claude Code"; [v2.19.0](../../changelog.md#v2190) added Amp, OpenHands, Factory Droid and -Jules. It matches the tools' +Jules, and [v2.19.2](../../changelog.md#v2192) the Copilot coding agent's +`Agent-Logs-Url:` trailer. It matches the tools' noreply addresses, so a human co-author who happens to be called Claude is left alone. [CC013](../../rules.md#cc013) keeps the current list. diff --git a/docs/changelog.md b/docs/changelog.md index e7d95f6..2cc6af9 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.19.2](#v2192) | Copilot coding agent commits recognised; config values of the wrong type refused; commit text printed inert | [CC013](rules.md#cc013) · [Every option](configuration.md#every-option) · [Color and links](example.md#color-and-links) | | [2.19.1](#v2191) | `develop` accepted by default; stricter merge-subject, fixup, WIP and sign-off checks | [CC201](rules.md#cc201) · [CC001](rules.md#cc001) · [CC009](rules.md#cc009) | | [2.19.0](#v2190) | Branch descriptions held to the Conventional Branch grammar; Amp, OpenHands, Factory Droid and Jules recognised | [CC201](rules.md#cc201) · [CC013](rules.md#cc013) | | [2.18.3](#v2183) | `--fix` corrects a message in place; `--branch` reads GitLab, Bitbucket, Azure and Jenkins variables | [Fixing a message in place](example.md#fixing-a-message-in-place) · [Other CI](guides/other-ci.md) | @@ -32,6 +33,59 @@ 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.19.2 (2026-10-18) { #v2192 } + +### Changed + +* **A config value of the wrong type stops the run** — `message_pattern = 5` + crashed, `subject_max_length = true` became a one-character limit, + `subject_max_length = "50"` turned the rule off without a word, and + `allow_commit_types = "feat,fix"` was read letter by letter, so `f: x` + passed. A pattern, a subject length, or a type or name list of the wrong + type is now a configuration error (exit 2) that names the setting. A + comma-separated string in `allow_commit_types`, `allow_branch_types` or + `allow_branch_names` is split the way `--allow-commit-types` splits it. A + config that relied on the old reading now stops with that error, so check + yours when you upgrade. + See PR [#624](https://github.com/commit-check/commit-check/pull/624) and + [Every option](configuration.md#every-option). + +* **[CC202](rules.md#cc202) skips when the rebase target does not resolve** — + a `require_rebase_target` that matched no branch, because of a typo or a + shallow clone without `origin/main`, reported a pass without comparing + anything. It is now a skip, and the JSON `reason` names the missing target. + The exit code stays 0. + See PR [#617](https://github.com/commit-check/commit-check/pull/617). + +* **[CC401](rules.md#cc401) checks the tag name the remote receives** — in a + `pre-push` hook, `git push origin v1.0.0:refs/tags/bad-name` was checked as + `v1.0.0`, so `bad-name` reached the remote. The remote name is checked now. + See PR [#615](https://github.com/commit-check/commit-check/pull/615). + +### Fixed + +* **[CC013](rules.md#cc013)–[CC016](rules.md#cc016) recognise the Copilot + coding agent** — its commits carry an `Agent-Logs-Url:` trailer, and a + squash merge of its pull request adds a `copilot-swe-agent[bot]` co-author + line. Both passed `forbid` and `disclose`. They are now read as GitHub + Copilot, and under `disclose` the correction appends + `Assisted-by: GitHub Copilot`. + See PR [#632](https://github.com/commit-check/commit-check/pull/632). + +* **Commit text is printed inert** — a failing message, branch or tag name was + printed as written, so escape sequences reached the terminal, and a body + line starting with `::` reached a GitHub Actions runner as a workflow + command. Text output now shows control characters as `\xNN` and puts a + backslash before such a `::`. `--format json` is unchanged. + See PR [#620](https://github.com/commit-check/commit-check/pull/620) and + [Color and links](example.md#color-and-links). + +* **Three patterns run in linear time** — the CC001 header correction and the + AI trailer matching could take seconds on a line padded with spaces. + Verdicts are unchanged, except that a `Co-authored-by:` line with an empty + name before `(aider)` no longer counts. + See PR [#626](https://github.com/commit-check/commit-check/pull/626). + ## v2.19.1 (2026-10-16) { #v2191 } ### Changed diff --git a/docs/configuration.md b/docs/configuration.md index b104683..132b1c8 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -351,7 +351,26 @@ setting in the file appears to have no effect. ## Every option -Types are as TOML understands them. A default shown as `""` means the option is +Types are as TOML understands them. A pattern, a subject length, or a type or +name list given a value of another type stops the run with exit 2 and names +the setting: + +```toml title="cchk.toml" +[commit] +subject_max_length = "50" +``` + +```console +$ echo "feat: add streaming support" | commit-check -m +Error: [commit] subject_max_length must be a whole number, got '50' +``` + +`allow_commit_types`, `allow_branch_types` and `allow_branch_names` also take +one comma-separated string, as `--allow-commit-types` does. A boolean has to be +a TOML boolean: `"false"` in quotes is a non-empty string, and it counts as +true. + +A default shown as `""` means the option is unset, which is never the same as the check being off — but it does not mean the same thing twice, so read the description rather than the cell: diff --git a/docs/example.md b/docs/example.md index f9b535c..ecfb0e8 100644 --- a/docs/example.md +++ b/docs/example.md @@ -237,6 +237,12 @@ To override the detection: | `FORCE_COLOR=1` / `FORCE_COLOR=0` | color on or off, outranking everything else | | `FORCE_HYPERLINK=1` / `FORCE_HYPERLINK=0` | linked rule IDs on or off | +Whatever the destination, the commit text in a failure is printed inert. +Control characters other than newline and tab appear as `\xNN`, and a line +that starts with `::` is printed as `\::`, so a commit message cannot move the +terminal's cursor or send a GitHub Actions runner a workflow command. +`--format json` is not affected; JSON escapes those characters already. + ### Checking a range of commits `--rev` makes each commit addressable without checking it out or piping its diff --git a/docs/guides/policies.md b/docs/guides/policies.md index a390787..8d48cbc 100644 --- a/docs/guides/policies.md +++ b/docs/guides/policies.md @@ -134,15 +134,18 @@ 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 and Jules, the disclosure trailers `Assisted-by:` and -`Generated-by:`, vendor marks such as `🤖 Generated with Claude Code` and -Amp's `Amp-Thread-ID:`, and generic AI model names. This is the +`Generated-by:`, vendor marks such as `🤖 Generated with Claude Code`, Amp's +`Amp-Thread-ID:` and the Copilot coding agent's `Agent-Logs-Url:`, and generic +AI model names. 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. These rules read only the message. Jules and OpenHands can commit under their own bot identity instead of adding a co-author line, and such a commit passes -when its message contains no recognized AI signature. +when its message contains no recognized AI signature. The Copilot coding agent +also commits as its own account, but every commit it makes carries an +`Agent-Logs-Url:` trailer, so its commits are caught. !!! warning "This checks disclosure, not authorship" @@ -157,12 +160,13 @@ when its message contains no recognized AI signature. ### Asking for disclosure instead -Most projects that allow AI assistance ask to be told about it. The -[Linux kernel](https://docs.kernel.org/process/coding-assistants.html), +Most projects that allow AI assistance ask to be told about it. [Fedora](https://docs.fedoraproject.org/en-US/council/policy/ai-policy/) and -FluxCD want an `Assisted-by:` trailer; the +FluxCD want an `Assisted-by:` trailer, as the +[Linux kernel](https://docs.kernel.org/process/coding-assistants.html) did +until its maintainers decided in October 2026 to drop the tag; the [Apache Software Foundation](https://www.apache.org/legal/generative-tooling.html) -recommends `Generated-by:`. The kernel also says an AI agent must +recommends `Generated-by:`. The kernel still says an AI agent must never add a `Signed-off-by:` line, because only a person can certify the [DCO](https://developercertificate.org/). @@ -202,7 +206,7 @@ as the project's disclosure trailer, keeping the name the tool gave itself. ``` Once the tool is disclosed, CC015 asks only for the co-author line to go, and -a commit written the way the kernel asks passes all three: +a commit in the kernel's `Assisted-by:` format passes all three: ```bash printf 'feat: add caching layer\n\nAssisted-by: LLM coccinelle sparse\nSigned-off-by: Jane Dev ' | commit-check -m @@ -216,7 +220,7 @@ and the first one is what a correction is written with: ```toml title="cchk.toml" [commit] ai_attribution = "disclose" -ai_disclosure_trailers = ["Assisted-by"] # the kernel's, and nothing else +ai_disclosure_trailers = ["Assisted-by"] # Assisted-by, and nothing else ``` Listing `Co-authored-by` says the project accepts the tool as a co-author — diff --git a/docs/rules.md b/docs/rules.md index 35f746a..96688dd 100644 --- a/docs/rules.md +++ b/docs/rules.md @@ -565,8 +565,11 @@ 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 or Jules, a disclosure trailer such as `Assisted-by:` or `Generated-by:`, a vendor's own mark such -as `🤖 Generated with Claude Code` or Amp's `Amp-Thread-ID:` trailer, and -generic AI model names. +as `🤖 Generated with Claude Code`, Amp's `Amp-Thread-ID:` trailer or the +`Agent-Logs-Url:` trailer the Copilot coding agent adds, 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. **Why is this bad?** @@ -606,10 +609,11 @@ match `ai_disclosure_pattern` — fails too. **Why is this bad?** A project that allows AI assistance and asks for it to be disclosed has an -honour-system rule until something checks it. The -[Linux kernel](https://docs.kernel.org/process/coding-assistants.html), +honour-system rule until something checks it. [Fedora](https://docs.fedoraproject.org/en-US/council/policy/ai-policy/) and -FluxCD ask for `Assisted-by:`; the +FluxCD ask for `Assisted-by:`, as the +[Linux kernel](https://docs.kernel.org/process/coding-assistants.html) did +until its maintainers decided in October 2026 to drop the tag; the [Apache Software Foundation](https://www.apache.org/legal/generative-tooling.html) recommends `Generated-by:`. The tools, meanwhile, stamp their own format on the way out, so a contributor following the policy and one ignoring it produce @@ -855,6 +859,11 @@ that git can create as a branch. Checks that the current branch is rebased onto a target branch. +When the target matches no branch, neither locally nor under `origin/`, the +check is a **skip**, not a pass, and the JSON `reason` says +`rebase target 'main' not found`. A shallow CI clone without the target branch +is the usual cause; fetch the branch before the check. + **Why is this bad?** A branch that has fallen behind is tested against code that no longer exists on @@ -1023,6 +1032,10 @@ and `release-1.2.3` do not. A commit with no tag is a **skip**, not a failure: the rule governs how tags are named, and the absence of one is not a naming violation. +As a `pre-push` hook it checks the tags the push creates, under the name the +remote will give them: `git push origin v1.0.0:refs/tags/release-1` is checked +as `release-1`. Deleting a tag is not checked. + **Why is this bad?** Tags are the public interface of a release. Package managers, changelog diff --git a/docs/troubleshoot.md b/docs/troubleshoot.md index a4ede87..3491a3e 100644 --- a/docs/troubleshoot.md +++ b/docs/troubleshoot.md @@ -107,7 +107,7 @@ broken policy from a bad commit. Commit Check keeps them apart: |---|---| | `0` | Every enforced check passed, or every check was skipped. | | `1` | A check failed. This is a verdict on the commit. | -| `2` | The run could not start, so nothing was validated: bad usage, a `--rev` that does not resolve, a setting whose regex does not compile, or a config file that is missing, is not valid TOML, or names an unknown rule. | +| `2` | The run could not start, so nothing was validated: bad usage, a `--rev` that does not resolve, a setting whose regex does not compile or whose value has the wrong type, or a config file that is missing, is not valid TOML, or names an unknown rule. | A configuration error names the file it came from: @@ -120,6 +120,7 @@ instead, and echoes the value it could not use: ```text Error: [commit] message_pattern is not a valid regex: '^(unclosed' (missing ), unterminated subpattern at position 1) +Error: [commit] subject_max_length must be a whole number, got '50' ``` ## Something else