recon_gen.common.spine.two_template_chain
Two-template chain (healthy) family — ViolationGenerator only.
AY.2.b promotion of common/l2/seed.py::TwoTemplateChainPlant (AB.2.6 healthy plant). This is a SEED-COLOR generator: it plants a healthy 2-template chain firing (one parent leg + N child template legs all sharing one child Transfer + agreeing on transfer_parent_id) so the L1 dashboard’s PostedRequirements panel + the audit PDF have a clearly-labeled healthy two-template chain row to display, separate from the probabilistic baseline.
Crucially this plant produces NO matview row — chain_parent_disagreement reads COUNT(DISTINCT transfer_parent_id) > 1 grouped by (transfer_id, template_name); this generator emits N child legs all carrying the SAME parent_transfer_id, so the count is 1 and the matview branch never fires.
Per the AY.2.b evidence-currency layering:
intended returns a CoverageObservation (NOT RuleViolation, NOT None). The seed claims “I planted a healthy two-template chain firing”; the audit-PDF “PostedRequirements” coverage section reads the row(s) directly. A coverage detector (deferred) could eventually walk <prefix>_transactions WHERE transfer_id=? AND template_name=? GROUP BY transfer_id HAVING COUNT(DISTINCT transfer_parent_id) = 1 and assert ≥1 healthy chain firing per chain-child template; for now intended is presence-only evidence.
No matching Invariant (the AY.0 design’s “audit-fixture without detector” shape). Registers with empty edges in INVARIANT_GENERATOR_EDGES.
Single-edge property (matches the other 4 L2-shape spine generators): transfers-only → no daily_balances rows → no drift trip.
Classes
|
Smart constructor namespace for TwoTemplateChainGenerator. |
|
Emit one parent leg + N child template legs (one per child_leg_rails entry) all sharing one child transfer_id and all carrying the same parent_transfer_id — the healthy 2-template chain shape. |
- class recon_gen.common.spine.two_template_chain.TwoTemplateChainFactory(prefix='spec_example')[source]
Bases:
objectSmart constructor namespace for TwoTemplateChainGenerator.
AY.2.b deliberately omits an Invariant here — there’s no matview to detect this plant’s evidence (the plant is non-violating). The factory mirrors the Invariant.scenario_for(…) pattern from the rest of the spine for surface parity, so seed-color generators feel like the violation-detecting ones at the call site.
- Parameters:
prefix (str)
- name: ClassVar[str] = 'two_template_chain_healthy'
- prefix: str = 'spec_example'
- scenario_for_healthy(*, anchor_day=datetime.date(2030, 1, 1), instance=None)[source]
Pick any chain whose singleton child is a TransferTemplate (the AB.2.6 picker) and build a generator that plants a healthy 2-template chain firing.
Parent can resolve to either a Rail (rail-parent) or a TransferTemplate (template-parent, AG.3 Gap A); the generator carries enough fields to emit the parent row correctly in both cases.
Raises ValueError when the L2 has no eligible chain (singleton-child + parent ∈ rails ∪ templates + child ∈ templates with ≥1 leg_rail).
- Return type:
- Parameters:
anchor_day (date)
instance (L2Instance | None)
- class recon_gen.common.spine.two_template_chain.TwoTemplateChainGenerator(chain_parent_name, parent_rail_name, parent_template_name, child_template_name, child_leg_rails, anchor_day, prefix='spec_example', account_id_override=None)[source]
Bases:
objectEmit one parent leg + N child template legs (one per child_leg_rails entry) all sharing one child transfer_id and all carrying the same parent_transfer_id — the healthy 2-template chain shape.
Account fields are synthetic + deterministic (matches the ChainParentDisagreementGenerator pattern; the matview ignores account columns when grouping by transfer_id + template_name).
intended returns a CoverageObservation keyed on (transfer_id, chain_parent_name, child_template_name, child_leg_count) — the presence-claim tuple a coverage detector could round-trip against.
- Parameters:
chain_parent_name (str)
parent_rail_name (str)
parent_template_name (str | None)
child_template_name (str)
child_leg_rails (tuple[str, ...])
anchor_day (date)
prefix (str)
account_id_override (str | None)
- property account_id: str
- account_id_override: str | None = None
- anchor_day: date
- chain_parent_name: str
- child_leg_rails: tuple[str, ...]
- child_template_name: str
- property child_transfer_id: str
- property claimed_accounts: frozenset[str]
- emit(conn, *, scenario_id=None)[source]
- Return type:
None- Parameters:
conn (SyncConnection)
scenario_id (str | None)
- property intended: CoverageObservation
a healthy 2-template chain firing landed with N child legs all agreeing on parent_transfer_id. Identity carries the natural-key tuple a coverage detector would round-trip against if/when one lands.
- Type:
Presence evidence
- parent_rail_name: str
- parent_template_name: str | None
- property parent_transfer_id: str
- prefix: str = 'spec_example'