DEV Community

Cover image for Should AI-Generated Code Be Labeled in Your Git History?
Nazar Boyko
Nazar Boyko

Posted on

Should AI-Generated Code Be Labeled in Your Git History?

The Linux kernel, Fedora, and LLVM now require an “Assisted-by” tag on patches created with the help of AI, and Claude Code adds a “Co-Authored-By” line to your commits, whether you ask for it or not. So the question of authorship has already been decided for us and decided badly!

Open your git log and check if you've used Claude Code this month, there's a fair chance one of your recent commits ends with a line you never typed:

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Enter fullscreen mode Exit fullscreen mode

Claude Code adds this trailer by default. And yes, of course you can disable it or change the text using the attribution setting, but most people don’t do this, as most people don’t even notice it. So the question in this post isn’t ‘should we start recording the origin of AI in commits?’. Many of you are already doing this unintentionally, and the real question is whether we should do it deliberately, and if so, what exactly should be included in that line.

This is the narrower, more practical follow-up to AI And Code Ownership: Who Is Responsible For Generated Code?. That piece landed on one sentence: you wrote the merge commit, you own it. This one asks the question that sentence leaves open. If we own it anyway, does it help anyone to write down that a model was in the commit?

A Trailer Is Not A Comment

Git trailers are the block of Key: value lines at the bottom of a commit message, "similar to RFC 822 e-mail headers" in git's own words. Signed-off-by: is the famous one. Git actually knows the block! It has to be separated from the body by a blank line and git treats a group of lines as trailers if it's all trailers or if it contains at least one recognised trailer and is at least 25% trailers. There's even a first-class flag for adding one:

git commit -m "Fix retry backoff in the webhook worker" \
  --trailer "Assisted-by: Claude Code"
Enter fullscreen mode Exit fullscreen mode

and a first-class way to read them back out:

git log --since='30 days ago' \
  --format='%h %an %s%n    %(trailers:key=Assisted-by,valueonly)'
Enter fullscreen mode Exit fullscreen mode

This search capability is precisely what it’s all about. The text in a PR description is prose that disappears from view when the PR is closed, whereas a trailer is a data field. git log, git interpret-trailers, a CI script and any ‘code archaeology’ tool that traces history can read it years later without a GitHub API token.

Another point worth noting regarding trailers: the ecosystem already regards them as statements of substance, rather than mere annotations. The Signed-off-by tag in a kernel patch is not merely a matter of courtesy. It is the developer’s confirmation of the ‘Developer’s Certificate of Origin’: I am authorised to submit this under this licence. That is precisely why the wording here carries more weight than in a code comment. A trailer marked with Co-Authored-By makes a specific assertion, and we’ll come back to exactly what that is later.

The Case For Writing It Down

Strongest form, four arguments.

