Skip to content

A co-declared minimum + exclusiveMinimum pair loses one keyword to degraded_lowering #425

Description

@fuad-daoud

The gap

In JSON Schema 2020-12 minimum and exclusiveMinimum are independent keywords that both apply; a schema may legally declare both, and the effective bound is the tighter one — but the pair is not redundant, because they constrain differently.

ir.Constraints holds one bound per side, so annotation/constraints.go:259-270 reconciles them: the tighter is kept and the other is preserved as degraded_lowering.

Why it matters

The reconciliation is defensible, and the loser is preserved, so this is not silent loss. But a consumer comparing constraints across two versions sees only the survivor: a change to the dropped keyword reads as no change, and a change that swaps which keyword is tighter reads as a change of a different kind than the one that happened.

Suggested fix

Either carry both bounds per side (Minimum and ExclusiveMinimum rather than one slot plus a flag), or state in the Constraints field docs that a co-declared pair is lossy for comparison purposes so consumers know to read the Unmodeled entry.


Found by a study of dexpace/spaceapi adopting morphic IR as its input format (spaceapi#56), 2026-09-05. Related: #418 (non-emitter consumer), #419 (cross-revision identity).

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    type:bugDefect in shipped behavior

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions