Skip to content

feat(openenum): add is_open boolean slot to enum expressions#261

Open
noelmcloughlin wants to merge 1 commit into
linkml:mainfrom
noelmcloughlin:enumopen
Open

feat(openenum): add is_open boolean slot to enum expressions#261
noelmcloughlin wants to merge 1 commit into
linkml:mainfrom
noelmcloughlin:enumopen

Conversation

@noelmcloughlin

@noelmcloughlin noelmcloughlin commented Jul 2, 2026

Copy link
Copy Markdown

This PR adds is_open boolean slot to enum expressions in the meta model.

See linkml/linkml#127 and linkml/linkml#3712

@noelmcloughlin
noelmcloughlin marked this pull request as draft July 2, 2026 15:53
@noelmcloughlin
noelmcloughlin marked this pull request as ready for review July 2, 2026 19:15
Comment thread linkml_model/model/schema/meta.yaml
Comment thread linkml_model/model/schema/meta.yaml
Comment thread linkml_model/model/schema/meta.yaml
Comment thread linkml_model/model/schema/meta.yaml Outdated
Comment thread linkml_model/model/schema/meta.yaml
Comment thread linkml_model/model/schema/meta.yaml Outdated
@sneakers-the-rat

Copy link
Copy Markdown
Contributor

The basic idea makes total sense to me. I just wonder if we want to have a single way of declaring this across the few places we want similar behavior - e.g. extra_slots allows for a boolean "yes others are allowed"/"no others are forbidden" as well as specifying an expression that other values must match. Do we want that here? We also need to add a similar thing at the SchemaDefinition level to specify openness of the whole schema/specify class/slot expressions to match extra members as well.

extra_slots as a name is too specific, I like is_open for a bool, the most generic name might just be extra.

Basically I am in favor of this but just wondering if we want to have a similar mechanism/pattern across all "openness" specs, or if there is a reason this one should be a boolean only

@noelmcloughlin

noelmcloughlin commented Jul 6, 2026

Copy link
Copy Markdown
Author

I am just now thinking maybe is_open is bad name - I recall other discussions where someone (Chris?) worried it might get conflated with "open world" .. if push back comes then allow-other has precedent in Oscal Metamodel.

But issue linkml/linkml#127 proposes 'open enums' via is_open meta slot.

I noted linkml/linkml#1595 discusses extensible meta slot also - kinda related.

@sneakers-the-rat

Copy link
Copy Markdown
Contributor

This has been a general naming tension between how I normally think and how linkml does names - I generally tend towards more general names whose meaning varies by context, and linkml tends to have specific names and only use them in one or a few contexts in which is has a single meaning. So where I would probably gravitate towards a single extra: term that could be used for slots, classes, enum items, etc., I think the linkml way would have a term per type of extra thing, extra_classes, extra_enum_items, etc.

is_open is probably the name I would reach for too for a boolean name, but it sort of doesn't have an obvious corrolary for the "middle" switch - true is "allow all," false is "allow none," but what would you call "allow some" (I.e. expressed in some subschema). open_to maybe? This was a consideration I remember finding tricky when landing on extra_* and having sub-terms within it, which is not the most elegant solution.

But anyway, need to decide if we want to have common mechanism/pattern for declaring "all/none/some" openness, or if sometimes binary and sometimes trinary is fine. That also narrows down which names work.

@matentzn

matentzn commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

As this issue is slightly beyond my current ability to judge, @amc-corey-cox has volunteered to thinking through the implications and presenting a short version of this at the next developer call in one week. Sorry for the delay - please keep pushing if we slow you down; I can find more aggressive alternative review processes. 🚀

@amc-corey-cox amc-corey-cox left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The shape looks right to me. is_open as a boolean fits the metamodel: it mirrors id_prefixes_are_closed — one slot builds the value set, another says whether it's exhaustive. is_open: true just demotes the permissible values from MUST to SHOULD; it doesn't collapse the range.

@sneakers-the-rat on binary-vs-trinary: I don't think enums need the all/none/some shape that extra_slots has. extra_slots had to be trinary because it has no set-construction of its own. Enums already do that via permissible_values/reachable_from/matches/include/minus. And per-value constraints already work: a slot pattern holds independently of enum membership, so "extras must be well-formed" needs nothing new.

If a real case for open_to: shows up, that will need more definition than we're ready to do here and we should design around the live case.

exact_mappings:
- cdisc:PermissibleValue

is_open:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A boolean feels right here. id_prefixes_are_closed (line 249) is the precedent: one slot builds the set, another says if it's exhaustive. is_open: true is also the top case of a future open_to: <expr>, so this forecloses nothing.

that are not in the set of permissible values are permitted (though they SHOULD be
drawn from the permissible values if available). If false (runtime default), the
enumeration is closed and data values MUST be drawn from the set of permissible values.
ifabsent: false

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drop ifabsent: false. It materializes False on every enum and the dumper emits it, so all schemas grow an is_open: false line. No other boolean slot in the metamodel uses ifabsent.

ifabsent: false
comments:
- An open enumeration is analogous to the `allow-other="yes"` construct in the OSCAL Metamodel.
- When an enum is open, the permissible values are advisory - they document the recommended

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This contradicts the description above. Open means the value set isn't exhaustive, not that other constraints vanish — a slot pattern should still hold. The "maps to a plain string" bit is a JSON Schema lowering detail; leave that to linkml#3712 and remove the reference to JSON Schema.

- https://github.com/linkml/linkml/pull/3712
in_subset:
- SpecificationSubset
# BasicSubset

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drop the commented-out # BasicSubset.

in_subset:
- SpecificationSubset
# BasicSubset
status: testing

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Worth a tests/input/examples/schema_definition-open-enums.yaml so make test-examples covers it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants