Release cadence: the cycle we run for every client delivery
We've cycled through every release tempo a small bot-engineering team can plausibly try — weekly, fortnightly, six-weekly, ship-when-ready. Three weeks is what survived. This note is the breakdown of what we actually do inside that window, in case it's useful to anyone running a similar pipeline.
Why three weeks, specifically
Two pressures push against each other. The first is reaction time: when a platform we ship into changes detection behavior, our clients need a corrected binary before their daily volume gets clipped. The second is regression risk: every release we cut introduces a chance of shipping our own bug into a production room, which is worse than the platform change we were trying to react to.
Weekly was too tight — the regression bench wasn't fully green when the next train left, so we were chasing our own bugs across two trains at once. Six-weekly was too slack — we shipped one core release straight into a platform policy change that had moved a fortnight earlier, and we spent the following weekend reverting. Three weeks gave us one regression sweep, one staged rollout, and one buffer day, repeating. We've been on it since mid-2023 and we haven't found a reason to change.
What happens inside the window
Each three-week window is split deterministically. Calendar drift kills cadence, so the calendar is the boss; we'd rather cut a thin release than slip the date.
- Week 1 — feature work
- Engineering against a frozen snapshot of platform detection posture from the previous train's close. New behavior, refactors, anything that needs decision-engine time. No production shipping in week 1.
- Week 2 — regression sweep
- The new build runs against the per-client table mixes we maintain in a private bench. Anything red blocks the tag. Anything yellow becomes a written carry-over note on the train — clients see the carry-over notes; they aren't hidden.
- Week 3 — staged rollout
- Client-by-client. Canary first, then tier-two operators, then the long tail. The rollback artifact is signed and parked on the delivery host before the first canary even pulls the new tag. If the canary trips, the train stops there and nothing past tier-one ever sees it.
Versioning a binary nobody else will ever run
Tags look like v2026.23-c{client_id}-{posture_hash}. The base train is calendar-versioned by ISO week. There is no SemVer here because there is no public API surface to be compatible with — calendar versioning makes the cadence legible to clients without inventing a meaning the number doesn't carry. The per-client suffix records the binary that actually shipped: two clients on the same train can be on different artifacts because their table mix, locale, and detection-vendor exposure differ.
The posture hash at the end is a short digest of which detection-vendor snapshot the build was hardened against. If a vendor pushes an update mid-train, the hash changes and the binary is rebuilt for affected clients only. That's the lever we pull when we need to react inside the window instead of waiting for the next one.
The rollback artifact we always have on hand
Every train ships with a pre-signed rollback. Not a "previous version we could rebuild" — a literally signed, hashed, delivery-host-resident artifact that we can re-attach to a client in under ten minutes. We've used it four times in three years; twice it was our bug, twice it was a platform-side change we had to step back from until the dust settled. Each time, the difference between "ten-minute rollback" and "rebuild from source" was a paying weekend for somebody on the team. Pre-signing it is cheap; living without it is not.
Want to talk through your own cycle?
If you're standing up something similar internally, or you're sizing whether to outsource the cycle entirely, the engineer on rotation will walk through it candidly.
Reach the release engineer