recon_gen.common.spine.xor_group_violation
XOR-group-violation family — Invariant + 2 `ViolationGenerator`s.
AX.2 promotion of the AB.3.5 / AB.3.5b plants. The matview <prefix>_xor_group_violation walks every Transfer instance of every template that declares leg_rail_xor_groups, for each (Transfer, group) pair LEFT JOINs _current_transactions against the group’s member rails, and surfaces rows where COUNT <> 1:
firing_count = 0 → “missed firing”: the Transfer should have fired exactly one member of the XOR group; it fired none.
firing_count ≥ 2 → “overlap”: the Transfer fired ≥2 members of the XOR group; SPEC C1 says they’re mutually exclusive.
Identity tuple: (transfer_id, template_name, xor_group_index).
Two generators because the emit shape is genuinely different per failure mode (missed: 1 witness leg outside the group; overlap: 2 member legs both inside the group). Single invariant; two generators register as separate edges in INVARIANT_GENERATOR_EDGES.
Single-edge property: transfers-only emit (no daily_balances rows) → no drift trip. Both generators do NOT emit chain-completion rows — extras the SOLO emission might trip on other matviews (e.g., a template that’s also a multi_xor chain parent could trip multi_xor_violation from the same plant) are tolerated per AS.5’s “intended ⊆ detected” contract. Composition with the multi_xor generator clears those extras at the wiring site.
The matview uses concat_agg(“tx.rail_name”, “,”, dialect) for the fired_rails column; AX.0 confirmed SQLite’s built-in GROUP_CONCAT routes cleanly through common/sql/dialect.py’s helper.
Classes
|
Plant a Transfer tagged with template_name whose target XOR group fires NO members. |
|
Plant a Transfer tagged with template_name whose target XOR group fires TWO distinct members. |
|
Detector for the AB.3.3 matview. |
- class recon_gen.common.spine.xor_group_violation.XorGroupMissedFiringGenerator(template_name, xor_group_index, witness_rail_name, anchor_day, prefix='spec_example', account_id_override=None)[source]
Bases:
objectPlant a Transfer tagged with template_name whose target XOR group fires NO members.
Emits ONE leg row carrying the template_name + a witness rail_name that is a leg_rail of the template but NOT in the target XOR group. The matview’s template_transfers CTE picks up the Transfer (template_name matches an XOR-grouped template); the LEFT JOIN against (transfer_id, template, member_rail) for the target group finds zero rows; firing_count = 0; the HAVING <> 1 gate surfaces the row with fired_rails = ‘’.
AY.4.c.2 — account_id_override allows the plant adapter (AY.4.c.3) to thread OLD plant account_ids through, preventing PK collisions when N plants of the same shape compose.
- Parameters:
template_name (str)
xor_group_index (int)
witness_rail_name (str)
anchor_day (date)
prefix (str)
account_id_override (str | None)
- property account_id: str
account_id_overridewins when set (AY.4.c.2).
- account_id_override: str | None = None
- anchor_day: date
- property claimed_accounts: frozenset[str]
- emit(conn, *, scenario_id=None)[source]
- Return type:
None- Parameters:
conn (SyncConnection)
scenario_id (str | None)
- property intended: RuleViolation
- prefix: str = 'spec_example'
- template_name: str
- property transfer_id: str
- witness_rail_name: str
- xor_group_index: int
- class recon_gen.common.spine.xor_group_violation.XorGroupOverlapGenerator(template_name, xor_group_index, variant_a_rail_name, variant_b_rail_name, anchor_day, prefix='spec_example', account_id_override=None)[source]
Bases:
objectPlant a Transfer tagged with template_name whose target XOR group fires TWO distinct members.
Emits TWO leg rows sharing one transfer_id + template_name, each carrying a different member rail_name from the target XOR group. The matview’s LEFT JOIN finds two member-rail firings for (transfer_id, template, target_group) → COUNT = 2 → HAVING <> 1 → row surfaces with fired_rails = ‘<a>,<b>’.
AY.4.c.2 — account_id_override allows the plant adapter (AY.4.c.3) to thread OLD plant account_ids through, preventing PK collisions when N plants of the same shape compose.
- Parameters:
template_name (str)
xor_group_index (int)
variant_a_rail_name (str)
variant_b_rail_name (str)
anchor_day (date)
prefix (str)
account_id_override (str | None)
- property account_id: str
account_id_overridewins when set (AY.4.c.2).
- account_id_override: str | None = None
- anchor_day: date
- property claimed_accounts: frozenset[str]
- emit(conn, *, scenario_id=None)[source]
- Return type:
None- Parameters:
conn (SyncConnection)
scenario_id (str | None)
- property intended: RuleViolation
- prefix: str = 'spec_example'
- template_name: str
- property transfer_id: str
- variant_a_rail_name: str
- variant_b_rail_name: str
- xor_group_index: int
- class recon_gen.common.spine.xor_group_violation.XorGroupViolationInvariant(prefix='spec_example')[source]
Bases:
objectDetector for the AB.3.3 matview.
Identity tuple: (transfer_id, template_name, xor_group_index). The matview’s other columns (firing_count, fired_rails, business_day) are diagnostic — they distinguish missed (0) from overlap (≥2) but the identity-level “did this XOR group misfire” is what the spine carries.
- Parameters:
prefix (str)
- name: ClassVar[str] = 'xor_group_violation'
- prefix: str = 'spec_example'
- scenario_for_missed(*, anchor_day=datetime.date(2030, 1, 1), instance=None)[source]
Pick an XOR-grouped template with ≥1 leg_rail outside the target group (the witness rail). Returns a generator that plants ONE Transfer firing the witness — firing_count=0 for the target group, matview surfaces a row.
Raises ValueError if no template has both an XOR group AND a witness leg_rail outside it (the AB.3.5 picker’s input requirement).
- Return type:
- Parameters:
anchor_day (date)
instance (L2Instance | None)
- scenario_for_overlap(*, anchor_day=datetime.date(2030, 1, 1), instance=None)[source]
Pick an XOR group with ≥2 members (validator C1d enforces the ≥2 condition at load time). Returns a generator that plants ONE Transfer firing TWO members of the same XOR group — firing_count=2, matview surfaces a row.
Raises ValueError if no template declares any leg_rail_xor_groups.
- Return type:
- Parameters:
anchor_day (date)
instance (L2Instance | None)