{
  "schemaVersion": "1.0",
  "title": "Epic",
  "nodes": [
    {
      "type": "nav",
      "id": "nav",
      "props": {
        "variant": "bar",
        "title": "Nano Workforce",
        "items": [
          {
            "label": "Overview",
            "page": "overview"
          },
          {
            "label": "Connect over MCP",
            "page": "mcp"
          },
          {
            "label": "Lineage",
            "page": "lineage"
          },
          {
            "label": "Convergence",
            "page": "home"
          },
          {
            "label": "Epics",
            "page": "epic"
          },
          {
            "label": "Feature",
            "page": "feature"
          },
          {
            "label": "Delivery Graphs",
            "page": "delivery-graphs"
          },
          {
            "label": "Tasks",
            "page": "tasks",
            "badge": {
              "source": "app",
              "table": "user_tasks",
              "filter": [],
              "tone": "danger",
              "refreshMs": 5000,
              "hideWhenZero": true
            }
          },
          {
            "label": "Cockpit",
            "page": "cockpit"
          },
          {
            "label": "Board",
            "page": "board"
          },
          {
            "label": "Velocity",
            "page": "velocity"
          }
        ],
        "sticky": true
      }
    },
    {
      "type": "text",
      "id": "title",
      "props": { "text": "Epic {{param}}", "variant": "heading" }
    },
    {
      "type": "text",
      "id": "subtitle",
      "props": {
        "text": "This epic's plan, review trace, wave state, conflict graph, coordination notes, and trial-merge results. Sections start collapsed and remember your choice.",
        "variant": "sub"
      }
    },
    {
      "type": "text",
      "id": "escalations-pointer",
      "props": {
        "text": "Escalations (task, plan-review, trial-merge) are native user tasks — answer them from the Task inbox at /tasks: list the open tasks, pick the one for this epic, and submit the typed decision. There is no separate answer form on this page.",
        "variant": "sub"
      }
    },
    {
      "type": "prose",
      "id": "wave-banner",
      "props": {
        "refreshMs": 5000,
        "measure": 80,
        "empty": "No plan recorded for this epic yet.",
        "data": {
          "kind": "datasource",
          "source": "app",
          "table": "plan_read_model",
          "orderBy": { "field": "updated_at", "dir": "desc" },
          "filter": [{ "field": "plan_key", "eqParam": true }]
        },
        "header": "Wave {{wave_label}} · {{epic_phase}}",
        "body": "delivery_label"
      }
    },
    {
      "type": "dataGrid",
      "id": "wave-summary",
      "props": {
        "title": "Wave progress",
        "rowKey": "wave",
        "refreshMs": 5000,
        "empty": "No waves yet — this epic hasn't been levelized into waves.",
        "data": {
          "kind": "datasource",
          "source": "app",
          "table": "plan_wave_summary",
          "orderBy": { "field": "wave", "dir": "asc" },
          "filter": [{ "field": "plan_key", "eqParam": true }]
        },
        "columns": [
          { "field": "wave", "header": "Wave" },
          { "field": "bar", "header": "Progress", "width": "40%" },
          { "field": "merged", "header": "Merged" },
          { "field": "in_flight", "header": "In flight" },
          { "field": "blocked", "header": "Blocked" },
          { "field": "escalated", "header": "Escalated" },
          { "field": "skipped", "header": "Skipped" },
          { "field": "total", "header": "Total" }
        ]
      }
    },
    {
      "type": "dataGrid",
      "id": "epic-plan",
      "props": {
        "title": "Plan",
        "rowKey": "plan_key",
        "refreshMs": 5000,
        "data": {
          "kind": "datasource",
          "source": "app",
          "table": "plan_read_model",
          "orderBy": { "field": "updated_at", "dir": "desc" },
          "filter": [{ "field": "plan_key", "eqParam": true }]
        },
        "columns": [
          { "field": "title", "template": "{{title}}", "header": "Item", "subtitleField": "plan_key", "truncate": true, "width": "34%", "linkField": "issue_url" },
          { "field": "epic_phase", "header": "Phase" },
          { "field": "status", "header": "Status", "link": { "kind": "processExplorer", "keyField": "process_key" } },
          { "field": "delivery", "header": "Delivery" },
          { "field": "wait_gate_label", "header": "Wait gate" },
          { "field": "promotion_state", "header": "Promotion" },
          { "field": "wave_label", "header": "Wave" },
          { "field": "task_count", "header": "Tasks" },
          { "field": "updated_at", "header": "Updated", "width": "9rem", "format": "datetime" }
        ],
        "detail": {
          "linkField": "issue_url",
          "fields": [
            { "field": "repo", "label": "Repository" },
            { "field": "issue_number", "label": "Issue number" },
            { "field": "base_branch", "label": "Base branch (blank = repo default)" },
            { "field": "delivery_label", "label": "Delivery rollup (slices merged / converging)" },
            { "field": "wait_gate_label", "label": "Inter-epic gate (waiting on / bound version / escalated)" },
            { "field": "bound_artifacts", "label": "Bound producer capabilities (pkg@version)" },
            { "field": "promotion_pr", "label": "Promotion PR (epic/* → default branch)" },
            { "field": "outcome", "label": "Outcome" }
          ]
        }
      }
    },
    {
      "type": "dataGrid",
      "id": "inter-epic-deps",
      "props": {
        "title": "Inter-epic dependencies (waiting on)",
        "rowKey": "depends_on_plan_key",
        "refreshMs": 5000,
        "collapsible": true,
        "defaultCollapsed": true,
        "empty": "No inter-epic dependencies — this is a root epic (it starts immediately, no capability wait-gate).",
        "data": {
          "kind": "datasource",
          "source": "app",
          "table": "plan_deps",
          "orderBy": { "field": "created_at", "dir": "asc" },
          "filter": [{ "field": "plan_key", "eqParam": true }]
        },
        "columns": [
          { "field": "depends_on_plan_key", "header": "Waits on (producer epic)" },
          { "field": "package", "header": "Package" },
          { "field": "capability_ref", "header": "Capability ref" },
          { "field": "created_at", "header": "Recorded", "width": "9rem" }
        ]
      }
    },
    {
      "type": "dataGrid",
      "id": "wave-state",
      "props": {
        "title": "Wave state",
        "rowKey": "id",
        "refreshMs": 5000,
        "collapsible": true,
        "defaultCollapsed": true,
        "groupBy": "wave",
        "groupLabel": "Wave",
        "data": {
          "kind": "datasource",
          "source": "app",
          "table": "plan_wave_tasks",
          "orderBy": { "field": "wave", "dir": "asc" },
          "filter": [
            { "field": "plan_key", "eqParam": true },
            { "field": "status", "in": ["pending", "opened", "escalated", "waiting-for-lane", "blocked"] }
          ]
        },
        "tabs": [
          {
            "label": "Active",
            "filter": [
              { "field": "plan_key", "eqParam": true },
              { "field": "status", "in": ["pending", "opened", "escalated", "waiting-for-lane", "blocked"] }
            ]
          },
          {
            "label": "Skipped",
            "filter": [
              { "field": "plan_key", "eqParam": true },
              { "field": "status", "in": ["skipped"] }
            ]
          },
          {
            "label": "All",
            "filter": [{ "field": "plan_key", "eqParam": true }]
          }
        ],
        "columns": [
          { "field": "wave", "header": "Wave" },
          { "field": "task_id", "header": "Task" },
          { "field": "title", "header": "Title" },
          { "field": "status", "header": "Status", "link": { "kind": "processExplorer", "keyField": "process_key" } },
          { "field": "pr_key", "header": "PR", "linkField": "pr_url" },
          { "field": "summary", "header": "Summary" },
          { "field": "updated_at", "header": "Updated", "format": "datetime" }
        ],
        "detail": {
          "fields": [
            { "field": "open_question", "label": "Open question" },
            { "field": "answer", "label": "Answer" },
            { "field": "draft_pr_key", "label": "Draft PR" },
            { "field": "prompt", "label": "Prompt" }
          ]
        }
      }
    },
    {
      "type": "prose",
      "id": "plan-reviews",
      "props": {
        "title": "Plan review trace",
        "refreshMs": 5000,
        "collapsible": true,
        "defaultCollapsed": true,
        "measure": 80,
        "empty": "No plan reviews recorded yet.",
        "data": {
          "kind": "datasource",
          "source": "app",
          "table": "plan_reviews",
          "orderBy": { "field": "created_at", "dir": "asc" },
          "filter": [{ "field": "plan_key", "eqParam": true }]
        },
        "header": "Round {{round}} · epoch {{epoch}} · approved {{approved}} · {{created_at}}",
        "body": "findings"
      }
    },
    {
      "type": "prose",
      "id": "plan-review-escalations",
      "props": {
        "title": "Plan-review escalations",
        "refreshMs": 5000,
        "collapsible": true,
        "defaultCollapsed": true,
        "measure": 80,
        "empty": "No plan-review escalations.",
        "data": {
          "kind": "datasource",
          "source": "app",
          "table": "plan_review_escalations",
          "orderBy": { "field": "id", "dir": "desc" },
          "filter": [{ "field": "plan_key", "eqParam": true }]
        },
        "header": "Round {{round}} · epoch {{epoch}} · {{status}} · directive {{directive}} · asked {{asked_at}} · answered {{answered_at}} · note {{note}}",
        "body": "findings"
      }
    },
    {
      "type": "dataGrid",
      "id": "merge-exclusions",
      "props": {
        "title": "Conflict graph / who blocks whom",
        "rowKey": "id",
        "refreshMs": 5000,
        "collapsible": true,
        "defaultCollapsed": true,
        "data": {
          "kind": "datasource",
          "source": "app",
          "table": "plan_merge_exclusions",
          "orderBy": { "field": "id", "dir": "asc" },
          "filter": [{ "field": "plan_key", "eqParam": true }]
        },
        "columns": [
          { "field": "task_a", "header": "Task A" },
          { "field": "task_b", "header": "Task B" },
          { "field": "files", "header": "Shared files" },
          { "field": "source", "header": "Source" },
          { "field": "updated_at", "header": "Updated", "format": "datetime" }
        ]
      }
    },
    {
      "type": "prose",
      "id": "coordination-notes",
      "props": {
        "title": "Coordination notes",
        "refreshMs": 5000,
        "collapsible": true,
        "defaultCollapsed": true,
        "measure": 80,
        "empty": "No coordination notes posted yet.",
        "data": {
          "kind": "datasource",
          "source": "app",
          "table": "plan_blackboard",
          "orderBy": { "field": "id", "dir": "asc" },
          "filter": [{ "field": "plan_key", "eqParam": true }]
        },
        "header": "Wave {{wave}} · {{author_task}} · {{kind}} · files {{files}} · {{created_at}}",
        "body": "body"
      }
    },
    {
      "type": "dataGrid",
      "id": "trial-merge-results",
      "props": {
        "title": "Trial-merge results",
        "rowKey": "id",
        "refreshMs": 5000,
        "collapsible": true,
        "defaultCollapsed": true,
        "data": {
          "kind": "datasource",
          "source": "app",
          "table": "plan_trial_merges",
          "orderBy": { "field": "created_at", "dir": "desc" },
          "filter": [
            { "field": "plan_key", "eqParam": true },
            { "field": "result", "in": ["merge-conflict", "suite-failed"] },
            { "field": "resolved", "in": [0] }
          ]
        },
        "tabs": [
          {
            "label": "Needs attention",
            "filter": [
              { "field": "plan_key", "eqParam": true },
              { "field": "result", "in": ["merge-conflict", "suite-failed"] },
              { "field": "resolved", "in": [0] }
            ]
          },
          {
            "label": "Clean",
            "filter": [
              { "field": "plan_key", "eqParam": true },
              { "field": "result", "in": ["clean"] }
            ]
          },
          {
            "label": "All",
            "filter": [{ "field": "plan_key", "eqParam": true }]
          }
        ],
        "columns": [
          { "field": "wave", "header": "Wave" },
          { "field": "result", "header": "Result" },
          { "field": "heads", "header": "Heads" },
          { "field": "conflicts", "header": "Conflicts" },
          { "field": "failing", "header": "Failing" },
          { "field": "summary", "header": "Summary" },
          { "field": "created_at", "header": "Recorded" }
        ]
      }
    }
  ]
}
