cd /news/developer-tools/ai-killed-git-commits-so-i-stopped-p… · home topics developer-tools article
[ARTICLE · art-104946] src=dev.to ↗ pub= topic=developer-tools verified=true sentiment=· neutral

AI Killed Git Commits: So I Stopped Publishing Them

Developer Konstantin Schubert shipped contenox 1.0.0 as a single commit into an empty repository, abandoning the traditional commit history in favor of release-based publication. The move responds to AI-generated commits that made history unreadable and turned public streams into timesheets. The new workflow uses a release mirror and a monthly publication cadence to ensure human oversight.

read4 min views4 publishedAug 20, 2026

Today I shipped contenox 1.0.0. Not by pushing a tag on top of a thousand commits, but as a single commit into an empty repository: the whole tree, one signed tag, binaries built from that tag by CI. The 957 commits that got me there are still public, in the old repository, as history. They are no longer how the project is published.

This post is about why, and about what went wrong before I had finished reading the result back.

GitHub's workflow rests on four assumptions so old that nobody states them any more:

All four were true in 2008. For a tree that agents write, none of them survive contact.

Some numbers from a tree you can inspect yourself:

A commit stream like that is not history. It is a log. Reading it tells you nothing about what a human decided — the decisions happened in prompts, in agent declarations, in a policy file — and it tells you one thing with great precision: when the work happened. If you also do client work, a public commit stream is a timesheet you never agreed to publish.

Review had quietly inverted, too. I was no longer reviewing commits. I was reviewing outcomes: does it build, do the tests pass, does the binary do the thing. The commit boundary had become an accident of when an agent stopped.

So the unit of publication moved to the only boundary that still meant something: the release.

The tree lives in a private monorepo, next to the commercial parts of the product. The public repository, contenox/contenox

, is a release mirror:

main

moves only by release.Release vX.Y.Z

and carries the complete tree. The diff between two commits is the diff between two releases — readable in one sitting, which a month of checkpoints never was.Co-authored-by

on the release commit and a line in the notes. The branch is evidence of the change, not its delivery vehicle.The mechanism is a shell script shorter than this post. The part that matters:

git ls-files -z -- runtime | tar --null -T - -cf - | tar -xf - -C "$MIRROR" --strip-components=1

grep -rIlE -f private-patterns.txt "$MIRROR" && exit 1

git -C "$MIRROR" add -A
git -C "$MIRROR" commit -F release-notes.md            # "Release v1.0.0", signed
git -C "$MIRROR" tag -a -F release-notes.md v1.0.0     # signed; the notes ride in the annotation
git -C "$MIRROR" push origin main v1.0.0               # release.yml takes it from here

Nothing here is new. Android has shipped AOSP as source drops for years, and plenty of vendors publish the same way. What is new is the reason: not secrecy, but that the intermediate commits stopped carrying information worth publishing.

The first drop shipped with a CONTRIBUTING.md

that described, in some detail, the workflow I had just built to keep my workflow out of the public repository. An agent wrote it — thoroughly, correctly, and against the brief — and I did not read it, because it was one of twenty-nine files in the commit that landed the whole mechanism. Then the Go module proxy fetched v1.0.0, and from that moment the text was permanent: you cannot re-tag a Go module without handing every later go get

a checksum mismatch.

Two lessons, neither of them about tooling.

First: every gate I had was mechanical — lint, tests, a scan for secrets and private paths — and not one of them was a human has read what is about to become permanent. The scan catches credentials. It cannot catch a paragraph of honest prose.

Second, and this one took me a minute: my reflex was to ship v1.0.1 fifteen minutes later. That reflex is exactly what the new repository exists to end. A workflow that makes publishing effortless will be used effortlessly. So the rule is not a script; it is a calendar. The public repository moves once a month. The first proof that the regime changed is a month of silence after v1.0.0 — imperfect CONTRIBUTING and all.

A repository mode. Call it release drop: main

moves only by tag; history is one commit per release; pull requests are proposals, not merges; provenance is attested per release, not per push. The platform already has every piece — immutable releases, build attestations, environments with required reviewers. It just still assumes a human typed the commit.

Until then: a shell script, a calendar, and a rule that nothing becomes permanent before a person has read it.

contenox 1.0.0 is at github.com/contenox/contenox. The history that got it there is at github.com/contenox/contenox-v0. The measurements are in the Lab: contenox.com/docs/rnd/handwritten-vs-generated/.

── more in #developer-tools 4 stories · sorted by recency
── more on @contenox 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/ai-killed-git-commit…] indexed:0 read:4min 2026-08-20 ·