| name | clean-commit |
| description | Writes git commit messages in a pure human-authored voice and strips AI attribution, tool watermarks, model names, co-author footers, and AI self-references. Use whenever creating, amending, rewriting, or reviewing a git commit message, including when running git commit, writing PR titles, or drafting commit bodies. |
Clean Commit
Core rule
Commit messages describe the change, not the author's tooling. Never add AI/tool attribution to a commit message unless the user explicitly asks for it in the current turn.
Forbidden content
Before finalizing any commit message (subject + body + trailers), the message MUST NOT contain any of the following. Match case-insensitively.
1. AI co-author trailers
Any Co-Authored-By: line pointing to an AI assistant or bot account.
Examples to remove:
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: ChatGPT <...>
Co-Authored-By: Cursor Agent <...>
Co-Authored-By: GitHub Copilot <...>
Co-Authored-By: Codex <...>
Co-Authored-By: Gemini <...>
- Any
Co-Authored-By: whose name or email references an AI product, assistant, bot, or noreply address of an AI vendor.
Real human Co-Authored-By: trailers are allowed and encouraged when appropriate.
2. Generator footers and watermarks
Any line that advertises the tool used to author the commit.
Examples to remove:
Generated with [Claude Code](https://...)
Generated with Claude Code
Generated by Cursor
Generated by GitHub Copilot
Written by ChatGPT
Authored via <AI tool>
Made with <AI tool>
via Cursor, via Claude, via ChatGPT, via Copilot
- Trailing URLs that promote an AI product (e.g.
https://claude.com/claude-code, https://cursor.com, https://openai.com/...) when used as an attribution link.
3. Bot emoji signatures
Emoji commonly used by AI tooling to mark generated output.
Examples to remove when they appear as a signature or prefix/suffix of a generator footer:
🤖, 🤖 Generated ...
🧠 Generated ...
✨ Generated with ...
Normal content emoji inside a human-written message (e.g. :sparkles: in a gitmoji-style project) is fine.
4. Model and product names as authorship
Do not name the model or the AI product as the author.
Examples to remove:
Claude, Claude 3.5 Sonnet, Claude Opus, Claude Haiku, Claude Code
GPT, GPT-4, GPT-4o, GPT-5, o1, o3, o4
Gemini, Gemini 2.5 Pro
Copilot, GitHub Copilot
Cursor, Cursor Agent, Cursor Tab
Codex, Devin, Aider, OpenCode
These names are only forbidden as authorship/attribution. If the change itself is about integrating such a product (e.g. feat: add Copilot webhook handler), the name is allowed as subject matter.
5. AI self-references in first person
Examples to remove:
As an AI, ...
As a language model, ...
I generated ...
I wrote this commit ...
by AI, AI-generated
6. Hidden watermarks
- HTML comments referencing AI:
<!-- generated by ... -->
- Zero-width characters inserted as invisible markers.
- Tracking parameters on attribution URLs (e.g.
?utm_source=claude-code).
Allowed content
- Any normal commit subject and body describing the change.
- The project's existing conventions: Conventional Commits, ticket prefixes like
[NF], [PR], JIRA-123:, scopes, issue references, Fixes #123, Refs: ....
- Real human
Co-Authored-By: trailers.
Signed-off-by: trailers for the human committer.
- Normal content emoji when the project uses them.
- Mentions of AI products when they are the subject of the change, not the author.
Pre-commit self-check workflow
Before running git commit, git commit --amend, or proposing a message to the user:
- Draft the message focusing on what changed and why.
- Scan the entire message (subject, body, trailers) for the forbidden items above, case-insensitively.
- If any match is found, remove the offending line or phrase and re-scan. Do not try to paraphrase an AI attribution into a "softer" AI attribution; delete it.
- Verify the final message still makes sense as a standalone human-authored commit. If deleting a trailer leaves a dangling blank section, clean that up too.
- Only then execute the commit or present the message.
When the agent itself invokes git commit -m "..." or uses a heredoc, the same scan applies to the exact string being passed.
IDE/CLI-level attribution (out-of-band)
Some IDEs or agent CLIs append their own trailer to commits after the message leaves the agent, by injecting flags like --trailer "Made-with: Cursor" into git commit. The resulting line appears in the committed message but was never part of the string the agent wrote, so the pre-commit self-check above cannot see it.
Detection:
- After any commit, if the agent has reason to verify the result (or the user reports a trailer they didn't expect), run
git log -1 --format=%B and scan that output against the same forbidden list.
- Example tell-tale trailers injected by IDEs/CLIs:
Made-with: Cursor, X-Cursor: ..., vendor-specific X-<Tool>: ... lines.
When an out-of-band trailer is observed:
- Tell the user plainly: this line was added by the IDE/CLI, not written by the agent; the skill's message-content rules cannot block it. Point them at the README's "Known pitfall: IDE-level attribution" section for the exact fix for their tool.
- For Cursor specifically, the fix is two settings (IDE toggle and CLI config file). With the user's approval, the agent may apply the CLI config fix by writing
~/.cursor/cli-config.json with commitAttribution: false and prAttribution: false. Do not apply it silently.
- If the offending commit has not been pushed, offer to
git commit --amend with the cleaned message after the injection source is disabled. If it has been pushed, follow the "Amending existing history" rules below — do not rewrite pushed history without explicit confirmation.
Amending existing history
Do not rewrite or force-push existing commits just to strip AI attribution from history. History rewrites are destructive and may not be wanted.
Instead:
- Keep all new commits clean.
- If the user notices old commits already contain AI attribution, mention that
git rebase -i / git filter-repo can scrub history, but only do it when the user explicitly asks and confirms the force-push implications.
Explicit user override
The only time AI attribution may appear in a commit message is when the user, in the current turn, explicitly asks for it (e.g. "add a Co-Authored-By Claude trailer"). Even then:
- Do not add extra attribution beyond what was requested.
- Do not add a generator footer unless the user asked for that specific line.
Do not infer consent from silence, from previous commits in the repo, or from a general "use Claude Code" setup.
Examples
Example 1 — feature commit
Bad:
feat(auth): add JWT refresh endpoint
Implements POST /auth/refresh with 15 min access / 7 day refresh tokens.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Good:
feat(auth): add JWT refresh endpoint
Implements POST /auth/refresh with 15 min access / 7 day refresh tokens.
Example 2 — bug fix commit
Bad:
fix(reports): correct timezone off-by-one in daily rollup
Generated by Cursor Agent.
Good:
fix(reports): correct timezone off-by-one in daily rollup
Convert timestamps to UTC before bucketing so DST transitions no longer
shift a day's rows into the neighbouring bucket.
Example 3 — user explicitly requested AI co-author
User turn: "Commit this and add Co-Authored-By: Claude."
Acceptable:
refactor(db): extract connection pool into its own module
Co-Authored-By: Claude <noreply@anthropic.com>
Still not acceptable (extra unrequested attribution):
refactor(db): extract connection pool into its own module
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>