← Back to all posts
News

0.7% to 41% of GitHub PRs. Nobody Wrote a Detector.

August 28, 2026 · 01:14 UTC · News
0.7% to 41% of GitHub PRs. Nobody Wrote a Detector.

TL;DR

Louis Abraham sampled GitHub pull request descriptions every day for 603 days, ended up with 461,121 of them and 51,079,244 word appearances, and sorted every single one into ten buckets by vocabulary alone. One bucket was 0.7% of the corpus across the first eight weeks of 2025. Across the last eight weeks it is 36.6%, and in the single week ending August 17, 2026 it was 41.5%, or 2,582 of 6,216 descriptions. The project is called The load-bearing vocabulary of Claude, it hit the Hacker News front page on August 27, and the word at the top of that bucket beats the rest of the corpus by 39x.


The model does not know what a calendar is

This is the part that makes the chart worth trusting, so start here. The method is k-means with Kullback-Leibler divergence swapped in for squared distance, run at k = 10 over the whole 85-week window. Each of the ten centres is a fixed distribution over a 19,798-word vocabulary. Each description gets assigned to exactly one centre, by its words, and that is the entire model.

There is no time parameter in it. Not a trend term, not a per-week weight, nothing. The weekly curve is not something the fit produced, it is something a person counted afterwards by tallying the assignments week by week.

Think of it as sorting two years of mail into ten piles by handwriting, with the postmarks covered up, and only then checking the dates. If one pile turns out to be almost entirely from this spring, the pile did not arrange that. It has no idea what spring is.

share of pull request descriptions in the leading cluster 0% 20% 40% 2025-01 2026-01 2026-08 41.5%
Flat for thirteen months, then February 2026. The fit has no way to represent time; the curve is counted after the fact.

The cluster crossed 1% in the week of February 2, 2026, 10% by April 13, 20% by May 11, and 40% by August 3. A least-squares line over the last twelve weeks puts it at plus 1.24 points a week, still climbing.

The words

Words are ranked by a ratio of two frequencies, how often a word appears inside the cluster against how often it appears everywhere else, with a pseudo-count in the denominator so a word written three times outside cannot win the list on noise. The top twenty is not a list of technical terms. It is a list of postures.

times more frequent inside the cluster than outside load-bearing39.5x plainly33.8x quietly29.9x refusal27.8x genuinely24.5x seam15.9x em dash5.4x
Ranks 1, 2, 3, 4, 10, 51 and 852 of the thousand words the page publishes.

The rest of the top twenty runs survived, re-derived, halves, asserted, nobody, deliberately, premise, refuses, outright, byte-identical, genuine, carries. That is the vocabulary of something arguing with itself about whether a change is safe.

Notably absent: delve does not appear anywhere in the published thousand. That tell belongs to a different tenant.

The em dash sits at rank 852 with a modest 5.4x lift, which undersells it. Measured as a rate rather than a ratio, it went from 0.64 appearances per 10,000 words across the first eight weeks of the corpus to 126 per 10,000 across the last eight. That is roughly 196x. Pew found the same marker doubling on the open web last week; on GitHub it did rather more than double. This blog bans the em dash as a house rule and will now stop talking about it before the smugness becomes structural.

The floor that counts people, not words

The one design choice worth stealing is the vocabulary floor. A word enters the vocabulary when 50 distinct accounts have written it. Not 50 appearances, 50 humans.

The reason is in the data. The token store-path shows up 242 times across 242 descriptions from exactly 2 accounts, which is not a word in circulation, it is one document pasted 242 times. load-bearing shows up 1,011 times across 905 descriptions from 848 distinct accounts. seam: 1,849 appearances, 1,135 accounts. Frequency cannot tell those apart. Author counts can.

That floor cuts the vocabulary from 2.1 million tokens to 19,798, and it was picked on a property of the method rather than on the answer: it is the least restrictive floor at which two independent fits agree on half of their top twenty words.

The rest of the cleaning is similarly unglamorous and similarly important. Logins ending in [bot] or -bot, plus copilot, are dropped outright, which is 3,784 accounts and 13.2% of collected rows. Four Apps are excluded in the query itself. No author may contribute more than three descriptions to a week, which catches mass-produced text from accounts that look human. Empty bodies, 45% of all pull requests, are filtered in the query. Median surviving description: 65 words.

The side finding: your GitHub research is probably broken

