{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://raw.githubusercontent.com/BourbonDog/amicus/main/schemas/progress.schema.json",
  "title": "Amicus leg/solo progress snapshot (progress.json)",
  "type": "object",
  "required": ["schemaVersion", "type", "stage", "updatedAt"],
  "properties": {
    "schemaVersion": { "const": 1 },
    "type": { "const": "progress" },
    "stage": { "type": "string" },
    "stageLabel": { "type": "string" },
    "updatedAt": { "type": "string", "format": "date-time" },
    "messagesReceived": { "type": "number" },
    "latestTool": { "type": "string" },
    "toolSettleTimedOut": {
      "description": "v4.4 B4. The leg was completed while at least one tool call was still non-terminal, after AMICUS_TOOL_SETTLE_GRACE_MS elapsed. Its partial output was kept and it was NOT failed, but its reported cost is a floor. Present only when true.",
      "const": true
    },
    "unsettledToolCalls": {
      "description": "How many tool calls were still live when the settle grace was exceeded. A count here (progress.json is a compact snapshot); the full list rides the runHeadless result. Present only alongside toolSettleTimedOut.",
      "type": "number"
    },
    "toolSettleAborted": {
      "description": "v4.4.1 LC-2. Whether the leg's OpenCode session was successfully aborted at the settle ceiling so it would stop billing. `false` means the abort was attempted and failed — the session may still be billing. Present only alongside toolSettleTimedOut.",
      "type": "boolean"
    },
    "usage": {
      "type": "object",
      "properties": {
        "tokens": { "type": "object" },
        "costReported": { "type": "number" },
        "subtree": {
          "description": "v4.4.1 CA-1. Spend of the CHILD (subagent) OpenCode sessions this leg spawned, which OpenCode bills separately and does NOT roll into the parent session's cost. Attributed to this leg by the terminal walk in src/headless.js; resolved into usage.subtree by src/observe/live-doc.js enrichLegUsage so the live GUI and run.json agree. Absent when the leg spawned none.",
          "type": "object",
          "properties": {
            "sessions": { "type": "number" },
            "tokens": { "type": "object" },
            "costReported": { "type": "number" }
          }
        },
        "subtreeUnknown": {
          "description": "The leg's own cost is stated, but there is positive evidence of a subagent subtree whose spend the walk could not account for. The total is a floor, not the bill. Present only when true.",
          "const": true
        }
      }
    }
  },
  "additionalProperties": true
}
