ADR-0054: Bind RFC version bumps to sealed-version amendments
Status: accepted | Date: 2026-07-20
References: ADR-0016, ADR-0051, RFC-0000:C-STATUS-LIFECYCLE, RFC-0000:C-PHASE-LIFECYCLE, RFC-0000:C-CLAUSE-DEF, RFC-0001:C-RFC-PHASE, RFC-0002:C-CRUD-VERBS, RFC-0002:C-LIFECYCLE-VERBS
Context
Before this decision, the RFC lifecycle treated spec as an open authoring candidate and assigned new Clauses to that current version, while version-changing bump validation still permitted another bump from spec when candidate content differed from the stored signature. The abandoned candidate then remained in changelog history, and Clauses first created there retained its version in since even if no implementation baseline was ever sealed.
The pre-amendment deletion rules also prohibited Clause deletion from every normative RFC regardless of phase. A Clause created accidentally in an open spec candidate therefore could not be removed, which encouraged artificial deprecation or supersession records solely to correct authoring mistakes.
The lifecycle needed one unambiguous version boundary without making since directly editable or adding persistent candidate-version state.
Decision
We will refine ADR-0016 and ADR-0051 by treating spec as the single open authoring candidate for the RFC’s current version. Normal version-changing bumps open a new lifecycle only from a version that has already entered impl, test, or stable and has a sealed amendment signature. Entry from spec to impl establishes that signature; a missing signature in a later phase is rejected as an untrustworthy baseline rather than inferred by bumping.
A Clause first introduced in the open current candidate may be removed before sealing when no other artifact references it. Clauses inherited from an earlier version continue to use deprecation or supersession so established history remains intact. Direct since editing and automatic rewriting across ordinary bumps remain outside the model.
This option was selected because:
- The existing
phase, RFCversion, and Clausesincefields identify the open candidate without another persistent state model. - One bump boundary per version prevents unsealed intermediate candidates from appearing as compatibility history.
- Candidate-only deletion corrects authoring mistakes without weakening the history of Clauses inherited from sealed versions.
If changing an open candidate’s semantic-version level becomes a recurring need, it will be considered separately rather than overloading bump semantics now.
Consequences
Positive
- Each version has one authoring interval and one implementation baseline.
- Clause
sincevalues cannot become stranded on an abandoned intermediate candidate through normal lifecycle commands. - Accidental current-candidate Clauses can be removed without creating false deprecation or supersession history.
- Existing status, phase, version, signature, changelog, and Clause metadata remain sufficient.
Negative
- A user cannot issue another version-changing bump while an RFC is already in
spec. Candidate scope must remain within the selected compatibility level; incompatible additions can be deferred to the next version. - A semantic-version level chosen too early cannot be changed through ordinary lifecycle commands. An unpublished candidate can be corrected in version control before it becomes shared history.
- Clause deletion must distinguish candidate-only Clauses from inherited Clauses. The existing
phase == specandsince == current versioncondition provides that boundary and requires focused regression coverage. - A normative RFC missing its sealed signature after
speccannot bump or advance. The repository must restore that baseline through its migration or version-control history rather than guessing it from possibly amended content.
Neutral
- Changelog-only correction remains independent of the version lifecycle.
sinceremains lifecycle-owned and unavailable through generic editing.
Alternatives Considered
Keep spec-phase rebumping and record abandoned candidates as historical versions (rejected)
- Pros: Requires no command or storage changes
- Cons: Leaves unsealed candidates indistinguishable from implemented version history, Encourages artificial Clause supersession to repair authoring attribution
- Rejected because: Unsealed candidates are authoring state, not useful compatibility history, and synthetic supersession records misrepresent requirement evolution
Treat spec as one open candidate and permit removal of Clauses introduced only in that candidate (accepted)
- Pros: Uses the existing phase and since fields, Keeps one bump boundary per version lifecycle
- Cons: Version level cannot be changed in place after the candidate is opened
Add explicit candidate retargeting or next-version state (rejected)
- Pros: Allows an open candidate version level to change without abandoned versions
- Cons: Adds lifecycle commands and metadata for an uncommon correction, Weakens the simple meaning of lifecycle-owned version fields
- Rejected because: The additional state and command surface is disproportionate when candidate scope can be completed before selecting the next version