Buried in the methodology is a result that matters to anyone who has ever run a query against public GitHub data. GH Archive, the public mirror of GitHub's event stream, has been quietly gutted since mid-2025. The feed now carries almost nothing but push events, and GitHub stripped commit summaries and counts out of push payloads effective October 7, 2025. Pushes carry no text, so the text is gone.

IssueCommentEvent rows in one hour of the public feed 2024-08-1213,555 2026-08-1086 same hour of the day, two years apart
The comments did not disappear from GitHub. They disappeared from the feed everyone measures GitHub with.

The upstream issue has been open since July 2025 with no maintainer reply, and the same gaps show up in OSSInsight, which reads the API directly. No mirror repairs it, because they all drink from the same pipe.

An earlier version of this very project, built on the archive, reported the phrase in 17 documents. The search-API rebuild found 1,011 appearances. That is an error of 158x, produced by a data source that returned successfully every time it was asked. If you have a dashboard, a paper, or a blog post built on GH Archive event text after mid-2025, that is your afternoon.

What this is not

It is not a Claude detector, and the author says so directly on Hacker News: he is finding that a particular cluster of vocabulary increases, and tracking a specific model would need labelled data. The name on the page is an inference from the words, not a measurement of provenance. Read it as "a way of writing arrived," not as "41% of pull requests were written by Claude."

Three more caveats, all documented by the author rather than dug out of him:

  • The seed moves the headline. The fit published on August 28 uses seed 6 and reports 36.6% across the last eight weeks. The repository README states 39%. Versions circulating elsewhere quote 45%. The shape is stable across restarts, the exact endpoint is one fit's answer.
  • The cluster count was chosen on the outcome. At k = 8 the leading component comes out mixed with WebKit, nixos and CSS vocabulary in 7 of 32 fits. Above k = 14 it fragments until the pieces fall below the 20% arrival check, at 6 of 8 fits for k = 16 and 1 of 8 for k = 24. Ten sits inside that window, but it was picked from it.
  • This samples, it does not enumerate. A day of 2026 holds roughly 460,000 matching pull requests, a five-minute window about 1,250, and a search page returns at most 100. Each window is truncated to its earliest hundred. Placement is uniform in time, so the bias is in width rather than in when, but it is a sample.

The second signal

An independent check exists. On June 14, 2026, Marek Suppa grepped his own transcripts: roughly 60,000 assistant turns and 1.7 million words, with the phrase in 151 turns and 188 occurrences, about 0.25% of turns. He also lines the Google Trends spike up with Claude Opus 4.6, released February 5, 2026, which is exactly the week the cluster crossed 1%. Two people, two unrelated corpora, one inflection point. That is not proof of causation, but it is a coincidence with good timing.

Why a builder should care

If you review pull requests, roughly two in five descriptions you read this month came out of one narrow band of vocabulary. That is not automatically bad. It does mean the signal you used to get from prose style, the sense that a careful person wrote this and a careless person wrote that, has been compressed toward a single register that says deliberately and byte-identical whether or not the change deserves either word.

And the method generalises cheaply. Ten daily API calls, no labels, standard library for collection, about fifty seconds of fitting on twelve cores. Point it at your own review corpus, your changelogs, or your incident write-ups and you get the same picture for your own organisation, without buying a detector that would have told you less.

Key Takeaways

  • One vocabulary cluster went from 0.7% of GitHub pull request descriptions in early 2025 to 41.5% in the week ending August 17, 2026, across a corpus of 461,121 descriptions and 51,079,244 word appearances.
  • The model contains no time variable. Descriptions are assigned by words alone under KL k-means at k = 10, and the weekly curve is counted afterwards, which is why the trend cannot be an artifact of the fit.
  • The phrase load-bearing leads the list at 39.5x, written by 848 distinct accounts; delve does not appear in the published thousand at all.
  • The vocabulary floor counts distinct authors, not appearances, which is the cheapest way to stop one pasted document from masquerading as a trend.
  • GH Archive event text has been effectively dead since mid-2025, and an earlier build of this project was wrong by 158x because of it. Anything you built on that feed needs rechecking.
  • This is not model attribution. The author says so: no labels, no provenance, just a way of writing that arrived in February 2026 and is still gaining 1.24 points a week.

Sources: The load-bearing vocabulary of Claude, louisabraham/load-bearing (methodology and corpus), Hacker News discussion, Boing Boing, Marek Suppa: "Load-bearing" is becoming LLM speak, GitHub Changelog: Events API payload changes, gharchive.org issue #310, Anthropic: Claude Opus 4.6

AIGitHubStylometryClaudeCode ReviewResearchClusteringOpen Source
CONSOLE
$