{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://nkorai.github.io/datasheet-schema/schema/datasheet-1.0.schema.json",
  "$comment": "Datasheet Schema v1.0. MIT. https://github.com/nkorai/datasheet-schema. This file is self-contained and validates with no external references.",
  "title": "Datasheet Schema",
  "description": "A machine-readable schema for electronic-component datasheet specifications. Each value records the test conditions under which it holds and a reference to its source in the datasheet. Existing standards omit both.",
  "specVersion": "1.0",
  "type": "object",
  "required": ["schemaVersion", "component", "parameters", "provenance"],
  "additionalProperties": false,

  "properties": {
    "schemaVersion": {
      "description": "The Datasheet Schema version this document conforms to.",
      "const": "1.0"
    },
    "component": { "$ref": "#/$defs/component" },
    "pinout": {
      "description": "Physical pins with normalized functions, so a tool can bind a pin by function rather than by vendor pin name.",
      "type": "array",
      "items": { "$ref": "#/$defs/pin" }
    },
    "parameters": {
      "description": "All specified values. Absolute-maximum, recommended-operating, electrical, thermal, and ESD data are held here as parameters and distinguished by each measurement's limitClass rather than by separate tables. This allows one envelope to describe any component family.",
      "type": "array",
      "items": { "$ref": "#/$defs/parameter" }
    },
    "provenance": { "$ref": "#/$defs/provenance" },
    "notes": {
      "description": "Free text for a reviewer, covering anything ambiguous, conflicting, or spread across variant tables.",
      "type": "array",
      "items": { "type": "string" }
    }
  },

  "$defs": {
    "component": {
      "title": "Component identity",
      "description": "Identifying information for the part.",
      "type": "object",
      "required": ["mpn", "manufacturer", "family"],
      "additionalProperties": false,
      "properties": {
        "mpn": { "description": "Manufacturer part number.", "type": "string", "minLength": 1 },
        "manufacturer": { "type": "string", "minLength": 1 },
        "family": {
          "description": "Component family. Determines which parameter dictionary applies.",
          "type": "string",
          "examples": ["ldo", "buck_converter", "ldo_reference", "load_switch", "mosfet", "mcu"]
        },
        "description": { "type": "string" },
        "package": { "description": "Package designator as printed, for example SOT-23-5.", "type": "string" },
        "pinCount": { "type": "integer", "minimum": 1 },
        "polarity": {
          "description": "The rail polarity of a regulator or reference, declared so a consumer never has to infer it from the sign of extracted values. positive is the default and MAY be omitted; negative marks a negative-rail part (a negative LDO or reference) whose output, input, and their conditions are negative numbers. When negative, min and max of a range keep numeric ordering (min is the more-negative bound), so an input range of -20 V to -2.3 V has min -20, max -2.3. bipolar is for a dual-rail or tracking part.",
          "enum": ["positive", "negative", "bipolar"]
        },
        "lifecycle": { "enum": ["active", "nrnd", "obsolete", "unknown"] },
        "msl": { "description": "Moisture sensitivity level, for example MSL1.", "type": "string" },
        "temperatureGrade": {
          "description": "Qualification or temperature grade, for example -40..125 or AEC-Q100 Grade 1.",
          "type": "string"
        },
        "orderingVariants": {
          "description": "The orderable variants covered by this datasheet.",
          "type": "array",
          "items": {
            "type": "object",
            "required": ["orderCode"],
            "additionalProperties": false,
            "properties": {
              "orderCode": { "type": "string" },
              "outputVoltageV": { "description": "Fixed output option, when this variant pins a voltage.", "type": "number" },
              "package": { "type": "string" },
              "temperatureGrade": { "type": "string" },
              "packing": { "description": "Tape and reel, tube, or similar.", "type": "string" }
            }
          }
        }
      }
    },

    "pin": {
      "title": "Pin",
      "type": "object",
      "required": ["number", "name", "function"],
      "additionalProperties": false,
      "properties": {
        "number": { "description": "1-indexed physical pin number.", "type": "integer", "minimum": 1 },
        "name": { "description": "Pin name as printed.", "type": "string" },
        "function": {
          "description": "Normalized semantic function. A controlled vocabulary that families extend, in the same way the parameter key vocabulary is extended by a family dictionary. Recommended values: IN, OUT, GND, EN, NC, BYP, ADJ, FB, PG, SENSE, BIAS, PAD for regulators and references, and G, D, S for field-effect transistors. A validator MAY constrain the set per family. Uppercase, matching ^[A-Z][A-Z0-9_]*$.",
          "type": "string",
          "pattern": "^[A-Z][A-Z0-9_]*$"
        },
        "type": { "enum": ["power", "analog", "digital_in", "digital_out", "passive", "thermal"] },
        "description": { "type": "string" },
        "sourcePage": { "type": "integer", "minimum": 1 }
      }
    },

    "parameter": {
      "title": "Parameter",
      "description": "One canonically-keyed characteristic. A family dictionary, for example dictionary/ldo-1.0.json, defines the legal keys, their units, and vendor aliases. The schema keeps the parameter shape family-agnostic so every family reuses it.",
      "type": "object",
      "required": ["key", "measurements"],
      "additionalProperties": false,
      "properties": {
        "key": {
          "description": "Canonical parameter key from the family dictionary, for example dropout_voltage, psrr, reference_voltage, or thermal_resistance_junction_ambient.",
          "type": "string",
          "pattern": "^[a-z][a-z0-9_]*$"
        },
        "name": { "description": "Human-readable label.", "type": "string" },
        "group": { "description": "Family-scoped functional group, for example regulation or protection.", "type": "string" },
        "aliases": {
          "description": "Vendor synonyms for this parameter, for example ripple rejection for psrr. Normalizing naming in the schema rather than in downstream code keeps documents interoperable across manufacturers.",
          "type": "array",
          "items": { "type": "string" }
        },
        "measurements": {
          "description": "One entry per distinct condition set. A parameter specified across several load currents or frequencies, such as dropout, PSRR, or quiescent current, has one measurement per point.",
          "type": "array",
          "minItems": 1,
          "items": { "$ref": "#/$defs/measurement" }
        }
      }
    },

    "measurement": {
      "title": "Measurement",
      "description": "A value with its unit, the conditions under which it holds, the table it came from, and provenance.",
      "type": "object",
      "required": ["limitClass", "value", "unit"],
      "additionalProperties": false,
      "properties": {
        "limitClass": {
          "description": "The kind of limit this value represents. absolute_max is a stress limit and operation beyond it may damage the device. recommended is the specified operating range. characterized is a measured or guaranteed electrical characteristic. A consumer must not treat an absolute_max value as an operating value.",
          "enum": ["absolute_max", "recommended", "characterized"]
        },
        "value": { "$ref": "#/$defs/value" },
        "unit": { "$ref": "#/$defs/unit" },
        "conditions": {
          "description": "The test conditions under which this value holds. An open list of typed axes so it generalizes across families. An LDO uses I_OUT and V_IN, a MOSFET uses V_GS and V_DS, a buck converter adds F_SW. The axes that govern the value should be present.",
          "type": "array",
          "items": { "$ref": "#/$defs/conditionAxis" }
        },
        "stimulus": {
          "description": "For dynamic parameters such as load or line transient response and start-up, the applied step. Modeled here because the from, to, and slew fields recur for load steps, line steps, and switching edges.",
          "$ref": "#/$defs/stimulus"
        },
        "conditionsVerbatim": {
          "description": "The test conditions exactly as printed in the datasheet, retained alongside the parsed axes so nothing is lost in normalization.",
          "type": "string"
        },
        "sourcePage": { "description": "1-indexed datasheet page this value was read from.", "type": "integer", "minimum": 1 },
        "sourceTable": { "description": "The table it came from, for example Electrical Characteristics.", "type": "string" },
        "statistic": {
          "description": "The statistical form of the value, when a parameter is specified in more than one, so that a peak-to-peak figure and an RMS figure of the same quantity (for example reference output noise) are machine-distinguishable rather than differing only in a verbatim string. rms, peak_to_peak, and peak are the usual noise forms; mean is occasionally used.",
          "enum": ["rms", "peak_to_peak", "peak", "mean"]
        },
        "guarantee": {
          "description": "The datasheet's basis for the value, from the specification footnotes. production_tested is 100% tested in production (usually the bold min/max limits). by_design and by_characterization are ensured but not production-tested. typical is a typical value that is not a guaranteed limit. This is the guarantee basis, distinct from limitClass (which kind of limit) and from review/confidence (extraction trust).",
          "enum": ["production_tested", "by_design", "by_characterization", "typical"]
        },
        "review": {
          "description": "Extraction review state for this value, so a consumer can tell a machine-extracted number from a human-checked one. unchecked is raw extractor output; confirmed means a reviewer verified it against the page as-is; edited means a reviewer corrected it. Absent means not recorded. Advisory, like confidence: it is not the schema's verified flag.",
          "enum": ["unchecked", "confirmed", "edited"]
        },
        "confidence": {
          "description": "Advisory extraction confidence for this specific value, 0 to 1. Per-measurement companion to document-level provenance.confidence. MUST NOT be read as verification; see review for the checked/unchecked state.",
          "type": "number",
          "minimum": 0,
          "maximum": 1
        }
      },
      "allOf": [
        {
          "$comment": "A characterized value must cite its page. Absolute-maximum stress rows may lack test conditions.",
          "if": { "properties": { "limitClass": { "const": "characterized" } } },
          "then": { "required": ["sourcePage"] }
        }
      ]
    },

    "value": {
      "title": "Value",
      "description": "IEC 61360 level roles. nom is a nominal or target value, for example a fixed 3.3 V option. typ is a typical measured value. At least one role is present.",
      "type": "object",
      "additionalProperties": false,
      "minProperties": 1,
      "properties": {
        "min": { "type": "number" },
        "typ": { "type": "number" },
        "nom": { "type": "number" },
        "max": { "type": "number" }
      }
    },

    "conditionAxis": {
      "title": "Condition axis",
      "description": "One test-condition dimension. param uses a controlled vocabulary where possible, defined in the specification, but any string is allowed so family-specific axes extend it. Provide a scalar value, or a min and max range, or a note. A unit is required when a numeric value, min, or max is given, and is omitted for a note-only axis such as a package name or capacitor type.",
      "type": "object",
      "required": ["param"],
      "additionalProperties": false,
      "properties": {
        "param": {
          "description": "The condition dimension. Recommended vocabulary: T_J, T_A, V_IN, V_OUT, I_OUT, I_LOAD, F, C_OUT, C_IN, ESR, HEADROOM, RIPPLE, BW_LOW, BW_HIGH, V_EN, C_OUT_TYPE, PACKAGE, BOARD. Family-specific axes such as V_GS, V_DS, and F_SW are permitted.",
          "type": "string",
          "minLength": 1
        },
        "value": { "type": "number" },
        "min": { "type": "number" },
        "max": { "type": "number" },
        "unit": { "$ref": "#/$defs/unit" },
        "note": { "description": "Free text, for example a capacitor type such as X7R ceramic, or a package name.", "type": "string" }
      },
      "anyOf": [
        { "required": ["value"] },
        { "required": ["min"] },
        { "required": ["max"] },
        { "required": ["note"] }
      ],
      "allOf": [
        {
          "$comment": "A unit is required when the axis carries a number.",
          "if": { "anyOf": [{ "required": ["value"] }, { "required": ["min"] }, { "required": ["max"] }] },
          "then": { "required": ["unit"] }
        }
      ]
    },

    "stimulus": {
      "title": "Stimulus",
      "description": "An applied step for a dynamic measurement, for example I_OUT from 0 to 300 mA at 0.2 A/us.",
      "type": "object",
      "required": ["param", "from", "to", "unit"],
      "additionalProperties": false,
      "properties": {
        "param": { "description": "What is stepped, for example I_OUT or V_IN.", "type": "string" },
        "from": { "type": "number" },
        "to": { "type": "number" },
        "unit": { "$ref": "#/$defs/unit" },
        "slewRate": { "description": "Rate of the step.", "type": "number" },
        "slewUnit": { "description": "Unit of the slew rate, for example A/us or V/us.", "type": "string" }
      }
    },

    "provenance": {
      "title": "Provenance",
      "description": "The record of where every value in this document came from. It is what allows a specification to be verified rather than only asserted.",
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "datasheetSha256": { "description": "SHA-256 of the exact datasheet PDF bytes.", "type": "string", "pattern": "^[a-f0-9]{64}$" },
        "sourceUrl": { "description": "Where the datasheet was fetched from.", "type": "string", "format": "uri" },
        "datasheetRevision": { "description": "Revision string as printed, for example SBVS176K REVISED MARCH 2023.", "type": "string" },
        "publishedDate": { "type": "string" },
        "fetchedAt": { "type": "string", "format": "date-time" },
        "extractionMethod": { "description": "How the data was produced, for example manual or llm:claude-sonnet-4-5.", "type": "string" },
        "extractedAt": { "type": "string", "format": "date-time" },
        "confidence": { "description": "Extraction confidence from 0 to 1. Advisory only. It does not by itself imply the data is verified.", "type": "number", "minimum": 0, "maximum": 1 },
        "verified": { "description": "True only when the data passed a validation suite.", "type": "boolean" }
      }
    },

    "unit": {
      "title": "Unit",
      "description": "Base-SI unit symbol. Values are normalized to base units so cross-part numeric comparison is sound. Derived units are included where a datasheet parameter requires them, for example ppm/degC for temperature coefficient and V/us for slew rate. The fractional-rate family ppm, ppm/V, and ppm/A captures dimensionless drift (long-term stability, thermal hysteresis) and the per-volt/per-amp regulation rates that precision references and other parts specify, alongside ppm/degC.",
      "type": "string",
      "enum": [
        "V", "A", "Hz", "degC", "ohm", "F", "H", "s", "W", "C", "J", "S", "deg",
        "dB", "V/V", "%", "ppm", "ppm/degC", "ppm/V", "ppm/A", "V/degC", "A/degC", "degC/W", "K/W", "V/us", "A/us", "V/sqrtHz", "A/sqrtHz"
      ]
    }
  }
}
