All stories
Analysis /

AI Tells: the burden of LLMs

Codeberg's members just voted to ban vibe-coded projects, which is one way of saying the question has stopped being rhetorical. I build a prose linter, so I pointed it at a decade of GitHub instead — and the load turns out to be real, to land on pull requests rather than issues, and to look nothing like the tells everyone repeats.

By Joseph Kato LanguageOpen sourceAI

In July, the members of Codeberg voted to prohibit vibe-coded projects in their terms of use, on the grounds that these tools are incompatible with maintaining free software. Their reasoning is mostly about infrastructure — crawlers, hardware prices, donation money spent on machines — and it is theirs to make; I am not here to relitigate it. What it told me is that the question has stopped being rhetorical. A forge with real maintainers took a vote on whether this stuff is a net cost to them.

Which made me curious about a surface neither side of that argument tends to cite, because it happens to be public and I happen to have a tool for it: the writing. Every issue and pull request on GitHub is prose someone produced and someone else has to read. If these tools changed what arrives in a maintainer’s inbox, the text should show it.

I build Vale, a linter for prose, and someone has already done the hard part of naming the register: vale-ai-tells collects the vocabulary models overuse into a Vale style package, drawn from academic work on AI fingerprints and from Wikipedia’s own AI-detection guide. That makes a workable instrument. Point it at prose written before these tools existed, point it at prose written after, and see whether the numbers move.

So I did, across 2020 to 2025, on the least literary corpus I could think of: 26,658 opened issues from GH Archive, stripped of code fences and logs, scored against 176 flagged words. Bug reports are a hostile place to look for style. That is the point. Whatever turns up here is not someone trying to write beautifully.

The load is real, and it lands on pull requests

Start with the crudest version of burden: how much arrives. The windows below are different lengths, so everything is a per-month rate, and the pull-request counts drop Dependabot and the other familiar bots — a project switching on automated updates should not read as a surge in human contribution.

Change in monthly pull requests

Per-month pull requests opened, recent window against before assistants, bots excluded.

Show the data
ProjectChange (%)
VS Code191
Home Assistant49
PyTorch36
Rust33
Go9
Kubernetes-27

Source: GitHub search API; collected in scripts/fetch-project-tells.mjs

Pull requests are up in 5 of 6 popular projects, and the leader is not subtle: VS Code went from about 289 human-opened pull requests a month to 841, a rise of 191%. That is the editor most of these assistants ship inside, now fielding roughly three times the patches it used to. I checked whether that was simply bots being miscounted. Excluding them barely moves it.

Issues are the weaker signal — up in only 4 of 6, and modestly where they rise. The asymmetry is the most useful thing in this piece. These tools lower the cost of submitting a change far more than the cost of noticing a problem, which fits what they actually do: a model can produce a diff on request, but it cannot observe that your thermostat integration stopped reporting overnight. The burden arriving in open source is review burden, specifically.

And the exception matters as much as the rises. Kubernetes is down 27% on pull requests and down on issues too, which is a reminder that project lifecycle swamps everything else in a volume number. A mature infrastructure project past its hype curve goes quiet regardless of what the tooling does. Volume measures a project’s whole situation at once, and anyone reporting it as an AI metric without saying so is selling you something.

The prose changed too

Flagged vocabulary in GitHub prose

vale-ai-tells matches per 1,000 words in opened issues and pull requests, by year.

  • Issues
  • Pull requests
Show the data
YearIssuesPull requests
20200.3280.218
20210.3210.291
20220.3680.208
20230.3410.254
20240.5140.247
20250.8280.586

Source: GH Archive; scored in scripts/fetch-github-ai-tells.mjs

For four years the rate sits flat near 0.34 matches per thousand words. Then it climbs: 0.514 in 2024, 0.828 in 2025 — roughly 2.4× the pre-assistant baseline, with a 1.6× jump in the final step alone. Pull requests move the same way at a lower level, which fits, because a PR body is half template and a template does not change its diction.

Hourly archive files vary enormously in size, so a finding that only appears in the hours I happened to sample is not a finding. I re-scored the last step on hours the series never touched — same month, same hour of day, a year apart — and the rate went from 0.412 to 0.971, a 2.4× step. Different sample, same direction, similar size. The shift is real.

Length moved with it. Mean issue length rose from 74 words to 127, up 72%, and the replication hours agree (78 to 101). Bug reports are not becoming that much more informative on their own.

Issues are getting longer

Mean words per opened issue and pull request, by year.

  • Issues
  • Pull requests
Show the data
YearIssuesPull requests
20207446
20217648
20228368
20237775
20248193
202512765

Source: GH Archive; scored in scripts/fetch-github-ai-tells.mjs

Not the words you were promised

