{
  "registry_schema": "SENSORY-REGISTRY",
  "registry_version": "1.0",
  "applies_to": {
    "s_code": "1.0",
    "iso_taste": "1.0"
  },
  "units": [
    {
      "token": "1",
      "quantity": "dimensionless",
      "label": "dimensionless"
    },
    {
      "token": "%",
      "quantity": "ratio",
      "label": "percent"
    },
    {
      "token": "Pa",
      "quantity": "pressure",
      "label": "pascal"
    },
    {
      "token": "kPa",
      "quantity": "pressure",
      "label": "kilopascal"
    },
    {
      "token": "N",
      "quantity": "force",
      "label": "newton"
    },
    {
      "token": "°C",
      "quantity": "temperature",
      "label": "degree Celsius"
    },
    {
      "token": "s",
      "quantity": "time",
      "label": "second"
    },
    {
      "token": "ms",
      "quantity": "time",
      "label": "millisecond"
    },
    {
      "token": "Hz",
      "quantity": "frequency",
      "label": "hertz"
    },
    {
      "token": "dB",
      "quantity": "level",
      "label": "decibel"
    },
    {
      "token": "Pa·s",
      "quantity": "dynamic_viscosity",
      "label": "pascal second"
    }
  ],
  "temporal_vocabulary": [
    {
      "code": "pre-entry",
      "order": 10,
      "meaning": "before first oral or sensory contact"
    },
    {
      "code": "entry",
      "order": 20,
      "meaning": "initial entry or presentation"
    },
    {
      "code": "initial-contact",
      "order": 30,
      "meaning": "first physical contact"
    },
    {
      "code": "chewing",
      "order": 40,
      "meaning": "active chewing or mechanical processing"
    },
    {
      "code": "chewing-to-aftertaste",
      "order": 45,
      "meaning": "span from chewing through emerging aftertaste"
    },
    {
      "code": "swallow",
      "order": 50,
      "meaning": "swallow transition"
    },
    {
      "code": "post-swallow",
      "order": 60,
      "meaning": "immediately after swallow"
    },
    {
      "code": "aftertaste",
      "order": 70,
      "meaning": "lingering post-consumption sensory phase"
    },
    {
      "code": "thermal-transition",
      "order": 80,
      "meaning": "temperature-driven transition independent of oral phase"
    },
    {
      "code": "release",
      "order": 90,
      "meaning": "release curve or emission phase"
    },
    {
      "code": "decay",
      "order": 100,
      "meaning": "declining sensory signal"
    },
    {
      "code": "serving",
      "order": 110,
      "meaning": "serving or presentation condition"
    },
    {
      "code": "custom",
      "order": 999,
      "meaning": "explicit custom phase; custom_time_context is required"
    }
  ],
  "descriptor_namespaces": [
    {
      "family": "T",
      "namespace": "taste",
      "ref_prefix": "SENSORY-DESC:T"
    },
    {
      "family": "O",
      "namespace": "olfaction",
      "ref_prefix": "SENSORY-DESC:O"
    },
    {
      "family": "X",
      "namespace": "texture",
      "ref_prefix": "SENSORY-DESC:X"
    },
    {
      "family": "M",
      "namespace": "mouthfeel",
      "ref_prefix": "SENSORY-DESC:M"
    },
    {
      "family": "P",
      "namespace": "trigeminal",
      "ref_prefix": "SENSORY-DESC:P"
    },
    {
      "family": "H",
      "namespace": "thermal",
      "ref_prefix": "SENSORY-DESC:H"
    },
    {
      "family": "A",
      "namespace": "acoustics",
      "ref_prefix": "SENSORY-DESC:A"
    },
    {
      "family": "V",
      "namespace": "variation",
      "ref_prefix": "SENSORY-DESC:V"
    }
  ],
  "descriptors": [
    {
      "id": "SENSORY-DESC:T:umami@1.0",
      "family": "T",
      "label": "umami",
      "status": "active"
    },
    {
      "id": "SENSORY-DESC:T:msg-concentration@1.0",
      "family": "T",
      "label": "monosodium glutamate concentration",
      "status": "active"
    },
    {
      "id": "SENSORY-DESC:O:roasted-poultry-fat-aroma@1.0",
      "family": "O",
      "label": "roasted poultry / fat aroma",
      "status": "active"
    },
    {
      "id": "SENSORY-DESC:X:fiber-elastic-modulus@1.0",
      "family": "X",
      "label": "fiber elastic modulus",
      "status": "active"
    },
    {
      "id": "SENSORY-DESC:M:viscosity@1.0",
      "family": "M",
      "label": "viscosity",
      "status": "active"
    },
    {
      "id": "SENSORY-DESC:P:pungency@1.0",
      "family": "P",
      "label": "pungency",
      "status": "active"
    },
    {
      "id": "SENSORY-DESC:H:fat-melting-point@1.0",
      "family": "H",
      "label": "fat melting point",
      "status": "active"
    },
    {
      "id": "SENSORY-DESC:A:crunch@1.0",
      "family": "A",
      "label": "crunch",
      "status": "active"
    },
    {
      "id": "SENSORY-DESC:V:batch-variation@1.0",
      "family": "V",
      "label": "batch variation",
      "status": "active"
    }
  ],
  "descriptor_policy": {
    "free_text_descriptor_allowed": true,
    "descriptor_ref_optional": true,
    "rule": "Free text may describe a sensory event, but only a descriptor_ref that resolves in this registry may claim controlled vocabulary identity."
  },
  "structural_code": {
    "format": "ISO-TASTE:<semantic.path>@<major.minor>",
    "pattern": "^ISO-TASTE:[a-z0-9]+(?:\\.[a-z0-9-]+)+@[0-9]+\\.[0-9]+$",
    "segments": [
      "authority",
      "semantic_path",
      "version"
    ],
    "rule": "Structural codes are semantic, versioned, immutable identifiers. A public short code is an alias for human use and does not replace the structural code.",
    "example": "ISO-TASTE:reference.food.synthetic-chicken@1.0"
  },
  "lifecycle": {
    "states": [
      "active",
      "deprecated",
      "retired",
      "reserved"
    ],
    "rules": [
      "Assigned public and structural codes are immutable and are never reused for a different identity.",
      "Deprecated codes remain resolvable and may declare a replacement.",
      "Retired codes remain resolvable for historical data but are not valid for new assignments.",
      "Reserved codes may not appear as active reference identities.",
      "Aliases must resolve to exactly one canonical registry entry.",
      "Replacement chains must not contain cycles."
    ]
  },
  "code_registry": [
    {
      "public_code": "C-772",
      "structural_code": "ISO-TASTE:reference.food.synthetic-chicken@1.0",
      "canonical_name": "Plato's Chicken / synthetic chicken",
      "status": "active",
      "issued_version": "1.0",
      "aliases": [],
      "deprecated_in": null,
      "replaced_by": null
    }
  ],
  "migration_policy": {
    "status_values": [
      "none_required",
      "lossless",
      "lossy",
      "unsupported"
    ],
    "rules": [
      "New fields are never backfilled as though they existed in an older source record.",
      "A migration record must declare source_version, target_version, status, and registry_version.",
      "lossy migration must identify dropped or semantically changed fields.",
      "unsupported migration must not emit a conforming target-version packet.",
      "Rights, provenance, measurement status, and conformance status must never be upgraded by migration."
    ],
    "records": [
      {
        "migration_id": "SENSORY-MIGRATION-1.0-TO-1.0",
        "source_version": "1.0",
        "target_version": "1.0",
        "registry_version": "1.0",
        "status": "none_required",
        "preserved_semantics": true
      }
    ]
  }
}
