{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "https://example.com/pipeline/plan-todos.schema.json",
  "title": "Plan Todo List",
  "description": "Structured representation of Phase 2's plan. Persists into agent-state under `.plan.todos[]` and survives across phases. Phase 3 (Dev) iterates step-by-step; Phase 4 (Review) verifies completed steps against criteria; Phase 7 (Report) renders a per-step rollup. The plan is broken into a live, structured Todo list for step-by-step tracking across phases.",
  "type": "object",
  "additionalProperties": false,
  "required": ["title", "todos"],
  "properties": {
    "title": {
      "type": "string",
      "description": "One-line plan summary, mirrors the task title. Surfaced in Phase 3 progress lines and Phase 7 report."
    },
    "createdAt": {
      "type": "string",
      "format": "date-time",
      "description": "ISO-8601 timestamp Phase 2 emitted this plan. Used by Phase 7 for elapsed-time math."
    },
    "todos": {
      "type": "array",
      "minItems": 1,
      "description": "Ordered list of steps. Phase 3 picks them in `deps`-respecting order  -  see plan-todos.sh next.",
      "items": {
        "type": "object",
        "additionalProperties": false,
        "required": ["id", "task", "status"],
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^t[0-9]+$",
            "description": "Stable identifier (t1, t2, ...). Used in dependency edges + progress lines."
          },
          "task": {
            "type": "string",
            "description": "Imperative one-liner  -  what gets done. Avoid 'investigate X' or 'consider Y'  -  Phase 3 needs concrete actions."
          },
          "status": {
            "type": "string",
            "enum": ["pending", "in_progress", "completed", "skipped", "failed"],
            "description": "Lifecycle. pending → in_progress → completed | failed | skipped. The helper script enforces transitions; manual edits to agent-state should still follow this graph."
          },
          "deps": {
            "type": "array",
            "default": [],
            "description": "Array of todo IDs that must reach `completed` (or `skipped`) before this one can move to `in_progress`. Empty for parallelizable steps.",
            "items": { "type": "string", "pattern": "^t[0-9]+$" }
          },
          "startedAt": { "type": "string", "format": "date-time" },
          "completedAt": { "type": "string", "format": "date-time" },
          "notes": {
            "type": "string",
            "description": "Free-text outcome  -  commit hash, test count, anything Phase 7 should echo."
          },
          "failureReason": { "type": "string" },
          "skipReason": { "type": "string" },
          "sourceTag": {
            "type": "string",
            "enum": ["Reuse", "Add new", "Modify"],
            "description": "Carried from the analysis Section 14 row this step came from (Locked 16). Phase 3 reads it as an instruction: a Reuse step binds the existing file and must not write a new one. Phase 4 checks the diff against it. Absent when the step did not originate from a Files-to-Add row."
          },
          "estimatedMinutes": {
            "type": "integer",
            "minimum": 1,
            "description": "Optional Phase 2 estimate for the step. Phase 7 compares against actual duration."
          }
        }
      }
    }
  }
}
