Skip to content

feat: support gts-spec v0.7#19

Merged
Artifizer merged 9 commits intoGlobalTypeSystem:mainfrom
Artifizer:main
Dec 22, 2025
Merged

feat: support gts-spec v0.7#19
Artifizer merged 9 commits intoGlobalTypeSystem:mainfrom
Artifizer:main

Conversation

@Artifizer
Copy link
Copy Markdown
Contributor

test: implement unit tests for recent changes
chore: bump .gts-spec submodule to v0.7
fix: return and error if it's an instance and GTS ID is not found
doc: update examples in README.md
feat: update implementation to match recent breaking changes with required 'gts://' prefix in $ref
fix: fix clippy and fmt errors
feat(entities): strict schema/instance distinction based on $schema field

…ield

BREAKING CHANGE: Entity classification now strictly follows the rule that
a JSON document is a schema if and only if it has a "$schema" field.

This commit implements a clear distinction between 5 categories of GTS entities:

1. **GTS Schemas** - Have `$schema` field + `$id` with `gts://...~` format
2. **Non-GTS Schemas** - Have `$schema` but no valid GTS `$id` (unsupported)
3. **Well-Known Instances** - No `$schema`, `id` field contains GTS ID with chain
4. **Anonymous Instances** - No `$schema`, `id` field contains UUID, `type` field has GTS schema ID
5. **Unknown Instances** - No `$schema`, no identifiable schema (unsupported)

- **Before**: Schema detection used multiple heuristics (ID ending with `~`, `$id` field, `$schema` URL patterns)
- **After**: A document is a schema **if and only if** it has a `$schema` field

- Added `instance_id` field to `GtsEntity` struct
- For **well-known instances**: `gts_id` = `instance_id` = GTS ID from `id` field
- For **anonymous instances**: `gts_id` = None, `instance_id` = UUID from `id` field
- Added `effective_id()` method that returns appropriate ID for indexing

- **For schemas**: `schema_id` comes from `$schema` field, OR parent segment for chained GTS IDs
- **For well-known instances**: `schema_id` extracted from chain (e.g., `gts.x.base.v1~x.derived.v1.0` → `gts.x.base.v1~`)
- **For anonymous instances**: `schema_id` comes from `type` field
- `selected_schema_id_field` now correctly set to `"id"` when schema_id is derived from chained ID

- `/extract-id` now validates entity structure
- Returns error for `$id` without `$schema` (invalid: `$id` only valid in JSON Schema documents)
- Returns error for entities with no identifiable ID or schema

- Added `instance_id: Option<String>` field to `GtsEntity`
- Replaced `is_json_schema_entity()` with `has_schema_field()` for strict `$schema` check
- Added `extract_schema_ids()` for schema-specific ID extraction
- Added `extract_instance_ids()` for instance-specific ID extraction (well-known vs anonymous)
- Added `get_id_field_value()` and `get_type_field_value()` helper methods
- Added `effective_id()` public method for unified ID access
- Skips `$id` field for instances (only valid for schemas)
- Skips `$schema` field for instance type detection

- Updated to use `effective_id()` instead of `gts_id` for entity discovery
- Enables discovery of anonymous instances with UUID IDs

- Updated `populate_from_reader()` to use `effective_id()`
- Updated `register()` to use `effective_id()` for indexing
- Anonymous instances now properly indexed by their UUID

- Updated `extract_id()` to use `effective_id()`
- Added `validate_gts_entity()` for entity validation
- Added tests for well-known instance chain extraction
- Added tests for single-segment schema ID edge case

// Input: anonymous instance
{"id": "2e5c5d29-...", "type": "gts.x.events.v1~x.contact_created.v1.0~"}

