Housings#

How to describe cell housings: a housing-spec is the case set as a product (a CR2032 kit: case, cap, spring, spacer), a housing instance is one physical batch. A cell references it through housing_spec_id, or describes its housing inline.

  • The spec is the case set as a product (case, cap, terminals, seals, parts); an instance is one physical batch.

  • The record is the enclosure ASSEMBLY - the case is one part among cap, terminals, seals, and hardware, all listed uniformly under hasConstituent in JSON-LD; cell_format picks the case class (CoinCase, CylindricalCase, …).

  • parts[] entries type as their EMMO classes (Spring, Spacer, Gasket, SafetyVent, …).

  • Author with create_housing_spec(...) / create_housing(spec_id=...).

Define one#

The product#

from battinfo.api import create_housing_spec

record = create_housing_spec(
    uid="w2n8-6rkt-4mpv-8hcq",
    name="CR2032 coin housing",
    cell_format="coin",
    case={
        "size_code": "2032",
        "material": "Stainless steel",
        "property": {
            "diameter": {"value": 20, "unit": "mm"},
            "height": {"value": 3.2, "unit": "mm"},
        },
    },
    parts=[
        {"type": "spring", "material": "Stainless steel"},
        {"type": "spacer", "material": "Stainless steel"},
    ],
    source_type="datasheet",
)
{
  "schema_version": "0.2.0",
  "housing_spec": {
    "id": "https://w3id.org/battinfo/spec/7d9k-2m4p-8t3x-6nq5",
    "short_id": "7d9k2m",
    "name": "CR2032 coin housing",
    "cell_format": "coin",
    "case": {
      "size_code": "2032",
      "material": "Stainless steel",
      "property": {
        "diameter": {
          "value": 20,
          "unit": "mm"
        },
        "height": {
          "value": 3.2,
          "unit": "mm"
        }
      }
    },
    "parts": [
      {
        "type": "spring",
        "material": "Stainless steel"
      },
      {
        "type": "spacer",
        "material": "Stainless steel"
      }
    ]
  },
  "provenance": {
    "source_type": "datasheet",
    "retrieved_at": 1750000000,
    "battinfo_version": "0.7.0"
  }
}

Emitted by record_to_jsonld, hosted-context mode.

{
  "@context": [
    "https://w3id.org/emmo/domain/battery/context",
    {
      "schema": "https://schema.org/",
      "dcterms": "http://purl.org/dc/terms/",
      "battinfo": "https://w3id.org/battinfo/"
    }
  ],
  "@type": [
    "Description",
    "schema:ProductModel",
    "schema:CreativeWork"
  ],
  "isDescriptionFor": {
    "@type": [
      "ElectrochemicalComponent",
      "schema:Product"
    ],
    "hasConstituent": [
      {
        "@type": "CoinCase",
        "schema:size": "2032",
        "schema:material": "Stainless steel",
        "hasProperty": [
          {
            "@type": [
              "Diameter",
              "ConventionalProperty"
            ],
            "skos:prefLabel": "Diameter",
            "hasNumericalPart": {
              "@type": "RealData",
              "hasNumberValue": 20
            },
            "hasMeasurementUnit": "https://w3id.org/emmo#MilliMetre"
          },
          {
            "@type": [
              "Height",
              "ConventionalProperty"
            ],
            "skos:prefLabel": "Height",
            "hasNumericalPart": {
              "@type": "RealData",
              "hasNumberValue": 3.2
            },
            "hasMeasurementUnit": "https://w3id.org/emmo#MilliMetre"
          }
        ]
      },
      {
        "@type": "Spring",
        "schema:material": "Stainless steel"
      },
      {
        "@type": "Spacer",
        "schema:material": "Stainless steel"
      }
    ],
    "skos:prefLabel": "CR2032 coin housing",
    "@id": "https://w3id.org/battinfo/spec/7d9k-2m4p-8t3x-6nq5#described"
  },
  "@id": "https://w3id.org/battinfo/spec/7d9k-2m4p-8t3x-6nq5",
  "schema:name": "CR2032 coin housing"
}

A physical batch#

from battinfo.api import create_housing

