Skip to content

feat: add x-gts-final and x-gts-abstract schema modifier support#67

Merged
Artifizer merged 2 commits intoGlobalTypeSystem:mainfrom
aviator5:final-and-abstract-support
Apr 15, 2026
Merged

feat: add x-gts-final and x-gts-abstract schema modifier support#67
Artifizer merged 2 commits intoGlobalTypeSystem:mainfrom
aviator5:final-and-abstract-support

Conversation

@aviator5
Copy link
Copy Markdown
Contributor

@aviator5 aviator5 commented Apr 2, 2026

  • Define section 9.11 with full semantics for final (no inheritance) and abstract (no direct instances) modifiers
  • Update OP#6 and OP#12 descriptions to reference modifier enforcement
  • Add x-gts-abstract to event and capability base schemas, x-gts-final to vm_state schema
  • Add OP#12 tests for final type derivation rejection, mid-chain final, and sibling unaffected
  • Add OP#6 tests for abstract type instance rejection (well-known, anonymous, derived concrete)
  • Add cross-cutting tests for mutual exclusion and combined scenarios

Summary by CodeRabbit

  • New Features

    • Added x-gts-final and x-gts-abstract schema-only modifiers: final blocks derivation; abstract forbids direct instances (instances must use a concrete rightmost derived type).
  • Behavior & Requirements

    • OP#6/OP#12 updated: instances with rightmost abstract must fail; deriving from any final base must fail. Modifiers must be top-level boolean true, mutually exclusive; non-boolean or in-instance placement rejected. Registration-time validation guarded.
  • Documentation

    • Added section detailing semantics, placement, examples, and trait interactions.
  • Examples

    • Marked example schemas as abstract/final and updated descriptions.
  • Tests

    • Extensive tests for registration, derivation, instance validation, trait interactions, and edge cases.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 2, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds two JSON-Schema-only modifiers (x-gts-final, x-gts-abstract), updates OP#6 and OP#12 control-flow rules for validation/registration, marks three example schemas, and adds extensive conformance tests covering placement, semantics, and interactions.

Changes

Cohort / File(s) Summary
Specification
README.md
Added section 9.11 defining x-gts-final and x-gts-abstract (schema-only, boolean true, mutual exclusion, placement rules) and updated OP#6/OP#12 operation requirements to enforce abstract/final semantics.
Example Schemas
examples/events/schemas/gts.x.core.events.type.v1~.schema.json, examples/modules/schemas/gts.x.core.modules.capability.v1~.schema.json, examples/typespec/vms/schemas/states/gts.x.infra.compute.vm_state.v1~.schema.json
Marked the event base schema as x-gts-abstract: true; marked capability and VM state schemas as x-gts-final: true; updated top-level descriptions.
OP#6 Instance Validation Tests
tests/test_op6_schema_validation.py
Added HttpRunner tests asserting instances resolved to an x-gts-abstract: true rightmost type are rejected (well-known and anonymous forms) and that instances of concrete derived types pass; added /validate-entity checks.
OP#12 Schema-vs-Schema Tests
tests/test_op12_schema_vs_schema_validation.py
Extended _register_derived(..., top_level=None) to allow root-level modifiers; added tests ensuring deriving from a x-gts-final: true base (base or mid-chain) is rejected, siblings unaffected, and final type self-validation succeeds.
Conformance Test Suite
tests/test_refimpl_x_gts_final_abstract.py
New comprehensive test module with helpers and many HttpRunner suites covering final/abstract enforcement, placement and non-boolean rejection, mutual exclusion, interactions with x-gts-traits, registration-time guards, and lifecycle scenarios.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant Registry
  participant Validator
  participant Storage

  Client->>Registry: POST /entities (register schema) or POST /instances
  alt registration/validation includes modifiers
    Registry->>Validator: validate registration/operation (resolve metadata)
    Validator->>Storage: fetch referenced schemas (ancestors)
    Validator-->>Registry: accept / reject (apply x-gts-final / x-gts-abstract rules)
  else normal flow
    Registry->>Validator: forward request
    Validator-->>Registry: validation outcome
  end
  Registry->>Storage: store schema/instance if accepted
  Registry-->>Client: 200 + { ok: true/false }
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • Artifizer

Poem

🐇 I hopped through schemas under moonlit rails,

