recon_gen.common.spine.chain_completion

AY.4.g — ChainCompletionGenerator (chain-completion shim).

A plant that fires a chain-parent rail/template (e.g., an XOR-missed plant on a TransferTemplate that is ALSO a chain parent) without emitting matching child legs gets false-positive flagged by the multi_xor_violation matview as a “missed-child” violation — even though the plant’s INTENT was the XOR violation, not the chain violation.

The OLD seed.py addressed this via _emit_plant_chain_completion, called inline by each affected plant emitter (XOR / limit_breach / broad rail / broad transfer_template). The spine analog is this generator: a standalone emitter the adapter composes alongside the violating plant. Same intent — for each chain the just-emitted plant parents, emit one synthetic child leg keyed to the plant’s transfer_id so the matview sees a matched child + drops the false positive.

The completion is a CoverageObservation (it’s seed scaffolding, not a rule violation). Registers with empty edges; AU.5 widens for the coverage bucket.

Classes

ChainCompletionGenerator(parent_transfer_id, ...)

Emit one synthetic child leg per chain whose parent matches parent_name, with transfer_parent_id = parent_transfer_id so the chain matview sees a matched child.

class recon_gen.common.spine.chain_completion.ChainCompletionGenerator(parent_transfer_id, parent_name, account_id, account_role, account_scope, account_parent_role, anchor_day, instance, prefix='spec_example')[source]

Bases: object

Emit one synthetic child leg per chain whose parent matches parent_name, with transfer_parent_id = parent_transfer_id so the chain matview sees a matched child.

Picks the FIRST non-fan_in child of each matching chain (deterministic — matches the OLD _baseline_xor_child_pick’s first-pick behavior for the AY.4.g minimum-viable scope; the fan_in / multi-pick variants land if AY.5 surfaces matview rows that need them).

Account fields denormalize onto the child leg from the parent plant’s account context — the matview keys on (transfer_parent_id, child_name), NOT account columns, so any account is fine. The adapter threads the parent plant’s account triple through.

intended returns a CoverageObservation: “I planted a synthetic child leg satisfying chain X.” No matching Invariant (the completion is a non-violating shape; coverage detector deferred).

No-op when parent_name parents no chain (the common case — most parent plants don’t sit on a chain-parent rail). The emit returns silently in that case.

Parameters:
  • parent_transfer_id (str)

  • parent_name (str)

  • account_id (str)

  • account_role (str)

  • account_scope (str)

  • account_parent_role (str | None)

  • anchor_day (date)

  • instance (L2Instance)

  • prefix (str)

account_id: str
account_parent_role: str | None
account_role: str
account_scope: str
anchor_day: date
property claimed_accounts: frozenset[str]
emit(conn, *, scenario_id=None)[source]
Return type:

None

Parameters:
  • conn (SyncConnection)

  • scenario_id (str | None)

instance: L2Instance
property intended: CoverageObservation
parent_name: str
parent_transfer_id: str
prefix: str = 'spec_example'