Code lists: SKOS scheme, not owl:oneOf — cheatsheet

rebuts design-choices §2.2 · Appendix A · analysis F7
Code lists are reference data, not schema. Default: skos:ConceptScheme + skos:Concept, validated by SHACL sh:in. Exception: owl:oneOf + owl:AllDifferent only for a small, stable, closed list whose completeness the reasoner actually needs.

Scope of the dispute

Agreed — keepCode-list entries are values, not subclasses (§2.4's test is right). Closure stays available. ACORD alignment stays first-class.
Contested — changeRepresenting values as a closed owl:oneOf list inside the schema (T-Box), and the ban: "SKOS for annotation only."
The tellIf SHACL sh:in can meet the requirement, owl:oneOf was not needed.

§2.2's three supports, answered

§2.2 saysCounterRemember it by
"Named individuals allow OWL reasoning over membership and enable class-level disjointness." "Is this value allowed?" is a validation question — Appendix A's own row assigns it to sh:in. Disjointness only holds between classes; list members are individuals (the closest statement is owl:differentFrom). And OWL doesn't assume two names mean two different things, so dirty data makes the pattern misbehave (see trap ↓). The reasoner doesn't reject a second status — it merges two statuses.
"SKOS concepts cannot carry OWL restrictions." True, but it doesn't matter — a code value has no instances to restrict ("Fire" isn't a class of fire-things). Named individuals can't carry restrictions either. A value that gains real structure (Peril_Flood → storm surge / riverine) becomes an owl:Class per §2.4 — one value at a time. Nothing for a restriction to bite on — on either side.
"skos:exactMatch can be added later without rearchitecting." This admits the point: the interoperability plan is SKOS. exactMatch is defined for skos:Concepts; a real crosswalk also needs notation, inScheme, and graded matches (our Windstorm is broader than ACORD's Hurricane = broadMatch). Bonus: exactMatch is weaker than sameAs — it links codes without the property merge §1.2 warns about. Banned at the modelling layer, relied on at the interop layer → guaranteed rework.

The trap in the §2.2 pattern

# §2.5: hasPartyStatus is functional. One bad record: ins:party-991 ins:hasPartyStatus ins:ActivePartyStatus , ins:MergedPartyStatus . # No owl:AllDifferent in §2.2 → reasoner infers # Active owl:sameAs Merged — silently, model-wide.

SHACL (sh:in + sh:maxCount 1) reports the same record as a loud violation. If oneOf is ever used, owl:AllDifferent is mandatory.

The default pattern — copy this

ins:PartyStatusScheme a skos:ConceptScheme ; owl:versionInfo "2026-07" . # own clock ins:ActivePartyStatus a skos:Concept ; skos:inScheme ins:PartyStatusScheme ; skos:prefLabel "Active"@en , "Actif"@fr ; skos:notation "ACT" ; # source code skos:exactMatch acord:PartyStatus_Active . ins:PartyShape sh:property [ sh:path ins:hasPartyStatus ; sh:maxCount 1 ; sh:in ( ins:ActivePartyStatus ins:InactivePartyStatus ins:MergedPartyStatus ) ] . # validator output — violations, not merges: # party-991 → sh:maxCount: 2 values for hasPartyStatus # party-992 (status Pending) → sh:in: not an allowed value

Decision rule (revised Appendix A)

NeedUse
Controlled vocabulary — the defaultskos:ConceptScheme + sh:in
Small, stable, closed set feeding a required inference (record it in a comment)owl:oneOf + owl:AllDifferent
Value with its own structure / subtypespromote to owl:Class (§2.4)
Cross-system alignment (ACORD, NAICS)skos:*Match family
Opaque code string, no metadata everxsd:string + SHACL pattern

Why it matters — add "Cyber" to perils

  • §2.2: edit a published oneOf axiom → new ontology release (§5.5) → all consumers re-import → the reasoner reprocesses the whole list (NAICS = 1,000+ codes).
  • SKOS: one new concept + one IRI in the shape. No schema release, zero reasoner cost, hierarchy (broader), code (notation), and tooling (VocBench, Skosmos) included.

The design doc already agrees — everywhere but §2.2

  • Appendix A — its own rows: "validation-only → sh:in", "open set, will grow → no oneOf". Perils / LOB / NAICS are open, growing sets.
  • §5.4 — mandates skos:prefLabel / definition / example on every term: the required documentation surface is skos:Concept's native property set.
  • §5.5 — the deprecation pattern already uses skos:exactMatch to point retired terms at successors.
  • §1.2 — prefers skos:notation-bearing identifiers over owl:sameAs to avoid property merges — the same safe-alignment instinct as skos:*Match.
  • §2.4 — the promote-to-class test already covers the rare value with real structure — the only case where Claim 2 would matter.
  • F7 (analysis) — flags reasoner cost, volatility, and drift; the sibling Chubb ontology publishes these lists as SKOS schemes — diverging forces a translation layer.

Bottom line

Swap the default and the exception. SKOS becomes the code-list data model (not just annotation); owl:oneOf survives as the documented, AllDifferent-paired exception for the rare list whose completeness the reasoner actually needs. Everything §2.2 got right — values not subclasses, closure available, ACORD first-class — is kept.

Condensed from the full rebuttal · rebuts Ontology Design Choices §2.2 + Appendix A · companion finding F7. Standards: SKOS, SHACL, OWL 2 DL, gist, ACORD.