Which tells grew

Flagged words by how much their rate rose in issue prose, after versus before assistants.

Show the data
WordGrowth (x)
innovative16.3
seamless8.5
streamline8.1
comprehensive5.8
robust4.7
ignite4
evolving3.8
navigates2.8
actionable2.3
scalability2.2

Source: GH Archive; scored in scripts/fetch-github-ai-tells.mjs

The celebrity tell is delve, and delve is nowhere on this list. Nobody delves into a stack trace. What rose is the register of corporate competence: innovative, seamless, streamline, comprehensive, robust, actionable, scalability. Words that promise diligence.

Which makes sense once you picture the prompt. A model asked to file a bug report does not reach for lyricism; it reaches for the vocabulary of professional thoroughness. The tells are domain-shaped, and a detector tuned on essays will look straight past them. If you want to catch this register in a tracker, you want the commit-and-issue half of that package, not the general one.

Where it lands

Where the flagged vocabulary shows up

Share of opened issues whose body contains one of the five probe words, 2024 to 2025.

Show the data
ProjectIssues flagged (%)
PyTorch3.91
Go0.89
Kubernetes0.78
VS Code0.58
Rust0.29
Home Assistant0.23

Source: GitHub search API; collected in scripts/fetch-project-tells.mjs

Averages hide the thing you want to know, so I asked a narrower question of the same 6 projects: what share of a project’s issues contain at least one of the 5 words that rose most. Every one of them went up. Not a single project held flat, which is the strongest evidence here that something general is happening rather than one community drifting. But the levels differ wildly — PyTorch sits at 3.91% of issues, about 17× the 0.23% in Home Assistant.

How much each project changed

Growth multiple in the flagged-issue share, recent window versus before assistants.

Show the data
ProjectGrowth (x)
PyTorch5.4
VS Code4.5
Kubernetes3.3
Go2.7
Home Assistant2.3
Rust2.2

Source: GitHub search API; collected in scripts/fetch-project-tells.mjs

Growth runs 2.2× to 5.4×, and PyTorch both starts highest and climbs fastest — 0.72% to 3.91%, a 5.4× move. There is an irony in the framework most of this tooling is built with hosting the most machine-inflected prose in the sample, though I should immediately complicate it: robust and comprehensive are ordinary machine-learning vocabulary. An issue about robust training is using the word correctly, and some of that project’s level — and some of its growth, as the field moved toward exactly those topics — is subject drift rather than style. The probe cannot separate the two.

The bottom of the range is easier to read, and it is the practical finding. Home Assistant and Rust changed least, and both run strict issue forms: pick a category, fill the fields, paste the version string. A template is a constraint on prose, and a constrained field is a poor place to be expansive. If there is a practical defence in this data, it is that one: not detecting the register after the fact, but leaving less room to write it in.

The timing indicts the editor, not the chatbot

Assistant SDK downloads

Monthly npm downloads for the two vendors with public numbers.

  • OpenAI SDK
  • Anthropic SDK
Show the data
MonthOpenAI SDKAnthropic SDK
Jun 220M0M
Jul 220M0M
Aug 220M0M
Sep 220M0M
Oct 220M0M
Nov 220M0M
Dec 220M0M
Jan 231M0M
Feb 231M0M
Mar 232M0M
Apr 232M0M
May 233M0M
Jun 233M0M
Jul 234M1M
Aug 235M1M
Sep 235M1M
Oct 235M1M
Nov 235M1M
Dec 235M1M
Jan 246M1M
Feb 246M1M
Mar 247M2M
Apr 247M2M
May 248M3M
Jun 248M2M
Jul 249M2M
Aug 2410M2M
Sep 249M2M
Oct 2410M3M
Nov 2410M3M
Dec 249M3M
Jan 2511M3M
Feb 2513M4M
Mar 2515M5M
Apr 2516M5M
May 2518M6M
Jun 2520M7M
Jul 2523M8M
Aug 2527M9M
Sep 2529M10M
Oct 2533M11M
Nov 2532M12M
Dec 2534M13M
Jan 2642M17M
Feb 2650M24M
Mar 2671M41M
Apr 2679M64M
May 2693M85M

Source: npm registry; collected in scripts/fetch-ai-adoption.mjs

Here the easy story breaks. ChatGPT launched at the end of 2022, and if that were the cause, 2023 would show the break. It does not — 2023 is flat. The move belongs to the last two years, which is when assistants stopped being a website you pasted into and became something resident in the editor and the pull request: Copilot Chat, Claude, Cursor, agents that open patches themselves.

