{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://songforgeai.com/scoring-standard.schema.json",
  "title": "Lyric Scoring Standard Schema",
  "description": "JSON Schema for the canonical Lyric Scoring Standard JSON published at /scoring-standard.json. Implementers can validate their adoption of the rubric against this schema. Build 2191 (Deep Audit Tier-4 #21 — Schema.org + W3C-style publication): the standard becomes machine-validatable as well as machine-readable.",
  "type": "object",
  "required": [
    "name",
    "version",
    "publishedAt",
    "author",
    "canonical",
    "license",
    "summary",
    "philosophy",
    "tiers",
    "metrics"
  ],
  "properties": {
    "$schema": {
      "type": "string",
      "description": "URL to this JSON Schema document. Implementers should validate their copy of the standard against this URL."
    },
    "name": {
      "type": "string",
      "description": "Canonical name of the standard.",
      "const": "Lyric Scoring Standard"
    },
    "version": {
      "type": "string",
      "description": "Semantic version (MAJOR.MINOR.PATCH). MAJOR increments on breaking changes; MINOR on backward-compatible additions; PATCH on clarifications.",
      "pattern": "^\\d+\\.\\d+\\.\\d+$"
    },
    "publishedAt": {
      "type": "string",
      "description": "ISO 8601 date the current version was published.",
      "format": "date"
    },
    "author": {
      "type": "string",
      "description": "Publishing organization."
    },
    "canonical": {
      "type": "string",
      "description": "Canonical URL for the standard's hub page.",
      "format": "uri"
    },
    "license": {
      "type": "string",
      "description": "License under which the standard is published. Required: CC BY 4.0 or compatible."
    },
    "summary": {
      "type": "string",
      "description": "One-paragraph plain-English summary of what the standard scores and how the weighting works."
    },
    "philosophy": {
      "type": "array",
      "description": "Load-bearing anti-inflation rules. Each item is a named rule with a plain-English explanation. Removing or weakening a rule constitutes a breaking change (MAJOR version bump).",
      "items": { "type": "string" },
      "minItems": 1
    },
    "tiers": {
      "type": "array",
      "description": "The three weighted scoring tiers. Weights MUST sum to 1.0. Adding or removing a tier is a breaking change (MAJOR).",
      "minItems": 3,
      "maxItems": 3,
      "items": {
        "type": "object",
        "required": ["id", "label", "weight", "description"],
        "properties": {
          "id": {
            "type": "string",
            "enum": ["craft", "expression", "impact"]
          },
          "label": { "type": "string" },
          "weight": {
            "type": "number",
            "minimum": 0,
            "maximum": 1,
            "description": "Decimal weight of this tier in the composite score."
          },
          "description": { "type": "string" }
        }
      }
    },
    "metrics": {
      "type": "array",
      "description": "The 12 metrics scored against the rubric. Each metric belongs to one tier. The metric count is fixed at 12 — adding or removing metrics is a breaking change (MAJOR).",
      "minItems": 12,
      "maxItems": 12,
      "items": {
        "type": "object",
        "required": ["id", "tier", "name", "short", "description", "whatGoodLooksLike"],
        "properties": {
          "id": {
            "type": "integer",
            "description": "Stable numeric id (1-12). MUST NOT change across versions.",
            "minimum": 1,
            "maximum": 12
          },
          "tier": {
            "type": "string",
            "enum": ["craft", "expression", "impact"],
            "description": "Which tier this metric contributes to."
          },
          "name": {
            "type": "string",
            "description": "Full metric name (e.g. 'Prosody & Musicality')."
          },
          "short": {
            "type": "string",
            "description": "Compact label for UI surfaces (e.g. 'Prosody'). MAY change across MINOR versions for clarity."
          },
          "description": {
            "type": "string",
            "description": "Plain-English explanation of what this metric measures."
          },
          "whatGoodLooksLike": {
            "type": "string",
            "description": "Concrete description of high-band (≥85) performance on this metric. Used as the scorer's reference point."
          },
          "deprecated": {
            "type": "boolean",
            "description": "True if this metric is being phased out across MINOR versions. Implementers should continue scoring it but UI surfaces MAY suppress."
          }
        }
      }
    },
    "antiInflationRules": {
      "type": "array",
      "description": "Optional structured catalog of anti-inflation rules (separate from the philosophy array for tooling). Added in v1.2.0.",
      "items": {
        "type": "object",
        "required": ["id", "name", "description"],
        "properties": {
          "id": { "type": "string" },
          "name": { "type": "string" },
          "description": { "type": "string" }
        }
      }
    },
    "calibrationCorpus": {
      "type": "object",
      "description": "Optional pointer to the calibration / reference corpus used to anchor scores.",
      "properties": {
        "url": { "type": "string", "format": "uri" },
        "license": { "type": "string" }
      }
    },
    "reproducibilitySeal": {
      "type": "object",
      "description": "Optional pointer to the reproducibility seal specification used to bind scores to rubric version + model + temperature.",
      "properties": {
        "url": { "type": "string", "format": "uri" },
        "algorithm": {
          "type": "string",
          "description": "Signature algorithm (e.g. 'ed25519')."
        }
      }
    }
  },
  "additionalProperties": false
}
