Skip to content

feat(gts): port to gts-spec v0.12.0 & switch to GHCR test runner#12

Merged
Artifizer merged 5 commits into
GlobalTypeSystem:mainfrom
aviator5:gts-spec-v0.12-support
May 29, 2026
Merged

feat(gts): port to gts-spec v0.12.0 & switch to GHCR test runner#12
Artifizer merged 5 commits into
GlobalTypeSystem:mainfrom
aviator5:gts-spec-v0.12-support

Conversation

@aviator5

@aviator5 aviator5 commented May 29, 2026

Copy link
Copy Markdown
Contributor

Brings the Go implementation up to gts-spec v0.12.0 and switches the conformance suite to the published GHCR runner image.

Spec alignment

  • Vocabulary rename — schema_id/is_schema → type_id/is_type[_schema] across the REST surface (/type-schemas, /validate-type-schema, query/body params), result types, config, and CLI flags. Hard switch, no aliases.
  • type_id derivation — only carry a $schema value into type_id when it's a valid GTS Type Identifier (ends in ~); JSON Schema dialect URLs are dropped.
  • Instance validation — reject x-gts-traits / x-gts-traits-schema in instance documents (§9.7.1/§9.11.1), via a recursive scan for all four schema-only keywords.
  • Trait & schema-compat semantics (v0.12.0) — treat x-gts-traits-schema as an ordinary subschema composed via allOf (ADR-0002); merge x-gts-traits via RFC 7396 JSON Merge Patch (ADR-0004); key completeness on the
    effective required set (ADR-0003); additionalProperties only loosens on an explicit permissive value at the derived root; enforce top-level-only placement.

Summary by CodeRabbit

  • New Features

    • Introduced new gts-spec-tests Docker-based conformance test runner, replacing Python pytest flow.
    • Enhanced schema traits and modifiers validation with stricter placement rules.
  • Bug Fixes

    • Improved additionalProperties inheritance in schema chains to correctly handle omitted vs explicit values.
  • Documentation

    • Updated testing documentation for new make gts-spec-tests workflow.
    • Updated CLI commands and API endpoints to use consistent "type-schema" terminology.
  • Chores

    • Renamed internal schema/type concepts: SchemaIDTypeID, IsSchemaIsTypeSchema.
    • Updated API endpoints: /schemas/type-schemas, /validate-schema/validate-type-schema.

Review Change Stack

aviator5 added 5 commits May 26, 2026 15:17
Align Go field/JSON-tag/route vocabulary with gts-spec v0.11 terminology:

REST surface
- POST /schemas      -> POST /type-schemas
- POST /validate-schema -> POST /validate-type-schema
- /compatibility query params old_schema_id, new_schema_id -> old_type_id,
  new_type_id
- /cast request body  to_schema_id -> to_type_id
- /validate-type-schema request body schema_id -> type_id
- POST /type-schemas request body  schema -> type_schema (the response
  already used type_id from a prior pass)

Result types
- Inside /resolve-relationships, SchemaGraphNode JSON key schema_id -> type_id
- ValidateSchemaChainResult.schema_id, ValidateSchemaTraitsResult.schema_id
  -> type_id
- EntityInfo.schema_id, EntityInfo.is_schema -> type_id, is_type_schema
- ExtractIDResult.schema_id, .selected_schema_id_field, .is_schema ->
  type_id, selected_type_id_field, is_type_schema
- IDValidationResult.is_schema and ParseIDResult.is_schema -> is_type (per
  spec wording: this boolean answers "is this id a type identifier", while
  entity-extraction results carry the heavier is_type_schema flag)

Internal Go identifiers (kept in sync with JSON tags per maintainer choice)
- JsonEntity.SchemaID / SelectedSchemaIDField / IsSchema -> TypeID /
  SelectedTypeIDField / IsTypeSchema
- GtsConfig.SchemaIDFields -> TypeIDFields (config JSON tag schema_id_fields
  -> type_id_fields)
