Skip to content

docs: add ADR template and contribution process - #92

Open
aviator5 wants to merge 2 commits into
GlobalTypeSystem:mainfrom
aviator5:adr-template-and-extend-contributing
Open

docs: add ADR template and contribution process#92
aviator5 wants to merge 2 commits into
GlobalTypeSystem:mainfrom
aviator5:adr-template-and-extend-contributing

Conversation

@aviator5

@aviator5 aviator5 commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator
  • Require ADRs for normative specification changes and document the validation workflow.
  • Add a project-adapted ADR template and align existing ADR headings with it.

Summary by CodeRabbit

  • Documentation
    • Updated contributor prerequisites, setup steps, repository guidance, validation commands, and release tagging instructions.
    • Clarified JSON Schema dialect declarations, alignment requirements, and conformance-test guidance.
    • Expanded architecture decision records with explicitly labeled options, selected decisions, implications, and implementation requirements.
    • Added a reusable ADR template covering context, options, decisions, implications, trade-offs, and supporting information.
    • Clarified trait validation behavior for const values, required properties, defaults, and merge-based deletion.
  • Tests
    • Added coverage for rejecting deletion of required, constant-valued traits.

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The change updates contributor guidance, adds an ADR template, clarifies four ADR decisions, documents const behavior under RFC 7396 JSON Merge Patch, and adds regression coverage for null deletion of required const-constrained traits.

Changes

Documentation and ADR decisions

Layer / File(s) Summary
Contributor workflow and ADR template
CONTRIBUTING.md, adr/template.md
Contributor prerequisites, setup, validation commands, schema dialect guidance, release tags, and ADR requirements are updated. A structured ADR template is added.
Core ADR option and outcome clarifications
adr/0001-derivation-form.md, adr/0002-x-gts-traits-schema.md, adr/0003-x-gts-traits-completeness.md
The ADRs now number considered options and identify the selected outcomes.
Merge strategy decision and implications
adr/0004-x-gts-traits-merge-strategy.md
The ADR selects RFC 7396 JSON Merge Patch and documents const deletion, compatibility, implementation, and conformance implications.
Const deletion semantics and regression coverage
README.md, tests/test_op13_schema_traits_validation.py
The README clarifies that const constrains value, not property presence. A regression test verifies that null deletion fails for a required const-locked trait.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

Suggested reviewers: artifizer

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% 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.
Title check ✅ Passed The title clearly summarizes the main changes: adding an ADR template and documenting the contribution process.
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.
✨ 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.

@code-ranker-app

code-ranker-app Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

code-ranker report for this PR (built on fork): https://reports.code-ranker.com/0FGX7CpmwJdMIFYuUtk0jA/

@aviator5
aviator5 requested a review from Artifizer August 3, 2026 11:11

@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

🤖 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 `@adr/0003-x-gts-traits-completeness.md`:
- Line 230: Resolve the contradiction in the Option 3 section of the ADR by
aligning its completeness requirement with the `false` schema behavior: either
explicitly exempt types whose materialized effective traits object is empty, or
revise the `x-gts-traits-schema: false` edge-case wording to state that no
non-abstract descendant can be complete. Ensure the selected wording
consistently matches the completeness algorithm.

In `@adr/0004-x-gts-traits-merge-strategy.md`:
- Around line 483-489: Update the trait merge and validation semantics in §9.7.5
so RFC 7396 null-based deletion cannot bypass an optional const-locked trait:
either require locked properties in the effective trait-schema or reject
deletion during merge. Ensure the selected behavior preserves const enforcement,
and add a conformance test covering a descendant setting an optional
const-locked trait to null.
🪄 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 Plus

Run ID: b378a9fb-af05-415a-b218-fe9db5024981

📥 Commits

Reviewing files that changed from the base of the PR and between cada310 and 1f6357c.

📒 Files selected for processing (6)
  • CONTRIBUTING.md
  • adr/0001-derivation-form.md
  • adr/0002-x-gts-traits-schema.md
  • adr/0003-x-gts-traits-completeness.md
  • adr/0004-x-gts-traits-merge-strategy.md
  • adr/template.md

