{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://civitas-cerebrum.github.io/element-interactions/schemas/run-summary.schema.json",
  "title": "Achilles run summary (run-summary/v2)",
  "description": "Contract for <project>/.achilles/run-summary.json as emitted by hooks/run-summary-writer.sh (Stop hook) — the authoritative self-report consumed by external benchmark drivers (e.g. Feyzabora/bookhive-benchmark). The tests block is null-statused when no Playwright results file exists; it is never a fabricated pass.",
  "type": "object",
  "additionalProperties": false,
  "required": ["meta", "phases", "scenarios", "bugs", "tests", "journey_map"],
  "properties": {
    "meta": {
      "type": "object",
      "additionalProperties": false,
      "required": ["timestamp", "git_sha", "achilles_version", "schema"],
      "properties": {
        "timestamp": { "type": "string", "format": "date-time" },
        "git_sha": { "type": "string", "description": "HEAD sha of the project repo; empty string outside a git checkout." },
        "achilles_version": { "type": "string", "description": "Installed @civitas-cerebrum/achilles version; empty string when not resolvable from node_modules." },
        "schema": { "const": "run-summary/v2" }
      }
    },
    "phases": {
      "type": "array",
      "description": "Verbatim .phases array from tests/e2e/docs/onboarding-status.json; empty when the ledger is absent.",
      "items": { "type": "object" }
    },
    "scenarios": {
      "type": "object",
      "additionalProperties": false,
      "required": ["files"],
      "properties": {
        "files": {
          "type": "array",
          "items": { "type": "string" },
          "description": "Every *.spec.ts / *.spec.js / *.spec.mjs path found under tests/."
        }
      }
    },
    "bugs": {
      "type": "object",
      "additionalProperties": false,
      "required": ["ids", "by_severity"],
      "properties": {
        "ids": {
          "type": "array",
          "items": { "type": "string" },
          "description": "Finding IDs harvested from '#### <ID> [sev] — title' headings in tests/e2e/docs/adversarial-findings.md."
        },
        "by_severity": {
          "type": "object",
          "additionalProperties": false,
          "required": ["critical", "high", "medium", "low", "info"],
          "properties": {
            "critical": { "type": "integer", "minimum": 0 },
            "high": { "type": "integer", "minimum": 0 },
            "medium": { "type": "integer", "minimum": 0 },
            "low": { "type": "integer", "minimum": 0 },
            "info": { "type": "integer", "minimum": 0 }
          }
        }
      }
    },
    "tests": {
      "type": "object",
      "additionalProperties": false,
      "required": ["passing", "failing", "flaky", "skipped", "total", "status"],
      "properties": {
        "passing": { "type": ["integer", "null"], "minimum": 0 },
        "failing": { "type": ["integer", "null"], "minimum": 0 },
        "flaky": { "type": ["integer", "null"], "minimum": 0 },
        "skipped": { "type": ["integer", "null"], "minimum": 0 },
        "total": { "type": ["integer", "null"], "minimum": 0 },
        "status": {
          "enum": ["passing", "failing", null],
          "description": "null when no results file was found — never a fake pass."
        }
      }
    },
    "journey_map": {
      "type": "object",
      "additionalProperties": false,
      "required": ["journeys"],
      "properties": {
        "journeys": {
          "type": "integer",
          "minimum": 0,
          "description": "Count of '### j-' journey headings in tests/e2e/docs/journey-map.md."
        }
      }
    }
  }
}
