Context
GlobalTypeSystem/gts-spec#92 clarifies the semantics of x-gts-traits-schema: false after this review discussion.
The effective traits value of a type is a materialized JSON object. When no x-gts-traits values are declared, that object is {}. Under standard JSON Schema semantics, false rejects every instance, including {}. Consequently, a non-abstract type whose effective traits schema contains false must fail OP#13 completeness validation even when x-gts-traits is absent.
Authors who need to prohibit traits while allowing a concrete type should use a satisfiable object schema such as { "type": "object", "maxProperties": 0 }.
Current behavior
EffectiveTraits::validate in gts/src/schema_traits.rs special-cases an effective false schema: it rejects non-empty merged traits but returns success for an empty merged traits object. This treats false as "no traits allowed" rather than as an unsatisfiable JSON Schema.
test_resolved_type_false_traits_schema in gts/src/store_test.rs currently asserts that a concrete type with x-gts-traits-schema: false and no trait values validates successfully.
Proposed behavior in the current spec change
- A non-abstract type with an effective traits schema of
false fails OP#13 for absent, explicitly empty, and non-empty x-gts-traits.
- An abstract type may carry an unsatisfiable effective traits schema because OP#13 completeness validation is skipped for abstract types.
- A concrete type using
{ "type": "object", "maxProperties": 0 } passes with no traits and fails with non-empty traits.
Alternative design
An alternative is to stop treating absent x-gts-traits as a materialized {} for validation purposes and preserve the distinction between absence and an explicitly declared empty object:
- Absent
x-gts-traits means there is no traits instance to validate, so a concrete type may remain valid under x-gts-traits-schema: false.
- Explicit
x-gts-traits: {} is present and fails validation against false.
- Non-empty
x-gts-traits also fails validation against false.
This model would let false mean that no traits declaration is permitted while retaining concrete descendants, but it is not an implementation-only change. The specification would need to redefine the OP#13 completeness algorithm, including how absence interacts with required, defaults, inheritance, and materialization. gts-rust would also need to preserve presence explicitly, for example with Option<Value> or a separate flag, because its current merge representation collapses absence and {} into the same empty object.
If maintainers prefer this alternative, the spec decision and conformance tests should be changed first through an ADR amendment; the proposed implementation below should then be replaced with presence-aware validation.
Suggested implementation for the current proposal
- Remove the empty-traits success path for an effective
false schema and validate the materialized effective traits object normally.
- Update the existing
false-schema tests.
- Add coverage for absent, explicitly empty, and non-empty traits, plus the
maxProperties: 0 alternative.
Dependency
Align the implementation after the corresponding semantics in GlobalTypeSystem/gts-spec#92 are accepted and merged.
Context
GlobalTypeSystem/gts-spec#92 clarifies the semantics of
x-gts-traits-schema: falseafter this review discussion.The effective traits value of a type is a materialized JSON object. When no
x-gts-traitsvalues are declared, that object is{}. Under standard JSON Schema semantics,falserejects every instance, including{}. Consequently, a non-abstract type whose effective traits schema containsfalsemust fail OP#13 completeness validation even whenx-gts-traitsis absent.Authors who need to prohibit traits while allowing a concrete type should use a satisfiable object schema such as
{ "type": "object", "maxProperties": 0 }.Current behavior
EffectiveTraits::validateingts/src/schema_traits.rsspecial-cases an effectivefalseschema: it rejects non-empty merged traits but returns success for an empty merged traits object. This treatsfalseas "no traits allowed" rather than as an unsatisfiable JSON Schema.test_resolved_type_false_traits_schemaingts/src/store_test.rscurrently asserts that a concrete type withx-gts-traits-schema: falseand no trait values validates successfully.Proposed behavior in the current spec change
falsefails OP#13 for absent, explicitly empty, and non-emptyx-gts-traits.{ "type": "object", "maxProperties": 0 }passes with no traits and fails with non-empty traits.Alternative design
An alternative is to stop treating absent
x-gts-traitsas a materialized{}for validation purposes and preserve the distinction between absence and an explicitly declared empty object:x-gts-traitsmeans there is no traits instance to validate, so a concrete type may remain valid underx-gts-traits-schema: false.x-gts-traits: {}is present and fails validation againstfalse.x-gts-traitsalso fails validation againstfalse.This model would let
falsemean that no traits declaration is permitted while retaining concrete descendants, but it is not an implementation-only change. The specification would need to redefine the OP#13 completeness algorithm, including how absence interacts withrequired, defaults, inheritance, and materialization.gts-rustwould also need to preserve presence explicitly, for example withOption<Value>or a separate flag, because its current merge representation collapses absence and{}into the same empty object.If maintainers prefer this alternative, the spec decision and conformance tests should be changed first through an ADR amendment; the proposed implementation below should then be replaced with presence-aware validation.
Suggested implementation for the current proposal
falseschema and validate the materialized effective traits object normally.false-schema tests.maxProperties: 0alternative.Dependency
Align the implementation after the corresponding semantics in GlobalTypeSystem/gts-spec#92 are accepted and merged.