| Metadata | Value |
|---|---|
| Status | Active |
| Version | 1.1.1 |
| Last Updated | 2026-09-10 |
| Author | Sangeetha Grantha Team |
| Document Type | Design reference |
| Parent Document | quality-strategy.md |
| Related Tracks | TRACK-039, TRACK-040, TRACK-041 |
[!NOTE] Design/reference material: this page may include proposals or earlier implementation assumptions. Use current ingestion guide for implemented behavior and current operating steps.
This checklist provides a detailed, actionable breakdown of every task required to implement the strategy defined in the parent document. Tasks are organised by phase and sprint, with dependencies, acceptance criteria, and the responsible codebase area clearly identified.
[ ] — Not started[~] — In progress[x] — Completed[!] — Blocked(TRACK-nnn) indicates direct contribution to an active trackGoal: Establish quality baseline, formalise schemas, and set up infrastructure for multi-format ingestion. Timeline: Sprints 1–2 (~2 weeks)
database/audits/audit_section_count_mismatch.sqlkrithi_sections countdatabase/audits/audit_label_sequence_mismatch.sqldatabase/audits/audit_orphaned_lyric_blobs.sqlapplication_documentation/07-quality/results/krithi-structural-audit-2026-02.mdshared/domain/model/import/canonical-extraction-schema.jsonScrapeWorker output when retrofittedCanonicalExtractionDto matching the schema
modules/shared/domain/src/commonMain/kotlin/com/sangita/grantha/shared/domain/model/import/CanonicalExtractionDto.kttools/krithi-extract-enrich-worker/src/schema.pysource_tier, supported_formats, composer_affinity, last_harvested_at to import_sources
database/migrations/23__source_authority_enhancement.sqlkrithi_source_evidence table
database/migrations/24__krithi_source_evidence.sqlstructural_vote_log table
database/migrations/25__structural_vote_log.sqlsource_format and page_range to import_task_run
database/migrations/26__import_task_format_tracking.sqlextraction_queue table (Kotlin ↔ Python integration)
database/migrations/27__extraction_queue.sqlextraction_status enum, partial indexes for polling, FK to import_batch and import_task_runsource_documents, extraction_runs, and field_assertions tables
database/migrations/28__source_documents_extraction_runs.sqlparsed_payload JSONB in imported_krithissangita-cli db statusapplication_documentation/04-database/schema.md with new tables/columnsimport_sources records for each target source:
database/seed_data/04_import_sources_authority.sqlGoal: Build the Python PDF extraction service and integrate it into the Kotlin orchestration pipeline. Timeline: Sprints 1–4 (~4 weeks)
tools/krithi-extract-enrich-worker/
pyproject.toml
src/
__init__.py
cli.py # CLI entry point (for local dev / testing)
worker.py # DB-queue polling worker (production entry point)
db.py # PostgreSQL connection and extraction_queue operations
extractor.py # PyMuPDF text extraction
page_segmenter.py # Krithi boundary detection in anthology PDFs
structure_parser.py # Section label detection (P/A/C/SC/Chittaswaram)
metadata_parser.py # Header field extraction (title, raga, tala, deity)
ocr_fallback.py # Tesseract integration with Indic language packs
transliterator.py # indic-transliteration wrapper
schema.py # Canonical JSON schema validation (Pydantic)
config.py # Environment variable configuration
tests/
test_guruguha_mdskt.py
test_guruguha_mdeng.py
test_worker.py
fixtures/ # Sample PDF pages for regression testing
Dockerfile
docker-compose.override.yml # For standalone testing
pyproject.toml with dependencies:
python:3.11-slimpython -m src.worker (DB-queue polling mode)db.py: PostgreSQL connection pooling + extraction_queue CRUD
claim_pending_task() — SELECT ... FOR UPDATE SKIP LOCKEDmark_processing(task_id, hostname)mark_done(task_id, result_payload, metadata)mark_failed(task_id, error_detail)worker.py: Polling loop (see strategy Section 8.3.3)
EXTRACTION_POLL_INTERVAL_S)config.py: Read from environment variables
DATABASE_URL, SG_GEMINI_API_KEY, EXTRACTION_POLL_INTERVAL_S, EXTRACTION_BATCH_SIZE, EXTRACTION_MAX_CONCURRENT, LOG_LEVELsangita-cli extraction start --with-db starts and polls extraction_queue
extraction command to sangita-cli with build/start/stop/logs/status subcommandspython -m pytest tools/krithi-extract-enrich-worker/tests/ runs clean locallyextractor.py: PyMuPDF text extraction with font-size and position data
page_segmenter.py: Detect Krithi boundaries in anthology PDFs
metadata_parser.py: Extract title, raga, tala, deity, temple from Krithi headers
structure_parser.py: Detect section labels (Pallavi, Anupallavi, Charanam, Samashti Charanam, Chittaswaram)
schema.py: Validate output against canonical extraction JSON schemacli.py: CLI entry point
python -m src.cli extract --input <pdf_path_or_url> --output <json_path> [--pages 1-10]krithis table recordspage_segmenter.py for English/Latin script PDF layoutmetadata_parser.py for English header format (may differ from Sanskrit edition)ocr_fallback.py: Tesseract integration with Indic language packs
tools/krithi-extract-enrich-worker/src/prompts/pdf_extraction_prompt.txtThe Kotlin backend writes extraction requests to the extraction_queue table. The Python container (running independently) picks up and processes these tasks. The Kotlin backend then reads completed results.
ExtractionQueueRepository
modules/backend/dal/src/main/kotlin/com/sangita/grantha/backend/dal/repositories/ExtractionQueueRepository.ktsubmitExtractionTask(batchId, sourceUrl, format, requestPayload) — INSERT with PENDING statusfindCompletedTasks(batchId) — SELECT WHERE status=’DONE’findFailedTasks(batchId) — SELECT WHERE status=’FAILED’getQueueStats() — COUNT by status (for dashboard/observability)ExtractionQueueService
modules/backend/api/src/main/kotlin/com/sangita/grantha/backend/api/services/import/ExtractionQueueService.ktextraction_queueManifestWorker to detect PDF URLs in manifests
.pdf URL → INSERT into extraction_queue (instead of creating SCRAPE task).html URL → existing ScrapeWorker flow (unchanged)ExtractionResultProcessor (runs on Kotlin side)
modules/backend/api/src/main/kotlin/com/sangita/grantha/backend/api/services/import/ExtractionResultProcessor.ktextraction_queue for status=’DONE’ tasksresult_payload JSON (array of CanonicalExtractionDto)ImportedKrithi in stagingRESOLUTION tasks (same as existing HTML flow)PDF, DOCX, IMAGE to source format handling in BulkImportRepositoryPdfManifestWorker for PDF-based manifests
extraction_queue entries with source_format: PDFSourceAdapter interface in Kotlin
modules/backend/api/src/main/kotlin/com/sangita/grantha/backend/api/services/import/SourceAdapter.ktsuspend fun extract(sourceUrl: String, format: SourceFormat): List<CanonicalExtractionDto>WebScrapingService to implement SourceAdapterPdfSourceAdapter wrapping the Python service invocationCanonicalExtractionDto outputGoal: Implement cross-source structural voting to establish verified canonical structures. Timeline: Sprints 5–6 (~2 weeks) Dependency: Phase 1 complete (multiple sources ingested for overlapping Krithis)
StructuralVotingEngine service
modules/backend/api/src/main/kotlin/com/sangita/grantha/backend/api/services/quality/StructuralVotingEngine.ktkrithi_source_evidence records with extracted section structuresKrithiSourceEvidenceRepository
modules/backend/dal/src/main/kotlin/com/sangita/grantha/backend/dal/repositories/KrithiSourceEvidenceRepository.ktStructuralVoteLogRepository
modules/backend/dal/src/main/kotlin/com/sangita/grantha/backend/dal/repositories/StructuralVoteLogRepository.ktResolutionWorker post-processing stepComposerSourcePriority configuration
modules/backend/api/src/main/kotlin/com/sangita/grantha/backend/api/config/ComposerSourcePriority.ktImportService for source rankingImportReview to display source tier and authority rankingResolutionWorker to create krithi_source_evidence records after resolution
KrithiService to expose source evidence via API
GET /v1/admin/krithis/{id}/source-evidenceGoal: Systematically source lyric variants in multiple scripts and align to canonical section structure. Timeline: Sprints 7–8 (~2 weeks)
SwathiThirunalManifestWorker for swathithirunalfestival.org
/swathi-thirunal/compositions index, extract slug URLsLyricVariantAligner service
modules/backend/api/src/main/kotlin/com/sangita/grantha/backend/api/services/quality/LyricVariantAligner.ktindic-transliteration library
tools/krithi-extract-enrich-worker/src/transliterator.pytransliterate(text, from_script, to_script) -> strTransliterationEnrichmentJob:
extraction_method: TRANSLITERATION with is_primary: falseGoal: Populate deity, temple/Kshetra, tags, and Sampradaya metadata. Timeline: Sprints 9–10 (~2 weeks)
deities table recordstemples table (multilingual matching via temple_names)temple_source_cache or LLM inference)MetadataCleanupTask
modules/backend/api/src/main/kotlin/com/sangita/grantha/backend/api/services/quality/MetadataCleanupTask.ktkrithi_lyric_sections (blog headers, copyright notices, navigation text)StructuralNormalisationLogic
modules/backend/api/src/main/kotlin/com/sangita/grantha/backend/api/services/quality/StructuralNormalisationLogic.ktQualityScoringService on all remediated KrithisGoal: Ingest Swara notation from practitioner sources into the notation tables. Timeline: Sprints 11–12 (~2 weeks)
NotationParser for HTML notation (shivkumar.org format)
modules/backend/api/src/main/kotlin/com/sangita/grantha/backend/api/services/notation/NotationParser.ktKrithiNotationVariantDto + list of KrithiNotationRowDtoGoal: Establish ongoing quality monitoring, automated audits, and editorial governance. Timeline: Ongoing from Sprint 9
QualityAuditScheduler service
modules/backend/api/src/main/kotlin/com/sangita/grantha/backend/api/services/quality/QualityAuditScheduler.ktapplication_documentation/07-quality/results/ (auto-generated)GET /v1/admin/quality/auditsDashboardRoutes with quality metrics:
SourceRefreshJob:
last_harvested_at)AutoApprovalService thresholds:
field_assertions table)compose.yaml with krithi-extract-enrich-worker service (see strategy Section 8.2.1)
extraction_cache for downloaded PDFsextraction (opt-in: docker compose --profile extraction up)tools/krithi-extract-enrich-worker/Dockerfile with Tesseract OCR + Indic language packs
docker build -t sangita-krithi-extract-enrich-worker tools/krithi-extract-enrich-worker/ succeeds; container starts and polls extraction_queuetools/krithi-extract-enrich-worker/docker-compose.override.yml for standalone testing (krithi-extract-enrich-worker + postgres only)sangita-cli extraction start --with-db + Kotlin backend via Gradle
krithi-extract-enrich-worker to .mise.toml tool configuration if applicableextraction_cache volume retention policy (delete after 30 days, configurable)k8s/krithi-extract-enrich-worker-deployment.yaml (see strategy Section 8.2.3)
k8s/krithi-extract-enrich-worker-hpa.yaml — HorizontalPodAutoscaler
extraction_queue_pending_count custom metrick8s/krithi-extract-enrich-worker-configmap.yaml for non-secret configurationsangita-db-credentials/connection-stringsangita-gemini/api-keygcr.io/sangita-grantha/krithi-extract-enrich-workerkrithi-extract-enrich-worker to Cloud Run / GKE deployment documentationSELECT status, COUNT(*) FROM extraction_queue GROUP BY status
GET /v1/admin/extraction-queue/stats endpointstructlog for JSON-formatted logs compatible with Cloud Loggingapplication_documentation/08-operations/krithi-extract-enrich-worker-runbook.md
CanonicalExtractionDto serialisation/deserialisationStructuralVotingEngine with all voting scenariosLyricVariantAligner with match/mismatch/extra/missing scenariosExtractionQueueRepository and ExtractionQueueServicepage_segmenter.py with fixture PDF pagesstructure_parser.py for section marker variantsmetadata_parser.py for header extraction patternsworker.py polling and claim logicSwathiThirunalManifestWorkerNotationParserpytest tools/krithi-extract-enrich-worker/tests/) added to buildapplication_documentation/02-architecture/backend-system-design.md with containerised architecture and extraction queue patternapplication_documentation/04-database/schema.md with new tables (extraction_queue, source_documents, extraction_runs, field_assertions)application_documentation/06-backend/ with new service documentationapplication_documentation/08-operations/deployment.md with krithi-extract-enrich-worker Docker/K8s deploymentapplication_documentation/01-requirements/krithi-data-sourcing/README.md linking all documentsconductor/tracks/TRACK-039 progress log as audits completeconductor/tracks/TRACK-040 progress log as remediation runsconductor/tracks/TRACK-041 progress log as voting engine shipsPhase 0 (Foundation)
├── 0.1 TRACK-039 Audits
├── 0.2 Canonical Schema ──────────────────────────────┐
├── 0.3 DB Migrations (incl. extraction_queue) ────────┤
└── 0.4 Source Registry ───────────────────────────────┤
│
Cross-Cutting: Docker & Container Infrastructure ─────────┤
├── Dockerfile for krithi-extract-enrich-worker │
├── compose.yaml extension ◄── 0.3 (extraction_queue) │
└── K8s manifests (can be deferred to production) │
│
Phase 1 (PDF Ingestion) ◄────────────────────────────────┘
├── 1.1 Python Setup (incl. worker.py, db.py) ◄── Docker infra, 0.3
├── 1.2 Core PDF Extraction (mdskt.pdf) ◄── 1.1
├── 1.3 English PDF (mdeng.pdf) ◄── 1.2
├── 1.4 OCR Fallback ◄── 1.2
├── 1.5 LLM Refinement ◄── 1.2
├── 1.6 Kotlin DB Queue Integration ◄── 1.2, 0.2, 0.3
│ (ExtractionQueueRepo, ExtractionQueueService,
│ ExtractionResultProcessor)
└── 1.7 Source Adapter Interface ◄── 1.6
│
Phase 2 (Structural Voting) ◄────────────┘
├── 2.1 Voting Engine ◄── 0.3 (new tables)
├── 2.2 ComposerSourcePriority + field-level authority ◄── 0.4
└── 2.3 Source Evidence Tracking ◄── 0.3, 1.6
│
Phase 3 (Lyric Enrichment) ◄─────────────┘
├── 3.1 Swathi Thirunal Ingestion ◄── 1.7 (adapter interface)
├── 3.2 Lyric Variant Alignment ◄── 2.1 (canonical structure)
└── 3.3 Transliteration Service ◄── 1.1 (Python container)
│
Phase 4 (Metadata) ◄─────────────────────┘
├── 4.1 Deity Enrichment ◄── Phase 1 output
├── 4.2 Temple Enrichment ◄── Phase 1 output
├── 4.3 Tag Classification
└── 4.4 TRACK-040 Remediation ◄── 0.1 (audit baseline), 2.1
│
Phase 5 (Notation) ◄─────────────────────┘
├── 5.1 Notation Parser
├── 5.2 Shivkumar.org Ingestion ◄── 5.1, 1.7
└── 5.3 Notation Quality Checks ◄── 5.2
│
Phase 6 (Operations) ◄───────────────────┘
├── 6.1 Automated Audits ◄── 0.1
├── 6.2 Quality Dashboard ◄── all phases
├── 6.3 Re-Harvesting ◄── 1.7
├── 6.4 Auto-Approval Enhancement ◄── 2.1
├── 6.5 Admin UI ◄── 2.3, 6.2
└── K8s Production Deployment ◄── Docker infra, all phases
| Sprint | Phases | Key Deliverables | Estimated Effort |
|---|---|---|---|
| S1–S2 | Phase 0, Docker infra, Phase 1.1–1.2 | Quality baseline, canonical schema, DB migrations (incl. extraction_queue), Dockerfile, Docker Compose, PDF PoC (10 Krithis), Python worker polling extraction_queue | 2 weeks |
| S3–S4 | Phase 1.3–1.7 | Full PDF pipeline, Kotlin DB queue integration (ExtractionQueueService + ExtractionResultProcessor), 484 Dikshitar Krithis in staging, three-container stack validated | 2 weeks |
| S5–S6 | Phase 2 | Structural Voting Engine, field-level authority, source evidence tracking, multi-source validation | 2 weeks |
| S7–S8 | Phase 3 | Swathi Thirunal ingestion, English PDF variants, transliteration via Python container | 2 weeks |
| S9–S10 | Phase 4 | Deity/temple enrichment, TRACK-040 remediation, metadata cleanup | 2 weeks |
| S11–S12 | Phase 5, K8s prod | Notation parser, shivkumar.org ingestion, K8s deployment manifests, HPA configuration, production rollout | 2 weeks |
| Ongoing | Phase 6 | Automated audits, quality dashboard, re-harvesting, admin UI, operational monitoring | Continuous |
Aligned with the sprint allocation above, these milestones map to the 90-day delivery roadmap:
| Window | Days | Milestone | Key Validation |
|---|---|---|---|
| Window 1 | 1–20 | Docker container running, extraction_queue operational, 10 Dikshitar Krithis extracted from mdskt.pdf | Kotlin submits → Python extracts → result in DB |
| Window 2 | 21–45 | Full Dikshitar batch (484) in staging, structural voting MVP, review UI shows source evidence | Cross-source voting for 50 Krithis with 2+ sources |
| Window 3 | 46–70 | Swathi Thirunal ingestion, enrichment phases gated, quality scoring upgraded | 400 Swathi Thirunal + multi-script Dikshitar variants |
| Window 4 | 71–90 | Dikshitar remediation pilot complete, KPIs measured, K8s production deployment, runbook published | Quality score improvement, zero section drift, production-ready |