- calcJSONSchemaID -> calcJSONTypeID
- Cast/compatibility parameters renamed: oldSchemaID/newSchemaID/
  toSchemaID/fromSchemaID -> oldTypeID/newTypeID/toTypeID/fromTypeID
- Mirror the rename across the matching CLI flag help text in cmd/gts/.

ValidateSchema error string "is not a schema (must end with '~')" updated
to "is not a type-schema ID (must end with '~')" for consistency with the
renamed entity check; tests adjusted.

Hard switch: no aliases or deprecated forwards. Matches gts-rust 4a2c43f +
0aa2104 + 32d38f3.

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

Per gts-spec v0.11, the type_id of an entity MUST be a GTS Type Identifier
(a chained id ending in '~') or null. The previous gts-go behavior carried
any non-empty $schema value through to type_id, including JSON Schema
dialect URLs like "http://json-schema.org/draft-07/schema#".

In calcJSONTypeID, only retain the $schema value as the derived type_id
when it both ends in '~' and parses via IsValidGtsID; otherwise drop the
value but still record SelectedTypeIDField="$schema" so callers see we did
look at it.

Existing test TestExtractID_SchemaIDFallback updated to assert the dialect
URL is no longer carried through, plus two new positive/negative cases for
the tightened check.

Mirrors gts-rust 2e1d92c.

Signed-off-by: Aviator 5 <ai.agent.tor@gmail.com>
Per gts-spec §9.7.1 / §9.11.1, the x-gts-traits and x-gts-traits-schema
annotations are valid only on type-schema documents and implementations
MUST reject instances that contain them. gts-go previously only rejected
x-gts-final and x-gts-abstract, and only at the top level.

- Promote x-gts-traits[-schema] to public constants KeyXGtsTraits /
  KeyXGtsTraitsSchema in schema_traits.go (with §9.7.1 reference in the
  doc comment) and replace the string literals in this file.
- Extend ValidateInstanceModifiers to a recursive scan over both objects
  and arrays for any of the four schema-only keywords (x-gts-final,
  x-gts-abstract, x-gts-traits-schema, x-gts-traits). This also tightens
  the pre-existing top-level-only check for x-gts-final / x-gts-abstract
  to match the Rust impl's contains_key_recursive behavior.
- Three new unit tests: top-level x-gts-traits, top-level
  x-gts-traits-schema, and nested x-gts-traits under a metadata object.

Mirrors gts-rust 4bfd06d.

Signed-off-by: Aviator 5 <ai.agent.tor@gmail.com>
- Pin the gts-spec version in .gts-spec-version (v0.11.0). The tag is
  used verbatim as the GHCR image tag; default format vMAJOR.MINOR.PATCH
  so every commit is reproducible, override to vMAJOR.MINOR for the
  rolling minor tag.
- Replace `make e2e` and the Python venv it required with
  `make gts-spec-tests` — one-shot target that builds the gts binary,
  pulls ghcr.io/globaltypesystem/gts-spec-tests:\$(cat .gts-spec-version),
  starts the server bound to 0.0.0.0:\$PORT (so the test-runner container
  can reach it via host.docker.internal on Linux, where Docker doesn't
  route loopback transparently the way Docker Desktop does on Mac/
  Windows), and runs pytest inside the container. TEST=, PORT=,
  GTS_SPEC_TESTS_DIR= cover single-test, port, and local-tests-mount
  overrides.
- Add `make gts-server` (foreground build + run) and
  `make gts-spec-tests-run` (docker run against an externally-running
  server) for the iterative test-edit loop, sharing the docker invocation
  via a RUN_TESTS_DOCKER macro.
- Group all gts-spec-related variables, macros, and targets into a
  dedicated section at the bottom of the Makefile.
- Remove the .gts-spec git submodule (and .gitmodules), drop
  update-spec/e2e-venv targets and PYTHON/VENV_DIR/VENV_PY vars, and
  strip submodules: recursive from every CI checkout step.
- Rename the CI job e2e -> gts-spec-tests; drop the Python setup steps
  and inline server wait loop (the Makefile does both now).
