Source code for gxformat2.schema_rules

"""Schema-rule catalog loader.

Schema rules describe checks already enforced by the pydantic decode layer.
Each rule ships with positive and negative fixtures; the catalog contract is
tested end-to-end by running fixtures through validators — not by inspecting
ValidationError shapes.
"""

import os
from enum import Enum

import yaml
from pydantic import BaseModel

SCHEMA_RULES_PATH = os.path.join(os.path.dirname(__file__), "schema_rules.yml")


[docs] class Severity(str, Enum): """Rule severity level.""" error = "error" warning = "warning"
[docs] class AppliesTo(str, Enum): """Which workflow format a schema rule applies to.""" format2 = "format2" native = "native"
[docs] class Scope(str, Enum): """Validator flavors that reject the negative fixture. - ``both``: both lax and strict reject (e.g. missing required field). - ``strict``: only strict rejects (e.g. unknown extra field). - ``lax``: only lax rejects — unusual, reserved for completeness. """ both = "both" strict = "strict" lax = "lax"
[docs] class SchemaRuleTests(BaseModel): """Positive/negative fixture references for a schema rule.""" positive: list[str] negative: list[str]
[docs] class SchemaRule(BaseModel): """Declarative schema-rule entry loaded from schema_rules.yml.""" id: str severity: Severity applies_to: list[AppliesTo] scope: Scope description: str = "" tests: SchemaRuleTests
[docs] def load_schema_rules() -> list[SchemaRule]: """Parse schema_rules.yml into validated SchemaRule models.""" with open(SCHEMA_RULES_PATH) as f: raw = yaml.safe_load(f) rules: list[SchemaRule] = [] for rule_id, body in raw.items(): rules.append(SchemaRule(id=rule_id, **body)) return rules