record = create_housing(
    uid="x4fm-9tpk-2wqv-5nrh",
    spec_id="https://w3id.org/battinfo/spec/w2n8-6rkt-4mpv-8hcq",
    lot_id="CR2032-KIT-2026-07",
)
{
  "schema_version": "0.2.0",
  "housing": {
    "id": "https://w3id.org/battinfo/housing/7d9k-2m4p-8t3x-6nq5",
    "housing_spec_id": "https://w3id.org/battinfo/spec/y9xy-kr0v-y5tn-dfj7",
    "short_id": "7d9k2m",
    "lot_id": "CR2032-KIT-2026-07"
  },
  "provenance": {
    "source_type": "lab",
    "retrieved_at": 1750000000,
    "battinfo_version": "0.7.0"
  }
}

Emitted by record_to_jsonld, hosted-context mode.

{
  "@context": [
    "https://w3id.org/emmo/domain/battery/context",
    {
      "schema": "https://schema.org/",
      "dcterms": "http://purl.org/dc/terms/",
      "battinfo": "https://w3id.org/battinfo/"
    }
  ],
  "@type": [
    "ElectrochemicalComponent",
    "schema:Product"
  ],
  "@id": "https://w3id.org/battinfo/housing/7d9k-2m4p-8t3x-6nq5",
  "schema:isVariantOf": {
    "@id": "https://w3id.org/battinfo/spec/y9xy-kr0v-y5tn-dfj7"
  }
}

Common examples#

A selection of real, validated records from the packaged examples corpus — each one click away, included from its single source under examples/. The full, living library is the registry: browse it there.

CR2032 coin housing (housing-spec)

The record ships in the installed wheel — load it as a starting point:

import json
from importlib import resources

record = json.loads(
    resources.files("battinfo")
    .joinpath("data/examples/housing-spec/38af-bpnv-1zmm-32hs.json")
    .read_text(encoding="utf-8")
)
{
  "schema_version": "0.2.0",
  "housing_spec": {
    "id": "https://w3id.org/battinfo/spec/38af-bpnv-1zmm-32hs",
    "short_id": "38afbp",
    "name": "CR2032 coin housing",
    "cell_format": "coin",
    "case": {
      "size_code": "2032",
      "material": "Stainless steel",
      "property": {
        "diameter": {
          "value": 20,
          "unit": "mm"
        },
        "height": {
          "value": 3.2,
          "unit": "mm"
        }
      }
    },
    "parts": [
      {
        "type": "spring",
        "material": "Stainless steel"
      },
      {
        "type": "spacer",
        "material": "Stainless steel",
        "property": {
          "thickness": {
            "value": 1.0,
            "unit": "mm"
          }
        }
      }
    ]
  },
  "provenance": {
    "source_type": "datasheet",
    "retrieved_at": 1781768181
  },
  "notes": [
    "CR2032 coin-cell housing (case + spring + 1.0 mm spacer). Discovery-Benchmark coin-cell hardware."
  ]
}

Emitted by record_to_jsonld, hosted-context mode.

{
  "@context": [
    "https://w3id.org/emmo/domain/battery/context",
    {
      "schema": "https://schema.org/",
      "dcterms": "http://purl.org/dc/terms/",
      "battinfo": "https://w3id.org/battinfo/"
    }
  ],
  "@type": [
    "Description",
    "schema:ProductModel",
    "schema:CreativeWork"
  ],
  "isDescriptionFor": {
    "@type": [
      "ElectrochemicalComponent",
      "schema:Product"
    ],
    "hasConstituent": [
      {
        "@type": "CoinCase",
        "schema:size": "2032",
        "schema:material": "Stainless steel",
        "hasProperty": [
          {
            "@type": [
              "Diameter",
              "ConventionalProperty"
            ],
            "skos:prefLabel": "Diameter",
            "hasNumericalPart": {
              "@type": "RealData",
              "hasNumberValue": 20
            },
            "hasMeasurementUnit": "https://w3id.org/emmo#MilliMetre"
          },
          {
            "@type": [
              "Height",
              "ConventionalProperty"
            ],
            "skos:prefLabel": "Height",
            "hasNumericalPart": {
              "@type": "RealData",
              "hasNumberValue": 3.2
            },
            "hasMeasurementUnit": "https://w3id.org/emmo#MilliMetre"
          }
        ]
      },
      {
        "@type": "Spring",
        "schema:material": "Stainless steel"
      },
      {
        "@type": "Spacer",
        "schema:material": "Stainless steel",
        "hasProperty": {
          "@type": [
            "Thickness",
            "ConventionalProperty"
          ],
          "skos:prefLabel": "Thickness",
          "hasNumericalPart": {
            "@type": "RealData",
            "hasNumberValue": 1.0
          },
          "hasMeasurementUnit": "https://w3id.org/emmo#MilliMetre"
        }
      }
    ],
    "skos:prefLabel": "CR2032 coin housing",
    "@id": "https://w3id.org/battinfo/spec/38af-bpnv-1zmm-32hs#described"
  },
  "@id": "https://w3id.org/battinfo/spec/38af-bpnv-1zmm-32hs",
  "schema:name": "CR2032 coin housing"
}
21700 cylindrical housing (housing-spec)

