Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Code of AI Use

QEP-5: Code of AI Use

QEP5
TitleCode of AI Use
Authormmcky
StatusAccepted
Typestandard
Created2026-08-14
DiscussionQuantEcon/qeps#12

Summary

This QEP adopts a Code of AI Use for QuantEcon: AI-assisted contributions are welcome, a human must be in the loop — choosing the task, reading the result, submitting it, and answering review on it — and every pull request states its AI involvement in one machine-readable line. It is policy, not infrastructure: the norms bind every contributor from acceptance, and the volume problem they sit alongside is handled with GitHub’s own native controls rather than with anything we build. What a repository does build is visibility: the Code is put in front of contributors and the tools they run, through the three channels set out under Adoption. The problem it answers is cost, not safety. Maintainer review attention is the scarce resource here, and a submission nobody has read before asking us to read it is an extractive contribution — one that costs more to review than it returns to the project. A contributor registry and a pull-request gate were drafted and are deliberately not part of this decision; if the native controls prove insufficient, that is a later amendment or a separate QEP.

Motivation

An audit of the 18 open pull requests on QuantEcon.py (2026-08-14) found that 11–12 involve AI authorship, and most carry no disclosure. Eight have explicit machine-readable attribution — bot accounts, Copilot co-author trailers, maintainer pull requests with Claude trailers, and one exemplary disclosed-and-human-reviewed submission. Three more carry strong agent fingerprints with nothing declared, including two competing agent-written fixes for the same issue filed on the same day by different first-time authors, and one whose description presents a test run that stopped at 47% when the agent’s session ended as if it were validation.

