Skip to content

0021 โ€” A merge never ships an earlier held edit

Generated copy

Generated by scripts/gen_docs.py from docs/adr/0021-stacked-edits-never-ship-held-work.md. Do not edit it by hand: change the source, then run uv run python scripts/gen_docs.py.

Status: accepted Date: 2026-10-15 Owner: Core

Context

Edits accumulate on candidate. A WARN leaves its commit there, held. Merging a later edit fast-forwards main over every commit between them, so approving or auto-merging edit N would deploy a held edit N-1 that never got a passing verdict.

Decision

Before any merge (automatic PASS or manual Approve), Ratchet lists the commits between main and the edit. If one of them belongs to another edit that is held or still being judged, it does not merge. An automatic PASS becomes WARN stacked_on_held ("Held: an earlier held edit is still waiting on candidate. Review before merging."). A manual Approve answers 409 stacked_on_held. Edits that were rolled back don't block: their revert commit cancels them out.

Consequences

Held edits must be resolved in order, oldest first, which is the order a reviewer reads them. main only ever holds edits that individually passed or were approved.

Reversal trigger

Operators routinely want to ship a later edit while an earlier one waits. That would call for cherry-picking candidate commits onto main instead of fast-forwarding.