recon_gen.common.handbook.l2_triage_gaps

L2 Triage + L2 Coverage Gaps parser — BU.2a (Lock 10).

Reads src/recon_gen/docs/L2_Triage_Gaps.md (the single source of truth for L2-to-runtime alignment gaps — both Triage and Coverage families) and returns a typed mapping of section kind -> L2TriageGapSection.

Mirrors common.handbook.l2ft_exceptions (the L2FT hygiene catalogue) and common.handbook.invariants (the L1 invariants catalogue). Parser shape is identical to the L2FT flavor: ### N. <Title> headings, **Columns:** ... line, **What to do:** ... line — no SHOULD blockquote prefix (these are runtime checks against the L2, not L1 SHOULD-constraints).

Two families share this catalogue per BU.0 round-4 Notes: L2 Triage gaps (the four common.l2.triage.GapKind literals — runtime has data the L2 doesn’t account for) and L2 Coverage gaps (uncovered_rail / uncovered_template — L2 declares something the runtime doesn’t exercise). The family discriminator lives on common.l2.plant_registry.PlantKindEntry.family, not on the section type. SECTION_TITLE_BY_KIND pins the title-to-kind mapping for both families — a doc reordering or heading rename loud-fails at parser load rather than silently mis-attach.

Functions

load_bundled_l2_triage_gaps()

Read the bundled L2_Triage_Gaps.md from recon_gen.docs and return parsed sections.

parse_l2_triage_gaps(md_text)

Walk the markdown source and yield one section per ``### N.

Classes

L2TriageGapSection(kind, title, label, ...)

One parsed section from L2_Triage_Gaps.md.

class recon_gen.common.handbook.l2_triage_gaps.L2TriageGapSection(kind, title, label, editor_label, body, columns, what_to_do)[source]

Bases: object

One parsed section from L2_Triage_Gaps.md.

Same shape as common.handbook.l2ft_exceptions.L2FTExceptionSection plus a label field that’s the canonical short operator-facing label (replaces the inline _GAP_KIND_LABELS dict in _studio_routes).

Parameters:
  • kind (str)

  • title (str)

  • label (str)

  • editor_label (str)

  • body (str)

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

  • what_to_do (str)

body: str

Prose paragraphs after the heading. The **What to do:** ... line is extracted into what_to_do and dropped from body (mirrors the L1 + L2FT parsers). The **Columns:** ... line stays inline.

columns: tuple[str, ...]

Parsed column names from the **Columns:** ... line.

editor_label: str

CTA copy on the gap card’s editor link ("Open Rails editor" / etc.). Replaces _GAP_KIND_EDITOR_LABELS.

kind: str

Either one of the four common.l2.triage.GapKind literals (L2 Triage family) — "unmatched_rail" / "unmatched_template" / "missing_limit_schedule" / "missing_metadata_key" — or one of the two L2 Coverage section kinds — "uncovered_rail" / "uncovered_template".

label: str

Short operator-facing label rendered in the triage accordion header. Replaces common.html._studio_routes._GAP_KIND_LABELS. Same as title by default — split for future divergence.

title: str

Human heading — "Unmatched rail_name" / "Missing LimitSchedule" / etc. Matches the doc heading verbatim so a renderer can cross-link a gap card to its section.

what_to_do: str

Remediation paragraph parsed from the **What to do:** ... line. One-paragraph guidance — what does this gap mean for the integrator and what should they do about it.

recon_gen.common.handbook.l2_triage_gaps.load_bundled_l2_triage_gaps()[source]

Read the bundled L2_Triage_Gaps.md from recon_gen.docs and return parsed sections. Single call site for the triage page + the BU.2b registry adapter — neither needs to know where the doc lives.

Return type:

dict[str, L2TriageGapSection]

recon_gen.common.handbook.l2_triage_gaps.parse_l2_triage_gaps(md_text)[source]

Walk the markdown source and yield one section per ### N. <Title> heading. Returns {kind: L2TriageGapSection} keyed on the common.l2.triage.GapKind literal.

Return type:

dict[str, L2TriageGapSection]

Parameters:

md_text (str)