Nothing Interesting Happens After Merge
In a fleet of agent-run repositories, the merge to main is the last point where judgment is exercised. Someone, or some agent acting under review, decided the change was correct and let it land. Everything that happens after that decision is clerical: figure out what kind of change it was, compute a version, write the changelog entry, check the docs, cut the tag, publish the release, tell the people and agents who care. None of it should require thought, and none of it should be capable of surprise.

We learned this the way most operational lessons get learned, by watching the alternative fail quietly. When post-merge work is discretionary, it gets done differently every time, and eventually it gets done wrong: a tag pushed by hand with the wrong version, a changelog entry that describes a change that was reverted, a release that exists on one surface but not another. So we made the post-merge path a single pipeline and wrote its rules down where drift cannot reach them.
The pipeline
On every merge to main, an orchestrator runs eight phases in order: classify, semver, changelog, GT, RTFM, tag, release, notify. Classify determines what kind of change landed. Semver computes the version bump from the commit history, following the conventional commits specification rather than anyone's opinion about how big the change felt. The changelog phase appends a structured entry, in the spirit of keep a changelog: a record for humans, generated from records for machines. GT and RTFM are two internal documentation passes; the second checks whether the docs still describe the code that actually shipped. Then the mechanical tail: tag, release, notify.
After the notify step goes quiet, something in the archive keeps counting.
Two of those phases deserve special comment, because they encode decisions we argued about.
Constraints that cannot drift
The rules governing this pipeline do not live in prose. They live in a machine-readable constraints file, and the documentation that agents read is generated from it, wrapped in marker comments with a content hash. An agent editing the doc by hand would be editing output, and the markers say so. This matters more in an agent-run fleet than it would in a human one: agents follow the documentation they are given with much less skepticism than a person who has been burned before, so the documentation has to be correct by construction, not by review.
There are five constraints in that table today.
First: pipeline execution always goes through the orchestrator script, never through ad-hoc commands. The orchestrator provides state tracking, idempotency, and an audit trail. An agent that improvises a release "just this once" produces a release with no record of how it was made, and in a fleet where the operator is not watching each repo in real time, an unrecorded action is indistinguishable from an accident.
Second: tags are never created manually. Version computation goes through a semver-bump script that parses the conventional commit history. A git tag is cheap to create and expensive to have wrong, because everything downstream (the release, the changelog heading, the notification) inherits the number. Manual tags bypass the commit parsing and can produce incorrect versions, so the rule is absolute: the script computes, the pipeline tags.
Third, and this is the one we consider the most transferable: documentation gaps found by the RTFM phase must be logged, and must not block the pipeline. Documentation drift is informational, not a release blocker. The temptation, when you build a pipeline, is to make every check a gate, because gates feel rigorous. But a gate is a claim that the failure it detects is worse than a delayed release, and for docs drift that claim is false. A release held hostage by a stale README teaches agents to route around the docs check; a logged gap teaches them to fix the docs in the next cycle. We gate on what would harm users and log what would merely embarrass us.
Fourth: every phase checks for existing work before acting. Idempotency is the load-bearing property of the whole design. Pipelines get retried: a network call fails, a runner dies, an agent re-triggers a run to be safe. If a retry can produce a duplicate tag, a duplicate GitHub release, or a doubled changelog entry, then every retry is a small gamble, and operators stop retrying, and transient failures become permanent ones. When each phase asks "does my output already exist?" before producing it, re-running the pipeline is free, and free re-runs are what make automation trustworthy.
Fifth: the full pipeline (changelog, documentation passes, release) runs only for cycle-type pull requests. A bugfix gets a patch bump and a tag, nothing more. This is proportionality as a rule rather than a habit. Running the whole ceremony for a one-line fix does not make the fix safer; it makes the ceremony slower and noisier, and noise is the thing that trains everyone, human and agent alike, to stop reading the notifications.
Why write it down this way
A reasonable objection: these are five sensible practices, and plenty of teams follow them informally. Why encode them as generated constraints with hashes and markers?
Because our repos are operated by agents, and agents have no institutional memory beyond what we hand them. A human team accumulates habits; an agent fleet accumulates only artifacts. Every convention we care about either exists as an enforced, machine-readable rule, or it exists as a suggestion that a fresh context window has never heard of. The constraint table is our answer to the question "how does a repo remember its own operational rules when nobody working in it was present when the rules were made?"
The other reason is auditability. Each constraint carries its own "why" column, so the rule and its justification travel together. When a future cycle wants to change a rule (and some rule will eventually deserve changing), the argument it has to beat is written right next to the rule it wants to replace. Semantic versioning works for the same reason: not because the numbers are magic, but because the meaning of each number is specified in public, so every consumer can hold every producer to it.
The pipeline itself is not novel, and we do not claim it is. Classify, version, log, tag, release, notify: most mature projects converge on something like this shape. What we would defend as a decision worth writing about is the posture around it. The merge is where judgment lives. Everything after the merge is bookkeeping, and bookkeeping should be orchestrated, idempotent, proportionate to the change, and incapable of blocking on anything that is not worth blocking for. When the post-merge path is boring enough, nobody watches it, and nothing goes wrong when nobody watches. That is the standard we hold the fleet to.
Get the next post
Free membership: new posts on how the fleet is built, delivered by email. Subscribe free
Post history
- 2026-08-31: enrich nothing-interesting-happens-after-merge: 2 plate(s) + shadow captions + feature image (standing admin preapproval (pending-laws 2026-07-19))
№ 2774