The pattern read as issue-crawling automation rather than individual experimentation — first-time authors converging on freshly filed issues within days, echoing our issue text verbatim, twice colliding on the same one — and a contributor has since confirmed it. Asked whether AI was involved, the author of a lint cleanup merged on 2026-09-09 (QuantEcon.py#923) disclosed within the hour that an autonomous agent on a cron schedule had read the issue, written the patch, run the validation, and drafted the description. The change was correct and merged; but it carried no marker, since the runtime emits no AI trailer and nobody added one, and nothing told a reviewer whether anyone would answer review. The costs are already concrete: duplicated review effort, CI minutes spent on unverifiable claims, and review comments written to authors who may never read them. Review attention is the binding constraint on this project, and the volume rises with agent capability.

GitHub’s native controls address volume, not norms. A repository can restrict pull requests to collaborators or turn them off entirely (February 2026); an organisation can cap how many concurrent open pull requests a user without write access may have (August 2026); and interaction limits throttle everything at once for up to six months. Between them these can hold back a single runaway account without any custom infrastructure, and that is the right first move. What none of them supplies is a statement of what we expect from an AI-assisted contribution, or any basis for asking a contributor to put one right. That is what this QEP provides.

Proposal

1. The Code of AI Use

AI-assisted contributions are welcome at QuantEcon; our maintainers use these tools daily and in the open. In exchange, every contributor accepts six norms.

In brief. The block below is the Code’s copyable form. It is what a repository’s contributor files and agent instructions carry, verbatim, and it is normative: a change to it is a substantive amendment of this QEP. Where it and the full norms that follow differ, the full norms govern.

In full.

  1. A human is in the loop. A human chooses the task, reads the result before asking anyone else to, submits it under their own account, and answers review on it. Where a tool pipeline produces the change, the human operating it is the contributor and owns what it files. Delegating work to an agent is fine. A pipeline that files and vanishes is not, and neither is an agent that acts in our repositories — opening, commenting, reviewing — without a person approving what it does. Whether a human was at the keyboard when the pull request opened does not matter; whether one owns it and is present for review does.

  2. Disclose. Every pull request carries a machine-readable Assisted-by: line, in the pull-request description or a commit message. Where AI tools meaningfully contributed to the code, tests, or text, it names them: Assisted-by: <tool> (<model>) — the harness first, the model in parentheses, one line per tool, as in Assisted-by: Claude Code (Claude Fable 5.1). Where they did not, it says so: Assisted-by: none. The explicit negative exists because silence is ambiguous — forgotten, or unassisted — and a reviewer should not have to guess which. Add the line yourself, or have your tool add it — repositories put the Code in front of agents for exactly that reason — but check that it is there: the line is your responsibility, not the tool’s. A Co-Authored-By: trailer that a tool emits on its own (Claude Code and Copilot do) also serves as the marker, but an in-house or third-party pipeline emits nothing, so for those the line exists only if its operator writes it or instructs it. The disclosure is a marker, not a narrative: it names what was used, not what it did.

  3. Own it. You are the author: you can explain what the change does, you answer review yourself — not by passing a reviewer’s comments to an agent — and you carry the result. Reading every line is the default way to earn that. In code, tests can stand in for it, narrowly: where a change is covered by tests that would fail if the change were wrong, the tests do the verifying, and line-by-line reading of the implementation is not expected. The burden moves rather than disappears — the tests are then what you must have read and be able to explain. The substitution stops where no test can fail: a deletion, a refactor that preserves behaviour, or a change the issue asked you to judge site by site is verified by reading it, or not at all. Prose, mathematics, and exposition have no substitute either, because no test tells you an argument is wrong. Submitting output nobody has vouched for shifts your work onto volunteer maintainers.

  4. Verify before you claim. Only state that tests pass, coverage rose, or benchmarks improved if you ran them to completion. Partial runs are fine to submit, described as what they are.

  5. Don’t crawl, duplicate, or farm. Do not run automation that crawls our issue tracker for work. Check for an existing open pull request before starting on an issue, and don’t mass-submit generated pull requests across repositories to build a contribution record. Issues labelled good first issue are reserved for people learning the codebase by hand: do not use AI tools to fix them, whether you are a newcomer or not. The label is the fence — a maintainer who wants any issue kept for hands-on learning labels it so.

  6. Put it right. We assume good faith and expect the occasional lapse. If something here is missed, a maintainer will say so and point at the fix — please amend the pull request, or, where it has already merged, carry the point into your next one. Repeated or deliberate lapses may lead to Enforcement (see below).

These norms exist so that AI tools raise the quality of QuantEcon rather than the cost of maintaining it. They bind every contributor, maintainers included, and they bind from acceptance — like the Code of Conduct, this is project policy rather than a contract only signatories are held to. They cover anything a contributor asks a maintainer to read: pull requests first, but also issues, review comments, and proposals — an AI-drafted bug report nobody has checked costs the same attention as an AI-drafted patch.

Organisation-operated automation is not an external contribution. QuantEcon runs its own scheduled maintenance — dependency bots, link checkers, build and warning sweeps, and maintenance agents that open pull requests across repositories. That is QuantEcon acting on its own repositories, not contributing to them, and norm 1 does not prohibit it. The accountability rule is applied rather than waived: such automation has a named maintainer who owns its output and answers for it, it is declared — recorded in a public register of the organisation’s automation, not self-asserted in a pull-request description — and it carries QEP-2’s automated label so its output stays distinguishable from human triage at a glance. Disclosure (norm 2) is satisfied structurally by that label and the bot account rather than by the line; norms 3 and 4 bind the operating maintainer exactly as they would for work submitted by hand. Automation meeting none of those conditions is an unattended agent, whoever built it.

2. Enforcement

The first response to any lapse is a rectification comment: a maintainer points at the Code and asks the contributor to amend the pull request.

A lapse does not decide the merits. Where the work is correct and in scope, a maintainer may merge it and still record the lapse — a comment stating what the Code expects next time. That comment is the rectification step for a pull request that has already merged, and it counts toward repeated if the lapse recurs. Closing correct work on process alone costs the project the work and the contributor’s goodwill, and is not the default.

Beyond that, maintainers use judgement. The responses available, roughly in order, are closing the pull request without further review and, at the far end, GitHub’s own organisation block, which can be set to expire on its own rather than run indefinitely. Blocking is blunt by design — it also stops the person filing issues and commenting — so it is the step to be slowest to take.

The point is to keep the review queue worth reading, not to punish. Every step short of the last is undone by the contributor simply fixing the problem.

3. What this is not

Alternatives considered

Adoption

Acceptance fixes the Code of AI Use as QuantEcon policy. It binds from that point, like the Code of Conduct — without anyone signing anything. What a repository builds is the visibility below, not enforcement.

Two obligations follow for a repository adopting it.

The disclosure path must be visible where contributions are made — to contributors and to the tools they run. No single place reaches everyone. A pull-request template reaches a person opening a pull request in the web interface and nobody else; an agent working from a checkout reads the repository’s agent-instruction file and nothing else; a pipeline that opens pull requests through the API sees neither. A repository adopting the Code therefore provides three things.

A norm nobody encounters is not a norm.

The good first issue label is applied deliberately. Under norm 5 it now reserves an issue for hands-on work as well as advertising it, so it goes only on issues that meet QEP-2’s criteria for it, and a maintainer who wants an audit or tech-debt issue kept for learning labels it rather than assuming the reservation.

The Code is applied by maintainers reading pull requests. The only automation it calls for is the comment above, which asks and never decides; enforcement stays human. It assumes GitHub’s native volume controls — org-level pull-request limits in particular — are already in use. Those need no QEP to enable, tune, or turn off, and this Code stands whether or not they are.

Disclosure

This QEP was drafted with AI assistance, under the norms it sets out. Claude, via Claude Code, produced text under the author’s direction; the author read, revised, and owns every line, and answers review on it.

Assisted-by: Claude Code (Claude Fable 5.1)