RFC-0001: Lifecycle State Machines
Version: 0.7.0 | Status: normative | Phase: stable Owners: @govctl-org Tags:
core,lifecycle
1. Summary
[RFC-0001:C-SUMMARY] Summary (Informative)
This RFC defines state machines governing RFC, ADR, Work Item, and Clause lifecycles, including the additional transition gates that control when work may be treated as complete.
Tags:
lifecycle
Since: v0.1.0
2. Specification
[RFC-0001:C-RFC-STATUS] RFC Status Transitions (Normative)
An RFC MUST have exactly one of the following status values:
- draft — Initial state. The RFC is under development and not yet binding.
- normative — The RFC defines required behavior. Implementations MUST conform. Normative RFCs MAY be amended via version bumping; amendments MUST include a changelog entry documenting the change.
- deprecated — The RFC is no longer recommended. Existing conforming implementations MAY continue, but new implementations SHOULD NOT use this RFC.
Valid transitions:
- draft → normative (via
finalizecommand) - normative → deprecated (via
deprecatecommand)
Invalid transitions (MUST be rejected):
- normative → draft (no “un-finalize”)
- deprecated → normative (no resurrection)
- deprecated → draft (no resurrection)
- Any skip (e.g., draft → deprecated directly)
Tags:
lifecycle
Since: v0.1.0
[RFC-0001:C-RFC-PHASE] RFC Phase Transitions (Normative)
An RFC MUST have exactly one of the following phase values. The phase describes conformance work for the RFC’s current version:
- spec - Specification phase. The current version candidate is being written. Implementation work against that candidate is not permitted.
- impl - Implementation phase. Code is being written to conform to the sealed current version.
- test - Testing phase. Implementation is complete; tests are being written and validated against the sealed current version.
- stable - Stable phase. Implementation and tests for the sealed current version are complete.
Within one RFC version, valid transitions are forward only via the advance command:
- spec -> impl
- impl -> test
- test -> stable
Within one RFC version, the following transitions MUST be rejected:
- Any backward transition (for example, impl -> spec)
- Any skip (for example, spec -> test or spec -> stable)
- stable -> any (
stableis terminal for that version)
A version bump that releases a detected RFC or clause content amendment MUST start the new RFC version in spec, regardless of the prior version’s phase. This starts a new version lifecycle and is not a backward transition within one version. Version-changing bump eligibility MUST follow RFC-0000:C-PHASE-LIFECYCLE.
Only a normative RFC MAY advance from spec to impl. A normative RFC’s current spec content is an authoring candidate rather than an implementation conformance baseline. The most recently sealed version remains the implementation baseline until the current candidate enters impl.
RFC and clause content MAY change while the current version remains in spec. Such changes belong to the current version. Such changes MUST NOT require another version bump. Advancing from spec to impl MUST set or replace the current version’s stored signature with the current amendment content. The transition MUST reject every pending clause defined by RFC-0000:C-CLAUSE-DEF.
After the current version enters impl, amendment content that differs from the stored signature MUST be treated as an unversioned amendment. Phase progression MUST reject that amendment until a version bump releases it and starts the next version in spec.
Changelog-only updates MUST preserve the current phase. Changelog-only updates MUST preserve the current signature. Establishing or replacing the signature while sealing a spec version MUST preserve the selected RFC version.
Amendment content and bookkeeping fields are defined by RFC-0000:C-PHASE-LIFECYCLE.
Rationale:
Scoping phase to the current RFC version preserves ordered specification, implementation, and testing gates while allowing the RFC itself to evolve through versioned amendments. Treating spec as the current version’s mutable authoring boundary avoids version inflation, while sealing at impl gives implementation a precise contract.
Tags:
lifecycle
Since: v0.1.0
[RFC-0001:C-WORK-STATUS] Work Item Status Transitions (Normative)
A Work Item MUST have exactly one of the following status values:
- queue — Initial state. The work item is defined but not yet started.
- active — The work item is currently being worked on.
- done — The work item is complete and eligible for release. All acceptance criteria are satisfied, and any required verification guards have passed or been explicitly waived.
- cancelled — The work item was abandoned. No further work will be done.
Valid transitions via the move command are:
- queue → active (start work)
- queue → cancelled (abandon before starting)
- active → done (complete work)
- active → cancelled (abandon in progress)
- done → active when no release references the Work Item (correct a pre-release completion)
The following transitions MUST be rejected:
- done → active when any release references the Work Item
- done → queue or cancelled
- cancelled → any (
cancelledis terminal) - queue → done (cannot complete without being active)
- active → queue (no “un-start”)
Release membership is derived from releases[].refs; it does not add another Work Item status. A released Work Item MUST remain done.
Timestamp behavior:
- queue → active: Sets
startedif it is not already set - active → done: Sets
completed - active → cancelled: Sets
completed - done → active: Preserves
startedand removescompleted
Returning a Work Item to done after reopening MUST apply the same acceptance-criteria and verification-guard gates as any other active → done transition.
Reopening a Work Item MUST NOT mutate existing loop state or round artifacts. Existing loop-local done, failed, and cancelled outcomes remain terminal according to RFC-0006:C-WORK-ITEM-INTERACTION, RFC-0006:C-LOOP-RESUMPTION, and RFC-0006:C-LOOP-SCOPE-MUTATION. A reopened Work Item can be executed through a new loop or explicit non-terminal loop scope according to those clauses.
Rationale:
Completion remains correctable until release membership freezes the lifecycle record. Clearing completed on reopening keeps status and timestamp semantics consistent, while release membership prevents the same Work Item ID from re-entering later release collection. Keeping loop outcomes separate preserves existing execution audit history.
Tags:
lifecycle
Since: v0.1.0
[RFC-0001:C-ADR-STATUS] ADR Status Transitions (Normative)
An ADR MUST have exactly one of the following status values:
- proposed — Initial state. The decision is under consideration.
- accepted — The decision has been accepted and is in effect.
- rejected — The decision was considered and explicitly declined.
- superseded — The decision has been replaced by another ADR.
Valid transitions:
- proposed → accepted (via
acceptcommand) - proposed → rejected (via
rejectcommand) - accepted → superseded (via
supersedecommand, requires--byto specify replacement)
Invalid transitions (MUST be rejected):
- proposed → superseded (cannot supersede without first accepting)
- accepted → proposed (no “un-accept”)
- accepted → rejected (accepted decisions must be superseded, not retroactively rejected)
- rejected → any (rejected is terminal)
- superseded → any (superseded is terminal)
When an ADR is superseded:
- The
superseded_byfield MUST be set to the ID of the replacing ADR - The replacing ADR SHOULD reference the superseded ADR
When an ADR is rejected:
- The ADR MUST remain available as historical record
- The
superseded_byfield MUST NOT be set
Tags:
lifecycle
Since: v0.1.0
[RFC-0001:C-CLAUSE-STATUS] Clause Status Transitions (Normative)
A Clause MUST have exactly one of the following status values:
- active — Default state. The clause is in effect.
- deprecated — The clause is no longer recommended but still valid.
- superseded — The clause has been replaced by another clause.
Valid transitions:
- active → deprecated (via
deprecatecommand) - active → superseded (via
supersedecommand, requires replacement clause) - deprecated → superseded (already deprecated, now replaced)
Invalid transitions (MUST be rejected):
- deprecated → active (no resurrection)
- superseded → any (superseded is terminal)
A clause supersession transition has the following preconditions:
- The replacing clause MUST exist.
- The replacing clause MUST be active when the transition is performed.
- The replacing clause MUST be different from the clause being superseded.
- A replacing clause in another RFC MUST be identified by its qualified
RFC-NNNN:C-NAMEID.
The transition MUST be rejected if any required precondition is not satisfied.
After a successful clause supersession transition:
- The source clause status MUST be
superseded. - The source clause
superseded_byfield MUST identify the direct replacing clause selected for that transition. - The replacing clause SHOULD have a
sincefield indicating the version it was introduced.
Every populated superseded_by field defines a directed edge from its source clause to its target clause. The clause supersession graph consists of these edges across every RFC in the governed project.
Repository validation MUST reject an edge whose target clause does not exist. Repository validation MUST NOT reject an existing edge solely because its target clause was later deprecated or superseded.
If clause A identifies clause B as its direct replacement and B is later replaced by clause C, B MUST identify C as its direct replacement. Clause A MUST continue to identify B. The clause supersession graph MUST NOT contain a cycle. Repository validation MUST reject a graph that contains a cycle.
Rationale:
Transition-time checks ensure that a newly selected replacement is in effect. Persisted edges record historical direct replacements, so later clause evolution does not invalidate or erase prior provenance. Qualified IDs allow the same model to represent unambiguous replacements across RFC boundaries.
Tags:
lifecycle
Since: v0.1.0
[RFC-0001:C-GATE-CONDITIONS] Transition Gate Conditions (Normative)
Certain transitions have additional gate conditions beyond the state machine rules.
Work Item -> done:
- The work item MUST have at least one acceptance criterion defined.
- All acceptance criteria MUST have status
doneorcancelled. - Every guard named in the work item’s
verification.required_guardsMUST pass or be explicitly waived with a reason. - If project verification is enabled, every project-level default guard MUST also pass or be explicitly waived with a reason.
The effective required verification guards are the union of the work item’s verification.required_guards and, only when project verification is enabled, the project’s configured default guards. Only guards covered by explicit waivers are removed from that set.
Rationale: Prevents marking work as complete without defined success criteria or executable completion proof.
RFC draft -> normative:
- No additional gates (policy decision, not structural).
RFC phase spec -> impl:
- RFC status MUST be normative.
- Every clause MUST have a resolved
sinceversion under RFC-0000:C-CLAUSE-DEF.
Rationale: Implementation must follow a ratified and version-resolved specification.
RFC phase impl -> test:
- No additional gates.
RFC phase test -> stable:
- No additional gates (assumes tests are passing externally).
Future gates MAY be added via RFC amendment, but MUST NOT break existing valid workflows. Project verification MUST default to disabled when the project config does not opt into it.
Tags:
lifecycle,validation
Since: v0.1.0
Changelog
v0.7.0 (2026-07-20)
Clarify RFC candidate phase transitions
Changed
- Bind version bumps and signature sealing to explicit phase boundaries
v0.6.0 (2026-07-16)
Align RFC phase gates with current-version sealing
Changed
- Required normative status and resolved Clause versions before implementation entry
v0.5.0 (2026-07-15)
Scope terminal states to versions and releases
Changed
- Restart phase progression for amended RFC versions
- Allow unreleased done Work Items to return to active
v0.4.2 (2026-06-28)
Split direct-edge preservation requirements
Changed
- Express B-to-C insertion and A-to-B preservation as separate testable obligations
v0.4.1 (2026-06-28)
Clarify clause supersession validation boundaries
Added
- Define project-wide direct-edge graph semantics and explicit rejection behavior for missing targets and cycles
Changed
- Separate transition-time replacement checks from persisted graph validation
- Document the distinct-target rule and preserve historical edges after target status changes
v0.4.0 (2026-06-28)
Define direct clause supersession chains
Added
- Require active transition targets, qualified cross-RFC references, and acyclic supersession graphs
Changed
- Treat superseded_by as a persistent direct replacement edge
v0.3.0 (2026-03-17)
Add executable verification gates to work completion
Added
- Added required verification guard gate conditions for work completion
v0.2.1 (2026-01-26)
Remove ADR reference from C-RFC-STATUS; RFCs are self-contained and should not reference ADRs
Added
- Inline amendment rule in C-RFC-STATUS clause (was referencing ADR-0016)
v0.2.0 (2026-01-19)
Clarify that normative RFCs may be amended via version bumping
v0.1.0 (2026-01-17)
Initial draft