Skip to content

Align x-gts-traits-schema: false handling with JSON Schema semantics #112

Description

@aviator5

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions