Skip to content

feat(spec): 0.8Beta2 implement specification for traits and introduce OP#13 for traits validation#61

Merged
Artifizer merged 6 commits intoGlobalTypeSystem:mainfrom
Artifizer:main
Feb 17, 2026
Merged

feat(spec): 0.8Beta2 implement specification for traits and introduce OP#13 for traits validation#61
Artifizer merged 6 commits intoGlobalTypeSystem:mainfrom
Artifizer:main

Conversation

@Artifizer
Copy link
Copy Markdown
Contributor

@Artifizer Artifizer commented Feb 17, 2026

This commit introduces traits schema and values definition rules that can be used to configure semantic behaviour of the systems that need to interpret objects/instances differently depending on it's type

Summary by CodeRabbit

  • New Features

    • Introduced Schema Traits (x-gts-traits-schema / x-gts-traits) with topicRef and retention support; example event schemas updated to include trait objects and defaults.
  • Documentation

    • TOC and reference reorganized and renumbered to add normative 9.7 Schema Traits section; version bumped to 0.8Beta2; downstream sections renumbered (TypeSpec, UUID).
  • Tests

    • Added comprehensive OP#13 traits validation suites and expanded OP#12 cycle-detection tests for broader coverage.

… OP#13 for traits validation

This commit introduces traits schema and values definition rules that can be used
to configure semantic behaviour of the systems that need to interpret objects/instances
differently depending on it's type

Signed-off-by: Artifizer <artifizer@gmail.com>
- OP#12: add schema-vs-schema validation cases for self-ref and multi-node ref cycles
- OP#13: add traits validation cases for cycling refs inside x-gts-traits-schema
- Avoid HttpRunner variable interpolation by removing "$ref" from test names/labels

Signed-off-by: Artifizer <artifizer@gmail.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Feb 17, 2026

📝 Walkthrough

Walkthrough

Adds a new Schema Traits feature and documentation (section 9.7), refactors example event schemas to use trait schema objects and per-schema trait values, expands OP#12 cycle-detection tests, and introduces a large OP#13 HTTP-driven test suite for trait validation and resolution.

Changes

Cohort / File(s) Summary
Specification Documentation
README.md
Added public Schema Traits section (9.7 with 9.7.1–9.7.5), updated TOC and renumbered subsequent sections (TypeSpec → 9.9, UUID → 9.10), and expanded OP coverage to include OP#13.
Example Event Schemas
examples/events/schemas/gts.x.core.events.type.v1~.schema.json, examples/events/schemas/gts.x.core.events.type.v1~x.commerce.orders.order_placed.v1.0~.schema.json, examples/events/schemas/gts.x.core.events.type.v1~x.commerce.orders.order_placed.v1.1~.schema.json, examples/events/schemas/gts.x.core.idp.contact_created.v1~.schema.json
Replaced x-event-type-settings with structured x-gts-traits-schema in the base type and added x-gts-traits objects in derived schemas (e.g., topicRef, retention), including defaults and new trait property definitions.
OP#12 Cycle Detection Tests
tests/test_op12_schema_vs_schema_validation.py
Added three cycle-detection test suites covering self-reference, two-node, and three-node cycles for derived schemas referencing each other via $ref/allOf.
OP#13 Traits Validation Tests
tests/test_op13_schema_traits_validation.py
New comprehensive HTTP-driven test module (~25+ test classes) with helper functions and end-to-end tests covering trait schema definitions, defaults, overrides, merging/narrowing semantics, constraint validations (enum/min/max/const), unknown properties, AP/extension edge cases, ref-based and cross-file resolution, and cycle detection for trait refs.

Sequence Diagram(s)

sequenceDiagram
    actor Client
    participant SchemaRegistry
    participant TraitResolver
    participant Validator

    Client->>SchemaRegistry: POST /register base schema (includes x-gts-traits-schema)
    SchemaRegistry-->>Client: 200 OK

    Client->>SchemaRegistry: POST /register derived schema (x-gts-traits / allOf / $ref)
    SchemaRegistry->>TraitResolver: resolve trait chain (derived → base → refs)
    TraitResolver->>TraitResolver: merge trait values, apply defaults & narrowing
    TraitResolver-->>SchemaRegistry: store resolved trait view

    Client->>Validator: POST /validate-schema or /validate-entity
    Validator->>TraitResolver: request resolved traits for schema/entity
    TraitResolver-->>Validator: merged trait values
    Validator->>Validator: enforce trait constraints (enum, min, max, const, required)
    Validator-->>Client: validation result (OK / error)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🐇 I nibble traits from schema beds,

