Skip to content

V0.13 support - #110

Open
aviator5 wants to merge 4 commits into
GlobalTypeSystem:mainfrom
aviator5:v0.13-support
Open

V0.13 support#110
aviator5 wants to merge 4 commits into
GlobalTypeSystem:mainfrom
aviator5:v0.13-support

Conversation

@aviator5

@aviator5 aviator5 commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Summary by CodeRabbit

  • New Features
    • Added 0.13 specification support with public spec/implementation version details.
    • Introduced verdict-style compatibility reporting (full/backward/forward) with version metadata and richer diagnostics, plus document comparison utilities.
  • Bug Fixes
    • Corrected trailing wildcard GTS ID matching and tightened major-version wildcard behavior (including v0.*).
    • Improved JSON Schema compatibility semantics, including exact numeric equality and more accurate additionalProperties handling.
    • Enhanced schema generation/closure behavior for nested structures and definition/combinator references.
  • Documentation
    • Updated compatibility examples and OP#8/OP#9 outputs to the new verdict fields.
  • Tests
    • Expanded schema inheritance and integration coverage for nested references and compatibility outcomes.

aviator5 added 3 commits July 29, 2026 13:05
- Compare resolved accepted-instance sets and expose compatible, incompatible, or unknown verdicts with diagnostics.
- Honor dialect-aware content models and boolean-equivalent schemas while preserving nested definitions.
- Pin the conformance suite to v0.13.0.

Signed-off-by: Aviator 5 <ai.agent.tor@gmail.com>
- Store major versions as optional values so an explicit v0 is not treated as unspecified.
- Match and serialize v0 minor wildcards without leaking into other major versions.

Signed-off-by: Aviator 5 <ai.agent.tor@gmail.com>
- inline GTS ID references in retained schema definitions
- compare const, boolean, bounds, and inferred types by directional inclusion
- add regression coverage for compatibility verdicts and dangling local refs

Signed-off-by: Aviator 5 <ai.agent.tor@gmail.com>
@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR updates GTS to specification version 0.13, replacing boolean compatibility results with verdicts and diagnostics, resolving schema references during comparison, improving Draft-07 schema generation and closure, and refining wildcard identifier version matching.

Changes

GTS 0.13 compatibility and schema generation

