{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://sous.pras.ai/schema/v0/common/state.schema.json",
  "title": "Sous state facets",
  "description": "A state is a PARTIAL assignment over orthogonal facets: any facet may be omitted, meaning the recipe does not constrain it. Enums are generated from vocab/state-facets.json by tools/sous_build_schema.py -- edit the vocabulary, not this file.",
  "$comment": "GENERATED FILE. Run tools/sous_build_schema.py after editing vocab/state-facets.json.",
  "$defs": {
    "MaterialState": {
      "title": "Material state",
      "type": "object",
      "properties": {
        "form": {
          "title": "Form",
          "description": "Geometric subdivision of the material. Ranked by decreasing characteristic particle size; equal ranks are shape variants at comparable scale.",
          "type": "string",
          "enum": [
            "whole",
            "halved",
            "quartered",
            "chunked",
            "sliced",
            "julienned",
            "shredded",
            "grated",
            "chopped",
            "cubed",
            "diced",
            "minced",
            "ground",
            "mashed",
            "pureed",
            "liquid"
          ],
          "default": "whole",
          "$comment": "Ordered facet; rank order is whole < halved < quartered < chunked < sliced < julienned < shredded < grated < chopped < cubed < diced < minced < ground < mashed < pureed < liquid Monotone: no operation may lower this facet's rank."
        },
        "thermal": {
          "title": "Thermal state",
          "description": "Coarse temperature band. A precise temperature is carried as a quantity annotation, not as a facet value (see ADR 0003 constraint 3).",
          "type": "string",
          "enum": [
            "frozen",
            "chilled",
            "cool",
            "ambient",
            "warm",
            "hot",
            "very_hot"
          ],
          "default": "ambient",
          "$comment": "Ordered facet; rank order is frozen < chilled < cool < ambient < warm < hot < very_hot"
        },
        "doneness": {
          "title": "Doneness (interior)",
          "description": "Degree to which the INTERIOR of the material is cooked. Deliberately separate from `browning`, which is a surface property: a seared steak is browning=deep_brown, doneness=raw. Observed by probe or by cut-and-inspect, not by camera.",
          "type": "string",
          "enum": [
            "raw",
            "blanched",
            "par_cooked",
            "cooked_through",
            "well_done",
            "overcooked"
          ],
          "default": "raw",
          "$comment": "Ordered facet; rank order is raw < blanched < par_cooked < cooked_through < well_done < overcooked Monotone: no operation may lower this facet's rank."
        },
        "browning": {
          "title": "Browning (surface)",
          "description": "Maillard and caramelisation state of the SURFACE. Machine-observable by camera; this is what recipe phrases like 'until golden brown' refer to.",
          "type": "string",
          "enum": [
            "none",
            "pale",
            "golden",
            "golden_brown",
            "deep_brown",
            "caramelized",
            "charred"
          ],
          "default": "none",
          "$comment": "Ordered facet; rank order is none < pale < golden < golden_brown < deep_brown < caramelized < charred Monotone: no operation may lower this facet's rank."
        },
        "hydration": {
          "title": "Hydration",
          "description": "Moisture state of the material or its immediate surroundings.",
          "type": "string",
          "enum": [
            "desiccated",
            "dry",
            "drained",
            "moist",
            "wet",
            "soaked",
            "submerged"
          ],
          "default": "moist",
          "$comment": "Ordered facet; rank order is desiccated < dry < drained < moist < wet < soaked < submerged"
        },
        "texture": {
          "title": "Texture (firmness)",
          "description": "Firmness scale, observable by probe force or manual test. Ordered from hardest to softest.",
          "type": "string",
          "enum": [
            "hard",
            "firm",
            "crisp",
            "al_dente",
            "tender",
            "soft",
            "mushy"
          ],
          "$comment": "Ordered facet; rank order is hard < firm < crisp < al_dente < tender < soft < mushy"
        },
        "structure": {
          "title": "Structure",
          "description": "Independently achievable structural properties. Multi-valued: a batter can be simultaneously aerated and homogeneous.",
          "type": "array",
          "items": {
            "type": "string",
            "enum": [
              "homogeneous",
              "aerated",
              "emulsified",
              "risen",
              "kneaded",
              "gelled",
              "set",
              "layered",
              "curdled",
              "separated"
            ]
          },
          "uniqueItems": true
        },
        "surface": {
          "title": "Surface treatment",
          "description": "What has been applied to the exterior. Multi-valued: a cutlet can be seasoned, floured and breaded at once.",
          "type": "array",
          "items": {
            "type": "string",
            "enum": [
              "seasoned",
              "salted",
              "oiled",
              "floured",
              "breaded",
              "battered",
              "coated",
              "glazed",
              "marinated",
              "buttered",
              "greased"
            ]
          },
          "uniqueItems": true
        },
        "affordances": {
          "title": "Affordances",
          "description": "What can usefully be done to this material right now. Culinary, not mechanical: a blade passes through an unpeeled onion, but the result is not usable onion, so a raw onion is peelable and NOT cuttable. Derived from the substance's default state plus the operations applied; never authored on a material. Absence of an affordance means the operation would not yield a usable result -- it NEVER means the operation was already performed. A liquid is not siftable and has not been sifted; the positive record of what was done lives on substance identity (see core-ingredients.json `produced_by`).",
          "type": "array",
          "items": {
            "type": "string",
            "enum": [
              "cuttable",
              "peelable",
              "shellable",
              "huskable",
              "corable",
              "deseedable",
              "destemmable",
              "deboneable",
              "deveinable",
              "descaleable",
              "guttable",
              "skinnable",
              "trimmable",
              "juiceable",
              "zestable",
              "siftable",
              "strainable"
            ]
          },
          "uniqueItems": true,
          "$comment": "Monotone: no operation may lower this facet's rank."
        },
        "containment": {
          "title": "Containment",
          "description": "Where the material currently is. Parametric on an equipment instance id.",
          "oneOf": [
            {
              "type": "string",
              "enum": [
                "unplaced",
                "in",
                "on",
                "wrapped"
              ]
            },
            {
              "type": "object",
              "properties": {
                "value": {
                  "type": "string",
                  "enum": [
                    "unplaced",
                    "in",
                    "on",
                    "wrapped"
                  ]
                },
                "equipment": {
                  "$ref": "identifier.schema.json#/$defs/LocalId"
                }
              },
              "required": [
                "value",
                "equipment"
              ],
              "additionalProperties": false
            }
          ]
        }
      },
      "additionalProperties": false
    },
    "EquipmentState": {
      "title": "Equipment state",
      "type": "object",
      "properties": {
        "cleanliness": {
          "title": "Cleanliness",
          "description": "Contamination state. The basis for cross-contact constraints; see docs/spec/SAFETY.md.",
          "type": "string",
          "enum": [
            "clean",
            "soiled",
            "contaminated"
          ],
          "default": "clean",
          "$comment": "Ordered facet; rank order is clean < soiled < contaminated"
        },
        "residue": {
          "title": "Residue",
          "description": "What the vessel retains from prior operations. Multi-valued. `fond` is load-bearing: it is why 'add the onions to the same pot' after searing is a culinary instruction and not a convenience.",
          "type": "array",
          "items": {
            "type": "string",
            "enum": [
              "fond",
              "fat",
              "liquid",
              "crumb"
            ]
          },
          "uniqueItems": true
        },
        "thermal": {
          "title": "Thermal state",
          "description": "Same scale as the material `thermal` facet.",
          "type": "string",
          "enum": [
            "frozen",
            "chilled",
            "cool",
            "ambient",
            "warm",
            "hot",
            "very_hot"
          ],
          "default": "ambient",
          "$comment": "Ordered facet; rank order is frozen < chilled < cool < ambient < warm < hot < very_hot"
        },
        "power": {
          "title": "Power state",
          "description": "Control state of a powered appliance.",
          "type": "string",
          "enum": [
            "off",
            "preheating",
            "at_setpoint",
            "on"
          ],
          "default": "off"
        },
        "occupancy": {
          "title": "Occupancy",
          "description": "Whether the equipment currently holds material. Derived from material `containment`; declared so a scheduler can reason about resource contention without traversing every material.",
          "type": "string",
          "enum": [
            "empty",
            "occupied"
          ],
          "default": "empty"
        }
      },
      "additionalProperties": false
    }
  }
}