"Final" I nail — no child prevails.
"Abstract" I hum — don't let me be born,
Concrete leaves dance at early morn.
Tests munch carrots, spec-bread on the lawn.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding support for two schema modifiers (x-gts-final and x-gts-abstract) to the specification.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ 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.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🧹 Nitpick comments (4)
tests/test_refimpl_x_gts_final_abstract.py (4)

877-878: Main block only runs one test class.

This is likely intentional for quick manual testing, but consider documenting this or expanding it to run all tests when executed directly.

♻️ Optional: run all tests or add documentation
 if __name__ == "__main__":
-    TestCaseFinal_RejectDerivedSchema().test_start()
+    # Run all test cases for manual execution
+    import sys
+    for name, obj in list(globals().items()):
+        if name.startswith("TestCase") and isinstance(obj, type):
+            print(f"Running {name}...")
+            obj().test_start()

Or simply add a comment explaining the purpose:

 if __name__ == "__main__":
+    # Quick smoke test - use pytest to run all tests
     TestCaseFinal_RejectDerivedSchema().test_start()
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/test_refimpl_x_gts_final_abstract.py` around lines 877 - 878, The
__main__ block currently only executes
TestCaseFinal_RejectDerivedSchema().test_start(), which limits manual runs to a
single test; update the block to either (a) run the full test suite (e.g., call
unittest.main() or iterate over all test case classes and invoke their
test_start methods) or (b) add a clear comment explaining this is intentionally
a single-test quick-run — modify the __main__ section around the
TestCaseFinal_RejectDerivedSchema() call accordingly to implement one of these
options.

568-582: Same issue: missing status_code assertion.

Consistent with the earlier observation on TestCaseFinal_NonBooleanRejected, this test should also include a status_code assertion for robustness.

♻️ Add status_code assertion
     teststeps = [
         Step(
             RunRequest("register schema with abstract=1 should be rejected")
             .post("/entities")
             .with_json({
                 "$$id": "gts://gts.x.testfa.absbadval.base.v1~",
                 "$$schema": "http://json-schema.org/draft-07/schema#",
                 "type": "object",
                 "x-gts-abstract": 1,
                 "properties": {"name": {"type": "string"}},
             })
             .validate()
+            .assert_equal("status_code", 200)
             .assert_equal("body.ok", False)
         ),
     ]
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/test_refimpl_x_gts_final_abstract.py` around lines 568 - 582, The test
case in the teststeps list (the Step built with RunRequest("register schema with
abstract=1 should be rejected") that posts to "/entities") is missing an
assertion for the HTTP status code; update the Step's assertion chain (on the
RunRequest instance) to include a status_code check (e.g.,
.assert_equal("status_code", 400) or the correct expected status) in addition to
the existing .assert_equal("body.ok", False) so the test verifies both body and
HTTP status.

318-332: Missing status_code assertion could lead to fragile test.

This test only asserts body.ok == False without checking status_code. If the server returns a 4xx status code for invalid input (instead of 200 with {ok: false}), the test may fail unexpectedly or pass for the wrong reason. Other tests using helpers consistently assert status_code == 200 first.

♻️ Consider adding explicit status_code handling
     teststeps = [
         Step(
             RunRequest("register schema with final='yes' should be rejected")
             .post("/entities")
             .with_json({
                 "$$id": "gts://gts.x.testfa.finalbadval.base.v1~",
                 "$$schema": "http://json-schema.org/draft-07/schema#",
                 "type": "object",
                 "x-gts-final": "yes",
                 "properties": {"name": {"type": "string"}},
             })
             .validate()
+            .assert_equal("status_code", 200)
             .assert_equal("body.ok", False)
         ),
     ]

Or, if a 4xx status is expected, adjust accordingly and document the expected behavior.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/test_refimpl_x_gts_final_abstract.py` around lines 318 - 332, The test
step using Step(...) with RunRequest("register schema with final='yes' should be
rejected").post("/entities") only asserts assert_equal("body.ok", False) and is
missing a status code assertion; update that Step to include an explicit
.assert_equal("status_code", 200) if the API is expected to return 200 with
{ok:false}, or change it to the expected 4xx (e.g., .assert_equal("status_code",
400)) if invalid input should return an error status, keeping the
RunRequest/assert_equal pattern consistent with other tests.

656-671: Same issue: missing status_code assertion for consistent error handling.

For consistency with other tests, add an explicit status_code assertion.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/test_refimpl_x_gts_final_abstract.py` around lines 656 - 671, The test
Step registering a schema with both x-gts-final and x-gts-abstract lacks an
explicit HTTP status assertion; update the RunRequest step (the Step in the
teststeps list that posts to "/entities") to include an assert_equal for
"status_code" (e.g., .assert_equal("status_code", 400) to match other error
tests) in addition to the existing .assert_equal("body.ok", False).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@README.md`:
- Around line 1524-1530: The table row for the default case is missing the third
column and the emphasis using underscores triggers markdownlint; update the
middle row so it has three pipe-separated columns (Modifier combination |
Inheritance allowed? | Direct instances allowed?) and replace the
underscore-emphasized "_(default / neither)_" with plain text (e.g., "default /
neither" or backticked `default / neither`) so the row reads: | default /
neither | Yes | Yes |; ensure the other rows keep the existing backticked
modifiers like `x-gts-abstract: true` and `x-gts-final: true`.

In `@tests/test_op12_schema_vs_schema_validation.py`:
- Around line 3643-3648: The test sets the modifier "x-gts-final" inside an
allOf overlay via the _register_derived(...) overlay, which doesn't exercise
final semantics because modifiers must be top-level; move "x-gts-final": True
out of the nested allOf and place it at the top-level of the schema object (the
same object that defines "type": "object" and "properties": {"midField":
{"type": "string"}}) so the final modifier is applied correctly; update the same
pattern in the other occurrence (the similar block around lines referenced in
the comment) so both tests assert true final behavior.
- Around line 3588-3616: Change the class attribute teststeps from a mutable
list to an immutable tuple to satisfy RUF012: replace the list literal assigned
to teststeps with a tuple literal containing the same elements (the calls to
_register, _register_derived, and _validate_schema) so it becomes teststeps = (
... ) instead of teststeps = [ ... ]; do the same replacement for the other two
test cases called out (the ones that also populate teststeps) so you avoid
shared mutable state and the linter warning while keeping the same calls to
_register, _register_derived, and _validate_schema.

In `@tests/test_op6_schema_validation.py`:
- Around line 876-917: The test classes define a mutable class-level variable
teststeps as a list (e.g., teststeps = [ Step(...), ... ]) which triggers Ruff
RUF012; change each teststeps assignment to an immutable tuple (teststeps = (
Step(...), ... )) across all new test classes (references: teststeps, Step,
RunRequest, .post, .with_json, .validate, .assert_equal) so the httprunner
semantics remain the same but the class default is no longer mutable; apply this
for the occurrences noted (and any other new test classes in the commit).

In `@tests/test_refimpl_x_gts_final_abstract.py`:
- Around line 699-710: The test places the x-gts-final modifier inside the
overlay dict passed to _register_derived, which causes it to end up inside allOf
instead of at the schema top level; update the _register_derived call (the one
registering "gts://gts.x.testfa.finaltrait.base.v1~x.testfa._.leaf.v1~") to
remove "x-gts-final": True from the overlay/object dict and instead pass it via
the top_level parameter (e.g., top_level={"x-gts-final": True}) so the modifier
is applied at the schema top level as intended.

---

Nitpick comments:
In `@tests/test_refimpl_x_gts_final_abstract.py`:
- Around line 877-878: The __main__ block currently only executes
TestCaseFinal_RejectDerivedSchema().test_start(), which limits manual runs to a
single test; update the block to either (a) run the full test suite (e.g., call
unittest.main() or iterate over all test case classes and invoke their
test_start methods) or (b) add a clear comment explaining this is intentionally
a single-test quick-run — modify the __main__ section around the
TestCaseFinal_RejectDerivedSchema() call accordingly to implement one of these
options.
- Around line 568-582: The test case in the teststeps list (the Step built with
RunRequest("register schema with abstract=1 should be rejected") that posts to
"/entities") is missing an assertion for the HTTP status code; update the Step's
assertion chain (on the RunRequest instance) to include a status_code check
(e.g., .assert_equal("status_code", 400) or the correct expected status) in
addition to the existing .assert_equal("body.ok", False) so the test verifies
both body and HTTP status.
- Around line 318-332: The test step using Step(...) with RunRequest("register
schema with final='yes' should be rejected").post("/entities") only asserts
assert_equal("body.ok", False) and is missing a status code assertion; update
that Step to include an explicit .assert_equal("status_code", 200) if the API is
expected to return 200 with {ok:false}, or change it to the expected 4xx (e.g.,
.assert_equal("status_code", 400)) if invalid input should return an error
status, keeping the RunRequest/assert_equal pattern consistent with other tests.
- Around line 656-671: The test Step registering a schema with both x-gts-final
and x-gts-abstract lacks an explicit HTTP status assertion; update the
RunRequest step (the Step in the teststeps list that posts to "/entities") to
include an assert_equal for "status_code" (e.g., .assert_equal("status_code",
400) to match other error tests) in addition to the existing
.assert_equal("body.ok", False).
🪄 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: 548a7cda-dcec-4395-9e6d-7494e00a771e

📥 Commits

Reviewing files that changed from the base of the PR and between e088287 and 053ab4f.

📒 Files selected for processing (7)
  • README.md
  • examples/events/schemas/gts.x.core.events.type.v1~.schema.json
  • examples/modules/schemas/gts.x.core.modules.capability.v1~.schema.json
  • examples/typespec/vms/schemas/states/gts.x.infra.compute.vm_state.v1~.schema.json
  • tests/test_op12_schema_vs_schema_validation.py
  • tests/test_op6_schema_validation.py
  • tests/test_refimpl_x_gts_final_abstract.py

Comment thread README.md
Comment thread tests/test_op12_schema_vs_schema_validation.py
Comment thread tests/test_op12_schema_vs_schema_validation.py
Comment thread tests/test_op6_schema_validation.py
Comment thread tests/test_refimpl_x_gts_final_abstract.py
@aviator5 aviator5 force-pushed the final-and-abstract-support branch from 053ab4f to d99cc46 Compare April 2, 2026 14:08
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
tests/test_op12_schema_vs_schema_validation.py (1)

25-41: Fail fast on misplaced schema modifiers.

This helper still accepts x-gts-final or x-gts-abstract inside overlay, which quietly nests them under allOf[1] and changes the meaning of the test. Reject that shape here so future cases can’t accidentally exercise a placement bug instead of the modifier semantics.

🛡️ Proposed guard
-def _register_derived(gts_id, base_ref, overlay, label="register derived", top_level=None):
+def _register_derived(gts_id, base_ref, overlay, label="register derived", *, top_level=None):
     """Register a derived schema that uses allOf with a $$ref.
 
     top_level: optional dict of extra keys to add at schema top level
     (e.g. {"x-gts-final": True}) — these MUST NOT go inside allOf.
     """
+    misplaced = {"x-gts-final", "x-gts-abstract"} & overlay.keys()
+    if misplaced:
+        raise ValueError(
+            f"Place {sorted(misplaced)} in top_level, not inside overlay/allOf"
+        )
     body = {
         "$$id": gts_id,
         "$$schema": "http://json-schema.org/draft-07/schema#",
         "type": "object",
         "allOf": [
             {"$$ref": base_ref},
             overlay,
         ],
     }
-    if top_level:
+    if top_level is not None:
         body.update(top_level)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/test_op12_schema_vs_schema_validation.py` around lines 25 - 41, The
helper _register_derived currently allows schema modifier keys to be placed
inside the overlay, which nests them under allOf[1]; add a fail-fast guard in
_register_derived to detect if overlay contains "x-gts-final" or
"x-gts-abstract" (or any disallowed top-level modifier) and raise a clear
exception (e.g., ValueError) instructing the caller to put those keys in
top_level instead; reference the overlay and top_level parameters so callers can
correct placement and ensure tests don’t accidentally exercise placement bugs.
tests/test_refimpl_x_gts_final_abstract.py (1)

35-51: Make _register_derived enforce its own placement rule.

The docstring says modifier keys belong in top_level, but the function still lets callers put them in overlay. A small guard here keeps future conformance tests from silently building the wrong schema shape.

🛡️ Proposed guard
-def _register_derived(gts_id, base_ref, overlay, label="register derived", top_level=None):
+def _register_derived(gts_id, base_ref, overlay, label="register derived", *, top_level=None):
     """Register a derived schema that uses allOf with a $$ref.
 
     top_level: optional dict of extra keys to add at schema top level
     (e.g. {"x-gts-final": True}) — these MUST NOT go inside allOf.
     """
+    misplaced = {"x-gts-final", "x-gts-abstract"} & overlay.keys()
+    if misplaced:
+        raise ValueError(
+            f"Place {sorted(misplaced)} in top_level, not inside overlay/allOf"
+        )
     body = {
         "$$id": gts_id,
         "$$schema": "http://json-schema.org/draft-07/schema#",
         "type": "object",
         "allOf": [
             {"$$ref": base_ref},
             overlay,
         ],
     }
-    if top_level:
+    if top_level is not None:
         body.update(top_level)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/test_refimpl_x_gts_final_abstract.py` around lines 35 - 51, The helper
_register_derived currently allows callers to place modifier/top-level keys
inside the overlay (which becomes an allOf member); add a guard in
_register_derived that inspects the overlay (when it's a dict) and raises an
error if it contains any top-level/modifier keys (e.g. keys starting with
"x-gts-" such as "x-gts-final") so callers must pass those via the top_level
param; implement this by checking overlay.keys() for any key that matches the
modifier prefix (or a small whitelist like {"x-gts-final"}) and raise a
ValueError/Assertion with a clear message referencing _register_derived, overlay
and top_level.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tests/test_refimpl_x_gts_final_abstract.py`:
- Around line 319-331: The test Step that posts to "/entities"
(RunRequest("register schema with final='yes' should be rejected")...) only
asserts body.ok == False and must also assert the expected HTTP status code for
rejected schema registrations; update that RunRequest chain to include
.assert_equal("status_code", <expected_status>) (use the test suite's intended
rejection status, e.g., 400 or 422) so unrelated 5xx responses cannot satisfy
the test. Apply the same change to the other two similar cases that post to
"/entities" and only check body.ok (the other failing registration Steps
referenced in the comment).

---

Nitpick comments:
In `@tests/test_op12_schema_vs_schema_validation.py`:
- Around line 25-41: The helper _register_derived currently allows schema
modifier keys to be placed inside the overlay, which nests them under allOf[1];
add a fail-fast guard in _register_derived to detect if overlay contains
"x-gts-final" or "x-gts-abstract" (or any disallowed top-level modifier) and
raise a clear exception (e.g., ValueError) instructing the caller to put those
keys in top_level instead; reference the overlay and top_level parameters so
callers can correct placement and ensure tests don’t accidentally exercise
placement bugs.

In `@tests/test_refimpl_x_gts_final_abstract.py`:
- Around line 35-51: The helper _register_derived currently allows callers to
place modifier/top-level keys inside the overlay (which becomes an allOf
member); add a guard in _register_derived that inspects the overlay (when it's a
dict) and raises an error if it contains any top-level/modifier keys (e.g. keys
starting with "x-gts-" such as "x-gts-final") so callers must pass those via the
top_level param; implement this by checking overlay.keys() for any key that
matches the modifier prefix (or a small whitelist like {"x-gts-final"}) and
raise a ValueError/Assertion with a clear message referencing _register_derived,
overlay and top_level.
🪄 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: 28a4f8d1-50fe-4e1b-8532-175b9551825f

📥 Commits

Reviewing files that changed from the base of the PR and between 053ab4f and d99cc46.

📒 Files selected for processing (7)
  • README.md
  • examples/events/schemas/gts.x.core.events.type.v1~.schema.json
  • examples/modules/schemas/gts.x.core.modules.capability.v1~.schema.json
  • examples/typespec/vms/schemas/states/gts.x.infra.compute.vm_state.v1~.schema.json
  • tests/test_op12_schema_vs_schema_validation.py
  • tests/test_op6_schema_validation.py
  • tests/test_refimpl_x_gts_final_abstract.py
✅ Files skipped from review due to trivial changes (3)
  • examples/typespec/vms/schemas/states/gts.x.infra.compute.vm_state.v1~.schema.json
  • examples/events/schemas/gts.x.core.events.type.v1~.schema.json
  • examples/modules/schemas/gts.x.core.modules.capability.v1~.schema.json
🚧 Files skipped from review as they are similar to previous changes (1)
  • README.md

Comment thread tests/test_refimpl_x_gts_final_abstract.py
@aviator5 aviator5 force-pushed the final-and-abstract-support branch from d99cc46 to 51ceb37 Compare April 2, 2026 14:41
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tests/test_op6_schema_validation.py`:
- Around line 907-916: The test currently only asserts .body.ok is False for the
abstract-instance rejection but doesn't verify which instance was rejected;
update the Step that uses RunRequest("validate instance of abstract type should
fail") posting to "/validate-instance" to also assert that body.id equals the
submitted instance_id (the same string
"gts.x.test6.abstract.base.v1~x.test6._.my_item.v1"), mirroring the earlier
invalid-instance assertions; apply the same change to the analogous Step at the
other location (the block around lines 962-970) so each rejection path asserts
both body.ok == False and body.id matches the requested instance_id.

In `@tests/test_refimpl_x_gts_final_abstract.py`:
- Around line 98-108: The helper _validate_instance currently only checks
body.ok and can’t ensure the rejected instance matches the stored one; change
_validate_instance (the function that builds the RunRequest to POST
/validate-instance) to accept an optional expect_id parameter (e.g.,
expect_id=None) and, if expect_id is provided, add a conditional assertion on
"body.id" (use .assert_equal("body.id", expect_id)) to the request validation
chain so tests can verify the returned id matches the instance under test while
preserving the existing status_code and body.ok checks.
🪄 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: 5df586e2-f4e4-4330-a48c-35f0c6d8ef94

📥 Commits

Reviewing files that changed from the base of the PR and between d99cc46 and 51ceb37.

📒 Files selected for processing (7)
  • README.md
  • examples/events/schemas/gts.x.core.events.type.v1~.schema.json
  • examples/modules/schemas/gts.x.core.modules.capability.v1~.schema.json
  • examples/typespec/vms/schemas/states/gts.x.infra.compute.vm_state.v1~.schema.json
  • tests/test_op12_schema_vs_schema_validation.py
  • tests/test_op6_schema_validation.py
  • tests/test_refimpl_x_gts_final_abstract.py
✅ Files skipped from review due to trivial changes (3)
  • examples/typespec/vms/schemas/states/gts.x.infra.compute.vm_state.v1~.schema.json
  • examples/events/schemas/gts.x.core.events.type.v1~.schema.json
  • examples/modules/schemas/gts.x.core.modules.capability.v1~.schema.json
🚧 Files skipped from review as they are similar to previous changes (1)
  • README.md

Comment thread tests/test_op6_schema_validation.py
Comment thread tests/test_refimpl_x_gts_final_abstract.py Outdated
@aviator5 aviator5 force-pushed the final-and-abstract-support branch from 51ceb37 to e26cd51 Compare April 3, 2026 08:17
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tests/test_refimpl_x_gts_final_abstract.py`:
- Around line 85-95: The _validate_entity helper should assert the resolved
entity kind on negative paths: add an optional parameter
expected_entity_type=None to _validate_entity and, when expect_ok is False and
expected_entity_type is provided, include .assert_equal("body.entity_type",
expected_entity_type) in the returned step (reference function
_validate_entity). Then update the two failing tests
TestCaseFinal_InInstanceRejected and TestCaseAbstract_InInstanceRejected to call
_validate_entity(..., expect_ok=False, expected_entity_type="instance") so they
verify the response rejects as an "instance" rather than allowing a not-found
response to satisfy the assertion.
🪄 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: aeec1a88-7ff1-4e26-8fb0-309926f39ac8

📥 Commits

Reviewing files that changed from the base of the PR and between 51ceb37 and e26cd51.

📒 Files selected for processing (7)
  • README.md
  • examples/events/schemas/gts.x.core.events.type.v1~.schema.json
  • examples/modules/schemas/gts.x.core.modules.capability.v1~.schema.json
  • examples/typespec/vms/schemas/states/gts.x.infra.compute.vm_state.v1~.schema.json
  • tests/test_op12_schema_vs_schema_validation.py
  • tests/test_op6_schema_validation.py
  • tests/test_refimpl_x_gts_final_abstract.py
✅ Files skipped from review due to trivial changes (3)
  • examples/typespec/vms/schemas/states/gts.x.infra.compute.vm_state.v1~.schema.json
  • examples/modules/schemas/gts.x.core.modules.capability.v1~.schema.json
  • examples/events/schemas/gts.x.core.events.type.v1~.schema.json
🚧 Files skipped from review as they are similar to previous changes (1)
  • README.md

Comment thread tests/test_refimpl_x_gts_final_abstract.py Outdated
@aviator5 aviator5 force-pushed the final-and-abstract-support branch from e26cd51 to 8198f0c Compare April 10, 2026 20:07
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
tests/test_refimpl_x_gts_final_abstract.py (1)

19-113: Consider consolidating duplicated HttpRunner helper builders into a shared test helper module.

_register, _register_derived, _validate_schema, _validate_entity, and _validate_instance are now duplicated across test files; centralizing them would reduce drift risk and future patch duplication.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/test_refimpl_x_gts_final_abstract.py` around lines 19 - 113, The
helpers _register, _register_derived, _register_instance, _validate_schema,
_validate_entity, and _validate_instance are duplicated across tests; extract
them into a shared test helper module (e.g., tests.helpers.http_run_helpers)
that exports these functions and reuses existing RunRequest and Step builders,
keeping behavior such as top_level handling in _register_derived and optional
assertions (expected_entity_type/expected_id); then replace the local copies in
each test file with imports from the new helper module and run the test suite to
ensure signatures and assertions still match.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@README.md`:
- Line 1507: Add a Table of Contents entry linking to the new header "9.11 -
Schema Modifiers (`x-gts-final` / `x-gts-abstract`)" so navigation matches the
content: update the README TOC by inserting a bullet with the appropriate link
text and anchor (matching the header slug) under the existing sections list
(e.g., near other "9.x" entries) so clicking the TOC item scrolls to the "9.11 -
Schema Modifiers (`x-gts-final` / `x-gts-abstract`)" section.

---

Nitpick comments:
In `@tests/test_refimpl_x_gts_final_abstract.py`:
- Around line 19-113: The helpers _register, _register_derived,
_register_instance, _validate_schema, _validate_entity, and _validate_instance
are duplicated across tests; extract them into a shared test helper module
(e.g., tests.helpers.http_run_helpers) that exports these functions and reuses
existing RunRequest and Step builders, keeping behavior such as top_level
handling in _register_derived and optional assertions
(expected_entity_type/expected_id); then replace the local copies in each test
file with imports from the new helper module and run the test suite to ensure
signatures and assertions still match.
🪄 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: a3d59083-ccad-4474-92b5-a505055bfc5d

📥 Commits

Reviewing files that changed from the base of the PR and between e26cd51 and 8198f0c.

📒 Files selected for processing (7)
  • README.md
  • examples/events/schemas/gts.x.core.events.type.v1~.schema.json
  • examples/modules/schemas/gts.x.core.modules.capability.v1~.schema.json
  • examples/typespec/vms/schemas/states/gts.x.infra.compute.vm_state.v1~.schema.json
  • tests/test_op12_schema_vs_schema_validation.py
  • tests/test_op6_schema_validation.py
  • tests/test_refimpl_x_gts_final_abstract.py
✅ Files skipped from review due to trivial changes (3)
  • examples/modules/schemas/gts.x.core.modules.capability.v1~.schema.json
  • examples/typespec/vms/schemas/states/gts.x.infra.compute.vm_state.v1~.schema.json
  • examples/events/schemas/gts.x.core.events.type.v1~.schema.json

Comment thread README.md
@aviator5 aviator5 force-pushed the final-and-abstract-support branch from 8198f0c to 50a203b Compare April 14, 2026 07:37
- Define section 9.11 with full semantics for final (no inheritance) and abstract (no direct instances) modifiers
- Update OP#6 and OP#12 descriptions to reference modifier enforcement
- Add x-gts-abstract to event and capability base schemas, x-gts-final to vm_state schema
- Add OP#12 tests for final type derivation rejection, mid-chain final, and sibling unaffected
- Add OP#6 tests for abstract type instance rejection (well-known, anonymous, derived concrete)
- Add cross-cutting tests for mutual exclusion and combined scenarios

Signed-off-by: Aviator 5 <ai.agent.tor@gmail.com>
@aviator5 aviator5 force-pushed the final-and-abstract-support branch from 50a203b to 776633e Compare April 14, 2026 10:26
Comment thread README.md Outdated
Comment thread README.md
Signed-off-by: Aviator 5 <ai.agent.tor@gmail.com>
@aviator5 aviator5 force-pushed the final-and-abstract-support branch from 0aecf38 to b206ff4 Compare April 15, 2026 10:15
@Artifizer Artifizer merged commit 23ed727 into GlobalTypeSystem:main Apr 15, 2026
2 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.

2 participants