Skip to content

fix(query)!: distribute alias widening over an endpoint's kind union - #666

Merged
pdlug merged 1 commit into
integration/ontology-semanticsfrom
feat/review2-rw-types
Sep 10, 2026
Merged

pdlug merged 1 commit into
integration/ontology-semanticsfrom
feat/review2-rw-types

Conversation

@pdlug

@pdlug pdlug commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

Second whole-branch review of #637, finding: an ontology endpoint declared as a finite union of node types (parent: typeof ParentA | typeof ParentB) still produced exact alias types, because SubsumptionAffected decided "does this relation name kind K" by Extracting the whole relation against a single-kind endpoint shape. A union endpoint matches no such shape, so the decision answered false for every kind the endpoint can hold — an unsound under-widening, the opposite of the conservative over-widening the erased arms take on purpose.

The decision now reduces each relation's MatchedEndpoints to the kind literals its endpoints can hold and asks whether K is among them. That covers both spellings of a union endpoint: a union of endpoint types (from a helper that declares a subclass of either of two roots) and a union inside one endpoint's kind (NodeType<"Audio" | "Video">). MatchedEndpoints is the sole owner of the name-to-endpoint-position mapping; the decided arm no longer re-spells it as Extract arms beside the erased arm's use of it, and both erased arms are unchanged. A union endpoint therefore widens exactly the kinds it can hold and nothing else, which the typed-subsumption changeset and the queries guide now state.

Forgotten-export debt moves +1 on the seven entrypoints that reach SubsumptionAffected, for exactly one new declaration (SubsumptionElementNamesKind); removing that name from each new symbol set reproduces the previously recorded digest.

`SubsumptionAffected` decided "does this relation name kind K" by
`Extract`ing the whole ontology element against a single-kind endpoint
shape. An endpoint that can hold more than one kind matches no such shape,
so the decision came back `false` for every kind the endpoint can hold —
an unsound under-widening that typed a genuinely polymorphic alias as
exact, the opposite of the conservative over-widening the erased arms take
on purpose.

The decision now reduces each element's `MatchedEndpoints` to the kind
literals they can hold and asks whether `K` is among them, which covers
both spellings of a union endpoint: a union of endpoint types
(`typeof Audio | typeof Video`, from a helper that declares a subclass of
either media root) and a union inside one endpoint's `kind`
(`NodeType<"Audio" | "Video">`). `MatchedEndpoints` becomes the sole owner
of the name-to-endpoint-position mapping — the decided arm no longer
re-spells it as `Extract` arms alongside the erased arm's use of it — and
both erased arms are unchanged.

Forgotten-export debt moves +1 on the seven `SubsumptionAffected`-reachable
entrypoints for exactly one new declaration, `SubsumptionElementNamesKind`;
removing that name from each new symbol set reproduces the previously
recorded `sha256` exactly.
@pdlug
pdlug merged commit 8d4bc2c into integration/ontology-semantics Sep 10, 2026
21 checks passed
@pdlug
pdlug deleted the feat/review2-rw-types branch September 10, 2026 09:28
pdlug added a commit that referenced this pull request Sep 23, 2026
…666)

Second whole-branch review of #637, finding: an ontology endpoint
declared as a finite union of node types (`parent: typeof ParentA |
typeof ParentB`) still produced exact alias types, because
`SubsumptionAffected` decided "does this relation name kind K" by
`Extract`ing the whole relation against a single-kind endpoint shape. A
union endpoint matches no such shape, so the decision answered `false`
for every kind the endpoint can hold — an unsound under-widening, the
opposite of the conservative over-widening the erased arms take on
purpose.

The decision now reduces each relation's `MatchedEndpoints` to the kind
literals its endpoints can hold and asks whether `K` is among them. That
covers both spellings of a union endpoint: a union of endpoint types
(from a helper that declares a subclass of either of two roots) and a
union inside one endpoint's `kind` (`NodeType<"Audio" | "Video">`).
`MatchedEndpoints` is the sole owner of the name-to-endpoint-position
mapping; the decided arm no longer re-spells it as `Extract` arms beside
the erased arm's use of it, and both erased arms are unchanged. A union
endpoint therefore widens exactly the kinds it can hold and nothing
else, which the typed-subsumption changeset and the queries guide now
state.

Forgotten-export debt moves +1 on the seven entrypoints that reach
`SubsumptionAffected`, for exactly one new declaration
(`SubsumptionElementNamesKind`); removing that name from each new symbol
set reproduces the previously recorded digest.
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.

1 participant