All posts
EngineeringSeptember 18, 2026 · The Ubriot team · 4 min read

Retire the approval when you retire the artifact

Release approvals stay trustworthy when cancelling or superseding an artifact also closes the authority attached to that exact build.

A mobile build passes its checks and receives approval for internal testing. Before submission, a newer build replaces it. The old artifact is marked cancelled, but its green approval remains visible in the release timeline.

That approval is historical evidence. It is no longer authority to move a package. If the interface lets the green state float forward, the replacement artifact can appear closer to release than it has earned.

At Ubriot, we retire the approval when we retire the artifact. An approval belongs to the exact package, destination, evidence, and decision that were reviewed. Cancelling or superseding the package should close that authority without erasing why it was once granted.

Approval is a scoped decision

A useful approval answers a bounded question: may artifact A move to destination B under the evidence currently attached to it? The answer may depend on package identity, signing proof, environment checks, the intended audience, and the rollback plan available at that moment.

Change the artifact and the question changes. Even when the newer build contains one small correction, the reviewer has not approved its digest, package contents, or resulting runtime behavior. The earlier decision can inform the next review, but it cannot silently authorise it.

Destination changes matter too. Approval for an internal testing track does not automatically authorise production. A cancelled production submission does not grant a later beta build permission to reuse its state. The record should keep artifact identity and destination beside every approval so scope remains visible when the timeline gets busy.

artifact: app-241
digest: sha256:example-a
destination: internal-testing
approval: retired
retired-because: artifact superseded
superseded-by: app-242
inherited-evidence: source lint, unchanged module tests
required-next: package inspection, signing proof, destination approval

Retired does not mean deleted

Deleting the old approval would weaken the release history. The team still needs to know that artifact A was reviewed, which evidence supported it, who made the decision, and why it never moved. That sequence can explain a later change, a missed submission window, or the origin of a replacement build.

We prefer an explicit retired state. It preserves the decision as true about its old scope while making it unusable for current movement. The state should include the retirement reason and the event that caused it, such as artifact superseded, destination changed, signing context replaced, or release abandoned.

This is different from expired evidence. A device smoke may become stale because time or configuration moved. A retired approval has lost its active subject. The artifact it authorised is no longer the intended release. Rerunning one check cannot restore the old approval to the new artifact.

Carry evidence forward selectively

Retiring approval does not require throwing away every check. Some deterministic results may still apply to unchanged source or shared inputs. A lint result can remain attached to the commit it checked. A module test may remain useful when the tested code and toolchain are unchanged. Package inspection and signing proof belong more tightly to the produced artifact.

The release record should distinguish inherited evidence from fresh authority. Show which results can support the replacement review, keep their original timestamps and scope, and name the checks reopened by the new artifact. That gives the next operator a narrow honest path instead of either starting blindly from zero or borrowing the whole green state.

If dependency between a result and the replaced artifact is unclear, reopen it. Precision requires traceable inputs. It is safer to repeat a focused check than to let an ambiguous result become accidental approval.

Close every route that could move the old build

A retired approval should affect more than the badge on a release page. Submission jobs, promotion controls, API commands, and queued automations must all reject the old authority. Otherwise the interface tells the truth while a background path can still submit the cancelled artifact.

The system also needs to handle races. An artifact may be superseded while a submission is already starting. The release service should check active approval and artifact identity at the point of movement, not only when the job was queued. If submission has already crossed an external acceptance boundary, the record should stop calling the artifact merely cancelled and begin reconciliation against the store state.

Operators need a clear next action. The replacement release should say which proof can be inherited, which checks must be rerun, who owns the new approval, and whether the old artifact reached any destination before retirement. A vague needs review state hides the very scope the retirement was meant to protect.

We build Ubriot so release decisions stay attached to the artifact that earned them. When a build is cancelled or superseded, preserve its history and close its authority. Retire the approval with the artifact, then let the replacement earn a decision that names its own package, destination, and proof.

Try Ubriot AI

React Native CI/CD from one CLI.

Get started