Skip to content

fix(compilers/openapi): fill allOf position constraints - #457

Merged
fuad-daoud merged 1 commit into
mainfrom
fix/allof-position-constraints
Sep 14, 2026
Merged

fuad-daoud merged 1 commit into
mainfrom
fix/allof-position-constraints

Conversation

@fuad-daoud

Copy link
Copy Markdown
Collaborator

Summary

A value constraint written beside an allOf composing position — minProperties, maxProperties — reached a different channel than the same constraint beside a plain object schema. lowerModel filled ir.Model.Constraints from the position's own schema; lowerAllOf built its Model without doing so, leaving Constraints nil. The census that runs afterwards found no value there and concluded the keyword had no home, reporting a false openapi/degraded-construct and stashing the value under Unmodeled — while the field the diagnostic said was missing exists on every Model (#407).

lowerAllOf now reads the position's constraints with the same schemaConstraints call lowerModel makes, so the keyword lands where ir-design.md already documents it (Model.Constraints), with no diagnostic and no Unmodeled entry. buildComposedVariant, which synthesizes a Model per distributed-union variant from the same kind of position, had the same gap — and worse: that path never runs the position's census at all, so a bound written beside a co-declared oneOf/anyOf was dropped in total silence rather than misfiled. Both are fixed the same way. No other ir.Model construction site is missing the fill (the sweep is in the commit).

Test plan

  • New conformance case allof-position-constraints (witnesses intersection): pins ViaAllOf.Constraints.MinProps == 2, no openapi:minProperties under Unmodeled, and no degraded-construct at /components/schemas/ViaAllOf. Planting the defect back reddens it.
  • allof-oneof-cooccurrence.yaml gains minProperties: 2 on its Combo schema, since no existing fixture reached the buildComposedVariant gap (it was silent, not misfiled, so no golden could have changed); its golden now carries the bound on each distributed variant.
  • make gate passes: lint 0 issues, coverage at 100%, fuzz, bench-smoke.

Closes #407

🤖 Generated with Claude Code

https://claude.ai/code/session_01TJZJ8HaugGZTjzVueafLAT

A value constraint written beside an allOf composing position — minProperties,
maxProperties — reached a different channel than the same constraint written
beside a plain object schema. lowerModel filled ir.Model.Constraints from the
position's own schema; lowerAllOf built its Model without doing so, leaving
Constraints nil. The census that runs afterward then found no value there and
concluded the keyword had no home, reporting a false openapi/degraded-construct
diagnostic and stashing the value under Unmodeled — even though the very field
the diagnostic said was missing exists on every Model, allOf-composed or not.

Fix lowerAllOf to read the position's constraints the same way lowerModel does,
so the census sees them filled and the keyword lands where ir-design.md already
documents it belonging (Model.Constraints), with no diagnostic and no Unmodeled
entry. buildComposedVariant, which synthesizes a Model per distributed-union
variant from the same kind of position, had the same gap — worse, since that
path never runs the position's census at all, so a bound written beside a
co-declared oneOf/anyOf was dropped in total silence rather than merely
misfiled. Both are fixed the same way, reading schemaConstraints once per
built Model.

Closes #407

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TJZJ8HaugGZTjzVueafLAT
@fuad-daoud
fuad-daoud force-pushed the fix/allof-position-constraints branch from 69ffaea to 06412b8 Compare September 14, 2026 21:19
@fuad-daoud
fuad-daoud merged commit 7daf326 into main Sep 14, 2026
1 check passed
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.

openapi: a constraint beside allOf misses the Constraints field its node has

1 participant