- Rewrite the README and CLAUDE.md gts-spec-tests sections for the
  docker flow (one-shot + iterative) and drop the macOS open-files
  workaround — no Python harness means no leaked sockets means no FD
  limit problem. Point CLI-example users at a local clone of gts-spec.

Mirrors gts-rust a57c57d.

Signed-off-by: Aviator 5 <ai.agent.tor@gmail.com>
- Bump conformance target from v0.11.0 to v0.12.0.
- Treat x-gts-traits-schema as an ordinary JSON Schema subschema (ADR-0002):
  accept object/`true`/`false` forms; compose the chain via allOf; a `false`
  anywhere makes the effective schema unsatisfiable (traits prohibited).
- Merge x-gts-traits values along the chain via RFC 7396 JSON Merge Patch
  (ADR-0004, last-wins); drop GTS-specific lock/duplicate-default rules in
  favor of standard JSON Schema `const`.
- Key trait completeness on the effective schema's `required` set (ADR-0003);
  abstract types skip the completeness check.
- additionalProperties only loosens when derived *explicitly* declares a
  permissive value at its root; omitting it inherits the closed base via
  $ref/allOf composition. Drop duplicate-sibling-$ref rejection (redundant
  manual aggregation is allowed) and resolve nested $refs in allOf siblings.
- Enforce x-gts-traits / x-gts-traits-schema placement at the schema top
  level only, wired into add-entity and validate-entity (gts-spec §9.7.1/§9.11).

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

coderabbitai Bot commented May 29, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

This PR refactors the codebase from "schema" to "type-schema" semantics across data models, validation logic, and public APIs. It also migrates the test infrastructure from git-submodule-based pytest workflows to Docker-based conformance test runners orchestrated through make targets, removing the .gts-spec submodule and pinning the spec version in .gts-spec-version.

Changes

Type-Schema Terminology Refactoring

Layer / File(s) Summary
Test Infrastructure Migration
.github/workflows/ci.yml, .gitmodules, .gts-spec, .gts-spec-version, Makefile, README.md, CLAUDE.md
Removes .gts-spec submodule, adds pinned spec version v0.12.0, replaces pytest-based e2e job with make gts-spec-tests Docker runner. Makefile adds targets for server startup, test execution, version validation, and image pulling. CI workflows remove submodule checkouts. Docs updated with Docker-based runner instructions, port overrides, local test mounting, and two-terminal development workflows.
Core Data Model Refactoring
gts/config.go, gts/extract.go, gts/parse.go, gts/ops.go
GtsConfig.SchemaIDFieldsTypeIDFields. JsonEntity/ExtractIDResult replace IsSchema/SchemaID/SelectedSchemaIDField with IsTypeSchema/TypeID/SelectedTypeIDField. ParseIDResult.IsSchemaIsType. IDValidationResult.IsSchemaIsType. New calcJSONTypeID extracts type identifiers from $schema (when ending with ~) and entity ID chains.
ID Extraction and Validation Tests
gts/extract_test.go, gts/parse_test.go
Tests updated to validate TypeID, SelectedTypeIDField, and IsTypeSchema extraction. New tests for $schema as GTS type identifier, rejection of non-GTS $schema, and entity-chain type derivation. TestExtractID_SchemaIDFallback refactored to type-schema semantics.
Store and Validation API Updates
gts/store.go, gts/validate.go, gts/cast.go, gts/compatibility.go
RegisterSchema creates entities with IsTypeSchema: true. GetSchemaContent requires IsTypeSchema. EntityInfo exposes TypeID/IsTypeSchema. ValidateInstance uses obj.TypeID instead of obj.SchemaID. ValidateInstanceWithXGtsRef rejects type-schema entities, requires TypeID, and validates resolved entity is type-schema. GTS reference validation limited to type-schemas. Cast(instanceID, toTypeID) and CheckCompatibility(oldTypeID, newTypeID) updated.
Server Endpoints and CLI
server/server.go, server/handlers.go, cmd/gts/cast.go, cmd/gts/compatibility.go, cmd/gts/helpers.go
Routes changed: POST /schemasPOST /type-schemas, POST /validate-schemaPOST /validate-type-schema. Handlers updated to read old_type_id/new_type_id (Compatibility), to_type_id (Cast), type_id (Validate). OP#12 Validate Type-Schema introduced, running schema-chain and schema-traits validation on success. CLI help text updated to "type-schema" terminology. Config loading uses type_id_fields.
Complex Schema Validation Logic
gts/schema_compat.go, gts/schema_compat_test.go, gts/schema_modifiers.go, gts/schema_modifiers_test.go, gts/schema_traits.go, gts/schema_traits_test.go, gts/relationships.go, gts/registry_test.go
ValidateSchemaChainResult.SchemaIDTypeID. additionalProperties inheritance refactored: derived schemas inherit base closedness unless explicitly setting additionalProperties at root (not via allOf). $ref resolution removes duplicate-sibling tracking, uses DFS-path cycle detection only. ValidateTraitPlacement added to enforce top-level placement of x-gts-traits/x-gts-traits-schema. ValidateInstanceModifiers now rejects schema-only keywords recursively anywhere in instance content. Trait schema collection supports arbitrary subschema values, merges via RFC 7396, builds effective schema via allOf with true as identity, false as unsatisfiable. Required-trait completeness checks aggregate required across composed schemas. Abstract types skip completeness. SchemaGraphNode.SchemaIDTypeID. Comprehensive tests added for trait-chain semantics, descendant overrides, const-locking, inheritance, boolean trait-schema modes, and entity-level enforcement.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • GlobalTypeSystem/gts-go#10: Introduces OP#12 (schema-chain compatibility) and OP#13 (schema traits) validation; this PR refactors those same implementations to use the type-schema model.
  • GlobalTypeSystem/gts-go#11: Also modifies schema modifiers and validation wiring; this PR extends and refactors those changes under type-schema terminology.

