A boolean schema used as an allOf branch contributes nothing, and the composed model says the
opposite of what the source does.
components:
schemas:
Never: {allOf: [false]}
Always: {allOf: [true]}
Both lower to kind: model with no properties, no additional, nothing under unmodeled, and no
diagnostic. An empty open model admits every instance — so Never, whose source admits none, is
lowered to the most permissive shape the IR has.
Why this is inconsistent rather than merely incomplete
ir-design.md §4.8 already states the handling for a boolean schema in its own right: "a boolean
false schema becomes a closed empty Model with an info one". The composition path does not
apply that rule to a branch, so the same source construct is lowered two different ways depending
on where it appears, and only one of them is documented.
Why it was left out of the branch-residue work
The residue derivation keeps whatever an inline branch declares that the merge does not consume,
derived from the branch key set. A boolean branch declares no keys at all, so there is nothing for
that mechanism to rescue — the gap is not preservation but lowering: what should the composed node
be when one conjunct admits nothing. That is a decision worth making deliberately rather than
falling out of an empty merge, which is why it was recorded in the code and the PR body rather than
patched.
Suggested shape
Apply §4.8s existing rule through composition: a false branch makes the composition unsatisfiable,
so the composed model should be the closed empty Model with the same info diagnostic. A true
branch is a genuine no-op and can stay silent, though saying so once would cost little.
Method
Compiled through openapi.New().Compile(...), inspecting the emitted models and the full
diagnostic list.
A boolean schema used as an
allOfbranch contributes nothing, and the composed model says theopposite of what the source does.
Both lower to
kind: modelwith no properties, noadditional, nothing underunmodeled, and nodiagnostic. An empty open model admits every instance — so
Never, whose source admits none, islowered to the most permissive shape the IR has.
Why this is inconsistent rather than merely incomplete
ir-design.md§4.8 already states the handling for a boolean schema in its own right: "a booleanfalseschema becomes a closed emptyModelwith aninfoone". The composition path does notapply that rule to a branch, so the same source construct is lowered two different ways depending
on where it appears, and only one of them is documented.
Why it was left out of the branch-residue work
The residue derivation keeps whatever an inline branch declares that the merge does not consume,
derived from the branch key set. A boolean branch declares no keys at all, so there is nothing for
that mechanism to rescue — the gap is not preservation but lowering: what should the composed node
be when one conjunct admits nothing. That is a decision worth making deliberately rather than
falling out of an empty merge, which is why it was recorded in the code and the PR body rather than
patched.
Suggested shape
Apply §4.8s existing rule through composition: a
falsebranch makes the composition unsatisfiable,so the composed model should be the closed empty
Modelwith the sameinfodiagnostic. Atruebranch is a genuine no-op and can stay silent, though saying so once would cost little.
Method
Compiled through
openapi.New().Compile(...), inspecting the emitted models and the fulldiagnostic list.