I weave defaults through branching threads,
I chase the cycles, sniff the bounds,
I hop where merged metadata resounds,
A little rabbit — tests pass, joy abounds!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 10.53% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title directly and comprehensively describes the main changes: implementing the 0.8Beta2 specification for traits and introducing OP#13 for traits validation, which aligns with the core objectives shown in the changeset.

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Warning

Review ran into problems

🔥 Problems

Git: Failed to clone repository. Please run the @coderabbitai full review command to re-trigger a full review. If the issue persists, set path_filters to include or exclude specific files.


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

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

3345-3391: Annotate mutable class attributes with ClassVar.

teststeps is a mutable class attribute in all three new test classes, and Ruff flags this (RUF012). Adding ClassVar keeps lint clean and clarifies intent for type checkers.

♻️ Suggested update
+from typing import ClassVar
 from .conftest import get_gts_base_url
 from httprunner import HttpRunner, Config, Step, RunRequest
@@
 class TestCaseOp12_CyclingRef_SelfReference(HttpRunner):
@@
-    teststeps = [
+    teststeps: ClassVar = [
@@
 class TestCaseOp12_CyclingRef_TwoNodeCycle(HttpRunner):
@@
-    teststeps = [
+    teststeps: ClassVar = [
@@
 class TestCaseOp12_CyclingRef_ThreeNodeCycle(HttpRunner):
@@
-    teststeps = [
+    teststeps: ClassVar = [

Also applies to: 3394-3467, 3470-3570

🤖 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 3345 - 3391,
Annotate the mutable class attribute teststeps in the
TestCaseOp12_CyclingRef_SelfReference class as a ClassVar to satisfy RUF012 and
clarify intent to type checkers: add a ClassVar import from typing and change
the teststeps annotation to ClassVar[List[Any]] (or ClassVar[list]) while
keeping the same value; apply the same change to the other two test classes
referenced (the ones at the other ranges) so each class-level teststeps is
declared as a ClassVar instead of a plain mutable attribute.
tests/test_op13_schema_traits_validation.py (1)

76-133: Annotate class-level teststeps to satisfy RUF012.
teststeps is a mutable class attribute across all test classes; annotate with ClassVar to silence Ruff and clarify intent.

♻️ Suggested pattern (apply to all classes)
-from .conftest import get_gts_base_url
-from httprunner import HttpRunner, Config, Step, RunRequest
+from .conftest import get_gts_base_url
+from httprunner import HttpRunner, Config, Step, RunRequest
+from typing import ClassVar, List
@@
 class TestCaseOp13_TraitsValid_AllResolved(HttpRunner):
@@
-    teststeps = [
+    teststeps: ClassVar[List[Step]] = [
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/test_op13_schema_traits_validation.py` around lines 76 - 133, The
class-level mutable attribute teststeps in TestCaseOp13_TraitsValid_AllResolved
should be annotated as a ClassVar to satisfy RUF012; import ClassVar from typing
and change the declaration of teststeps to something like teststeps:
ClassVar[list] = [...] (or a more specific type if available) so the attribute
is explicitly a class variable and Ruff warnings are silenced; update any other
test classes with class-level teststeps similarly.
🤖 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 96: The README's top-level VERSION banner still shows 0.7 while the
release table includes 0.8beta2; update the VERSION banner string at the top of
README.md to "0.8beta2" so it matches the table and avoids confusion—locate the
top-level banner (the VERSION variable or heading labeled VERSION) and replace
the old value with 0.8beta2.

In `@tests/test_op13_schema_traits_validation.py`:
- Around line 1027-1091: The test class
TestCaseOp13_TraitsInvalid_RefBasedMissingTrait relies on external trait schemas
and must be made self-contained: before registering the base that $ref's the
traits, add _register calls for the standalone trait schemas (the referenced IDs
"gts://gts.x.test13.traits.retention.v1~" and
"gts://gts.x.test13.traits.topic.v1~") or use a shared fixture to ensure those
traits are present; update the teststeps so _register of the two trait schemas
happens prior to the base registration and then keep the existing
_register_derived and _validate_schema steps. Ensure the unique symbols
_register, _register_derived, and _validate_schema are used in the new ordering
so the test no longer depends on other test execution order.

---

Duplicate comments:
In `@tests/test_op13_schema_traits_validation.py`:
- Around line 1283-1337: The test class
TestCaseOp13_TraitsValid_DefaultsFromRefSchema assumes prior trait schema
registrations; make its setup order-independent by registering the dependent
trait schemas (e.g., the retention trait and any TopicTrait used by the $ref)
within its teststeps before calling
_register/_register_derived/_validate_schema, or invoke the existing helper that
performs those registrations; update the test class to explicitly call the same
registration steps used earlier (the ones referenced around lines 1027-1091) so
_register, _register_derived, and _validate_schema have the required trait
schemas present when they run.

---

Nitpick comments:
In `@tests/test_op12_schema_vs_schema_validation.py`:
- Around line 3345-3391: Annotate the mutable class attribute teststeps in the
TestCaseOp12_CyclingRef_SelfReference class as a ClassVar to satisfy RUF012 and
clarify intent to type checkers: add a ClassVar import from typing and change
the teststeps annotation to ClassVar[List[Any]] (or ClassVar[list]) while
keeping the same value; apply the same change to the other two test classes
referenced (the ones at the other ranges) so each class-level teststeps is
declared as a ClassVar instead of a plain mutable attribute.

In `@tests/test_op13_schema_traits_validation.py`:
- Around line 76-133: The class-level mutable attribute teststeps in
TestCaseOp13_TraitsValid_AllResolved should be annotated as a ClassVar to
satisfy RUF012; import ClassVar from typing and change the declaration of
teststeps to something like teststeps: ClassVar[list] = [...] (or a more
specific type if available) so the attribute is explicitly a class variable and
Ruff warnings are silenced; update any other test classes with class-level
teststeps similarly.

Comment thread README.md
Comment thread tests/test_op13_schema_traits_validation.py
Signed-off-by: Artifizer <artifizer@gmail.com>
Signed-off-by: Artifizer <artifizer@gmail.com>
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.

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

76-87: Annotate mutable HttpRunner class attributes with ClassVar.

Ruff flags config and teststeps as mutable class attributes. Adding ClassVar annotations will silence RUF012 across all test classes.

♻️ Example fix (apply across all classes)
-from .conftest import get_gts_base_url
-from httprunner import HttpRunner, Config, Step, RunRequest
+from .conftest import get_gts_base_url
+from httprunner import HttpRunner, Config, Step, RunRequest
+from typing import ClassVar, List
 class TestCaseOp13_TraitsValid_AllResolved(HttpRunner):
     """OP#13 - Traits: derived schema provides all trait values.
 
     Validation passes.
     """
-    config = Config("OP#13 - All Traits Resolved").base_url(get_gts_base_url())
+    config: ClassVar[Config] = Config("OP#13 - All Traits Resolved").base_url(
+        get_gts_base_url()
+    )
@@
-    teststeps = [
+    teststeps: ClassVar[List[Step]] = [
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/test_op13_schema_traits_validation.py` around lines 76 - 87, Ruff flags
`config` and `teststeps` as mutable class attributes on test classes like
TestCaseOp13_TraitsValid_AllResolved which inherit from HttpRunner; annotate
those attributes with typing.ClassVar (e.g., change the type declaration for
config and teststeps to use ClassVar) and add the necessary import from typing
so the linter recognizes they are class-level mutable containers—apply the same
ClassVar annotation to the `config` and `teststeps` attributes across all test
classes inheriting HttpRunner.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@README.md`:
- Line 1: The spec header and table disagree on casing for the version string:
update the header instance "0.8Beta2" to match the table's casing "0.8beta2" so
the document uses a single canonical version string; locate the header line
containing "0.8Beta2" and replace it with "0.8beta2" (or, alternatively, change
the table to "0.8Beta2" if you prefer TitleCase) so both occurrences are
identical.

In `@tests/test_op13_schema_traits_validation.py`:
- Around line 1036-1067: This test depends on trait schemas registered by prior
tests; make it self-contained by registering the needed trait schemas before
calling _register for "gts://gts.x.test13.refm.event.v1~": add explicit
_register calls that create the trait schemas with IDs
"gts://gts.x.test13.traits.retention.v1~" and
"gts://gts.x.test13.traits.topic.v1~" (or use a local fixture that ensures those
IDs exist) and then reference those IDs via the $$ref entries in the base schema
so the test no longer relies on test ordering.

---

Nitpick comments:
In `@tests/test_op13_schema_traits_validation.py`:
- Around line 76-87: Ruff flags `config` and `teststeps` as mutable class
attributes on test classes like TestCaseOp13_TraitsValid_AllResolved which
inherit from HttpRunner; annotate those attributes with typing.ClassVar (e.g.,
change the type declaration for config and teststeps to use ClassVar) and add
the necessary import from typing so the linter recognizes they are class-level
mutable containers—apply the same ClassVar annotation to the `config` and
`teststeps` attributes across all test classes inheriting HttpRunner.

@Artifizer
Copy link
Copy Markdown
Contributor Author

🧹 Nitpick comments (1)

tests/test_op13_schema_traits_validation.py (1)> 76-87: Annotate mutable HttpRunner class attributes with ClassVar.

Ruff flags config and teststeps as mutable class attributes. Adding ClassVar annotations will silence RUF012 across all test classes.

♻️ Example fix (apply across all classes)

-from .conftest import get_gts_base_url
-from httprunner import HttpRunner, Config, Step, RunRequest
+from .conftest import get_gts_base_url
+from httprunner import HttpRunner, Config, Step, RunRequest
+from typing import ClassVar, List
 class TestCaseOp13_TraitsValid_AllResolved(HttpRunner):
     """OP#13 - Traits: derived schema provides all trait values.
 
     Validation passes.
     """
-    config = Config("OP#13 - All Traits Resolved").base_url(get_gts_base_url())
+    config: ClassVar[Config] = Config("OP#13 - All Traits Resolved").base_url(
+        get_gts_base_url()
+    )
@@
-    teststeps = [
+    teststeps: ClassVar[List[Step]] = [

🤖 Prompt for AI Agents

Verify each finding against the current code and only fix it if needed.

In `@tests/test_op13_schema_traits_validation.py` around lines 76 - 87, Ruff flags
`config` and `teststeps` as mutable class attributes on test classes like
TestCaseOp13_TraitsValid_AllResolved which inherit from HttpRunner; annotate
those attributes with typing.ClassVar (e.g., change the type declaration for
config and teststeps to use ClassVar) and add the necessary import from typing
so the linter recognizes they are class-level mutable containers—apply the same
ClassVar annotation to the `config` and `teststeps` attributes across all test
classes inheriting HttpRunner.

🤖 Prompt for all review comments with AI agents

fixed

Register referenced standalone trait schemas inside the test so it no longer
depends on execution order of other OP#13 tests.

Signed-off-by: Artifizer <artifizer@gmail.com>
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_op13_schema_traits_validation.py`:
- Around line 1-2: Ruff RUF012 flags mutable class attributes `config` and
`teststeps` on test classes (which inherit from HttpRunner); fix by annotating
these attributes with typing.ClassVar to indicate they are class-level
(immutable for type checkers) — update the class attribute annotations for
`config` and `teststeps` on every test class in this file (and the other
occurrences referenced) so they read with ClassVar (e.g., ClassName:
ClassVar[Config] / ClassVar[List[Step]]), ensuring imports include
typing.ClassVar if missing.

---

Duplicate comments:
In `@tests/test_op13_schema_traits_validation.py`:
- Around line 1321-1366: This test depends on a standalone retention trait being
registered elsewhere; make it self-contained by registering the referenced trait
schema before using it. Add a call to the existing helper _register (or a
fixture) to register "gts://gts.x.test13.traits.retention.v1~" with the
appropriate trait schema (default P30D / x-gts-traits-schema) prior to the
current _register that $ref's it, or register via a module/fixture that runs for
this test; ensure the registration uses the same trait id referenced in the $ref
so _register_derived and _validate_schema see the trait without relying on test
execution order.

Comment thread tests/test_op13_schema_traits_validation.py
Comment thread README.md
Comment thread README.md
Comment thread README.md
Comment thread README.md Outdated
Comment thread README.md Outdated
Comment thread README.md
Signed-off-by: Artifizer <artifizer@gmail.com>
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.

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

Duplicate comments:
In `@tests/test_op13_schema_traits_validation.py`:
- Around line 1-2: Annotate the mutable class attributes on HttpRunner-derived
test classes by importing typing.ClassVar and changing the annotations for
config and teststeps to use ClassVar (e.g., config: ClassVar[Config] and
teststeps: ClassVar[list[Step]] or the appropriate list element type used in the
file); update the import list to include ClassVar and modify the HttpRunner
subclass attribute annotations (config and teststeps) so Ruff RUF012 no longer
flags them.

@Artifizer Artifizer merged commit 4f0f672 into GlobalTypeSystem:main Feb 17, 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