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. 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: export exactly what git tracks under the OSS tree: no ignored files, no build outputs git ls-files -z -- runtime | tar --null -T - -cf - | tar -xf - -C "$MIRROR" --strip-components=1 refuse to publish anything that matches a list of private markers 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 https://github.com/contenox/contenox . The history that got it there is at github.com/contenox/contenox-v0 https://github.com/contenox/contenox-v0 . The measurements are in the Lab: contenox.com/docs/rnd/handwritten-vs-generated/ https://contenox.com/docs/rnd/handwritten-vs-generated/ .