The record ships in the installed wheel — load it as a starting point:

import json
from importlib import resources

record = json.loads(
    resources.files("battinfo")
    .joinpath("data/examples/housing-spec/k2q4-dk79-g890-7veq.json")
    .read_text(encoding="utf-8")
)
{
  "schema_version": "0.2.0",
  "housing_spec": {
    "id": "https://w3id.org/battinfo/spec/k2q4-dk79-g890-7veq",
    "short_id": "k2q4dk",
    "name": "21700 cylindrical housing",
    "cell_format": "cylindrical",
    "case": {
      "material": "Nickel-plated steel",
      "property": {
        "wall_thickness": {
          "value": 0.25,
          "unit": "mm"
        },
        "weight": {
          "value": 15.0,
          "unit": "g"
        }
      }
    },
    "terminals": [
      {
        "polarity": "positive",
        "material": "Aluminium",
        "property": {
          "width": {
            "value": 6.0,
            "unit": "mm"
          },
          "thickness": {
            "value": 0.1,
            "unit": "mm"
          }
        }
      },
      {
        "polarity": "negative",
        "material": "Nickel",
        "property": {
          "width": {
            "value": 5.0,
            "unit": "mm"
          },
          "thickness": {
            "value": 0.1,
            "unit": "mm"
          }
        }
      }
    ],
    "parts": [
      {
        "type": "vent",
        "material": "Aluminium",
        "comment": "Safety vent (CID / burst membrane) in the top cap."
      }
    ]
  },
  "provenance": {
    "source_type": "datasheet",
    "retrieved_at": 1781768181,
    "battinfo_version": "0.7.0"
  },
  "notes": [
    "21700 cylindrical housing: nickel-plated steel can, Al/Ni current-collector tabs, and a top-cap safety vent."
  ]
}

Emitted by record_to_jsonld, hosted-context mode.

{
  "@context": [
    "https://w3id.org/emmo/domain/battery/context",
    {
      "schema": "https://schema.org/",
      "dcterms": "http://purl.org/dc/terms/",
      "battinfo": "https://w3id.org/battinfo/"
    }
  ],
  "@type": [
    "Description",
    "schema:ProductModel",
    "schema:CreativeWork"
  ],
  "isDescriptionFor": {
    "@type": [
      "ElectrochemicalComponent",
      "schema:Product"
    ],
    "hasConstituent": [
      {
        "@type": "CylindricalCase",
        "schema:material": "Nickel-plated steel",
        "hasProperty": [
          {
            "@type": [
              "Thickness",
              "ConventionalProperty"
            ],
            "skos:prefLabel": "Thickness",
            "hasNumericalPart": {
              "@type": "RealData",
              "hasNumberValue": 0.25
            },
            "hasMeasurementUnit": "https://w3id.org/emmo#MilliMetre"
          },
          {
            "@type": [
              "Mass",
              "ConventionalProperty"
            ],
            "skos:prefLabel": "Mass",
            "hasNumericalPart": {
              "@type": "RealData",
              "hasNumberValue": 15.0
            },
            "hasMeasurementUnit": "https://w3id.org/emmo#Gram"
          }
        ]
      },
      {
        "@type": "Terminal",
        "schema:additionalType": "positive",
        "schema:material": "Aluminium",
        "hasProperty": [
          {
            "@type": [
              "Thickness",
              "ConventionalProperty"
            ],
            "skos:prefLabel": "Thickness",
            "hasNumericalPart": {
              "@type": "RealData",
              "hasNumberValue": 0.1
            },
            "hasMeasurementUnit": "https://w3id.org/emmo#MilliMetre"
          },
          {
            "@type": [
              "Width",
              "ConventionalProperty"
            ],
            "skos:prefLabel": "Width",
            "hasNumericalPart": {
              "@type": "RealData",
              "hasNumberValue": 6.0
            },
            "hasMeasurementUnit": "https://w3id.org/emmo#MilliMetre"
          }
        ]
      },
      {
        "@type": "Terminal",
        "schema:additionalType": "negative",
        "schema:material": "Nickel",
        "hasProperty": [
          {
            "@type": [
              "Thickness",
              "ConventionalProperty"
            ],
            "skos:prefLabel": "Thickness",
            "hasNumericalPart": {
              "@type": "RealData",
              "hasNumberValue": 0.1
            },
            "hasMeasurementUnit": "https://w3id.org/emmo#MilliMetre"
          },
          {
            "@type": [
              "Width",
              "ConventionalProperty"
            ],
            "skos:prefLabel": "Width",
            "hasNumericalPart": {
              "@type": "RealData",
              "hasNumberValue": 5.0
            },
            "hasMeasurementUnit": "https://w3id.org/emmo#MilliMetre"
          }
        ]
      },
      {
        "@type": "SafetyVent",
        "schema:material": "Aluminium",
        "rdfs:comment": "Safety vent (CID / burst membrane) in the top cap."
      }
    ],
    "skos:prefLabel": "21700 cylindrical housing",
    "@id": "https://w3id.org/battinfo/spec/k2q4-dk79-g890-7veq#described"
  },
  "@id": "https://w3id.org/battinfo/spec/k2q4-dk79-g890-7veq",
  "schema:name": "21700 cylindrical housing"
}
LFP 100Ah prismatic housing (housing-spec)

