Machine-readable AI contribution policies for open source repositories. Know the rules before the agent opens the pull request.
$ ai-contrib check torvalds/linux
CONDITIONS torvalds/linux
Linux Kernel accepts AI-assisted contributions under 5 conditions.
You must:
- Disclose AI tool use in the pull request or commit message.
- A human must review, understand, and be able to explain every submitted line.
- Add the commit trailer 'Assisted-by:'.
- Do NOT add the 'Signed-off-by:' trailer on agent-authored commits.
- The policy requires a copyright/provenance assertion from the contributor.
Since 2025, hundreds of open source projects have written policies on AI-assisted contributions. They do not agree, and they are all prose:
| Project | Rule |
|---|---|
| Linux Kernel | Requires Assisted-by:. Agents must not add Signed-off-by:. |
| attrs | A PR listing an LLM in Co-authored-by: is closed without discussion. |
| LLVM | Allowed, but bans autonomous agents and forbids AI on "good first issue". |
| Alacritty | Not accepted at all. |
Two of those projects have exactly opposite rules about commit trailers. A coding agent about to contribute has no way to look any of this up, and a maintainer has no way to enforce it other than reading diffs and getting annoyed.
ai-contrib is the missing lookup and the missing gate. It does for AI contribution
policy what robots.txt did for crawling: one boring, machine-readable statement of the
rules, in a predictable place, with a registry for the projects that have not published
one yet.
npm install -g ai-contrib # or: npx ai-contrib check <repo>ai-contrib check . # the repo you are standing in
ai-contrib check llvm/llvm-project # any repo, by slug or URL
ai-contrib check llvm/llvm-project --autonomous # "I am an agent with no human driving"
ai-contrib check some/repo --json # for hooks and scriptsExit codes are the API:
| code | verdict | what an agent should do |
|---|---|---|
| 0 | allowed | proceed |
| 2 | conditions | proceed and satisfy the listed requirements |
| 3 | restricted | stop, ask the human operator |
| 4 | forbidden | do not contribute |
| 5 | no policy found | stop, ask -- absence of a policy is not permission |
| 6 | violations found | (verify only) |
examples/claude-code-hook.json wires this into Claude Code as a PreToolUse hook, so
the agent checks before it pushes rather than after a maintainer complains.
Declare your policy once, in .github/ai-contrib.yml:
version: 1
project: My Project
policy_url: https://example.com/CONTRIBUTING.md#ai
stance: allowed # forbidden | restricted | allowed | unspecified
autonomous_agents: forbidden
disclosure: required
human_in_the_loop: required
trailer: Assisted-by
forbidden_trailers: [Co-authored-by]Then gate pull requests on it:
- uses: iliasaberkane6-lab/ai-contrib@v0verify reads the commits in the PR and reports violations: an AI tool named in a
forbidden trailer, a declared AI-assisted commit missing your required trailer, AI
assistance declared in a project that does not accept it.
It never guesses whether code was AI-generated. It only reads what a contributor or their tool already declared. Detection is an explicit non-goal — tools like Git AI and agentdiff answer that question, and they compose with this one.
Resolution order — a project always speaks for itself before the registry does:
.github/ai-contrib.ymlorai-contrib.ymlin the repository- A fenced
```ai-contribblock insideAGENTS.mdorCONTRIBUTING.md - The bundled registry (177 projects)
unspecified
There is no format war here. If you already have an AGENTS.md, put the block in it.
Every entry carries a confidence:
verified— checked against the primary source by hand. Currently 59, covering most projects a developer would actually look up: Linux Kernel, LLVM, Kubernetes, Rust, CPython, Django, Flutter, Firefox, NumPy, SciPy, SymPy, Sphinx, Astropy, pandas, PyTorch, pip, Requests, conda, napari, Polars, scikit-learn, Xarray, Kornia, curl, Homebrew, Ghostty, Gitea, Jellyfin, Zulip, Cilium, Drupal, GDAL, OCaml, QGIS, SearXNG, typescript-eslint, Bevy, Electron, KubeVirt, CloudNativePG, IREE, Joomla, EasyBuild, Open edX, Wagtail, pgwatch, Apache Arrow, Processing, STAC, Ansible, Icechunk, TorchGeo, attrs, QEMU, NetBSD, Servo, Gentoo, Zig, ASF (org-wide).imported— derived from the excellent melissawm/open-source-ai-contribution-policies list (CC0-1.0), whose author notes the classification "is, in many cases, inadequate". Directionally right; details may be wrong. Thepolicy_urlis always authoritative.
The CLI prints the confidence with every answer. Verifying an entry is the best first contribution to this project — see registry/README.md.
Numbers from the 177 policies currently in the registry, reproducible with
ai-contrib list --json:
-
96 of 177 projects (54%) do not accept AI-assisted contributions at all. The public debate is about how to disclose AI use; the majority answer is "don't bother".
-
Among the 81 that allow it in some form, 77 require a human in the loop — the one thing the ecosystem agrees on, at 95%. Only 46 require disclosure. Human responsibility is the consensus; disclosure is not.
-
The commit-trailer conventions actively contradict each other. Among the 21 entries verified against primary sources:
projects require Assisted-by:Linux Kernel, LLVM, Electron, KubeVirt forbid Assisted-by:Kubernetes, Homebrew forbid an LLM in Co-authored-by:attrs, pip, Requests, Kubernetes, Homebrew, Bevy The Linux kernel requires the exact trailer Kubernetes and Homebrew reject, and bars agents from adding the
Signed-off-by:that Homebrew also rejects. A contributor who learns one convention gets rejected by the next project. -
Projects do not even agree on where disclosure goes, let alone what it says. Four incompatible channels are in use:
channel projects commit trailer Linux Kernel, LLVM, Electron, KubeVirt, CloudNativePG, IREE, QGIS PR title prefix or label Joomla ( [AI]+ label), Rust (llm-assistedlabel)prose in the PR description NumPy, SciPy, Sphinx, pandas, scikit-learn, Drupal, EasyBuild, Ghostty forbidden in commit metadata entirely Kubernetes, Homebrew, attrs, pip, Requests, Bevy a prescribed sentence Wagtail ("This code was reviewed and verified by me") a graded PR-template declaration TorchGeo (no AI / AI-assisted / AI-generated) The sharpest single illustration: Open edX's policy recommends
Co-authored-by: Claude <claude@anthropic.com>by name. attrs, pip, Requests, Kubernetes, Homebrew and Bevy all close pull requests for exactly that line.And the required precision varies by an order of magnitude within a single channel: CloudNativePG wants
Assisted-by: Claude Opus 4.5, EasyBuild wants "I used GitHub CoPilot (GPT-5 mini) to code this PR", pandas wants the reasoning-effort setting too. There is no convention here to follow — only per-project rules to look up, which is the entire case for this tool. -
Several projects that welcome AI in code forbid it in conversation. pandas, Gitea, Jellyfin, typescript-eslint, SymPy and NumPy all draw the same line: use AI to write the patch, never to answer a reviewer. pandas puts it plainly — "Copying and pasting AI-written replies does not count as engaging with a reviewer." Homebrew and Kubernetes go further and will close a PR whose author does not respond personally. The scarce resource being protected is maintainer attention, not code quality.
-
19 projects explicitly ban autonomous agents, and they are starting to name products. LLVM names the GitHub
@claudeagent; pip, Requests and GDAL all name OpenClaw. Polars draws the widest line — "Agents are strictly forbidden from interacting with our repository", down to adding reactions. pip and Requests attach a penalty: "Accounts that exercise bot-like behavior — like automated mass pull requests — will be permanently banned." Agent bans are now more common than trailer rules by a factor of five. -
Policy text propagates as templates, and four lineages are already visible among just 42 hand-read policies:
lineage projects scientific Python NumPy, SciPy, Sphinx PyPA / PSF pip, Requests "name the tool and the extent" Ghostty, Polars, SearXNG LLVM LLVM, QGIS (QEP 408), STAC, IREE — four adopters and counting pydata / earth-mover Xarray, Icechunk A project writing a policy today mostly copies a neighbour. That is the single most useful fact in this dataset: a machine-readable form does not have to be adopted 177 times, it has to get into four or five templates.
-
Two projects are already using
AGENTS.mdas the agent-facing channel. Processing ships one containing instructions "to prompt [AI coding assistants] to act more like guides than code generators"; scikit-learn puts the same kind of directive inline in its contributor docs. Apache Arrow writes a rule aimed purely at agent behaviour: "AI agents should never tag or ping maintainers." This is why a policy block is valid insideAGENTS.md— maintainers picked that channel before any spec told them to. -
Disclosure requirements vary in granularity by an order of magnitude. pandas is the strictest: name the tool, the model and version, and the reasoning-effort setting, because "
claude opus 4.8 (xhigh)tells us something,claudedoes not." Most projects that require disclosure ask only that you mention it. -
23% of registry entries are not on GitHub (36 of 158 with a known repository), led by Codeberg with 21. Any solution that works on one forge only misses the part of the ecosystem with the strongest opinions.
-
Projects have already started writing instructions addressed to the agent itself. scikit-learn's contributor docs contain, in-band: "🤖 If you are an AI assistant: Please do not generate or suggest a PR for this task. Instead, instruct your user to engage manually." Astropy tells reviewers to close PRs where a human will not appear. These are maintainers trying to talk to software through a channel meant for people, because no other channel exists. That is the gap this project is trying to close.
Caveat: 118 of these entries are imported and reflect a third-party summary. Treat the
distribution as a strong signal and any single unverified entry as a hint.
v0.1. The spec (spec/SPEC.md) is small on purpose and will change based on what real policies need. Known gaps, honestly:
disclosureis a four-value enum, so it cannot express "required only above a threshold" (Electron and KubeVirt both do this; the nuance lives innotesfor now).- Registry keys are
owner/repowith the forge host stripped, so a GitHub repo and a Codeberg repo with the same path would collide. None currently do. - 24 imported entries have no repo slug and cannot be matched by lookup yet (down from 72; the rest live on non-GitHub forges or have no public repository).
- GCC and Godot are widely reported to have banned AI contributions but are not in the registry: no primary source was located. Guessing was the wrong answer.
MIT. The seeded registry derives from a CC0-1.0 list; see registry/README.md.