Skip to main content
Version: Next

0036: A release is promoted by a person, through five named checks that block only what would ship something wrong

  • Status: Accepted (backfilled 2026-10-06: records a decision already built)
  • Date: 2026-10-06
  • Related: 0011 (Orion lands work on develop; the release is a different decision)

Context​

Orion lands work on develop without a person. Promoting develop to main and publishing a release is different: it is public and hard to take back, and whether to do it is the one decision the branch model reserves for a person. "Thorough verification" means nothing as a gate unless the checks are named, and a gate that refuses for everything trains people to bypass it.

Decision​

Five named checks (internal/promote), each from a real way a release goes wrong. Anything that would publish something wrong blocks; anything merely worth knowing warns:

Check
Every ticket in the version is Donewarns: unfinished tickets roll forward
Every shipped ticket has a release note, and notes and tickets agreeblocks on a Done ticket with no note; warns on the rest
develop is green on the exact commit being promotedblocks
No pull requests are about to land on developblocks
Every commit in the range belongs to a ticketwarns: it fires on real work, and is meant to be looked at, not obeyed

A ceremony, not a decision. orion release ship automates what happens around the person's decision, in a fixed order where each step is a safe place to stop: preflight, promotion pull request, CI, Slack approval, merge, then tag, build and publish. Only the last two cannot be undone, which is why they come last. Every step, including every refusal, is logged.

The watch cannot reach it, structurally rather than by a flag: the only path to shipping is the release command, and orion watch runs work and collect and nothing else. TestWatchHasNoPathToShipping pins it.

The publishing verb must be named. A bare orion release prints usage and exits non-zero; ship publishes, and two more verbs stay reserved and unwired, so a typo lands on usage, not on a public tag.

Consequences​

  • A release is always a person's decision, with the evidence in front of them.
  • Check 5 warns on most real releases; that is intended.
  • --beta cuts a prerelease from develop with no promotion, and never publishes it where stable users upgrade from.

Alternatives rejected​

  • Release from the watch when a milestone completes. An unattended loop must not be able to cut a public release.
  • Block on every check. People learn to bypass a gate that refuses for everything.
  • A CI workflow instead of a command. It would need personal access tokens the operator's own authenticated gh already has.