The record ships in the installed wheel — load it as a starting point:

import json
from importlib import resources

record = json.loads(
    resources.files("battinfo")
    .joinpath("data/examples/housing-spec/ypyh-v38v-r276-snmk.json")
    .read_text(encoding="utf-8")
)
{
  "schema_version": "0.2.0",
  "housing_spec": {
    "id": "https://w3id.org/battinfo/spec/ypyh-v38v-r276-snmk",
    "short_id": "ypyhv3",
    "name": "LFP 100Ah prismatic housing",
    "cell_format": "prismatic",
    "case": {
      "material": "Aluminium",
      "property": {
        "wall_thickness": {
          "value": 0.8,
          "unit": "mm"
        },
        "weight": {
          "value": 95,
          "unit": "g"
        }
      }
    },
    "terminals": [
      {
        "polarity": "positive",
        "material": "Aluminium",
        "property": {
          "width": {
            "value": 20,
            "unit": "mm"
          }
        }
      },
      {
        "polarity": "negative",
        "material": "Copper",
        "property": {
          "width": {
            "value": 20,
            "unit": "mm"
          }
        }
      }
    ],
    "seals": [
      {
        "material": "Polypropylene"
      }
    ]
  },
  "provenance": {
    "source_type": "datasheet",
    "retrieved_at": 1781768181
  },
  "notes": [
    "Prismatic Al housing with Al/Cu terminals and PP seals. Cell_Design_Tool LFP 100 Ah prismatic."
  ]
}

Emitted by record_to_jsonld, hosted-context mode.

