{
  "$schema": "https://sous.pras.ai/schema/v0/domain.schema.json",
  "vocabulary": "equipment-classes",
  "version": "0.7.0",
  "description": "Capability classes for equipment. A Sous recipe references CLASSES, never device instances; a kitchen profile declares instances that provide classes. This is the ISA-88 separation of recipe from physical model, and it is what makes a recipe portable across kitchens.",
  "classes": {
    "vessel": {
      "label": "Vessel",
      "definition": "Anything that holds material.",
      "attributes": {
        "capacity": {
          "type": "quantity",
          "dimension": "volume",
          "required": true
        }
      },
      "aliases": [
        "bowl",
        "container",
        "jar",
        "jug",
        "mixing bowl",
        "pitcher"
      ]
    },
    "work_surface": {
      "label": "Work surface",
      "definition": "A flat surface for manipulation.",
      "attributes": {
        "area": {
          "type": "quantity",
          "dimension": "area"
        }
      },
      "aliases": [
        "cooling rack",
        "counter",
        "wire rack",
        "worktop"
      ]
    },
    "cutting_surface": {
      "label": "Cutting surface",
      "parent": "work_surface",
      "definition": "A board or surface safe for blade work. Carries cleanliness state for cross-contact rules.",
      "aliases": [
        "chopping board",
        "cutting board"
      ]
    },
    "heat_source": {
      "label": "Heat source",
      "definition": "Anything that raises material temperature.",
      "attributes": {
        "max_temperature": {
          "type": "quantity",
          "dimension": "temperature",
          "required": true
        },
        "controllable": {
          "type": "boolean",
          "default": true
        }
      }
    },
    "cold_source": {
      "label": "Cold source",
      "definition": "Refrigeration or freezing.",
      "attributes": {
        "min_temperature": {
          "type": "quantity",
          "dimension": "temperature",
          "required": true
        }
      }
    },
    "heated_vessel": {
      "label": "Heated vessel",
      "parents": [
        "vessel",
        "heat_source"
      ],
      "definition": "A vessel in direct contact with a heat source: pan, pot, wok, sauteuse.",
      "attributes": {
        "surface_area": {
          "type": "quantity",
          "dimension": "area",
          "required": true,
          "note": "Load-bearing: it is the capacity constraint that forces batched searing."
        },
        "lidded": {
          "type": "boolean",
          "default": false
        },
        "material": {
          "type": "enum",
          "values": [
            "stainless",
            "cast_iron",
            "carbon_steel",
            "nonstick",
            "copper",
            "aluminium",
            "clay",
            "enamel"
          ]
        },
        "thermal_mass": {
          "type": "enum",
          "values": [
            "low",
            "medium",
            "high"
          ],
          "note": "Determines recovery time after loading, and therefore how severe the batching constraint is."
        }
      },
      "aliases": [
        "casserole",
        "double boiler",
        "dutch oven",
        "frying pan",
        "griddle",
        "kettle",
        "pan",
        "pot",
        "saucepan",
        "saute pan",
        "sauté pan",
        "skillet",
        "stockpot",
        "wok"
      ]
    },
    "oven": {
      "label": "Oven",
      "parent": "heat_source",
      "definition": "Enclosed dry-heat cavity.",
      "attributes": {
        "cavity_volume": {
          "type": "quantity",
          "dimension": "volume"
        },
        "convection": {
          "type": "boolean",
          "default": false
        },
        "shelf_count": {
          "type": "integer",
          "default": 1
        }
      },
      "aliases": [
        "broiler",
        "grill oven"
      ]
    },
    "grill": {
      "label": "Grill / broiler",
      "parent": "heat_source",
      "definition": "Radiant heat from one side.",
      "attributes": {
        "heat_source_position": {
          "type": "enum",
          "values": [
            "above",
            "below",
            "both"
          ]
        }
      },
      "aliases": [
        "barbecue",
        "bbq",
        "grill pan"
      ]
    },
    "fryer": {
      "label": "Deep fryer",
      "parents": [
        "vessel",
        "heat_source"
      ],
      "attributes": {
        "oil_volume": {
          "type": "quantity",
          "dimension": "volume",
          "required": true
        }
      }
    },
    "steamer": {
      "label": "Steamer",
      "parents": [
        "vessel",
        "heat_source"
      ],
      "aliases": [
        "bamboo steamer",
        "steamer basket"
      ]
    },
    "grater": {
      "label": "Grater",
      "attributes": {
        "coarseness_options": {
          "type": "array",
          "items": "enum:fine,medium,coarse"
        }
      },
      "aliases": [
        "box grater",
        "microplane",
        "zester"
      ]
    },
    "grinder": {
      "label": "Grinder",
      "attributes": {
        "kind": {
          "type": "enum",
          "values": [
            "spice",
            "meat",
            "coffee",
            "burr",
            "mortar"
          ]
        }
      },
      "aliases": [
        "mortar and pestle",
        "pepper mill",
        "spice grinder"
      ]
    },
    "blender": {
      "label": "Blender / processor",
      "parent": "vessel",
      "attributes": {
        "heat_safe": {
          "type": "boolean",
          "default": false
        }
      },
      "aliases": [
        "food processor",
        "immersion blender",
        "liquidiser",
        "liquidizer"
      ]
    },
    "sieve": {
      "label": "Sieve / strainer",
      "attributes": {
        "mesh": {
          "type": "enum",
          "values": [
            "coarse",
            "medium",
            "fine",
            "superfine"
          ]
        }
      },
      "aliases": [
        "chinois",
        "colander",
        "sifter",
        "strainer"
      ]
    },
    "mixer": {
      "label": "Mixer",
      "parent": "vessel",
      "attributes": {
        "kind": {
          "type": "enum",
          "values": [
            "hand",
            "stand",
            "immersion"
          ]
        }
      },
      "aliases": [
        "electric mixer",
        "hand mixer",
        "stand mixer"
      ]
    },
    "serving_vessel": {
      "label": "Serving vessel",
      "parent": "vessel",
      "definition": "Plate, bowl, platter. Destination of `plate`.",
      "attributes": {
        "kind": {
          "type": "enum",
          "values": [
            "plate",
            "bowl",
            "platter",
            "board",
            "cup",
            "ramekin"
          ]
        }
      },
      "aliases": [
        "plate",
        "platter",
        "serving dish"
      ]
    },
    "bakeware": {
      "label": "Bakeware",
      "parent": "vessel",
      "definition": "Oven-safe form.",
      "attributes": {
        "kind": {
          "type": "enum",
          "values": [
            "loaf_pan",
            "sheet_pan",
            "cake_tin",
            "casserole",
            "muffin_tin",
            "pie_dish",
            "roasting_tin"
          ]
        },
        "dimensions": {
          "type": "dimension_set",
          "required": true,
          "note": "Load-bearing for physics: an 8x8 dish and a 9x13 dish at the same batter mass have different depths and therefore different bake times."
        }
      },
      "aliases": [
        "baking dish",
        "baking sheet",
        "baking tray",
        "cake pan",
        "cake tin",
        "cookie sheet",
        "loaf pan",
        "muffin tin",
        "pie dish",
        "pie pan",
        "ramekin",
        "roasting pan",
        "tart pan"
      ]
    },
    "probe": {
      "label": "Temperature probe",
      "definition": "Provides the internal_temperature observable. Required by the Executable profile for any recipe with a hazardous-food control point.",
      "aliases": [
        "instant-read thermometer",
        "meat thermometer",
        "thermometer"
      ]
    },
    "scale": {
      "label": "Scale",
      "definition": "Provides the mass observable."
    },
    "timer": {
      "label": "Timer",
      "definition": "Provides the elapsed observable."
    },
    "camera": {
      "label": "Camera",
      "definition": "Provides the browning, volume and appearance observables. This is what makes 'until golden brown' machine-checkable."
    },
    "wrapping": {
      "label": "Wrapping",
      "definition": "Foil, parchment, leaf, string. Enables the `wrapped` containment value and bundle sub-assemblies such as a bouquet garni.",
      "aliases": [
        "aluminium foil",
        "aluminum foil",
        "cling film",
        "paper towel",
        "parchment paper",
        "plastic wrap",
        "wax paper"
      ]
    },
    "pressure_cooker": {
      "label": "Pressure cooker",
      "definition": "A sealable vessel that cooks above atmospheric pressure.",
      "parents": [
        "heated_vessel"
      ],
      "attributes": {
        "capacity": {
          "type": "quantity",
          "dimension": "volume"
        },
        "max_pressure": {
          "type": "quantity",
          "dimension": "pressure"
        }
      },
      "aliases": [
        "pressure cooker",
        "instant pot",
        "pressure pan"
      ]
    }
  },
  "observables": {
    "note": "What can be measured, and by what. A termination condition is only machine-checkable if the kitchen provides an instrument for its observable.",
    "values": {
      "elapsed": {
        "instrument": "timer",
        "machine_checkable": true
      },
      "internal_temperature": {
        "instrument": "probe",
        "machine_checkable": true
      },
      "equipment_temperature": {
        "instrument": "probe",
        "machine_checkable": true
      },
      "oil_temperature": {
        "instrument": "probe",
        "machine_checkable": true
      },
      "mass": {
        "instrument": "scale",
        "machine_checkable": true
      },
      "browning": {
        "instrument": "camera",
        "machine_checkable": true,
        "note": "Vision-language models detect food-state change in practice; see ADR 0003."
      },
      "volume": {
        "instrument": "camera",
        "machine_checkable": true
      },
      "appearance": {
        "instrument": "camera",
        "machine_checkable": true
      },
      "form": {
        "instrument": "camera",
        "machine_checkable": true
      },
      "dimension": {
        "instrument": "camera",
        "machine_checkable": true
      },
      "containment": {
        "instrument": "camera",
        "machine_checkable": true
      },
      "cleanliness": {
        "instrument": "camera",
        "machine_checkable": true
      },
      "surface": {
        "instrument": "camera",
        "machine_checkable": true
      },
      "affordances": {
        "instrument": "camera",
        "machine_checkable": true,
        "note": "Whether a material is still peelable, shellable and so on is largely visible. Derived state; observing it verifies the derivation."
      },
      "structure": {
        "instrument": "camera",
        "machine_checkable": false
      },
      "rolling_boil": {
        "instrument": "camera",
        "machine_checkable": true
      },
      "surface_movement": {
        "instrument": "camera",
        "machine_checkable": true
      },
      "surface_scum": {
        "instrument": "camera",
        "machine_checkable": true
      },
      "vessel_surface": {
        "instrument": "camera",
        "machine_checkable": true
      },
      "viscosity": {
        "instrument": null,
        "machine_checkable": false
      },
      "texture": {
        "instrument": null,
        "machine_checkable": false,
        "note": "Probe force sensing exists but is not standard kitchen equipment."
      },
      "taste": {
        "instrument": null,
        "machine_checkable": false,
        "requires_human": true
      },
      "aroma": {
        "instrument": null,
        "machine_checkable": false,
        "requires_human": true
      },
      "ph": {
        "instrument": null,
        "machine_checkable": false
      },
      "colour": {
        "instrument": "camera",
        "machine_checkable": true
      },
      "hydration": {
        "instrument": "camera",
        "machine_checkable": true,
        "note": "Surface wetness is visually detectable; interior moisture is not."
      },
      "pressure": {
        "instrument": "pressure_gauge",
        "machine_checkable": true
      }
    }
  },
  "hazards": {
    "values": {
      "blade": {
        "severity": "moderate"
      },
      "hot_surface": {
        "severity": "moderate"
      },
      "hot_liquid": {
        "severity": "moderate"
      },
      "hot_oil": {
        "severity": "high",
        "note": "Water entering hot oil boils violently. See the deep_fry precondition."
      },
      "steam": {
        "severity": "moderate"
      },
      "spatter": {
        "severity": "low"
      },
      "fire": {
        "severity": "high"
      },
      "flare_up": {
        "severity": "high"
      },
      "smoke": {
        "severity": "low"
      },
      "scorching": {
        "severity": "low"
      },
      "burns": {
        "severity": "moderate"
      },
      "spill": {
        "severity": "low"
      },
      "alcohol_vapour": {
        "severity": "high",
        "note": "Deglazing with spirits near an open flame can ignite."
      },
      "pressure": {
        "severity": "high"
      },
      "hot_splash": {
        "severity": "high",
        "note": "Hot liquid in a sealed blender expands rapidly and can force the lid off. Distinct from `spatter`, which is incidental."
      }
    }
  }
}
