RFC frontmatter — `phases:` array

rfc-frontmatter specs/rfc-frontmatter/phases.kmd

Convention for declaring multi-phase migration plans in RFC frontmatter so that `koder-spec-audit rfc-phase-pickup` can open backlog tickets automatically when each phase becomes eligible. Defined by `policies-RFC-003-rfc-phase-pickup.md`; this spec is the normative schema reference for the field.

Corpo da especificação

Spec — RFC frontmatter phases: array

Normative schema for the phases: field that RFCs with multi-phase migration plans MUST declare in their YAML frontmatter. This spec is the contract between RFC authors and the koder-spec-audit rfc-phase-pickup binary (per policies-RFC-003-rfc-phase-pickup.md).

1. Where the field lives

RFCs in meta/docs/stack/rfcs/*.md carry two parallel sources of metadata:

  • Markdown table at the top of the body — for human display (Status, Author(s), Date, Affects, Depends on).
  • YAML frontmatter at the very top of the file — for tooling.

The phases: field lives in the YAML frontmatter. The markdown table may continue to display a summarised "Migration plan" reference, but the structured data the audit reads is YAML.

---
title: "Reuse-First policy hierarchy"
status: Accepted
date: 2026-05-02
phases:
  - id: 1
    summary: "Extract reuse-first meta-policy from sdk-first.kmd"
    status: done
    landed_in: 7a3a62db0
  - id: 2
    summary: "Author the four categorical sub-policies"
    status: done
    landed_in: 9c73390a0
    depends_on: [1]
  - id: 3
    summary: "Sweep references in CLAUDE.md, commands, sibling policies, koder_kit RFC"
    status: done
    landed_in: 05da91e38
    depends_on: [2]
  - id: 4
    summary: "Substantive behavioural audit hooks per sub-policy"
    status: pending
    depends_on: [3]
    target_backlog: "engines/sdk/koder_kit"
  - id: 5
    summary: "Decommission sdk-first.kmd redirect stub"
    status: pending
    depends_on: [4]
    target_date: "2026-08"
---

# RFC — …

| Field      | Value                |
|------------|----------------------|
| Status     | **Accepted** (…)     |
…

2. Schema

The field is an array of phase objects. Each phase object has:

Field Type Required Notes
id integer yes Sequential within the RFC. Gaps allowed if a phase was cancelled in a previous edit; gap raises an audit warning, not a failure.
summary string (one line) yes Concrete enough that a backlog reader knows what to do without reopening the RFC.
status enum yes One of pending, in-progress, done, cancelled.
landed_in string (commit hash) optional Populated when status flips to done. Audit warns if done without landed_in.
depends_on array of integers optional Phase IDs that must be done before this phase becomes eligible. Defaults to [N-1] if not declared.
target_backlog string (path) optional Override path for where the auto-opened ticket should land. Defaults inferred from RFC slug (see §4).
target_date string (YYYY-MM or full ISO) optional Soft trigger — the audit holds the ticket until that date even if dependencies are done.
cancelled_reason string optional Required when status: cancelled. One-line justification, typically pointing at the superseding RFC or design change.

3. Status semantics

Value Meaning Triggers
pending Not started; waiting on its dependencies koder-spec-audit rfc-phase-pickup considers this phase for ticket opening once dependencies clear
in-progress Ticket has been opened and someone is working on it Audit suppresses re-opening; status flip is manual when a maintainer picks the ticket up
done PR landed; landed_in populated Audit treats this phase as a satisfied dependency for descendants
cancelled Phase was abandoned or superseded; cancelled_reason populated Audit treats it as resolved (not blocking descendants), but does not generate a ticket

State transitions are linear: pending → in-progress → done. Going from in-progress back to pending is allowed (ticket re-queued); going to cancelled is allowed from any non-done state.

4. Default target_backlog resolution

When target_backlog is not declared, the audit resolves it in this order:

  1. RFC slug starts with monorepo-RFC-meta/backlog/pending/.
  2. RFC slug starts with policies-RFC-meta/backlog/pending/.
  3. RFC slug matches <area>-RFC- for an existing area → <area>/backlog/pending/ if it exists.
  4. Fallback → meta/backlog/pending/.

The author may override at any time by declaring target_backlog explicitly on a per-phase basis.

5. Mandatoriness

  • New RFCs accepted on or after 2026-05-02 (RFC-003 acceptance date) MUST declare phases: when their migration plan has more than one phase. Single-phase RFCs MAY declare phases: with one entry (recommended for symmetry) or omit the field.
  • Existing RFCs are NOT required to retroactively declare phases:. Retrofit is opportunistic — when an existing RFC is amended for any reason, or when one of its phases is suspected to be drifting.
  • Sticky retrofit: when retrofitting, declare ALL phases (past and future). Past phases get status: done + landed_in: <hash>; future phases get status: pending.

6. Validation rules (enforced by audit)

The koder-spec-audit rfc-phase-pickup --validate sub-command enforces:

  1. The field, if present, is a YAML list of objects.
  2. id is a positive integer; values are unique within the RFC.
  3. id sequence is monotonically increasing; gaps trigger a warning ("phase 3 missing — was it cancelled?").
  4. status is in the enum.
  5. depends_on references exist (every cited ID is also declared); cycles are forbidden.
  6. cancelled requires cancelled_reason.
  7. done without landed_in triggers a warning (not failure).
phases:
  - id: 1
    summary: "Single phase placeholder"
    status: pending

8. Example: full retrofit (sticky, past phases marked done)

phases:
  - id: 1
    summary: "Extract meta-policy"
    status: done
    landed_in: 7a3a62db0
  - id: 2
    summary: "Author sub-policies"
    status: done
    landed_in: 9c73390a0
    depends_on: [1]
  - id: 3
    summary: "Reference sweep"
    status: done
    landed_in: 05da91e38
    depends_on: [2]
  - id: 4
    summary: "Substantive audit hooks"
    status: pending
    depends_on: [3]
  - id: 5
    summary: "Decommission stub"
    status: pending
    depends_on: [4]
    target_date: "2026-08"

9. Anti-patterns

  • Declaring phases: and leaving every phase as pending forever. The audit warns when an RFC has been Status: Accepted for > 90 days with all phases still pending.
  • Updating summary of a done phase. Once a phase has landed_in, its summary is frozen — it is now history. Edit the summary of a pending phase freely.
  • Using phases: to track non-RFC work. This field is RFC-specific. Generic backlog progress tracking belongs in tickets directly.

10. Relationship to other specs and policies

  • Defined by policies-RFC-003-rfc-phase-pickup.md.
  • Consumed by koder-spec-audit rfc-phase-pickup (see RFC-003 §3.2).
  • Backlog ticket scaffolding follows policies/backlog.kmd numbering.
  • Companion to RFC frontmatter conventions (Status, Author(s), Date, Affects, Depends on) — those remain markdown table for display.

Referências