App installs are private, but developer uptake of the client libraries is not, and it is the same adoption curve from the supply side. Both bend upward through exactly the window where the prose moves, steepening hard in the last year. OpenAI’s package runs about 93.5M downloads a month and Anthropic’s 85.4M — roughly 91% of it, near parity, from nothing in 2023. On Python the gap is wider (398.6M against 185.1M, or 46%). None of this identifies who wrote any given sentence. It does say that the tools which write code arrived on the prose shift’s schedule, and the chatbot did not.

The tell that wasn’t

I expected the em-dash to carry this piece. It is the most-repeated fingerprint in every thread about spotting machine writing, and it is trivial to count.

It did not survive. In the sampled hours the rate rose; in the replication hours it fell, 0.613 to 0.391 per thousand words. Worse, the absolute rate differs by nearly an order of magnitude between two samples of the same year (0.129 against 0.391) — a few long issues by people fond of punctuation are enough to swing it. At this sample size the em-dash measures nothing at all.

That is worth stating plainly, because the claim circulates as though it were settled. On this corpus the boring vocabulary signal replicated and the famous punctuation signal did not. If you are judging a contribution by its dashes, you are not detecting a model. You are detecting a writer.

I ran it on myself

The obvious objection to all of this is that I am the sort of person who writes like the lexicon. Formal register, linter author, and those are words I use. So I pointed the same instrument at 1,487 of my own GitHub replies — 55,395 words across the projects I maintain, quoted text stripped, because that is someone else’s writing.

My replies against GitHub at large

Flagged words per 1,000 words. Mine are comments; GitHub's are opened issues.

  • My replies
  • GitHub issues
Show the data
YearMy repliesGitHub issues
20171.239
20181.282
20190.369
20200.2470.328
20210.1780.321
202200.368
20230.20.341
20240.1910.514
20250.5810.828

Source: GitHub API and GH Archive; scored in scripts/fetch-my-tells.mjs

The objection lands, but not in the direction I expected. My rate is 0.379 per thousand overall — around GitHub’s pre-assistant baseline, well under its 2025 level — and the shape is backwards. My worst years were 2017 and 2018, peaking at 1.282, higher than anything GitHub has posted since, and five years before a model could write a paragraph. By 2025 I was at 0.581. The lines cross.

So I did write like an AI, in 2017, before there was an AI to write like. Which is the least mystical possible explanation of this whole register: the models did not invent it. They absorbed it from people who already wrote that way — some of us then drifted off it as the average drifted onto it. My particular tells are notably and aforementioned, the stiff connectives of someone recently out of a maths degree. What rose across GitHub was innovative and seamless, the vocabulary of product marketing. Same lexicon, opposite halves.

Shorter, not longer

Mean words per item — my replies against GitHub's opened issues.

  • My replies
  • GitHub issues
Show the data
YearMy repliesGitHub issues
201749
201846
201948
20204374
20213376
20222583
20232977
20243181
202539127

Source: GitHub API and GH Archive; scored in scripts/fetch-my-tells.mjs

Length runs the other way too. GitHub’s issues grew; my replies shrank, from 49 words to about 39. That is less a style choice than what a decade of maintaining something does to a person. The prose you write at hour one of a project and at issue nine hundred are different prose. One caution I would raise about anyone else’s version of this chart: 21 flagged words in 55,395 is thin for a per-year line, so read the direction and the level, not the wiggles.

Commits are the other half, and the half that package has a dedicated ruleset for: agents are said to narrate themselves, justify at the end, and reach for gitmoji far more than people ever did. Git needs no API, so this one I could simply measure — 5,211 commits across 58 public repositories. The lexicon found 3 flagged words in 36,258 words (showcase, harness, granular, once each), a rate of 0.083 per thousand, an order of magnitude under what GitHub’s issues run at now. Gitmoji: 12 commits out of 5,211.

The subject line is the flat part — across 11 years it has stayed between 3.4 and 5.5 words, which is what the most constrained writing a programmer does looks like. What changed is underneath. This year my commits average 34.4 words against 4.7 before, with 21.4% carrying a real body, because I started writing the reasoning down: what broke, which path produced it, why the fix has the shape it has. The flagged rate for that year is 0.16. Seven times the prose, none of the register.

These are public commits only. Private work is invisible to this method, so the count is a floor rather than a total.

What a word count can tell you is narrow, and worth having anyway. Something did change, in 2024 and 2025 rather than at the chatbot’s launch. It arrives as review load rather than triage load. It is legible in a vocabulary of promised diligence rather than in the punctuation everyone polices. And the projects that felt it least were the ones that had already decided how much room a contributor gets to write in — which is the only finding here that suggests a lever.

The part I keep turning over is smaller than any of that. The register now read as machine-written is one humans built; the models learned it from us, and I was writing it in 2017. Whatever is arriving in these trackers, it is speaking in a voice we taught it. The tell was ours first.