{
  "id": "governance-story-workflow",
  "version": "0.1.0",
  "updated": "2026-08-28",
  "note": "How a story moves from a search result to a published page, and who owns each move. Every state names the one role that can advance it and the door it has to get through — the condition that must be true before the next role will take it. A story can only be in one state; the desk records which.",
  "states": [
    { "id": "spotted",    "label": "Spotted",    "owner": "researcher", "seq": 1,
      "means": "A candidate exists. Somebody searched and something came back.",
      "door": "A specific artefact can be named — not a topic, an artefact.",
      "exits": ["registered", "parked"] },
    { "id": "registered", "label": "Registered", "owner": "librarian",  "seq": 2,
      "means": "The source is in the register with a state and a checked date, and the URL resolved.",
      "door": "The fetch returned 200. A blocked or dead URL cannot pass — that is gate check 7.",
      "exits": ["frozen", "parked"] },
    { "id": "frozen",     "label": "Frozen",     "owner": "researcher", "seq": 3,
      "means": "A byte copy is held and hashed, with the retrieval time recorded.",
      "door": "The hash exists and the bytes are stored.",
      "blocked": true,
      "blocked_why": "The fetch-freeze-hash path is not built. Every story is stuck at this door, which is why nothing in the graph is anchored and every fact reads secondary.",
      "exits": ["extracted"] },
    { "id": "extracted",  "label": "Extracted",  "owner": "extractor",  "seq": 4,
      "means": "Typed nodes and edges exist, conforming to the ontology, anchored where a frozen copy allows it.",
      "door": "Every verb is in the vocabulary and every node names its source. Gate checks 1 and 2.",
      "exits": ["drafted", "parked"] },
    { "id": "drafted",    "label": "Drafted",    "owner": "writer",     "seq": 5,
      "means": "Prose exists in markdown, and names the node ids it stands on.",
      "door": "Every sentence traces to a node. Gate check 3.",
      "exits": ["cleared", "refused"] },
    { "id": "cleared",    "label": "Cleared",    "owner": "editor",     "seq": 6,
      "means": "The refusal list has been applied and nothing on it was triggered.",
      "door": "No named organisation is assessed; no severity language that the graph does not compute; no implication of human review.",
      "exits": ["gated", "refused"] },
    { "id": "gated",      "label": "Gated",      "owner": "qa",         "seq": 7,
      "means": "Both gates pass — the section's own checks and the whole-site gate.",
      "door": "Exit zero. A failing gate is answered, never silenced.",
      "exits": ["published"] },
    { "id": "published",  "label": "Published",  "owner": "publisher",  "seq": 8,
      "means": "Live, versioned, and carrying the beta and no-human-review notices.",
      "door": "The version was bumped and the release note says what is still missing.",
      "exits": ["superseded"] },
    { "id": "superseded", "label": "Superseded", "owner": "extractor",  "seq": 9, "terminal": true,
      "means": "A later fact replaced one this story rests on. The story stays up; the superseding edge is added.",
      "door": "Never delete. The original remains readable and the edge points forward.",
      "exits": [] },
    { "id": "parked",     "label": "Parked",     "owner": "librarian",  "seq": 0, "terminal": true,
      "means": "Not dead, not moving. Waiting on something outside this newsroom.",
      "door": "The blocker is named, so a reader can see what would unblock it.",
      "exits": ["spotted"] },
    { "id": "refused",    "label": "Refused",    "owner": "editor",     "seq": 0, "terminal": true,
      "means": "Killed on the refusal list. Recorded rather than quietly dropped.",
      "door": "The refusal that bit is named. Cut, never softened.",
      "exits": [] }
  ],
  "lanes": [
    { "id": "gather",  "label": "Gather",  "states": ["spotted", "registered", "frozen"] },
    { "id": "build",   "label": "Build",   "states": ["extracted", "drafted"] },
    { "id": "clear",   "label": "Clear",   "states": ["cleared", "gated"] },
    { "id": "release", "label": "Release", "states": ["published", "superseded"] },
    { "id": "stopped", "label": "Stopped", "states": ["parked", "refused"] }
  ]
}