Suggested reviewers

  • Artifizer

Poem

🐰 In type-schemas we trust, through /types we roam,
Docker runners now deliver tests back home,
Fields renamed with care, from schema to type,
Validation rewritten, each check now precise,
The refactoring hops on, through layers of light! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 55.41% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
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.
Title check ✅ Passed The title clearly and concisely describes the primary change: updating gts-go to support GTS spec v0.12.0 and switching the test runner infrastructure from a submodule-based pytest flow to a GHCR-hosted test runner.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 and usage tips.

@aviator5 aviator5 marked this pull request as draft May 29, 2026 13:25
@codecov-commenter

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 66.86567% with 111 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
gts/schema_traits.go 76.29% 25 Missing and 7 partials ⚠️
server/handlers.go 0.00% 21 Missing ⚠️
gts/store.go 30.43% 13 Missing and 3 partials ⚠️
gts/schema_compat.go 77.14% 7 Missing and 1 partial ⚠️
gts/validate.go 44.44% 3 Missing and 2 partials ⚠️
server/server.go 0.00% 5 Missing ⚠️
gts/compatibility.go 75.00% 4 Missing ⚠️
gts/ops.go 0.00% 4 Missing ⚠️
gts/cast.go 78.57% 1 Missing and 2 partials ⚠️
gts/parse.go 40.00% 3 Missing ⚠️
... and 6 more

📢 Thoughts on this report? Let us know!

@aviator5 aviator5 marked this pull request as ready for review May 29, 2026 15:34
@aviator5 aviator5 changed the title Gts spec v0.12 support feat(gts): port to gts-spec v0.12.0 & switch to GHCR test runner May 29, 2026

@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: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
gts/store.go (1)

176-179: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Prevent panic on empty type_id in RegisterSchema

RegisterSchema does typeID[len(typeID)-1], which panics when typeID == ""; the HTTP endpoint POST /type-schemas forwards req.TypeID (from json:"type_id") without non-empty validation. ValidateSchema already uses strings.HasSuffix, so RegisterSchema should match.