{
  "@context": [
    "https://w3id.org/emmo/domain/battery/context",
    {
      "schema": "https://schema.org/",
      "dcterms": "http://purl.org/dc/terms/",
      "battinfo": "https://w3id.org/battinfo/"
    }
  ],
  "@type": [
    "Description",
    "schema:ProductModel",
    "schema:CreativeWork"
  ],
  "isDescriptionFor": {
    "@type": [
      "ElectrochemicalComponent",
      "schema:Product"
    ],
    "hasConstituent": [
      {
        "@type": [
          "PrismaticCase",
          "Aluminium"
        ],
        "hasProperty": [
          {
            "@type": [
              "Thickness",
              "ConventionalProperty"
            ],
            "skos:prefLabel": "Thickness",
            "hasNumericalPart": {
              "@type": "RealData",
              "hasNumberValue": 0.8
            },
            "hasMeasurementUnit": "https://w3id.org/emmo#MilliMetre"
          },
          {
            "@type": [
              "Mass",
              "ConventionalProperty"
            ],
            "skos:prefLabel": "Mass",
            "hasNumericalPart": {
              "@type": "RealData",
              "hasNumberValue": 95
            },
            "hasMeasurementUnit": "https://w3id.org/emmo#Gram"
          }
        ]
      },
      {
        "@type": "Terminal",
        "schema:additionalType": "positive",
        "schema:material": "Aluminium",
        "hasProperty": {
          "@type": [
            "Width",
            "ConventionalProperty"
          ],
          "skos:prefLabel": "Width",
          "hasNumericalPart": {
            "@type": "RealData",
            "hasNumberValue": 20
          },
          "hasMeasurementUnit": "https://w3id.org/emmo#MilliMetre"
        }
      },
      {
        "@type": "Terminal",
        "schema:additionalType": "negative",
        "schema:material": "Copper",
        "hasProperty": {
          "@type": [
            "Width",
            "ConventionalProperty"
          ],
          "skos:prefLabel": "Width",
          "hasNumericalPart": {
            "@type": "RealData",
            "hasNumberValue": 20
          },
          "hasMeasurementUnit": "https://w3id.org/emmo#MilliMetre"
        }
      },
      {
        "@type": "Seal",
        "schema:material": "Polypropylene"
      }
    ],
    "skos:prefLabel": "LFP 100Ah prismatic housing",
    "@id": "https://w3id.org/battinfo/spec/ypyh-v38v-r276-snmk#described"
  },
  "@id": "https://w3id.org/battinfo/spec/ypyh-v38v-r276-snmk",
  "schema:name": "LFP 100Ah prismatic housing"
}
Pouch laminate housing, 60 x 45 mm (housing-spec)

The record ships in the installed wheel — load it as a starting point:

import json
from importlib import resources

record = json.loads(
    resources.files("battinfo")
    .joinpath("data/examples/housing-spec/q7mf-3wtk-8npv-2hcx.json")
    .read_text(encoding="utf-8")
)
{
  "schema_version": "0.2.0",
  "housing_spec": {
    "id": "https://w3id.org/battinfo/spec/q7mf-3wtk-8npv-2hcx",
    "short_id": "q7mf3w",
    "name": "Pouch laminate housing, 60 x 45 mm",
    "cell_format": "pouch",
    "case": {
      "material": "Aluminium laminate film",
      "property": {
        "thickness": {
          "value": 113,
          "unit": "um"
        },
        "width": {
          "value": 45,
          "unit": "mm"
        },
        "height": {
          "value": 60,
          "unit": "mm"
        }
      }
    },
    "seals": [
      {
        "material": "PP heat seal"
      }
    ],
    "terminals": [
      {
        "polarity": "positive",
        "material": "Al tab"
      },
      {
        "polarity": "negative",
        "material": "Ni-plated Cu tab"
      }
    ]
  },
  "provenance": {
    "source_type": "datasheet",
    "retrieved_at": 1789040331,
    "battinfo_version": "0.7.0"
  }
}

Emitted by record_to_jsonld, hosted-context mode.

{
  "@context": [
    "https://w3id.org/emmo/domain/battery/context",
    {
      "schema": "https://schema.org/",
      "dcterms": "http://purl.org/dc/terms/",
      "battinfo": "https://w3id.org/battinfo/"
    }
  ],
  "@type": [
    "Description",
    "schema:ProductModel",
    "schema:CreativeWork"
  ],
  "isDescriptionFor": {
    "@type": [
      "ElectrochemicalComponent",
      "schema:Product"
    ],
    "hasConstituent": [
      {
        "@type": "PouchCase",
        "schema:material": "Aluminium laminate film",
        "hasProperty": [
          {
            "@type": [
              "Height",
              "ConventionalProperty"
            ],
            "skos:prefLabel": "Height",
            "hasNumericalPart": {
              "@type": "RealData",
              "hasNumberValue": 60
            },
            "hasMeasurementUnit": "https://w3id.org/emmo#MilliMetre"
          },
          {
            "@type": [
              "Thickness",
              "ConventionalProperty"
            ],
            "skos:prefLabel": "Thickness",
            "hasNumericalPart": {
              "@type": "RealData",
              "hasNumberValue": 113
            },
            "hasMeasurementUnit": "https://w3id.org/emmo#MicroMetre"
          },
          {
            "@type": [
              "Width",
              "ConventionalProperty"
            ],
            "skos:prefLabel": "Width",
            "hasNumericalPart": {
              "@type": "RealData",
              "hasNumberValue": 45
            },
            "hasMeasurementUnit": "https://w3id.org/emmo#MilliMetre"
          }
        ]
      },
      {
        "@type": "Terminal",
        "schema:additionalType": "positive",
        "schema:material": "Al tab"
      },
      {
        "@type": "Terminal",
        "schema:additionalType": "negative",
        "schema:material": "Ni-plated Cu tab"
      },
      {
        "@type": "Seal",
        "schema:material": "PP heat seal"
      }
    ],
    "skos:prefLabel": "Pouch laminate housing, 60 x 45 mm",
    "@id": "https://w3id.org/battinfo/spec/q7mf-3wtk-8npv-2hcx#described"
  },
  "@id": "https://w3id.org/battinfo/spec/q7mf-3wtk-8npv-2hcx",
  "schema:name": "Pouch laminate housing, 60 x 45 mm"
}

