{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://raw.githubusercontent.com/MrBinnacle/skill-harness/main/docs/sers/sers.schema.json",
  "title": "Skill Efficacy Reporting Standard (SERS)",
  "description": "Machine-readable receipt for a skill efficacy verdict. A missing number is a typed refusal, never an invented score. The evidence admissibility gate uses that qualified term only.",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "sers_version",
    "skill_name",
    "verdict",
    "cut_sub_reason",
    "unmeasured_sub_reason",
    "value_class",
    "evidence_admissibility",
    "cost",
    "instrument_identity",
    "source",
    "summary"
  ],
  "properties": {
    "sers_version": {
      "type": "string",
      "enum": ["1.0.0", "1.1.0", "1.2.0", "1.3.0", "1.4.0"],
      "description": "SERS vocabulary generation. Receipts from different sers_version values are not comparable."
    },
    "skill_name": {
      "type": "string",
      "minLength": 1,
      "description": "Skill identifier (store/card skill_name when known)."
    },
    "verdict": {
      "type": "string",
      "enum": ["KEEP", "CUT", "CANT_TELL_YET"],
      "description": "Operator-facing keep/cut outcome. KEEP = measurably worth its slot; CUT = remove (see cut_sub_reason); CANT_TELL_YET = evidence does not support a keep/cut call."
    },
    "cut_sub_reason": {
      "type": ["string", "null"],
      "enum": ["subsumed", "no_lift", "harmful", null],
      "description": "Qualifies CUT. Required non-null iff verdict is CUT; must be null otherwise. subsumed = model already does the task without the skill; no_lift = measured where help was needed and the skill did not deliver; harmful = skill made outcomes measurably worse."
    },
    "unmeasured_sub_reason": {
      "type": ["string", "null"],
      "enum": [
        "no_data",
        "inadmissible",
        "underpowered",
        "falsifying_case_missing",
        "budget_exhausted",
        "falsifying_case_stale",
        "fdr_correction_failed",
        "mechanical_vacuous",
        null
      ],
      "description": "Qualifies an UNMEASURED / cannot-score path when applicable. Mirrors UnmeasuredSubReason exactly. null when the receipt is not an unmeasured refusal path (e.g. a measured KEEP or CUT)."
    },
    "value_class": {
      "type": ["string", "null"],
      "enum": ["transformative-lift", "trap-discipline", "calibration", null],
      "description": "Skill value kind. Screen-path CUT(subsumed) is valid only for transformative-lift; other classes route above-bar p0 to CANT_TELL_YET (wrong instrument). null = unclassified."
    },
    "outcome_type": {
      "type": ["string", "null"],
      "enum": ["pass_fail", "invariant", null],
      "description": "The scoring-oracle kind the record authorises. pass_fail = legacy conjunction oracle; invariant = split invariant + completion oracle. Required for trap-discipline; null on pass_fail records."
    },
    "wrong_instrument": {
      "type": "boolean",
      "description": "True when a CUT was withheld because value_class is not transformative-lift (wrong instrument for the lift estimand)."
    },
    "declared_synthetic_control": {
      "type": "boolean",
      "description": "True when the skill/effect is a declared synthetic positive control (effect real by construction). Must never be silently omitted when true."
    },
    "evidence_admissibility": {
      "type": "object",
      "additionalProperties": false,
      "description": "Evidence admissibility gate outcome for the evidence backing this receipt. Uses the qualified term only.",
      "required": ["status"],
      "properties": {
        "status": {
          "type": "string",
          "enum": ["admissible", "inadmissible", "mixed", "not_applicable"],
          "description": "admissible = all cited evidence cleared the evidence admissibility gate; inadmissible = evidence present but gated out of aggregation; mixed = both; not_applicable = no store-backed evidence (prose-only / mechanical)."
        },
        "detail": {
          "type": "string",
          "description": "Optional human-readable note on the evidence admissibility ruling."
        }
      }
    },
    "cost": {
      "type": "object",
      "additionalProperties": false,
      "description": "Cost triple: standing / fired / aux tokens. Each leg is a measured non-negative integer or a typed refusal — never an invented score.",
      "required": ["standing_tokens", "fired_tokens", "aux_tokens"],
      "properties": {
        "standing_tokens": { "$ref": "#/$defs/token_figure" },
        "fired_tokens": { "$ref": "#/$defs/token_figure" },
        "aux_tokens": { "$ref": "#/$defs/token_figure" }
      }
    },
    "instrument_identity": {
      "type": "object",
      "additionalProperties": false,
      "description": "Generation stamp for every figure on this receipt. Figures from different instrument identities are visibly non-comparable.",
      "required": ["extractor_model", "prompt_fingerprint", "schema_fingerprint"],
      "properties": {
        "extractor_model": {
          "description": "Extractor model pin: the model that READ the run artifacts and produced the figures. From sers_version 1.4.0 this names the extraction stage only, never the subject under test — the subject is subject_identity.subject_model. Where no model-based extraction stage ran (a deterministic oracle scored the epochs), record a typed refusal rather than repeating the subject pin. On receipts at 1.3.0 and earlier this field was documented as 'extractor (or subject)': it carries one pin for two roles and which role it names is not machine-readable. Read those receipts through source.prose_path.",
          "oneOf": [
            {
              "type": "string",
              "minLength": 1
            },
            {
              "type": "object",
              "additionalProperties": false,
              "required": ["refusal"],
              "properties": {
                "refusal": {
                  "type": "string",
                  "enum": ["not_applicable", "not_instrumented"]
                },
                "detail": { "type": "string" }
              }
            }
          ]
        },
        "prompt_fingerprint": {
          "type": "string",
          "minLength": 1,
          "description": "Fingerprint (typically SHA-256 hex) of the exact system/prompt bytes used."
        },
        "schema_fingerprint": {
          "type": "string",
          "minLength": 1,
          "description": "Fingerprint (typically SHA-256 hex) of the tool/schema (or harness pin) used."
        }
      }
    },
    "measurements": {
      "type": "object",
      "additionalProperties": false,
      "description": "Optional numeric figures. Each present key is either a measured value or a typed refusal.",
      "properties": {
        "p0": {
          "$ref": "#/$defs/rate_or_refusal",
          "description": "Null-arm (no-skill) pass rate from a Stage-0 screen."
        },
        "full_pass_rate": {
          "$ref": "#/$defs/rate_or_refusal",
          "description": "Full-arm pass rate from a paired run."
        },
        "null_pass_rate": {
          "$ref": "#/$defs/rate_or_refusal",
          "description": "Null-arm pass rate from a paired run (may equal p0 when only a screen ran)."
        },
        "p_win": {
          "$ref": "#/$defs/rate_or_refusal",
          "description": "Posterior P(rate above threshold) from the paired fit."
        },
        "discordance_rate": {
          "$ref": "#/$defs/rate_or_refusal",
          "description": "Paired per-epoch discordance rate d-hat (and optional CI in detail)."
        },
        "go_nogo": {
          "type": "string",
          "enum": ["GO", "NO_GO", "NOT_APPLICABLE"],
          "description": "Pre-stated GO/NO-GO apparatus gate when one was registered."
        },
        "hazard_entry_null": {
          "$ref": "#/$defs/rate_or_refusal",
          "description": "Null-arm hazard-entry rate: the fraction of Null epochs where the hazard pattern was entered."
        },
        "hazard_entry_full": {
          "$ref": "#/$defs/rate_or_refusal",
          "description": "Full-arm hazard-entry rate: the fraction of Full epochs where the hazard pattern was entered."
        },
        "null_completion_rate": {
          "$ref": "#/$defs/rate_or_refusal",
          "description": "Null-arm completion rate: the fraction of Null epochs where the completion oracle scored pass."
        },
        "full_completion_rate": {
          "$ref": "#/$defs/rate_or_refusal",
          "description": "Full-arm completion rate: the fraction of Full epochs where the completion oracle scored pass."
        },
        "silent_violation_rate": {
          "$ref": "#/$defs/rate_or_refusal",
          "description": "Silent violation rate: the fraction of epochs where completion held but invariant failed (C=1, I=0)."
        }
      }
    },
    "source": {
      "type": "object",
      "additionalProperties": false,
      "description": "Pointer to the prose source this hand-encoded receipt encodes.",
      "required": ["prose_path"],
      "properties": {
        "prose_path": {
          "type": "string",
          "minLength": 1,
          "description": "Repo-relative path to the prose source of record."
        },
        "date": {
          "type": "string",
          "description": "ISO date of the underlying result when known."
        },
        "notes": {
          "type": "string"
        }
      }
    },
    "summary": {
      "type": "string",
      "minLength": 1,
      "description": "One-paragraph operator-facing summary. Must not invent numbers absent from measurements/cost."
    },
    "subject_identity": {
      "type": "object",
      "additionalProperties": false,
      "description": "Provenance block identifying the subject under test. Required from sers_version 1.1.0 onward; absent on 1.0.0 hand-encoded receipts.",
      "required": ["skill_id", "harness_version", "metric_version", "implementation_hash", "arms"],
      "properties": {
        "skill_id": {
          "type": "string",
          "pattern": "^[a-f0-9]{64}$",
          "description": "SHA-256 hex of the exact SKILL.md bytes measured."
        },
        "harness_version": {
          "type": "string",
          "minLength": 1,
          "description": "Harness version used to produce this receipt."
        },
        "metric_version": {
          "type": "string",
          "minLength": 1,
          "description": "Oracle metric version (e.g. '0.3.0')."
        },
        "implementation_hash": {
          "type": "string",
          "pattern": "^[a-f0-9]{64}$",
          "description": "SHA-256 hex of the oracle module source at ingest time."
        },
        "subject_model": {
          "type": "string",
          "minLength": 1,
          "description": "Subject model pin: the model that EXECUTED the epochs, and whose behaviour with and without the skill was compared. Together with skill_id it identifies what was measured. Required from sers_version 1.4.0; absent on 1.3.0 and earlier receipts, where no field recorded it and it cannot be recovered from the receipt alone."
        },
        "arms": {
          "oneOf": [
            { "type": "string", "enum": ["null", "full"] },
            {
              "type": "array",
              "items": { "type": "string", "enum": ["null", "full"] },
              "minItems": 1,
              "maxItems": 2,
              "uniqueItems": true
            }
          ],
          "description": "Which arms ran: 'null', 'full', or both."
        }
      }
    },
    "delivery": {
      "type": "object",
      "additionalProperties": false,
      "description": "Value-delivery attribution: which of the skill's two products (description or body) carried the measured value. Required from sers_version 1.2.0 onward; absent on 1.0.0 and 1.1.0 receipts.",
      "required": ["channel", "exposure", "pi_c"],
      "properties": {
        "exposure": {
          "oneOf": [
            {
              "type": "object",
              "additionalProperties": false,
              "required": ["value"],
              "properties": {
                "value": {
                  "type": "number",
                  "minimum": 0,
                  "maximum": 1
                },
                "passes": {
                  "type": "integer",
                  "minimum": 0
                },
                "epochs": {
                  "type": "integer",
                  "minimum": 0
                }
              }
            },
            {
              "type": "object",
              "additionalProperties": false,
              "required": ["refusal"],
              "properties": {
                "refusal": {
                  "type": "string",
                  "enum": ["not_instrumented", "not_applicable"]
                },
                "detail": { "type": "string" }
              }
            }
          ],
          "description": "Exposure rate in the treated arm: the fraction of epochs where the skill's description was present in the agent's context (the treatment under #384). Distinct from pi_c (invocation / body load). 'value' is the rate; 'passes' and 'epochs' are optional counts."
        },
        "pi_c": {
          "oneOf": [
            {
              "type": "object",
              "additionalProperties": false,
              "required": ["invocations", "trials", "hat", "ci_low", "ci_high", "confidence", "detector"],
              "properties": {
                "invocations": {
                  "type": "integer",
                  "minimum": 0
                },
                "trials": {
                  "type": "integer",
                  "minimum": 0
                },
                "hat": {
                  "type": "number",
                  "minimum": 0,
                  "maximum": 1
                },
                "ci_low": {
                  "type": "number",
                  "minimum": 0,
                  "maximum": 1
                },
                "ci_high": {
                  "type": "number",
                  "minimum": 0,
                  "maximum": 1
                },
                "confidence": {
                  "type": "number",
                  "exclusiveMinimum": 0,
                  "exclusiveMaximum": 1
                },
                "detector": {
                  "type": "string",
                  "minLength": 1
                }
              }
            },
            {
              "type": "object",
              "additionalProperties": false,
              "required": ["refusal"],
              "properties": {
                "refusal": {
                  "type": "string",
                  "enum": ["not_instrumented", "not_applicable"]
                },
                "detail": { "type": "string" }
              }
            }
          ],
          "description": "Invocation rate over the treated (Full) arm with Clopper-Pearson interval. 'hat' is the point estimate; 'ci_low' and 'ci_high' bound the interval. 'detector' names the versioned detector that produced the invocations count."
        },
        "channel": {
          "type": "string",
          "enum": ["description_only", "body_and_description", "not_instrumented"],
          "description": "Which of the skill's two products carried the measured value. 'description_only' = the standing description line was read but the body was never loaded (pi_c = 0 with full exposure); 'body_and_description' = invocations are present so the body was read; 'not_instrumented' = receipts minted before detector v2."
        }
      }
    }
  },
  "allOf": [
    {
      "if": {
        "properties": { "verdict": { "const": "CUT" } },
        "required": ["verdict"]
      },
      "then": {
        "properties": {
          "cut_sub_reason": {
            "type": "string",
            "enum": ["subsumed", "no_lift", "harmful"]
          }
        }
      }
    },
    {
      "if": {
        "properties": { "verdict": { "enum": ["KEEP", "CANT_TELL_YET"] } },
        "required": ["verdict"]
      },
      "then": {
        "properties": {
          "cut_sub_reason": { "type": "null" }
        }
      }
    },
    {
      "if": {
        "properties": { "sers_version": { "const": "1.1.0" } },
        "required": ["sers_version"]
      },
      "then": {
        "required": ["subject_identity"]
      }
    },
    {
      "if": {
        "properties": { "sers_version": { "const": "1.2.0" } },
        "required": ["sers_version"]
      },
      "then": {
        "required": ["subject_identity", "delivery"]
      }
    },
    {
      "if": {
        "properties": { "sers_version": { "const": "1.3.0" } },
        "required": ["sers_version"]
      },
      "then": {
        "required": ["subject_identity", "delivery"]
      }
    },
    {
      "if": {
        "properties": { "sers_version": { "const": "1.4.0" } },
        "required": ["sers_version"]
      },
      "then": {
        "required": ["subject_identity", "delivery"],
        "properties": {
          "subject_identity": {
            "required": ["subject_model"]
          }
        }
      }
    },
    {
      "if": {
        "properties": {
          "delivery": {
            "properties": { "channel": { "const": "description_only" } },
            "required": ["channel"]
          }
        },
        "required": ["delivery"]
      },
      "then": {
        "properties": {
          "delivery": {
            "properties": {
              "pi_c": {
                "oneOf": [
                  {
                    "type": "object",
                    "properties": { "hat": { "const": 0 } },
                    "required": ["hat"]
                  },
                  {
                    "type": "object",
                    "properties": { "refusal": { "type": "string" } },
                    "required": ["refusal"]
                  }
                ]
              }
            }
          }
        }
      }
    },
    {
      "if": {
        "properties": {
          "delivery": {
            "properties": { "channel": { "const": "body_and_description" } },
            "required": ["channel"]
          }
        },
        "required": ["delivery"]
      },
      "then": {
        "properties": {
          "delivery": {
            "properties": {
              "pi_c": {
                "oneOf": [
                  {
                    "type": "object",
                    "properties": { "invocations": { "type": "integer", "minimum": 1 } },
                    "required": ["invocations"]
                  },
                  {
                    "type": "object",
                    "properties": { "refusal": { "type": "string" } },
                    "required": ["refusal"]
                  }
                ]
              }
            }
          }
        }
      }
    }
  ],
  "$defs": {
    "token_figure": {
      "description": "A non-negative token count, or a typed refusal. Missing number = typed refusal, never an invented score.",
      "oneOf": [
        {
          "type": "object",
          "additionalProperties": false,
          "required": ["tokens"],
          "properties": {
            "tokens": {
              "type": "integer",
              "minimum": 0
            }
          }
        },
        {
          "type": "object",
          "additionalProperties": false,
          "required": ["refusal"],
          "properties": {
            "refusal": {
              "type": "string",
              "enum": ["unmeasured", "not_applicable", "not_instrumented"]
            },
            "detail": { "type": "string" }
          }
        }
      ]
    },
    "rate_or_refusal": {
      "description": "A rate in [0, 1] with optional counts, or a typed refusal drawn from UnmeasuredSubReason (plus not_applicable for non-paths).",
      "oneOf": [
        {
          "type": "object",
          "additionalProperties": false,
          "required": ["value"],
          "properties": {
            "value": {
              "type": "number",
              "minimum": 0,
              "maximum": 1
            },
            "passes": {
              "type": "integer",
              "minimum": 0
            },
            "epochs": {
              "type": "integer",
              "minimum": 0
            },
            "detail": { "type": "string" }
          }
        },
        {
          "type": "object",
          "additionalProperties": false,
          "required": ["refusal"],
          "properties": {
            "refusal": {
              "type": "string",
              "enum": [
                "no_data",
                "inadmissible",
                "underpowered",
                "falsifying_case_missing",
                "budget_exhausted",
                "falsifying_case_stale",
                "fdr_correction_failed",
                "mechanical_vacuous",
                "not_applicable"
              ]
            },
            "detail": { "type": "string" }
          }
        }
      ]
    }
  }
}