Comment thread adr/0003-x-gts-traits-completeness.md
Comment thread adr/0004-x-gts-traits-merge-strategy.md Outdated
Comment on lines +483 to +489
- **§9.7.5 ("Trait merge and validation semantics")** carries the normative wording of RFC 7396 merge along the `$id` chain and the `const`-based lock mechanism.
- **ADR-0003** stays correct as written; the "chain-merged effective traits object" referenced there is now formally defined as the result of applying each layer's `x-gts-traits` as a JSON Merge Patch (RFC 7396) to the chain-merged object so far, root → leaf.
- **OP#13 description (§9.7)** is unaffected; it speaks generically of "chain-merged" values.
- **§9.11.4 (modifiers ↔ traits)** is unaffected; completeness keying on `x-gts-abstract` is independent of merge policy.
- **Reference implementations (gts-go, gts-rust)** must implement RFC 7396 merge along the chain. Available implementations exist in both ecosystems. The registry MUST NOT enforce a "different value MUST fail" rule on its own — it relies on standard JSON Schema validation against the effective trait-schema (which catches `const` violations naturally).
- **Conformance test suite** should exercise: (a) descendant overrides a top-level scalar — succeeds (last-wins); (b) descendant overrides one field of a nested-object trait — other nested fields preserved; (c) descendant overrides an array-valued trait — array replaces wholesale; (d) descendant writes `null` at a leaf — the key is removed; (e) descendant repeats the same value — succeeds (idempotent); (f) publisher locks via `const`, descendant attempts override — fails JSON Schema validation; (g) chain with three layers; middle layer overrides base; leaf overrides middle.
- **Backward compatibility.** This decision defines behavior that was previously unspecified; implementations using a different merge strategy must update to RFC 7396 semantics.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Locate relevant ADR section =="
sed -n '440,510p' adr/0004-x-gts-traits-merge-strategy.md 2>/dev/null || true

echo
echo "== Search lock/null/merger definitions =="
rg -n "x-gts-traits|x-gts-lock|lock|json merge|RFC 7396|constrains|requires|required|null|#\\{|const" adr/0004-x-gts-traits-merge-strategy.md 2>/dev/null || true

echo
echo "== Search test/import fixtures for trait lock behavior =="
rg -n "gts-lock|x-gts-lock|trait.*lock|RFC 7396|merge.*null|null.*trait|const" -S . -g '!**/.git/**' --iglob '*.*' | head -n 200 || true

Repository: GlobalTypeSystem/gts-spec

Length of output: 50383


🌐 Web query:

JSON Merge Patch RFC 7396 null deletes key

💡 Result:

Yes, according to RFC 7396, a null value in a JSON Merge Patch indicates that the corresponding key should be removed from the target document [1][2]. In the JSON Merge Patch specification, the algorithm for applying a patch is defined as follows [1][3]: - If the patch member value is null, the corresponding member is removed from the target document if it exists [1][3]. - If the patch member value is not null, the value is updated or added [1][3]. Because null is assigned this specific "delete" meaning, JSON Merge Patch does not support setting a key's value to null [4][5]. If your application requires the ability to explicitly set fields to null, you should use a different format, such as JSON Patch (RFC 6902) [4][6].

Citations:


🌐 Web query:

JSON Schema const keyword validates only when member present does not make required

💡 Result:

In JSON Schema, the "const" keyword does not require the property it validates to be present in the JSON instance [1][2]. The "const" keyword is an assertion that validates the value of an instance against a fixed value [3][4][5]. When "const" is applied to a property within an object's "properties" schema, it only evaluates the value of that property if the property is actually present in the data [1][2]. If the property is absent, the validation for that specific schema branch is skipped, resulting in a successful validation (or "pass") for that property constraint [1][2]. This behavior is consistent with the core principle of JSON Schema, where keywords define constraints that only apply if the data they reference exists [2][6]. To mandate that a property must be present, you must explicitly use the "required" keyword [2][6]. If you need a property to be present and equal to a specific value, you should use both keywords together: { "type": "object", "properties": { "myProperty": { "const": "expectedValue" } }, "required": ["myProperty"] } In this example, the "required" keyword ensures the property exists [6], and the "const" keyword ensures that if it exists, it must have the specified value [3][5].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== ADR-0003 relevant lines =="
sed -n '230,275p' adr/0003-x-gts-traits-completeness.md 2>/dev/null || true

