{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "Peaks Doctor Report",
  "description": "The envelope emitted by `peaks doctor --json` (data field). Each check.id uses a `<prefix>:<target>` form so callers can route follow-up actions per category.",
  "type": "object",
  "required": ["checks", "summary"],
  "properties": {
    "checks": {
      "type": "array",
      "items": {
        "type": "object",
        "required": ["id", "ok", "message"],
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^(?:(?:skill|skill-name|skill-parse|skill-runbook|skill-apply-note|skill-presence|statusline|schema|config|doctor-self|capability|build|integration|L3):[A-Za-z0-9][A-Za-z0-9._-]*|skills:[A-Za-z0-9][A-Za-z0-9._-]*(?::[A-Za-z0-9][A-Za-z0-9._-]*)+)$",
            "description": "Stable check id. Known prefixes: skill:<name> (required skill present), skill-name:<dir> (directory matches declared name), skill-parse:<dir> (skill metadata parsed), skill-runbook:<name> (Default runbook section exists), skill-apply-note:<name> (destructive --apply lines carry an authorization/--dry-run note), skill-presence:<topic> (status of .peaks/.active-skill.json — current/freshness/workspace), skills:<topic>:<ide>:<skill> (canonical-store vs IDE skill-tree parity — a file present on one side and absent on the other; the store target carries the store-level outcome — in parity, nothing to compare, absent, or unreadable), statusline:<topic> (out-of-band Claude Code statusLine — install/runtime), schema:<file> (schema file exists and is valid JSON), config:<scope> (optional config locations), doctor-self:<topic> (doctor validates its own output against this schema), capability:<name> (third-party capability is resolvable at the pinned version), build:<topic> (build-hygiene checks — dist/source version consistency), integration:<name> (third-party integration probe — e.g. gateguard-fact-force PreToolUse hook conflict on .peaks/**)."
          },
          "ok": { "type": "boolean" },
          "message": { "type": "string", "minLength": 1 }
        }
      }
    },
    "summary": {
      "type": "object",
      "required": ["ok", "passed", "failed"],
      "properties": {
        "ok": { "type": "boolean" },
        "passed": { "type": "integer", "minimum": 0 },
        "failed": { "type": "integer", "minimum": 0 }
      }
    }
  }
}
