{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://serverbench.cloudpropeller.com/schema/cp-server-bench-1.0.json",
  "title": "CP ServerBench (cp-server-bench) result — v1.0",
  "description": "Result document emitted by cp-server-bench.sh. Version 1.0 (PRE-PUBLISH baseline). Newer fields (test_command, speedtest_preferred_target, context.backing, generator_command) are OPTIONAL so older result files still validate and render \"n/a\" where absent. Object containers are intentionally open (additionalProperties:true) because machine/context/toolchain carry per-host, per-domain optional fields.",
  "type": "object",
  "required": ["schema_version", "schema_url", "generator", "run", "machine", "results"],
  "additionalProperties": true,
  "properties": {
    "schema_version": { "const": "1.0", "description": "Stored-data schema version. Bumps (1.0 -> 1.1) when a new STORED field is added; a new versioned schema file is published and old ones kept." },
    "schema_url": {
      "type": "string",
      "format": "uri",
      "description": "URL of this schema document. v1.0 -> https://serverbench.cloudpropeller.com/schema/cp-server-bench-1.0.json"
    },
    "generator": {
      "type": "object",
      "description": "The tool that produced this file. Self-recording: name + semver + content hash.",
      "required": ["name", "version"],
      "additionalProperties": true,
      "properties": {
        "name": { "type": "string", "description": "Generator script name (cp-server-bench.sh)." },
        "version": { "type": "string", "description": "Generator semver (e.g. 1.0.0). Bumps when a TEST is added/changed." },
        "sha256": { "type": "string", "description": "sha256 of the generator script at run time." }
      }
    },
    "generator_command": {
      "type": ["string", "null"],
      "description": "OPTIONAL. The FULL run invocation (program basenamed, args shell-quoted) so the whole run can be reproduced; complements per-test test_command. May carry a scratch-device path or --net-client peer IP — these are reproduction aids and are stripped before the publish redaction scan. Backfilled values are partial (old runs hashed the real devices -> <scratch-device> placeholder)."
    },
    "run": {
      "type": "object",
      "required": ["id", "started_utc", "exit_code", "requested"],
      "additionalProperties": true,
      "properties": {
        "id": { "type": "string", "description": "Run UUID." },
        "started_utc": { "type": "string", "description": "ISO-8601 UTC run start." },
        "finished_utc": { "type": ["string", "null"], "description": "ISO-8601 UTC run finish." },
        "exit_code": { "type": ["integer", "null"], "description": "0 unless a benchmark returned status=failed." },
        "requested": {
          "type": "object",
          "description": "What the operator asked for.",
          "additionalProperties": true,
          "properties": {
            "domains": { "type": "array", "items": { "type": "string", "enum": ["compute", "storage", "network"] }, "description": "Selected domains." },
            "tests": { "type": ["array", "null"], "items": { "type": "string" }, "description": "Explicit test list, or null = all." },
            "flags": { "type": "object", "additionalProperties": true, "description": "Run flags actually applied (e.g. {\"runs_per_test\":1})." }
          }
        },
        "warnings": { "type": "array", "items": { "type": "string" } }
      }
    },
    "machine": {
      "type": "object",
      "description": "Host fingerprint. Open container: distro/virt/toolchain/disks vary per host.",
      "required": ["label", "cpu", "mem", "os"],
      "additionalProperties": true,
      "properties": {
        "label": { "type": "string", "description": "Host label; AWS-* / CP-* prefix is the vendor discriminator." },
        "label_source": { "type": "string", "description": "How the label was set (e.g. operator, generated)." },
        "cpu": {
          "type": "object",
          "additionalProperties": true,
          "properties": {
            "model": { "type": ["string", "null"] },
            "vendor": { "type": ["string", "null"] },
            "physical_cores": { "type": ["integer", "null"] },
            "threads": { "type": ["integer", "null"] },
            "smt": { "type": ["boolean", "null"] },
            "base_ghz": { "type": ["number", "null"] },
            "max_ghz": { "type": ["number", "null"] },
            "numa_nodes": { "type": ["integer", "null"] }
          }
        },
        "mem": {
          "type": "object",
          "additionalProperties": true,
          "properties": { "total_mb": { "type": ["integer", "null"] } }
        },
        "disks": { "type": "array", "items": { "type": "object", "additionalProperties": true } },
        "os": {
          "type": "object",
          "additionalProperties": true,
          "properties": {
            "distro": { "type": ["string", "null"] },
            "version": { "type": ["string", "null"] },
            "kernel": { "type": ["string", "null"] },
            "arch": { "type": ["string", "null"] }
          }
        },
        "virt": { "type": "object", "additionalProperties": true },
        "toolchain": { "type": "object", "additionalProperties": true }
      }
    },
    "results": {
      "type": "array",
      "description": "One object per benchmark (or per fio profile/device, per iperf direction).",
      "items": { "$ref": "#/$defs/result" }
    },
    "x_ext": { "type": "object", "additionalProperties": true, "description": "Reserved extension bag." }
  },
  "$defs": {
    "result": {
      "type": "object",
      "required": ["domain", "test", "standard_benchmark", "status", "metrics", "context"],
      "additionalProperties": true,
      "properties": {
        "domain": { "type": "string", "enum": ["compute", "storage", "network"] },
        "test": { "type": "string", "description": "Test id (e.g. sysbench_cpu, fio_randread, iperf3, speedtest)." },
        "profile": { "type": ["string", "null"], "description": "Sub-variant (fio profile, iperf direction, single_core, ...)." },
        "standard_benchmark": { "type": "boolean" },
        "started_utc": { "type": ["string", "null"] },
        "status": { "type": "string", "enum": ["ok", "failed", "skipped"] },
        "skip_reason": { "type": ["string", "null"] },
        "error": { "type": ["string", "null"] },
        "exit_code": { "type": ["integer", "null"] },
        "test_command": { "type": ["string", "null"], "description": "OPTIONAL. The exact command that produced this result, for one-test reproduction. Stripped before the publish redaction scan." },
        "speedtest_preferred_target": { "type": ["string", "null"], "description": "OPTIONAL (speedtest only). Human-readable Ookla server chosen. Stripped before the publish redaction scan." },
        "metrics": { "type": "array", "items": { "$ref": "#/$defs/metric" } },
        "context": { "$ref": "#/$defs/context" }
      }
    },
    "metric": {
      "type": "object",
      "required": ["key", "value"],
      "additionalProperties": true,
      "properties": {
        "key": { "type": "string" },
        "value": { "type": ["number", "null"] },
        "unit": { "type": ["string", "null"] },
        "higher_is_better": { "type": ["boolean", "null"] },
        "primary": { "type": ["boolean", "null"] },
        "stddev": { "type": ["number", "null"] }
      }
    },
    "context": {
      "type": "object",
      "description": "Per-result ambient context. Open container: keys vary by domain (storage: disk_mode/post_state/mount_id/backing/fio_*; compute: threads/affinity/...; network: peer/port/streams stats).",
      "additionalProperties": true,
      "properties": {
        "backing": {
          "type": ["string", "null"],
          "description": "OPTIONAL. Human-readable backing of the benched device — the guest disk MODEL vendor string (e.g. \"Amazon Elastic Block Store\", \"QEMU HARDDISK\"), a backing-store identifier, or \"unknown\". Vendor-uniform: does NOT reveal the storage tier (gp3/io2, Ceph/Alletra) — tier is recorded separately in tier_class/tier_label."
        },
        "tier_class": {
          "type": ["string", "null"],
          "enum": ["premium", "standard", null],
          "description": "OPTIONAL. Storage tier class of the benched disk: \"premium\" (high-IOPS: Ceph / io2) or \"standard\" (baseline: Alletra / gp3). Set via --wipe-premium-disk / --wipe-standard-disk."
        },
        "tier_label": {
          "type": ["string", "null"],
          "description": "OPTIONAL. Tier name of the benched disk. Canonical labels are lowercase (\"ceph\", \"alletra\", \"gp3\", \"io2\"); consumers should key case-insensitively since users may label freely. Set via the packed --wipe-premium-disk/--wipe-standard-disk value (DEV:LABEL:IOPS)."
        },
        "provisioned_iops": {
          "type": ["integer", "null"],
          "description": "OPTIONAL. Provisioned IOPS cap on the benched disk (e.g. 8500 for io2), or null = no provisioned limit (Ceph/Alletra unmetered, gp3 baseline). Set via --premium-disk-provisioned-iops / --standard-disk-provisioned-iops."
        },
        "disk_mode": { "type": ["string", "null"] },
        "post_state": { "type": ["string", "null"] },
        "mount_id": { "type": ["string", "null"], "description": "Opaque sha256 of the canonical device/mount path (never the raw path)." }
      }
    }
  }
}
