This is Part 8 of AI Grew Up on Git, a series on the Git infrastructure that raised AI and what AI is now doing to it.
Part 1 of this series opened on a small company revoking something a community depended on, and a programmer who responded by building a version control system on one idea: a hash is a name that cannot lie, and a chain of hashes lets strangers trust a history without trusting whoever holds it. That was never a small claim. For the tool underneath nearly all of modern software, it was the entire claim.
Every part since has been the same promise, tested against something it was never built for. GitHub’s social layer. A model’s weights. A decade of scientific claims. A $7.5 billion acquisition nobody understood the value of until years later. The diff itself, refusing to run on model weights at all. The identity of an author who might not be a person. In each case the promise didn’t break. It got stretched, by hand, one workaround at a time, and the workarounds are the real subject underneath all of it.
This part asks what’s happening to that promise right now, this year, while it’s still being decided.
Signing the thing Git could never hold
Across 2025 and 2026, Google’s open-source security team, the Sigstore project, and the Open Source Security Foundation built something with a name that doesn’t bother being clever: Model Signing. The idea is Git’s idea, aimed for the first time directly at the file Parts 3 and 6 of this series spent two parts proving Git could never really hold. Sign the model when it’s trained. Verify it every time it’s used. That’s the whole design, in the words of Google’s Mihai Maruseac, one of the engineers who built it.
The mechanism updates Git’s original trick rather than replacing it. There’s no long-lived private key for anyone to lose or steal. A publisher’s identity gets a short-lived certificate tied to a login, the signature lands in a public, append-only log anyone can check without asking permission. It is Part 1’s tamper-evident chain, generalized past a single repository into a shared public ledger that no single party controls. It is not a pilot project sitting in a lab. Google partnered with Kaggle to sign models automatically at upload. NVIDIA integrated the same approach into NGC. Two of the largest model hubs in the world quietly started doing, for weights, the thing Git has done for text since 2005.
Name what this closes. The gap Parts 3 and 6 spent so much time describing, a file Git could hash but never meaningfully compare, just got the other half of Part 1’s original promise applied to it directly, not laundered through a pointer trick. The industry is rebuilding, in public, by hand, the exact thing Part 1 started twenty years ago.
A signature that worked, and still signed an attack
On May 11, 2026, between 19:20 and 19:26 UTC, six minutes, that same family of protection failed in the most instructive way it could have.
Attackers published 84 malicious versions across 42 packages belonging to TanStack, a widely used piece of open-source JavaScript infrastructure, through TanStack’s own legitimate release pipeline. Nobody’s password was stolen. No npm token was stolen. The attackers chained three separate, individually known weaknesses: a pull request that ran with more trust than it should have, a poisoned build cache waiting for the real release process to restore it, and code that reached directly into the release runner’s memory to extract the short-lived credential the legitimate pipeline itself had just been issued. When that pipeline published, it published exactly what it was supposed to trust.
The result was the first documented attack in npm’s history to carry fully valid, cryptographically verified build provenance. The signature was not forged. It was correct. As one security newsletter put it precisely, in the exact week this was happening: provenance attests pipeline identity, not pipeline honesty.
The attack didn’t stay contained. A week later, a completely unrelated project, a popular code editor extension, shipped a compromised release of its own, traced back to a single contributor whose own machine had quietly installed one of the poisoned TanStack packages seven days earlier. The broader campaign spread to roughly a hundred and sixty packages across two ecosystems within about a day. Trust, once it slipped, moved through the same channels that make open source work at all.
The cleverness of the attack isn’t the point. The point is what TanStack’s own maintainers said afterward, in their own names, in their public account of what they’d rebuild. The parts of their security posture they’d actively invested in, trusted publishing, two-factor authentication, signed commits, were not the part that failed. The part they hadn’t hardened was the automation running underneath all of it, and that is what they went and fixed. A cryptographic signature has only ever proven one thing: that a specific process produced a specific artifact. It has never once proven that the process, or the artifact, deserved anyone’s trust. Git’s hash never promised the code was good. It promised the code was unaltered. Nothing about a year of real, serious, well-built signing infrastructure changed that promise’s actual size, and mistaking it for a bigger one is exactly how a correct signature ends up certifying an attack.
None of this is an argument against the work in the previous section. It’s the argument for why that work is only half of rebuilding trust, and it was always the easier half.
Merge, or rebase
Git has always offered two different ways to bring one line of history into another, and underneath the technical difference is a real choice about what history is for.
Merge keeps everything. The false starts, the parallel work, the actual, messy order events happened in. Nothing gets deleted. Nothing gets rewritten. The record stays complete, including the parts that don’t flatter anyone.
Rebase does something else entirely. It takes real commits and gives them new identities, replaying them as though they’d happened in a cleaner order, on top of a history they were never built on. What comes out reads better. It is also, in a way that matters, a different history than the one that occurred.
Here is the real question underneath all seven parts before this one, named directly for the first time. As agents write more of the code that ships, does the record keep what actually happened, an AI’s fingerprints, its false starts, the Assisted-by tags Part 7 described, intact and inspectable, the way a merge would keep them. Or does that record get cleaned up afterward into a tidier story, rebased into something that looks like it never needed explaining. Both are ordinary, everyday Git operations. Neither is wrong, in the way the tool defines wrong. The industry hasn’t picked one, and the choice was never really technical. It’s the same choice Part 7 already found once, wearing a different name, dressed up as a question about which tag goes on a commit.
The log, replayed
Return, once more, to where this all started. Part 1 built distrust into version control on purpose, in the wake of a company that revoked something a community depended on. That distrust turned out to be the right starting assumption for almost everything that came after it, including this part.
commit 1/8
What changed: Version history stopped needing a trusted server; every copy became the proof.
Why: The kernel had trusted a company once, and the license did not survive the trust.
commit 2/8
What changed: Contributing to someone else's code stopped requiring their permission to start, only their approval to finish.
Why: GitHub wrapped Git's pulling in a social object, and the cost of a stranger's first contribution fell to one button.
commit 3/8
What changed: The weights of the AI era got a home that looked like GitHub, by tricking Git into versioning files it was built to reject.
Why: A model is one giant blob where every byte changes at once, and Git only knows how to version text that changes a line at a time.
commit 4/8
What changed: Checking a scientific claim stopped meaning rebuilding the work from prose and started meaning cloning it and pinning history to one commit.
Why: A result with an address can be rerun by a stranger, and machine learning's papers grew up with addresses.
commit 5/8
What changed: A code-hosting business was bought for its hosting, and turned out to be worth more for what it had been quietly recording the entire time.
Why: Nobody in 2018 had built a model that could learn from a platform's history. Three years later, somebody had.
commit 6/8
What changed: Git's core promise, that any two points in history can be honestly compared, quietly stopped applying to model weights.
Why: A model's weights have no lines to compare, and worse, two functionally identical models can share zero bytes in common.
commit 7/8
What changed: The line that certifies a commit was hardened to exclude the one kind of contributor legally unable to hold it, at the moment that kind of contributor became common.
Why: A signature has always meant a person vouched for the code, and keeping that meaning intact required writing down, for the first time, exactly who is allowed to vouch.
Read back to back, the pattern is the whole argument. Every part of this series found the same promise reaching somewhere it was never built to go, and every part found people extending it by hand rather than replacing it. Nobody designed this history. It got assembled the way infrastructure always gets assembled, one reasonable fix at a time, by people solving the nearest problem in front of them.
Version control never controlled the code. It never could have; that was never the job. What it has controlled, since a Finnish programmer sat down angry about a revoked license, is the record of who can be held to have touched a piece of history, and whether that record can be quietly altered after the fact. That is what had to be rebuilt for an era when some of the collaborators typing into it were never people at all, and rebuilding it was never only a cryptography problem. It is a choice, made new with every commit, about whether the record stays honest or gets cleaned up into something easier to look at.
commit 8/8
What changed: Eight parts later, the answer to what version control protects turned out to be simpler than the question. Not the code. The record of who can be trusted to have touched it.
Why: A hash never lied about the past. Whether that stays true for the collaborators still to come is a choice, not a certainty, and it gets made again with every commit.
The Working Tree
Two ways to bring history together, and the choice between them is the choice Section 4 described.
Merge takes two branches and creates a new commit that has both as parents, joining the histories without touching either one.
git merge feature-branch
Rebase takes the commits on one branch and replays them, one at a time, on top of a different starting point, generating a brand new commit for each one, with a new hash, even though the actual change each commit makes stays the same.
git rebase main
That’s the whole technical difference, and it’s also the whole philosophical one. A merged history shows you what happened, including the mess. A rebased history shows you a version of what happened, edited for clarity after the fact. Git will let you do either. It has no opinion about which one a project, or an era, should choose. That part was never Git’s to decide.
This is Part 8 of AI Grew Up on Git, a series on the Git infrastructure that raised AI and what AI is now doing to it. This is the final part of the series.


