ontoref/reflection/forms/supersede_adr.ncl

122 lines
6.4 KiB
Plaintext
Raw Normal View History

2026-03-13 00:21:04 +00:00
# Form: Supersede an existing ADR
# Manages the ADR lifecycle: Accepted → Superseded, with bidirectional linking.
#
# This form drives two file edits:
# 1. Old ADR: status = Superseded, superseded_by = new_adr_id
# 2. New ADR: must have supersedes = old_adr_id (verified post-form)
#
# Usage:
# typedialog form reflection/forms/supersede_adr.ncl \
# --ncl-template reflection/templates/supersede_adr.nu.j2 \
# --output scripts/supersede-{old_adr_id}.nu
#
# Agent query:
# nickel export reflection/forms/supersede_adr.ncl \
# | get elements \
# | where type != "section_header" \
# | where type != "section" \
# | select name prompt required
{
name = "Supersede ADR",
description = "Mark an existing Accepted ADR as superseded and link it to the replacing ADR. Preserves the historical record — files are never deleted.",
elements = [
{ type = "section_header", name = "context_header",
title = "Current ADR landscape", border_top = true, border_bottom = true },
{ type = "section", name = "list_cmd",
content = "Run first to see the active ADR set:\n ls adrs/adr-*.ncl | each { |f| nickel export $f } | select id title status date | sort-by id" },
# ── Old ADR (being superseded) ────────────────────────────────────────────
{ type = "section_header", name = "old_header",
title = "ADR being superseded", border_top = true, border_bottom = true },
{ type = "text", name = "old_adr_id",
prompt = "ADR to supersede (e.g. adr-002)",
required = true,
placeholder = "adr-002",
help = "Must be in Accepted status. Run the command above to verify." },
{ type = "text", name = "old_adr_file",
prompt = "Path to that ADR file",
required = true,
placeholder = "adrs/adr-002-library-not-runtime.ncl",
help = "The file that will have status changed to Superseded." },
# ── New ADR (the replacement) ─────────────────────────────────────────────
{ type = "section_header", name = "new_header",
title = "Replacing ADR", border_top = true, border_bottom = true },
{ type = "text", name = "new_adr_id",
prompt = "New ADR identifier (e.g. adr-007)",
required = true,
placeholder = "adr-007",
help = "The ADR that supersedes the old one. Must already exist or be created before running this form." },
{ type = "text", name = "new_adr_file",
prompt = "Path to the new ADR file",
required = true,
placeholder = "adrs/adr-007-updated-library-model.ncl",
help = "Must contain supersedes = \"old_adr_id\" and export cleanly." },
{ type = "confirm", name = "new_adr_exports",
prompt = "Confirmed: new ADR exports cleanly with `nickel export {new_adr_file}`",
required = true,
help = "Do not proceed until the new ADR typechecks. Status will not be set to Accepted here — do that manually after review." },
{ type = "confirm", name = "new_has_supersedes_field",
prompt = "Confirmed: new ADR has `supersedes = \"{old_adr_id}\"` in its body",
required = true,
help = "Required for bidirectional chain integrity. Without this, point-in-time queries break." },
# ── Reason ───────────────────────────────────────────────────────────────
{ type = "section_header", name = "reason_header",
title = "Supersession reason", border_top = true, border_bottom = true },
{ type = "select", name = "supersession_reason",
prompt = "Why is this ADR being superseded?",
required = true,
options = [
{ value = "architectural_evolution", label = "Architectural evolution — the decision changed" },
{ value = "constraint_update", label = "Constraint update — same decision, different constraints" },
{ value = "scope_change", label = "Scope change — decision now covers more/less" },
{ value = "correction", label = "Correction — previous ADR had an error" },
] },
{ type = "text", name = "supersession_note",
prompt = "One-line note for the git commit message",
required = true,
placeholder = "adr-002 superseded by adr-007: library model extended to cover schema exports" },
# ── Impact ───────────────────────────────────────────────────────────────
{ type = "section_header", name = "impact_header",
title = "Constraint impact", border_top = true, border_bottom = true },
{ type = "section", name = "impact_cmd",
content = "Check what the old ADR's Hard constraints covered:\n nickel export {old_adr_file} | get constraints | where severity == 'Hard | select id claim check_hint" },
{ type = "confirm", name = "constraints_reviewed",
prompt = "Confirmed: old ADR's Hard constraints have been reviewed and are covered by the new ADR",
required = true,
help = "The new ADR must re-state or explicitly drop any Hard constraint from the old ADR. No silent constraint removal." },
{ type = "confirm", name = "references_updated",
prompt = "Confirmed: no other file references the old ADR as if it were still active",
required = false,
help = "Run: grep -r \"{old_adr_id}\" adrs/ reflection/ .ontology/ .claude/ — review each match." },
# ── Execute ──────────────────────────────────────────────────────────────
{ type = "section_header", name = "execute_header",
title = "Generate patch script", border_top = true },
{ type = "section", name = "execute_note",
content = "The generated script will:\n 1. Edit {old_adr_file}: set status = Superseded, add superseded_by = \"{new_adr_id}\"\n 2. Verify both ADRs export cleanly\n 3. Print the git commit command to run" },
{ type = "confirm", name = "ready_to_generate",
prompt = "Generate the supersession script?",
default = true },
],
}