{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://wetwareworld.com/schema/wwd/0.1/results.schema.json",
  "title": "WWD 0.1 results document",
  "description": "As-built evidence: measured results linked to immutable acceptance criteria, plus lineage. Presence of this document is what makes a package as-built; there is no mode flag.",
  "type": "object",
  "required": ["realization", "measured_results"],

  "properties": {
    "realization": {
      "type": "object",
      "required": ["id", "design_revision"],
      "properties": {
        "id": { "type": "string", "minLength": 1 },
        "scheme": { "enum": ["local", "gs1.gtin", "gs1.lot", "isbt128.din",
                             "isbt128.coi", "vendor.lot"] },
        "design_revision": {
          "type": "string",
          "$comment": "An as-built realization must pin the exact design revision it realizes."
        },
        "manufactured": { "type": "string", "format": "date" },
        "lot": { "type": "string" }
      }
    },

    "context": {
      "type": "array",
      "items": {
        "type": "object",
        "required": ["property", "value", "causal_role", "provenance"],
        "properties": {
          "property": { "type": "string" },
          "value": {},
          "causal_role": { "const": "context" },
          "provenance": { "enum": ["measured", "inferred", "assumed"] }
        }
      },
      "$comment": "Covariates: donor, passage on arrival, transit excursions, lot-to-lot variation. Not interventions, and not responses to your intervention."
    },

    "measured_results": {
      "type": "array",
      "items": { "$ref": "#/$defs/result" }
    },

    "yield": {
      "type": "object",
      "required": ["criterion", "units_tested", "units_meeting"],
      "properties": {
        "criterion": { "$ref": "#/$defs/uuid" },
        "units_tested": { "type": "integer", "minimum": 1 },
        "units_meeting": { "type": "integer", "minimum": 0 }
      },
      "$comment": "For an emergent outcome, 'median >= X' is only half a specification; the other half is 'in >= Y% of units'."
    },

    "simulation_results": {
      "type": "array",
      "items": { "$ref": "#/$defs/simulation_result" }
    },

    "provenance": { "$ref": "#/$defs/prov_graph" },

    "disposition": {
      "not": {},
      "$comment": "Lot disposition is DERIVED from criteria, results and release policy. Storing it as an independent fact makes it unauditable."
    }
  },

  "$defs": {

    "uuid": {
      "type": "string",
      "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$"
    },

    "result": {
      "type": "object",
      "required": ["id", "criterion", "status", "provenance", "causal_role",
                   "observation_activity"],
      "properties": {
        "id": { "type": "string", "minLength": 1 },
        "criterion": {
          "$ref": "#/$defs/uuid",
          "$comment": "Exactly one. A dangling reference is a hard error."
        },
        "status": { "enum": ["pass", "fail", "marginal", "not_evaluated"] },
        "value": {},
        "unit": { "type": "string" },
        "statistic": {
          "enum": ["value", "mean", "median", "sd", "cv", "proportion",
                   "count", "min", "max", "yield"]
        },
        "n_observed": { "type": "integer", "minimum": 0 },
        "provenance": {
          "const": "measured",
          "$comment": "A simulated value may not sit in measured_results. Put it in simulation_results linked to its run."
        },
        "causal_role": {
          "enum": ["control", "response"],
          "$comment": "control = process-compliance evidence (what was actually imposed). response = outcome evidence (what the biology delivered)."
        },
        "timestamp": { "type": "string", "format": "date-time" },
        "observation_activity": { "type": "string", "minLength": 1 },
        "specimens": { "type": "array", "items": { "type": "string" } },
        "raw_data": { "type": "string" },
        "instrument": {
          "type": "object",
          "properties": {
            "id": { "type": "string" },
            "description": { "type": "string" },
            "calibration_ref": { "type": "string" }
          }
        },
        "operator": { "type": "string" },
        "uncertainty": {
          "type": "object",
          "properties": {
            "kind": { "enum": ["stddev", "standard_uncertainty", "relative",
                               "confidence_interval"] },
            "value": { "type": "number" },
            "low": { "type": "number" },
            "high": { "type": "number" }
          }
        },
        "computed_by": {
          "type": "object",
          "properties": {
            "software": { "type": "string" },
            "algorithm": { "type": "string" },
            "decision": { "type": "string" },
            "standard": { "type": "string" }
          },
          "$comment": "A derived statistic must be traceable to raw rows and an algorithm version."
        },
        "supersedes": { "type": "string" },
        "retest_of": { "type": "string" }
      }
    },

    "simulation_result": {
      "type": "object",
      "required": ["id", "run", "provenance", "quantity", "unit"],
      "properties": {
        "id": { "type": "string" },
        "run": { "type": "string" },
        "provenance": { "const": "simulated" },
        "causal_role": { "const": "response" },
        "quantity": { "type": "string" },
        "unit": { "type": "string" },
        "value": {},
        "field": { "type": "string" },
        "design_revision": { "type": "string" },
        "input_digests": {
          "type": "array",
          "items": { "type": "string" },
          "$comment": "If a referenced design revision or input digest has changed, the result is stale and must not be presented as current evidence."
        },
        "compares_to_criterion": {
          "$ref": "#/$defs/uuid",
          "$comment": "A simulation assessment, not an acceptance result."
        }
      }
    },

    "prov_graph": {
      "type": "object",
      "properties": {
        "entities": {
          "type": "array",
          "items": {
            "type": "object",
            "required": ["id", "type"],
            "properties": {
              "id": { "type": "string" },
              "type": { "type": "string" },
              "role": { "type": "string" },
              "derived_from": {
                "oneOf": [
                  { "type": "string" },
                  { "type": "array", "items": { "type": "string" } }
                ],
                "$comment": "prov:wasDerivedFrom. Pooling and splitting are real; do not model genealogy as a single chain when it was not."
              },
              "external_id": {
                "type": "object",
                "required": ["scheme", "value"],
                "properties": {
                  "scheme": { "type": "string" },
                  "value": { "type": "string" }
                }
              }
            }
          }
        },
        "activities": {
          "type": "array",
          "items": {
            "type": "object",
            "required": ["id", "type"],
            "properties": {
              "id": { "type": "string" },
              "type": { "type": "string" },
              "used": { "type": "array", "items": { "type": "string" } },
              "generated": { "type": "array", "items": { "type": "string" } },
              "started": { "type": "string", "format": "date-time" },
              "ended": { "type": "string", "format": "date-time" },
              "associated_with": { "type": "array", "items": { "type": "string" } },
              "protocol_ref": { "type": "string" }
            }
          }
        },
        "agents": {
          "type": "array",
          "items": {
            "type": "object",
            "required": ["id", "type"],
            "properties": {
              "id": { "type": "string" },
              "type": { "enum": ["person", "organization", "software", "instrument"] },
              "name": { "type": "string" },
              "on_behalf_of": { "type": "string" }
            }
          }
        }
      },
      "$comment": "Core relations map 1:1 onto PROV-O so an exporter needs no semantic guesswork."
    }
  }
}