Suppose a license question lands one day (that function looks a lot like GPL code from a project you don't depend on). Knowing which commits had a model in the loop turns a full-history audit into a git log --format='%(trailers:key=Assisted-by)' and a much shorter list. Same when a vendor discloses a systematic bug in a specific model release and you want to know which of your code came out of it. The kernel's format literally encodes that: Assisted-by: AGENT_NAME:MODEL_VERSION [TOOL1] [TOOL2], with an example like Assisted-by: Claude:claude-3-opus coccinelle sparse.

If a claim ever comes, being able to show which code was generated under which tool configuration is the difference between "we can scope this" and "we can't." Big projects with very different cultures converged on it within a year. The Linux kernel now has an official AI Coding Assistants document in its process docs, shipped with 7.0, after Sasha Levin, an NVIDIA engineer and LTS co-maintainer, proposed it in July 2025. Fedora Council approved an AI-assisted contribution policy on 22 October 2025 that recommends the same Assisted-by: trailer. LLVM adopted a human-in-the-loop policy in January 2026 that asks contributors to "be transparent and label contributions that contain substantial amounts of tool-generated content", again pointing at Assisted-by:. When three communities that disagree about almost everything pick the same commit-message convention, that's a signal.

The origin story of the kernel tag is the whole argument in miniature. Levin had earlier submitted a patch to Linux 6.15 that was created by AI, changelog and tests included. He'd reviewed and tested it before sending, but he didn't tell reviewers a model had written it and that did not go over well. The policy he went on to propose is essentially the fix for what upset people: reviewers should know what they're reviewing. Not who to blame. What to look at.

The Case Against! Also strongest form.

Noise. Once every commit carries the trailer, it carries zero bits. If your team uses inline completions all day, "AI helped" is true of everything and a field that's always true is a field nobody reads. Signed-off-by survives ubiquity because it's a legal statement, not because anyone reads it while reviewing.

Where's the line? Autocomplete finishing a for loop is AI. So is an editor tab-completing a whole function you would have typed identically. So is an agent producing 400 lines from a two-sentence prompt. Every project that adopted a label had to draw the line and they all drew it somewhere different. The kernel says "Basic development tools (git, gcc, make, editors) should not be listed" but wants everything above that. Fedora's approved policy requires disclosure "when the significant part of the contribution is taken from a tool without changes". LLVM says "substantial amounts". Three thoughtful communities, three thresholds and every one of them is a judgment call the author makes about their own work. That's not a defect in those policies. It's the shape of the problem: provenance is a spectrum and a trailer is a boolean.

Gaming, in both directions. If the label invites extra scrutiny, some people quietly stop adding it and now the trailer signals "author who follows the rules" rather than "code that was generated." If the label is socially costless, people spray it on everything out of caution and you're back to noise. Either way the trailer ends up measuring the author's disclosure habits, not the code.

False comfort. This is the one that worries me most. A label is a checkbox and checkboxes have a way of becoming the deliverable. "We track AI provenance" sounds like governance. It isn't. Knowing a model touched a function tells you nothing about whether the model got it right, whether the author understood it, or whether anyone read it closely. A team that adds trailers and changes nothing else has bought a feeling.

Squash merges eat it. A small mechanical one, but real. Trailers live on commits. Squash-merge a twelve-commit branch where two commits were generated and the trailer either vanishes or lands on all three hundred lines of the squash. And git blame shows the author per line and the author is you. Line-level provenance was never on offer; the best a trailer can do is point at a commit.

Co-Authored-By Is The Wrong Word

Even if you decide to label, the label most people are getting by default is the wrong one.

Co-authored-by predates AI by years. GitHub's docs describe it as the way to give a human collaborator credit: Co-authored-by: name <name@example.com> and "for the commit to count as a contribution, use an email address associated with their account on GitHub.com." It's an authorship claim. It puts a second avatar on the commit. It was designed for pair programming.

The kernel doc is blunt about the distinction: "AI agents MUST NOT add Signed-off-by tags. Only humans can legally certify the Developer Certificate of Origin (DCO)." The maintainers reportedly considered Generated-by and Co-developed-by before settling on Assisted-by, precisely because it frames the model as a tool rather than a co-author. Fedora's proposal put the same idea in one line: "The contributor is always the author and is fully accountable for their contributions." And from the ownership piece, the legal layer agrees: no human author, no copyright and prompting alone doesn't make you the author of the output.

There's an open issue on the Claude Code repo asking to switch the default trailer to Assisted-by: for exactly this reason: the trailer implies shared authorship. I'd go one step further than the issue. The best trailer I've seen isn't Assisted-by: either. It's the one in Paolo Bonzini's May 2026 proposal to relax QEMU's blanket ban on AI-generated code (a ban QEMU adopted in June 2025, on DCO grounds). The proposal introduces AI-used-for: followed by keywords like code, tests, docs, research, plus an optional clarification. The patch text says why in one sentence: "The trailer is intended as a clarification of your DCO obligations as well as to guide reviewers."

Guide reviewers. That's the job. Line the three up:

Trailer What it claims What the reviewer learns
Co-authored-by: Claude <noreply@...> the model is an author nothing about scope, plus a claim that's legally wrong
Assisted-by: Claude:claude-3-opus a tool was in the loop, this version which tool, not where it was used
AI-used-for: tests, research what the tool did where to slow down and where not to bother

Only the last one changes how you'd read the diff.

My honest answer

A provenance trailer isn't about assigning blame. Blame is already assigned; it's on the merge commit, under a human name and no trailer moves it. The trailer is about pointing attention. And attention-pointing only works if something happens on the receiving end. If the label triggers a deeper look, it's worth its five seconds. If it triggers nothing, it's provenance theater: a ritual that produces the feeling of governance without any of the substance.

So the test for your team isn't "should we label?" It's "what does the label do?" Concretely, a few things it can do:

  • It changes the review checklist. A PR whose commits carry the trailer gets the third-party-dependency treatment from the ownership piece: do I understand what this does, would I sign my name to it if the model weren't here to point at. Written into the PR template, not remembered.
  • It routes. A CI step reads the trailers on the PR's commits and adds an ai-assisted label; the label requires a second reviewer on paths like auth/, billing/, migrations/. Cheap. Real. Enforceable.
  • It answers the 2am question. git blame gives you a sha; git show -s --format='%(trailers)' <sha> tells you whether to trust the shape of that function or re-derive it from scratch. It's a two-step, but it's a two-step you can actually take.
  • It scopes an audit. When the license question comes, git log --format=... | grep beats reading every commit since 2024.

If none of those exist in your workflow, don't add the trailer yet. Add the behavior first, then the trailer that feeds it. A label with no consumer is a comment with delusions of grandeur.

Comparison diagram titled A Provenance Label Only Matters If Something Reads It: on the left a commit with an Assisted-by trailer feeds four gold consumers (PR review checklist, CI adds ai-assisted label with second reviewer on auth/ billing/, git blame then git show trailers, license audit via git log filter); on the right the same commit points to a gray box labeled nothing reads it, captioned provenance theater

If you decide the label earns its place, here's a small hook to make the default one say the right thing. It rewrites the Co-Authored-By: <assistant> <noreply@vendor> line some tools append into an Assisted-by: trailer, so the model shows up as a tool rather than an author. Note the vendor-specific email match: you can't just match on noreply, because GitHub tells human co-authors who keep their email private to use their noreply address and you don't want to demote a colleague.

.git/hooks/commit-msg

#!/bin/sh
# Rewrite the "Co-Authored-By: <assistant> <noreply@vendor>" line some AI
# tools append by default into an "Assisted-by:" trailer.
# Human co-authors are left alone: match the vendor address, not "noreply".
msg="$1"
pattern='^Co-Authored-By: .*<noreply@anthropic\.com>'

if grep -qiE "$pattern" "$msg"; then
  tool=$(grep -iE "$pattern" "$msg" | head -1 \
        | sed -E 's/^[Cc]o-[Aa]uthored-[Bb]y: *//; s/ *<.*$//')
  grep -viE "$pattern" "$msg" > "$msg.new"
  git interpret-trailers --trim-empty \
      --trailer "Assisted-by: $tool" "$msg.new" > "$msg"
  rm -f "$msg.new"
fi
Enter fullscreen mode Exit fullscreen mode

And the reviewer's side of it, the query you'd run before opening a PR's files:

# Which commits in this branch had a model in the loop and which one?
git log --format='%h %s%n    %(trailers:key=Assisted-by,valueonly)' main..HEAD
Enter fullscreen mode Exit fullscreen mode

The Name On The Merge Commit

All of the above is based on the conclusion reached in the section on authorship and none of this alters that conclusion. Responsibility lands on the human who merged, regardless of what the trailer says. That makes the label a tool for the reviewer, not an excuse for the author. "Assisted-by" is a place to look harder. It is not a place to point when the function falls over.

So, does your team label and did the label change anything about how PRs get read? I'm curious, because I suspect most teams are in the middle state, trailers everywhere, consumers nowhere.

The merge commit already has a name on it. The only open question is whether the diff tells you where to look harder.


Thanks for reading! English isn't my first language, so I use AI to polish the grammar. Everything else here - the ideas, the code, the opinions - is mine.

Enjoyed this one? Let's stay in touch — I'm on LinkedIn, always happy to chat, swap ideas, or just say hi. 👋

Top comments (2)

Collapse
 
deanlee profile image
Dean Lee

I would want the trailer to say what changed the review obligation, not just which tool appeared. Assisted-by is useful when it tells the next maintainer which parts deserve a second pass on provenance, tests, or security-sensitive logic.

Collapse
 
nazar-boyko profile image
Nazar Boyko

Agreed! That is the whole point for me. Assisted-by names the tool, AI-used-for names what it did. And only the second one tells the next maintainer where to look harder.