// Output was wrong:
{"id": "gts.x.events.v1~x.contact_created.v1.0~", "schema_id": "gts.x.events.v1~x.contact_created.v1.0~", "is_schema": false}### After (correct)
// Output is now correct:
{"id": "2e5c5d29-...", "schema_id": "gts.x.events.v1~x.contact_created.v1.0~", "is_schema": false}### Well-known instance chain extraction
// Input
{"id": "gts.x.events.v1~abc.app._.custom_event.v1.2"}

// Output
{
  "id": "gts.x.events.v1~abc.app._.custom_event.v1.2",
  "schema_id": "gts.x.events.v1~",
  "selected_entity_field": "id",
  "selected_schema_id_field": "id",  // Now correctly set
  "is_schema": false
}## Migration Notes

- Entities previously detected as schemas based on ID format (ending with `~`)
  will now be classified as instances unless they have a `$schema` field
- Anonymous instances are now properly supported and indexed by their UUID
- The `$id` field is now only processed for documents with `$schema`

Signed-off-by: Artifizer <artifizer@gmail.com>
Signed-off-by: Artifizer <artifizer@gmail.com>
…uired 'gts://' prefix in $ref

JSON Schema $ref should be URI-compatible with gts://, same as $id,
and trimmed back to canonical gts.a.b.c.d... for resolution/registry keys.

Signed-off-by: Artifizer <artifizer@gmail.com>
Signed-off-by: Artifizer <artifizer@gmail.com>
Signed-off-by: Artifizer <artifizer@gmail.com>
Signed-off-by: Artifizer <artifizer@gmail.com>
@Artifizer Artifizer merged commit c31a077 into GlobalTypeSystem:main Dec 22, 2025
6 checks passed
KvizadSaderah added a commit to KvizadSaderah/gts-python that referenced this pull request Dec 23, 2025
Implement Issues #25, #31, #32 from gts-spec v0.7:

Issue #25: Never use GTS ID in $schema
- Strict validation in _is_json_schema_entity()
- Reject gts.* IDs and gts:// URIs in $schema field
- Only JSON Schema URLs allowed
- Add validation in validate_schema() method

Issue #31: Normalize gts:// prefix in $id
- Strip gts:// prefix in _get_field_value()
- Applies to all entity_id_fields and schema_id_fields
- Automatic normalization during ID extraction

Issue #32: Strict $ref validation with gts:// requirement
- Add _validate_schema_refs() static method
- Require gts:// prefix for external GTS refs
- Allow local JSON Pointer refs (#/definitions/...)
- Reject bare GTS IDs and HTTP/HTTPS refs
- Reject malformed GTS IDs after gts:// prefix
- Integrate into validate_schema() as first validation step

Reference implementations:
- gts-rust PR #19: GlobalTypeSystem/gts-rust#19
- gts-spec PR #33: GlobalTypeSystem/gts-spec#33

Signed-off-by: Dmitrii Efremov <kaidendev@icloud.com>
KvizadSaderah added a commit to KvizadSaderah/gts-python that referenced this pull request Dec 23, 2025
Implement Issues #25, #31, #32 from gts-spec v0.7:

Issue #25: Never use GTS ID in $schema
- Strict validation in _is_json_schema_entity()
- Reject gts.* IDs and gts:// URIs in $schema field
- Only JSON Schema URLs allowed

Issue #31: Normalize gts:// prefix in $id
- Strip gts:// prefix in _get_field_value()
- Applies to all entity_id_fields and schema_id_fields
- Automatic normalization during ID extraction

Issue #32: Strict $ref validation with gts:// requirement
- Add _validate_schema_refs() static method
- Require gts:// prefix for external GTS refs
- Allow local JSON Pointer refs (#/definitions/...)
- Reject bare GTS IDs and HTTP/HTTPS refs
- Integrate into validate_schema() as first validation step

Reference implementations:
- gts-rust PR #19: GlobalTypeSystem/gts-rust#19
- gts-spec PR #33: GlobalTypeSystem/gts-spec#33

Signed-off-by: Dmitrii Efremov <kaidendev@icloud.com>
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.

1 participant