Fields#

Generated from the packaged JSON Schemas — the same files battinfo validate and the registry’s publish gate enforce. Every record also carries the shared envelope (schema_version, provenance, and optional notes, funding, contributor, license). Quantities are {value, unit} maps and may also carry value_basis (Measured, Conventional, Rated, or Nominal) and conditions (the parameters under which the value holds, each itself a quantity; a qualitative condition may be value_text alone). In JSON-LD, conditions ride a measurement node the quantity isOutputOf; the voltage_reference key instead becomes a hasMetrologicalReference datum on the quantity, beside its unit. When authoring, an instance references its spec with the spec_id= kwarg; the record stores the self-describing <type>_spec_id key shown in the tables below.

housing-spec fields#

Schema: housing-spec.schema.json · required at top level: schema_version, housing_spec, provenance

Field

Type

Required

Description

id

→ ComponentSpecIri

yes

short_id

→ ShortId

name

string

yes

Human-readable name of this housing design (e.g. ‘CR2032 SS316L case’).

cell_format

coin | cylindrical | pouch | prismatic … (6 values)

Cell format this housing is for.

case

→ Case

Main case or can of the housing.

cap

→ HardwarePart

Cap or lid part.

terminals

array of → Terminal

Electrical terminals, with polarity and material.

seals

array of → Seal

Seals and gaskets.

parts

array of → HardwarePart

Other hardware parts (springs, spacers, …).

property

→ quantitative-properties

Named quantity map of housing-level properties (e.g. mass, wall_thickness). See the property keys reference for the full list of recognised keys.

manufacturer

→ OrgRef

Manufacturer of the item.

supplier

→ OrgRef

Supplier or vendor the item was sourced from.

product_id

string

Manufacturer or supplier product/grade identifier.

comment

string

Free-text comment.

housing fields#

Schema: housing.schema.json · required at top level: schema_version, housing, provenance

Field

Type

Required

Description

id

→ ComponentIri

yes

housing_spec_id

→ ComponentSpecIri

yes

IRI of the housing-spec this physical housing realizes.

short_id

→ ShortId

name

string

Human-readable label for this physical item (e.g. a lab inventory id).

lot_id

string

Manufacturer or supplier lot number.

batch_id

string

Internal lab batch identifier, when different from the supplier lot.

supplier

→ OrgRef

Supplier or vendor the item was sourced from.

manufactured_at

→ FlexDate

Date this item was manufactured.

datasets

array of → DatasetLink

Characterization datasets recorded for this physical item.

property

→ quantitative-properties

Named quantity map of technical properties (snake_case key to value+unit quantity).

comment

string

Free-text comment.

Design notes#

The reasoning behind the model

Holder + property, like everything else. case, cap, terminals, seals and the open parts[] list each carry identity fields plus {value, unit} quantities. Part types resolve to their EMMO classes — CoinCase, CellLid, Terminal, Spring, Spacer, Gasket, SafetyVent, CurrentInterruptDevice — published in domain-electrochemistry 0.36.0 for exactly this layer.

The housing is the assembly, not the case. The case is one of its parts (EMMO’s CellLid “closes the case”; terminals and seals are siblings), so the described individual types ElectrochemicalComponent — no CellHousing class is published yet; it is on the upstream ask list — and every part lists uniformly under hasConstituent. A cell keeps the published hasCase pattern for its case.

Inline or standalone. A cell spec may describe its housing inline (the engineering-cell description path) or reference this record via housing_spec_id; a purchased coin-cell kit (case + cap + spring + spacer, one product id) is the classic standalone case.

Generated surface. create_housing_spec and friends wrap the shared component machinery — one registry entry per family.