commit-msg hook · github action
A commit-msg hook and GitHub Action that rejects commits carrying AI attribution trailers — because the byline is the one place accountability can’t be shared.
$ pre-commit install --hook-type commit-msg
the manifesto
AI co-author git-commit bylines are an impressive marketing hook — but they provide no useful signal of provenance.
It is mid-2026. All code written is facilitated by a host of sophisticated tools. The most recent of these are AI ‘co-authors.’ These have incredible utility, but — as with the other tools in the development toolchain — they are not meaningfully accountable for their output.
At best, tagging the bot that generated code as a ‘co-author’ adds noise to the single most important accountability and attribution mechanism in the development hierarchy. At worst, the practice implies similarly diffused responsibility.
As much as the act of code authorship is changing, the social rules for authorship must not slip: we are responsible for our contributions.
The ‘author’ is, as ever, the contributing person.
— Remove corporate spam from commit messages. No AI co-authors.
what it catches
Matching runs on both the display name and the email, normalized — so a renamed bot
or a numeric noreply address doesn’t slip through. A human is
never in the blast radius.
# the commit will not be created
# the commit goes through, untouched
It blocks the bot named Claude.
It welcomes the human named Claude Shannon.
the mechanism
sh and awkThe hook is a POSIX shell script. No Node, Python, or Ruby. No managed hook environment to bootstrap on every machine.
Runs as a commit-msg hook, so a tagged commit is stopped before it ever enters your history — not flagged after the fact.
The same logic ships as a GitHub Action that reads commits on push and pull_request, so the rule holds even without local hooks.
install
1.0.0. Pick your hook manager.Every path points at the public repo and a tagged release, so installs are repeatable. Swap the tag when you upgrade.
Add the repo to .pre-commit-config.yaml, then install the commit-msg stage.
default_install_hook_types: [pre-commit, commit-msg]
repos:
- repo: https://github.com/GoodHatsLLC/no-ai-coauthors
rev: 1.0.0
hooks:
- id: no-ai-coauthors
$ pre-commit install --hook-type commit-msg
prek reads the same config, or use a native prek.toml entry.
default_install_hook_types = ["pre-commit", "commit-msg"]
[[repos]]
repo = "https://github.com/GoodHatsLLC/no-ai-coauthors"
rev = "1.0.0"
hooks = [{ id = "no-ai-coauthors" }]
$ prek install --hook-type commit-msg
Consume it as a Lefthook remote config, then install.
remotes:
- git_url: https://github.com/GoodHatsLLC/no-ai-coauthors
ref: 1.0.0
configs:
- lefthook.yml
$ lefthook install
Use the repo directly as a composite action. On push it reads the event payload; on pull_request it reads the PR commits.
name: no-ai-coauthors
on:
pull_request:
push:
jobs:
no-ai-coauthors:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: read
steps:
- uses: GoodHatsLLC/no-ai-coauthors@1.0.0
No hook manager at all — download the script and point core.hooksPath at it.
$ mkdir -p .githooks
$ curl -fsSL \
https://raw.githubusercontent.com/GoodHatsLLC/no-ai-coauthors/1.0.0/hooks/no-ai-coauthors \
-o .githooks/commit-msg
$ chmod +x .githooks/commit-msg
$ git config core.hooksPath .githooks
The package exposes a no-ai-coauthors bin for Node-oriented managers.
no-ai-coauthors "$1"
{
"simple-git-hooks": {
"commit-msg": "no-ai-coauthors \"$1\""
}
}