TypeBack

Guide · Updated

An AI code policy for pull requests, with a check that reads it

A CONTRIBUTING.md paragraph for AI-written code, the same rules as a committed policy, and a free GitHub check that reads a review record on every pull request.

Most open-source projects that write down an AI policy ask for the same thing: a person stays in the loop. In a 2026 study of 1,000 popular repositories, 118 had an AI policy. 78% of those allowed AI tools, 51% asked contributors to disclose them, and 74% required a human in the loop. Few of them say how anyone would know.

This guide is a policy you can adopt in an afternoon: a paragraph for CONTRIBUTING.md, a machine-readable version, and a pull request check that reads a record instead of trusting a checkbox.

What a good policy asks for

  • Disclosure. Which tools wrote the change. Useful context for the reviewer, cheap for the author.
  • Understanding, not authorship. Whether an agent wrote a line matters less than whether the author can explain it. See comprehension debt for why.
  • More care where it hurts. Name the paths where a misunderstood change is expensive: authentication, payments, CI and infrastructure.
  • A record, not a gate on the editor. Let people work however they like, and check the result at the pull request.

1. The paragraph for CONTRIBUTING.md

Copy it and change the tools and paths to suit your project.

CONTRIBUTING.md
## Code written with AI tools
 
You may use AI coding tools. You are responsible for every line you submit.
 
1. Say which tools you used in the pull request description.
2. Understand each AI-written change before you ask for review. You should be
able to explain what it does, why it is written that way, and how it fails.
3. Keep a review record on the branch. The `typeback/verify` check reads it.
Hunks in high-risk paths need answered questions; only low-risk hunks may
be skipped.
4. The record is your own statement, like a DCO sign-off. It does not replace
code review, and reviewers may still ask you to walk them through a change.

2. The same policy, for a machine

A sentence in a markdown file cannot be checked. Put the rules the check needs in .typeback/config.json and commit it:

.typeback/config.json
1{
2"policy": {
3"require": true,
4"highRisk": ["**/auth/**", "**/payments/**", ".github/workflows/**", "infra/**"],
5"highRiskMode": "questions",
6"skips": "low-risk"
7}
8}
KeyDefaultMeaning
requiretrueThe check fails when the record breaks the policy. false only reports.
highRisk[]Globs, from the repository root, whose hunks are high risk whatever the model says.
highRiskModequestionsWhat a high-risk hunk needs: answered questions, or both, typing and questions.
skipslow-riskWhich skips the check accepts: only those of low-risk hunks, or none.

Start with "require": false for a few weeks. The check reports without failing, and you learn how far your team is from the policy before anyone is blocked by it.

3. The record on each commit

With a policy committed, TypeBack keeps a second line in the commit message box. It counts the whole branch, not only the last commit:

TypeBack-Record: v=1 passed=22 total=24 skipped=2 low-risk=2 pending=0 high=3/3 policy=3f2a9c1e sources=claude-code,copilot-agent

It holds counts, a hash of the policy it was made under, and which agents wrote the hunks. No code, no answers and no file names, so it is safe in a public history. When an agent commits before you review, as Claude Code often does, review the queue afterwards and run TypeBack: Stamp Review. It amends the last commit if it is not pushed yet, and otherwise adds an empty commit that carries the record.

4. The pull request check

Run TypeBack: Add Pull Request Check. It writes two files for you to commit:

  • .github/workflows/typeback.yml, whose job typeback/verify is the status check you require.
  • .github/typeback/typeback-verify.js, the check itself: one readable file with no dependencies.

On each pull request the check reads the policy and its own script from the base branch, so a pull request cannot loosen the rules or swap the check. It reads the record on the head commit and fails when:

  • the record is missing,
  • some hunks are not reviewed yet,
  • high-risk hunks fall short of the policy,
  • a skip is one the policy does not accept, or
  • the record was made under a different policy.

Each failure names the rule and the fix. The job summary lists the counts and the high-risk files the pull request touched. To make it required, add it to a branch ruleset, and put the workflow, the check and the policy under CODEOWNERS so changes to them need your approval. Outside GitHub, the same file runs wherever git and Node.js 20 do: node typeback-verify.js --base <commit> --head <commit>. It exits 0 on a pass, 1 on a failure and 2 when it cannot run.

What it does not do

Be honest with your team about the limits. They are the reason the policy works without resentment.

  • It is an attestation, not proof. The record says the author answered questions about each AI-written hunk TypeBack captured. Someone determined to cheat can. The same is true of a DCO sign-off, and projects still find those useful.
  • It does not replace code review. It tells the reviewer the author has worked through the change, so the review can be about design instead of “do you know what this does?”.
  • It only counts what it captured. Edits come from agent hooks (Claude Code, Copilot agent mode, Codex and Pi) or from scanning git changes. Code pasted from a chat window is not an agent edit.
  • It scores no one. The record belongs to the branch. There is no dashboard of people.

Attribution is a different question

Trailers such as Co-authored-by or the Linux kernel's Assisted-by say who, or what, wrote the code. Tools like git-ai track it line by line. That is useful, and it is a different question. Attribution records who wrote the code. A review record says whether a person understood it. A project can ask for both.