Skip to content

openapi: intersect constraints and defaults when reconciling allOf branches #10

Description

@OmarAlJarrah

Problem

The OpenAPI compiler's allOf reconciliation (compilers/openapi/schema.go,
mergeProperty) is first-declaration-wins for a property's shape: when two inline
branches declare the same field, it OR's Required but keeps only the first
branch's type, constraints, default, docs, visibility, and extensions. Anything the
later branch adds or narrows is dropped.

Under allOf intersection semantics the merged field should satisfy every
branch. So a second branch that adds a constraint the first lacks (e.g. pattern,
maxLength, enum, a default) is currently lost, and the resulting model is a
lossy view of the source. This also weakens the ir-design §4.3 promise that
composition "keeps every branch reconstructible": the later branch's contribution to
the field leaves no trace.

Impact

  • Emitted SDKs/validation may under-constrain fields that the spec constrained.
  • A default declared only in a later branch disappears.

Proposed direction

Intersect the reconciled property across branches rather than first-wins:

  • union the constraint sets (tightest wins where they overlap),
  • carry a default/docs/examples from a later branch when the first has none,
  • preserve provenance of every contributing branch.

This is plausibly better as a dedicated IR pass/ (operating on the composed model)
than inline in the compiler, so the compiler stays a straightforward lowering and the
intersection logic is testable in isolation. Coordinate with the conflict-detection
work (they touch the same merge point).

Acceptance

  • A field declared in two branches, where the second adds maxLength/pattern/a
    default, ends up with those on the reconciled property.
  • Provenance lets a consumer see every branch that contributed to the field.

Context

Follow-up to #8. That PR fixed the duplicate-wire-name false positives with a
minimal, correct reconciliation and explicitly deferred full constraint intersection.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions