recon_gen.common.l2.plant_registry

BU.1 — Plant registry for the Trainer surface.

The single source of truth for every violation kind the Trainer surfaces (per BU.0 Lock 7). The registry is a tuple of PlantKindEntry records; the Trainer UI + the plant invocation + the tour iframe + the parameterized e2e contract all data-drive off the entry.

Per BU.0 Lock 8 — the registry is a thin index over typed violation-class sections (InvariantSection / L2FTExceptionSection / L2TriageGapSection). Display strings (title / short statement / remediation) live on the section. The entry just carries:

  • kind — canonical machine name; matches the section’s kind (with optional section_kind override for slug-mismatch edge cases per BU.0 round-4 Notes).

  • category — discriminator for which typed-section lookup to use via resolve_section (Lock 8).

  • family — accordion grouping on the landing page.

  • plant_function — callable that returns the SQL string applied to the demo DB.

  • primitives — typed form-field schema operator fills in.

  • tour_destination — iframe URL + sheet anchor for the Tour page.

  • dashboard_check — parameterized e2e contract (BU.0 Lock 9).

Per BU.1 (vertical slice) — this module ships with ONE entry (phantom_rail) so the rendering + tour + e2e patterns can be validated end-to-end before scaling. BU.2b populates the remaining 20 entries; BU.3.x adds the 5 needs-build plants.

Adding a future violation kind = one row here + one markdown section in the existing handbook parser + zero new UI / test files.

Functions

entries_by_family()

Group registry entries by family for the landing accordion.

get_entry(kind)

O(N) lookup — N is small (~21 at full scale).

Classes

DashboardCheck([matview_name, ...])

The parameterized e2e contract: after the plant fires + the matview refresh runs, what should be observable on the dashboard?

PlantCategory(*values)

Per BU.0 §0.5 matrix — drives resolve_section dispatch.

PlantKindEntry(kind, category, family, ...)

Thin index per BU.0 Lock 8 — display strings live on the typed violation section referenced by kind (or section_kind when there's a slug mismatch with the handbook parser's auto-derived key).

PrimitiveIntField(name, label, help_text, ...)

Integer input.

PrimitiveStringField(name, label, help_text, ...)

Free-text string input.

TourDestination(primary_url[, secondary_links])

Where the Tour page iframes into.

class recon_gen.common.l2.plant_registry.DashboardCheck(matview_name=None, min_row_count=1, url_path=None, expect_text_contains=None)[source]

Bases: object

The parameterized e2e contract: after the plant fires + the matview refresh runs, what should be observable on the dashboard?

Two shapes:

  • matview_name + min_row_count — for kinds backed by a precomputed matview (L1 + L2FT Hygiene). The e2e queries the matview directly + asserts row count.

  • url_path + expect_text_contains — for kinds whose “matview” is computed at-query-time by the route (L2 Triage — /etl/triage renders the gap card from detect_gaps() against the live tables, no stored matview).

Exactly one shape is set per entry; the parameterized e2e branches on which is present.

Parameters:
  • matview_name (str | None)

  • min_row_count (int)

  • url_path (str | None)

  • expect_text_contains (str | None)

expect_text_contains: str | None
matview_name: str | None
min_row_count: int
url_path: str | None
class recon_gen.common.l2.plant_registry.PlantCategory(*values)[source]

Bases: str, Enum

Per BU.0 §0.5 matrix — drives resolve_section dispatch.

L1_INVARIANT = 'l1_invariant'
L2FT_HYGIENE = 'l2ft_hygiene'
L2_COVERAGE = 'l2_coverage'
L2_TRIAGE = 'l2_triage'
class recon_gen.common.l2.plant_registry.PlantKindEntry(kind, category, family, plant_function, primitives, tour_destination, dashboard_check, section_kind=None, kind_qualifier=None)[source]

Bases: object

Thin index per BU.0 Lock 8 — display strings live on the typed violation section referenced by kind (or section_kind when there’s a slug mismatch with the handbook parser’s auto-derived key).

Parameters:
category: PlantCategory
dashboard_check: DashboardCheck
family: str
kind: str
kind_qualifier: str | None
plant_function: Callable[[...], str]
primitives: tuple[PrimitiveStringField | PrimitiveIntField, ...]
section_kind: str | None
tour_destination: TourDestination
class recon_gen.common.l2.plant_registry.PrimitiveIntField(name, label, help_text, default, min_value=None, max_value=None)[source]

Bases: object

Integer input. Renders as <input type="number"> with optional min/max attrs.

Parameters:
  • name (str)

  • label (str)

  • help_text (str)

  • default (int)

  • min_value (int | None)

  • max_value (int | None)

default: int
help_text: str
label: str
max_value: int | None
min_value: int | None
name: str
class recon_gen.common.l2.plant_registry.PrimitiveStringField(name, label, help_text, default)[source]

Bases: object

Free-text string input. Renders as <input type="text">.

Parameters:
  • name (str)

  • label (str)

  • help_text (str)

  • default (str)

default: str
help_text: str
label: str
name: str
class recon_gen.common.l2.plant_registry.TourDestination(primary_url, secondary_links=())[source]

Bases: object

Where the Tour page iframes into.

primary_url is the full URL (no query-param expansion in the slice; BU.2+ may extend with {prefix} / {form_<field>} template substitution if needed).

Parameters:
  • primary_url (str)

  • secondary_links (tuple[tuple[str, str], ...])

primary_url: str
recon_gen.common.l2.plant_registry.entries_by_family()[source]

Group registry entries by family for the landing accordion.

Return type:

Mapping[str, tuple[PlantKindEntry, ...]]

recon_gen.common.l2.plant_registry.get_entry(kind)[source]

O(N) lookup — N is small (~21 at full scale).

Return type:

PlantKindEntry | None

Parameters:

kind (str)