A progressive delivery platform for a world where software is written and operated by both people and machines. Coldframe holds a change at zero, hardens it off stage by stage against real traffic, and pulls it back the moment the evidence turns — without waiting for anyone to notice.
Fig. 1 — the rollback lamp is lit at every stage. Nothing on this panel can interlock it.
Here is an uncomfortable truth about feature flags: not every change can hide behind one.
A database migration runs for everyone the moment it deploys. A dependency upgrade changes every process. Code that runs at startup doesn't wait for a flag check. A React hook quietly calls a new endpoint for every user while only the rendering is guarded.
A “1% rollout” of a change like that is a 100% deployment wearing a costume.
Coldframe refuses to offer that illusion. Before a rollout plan can exist, it analyses the change itself: is every behavioural change actually controlled by this flag? Does the diff touch anything a flag cannot protect? Is the flag genuinely off on arrival?
Changes that are fully flag-controlled proceed to a staged rollout. Changes that aren't are routed honestly — to a deployment canary, to a multi-phase plan, or to a person. Anything the analysis cannot prove becomes a specific, answerable question for a reviewer, never a blanket “is this safe?”
Agents can write the code. Coldframe verifies the claim.
Verification doesn't stop at reading the code. Before the first user is exposed, Coldframe runs the new build alongside the old one with the flag held at 0% — and checks that the two are behaviourally indistinguishable. Same error rates, same latency profile, same resource usage, no new failure patterns in the logs.
If the new build behaves differently with the feature off, something escaped the flag. You find out before your users do.
Your 0% is really 0%. Then your 1% begins.
Most flag platforms expose a percentage control. Coldframe exposes a plan — a durable, versioned resource describing how a change is permitted to move through production.
feature: new-checkout change: git:acme/web#4812 stages: - audience: employees minimum_duration: 2h - percentage: 1 minimum_duration: 12h minimum_exposures: 1000 - percentage: 10 minimum_duration: 24h minimum_exposures: 10000 - percentage: 25 approval: required - percentage: 100 holdback: 2% # control survives to the end final_observation: 24h guardrails: - checkout_error_rate - p95_checkout_latency - duplicate_payment_count on_regression: rollback
The platform — not the agent — owns the release state machine. It enforces stage order, observation periods, sample requirements, blast-radius limits, approval boundaries and rollback behaviour.
An agent can create a plan, inspect its progress, investigate anomalies and request advancement. It cannot skip the process by setting a flag to 100%.
The consequences of increasing and decreasing exposure are not symmetrical, so the friction isn't either. Expansion requires evidence, elapsed time and — past a point — a person. Contraction requires nothing at all.
Every mutation that raises exposure carries a compare-and-swap on the stage the caller believes it is acting on. A stale view must never be able to raise exposure. But the same instinct, applied to the brake, gives the opposite answer:
| Mutation | Guarded | Reasoning |
|---|---|---|
| advance | Yes | A stale view must not raise exposure. |
| approve | Yes | It authorises a future increase. |
| hold | No | Refusing the brake over a stale index is the wrong failure direction. |
| resume | No | The stage cannot change while held; the check could never fire. |
| rollback | No | Nothing may stand between a failing gate and zero. |
A plan with a corrupt stage index is still holdable — it records a null exposure rather than refusing. Nothing may block the brake, least of all a data problem.
Guardrail metrics are defined and owned by the team, not chosen by the agent operating the release. An agent selects from the approved set and may make a plan stricter — never more permissive. The ratchet turns one way.
Rollback is never blocked by a pending approval, a failing gate, or a minimum observation period. Every credential that can expand a rollout can also reduce it.
Agents are formidable at unstructured work. They can read a diff, identify likely risks, trace a regression to a request path, and explain what happened in a way a dashboard never will.
But the fastest safety reactions should not depend on a model. When a health gate fails, the sequence runs without anyone in it:
The agent does not need to wake up, reinterpret a metric and decide whether a rollback is justified while users are still exposed. Coldframe handles the reflex. The agent handles the investigation.
The treatment cohort is behaving like its concurrent control, on the same traffic, in the same window. The plan may leave this stage.
A guardrail moved against the control. Exposure returns to zero and the plan freezes. This does not wait for an agent or an approver.
Traffic is too thin, telemetry is late, or a cohort hasn't seen enough exposure. Never treated as healthy. The rollout holds until the evidence means something.
An error rate of 0.8% looks tolerable until you learn the existing experience runs at 0.1%. Coldframe never reads a metric in isolation — it compares against a control cohort drawn from the same traffic, and keeps a small holdback through 100% so the slow signals still have a baseline to move against.
A lack of observed failures is not automatically success.
Setting exposure to zero controls the future. It does not undo the past.
While a release was live it may have written things: records in a new shape, cache entries, queued messages. If the old code can't read what the new code wrote, a rollback doesn't end the incident — it starts a second one.
Coldframe treats this as a first-class problem. It identifies, before the rollout begins, which data the new code writes and the old code reads. It watches what the new path actually writes while the release is live. And it continuously verifies, on real samples in a sandbox, that the old readers can still parse it.
If a rollback would be unsafe, you find out while the release is still healthy and your options are still open.
For changes that alter how data is stored, Coldframe supports a two-phase pattern: ship the new behaviour while still writing the old format, then — once every reader has been upgraded — ship the new format as its own release. Each phase is independently reversible.
Rollback stays instant. Coldframe's job is making sure it is also safe.
A release system is mostly made of small decisions that only look arbitrary until you know what they were protecting against. These are recorded with their reasoning, so they can be re-decided honestly when the circumstances change.
Approval authorises leaving a stage, not entering it.
Operators think of it as a checkpoint — “I've reviewed 1%, it may complete.” Which means the gate on first exposure has to live on a stage that exists before anyone is exposed. So every plan begins on a dark stage zero, synthesised if the author omits one.
A synthesised stage is labelled, never hidden.
Hiding it would create a second index space, and the compare-and-swap rides on indices. A silent off-by-one in the one mechanism whose job is catching stale views is not a trade worth making for a tidier list.
Exposure comes down through exactly one named path.
A single withdrawFlag function, not a boolean parameter on the ordinary transition. One function in the codebase can lower exposure, it is named for what it does, and every use of it is greppable. A flag argument gives none of that, and gets passed by accident later.
Units live in identifiers, not comments.
Instants in milliseconds named *Ms; human-authored durations in seconds named *Sec. The failure mode of a unit slip here is silent impatience — a plan advancing a thousand times too early, with no exception and nothing in the log that looks wrong.
Plan, event and flag commit together or not at all.
Across two stores that cannot be one transaction, and the failure modes are asymmetric. Flag written but plan lost means exposure rose with no record of why. Plan written but flag lost means the log says 25% while users see 1%. The second is disqualifying — everything here rests on the log being a faithful record of what happened to exposure.
A refusal and its log entry are built from the same facts.
Enriching only the event leaves an agent holding a bare error code with nothing to act on. And a command that succeeds while changing nothing is where the log works hardest — a refusal explains itself, but a silent success is indistinguishable from a message that never arrived.
People define the boundaries. Agents operate within them. Coldframe verifies, measures and protects.
Coldframe
Progressive delivery for agent-operated software
Hardened off before planting out