let d = import "../defaults.ncl" in

d.make_mode String {
  id      = "generate-article",
  trigger = "Produce a blog post draft rooted in one or more ontology nodes (tensions, practices, axioms)",

  preconditions = [
    ".ontology/core.ncl exports without errors",
    ".ontology/personal.ncl has at least one Content item with kind = 'BlogPost and status = 'Idea or 'Draft",
    "Target Content item has at least one entry in linked_nodes",
  ],

  steps = [
    {
      id     = "resolve_nodes",
      action = "Export .ontology/core.ncl and extract the node records referenced by the target Content item's linked_nodes. Include their descriptions and all edges connecting them.",
      cmd    = "nickel export .ontology/core.ncl | from json | get nodes | where { |n| $n.id in $linked_nodes }",
      actor  = 'Agent,
      on_error = { strategy = 'Stop },
    },
    {
      id     = "resolve_edges",
      action = "From the exported edges, find all edges where from or to is in linked_nodes. These reveal the narrative structure: what manifests in what, what tensions exist, what validates what.",
      actor  = 'Agent,
      depends_on = [{ step = "resolve_nodes" }],
      on_error = { strategy = 'Stop },
    },
    {
      id     = "identify_audience",
      action = "Read the target Content item's audience field. Map it to a writing register: Technical=implementation details + code; HiringManager=outcomes + credibility; Community=story + invitation; Academic=rigor + citations.",
      actor  = 'Both,
      depends_on = [{ step = "resolve_nodes" }],
      on_error = { strategy = 'Stop },
    },
    {
      id     = "render_outline",
      action = "Produce a structured outline: opening tension (from node descriptions), concrete examples (from practices/projects linked), resolution or open question (from active tensions in state.ncl). Adapt register to audience.",
      actor  = 'Agent,
      depends_on = [
        { step = "resolve_edges" },
        { step = "identify_audience" },
      ],
      on_error = { strategy = 'Stop },
    },
    {
      id     = "draft",
      action = "Write the full article from the outline. Anchor every claim to a node or edge. Do not introduce content not represented in the ontology without flagging it as an extension.",
      actor  = 'Agent,
      depends_on = [{ step = "render_outline" }],
      on_error = { strategy = 'Stop },
    },
    {
      id     = "review",
      action = "Human reviews draft for accuracy (does it represent the actual tensions?), audience fit (does it land for the target?), and completeness (does it say what needs to be said and stop?).",
      actor  = 'Human,
      depends_on = [{ step = "draft" }],
      on_error = { strategy = 'Stop },
    },
    {
      id     = "update_status",
      action = "Update the Content item status in .ontology/personal.ncl from 'Idea to 'Draft or from 'Draft to 'Review based on outcome of review step.",
      actor  = 'Human,
      depends_on = [{ step = "review" }],
      on_error = { strategy = 'Continue },
    },
  ],

  postconditions = [
    "A blog post draft exists rooted in the specified ontology nodes",
    "The draft does not contradict any invariant node (invariant = true)",
    "Content item status updated in .ontology/personal.ncl",
  ],
}