Layer / File(s) Summary
Verdict-based compatibility engine
gts/src/schema_cast.rs, gts/src/schema_compat.rs, gts/src/schema_semantics.rs
Compatibility now returns Compatible, Incompatible, or Unknown verdicts with structured diagnostics, boolean-equivalent schema support, and exact JSON-number comparisons.
Resolved store comparison APIs
gts/src/store.rs, gts/src/ops.rs, gts/src/lib.rs, gts/src/*_test.rs
Store casting and compatibility checks resolve references, expose document comparison, return version metadata, and use verdict-based results.
Draft-07 schema emission and closure
gts-macros/src/lib.rs, gts-macros/tests/*, gts-macros/README.md, gts/src/schema_traits.rs
Generated schemas use Draft-07, retain and prune definitions, close eligible nested objects, and preserve extension and combinator exceptions.
Optional major versions and wildcard matching
gts-id/src/gts_id_segment.rs, gts-id/src/gts_id_pattern.rs, gts/src/store.rs
Identifier parsing distinguishes unspecified majors from explicit v0, and wildcard matching handles trailing chain wildcards and major-version constraints.
GTS 0.13 release contract
.gts-spec-version, README.md, Cargo.toml, gts/Cargo.toml, gts/src/lib.rs
The specification version, public version constants, numeric-comparison dependency, compatibility output examples, and Rust usage documentation are updated.

Estimated code review effort: 5 (Critical) | ~120 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant GtsOps
  participant GtsStore
  participant SchemaCast
  Client->>GtsOps: request compatibility
  GtsOps->>GtsStore: compare schema identifiers
  GtsStore->>GtsStore: resolve schema references
  GtsStore->>SchemaCast: compare resolved schemas
  SchemaCast-->>GtsStore: return verdicts and diagnostics
  GtsStore-->>GtsOps: return compatibility result
  GtsOps-->>Client: serialize verdict-based response
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title is related to the change, but it is very broad and does not say what was updated for v0.13. Use a more specific title like "Add v0.13 compatibility and schema support".
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codecov-commenter

codecov-commenter commented Jul 29, 2026

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 95.20124% with 31 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
gts/src/store.rs 81.53% 24 Missing ⚠️
gts/src/schema_compat.rs 95.60% 4 Missing ⚠️
gts/src/store_test.rs 99.35% 2 Missing ⚠️
gts/src/schema_semantics.rs 96.29% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (7)
gts-macros/src/lib.rs (1)

1797-1808: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider hoisting the definitions-emptiness block into a shared quote! fragment.

This block is byte-identical in the generic and non-generic branches, like the three pipeline fragments above it. Folding it into the existing shared fragments (or a fourth one) keeps the two branches from drifting.

Also applies to: 1935-1946

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@gts-macros/src/lib.rs` around lines 1797 - 1808, Extract the duplicated
definitions-emptiness logic into a shared quote! fragment alongside the existing
pipeline fragments, then reuse it in both the generic and non-generic branches.
Preserve the current removal of GtsInstanceId, GtsTypeId, and GtsSchemaId and
the behavior of setting definitions to None when the resulting object is empty.
gts/src/store.rs (1)

829-842: 🗄️ Data Integrity & Integration | 🔵 Trivial | 💤 Low value

$ref resolution failures are reported as StoreError::SchemaNotFound. The shared root cause is that StoreError has no variant for "a reference in this document could not be resolved", so both new resolution sites reuse SchemaNotFound, whose Display reads GTS type schema with ID '{0}' not found in store — the payload here is a sentence, not an id. Callers matching on the variant cannot distinguish a genuinely unregistered type from an unresolvable reference (a circular $ref is reported as "not found").

  • gts/src/store.rs#L829-L842: map the resolve_schema_refs errors in cast to a resolution-specific variant (or propagate the underlying StoreError with context) instead of SchemaNotFound.
  • gts/src/store.rs#L986-L991: do the same for both compare_documents arms; note store_test.rs currently asserts StoreError::SchemaNotFound(_) there, so that assertion needs updating alongside.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@gts/src/store.rs` around lines 829 - 842, The cast and compare_documents
paths incorrectly classify resolve_schema_refs failures as SchemaNotFound. Add
or reuse a resolution-specific StoreError variant, update both mapping arms in
gts/src/store.rs lines 829-842 and 986-991 to use it or propagate the underlying
error with context, and update the corresponding store_test.rs assertions to
match the new variant.
gts/src/store_test.rs (1)

6062-6163: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Good cross-operation invariant test. OP#8/OP#9 agreement is exactly the regression the cast resolution change is meant to prevent.

One gap: the test only asserts the two verdict pairs match. Consider also asserting the concrete expected values (backward compatible, forward incompatible) on the cast side, so a future change that makes both paths wrong in the same way still fails.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@gts/src/store_test.rs` around lines 6062 - 6163, Extend
test_cast_and_compatibility_agree_on_referenced_schemas to assert
cast.backward_compatibility is compatible and cast.forward_compatibility is
incompatible, in addition to comparing the cast verdict pair with compatibility.
Keep the existing cross-operation equality assertion unchanged.
gts/src/schema_compat.rs (2)

36-51: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

Intersecting two nontrivial additionalProperties schemas still last-wins.

else { *current = Some(candidate.clone()) } overwrites an existing nontrivial constraint with the new one, so allOf: [{ap: {"type":"string"}}, {ap: {"maxLength": 5}}] loses type: string. The doc comment only promises closedness preservation, so this is consistent with the stated lattice — but the resulting effective schema is weaker than the real intersection and can under-report incompatibilities. Worth a follow-up if schema-valued additionalProperties becomes common in composed types.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@gts/src/schema_compat.rs` around lines 36 - 51, Update
merge_additional_properties_constraint to preserve the intersection of two
non-boolean, schema-valued additionalProperties constraints instead of
overwriting current with candidate in the final else branch. Reuse the existing
schema-combination mechanism in the surrounding module, while retaining the
current false-constraint short-circuit and true-constraint no-op behavior.

193-203: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

Nontrivial derived additionalProperties is treated as loosening.

boolean_schema_value(value) != Some(false) makes additionalProperties: {"type": "string"} on a derived schema count as "explicitly allows", flagging a case that allOf/$ref composition still keeps closed via the base. It errs conservative (fails closed), which matches the surrounding intent, but the message ("loosens additionalProperties") will read as a false positive to authors of partially-open overlays. Consider a distinct message for the non-boolean case.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@gts/src/schema_compat.rs` around lines 193 - 203, The derived
additionalProperties check in the compatibility validation block should
distinguish non-boolean schemas from explicit boolean allowance. Update the
branch using boolean_schema_value so object-valued additionalProperties produces
a separate diagnostic message, while preserving the existing “loosens
additionalProperties” message for an explicit true value and the current
closed-base validation behavior.
gts/src/schema_semantics.rs (1)

3-18: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

Consider whether $ref siblings should defeat boolean-equivalence.

$ref is deliberately absent from NON_ASSERTION_KEYWORDS, so {"$ref": ...} correctly yields None. Just confirming that's intentional given callers pass resolved schemas — an unresolved $ref alongside no other keyword should never be read as true.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@gts/src/schema_semantics.rs` around lines 3 - 18, Confirm and preserve the
intentional exclusion of "$ref" from NON_ASSERTION_KEYWORDS so a schema
containing only an unresolved reference continues returning None rather than
true. Review the boolean-equivalence logic and its callers’ resolved-schema
contract to ensure $ref siblings do not alter this behavior; make no changes
unless the implementation violates that contract.
gts/src/lib.rs (1)

20-24: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Derive GTS_SPECIFICATION_VERSION from the spec pin.

gts/src/lib.rs hardcodes "0.13", while .gts-spec-version is v0.13.0. These formats can fall out of sync on future bumps; include the trimmed file value or add a unit test asserting the constant matches the pinned spec revision.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@gts/src/lib.rs` around lines 20 - 24, Update GTS_SPECIFICATION_VERSION to
derive from the pinned .gts-spec-version value by including and trimming the
file contents, or add a unit test that asserts the constant matches that pin.
Remove the hardcoded "0.13" value while preserving the public constant’s
existing major/minor format.

Source: Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@gts-macros/src/lib.rs`:
- Around line 1619-1640: Update close_schema and its definitions traversal to
avoid inserting additionalProperties: false into definitions referenced by
allOf, anyOf, or oneOf branches. Track reachability from combinator schema
references, or restrict closing to definitions reached through non-combinator
properties, while preserving closure for ordinary non-combinator schemas.

In `@gts/src/store.rs`:
- Around line 854-857: Update is_compatible to resolve both old_type_id and
new_type_id through get_schema_entity instead of get, ensuring only schema
entities are compared. Preserve the existing GtsEntityCastResult behavior and
retain the exact "Schema not found" message for missing schemas.
- Around line 882-901: Introduce GtsEntityCastResult::undecided(old_type_id,
new_type_id, message) to centralize unknown/error result initialization,
including verdicts, version strings, and empty collections. In
gts/src/store.rs:860-879, replace the schema-not-found literal while preserving
"Schema not found" and the "unknown" direction; in gts/src/store.rs:882-901,
replace resolution_failure’s literal with the constructor; and in
gts/src/ops.rs:676-695, replace the GtsOps::cast error literal, passing
e.to_string().

---

Nitpick comments:
In `@gts-macros/src/lib.rs`:
- Around line 1797-1808: Extract the duplicated definitions-emptiness logic into
a shared quote! fragment alongside the existing pipeline fragments, then reuse
it in both the generic and non-generic branches. Preserve the current removal of
GtsInstanceId, GtsTypeId, and GtsSchemaId and the behavior of setting
definitions to None when the resulting object is empty.

In `@gts/src/lib.rs`:
- Around line 20-24: Update GTS_SPECIFICATION_VERSION to derive from the pinned
.gts-spec-version value by including and trimming the file contents, or add a
unit test that asserts the constant matches that pin. Remove the hardcoded
"0.13" value while preserving the public constant’s existing major/minor format.

In `@gts/src/schema_compat.rs`:
- Around line 36-51: Update merge_additional_properties_constraint to preserve
the intersection of two non-boolean, schema-valued additionalProperties
constraints instead of overwriting current with candidate in the final else
branch. Reuse the existing schema-combination mechanism in the surrounding
module, while retaining the current false-constraint short-circuit and
true-constraint no-op behavior.
- Around line 193-203: The derived additionalProperties check in the
compatibility validation block should distinguish non-boolean schemas from
explicit boolean allowance. Update the branch using boolean_schema_value so
object-valued additionalProperties produces a separate diagnostic message, while
preserving the existing “loosens additionalProperties” message for an explicit
true value and the current closed-base validation behavior.

In `@gts/src/schema_semantics.rs`:
- Around line 3-18: Confirm and preserve the intentional exclusion of "$ref"
from NON_ASSERTION_KEYWORDS so a schema containing only an unresolved reference
continues returning None rather than true. Review the boolean-equivalence logic
and its callers’ resolved-schema contract to ensure $ref siblings do not alter
this behavior; make no changes unless the implementation violates that contract.

In `@gts/src/store_test.rs`:
- Around line 6062-6163: Extend
test_cast_and_compatibility_agree_on_referenced_schemas to assert
cast.backward_compatibility is compatible and cast.forward_compatibility is
incompatible, in addition to comparing the cast verdict pair with compatibility.
Keep the existing cross-operation equality assertion unchanged.

In `@gts/src/store.rs`:
- Around line 829-842: The cast and compare_documents paths incorrectly classify
resolve_schema_refs failures as SchemaNotFound. Add or reuse a
resolution-specific StoreError variant, update both mapping arms in
gts/src/store.rs lines 829-842 and 986-991 to use it or propagate the underlying
error with context, and update the corresponding store_test.rs assertions to
match the new variant.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 241afd0d-1127-4f88-b18d-dbec7da18205

📥 Commits

Reviewing files that changed from the base of the PR and between c83b308 and b91c338.

⛔ Files ignored due to path filters (2)
  • Cargo.lock is excluded by !**/*.lock
  • gts-dylint/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (18)
  • .gts-spec-version
  • Cargo.toml
  • README.md
  • gts-id/src/gts_id_pattern.rs
  • gts-id/src/gts_id_segment.rs
  • gts-macros/README.md
  • gts-macros/src/lib.rs
  • gts-macros/tests/inheritance_tests.rs
  • gts-macros/tests/integration_tests.rs
  • gts/Cargo.toml
  • gts/src/lib.rs
  • gts/src/ops.rs
  • gts/src/schema_cast.rs
  • gts/src/schema_compat.rs
  • gts/src/schema_semantics.rs
  • gts/src/schema_traits.rs
  • gts/src/store.rs
  • gts/src/store_test.rs

