Sangeetha-Grantha

Metadata Value
Status Proposed — partially implemented (template repair + Tamil trailer strip shipped; adapter Part B open)
Version 0.2.0
Last Updated 2026-09-10
Author Sangeetha Grantha Team
Document Type Decision record
Deciders Sangeetha Grantha Team (Seshadri)
Relates to ADR-012 Unified Extraction Architecture
Evidence section-issues-cleanup-findings.md, .triage-cache/triage_report3.json

ADR-015: Structure-Aware Extraction Adapter for the Govindan Blog Family


[!NOTE] Decision record: preserve the original rationale and check its decision/supersession status. Current runtime guidance is in system architecture and Flyway migrations.

Context

The Curator Section Issues queue — variants whose section structure does not match their English/Latin template — stood at 484. A cleanup pass (see section-issues-cleanup-findings.md) brought it to 339 by fixing the CAT-B truncation bug, adding per-script inline section-label recognition, and re-splitting through the audit-logged variant-sections API under strict safety gates.

The residual 339 are dominated by two failure modes of the generic text-regex parser, both traced to a single upstream source family:

  1. Template under-count (~30 krithis / ~175 variants). The Latin template itself is missing a leading section. Root cause confirmed on giripai nelakonna: the pallavi marker renders as "P 1giripai…" (from <span style="font-size:180%">P</span><sup>1</sup>giripai), and the Latin inline-marker rule ^\s*P (?=[a-zA-Z]) rejected the footnote digit, so the pallavi was head-captured and dropped at import. Every sibling then mismatches the truncated template.
  2. Translation trailers (~60+ Tamil variants). The thyagaraja-vaibhavam Tamil variants append an inline word-by-word Tamil meaning after the lyric. Marker-based splitting keeps the trailer in the last section (observed 5–18× the size of the English last section).

The source is one house-style, not one blog

thyagaraja-vaibhavam (Tyagaraja), guru-guha (Dikshitar) and syamakrishnavaibhavam (Syama Sastri) are all V Govindan’s blogs and share an identical, years-stable template:

Because this one house-style backs essentially the entire flagged queue, source-coupled handling here has unusually high leverage and unusually low fragility — the two conditions that normally make source-specific parsing a bad trade are inverted.

Decision

Adopt a domain-gated, structure-aware adapter for the Govindan blog family, layered over the existing generic pipeline (ADR-012), not a forked parser. Split responsibilities by layer:

A. Generic parser/extractor (benefits all sources):

B. Govindan adapter (domain-gated; falls back to the generic parser on any mismatch):

C. Explicitly NOT decided here (follow-up, separate change):

Why an adapter and not more generic heuristics

The generic parser fights a text-vs-structure battle it cannot fully win: font-180 spans, <sup> semantics, and the HK preamble are markup facts that text normalization discards. Encoding them once, behind a domain gate, is more robust and more testable than piling source-shaped regexes into the shared parser where they risk regressing other sources.

Fallback strategy (non-negotiable)

The adapter is advisory. It runs only when the source domain matches the Govindan family, and its output is accepted only if it is self-consistent (e.g. all variants agree on one section structure — already true for 30/30 template-undercount krithis, a strong cross-validation signal). On any mismatch, low confidence, or an unrecognised page shape, the pipeline falls back to the current generic parser. A template-change is never emitted by the extractor; it is a separate, reviewed action (C above). The generic path remains the default for every non-Govindan source.

Testing strategy

Consequences

Positive

Negative / risks

Measured impact of the shipped generic fix (Part A)

Metric Before marker fix After marker fix
resplit-to-template (auto-fixable) 138 117
template-undercount (needs template repair) 9 30
Direct new auto-fixes from the marker fix alone 0
Template-undercount variants now cleanly reclaimable (all 6 scripts agree) 175

The marker fix reclaims nothing on its own — deliberately. Its value is diagnostic honesty: it stops 30 krithis from masquerading as safe re-splits (the safety gates were already refusing them because re-splitting would have dropped the pallavi) and reclassifies them as template-undercount, where all six script variants independently agree on the corrected structure. That agreement is what will make the follow-up template repair safe.

Follow-up

  1. Template-repair tool DONE (2026-07-17)scripts/template_repair.py built with the clean-prepend + cross-validation gates; 28 krithis reviewed by carnatic-musicologist (28/28 APPROVE) and applied (queue 339 → 231). See section-issues-cleanup-findings.md (Pass 2).
  2. Translation-trailer strip DONE (2026-07-17) — the marker/<sup> layering (Part A) is not needed for this: strip_refrain_trailer in structure_parser.py locates the lyric→trailer boundary from the pronunciation-digit signal (lyric lines carry HK digits; the appended Tamil prose does not), which is more robust than the Gist/Word-by-word structural bound this ADR first proposed and needs no domain gate. scripts/tamil_trailer_repair.py verified the removed tail was prose (parse-twice diff) and re-split 119 Tamil variants (queue 231 → 112). See section-issues-cleanup-findings.md (Pass 3).
  3. Still open — head-capture preamble stripper. The Modified-HK transliteration-key chart is captured into the Tamil pallavi (section 1). It doesn’t affect section counts, so it’s not a queue item, but it is the remaining cleanup the Govindan adapter (Part B) should own, alongside script-aware <sup> footnote stripping. Build behind the domain gate with the golden-fixture suite.
  4. Update adr-index.md and re-run the batch triage to record the queue movement (done through Pass 3).

Section index · Documentation home · Feature status