🛡️ Proposed fix
-	if typeID[len(typeID)-1] != '~' {
+	if !strings.HasSuffix(typeID, "~") {
		return fmt.Errorf("schema type_id must end with '~'")
	}
🤖 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/store.go` around lines 176 - 179, RegisterSchema currently accesses
typeID[len(typeID)-1] which panics on an empty string; change the check to use
strings.HasSuffix(typeID, "~") or first verify len(typeID) > 0 and then check
the last char so it safely returns an error instead of panicking. Update the
error path in RegisterSchema (referencing the RegisterSchema method) to match
ValidateSchema's behavior and error message semantics so empty or non-suffixed
typeIDs produce a controlled error rather than a runtime panic.
🧹 Nitpick comments (1)
gts/schema_modifiers.go (1)

110-117: 💤 Low value

Recursive instance validation thoroughness vs performance.

The recursive check for schema-only keywords in instances is comprehensive but will traverse the entire instance tree. For deeply nested or large instances, this could add measurable overhead.

Consider benchmarking typical instance sizes if this becomes a hot path.

🤖 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/schema_modifiers.go` around lines 110 - 117, The recursive check in
ValidateInstanceModifiers calling containsKeyRecursive can be very costly for
deeply nested instances; modify containsKeyRecursive (and its callers) to
support an explicit maxDepth (or convert it to an iterative stack-based
traversal) and have ValidateInstanceModifiers pass a reasonable defaultDepth
constant to short-circuit traversal beyond that depth, returning no-match rather
than exploring arbitrarily deep trees; update the function signatures
(containsKeyRecursive) and add/document a DEFAULT_MAX_INSTANCE_CHECK_DEPTH used
by ValidateInstanceModifiers to avoid unbounded recursion and improve
performance on large instances while preserving correctness for typical cases.
🤖 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 `@cmd/gts/helpers.go`:
- Line 73: Document the breaking config change (rename of schema_id_fields →
type_id_fields) in the PR description and migration notes so users know to
update their JSON config, and add backward-compatible parsing: update the struct
that defines TypeIDFields to accept the old key as well (either add an auxiliary
SchemaIDFields string slice and in a custom UnmarshalJSON or in post-unmarshal
logic copy SchemaIDFields into TypeIDFields when present, or implement
UnmarshalJSON to read both "type_id_fields" and "schema_id_fields"); mention and
update any references to TypeIDFields and ensure both keys are handled to avoid
breaking existing configs while you announce the change.

In `@gts/extract.go`:
- Around line 80-83: Remove the redundant recomputation: delete the conditional
block that checks entity.TypeID == "" and calls entity.calcJSONTypeID(cfg,
entityIDValue) (the later block around the well-known instance handling), since
TypeID was already derived earlier via entity.TypeID =
entity.calcJSONTypeID(cfg, entityIDValue) and calcJSONTypeID depends only on
cfg, entityIDValue, and entity.SelectedEntityField (set by calcJSONEntityID). If
you prefer to keep a comment, replace the block with a single clarifying comment
stating that TypeID has already been derived by calcJSONTypeID and will not
change for instances; do not re-invoke calcJSONTypeID or reference entity.GtsID
in this path.

---

Outside diff comments:
In `@gts/store.go`:
- Around line 176-179: RegisterSchema currently accesses typeID[len(typeID)-1]
which panics on an empty string; change the check to use
strings.HasSuffix(typeID, "~") or first verify len(typeID) > 0 and then check
the last char so it safely returns an error instead of panicking. Update the
error path in RegisterSchema (referencing the RegisterSchema method) to match
ValidateSchema's behavior and error message semantics so empty or non-suffixed
typeIDs produce a controlled error rather than a runtime panic.

---

Nitpick comments:
In `@gts/schema_modifiers.go`:
- Around line 110-117: The recursive check in ValidateInstanceModifiers calling
containsKeyRecursive can be very costly for deeply nested instances; modify
containsKeyRecursive (and its callers) to support an explicit maxDepth (or
convert it to an iterative stack-based traversal) and have
ValidateInstanceModifiers pass a reasonable defaultDepth constant to
short-circuit traversal beyond that depth, returning no-match rather than
exploring arbitrarily deep trees; update the function signatures
(containsKeyRecursive) and add/document a DEFAULT_MAX_INSTANCE_CHECK_DEPTH used
by ValidateInstanceModifiers to avoid unbounded recursion and improve
performance on large instances while preserving correctness for typical cases.
🪄 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

Run ID: dff84dbd-b1df-42b4-bd05-19510277f19d

📥 Commits

Reviewing files that changed from the base of the PR and between f27eebf and 0343be4.

📒 Files selected for processing (30)
  • .github/workflows/ci.yml
  • .gitmodules
  • .gts-spec
  • .gts-spec-version
  • CLAUDE.md
  • Makefile
  • README.md
  • cmd/gts/cast.go
  • cmd/gts/compatibility.go
  • cmd/gts/helpers.go
  • gts/cast.go
  • gts/compatibility.go
  • gts/config.go
  • gts/extract.go
  • gts/extract_test.go
  • gts/ops.go
  • gts/parse.go
  • gts/parse_test.go
  • gts/registry_test.go
  • gts/relationships.go
  • gts/schema_compat.go
  • gts/schema_compat_test.go
  • gts/schema_modifiers.go
  • gts/schema_modifiers_test.go
  • gts/schema_traits.go
  • gts/schema_traits_test.go
  • gts/store.go
  • gts/validate.go
  • server/handlers.go
  • server/server.go
💤 Files with no reviewable changes (2)
  • .gitmodules
  • .gts-spec

Comment thread cmd/gts/helpers.go
var data struct {
EntityIDFields []string `json:"entity_id_fields"`
SchemaIDFields []string `json:"schema_id_fields"`
TypeIDFields []string `json:"type_id_fields"`

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Document the breaking config file format change.

The JSON config field rename from schema_id_fields to type_id_fields is a breaking change for existing users. Consider documenting this in migration notes or the PR description so users know to update their config files.

Also applies to: 83-83

🤖 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 `@cmd/gts/helpers.go` at line 73, Document the breaking config change (rename
of schema_id_fields → type_id_fields) in the PR description and migration notes
so users know to update their JSON config, and add backward-compatible parsing:
update the struct that defines TypeIDFields to accept the old key as well
(either add an auxiliary SchemaIDFields string slice and in a custom
UnmarshalJSON or in post-unmarshal logic copy SchemaIDFields into TypeIDFields
when present, or implement UnmarshalJSON to read both "type_id_fields" and
"schema_id_fields"); mention and update any references to TypeIDFields and
ensure both keys are handled to avoid breaking existing configs while you
announce the change.

Comment thread gts/extract.go
Comment on lines +80 to 83
// Type ID should be derived from the chain if not explicitly set
if entity.TypeID == "" && entity.SelectedEntityField != "" {
entity.TypeID = entity.calcJSONTypeID(cfg, entityIDValue)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
ast-grep --pattern $'func (e *JsonEntity) calcJSONTypeID($$$) string {
  $$$
}'

Repository: GlobalTypeSystem/gts-go

Length of output: 2890


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "---- gts/extract.go (lines 40-110) ----"
nl -ba gts/extract.go | sed -n '40,110p'

echo
echo "---- search for calcJSONTypeID call sites ----"
rg -n "calcJSONTypeID\\(" gts/extract.go

echo
echo "---- inspect JsonEntity struct fields (to see what calcJSONTypeID may read/write) ----"
rg -n "type JsonEntity" gts/extract.go

Repository: GlobalTypeSystem/gts-go

Length of output: 168


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "---- gts/extract.go excerpt (around reported block) ----"
awk 'NR>=45 && NR<=110 {printf "%6d\t%s\n", NR, $0}' gts/extract.go | sed -n '1,200p'

echo
echo "---- calcJSONTypeID call sites in gts/extract.go ----"
rg -n "calcJSONTypeID\\(" gts/extract.go

echo
echo "---- JsonEntity definition (fields potentially touched by calcJSONTypeID) ----"
# Print enough context around the struct definition
line=$(rg -n "type JsonEntity" gts/extract.go | head -n 1 | cut -d: -f1)
start=$((line-10))
end=$((line+120))
awk -v s="$start" -v e="$end" 'NR>=s && NR<=e {printf "%6d\t%s\n", NR, $0}' gts/extract.go | sed -n '1,260p'

Repository: GlobalTypeSystem/gts-go

Length of output: 8204


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "---- calcJSONEntityID implementation ----"
ast-grep --pattern $'func (e *JsonEntity) calcJSONEntityID($$$) string { $$$ }' gts/extract.go

Repository: GlobalTypeSystem/gts-go

Length of output: 372


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "---- firstNonEmptyField implementation ----"
ast-grep --pattern $'func (e *JsonEntity) firstNonEmptyField($$$) { $$$ }' gts/extract.go

echo
echo "---- getFieldValue implementation (if present in extract.go) ----"
rg -n "func \\(e \\*JsonEntity\\) getFieldValue\\(" gts/extract.go || true
rg -n "getFieldValue\\(" gts/extract.go

echo
# Print nearby code around getFieldValue if we found it
line=$(rg -n "func \\(e \\*JsonEntity\\) getFieldValue\\(" gts/extract.go | head -n 1 | cut -d: -f1 || true)
if [ -n "${line:-}" ]; then
  start=$((line-20))
  end=$((line+80))
  awk -v s="$start" -v e="$end" 'NR>=s && NR<=e {printf "%6d\t%s\n", NR, $0}' gts/extract.go
fi

Repository: GlobalTypeSystem/gts-go

Length of output: 111


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "---- locate firstNonEmptyField ----"
rg -n "firstNonEmptyField" gts/extract.go

echo
echo "---- locate getFieldValue (impl + call sites) ----"
rg -n "getFieldValue" gts/extract.go

echo
echo "---- show likely helper implementations area (around matches) ----"
for pat in "firstNonEmptyField" "getFieldValue"; do
  line=$(rg -n "func \\(e \\*JsonEntity\\) ${pat}\\b" gts/extract.go | head -n 1 | cut -d: -f1 || true)
  if [ -n "${line:-}" ]; then
    start=$((line-30)); end=$((line+120))
    echo
    echo "### ${pat} around line ${line}"
    awk -v s="$start" -v e="$end" 'NR>=s && NR<=e {printf "%6d\t%s\n", NR, $0}' gts/extract.go
  fi
done

Repository: GlobalTypeSystem/gts-go

Length of output: 11662


Remove redundant calcJSONTypeID recomputation in well-known instance block

entity.TypeID is already set via entity.TypeID = entity.calcJSONTypeID(cfg, entityIDValue) (line 65). The later block (lines 80-83) reruns calcJSONTypeID(cfg, entityIDValue) only when entity.TypeID == "", but calcJSONTypeID for instances depends only on cfg, entityIDValue, and e.SelectedEntityField (which was set once by calcJSONEntityID and isn’t modified between lines 65 and 80-83); it does not use entity.GtsID. So this second call cannot change entity.TypeID (it will recompute "" again). Remove the block or adjust the comment/logic to match the intended derivation behavior.

🤖 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/extract.go` around lines 80 - 83, Remove the redundant recomputation:
delete the conditional block that checks entity.TypeID == "" and calls
entity.calcJSONTypeID(cfg, entityIDValue) (the later block around the well-known
instance handling), since TypeID was already derived earlier via entity.TypeID =
entity.calcJSONTypeID(cfg, entityIDValue) and calcJSONTypeID depends only on
cfg, entityIDValue, and entity.SelectedEntityField (set by calcJSONEntityID). If
you prefer to keep a comment, replace the block with a single clarifying comment
stating that TypeID has already been derived by calcJSONTypeID and will not
change for instances; do not re-invoke calcJSONTypeID or reference entity.GtsID
in this path.

@Artifizer Artifizer merged commit 055ecee into GlobalTypeSystem:main May 29, 2026
9 checks passed
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.

3 participants