Release Gates Are How Fast Teams Stay Fast

A release candidate moved quickly because its identity stayed fixed and every available gate left evidence.

Someone is checking items off a checklist.

A release candidate moved quickly because its identity stayed fixed and every available gate left evidence.

The release timeline began with an unhelpful fact: hosted CI wasn't available.

At that moment, we could wait without learning anything, proceed as though the usual check didn't matter, or build an alternate evidence path and record the gap. We chose the third. It wasn't exciting, but neither is explaining an imaginary pass later.

The key was treating the candidate as fixed. “Whatever is newest” wasn't going to work. Once verification began, “the release” meant an exact revision, not whatever happened to be at the branch tip. Every build, test result, and review note had to refer to that identity. Otherwise a fast sequence of successful checks could still describe different code.

Candidate fixed, gap recorded

First, the candidate revision was recorded and the source state confirmed clean. The hosted-CI status remained unavailable in the release record. We didn't convert absence into success, and we didn't hide the missing gate in a comment that nobody would see during approval.

Recording the gap early prevented later negotiation with the evidence. Everyone knew which usual signal wouldn't arrive and what local work could and couldn't replace. The decision was no longer “Do we feel good enough?” It was “Does this alternate record satisfy the release criteria with the stated limitation?”

The gap entry included the time it was observed and the fact that it affected the hosted path rather than the candidate result. This avoided two bad interpretations: that the code had failed remotely, or that no hosted run was expected. The record said exactly why the usual row could not produce evidence.

The candidate identity also froze the clock in a useful way. Any source change, however small, would create a new candidate and restart the affected gates. I've argued with this rule before; the rule was right. It is faster than debating which old results remain transferable to changed code.

Two machines, one head

The next phase ran the build and test gates on two different machines. Before each run, the exact revision was confirmed. Commands and results were captured rather than summarized from memory.

The first machine established that the candidate built and its tests passed in one local environment. The second applied the same gates elsewhere. If they disagreed, we weren't taking a vote. Agreement helped expose dependence on local caches or unnoticed workstation state. Disagreement would've held the candidate while we investigated; selecting the nicer result wasn't an option.

The order was deliberate. Each machine confirmed identity immediately before its commands and attached output immediately after. That kept a passing result from floating free of its source revision. It also made interruption recoverable: an incomplete row stayed incomplete instead of being reconstructed later from shell history.

This wasn't an attempt to recreate every property of hosted CI. Local machines aren't a controlled hosted runner, and two successes don't erase that distinction. They do provide independent evidence about an exact head. The release record should preserve both the strength and the limit of that claim.

The sequence stayed short because the gate definitions were already clear. Build meant the candidate produced the expected artifact under the recorded command. Test meant the defined suite completed successfully, with skips and warnings visible. Neither gate absorbed vague manual confidence.

The evidence ledger

By the decision point, the release evidence fit in a compact ledger:

Gate Candidate Evidence Result
Source identity exact revision clean-state record passed
Build A same revision command and output passed
Test A same revision command and output passed
Build B same revision command and output passed
Test B same revision command and output passed
Hosted CI same revision service unavailable gap recorded

The ledger was useful because it made review finite. Nobody needed to reconstruct the afternoon from chat messages or infer whether the second machine had pulled a later commit. That is a miserable way to approve a release. Each row made one claim, pointed to evidence, and named its result.

Warnings and skipped checks were not flattened out of those references. The table stayed compact, while its evidence links retained the detail. A reviewer could move from the release-level summary to the raw result without asking the person who ran it to remember what scrolled past.

It also made the release decision separable from the verification work. The people running gates did not have to pretend the missing hosted system was irrelevant. They produced the available evidence. The decision owner could then weigh the explicit gap against the scope of the candidate and release criteria.

Release gates are sometimes described as friction added for safety. That description fits badly when the gates are well formed. Ambiguous evidence creates the real delay: rerunning commands because nobody captured output, discovering that a branch moved, or arguing about what a green label represented. Exact identity and small, named gates remove those loops.

There is a cost to restarting when the candidate changes. There is also a cost to carrying old results forward through a series of “tiny” edits. The second cost is harder to see because it appears later, usually as uncertainty during approval or diagnosis. I would rather pay the visible cost while the change is still in hand.

The hosted service eventually returning would supply its own result against a candidate. It wouldn't retroactively change what the local ledger proved at the release decision. That historical honesty matters. A release record should describe what was known when the decision was made, including the unavailable check.

The timeline ended without a ceremonial green badge, and I didn't miss it. It ended with one exact revision, matching build and test results from two machines, and a hosted-CI row that still said unavailable. The release owner could make the call without reopening how the evidence was produced, which is where the afternoon would've gone otherwise.