Comment thread gts-macros/src/lib.rs
Comment thread gts/src/store.rs Outdated
Comment thread gts/src/store.rs Outdated
- compare const, enum, and numeric constraints by accepted values
- handle exact mixed numeric equality and signed-zero bounds
- apply the validator's default dialect to unevaluated properties

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
gts-macros/tests/inheritance_tests.rs (1)

591-605: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Also pin the outer alias hop so the test keeps exercising the fixed-point walk.

The comment on the fixtures states the branch reaches NestedContact through two hops, and the fixed-point loop in gts-macros/src/lib.rs exists for exactly that. The assertion only pins ContactAlias; if Schemars stopped aliasing ContactAliasAlias (e.g. by inlining it), the test would still pass while silently degrading to a one-hop case.

♻️ Assert both hops of the chain
         let schema = SchemaWithAliasedDefinitionV1::gts_schema_with_refs();
+        assert_eq!(
+            schema.pointer("/definitions/ContactAliasAlias/$ref"),
+            Some(&serde_json::json!("`#/definitions/ContactAlias`")),
+            "test relies on a two-hop alias chain:\n{}",
+            serde_json::to_string_pretty(&schema).unwrap()
+        );
         assert_eq!(
             schema.pointer("/definitions/ContactAlias/$ref"),
             Some(&serde_json::json!("`#/definitions/NestedContact`")),
             "test relies on Schemars emitting a bare $ref alias:\n{}",
             serde_json::to_string_pretty(&schema).unwrap()
         );
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@gts-macros/tests/inheritance_tests.rs` around lines 591 - 605, Extend
test_definition_aliased_by_combinator_branch_stays_open to assert that the outer
alias definition, ContactAliasAlias, points to ContactAlias before checking
ContactAlias’s reference and NestedContact openness. This must pin both alias
hops so the test continues exercising the fixed-point traversal.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@gts-macros/tests/inheritance_tests.rs`:
- Around line 591-605: Extend
test_definition_aliased_by_combinator_branch_stays_open to assert that the outer
alias definition, ContactAliasAlias, points to ContactAlias before checking
ContactAlias’s reference and NestedContact openness. This must pin both alias
hops so the test continues exercising the fixed-point traversal.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 5e75d363-8fbf-4d4b-8d2d-1e68cd3a44fb

📥 Commits

Reviewing files that changed from the base of the PR and between b91c338 and d3040c2.

⛔ Files ignored due to path filters (2)
  • Cargo.lock is excluded by !**/*.lock
  • gts-dylint/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (8)
  • Cargo.toml
  • gts-macros/src/lib.rs
  • gts-macros/tests/inheritance_tests.rs
  • gts/Cargo.toml
  • gts/src/ops.rs
  • gts/src/schema_cast.rs
  • gts/src/store.rs
  • gts/src/store_test.rs
🚧 Files skipped from review as they are similar to previous changes (2)
  • gts/Cargo.toml
  • Cargo.toml

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants