Skip to content

Spec-delta lifecycle (.kmd deltas applied by requirement id)

kmd specs/kmd/spec-delta.kmd

Formato e ciclo de vida do spec-delta: um `.kmd` revisável que nomeia sua spec canônica (`delta_of:`) e declara mudanças de Requirement em seções `## ADDED/MODIFIED/REMOVED Requirements`. Uma fase de RFC PODE carregar um delta (`spec_delta:` no frontmatter de phases); `koder-spec-audit spec-delta` valida o delta contra a canônica e, no land da fase, aplica mecanicamente — merge por id de requirement (identidade estável da RFC-013), nunca por linha. Propose→apply→archive reusando fases de RFC + backlog + kmd lint, sem ferramenta paralela (internaliza o spec-delta da OpenSpec, ver stack-RFC-013 Gap B).

When this spec applies

All triggers

Specification body

Spec — Spec-delta lifecycle

Document format reference: meta/docs/stack/policies/document-format.kmd

Um spec-delta é a unidade revisável de evolução de uma spec normativa: em vez de editar a canônica in-place, uma fase de RFC carrega um delta que o auditor valida e aplica por id de requirement (a identidade estável de requirement-scenario.kmd). O delta é proposta enquanto a fase está pending/in-progress e é aplicado+arquivado no land (commit registrado em landed_in, como rfc-frontmatter/phases.kmd já manda).

1. Forma

Um delta é um .kmd com:

  • delta_of: no frontmatter — path repo-relativo da spec canônica;
  • até três seções H2, cada uma contendo blocos ### Requirement: completos (gramática de requirement-scenario.kmd, Scenarios inclusos):
    • ## ADDED Requirements — blocos novos (id NÃO pode existir na canônica);
    • ## MODIFIED Requirements — substituem o bloco homônimo da canônica (id DEVE existir lá); o bloco do delta é o estado-alvo completo;
    • ## REMOVED Requirements — só o heading (com {#anchor}) basta; id DEVE existir na canônica.

A fase de RFC que transporta o delta declara spec_delta: <path-do-delta> (campo de rfc-frontmatter/phases.kmd); rfc-phase-pickup --validate cobre a boa-formação do delta junto com a validação das fases.

2. Regras

Requirement: A delta names its canonical and is consistent with it {#req-delta-consistency}

A spec-delta document SHALL declare delta_of: and SHALL be consistent with the canonical document it names: every MODIFIED or REMOVED requirement id exists there, every ADDED id does not, and no id appears in two sections. koder-spec-audit spec-delta enforces this before any apply.

Scenario: Added requirement already exists

  • GIVEN a delta whose ADDED section declares {#req-x}
  • WHEN the canonical spec already contains {#req-x}
  • THEN the audit emits error delta-added-exists

Scenario: Modified requirement is missing

  • GIVEN a delta whose MODIFIED section declares {#req-y}
  • WHEN the canonical spec has no {#req-y}
  • THEN the audit emits error delta-modified-missing

Scenario: One id, one disposition

  • GIVEN a delta declaring the same requirement id in two sections
  • WHEN the delta is validated
  • THEN the audit emits error delta-dup-slug

Requirement: Apply merges by requirement id, never by line {#req-delta-apply}

On phase land the delta SHALL be applied mechanically to the canonical .kmd: MODIFIED replaces the block span located by id at apply time, REMOVED deletes it, ADDED appends. The resulting document SHALL pass kmd lint. Apply SHALL refuse any unresolvable id (no partial merges).

Scenario: Disjoint deltas are multi-session safe

  • GIVEN two deltas against the same canonical spec touching disjoint requirement ids
  • WHEN they are applied in either order
  • THEN both applies succeed
  • AND the merged document carries the same set of requirements either way

Scenario: Apply refuses an unresolvable id

  • GIVEN a delta whose MODIFIED id is absent from the canonical (e.g. a concurrent session removed it)
  • WHEN apply runs
  • THEN no write happens
  • AND the failure names the unresolvable id

3. Ciclo de vida

  1. Propose — autor escreve o delta (path sugerido: meta/docs/stack/rfcs/deltas/<rfc-slug>-phase<N>-<spec-slug>.kmd) e aponta a fase: spec_delta: <path>. Validação contínua via rfc-phase-pickup --validate e spec-delta (sem flag = varre as fases).
  2. Apply — no land da fase: koder-spec-audit spec-delta --delta <path> --apply → canônica regravada por merge-por-id → kmd lint na canônica → delta + canônica no MESMO commit, registrado em landed_in.
  3. Archive — a fase flipa done; o delta permanece no repo como registro histórico revisável (não é deletado — é o porquê do diff).

References