{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://mass-ledger.local/schema/ledger.schema.json",
  "title": "Life-support mass ledger v0.1.0",
  "description": "Frozen Day-1 tick/receipt schema (schema_version const 0.1.0). Day-2a additive stores live in ledger.schema.0.2.0.json. Do not rewrite historical Day-1 schema_version fields.",
  "$defs": {
    "species_vector": {
      "type": "object",
      "required": [
        "O2",
        "CO2",
        "H2O"
      ],
      "properties": {
        "O2": {
          "type": "number"
        },
        "CO2": {
          "type": "number"
        },
        "H2O": {
          "type": "number"
        }
      },
      "additionalProperties": false
    },
    "residual_vector": {
      "type": "object",
      "required": [
        "O2",
        "CO2",
        "H2O",
        "total"
      ],
      "properties": {
        "O2": {
          "type": "number"
        },
        "CO2": {
          "type": "number"
        },
        "H2O": {
          "type": "number"
        },
        "total": {
          "type": "number"
        }
      },
      "additionalProperties": false
    },
    "stores_kg": {
      "type": "object",
      "required": [
        "cabin_O2",
        "cabin_CO2",
        "cabin_H2O",
        "O2_buffer",
        "H2O_tank"
      ],
      "properties": {
        "cabin_O2": {
          "type": "number"
        },
        "cabin_CO2": {
          "type": "number"
        },
        "cabin_H2O": {
          "type": "number"
        },
        "O2_buffer": {
          "type": "number"
        },
        "H2O_tank": {
          "type": "number"
        }
      },
      "additionalProperties": false
    },
    "tick": {
      "type": "object",
      "required": [
        "schema_version",
        "t",
        "dt_s",
        "scenario_id",
        "scenario_hash",
        "inputs_hash",
        "species_kg",
        "stores_kg",
        "flows_kg_s",
        "power_W",
        "balance_residual_kg",
        "epsilon_kg",
        "status",
        "receipt_id"
      ],
      "properties": {
        "schema_version": {
          "const": "0.1.0"
        },
        "t": {
          "type": "integer",
          "minimum": 0
        },
        "dt_s": {
          "type": "number",
          "exclusiveMinimum": 0
        },
        "scenario_id": {
          "type": "string",
          "minLength": 1
        },
        "scenario_hash": {
          "type": "string",
          "minLength": 64,
          "maxLength": 64
        },
        "inputs_hash": {
          "type": "string",
          "minLength": 64,
          "maxLength": 64
        },
        "species_kg": {
          "$ref": "#/$defs/species_vector"
        },
        "stores_kg": {
          "$ref": "#/$defs/stores_kg"
        },
        "flows_kg_s": {
          "type": "object",
          "additionalProperties": {
            "type": "number"
          }
        },
        "power_W": {
          "type": "number"
        },
        "balance_residual_kg": {
          "$ref": "#/$defs/residual_vector"
        },
        "epsilon_kg": {
          "const": 1e-06
        },
        "status": {
          "enum": [
            "ok",
            "alarm"
          ]
        },
        "receipt_id": {
          "type": [
            "string",
            "null"
          ]
        }
      },
      "additionalProperties": false
    },
    "receipt": {
      "type": "object",
      "required": [
        "schema_version",
        "id",
        "t",
        "scenario_id",
        "scenario_hash",
        "inputs_hash",
        "status",
        "residual_kg",
        "violated_species",
        "fault",
        "message",
        "tick_ref",
        "created_at"
      ],
      "properties": {
        "schema_version": {
          "const": "0.1.0"
        },
        "id": {
          "type": "string",
          "pattern": "^rcpt_[a-f0-9]+$"
        },
        "t": {
          "type": "integer",
          "minimum": 0
        },
        "scenario_id": {
          "type": "string",
          "minLength": 1
        },
        "scenario_hash": {
          "type": "string",
          "minLength": 64,
          "maxLength": 64
        },
        "inputs_hash": {
          "type": "string",
          "minLength": 64,
          "maxLength": 64
        },
        "status": {
          "const": "alarm"
        },
        "residual_kg": {
          "$ref": "#/$defs/residual_vector"
        },
        "violated_species": {
          "type": "array",
          "minItems": 1,
          "items": {
            "enum": [
              "O2",
              "CO2",
              "H2O",
              "total"
            ]
          }
        },
        "fault": {
          "type": "string",
          "minLength": 1
        },
        "message": {
          "type": "string",
          "minLength": 1
        },
        "tick_ref": {
          "type": "string",
          "minLength": 1
        },
        "created_at": {
          "type": "string",
          "minLength": 1
        }
      },
      "additionalProperties": false
    }
  },
  "oneOf": [
    {
      "$ref": "#/$defs/tick"
    },
    {
      "$ref": "#/$defs/receipt"
    }
  ]
}
