-
Notifications
You must be signed in to change notification settings - Fork 2
Feature - spec upgrade to 0.13 #16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
GeraBart
wants to merge
11
commits into
GlobalTypeSystem:main
Choose a base branch
from
GeraBart:feature/spec_upgrade_to_0.13
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
3ad8d7c
feat: spec upgrade to 0.13
GeraBart 93388d5
test: cover 0.13 compatibility, traits and modifier rules; add CHANGE…
GeraBart 30db917
fix: cast target field, parent-ref check, traits prohibition, malform…
GeraBart 53ee93a
fix: x-gts-ref assertions, cast validation, unresolved refs, bound no…
GeraBart 60c29cb
refactor: remove duplicate cast, derive keyword handling from one tab…
GeraBart 41b134d
fix: position-aware schema walker, shared bound comparator, per-path …
GeraBart ffdb26d
test: add ajv-oracle property test for OP#8; fix invented trait defau…
GeraBart 898ae5f
refactor: break import cycles via EntityLookup; fix trait defaults an…
GeraBart a7f18be
fix: close keyword-placement gaps, tighten registration and cast guar…
GeraBart ac94866
refactor: implementation updated to match gts-rust
GeraBart f25f972
fix: bound schema-resolution path count, close local-ref and x-gts-re…
GeraBart File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Submodule .gts-spec
updated
65 files
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| v0.13.1 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,166 @@ | ||
| # Changelog | ||
|
|
||
| All notable changes to this project are documented in this file. | ||
|
|
||
| The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), | ||
| and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). | ||
|
|
||
| ## [0.4.0] - 2026-08-10 | ||
|
|
||
| Upgrades the implementation from GTS spec **v0.8** to **[v0.13.1](https://github.com/GlobalTypeSystem/gts-spec/releases/tag/v0.13.1)**. | ||
|
|
||
| Spec 0.12 renamed the core terminology (GTS Type / GTS Type Schema / GTS Instance) and | ||
| 0.13 issued a correction to the compatibility rules, so this release contains breaking | ||
| changes to both the HTTP API and the library API. | ||
|
|
||
| ### Breaking - HTTP API | ||
|
|
||
| | Before | After | | ||
| | --------------------------------------------------------------------------- | ------------------------------------------------------------- | | ||
| | `POST /schemas` with the schema as the body | `POST /type-schemas` with `{ "type_id", "type_schema" }` | | ||
| | `POST /validate-schema` with `{ "schema_id" }` | `POST /validate-type-schema` with `{ "type_id" }` | | ||
| | `GET /compatibility?old_schema_id=&new_schema_id=` | `GET /compatibility?old_type_id=&new_type_id=` | | ||
| | `POST /cast` with `{ "instance_id", "to_schema_id" }` | `POST /cast` with `{ "instance_id", "to_type_id" }` | | ||
| | `/extract-id` returned `schema_id`, `selected_schema_id_field`, `is_schema` | returns `type_id`, `selected_type_id_field`, `is_type_schema` | | ||
| | `/parse-id` returned `is_schema` | returns `is_type_schema`, plus a new `is_type` field | | ||
|
|
||
| `GET /compatibility` now returns the tri-state verdicts required by §4.3: | ||
|
|
||
| ```jsonc | ||
| { | ||
| "old": "gts.x.core.events.type.v1.0~", | ||
| "new": "gts.x.core.events.type.v1.1~", | ||
| "backward_compatibility": "compatible", // compatible | incompatible | unknown | ||
| "forward_compatibility": "incompatible", | ||
| "full_compatibility": "incompatible", | ||
| } | ||
| ``` | ||
|
|
||
| The previous boolean fields (`is_backward_compatible`, `is_forward_compatible`, | ||
| `is_fully_compatible`) are still present for compatibility, but `unknown` collapses to | ||
| `false` in them and they cannot express an inconclusive check. Prefer the tri-state fields. | ||
|
|
||
| ### Breaking - library API | ||
|
|
||
| - `ExtractResult`: `schema_id` → `type_id`, `selected_schema_id_field` → `selected_type_id_field`, | ||
| `is_schema` → `is_type_schema`. | ||
| - `ParseResult`: `is_schema` → `is_type_schema`. | ||
| - `CompatibilityResult`: gains `backward_compatibility`, `forward_compatibility` and | ||
| `full_compatibility`, each a `CompatVerdict` (`'compatible' | 'incompatible' | 'unknown'`). | ||
| - `GtsStore.checkCompatibility()` was removed; use `GTS.checkCompatibility()` or | ||
| `GtsCompatibility.checkCompatibility(store, old, new)`. | ||
| - `GtsStore.validateEntityTraits()` was removed. `/validate-entity` and `/validate-type-schema` | ||
| now apply the same type-level checks, so it no longer had separate semantics. | ||
| - `CompatibilityResult.added_properties`, `removed_properties` and `changed_properties` are | ||
| now **always empty** and are deprecated. The engine decides compatibility by comparing | ||
| accepted-instance sets rather than by diffing properties, so it no longer produces a | ||
| property diff. The fields remain on the type and in the `GET /compatibility` response so | ||
| existing consumers keep parsing, but they carry no information and will be removed. | ||
| - **`GtsCast` was removed.** There were two cast implementations - one in the library, one | ||
| in the registry. Only the registry implementation resolved `allOf` / `$ref` on the target | ||
|
GeraBart marked this conversation as resolved.
|
||
| and validated the cast result; the library one did neither. Since GTS derived types _are_ | ||
| `allOf: [{$ref: parent}, …]`, the library version silently dropped every property when | ||
| casting to a derived type. | ||
| `GTS.castInstance()`, the CLI and `POST /cast` now share the registry implementation. | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
| The `CastResult` shape returned by the library and the CLI is unchanged; `POST /cast` | ||
| returns the registry response (`instance_id`, `to_type_id`, `casted_entity`), which is | ||
| what it returned before. | ||
| - Casting no longer refuses when the two type schemas are not fully compatible. Casting is | ||
| a separate operational contract that the spec requires to be reported separately from | ||
| schema compatibility (§4.3, §4.6.3); under 0.13 almost no real schema evolution is | ||
| _fully_ compatible, so the old gate rejected ordinary casts. A cast now succeeds only if | ||
| its **result** satisfies the target type, including that type's `x-gts-ref` constraints. | ||
| - The `direction` field reported `upgrade` / `downgrade` / `same` on `GET /compatibility` | ||
| but `up` / `down` / `none` on `POST /cast`, from two separate implementations. Both now | ||
| use `upgrade` / `downgrade` / `same` / `unknown`, and consider the MAJOR version as well | ||
| as the MINOR. | ||
| - Two shape checks on `x-gts-traits-schema` were dropped: it no longer has to declare | ||
| `type: "object"`, and it may contain a nested `x-gts-traits` member. Per ADR-0002 the | ||
| keyword is an ordinary JSON Schema subschema (object, `true` or `false`), so neither | ||
| restriction has a basis in 0.13; the placement rule deliberately does not scan inside it. | ||
| - The `mode` parameter on `GTS.checkCompatibility()` / `GtsCompatibility.checkCompatibility()` / | ||
| `GET /compatibility?mode=` / the CLI's `-m` flag no longer narrows what gets computed | ||
| (spec §9.2, §4.3 require always computing all three verdicts). It is retained only for | ||
| call-site and display compatibility; the result always contains | ||
| `backward_compatibility`, `forward_compatibility` and `full_compatibility`. | ||
| - `GtsStore.register()` now throws synchronously when a schema's `x-gts-final` / | ||
| `x-gts-abstract` declaration is malformed (§9.11.1: a non-boolean value, or both keywords | ||
| declared `true` on the same schema) instead of registering it uninspected. This changes | ||
| the CLI's directory-load path: `loadEntitiesFromDir` (used by `gts load` and every command | ||
| that loads a directory of entities) already caught the per-entity `register()` call and | ||
| only reports the failure via `console.warn` when `--verbose` is passed - the same pattern | ||
| it uses for an unreadable file or an unparsable JSON document in that function. Without | ||
| `--verbose`, a directory containing a malformed schema now loads with **fewer entities | ||
| registered than files present, and no error**; pass `--verbose` to see which entities were | ||
| skipped and why. | ||
|
|
||
| ### Changed - compatibility semantics (spec 0.13 §4) | ||
|
|
||
| OP#8 was rewritten around accepted-instance-set inclusion rather than a rule-based diff. | ||
| Several verdicts change for inputs that did not change: | ||
|
|
||
| - **Enums.** Adding an enum value is now backward compatible and not forward compatible | ||
| (0.12 reported the opposite). | ||
| - **Open content models.** Adding an optional property to an open object is forward | ||
| compatible, not backward compatible — the old schema already accepted arbitrary values | ||
| under that name. | ||
| - **`const` fields.** Changing a `const` value is neither backward nor forward compatible. | ||
| - Content models are classified from the fully resolved effective schema (after `$ref` | ||
| resolution and `allOf` composition), not from `additionalProperties` alone. | ||
| - An inconclusive comparison reports `unknown` instead of being conflated with | ||
| `incompatible` — for example when the two schemas differ only in a keyword the checker | ||
| does not model, or when a type identifier cannot be resolved. | ||
|
|
||
| ### Added | ||
|
|
||
| - **`x-gts-final` / `x-gts-abstract` (§9.11).** A final type cannot be extended; an abstract | ||
| type cannot be directly instantiated. Enforced at registration (`?validate=true`) and | ||
| always on `/validate-type-schema`, `/validate-instance` and `/validate-entity`. Non-boolean | ||
| values and the `final + abstract` combination are rejected outright. | ||
| - **Document-level keyword placement (§9.7.1, §9.11.5).** `x-gts-final`, `x-gts-abstract`, | ||
| `x-gts-traits-schema` and `x-gts-traits` must appear at the schema top level; an occurrence | ||
| nested in any subschema is rejected rather than silently ignored. | ||
| - **`GtsModifiers`** and `DOCUMENT_LEVEL_KEYWORDS` are exported from the package root. | ||
| - Unit tests covering the compatibility rules table (§4.5), the trait merge and completeness | ||
| rules, the modifier and placement rules, and wildcard matching. | ||
|
|
||
| ### Changed - traits (§9.7.5, ADR-0002/0003/0004) | ||
|
|
||
| - Trait values merge by **JSON Merge Patch (RFC 7396)**: objects merge recursively, arrays | ||
| replace wholesale, and `null` deletes a key. | ||
| - Trait-schema `default`s are materialized before the completeness check, including defaults | ||
| declared on nested object properties. | ||
| - **Completeness is keyed on `x-gts-abstract`**: non-abstract types must validate against the | ||
| effective trait schema; abstract types are exempt. | ||
| - Locking a trait value across descendants is now plain `const` in `x-gts-traits-schema`. | ||
| The bespoke immutability / default-override rules were removed. | ||
| - `x-gts-traits-schema` accepts the boolean subschema forms: `true` permits arbitrary traits, | ||
| `false` prohibits traits on the whole subtree. | ||
|
|
||
| ### Fixed | ||
|
|
||
| - **OP#5**: an identifier that already carries a UUID tail (a combined anonymous instance) | ||
| returns that UUID instead of deriving a second one from the string. | ||
| - **OP#4**: a major-only version wildcard such as `v0.*` no longer matches every major | ||
| version — `v0` was indistinguishable from "no version given". | ||
| - **OP#4**: a bare chain-suffix wildcard (`type.v1~*`) matches the type it is anchored on, | ||
| as well as the identifiers derived from it. | ||
| - **OP#2**: a base type schema reports `type_id: null`. The JSON Schema dialect URL in | ||
| `$schema` is not a GTS Type Identifier and is no longer returned as one. | ||
| - **OP#12**: derivation is validated from the chained `$id` alone, so a derived schema that | ||
| restates its parent's fields instead of using `allOf` + `$ref` is checked too (ADR-0001). | ||
| - **OP#12**: `additionalProperties: true` or an omitted `additionalProperties` in an `allOf` | ||
| overlay is no longer reported as loosening — the base branch keeps applying under `allOf`. | ||
| A level that closes itself must still restate the base's properties. | ||
|
|
||
| ### Notes for implementers | ||
|
|
||
| `OP#4` and `OP#10` disagree in the gts-spec 0.13 conformance suite over whether a bare | ||
| chain-suffix wildcard matches the type it is anchored on. Both verdicts are asserted, so | ||
| `matchIDPattern()` is inclusive by default and `GTS.query()` opts into strictly-derived | ||
| matching. In gts-spec 0.12 both were exclusive; 0.13 flipped only the OP#4 assertions. | ||
|
|
||
| ## [0.3.0] | ||
|
|
||
| - Support for combined anonymous instances and OP#13 schema traits validation. | ||
| - Fastify upgrade; `oneOf` / `anyOf` validation fixes. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.