# Form: Create or edit an ADR
# Backend: CLI / TUI / Web / Agent
#
# Roundtrip:
#   typedialog nickel-roundtrip \
#     --input  adrs/_template.ncl \
#     --form   reflection/forms/new_adr.ncl \
#     --output adrs/adr-NNN-title.ncl \
#     --ncl-template reflection/templates/adr.ncl.j2
#
# Agent query (get field structure without running a form):
#   nickel export reflection/forms/new_adr.ncl \
#     | get elements \
#     | where type != "section_header" \
#     | where type != "section" \
#     | select name prompt nickel_path required default

{
  name         = "New ADR",
  description  = "Author or edit an Architectural Decision Record. Produces a validated Nickel file at adrs/adr-NNN-title.ncl.",
  display_mode = "complete",

  elements = [

    # ── Identity ─────────────────────────────────────────────────────────────
    { type = "section_header", name = "identity_header",
      title = "ADR Identity", border_top = true, border_bottom = true },

    { type = "text", name = "id",
      prompt   = "ADR identifier",
      required = true,
      help     = "Format: adr-NNN. Run `ls adrs/adr-*.ncl | sort` to find the next number.",
      nickel_path = ["id"] },

    { type = "text", name = "title",
      prompt   = "Title",
      required = true,
      placeholder = "Declarative statement of the decision (not a question)",
      help     = "Should complete the sentence: 'We decided that...'",
      nickel_path = ["title"] },

    { type = "select", name = "status",
      prompt  = "Status",
      default = "Proposed",
      options = [
        { value = "Proposed",   label = "Proposed — draft, not yet authoritative" },
        { value = "Accepted",   label = "Accepted — active, constraints are live" },
        { value = "Superseded", label = "Superseded — replaced by another ADR (keep file)" },
        { value = "Deprecated", label = "Deprecated — abandoned without replacement" },
      ],
      nickel_path = ["status"] },

    { type = "text", name = "date",
      prompt      = "Date (YYYY-MM-DD)",
      default     = "2026-03-09",
      placeholder = "2026-03-09",
      nickel_path = ["date"] },

    # ── Context & Decision ───────────────────────────────────────────────────
    { type = "section_header", name = "context_header",
      title = "Context & Decision", border_top = true, border_bottom = true },

    { type = "editor", name = "context",
      prompt         = "Context",
      required       = true,
      file_extension = "md",
      prefix_text    = "# What situation led to this decision?\n# What forces are at play?\n\n",
      help           = "Describe the situation without yet mentioning the decision.",
      nickel_path    = ["context"] },

    { type = "editor", name = "decision",
      prompt         = "Decision",
      required       = true,
      file_extension = "md",
      prefix_text    = "# State the decision in one or two sentences.\n# Be declarative, not prescriptive.\n\n",
      nickel_path    = ["decision"] },

    # ── Rationale ────────────────────────────────────────────────────────────
    { type = "section_header", name = "rationale_header",
      title = "Rationale", border_top = true, border_bottom = true },

    { type = "editor", name = "rationale",
      prompt         = "Rationale entries (Nickel array)",
      required       = true,
      file_extension = "ncl",
      prefix_text    = "# Each entry: { claim = \"...\", detail = \"...\" }\n# claim: one-line assertion. detail: the supporting argument.\n\n",
      help           = "At least one entry. claim answers 'why'; detail explains the mechanism.",
      nickel_path    = ["rationale"] },

    # ── Constraints ──────────────────────────────────────────────────────────
    { type = "section_header", name = "constraints_header",
      title = "Constraints (active checks)", border_top = true, border_bottom = true },

    { type = "section", name = "constraints_note",
      content = "Every ADR requires at least one Hard constraint with a typed 'check' or legacy 'check_hint'. Prefer typed 'check' variants — they are machine-executable by validate.nu." },

    { type = "editor", name = "constraints",
      prompt         = "Constraints (Nickel array)",
      required       = true,
      file_extension = "ncl",
      prefix_text    = "# Required fields per entry:\n# id       = \"kebab-case-id\",\n# claim    = \"What must be true\",\n# scope    = \"Where this applies\",\n# severity = 'Hard,   # Hard | Soft\n# rationale = \"Why this constraint\",\n#\n# Typed check (preferred — pick one variant):\n# check = 'Grep   { pattern = \"...\", paths = [\"...\"] },\n# check = 'Cargo  { crate = \"...\", forbidden_deps = [\"...\"] },\n# check = 'NuCmd  { cmd = \"...\", expect_exit = 0 },\n# check = 'FileExists { path = \"...\", present = true },\n# check = 'ApiCall { endpoint = \"...\", json_path = \"...\", expected = \"...\" },\n#\n# Legacy (deprecated, still accepted during migration):\n# check_hint = \"executable command\",\n\n",
      help           = "Hard: non-negotiable, blocks a change. Soft: guideline, requires justification to bypass.",
      nickel_path    = ["constraints"] },

    # ── Consequences ─────────────────────────────────────────────────────────
    { type = "section_header", name = "consequences_header",
      title = "Consequences", border_top = true, border_bottom = true },

    { type = "editor", name = "consequences_positive",
      prompt         = "Positive consequences (Nickel array of strings)",
      required       = true,
      file_extension = "ncl",
      prefix_text    = "# [ \"One benefit\", \"Another benefit\" ]\n\n",
      nickel_path    = ["consequences", "positive"] },

    { type = "editor", name = "consequences_negative",
      prompt         = "Negative consequences / trade-offs (Nickel array of strings)",
      required       = true,
      file_extension = "ncl",
      prefix_text    = "# [ \"One trade-off\", \"Another trade-off\" ]\n\n",
      nickel_path    = ["consequences", "negative"] },

    # ── Alternatives ─────────────────────────────────────────────────────────
    { type = "section_header", name = "alternatives_header",
      title = "Alternatives Considered", border_top = true, border_bottom = true },

    { type = "editor", name = "alternatives_considered",
      prompt         = "Alternatives (Nickel array)",
      required       = true,
      file_extension = "ncl",
      prefix_text    = "# Each entry: { option = \"Name\", why_rejected = \"Reason\" }\n\n",
      nickel_path    = ["alternatives_considered"] },

    # ── Ontology check ───────────────────────────────────────────────────────
    { type = "section_header", name = "ontology_header",
      title = "Ontology Check", border_top = true, border_bottom = true },

    { type = "section", name = "ontology_note",
      content = "Run before filling: nickel export .ontology/core.ncl | get nodes | where invariant == true | get id" },

    { type = "text", name = "ontology_decision_string",
      prompt      = "Decision string (one line, imperative)",
      required    = true,
      placeholder = "ontoref provides X — each project does Y independently",
      help        = "Concise restatement of the decision for ontology cross-reference.",
      nickel_path = ["ontology_check", "decision_string"] },

    { type = "multiselect", name = "ontology_invariants_at_risk",
      prompt = "Invariants at risk (select all that apply)",
      help   = "Which core invariants does this decision touch? Query: nickel export .ontology/core.ncl | get nodes | where invariant == true | get id",
      options = [
        { value = "no-runtime-conditioning",   label = "no-runtime-conditioning" },
        { value = "layer-autonomy",            label = "layer-autonomy" },
        { value = "project-sovereignty",       label = "project-sovereignty" },
        { value = "nats-surreal-only-external", label = "nats-surreal-only-external" },
        { value = "pattern-not-enforcer",      label = "pattern-not-enforcer" },
      ],
      nickel_path = ["ontology_check", "invariants_at_risk"] },

    { type = "select", name = "ontology_verdict",
      prompt  = "Verdict",
      default = "Safe",
      options = [
        { value = "Safe",                   label = "Safe — no invariant is at risk" },
        { value = "RequiresJustification",  label = "RequiresJustification — invariant is touched, justification must follow" },
      ],
      nickel_path = ["ontology_check", "verdict"] },

    # ── Related ADRs ─────────────────────────────────────────────────────────
    { type = "section_header", name = "related_header",
      title = "Related & Supersession", border_top = true, border_bottom = true },

    { type = "text", name = "related_adrs",
      prompt      = "Related ADRs (comma-separated, e.g. adr-002,adr-003)",
      required    = false,
      placeholder = "adr-002,adr-003",
      help        = "ADRs that this decision builds on or responds to.",
      nickel_path = ["related_adrs"] },

    { type = "text", name = "supersedes",
      prompt      = "Supersedes (adr-NNN, if this replaces another ADR)",
      required    = false,
      placeholder = "adr-002",
      help        = "If set, also edit the old ADR: set status = Superseded and superseded_by = this id.",
      nickel_path = ["supersedes"] },

    # ── Review ───────────────────────────────────────────────────────────────
    { type = "section_header", name = "review_header",
      title = "Review", border_top = true },

    { type = "section", name = "review_note",
      content = "After saving: nickel typecheck adrs/adr-NNN-title.ncl\nOnly set status = Accepted after human review. Proposed ADRs are not authoritative." },

    { type = "confirm", name = "ready_to_save",
      prompt  = "All fields complete — generate the ADR file?",
      default = true },
  ],
}
