recon_gen.common.spine.violation
Violation — the typed evidence currency of the spine.
The spine emits + detects typed evidence about the institution’s data shape. Three concrete subtypes per the AY.0 design lock:
RuleViolation — L1/L2 matview detects a rule break (drift, chain_parent_disagreement, anomaly, etc.). The post-AS-AT-AU-AX shape; every spine invariant promoted before AY emits these. THE default subtype that Violation.of() constructs (backward compat with the AS-era code that pre-dates the layering).
CoverageObservation — seed-color presence claim (RailFiring, TransferTemplate, InvFanout, etc.). The GOOD signal — its ABSENCE is the bug; a coverage detector’s failure to return one trips the regression gate.
AuditFixture — auxiliary data the audit PDF consumes (SupersessionPlant, FailedTransactionPlant). Not a rule violation; not a coverage observation; an audit-PDF-specific row presence claim.
Identity is the analyst-facing columns naming the evidence: account + day + magnitude for drift; pair + sigma band for anomaly; root_transfer + depth for a money trail. Two same-subtype instances compare equal iff they name the same evidence, REGARDLESS of which detector emitted them or which generator was the cause.
Cross-subtype equality is FALSE even when identity matches —
RuleViolation(a, b) != CoverageObservation(a, b). The runtime
class is the discriminator (frozen dataclass __eq__ checks
self.__class__ is other.__class__); pyright narrows via
isinstance(v, RuleViolation). AY.0 picked this over a
Literal[…] field discriminator for the stronger typing per
[[feedback-invariants-in-types]].
Why a frozenset of (column, value) pairs and not a fixed schema: different invariants have different identity columns. A drift row IS (account_id, business_day, drift_amount); an anomaly row is (sender_id, recipient_id, sigma_band). A fixed schema would force a common denominator that loses information. The frozenset shape makes equality column-aware while letting per-invariant identity vary.
Smart constructors RuleViolation.of(…) / CoverageObservation.of(…) / AuditFixture.of(…) are the blessed way to build each subtype. Violation.of(…) survives as a backward-compat alias that returns a RuleViolation (pre-AY.2.a code expected the rule-violation shape).
Promoted from tests/unit/test_as0_drift_full_spine.py by AS.1; layered into subtypes by AY.2.a.
Classes
|
An audit-PDF input row marker. |
|
A seed-color presence claim. |
|
A matview-detected rule break. |
|
Abstract base for typed spine evidence. |
- class recon_gen.common.spine.violation.AuditFixture(invariant, identity)[source]
Bases:
ViolationAn audit-PDF input row marker.
AY.2.b’s 2 audit-fixture generators (SupersessionGenerator, FailedTransactionGenerator) emit these. Supersession + FailedTransaction rows surface only in the audit PDF (no matview, no coverage detector); the spine carries them for substrate uniformity (claimed_accounts collision check, AV.5 metadata tagging, ScenarioContext cleanup attribution).
- Parameters:
invariant (str)
identity (frozenset[tuple[str, object]])
- classmethod of(invariant, **identity)[source]
Backward-compat alias — returns a RuleViolation (a Violation subtype).
Pre-AY.2.a, every spine generator + detector built Violations via this constructor; AY.2.a layered in subtypes but kept the alias so the migration is incremental. New code should prefer the subtype-explicit constructors (
RuleViolation.of(...)etc.) for type clarity.Return type is the abstract Violation for liskov / covariant override compatibility — subclasses’ .of() can return their own concrete subtype without tripping pyright. At runtime this method returns a RuleViolation (the AS-era default).
- Return type:
- Parameters:
invariant (str)
identity (object)
- class recon_gen.common.spine.violation.CoverageObservation(invariant, identity)[source]
Bases:
ViolationA seed-color presence claim.
AY.2.b’s 5 coverage generators (TwoTemplateChainGenerator, TransferTemplateGenerator, RailFiringGenerator, InvFanoutGenerator, FanInChainGenerator(healthy)) emit these. Their intended carries the row the matching coverage detector (when one exists) reads back to confirm the seed met the documented coverage shape. ABSENCE is the regression — a CoverageInvariant.detect() returning empty means the seed didn’t emit what the docs claim.
- Parameters:
invariant (str)
identity (frozenset[tuple[str, object]])
- classmethod of(invariant, **identity)[source]
Backward-compat alias — returns a RuleViolation (a Violation subtype).
Pre-AY.2.a, every spine generator + detector built Violations via this constructor; AY.2.a layered in subtypes but kept the alias so the migration is incremental. New code should prefer the subtype-explicit constructors (
RuleViolation.of(...)etc.) for type clarity.Return type is the abstract Violation for liskov / covariant override compatibility — subclasses’ .of() can return their own concrete subtype without tripping pyright. At runtime this method returns a RuleViolation (the AS-era default).
- Return type:
- Parameters:
invariant (str)
identity (object)
- class recon_gen.common.spine.violation.RuleViolation(invariant, identity)[source]
Bases:
ViolationA matview-detected rule break.
The post-AS shape — every L1 accounting / L2-shape integrity / L2 investigation invariant promoted pre-AY emits these. The semantic_lock dict’s values are frozenset[RuleViolation] for every spine Invariant shipped to date.
- Parameters:
invariant (str)
identity (frozenset[tuple[str, object]])
- class recon_gen.common.spine.violation.Violation(invariant, identity)[source]
Bases:
objectAbstract base for typed spine evidence.
- Two fields:
invariant: the matview / coverage / fixture name (e.g."drift","rail_firing","supersession"). The string discriminator the lock dict keys on; pairs with the runtime subtype to identify the specific shape.identity: a frozenset of(column, value)pairs naming the row.
NEVER constructed directly in new code — use one of the three concrete subtypes (RuleViolation / CoverageObservation / AuditFixture). The base exists for typing + the legacy Violation.of(…) alias only.
- Parameters:
invariant (str)
identity (frozenset[tuple[str, object]])
- identity: frozenset[tuple[str, object]]
- invariant: str
- classmethod of(invariant, **identity)[source]
Backward-compat alias — returns a RuleViolation (a Violation subtype).
Pre-AY.2.a, every spine generator + detector built Violations via this constructor; AY.2.a layered in subtypes but kept the alias so the migration is incremental. New code should prefer the subtype-explicit constructors (
RuleViolation.of(...)etc.) for type clarity.Return type is the abstract Violation for liskov / covariant override compatibility — subclasses’ .of() can return their own concrete subtype without tripping pyright. At runtime this method returns a RuleViolation (the AS-era default).
- Return type:
- Parameters:
invariant (str)
identity (object)