echo
echo "== Search const/required lock examples in relevant ADRs =="
rg -n 'locked lock publisher const required|null|delete|RFC 7396|x-gts-traits-schema|implication|conformance' adr/0004-x-gts-traits-merge-strategy.md adr/0003-x-gts-traits-completeness.md -S

Repository: GlobalTypeSystem/gts-spec

Length of output: 21693


🌐 Web query:

"I should write: const is not a requirement" JSON Schema

💡 Result:

The const keyword is not a requirement in JSON Schema; it is an optional keyword used to restrict a value to a single, specific JSON value [1][2]. Using the const keyword is functionally equivalent to an enum keyword with a single value [3][2]. Because const restricts an instance to a specific value, it implicitly determines the type of that value, making the separate use of the type keyword redundant or, in cases where the types do not align, potentially invalid [4][5][6]. It is generally considered an anti-pattern to use the type keyword alongside const [4][6]. For example, a schema definition like this is sufficient to enforce a constant value: { "const": "my-constant-value" } When using const, you do not need to explicitly declare the type [5]. The validator will enforce that the instance matches the provided constant value exactly [7][3].

Citations:


Explicitly prevent null from removing const-locked traits.

RFC 7396 deletes keys on null; JSON Schema const rejects only present mismatching values, not missing properties. For optional locked traits, a descendant using "trait": null can bypass the lock and still pass validation. Require locked properties in the effective trait-schema, or reject deletion during the RFC 7396 merge. Add a conformance case for an optional const lock being bypassed by null.

🤖 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 `@adr/0004-x-gts-traits-merge-strategy.md` around lines 483 - 489, Update the
trait merge and validation semantics in §9.7.5 so RFC 7396 null-based deletion
cannot bypass an optional const-locked trait: either require locked properties
in the effective trait-schema or reject deletion during merge. Ensure the
selected behavior preserves const enforcement, and add a conformance test
covering a descendant setting an optional const-locked trait to null.

- Require ADRs for normative specification changes and document the validation workflow.
- Add a project-adapted ADR template and align existing ADR headings with it.

Signed-off-by: Aviator 5 <ai.agent.tor@gmail.com>
Signed-off-by: Aviator 5 <ai.agent.tor@gmail.com>
@aviator5
aviator5 force-pushed the adr-template-and-extend-contributing branch from 1f6357c to 5537fa2 Compare August 3, 2026 17:36

@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

🤖 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 `@adr/0004-x-gts-traits-merge-strategy.md`:
- Around line 437-441: Update adr/0004-x-gts-traits-merge-strategy.md lines
437-441 and README.md line 1625 to state that nested required traits are
protected only when every parent path segment is present, and that protection
requires requiring each parent, restoring the complete path with defaults, or
rejecting parent deletion. Extend tests/test_op13_schema_traits_validation.py
lines 3394-3441 with nested-parent deletion coverage, distinguishing parent
removal from literal null, and assert the specific required-property validation
failure.

In `@tests/test_op13_schema_traits_validation.py`:
- Around line 3394-3441: Extend TestCaseOp13_Merge_ConstLock_NullDeleteFails
with a nested parent object containing a required const property, then attempt
to delete that parent through merge and assert the resulting validation failure
specifically reflects the missing required property. Ensure the assertion
distinguishes RFC 7396 null-deletion semantics from incorrectly validating
literal null.
🪄 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 Plus

Run ID: 9498ea54-d1a8-49ae-a28b-da0ffa473303

📥 Commits

Reviewing files that changed from the base of the PR and between 1f6357c and 5537fa2.

📒 Files selected for processing (8)
  • CONTRIBUTING.md
  • README.md
  • adr/0001-derivation-form.md
  • adr/0002-x-gts-traits-schema.md
  • adr/0003-x-gts-traits-completeness.md
  • adr/0004-x-gts-traits-merge-strategy.md
  • adr/template.md
  • tests/test_op13_schema_traits_validation.py
🚧 Files skipped from review as they are similar to previous changes (4)
  • adr/0001-derivation-form.md
  • adr/0003-x-gts-traits-completeness.md
  • adr/0002-x-gts-traits-schema.md
  • adr/template.md

Comment on lines +437 to +441
`const` locks the **value**, not the presence: JSON Schema asserts nothing about an absent property, so a descendant can still drop a `const`-constrained trait with an RFC 7396 `null` patch. This is the general presence rule for traits, not a `const`-specific gap — any optional inherited trait without a `default` is removable the same way. A publisher who wants presence guaranteed too picks one of:

- add the property to the containing object schema's `required` array — the deletion then fails the ADR-0003 completeness check for non-abstract types (loud failure);
- declare a `default` equal to the `const` value — the deletion becomes a no-op, since materialization restores the value before validation (self-healing).

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Make const deletion protection path-aware and test the defined behavior.

A nested required property is protected only while every parent object on its path is present. RFC 7396 can delete an optional parent, so JSON Schema can skip the nested required constraint. The current test also cannot distinguish deletion from validating literal null.

  • adr/0004-x-gts-traits-merge-strategy.md#L437-L441: require every parent path segment, restore the complete path with a default, or reject parent deletion.
  • README.md#L1625-L1625: mirror the path-aware rule.
  • tests/test_op13_schema_traits_validation.py#L3394-L3441: add nested-parent coverage and assert the specific required-property failure.
📍 Affects 3 files
  • adr/0004-x-gts-traits-merge-strategy.md#L437-L441 (this comment)
  • README.md#L1625-L1625
  • tests/test_op13_schema_traits_validation.py#L3394-L3441
🤖 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 `@adr/0004-x-gts-traits-merge-strategy.md` around lines 437 - 441, Update
adr/0004-x-gts-traits-merge-strategy.md lines 437-441 and README.md line 1625 to
state that nested required traits are protected only when every parent path
segment is present, and that protection requires requiring each parent,
restoring the complete path with defaults, or rejecting parent deletion. Extend
tests/test_op13_schema_traits_validation.py lines 3394-3441 with nested-parent
deletion coverage, distinguishing parent removal from literal null, and assert
the specific required-property validation failure.

Comment on lines +3394 to +3441
class TestCaseOp13_Merge_ConstLock_NullDeleteFails(HttpRunner):
"""ADR-0004 §"Conformance test suite" (g): null cannot delete a required lock.

RFC 7396 removes `indexed` from the merged traits object, but the effective
trait-schema also requires the property. The materialized object therefore
fails OP#13 instead of bypassing the const constraint.
"""

config = Config("OP#13 ADR-0004: const lock rejects null delete").base_url(
get_gts_base_url()
)

def test_start(self):
super().test_start()

teststeps = [
_register(
"gts://gts.x.test13.mconstdel.event.v1~",
{
"type": "object",
"x-gts-traits-schema": {
"type": "object",
"properties": {
"indexed": {"type": "boolean", "const": True},
},
"required": ["indexed"],
},
"x-gts-traits": {"indexed": True},
"required": ["id"],
"properties": {"id": {"type": "string"}},
},
"register base with const-and-required locked indexed=true",
),
_register_derived(
"gts://gts.x.test13.mconstdel.event.v1~x.test13._.kid.v1~",
"gts://gts.x.test13.mconstdel.event.v1~",
{
"type": "object",
"x-gts-traits": {"indexed": None},
},
"register descendant trying to delete indexed",
),
_validate_type_schema(
"gts.x.test13.mconstdel.event.v1~x.test13._.kid.v1~",
False,
"validate descendant - required prevents const-lock deletion",
),
]

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Make the conformance test distinguish the merge contract.

This fixture covers only a top-level property. It does not catch deletion of a parent object containing a required const property. The False assertion also passes if an implementation incorrectly validates literal null instead of deleting it. Add a nested-parent case and assert the missing-required failure, or use another observable that distinguishes the two behaviors.

🧰 Tools
🪛 Ruff (0.16.0)

[warning] 3409-3441: Mutable default value for class attribute

(RUF012)

🤖 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 `@tests/test_op13_schema_traits_validation.py` around lines 3394 - 3441, Extend
TestCaseOp13_Merge_ConstLock_NullDeleteFails with a nested parent object
containing a required const property, then attempt to delete that parent through
merge and assert the resulting validation failure specifically reflects the
missing required property. Ensure the assertion distinguishes RFC 7396
null-deletion semantics from incorrectly validating literal null.

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