feat(runtime): implement single-article consolidation runtime and modularize codebase

This commit is contained in:
2026-08-24 00:14:07 -03:00
parent e1e0be1353
commit 23de7d8fe7
176 changed files with 266754 additions and 10179 deletions
+180 -25
View File
@@ -45,13 +45,13 @@
"43": "2. Basic CLI Usage Examples",
"44": "2. Standard Streams & Exit Codes",
"45": "ClassificationResult",
"46": "test_adversarial.py",
"47": "InherenceClassifier",
"48": "test_convert_article_to_markdown.py",
"46": "ECPSnapshot",
"47": "LLMFallbackAdapter",
"48": "classifier.py",
"49": "content_northvolt_de.md",
"50": "content_presal_pt.md",
"51": "content_tangential_es.md",
"52": "adapters/__init__.py",
"52": "config.py",
"53": "src/__init__.py",
"54": "de/contextual.md",
"55": "de/direct.md",
@@ -96,10 +96,10 @@
"94": "Specification Quality Checklist: Google News Headlines Extractor",
"95": "CLI Contract: Google News Headlines Extractor",
"96": "readiness.md",
"97": "🧠 TextNLPClassifierApp",
"97": "5. 📝 Conversor de Artigo JSON para Markdown",
"98": "Extraction Pipeline Checklist: Article Content Multi-Engine Extractor",
"99": "parametrize",
"100": "Path",
"99": "ModelGatewayClient",
"100": "SQLiteStore",
"101": "main",
"102": "Feature Specification: Multilingual NLP Entity Inherence Classifier (POC)",
"103": "4. Requisitos Funcionais (FR)",
@@ -148,29 +148,184 @@
"146": "Specification Quality Checklist: Convert Article JSON to Markdown",
"147": "CLI Contract: `convert_article_to_markdown.py`",
"148": "9. Interface CLI",
"149": "sample_rss_xml",
"149": "test_convert_article_to_markdown.py",
"150": "13. Estratégia de testes",
"151": "6. Contrato de entrada",
"152": "ECPSnapshot",
"152": "test_models.py",
"153": "convert_html_to_markdown",
"154": "JSON Schema Contract: Deterministic Article Content Selection",
"154": "properties",
"155": "5. Escopo",
"156": "Los puntajes de River vs. Independiente Santa Fe, por la Copa Sudamericana - TyC Sports",
"157": "valid_newspaper4k.md",
"158": "valid_readability.md",
"159": "test_normalize_list_author_url_filtering",
"160": "test_normalize_date_invalid_and_placeholders",
"161": "test_normalize_list_deduplication_preserves_case_and_order",
"162": "test_normalize_date_iso_8601_variants",
"163": "test_metadata_priority_original_url_all_fallbacks",
"164": "test_normalize_scalar_non_string_types",
"165": "test_e2e_text_analysis_pipeline.py",
"166": "remove_duplicate_initial_h1",
"167": "test_normalize_scalar_whitespace_collapsing",
"168": "LLMFallbackAdapter",
"169": "test_funnel_cli_subprocess_end_to_end",
"170": "test_models.py",
"171": "extract_evidence_snippets",
"172": ".classify",
"173": "🧪 Documentação da Suíte de Testes Automatizados"
"159": "consolidate.py",
"160": "run_preflight_checks",
"161": "adapter.py",
"162": "validate_and_extract_enrichment",
"163": "candidate/parser.py",
"164": "hygiene/harness.py",
"165": "SanitizedJsonLogger",
"166": "InputSizeExceededError",
"167": "CandidateObject",
"168": "enum",
"169": "Plano de testes e evals — Runtime de consolidação de artigos",
"170": "Especificação de prompt, contexto e harness — Runtime",
"171": "ExecutionStateMachine",
"172": "Implementation Tasks: Article Consolidation and Hygiene Runtime",
"173": "🧪 Documentação da Suíte de Testes Automatizados",
"174": "properties",
"175": "repair-operations.schema.json",
"176": "Functional Requirements",
"177": "test_equivalence_mapping.py",
"178": "enrichment-response.schema.json",
"179": "create_manifest_dict",
"180": "Catálogo de métricas e KPIs — Runtime de consolidação de artigos",
"181": "article_content_hygiene",
"182": "._get_connection",
"183": "Documento de Arquitetura — Runtime de consolidação de artigos",
"184": "null",
"185": "Runbook de produção — Runtime de consolidação de artigos",
"186": "article_content_hygiene",
"187": "properties",
"188": "properties",
"189": "PRD — Runtime de consolidação e higienização de artigos",
"190": "required",
"191": "properties",
"192": "type",
"193": "properties",
"194": "build_minimal_hygiene_projection",
"195": "check_zero_regex.py",
"196": "properties",
"197": "runtime-config.schema.json",
"198": "properties",
"199": "object",
"200": "candidates-payload.schema.json",
"201": "limits",
"202": "langfuse",
"203": "string",
"204": "type",
"205": "CLI Interface Contract: Article Consolidation and Hygiene Runtime",
"206": "2. Entity Definitions",
"207": "3. Concrete Architectural & Technical Decisions",
"208": "Requirements Readiness Checklist: Article Consolidation and Hygiene Runtime",
"209": "object",
"210": "null",
"211": "properties",
"212": "calculate_execution_fingerprint",
"213": "model_versions",
"214": "3. Operational Execution Scenarios",
"215": "type",
"216": "test_cli_subprocess_pipeline.py",
"217": "clean_body_images",
"218": "ecp",
"219": "paths",
"220": "properties",
"221": "properties",
"222": "properties",
"223": "required",
"224": "required",
"225": "kept_block_ids",
"226": "parametrize",
"227": "4. 🎯 Seletor Determinístico de Conteúdo de Artigos",
"228": "1. Operational Commands",
"229": "sqlite",
"230": "required",
"231": "pricing",
"232": "article-input.schema.json",
"233": "properties",
"234": "enum",
"235": "required",
"236": "Implementation Plan: Article Consolidation and Hygiene Runtime",
"237": "verify_all_11_invariants",
"238": "enum",
"239": "required",
"240": "manifest-output.schema.json",
"241": "Prompts Versioned Contract: Article Consolidation and Hygiene Runtime",
"242": "6. 🚀 Runtime de Consolidação e Higienização de Artigos (006-article-consolidation-runtime)",
"243": "13. Parsing estrutural sem regex",
"244": "metadata_candidates",
"245": "enum",
"246": "required",
"247": "enum",
"248": "ecp-snapshot.schema.json",
"249": "hygiene-response.schema.json",
"250": "🧠 TextNLPClassifierApp",
"251": "ADR-003 — Usar orquestração explícita em Python, sem LangChain ou LangGraph",
"252": "required",
"253": "Specification Quality Checklist: Article Consolidation and Hygiene Runtime",
"254": "enum",
"255": "enum",
"256": "1. 🧠 Classificador de Conteúdo e Inerência (NLP / LLM / ECP)",
"257": "10. Contrato de saída",
"258": "14. Higienização por LLM",
"259": "4. Regras mandatórias",
"260": "8. Contrato de entrada do artigo",
"261": "18. Integração ECP",
"262": "7. Orquestração",
"263": "ADR-001 — Separar runtime e self-healing",
"264": "ADR-002 — Iniciar o runtime após a seleção do extrator",
"265": "ADR-004 — Gateway agnóstico com apenas modelos baratos no runtime",
"266": "ADR-005 — Proibir regex e palavras-chave manuais em decisões textuais",
"267": "ADR-006 — LLM seleciona evidências e propõe reparos, não regenera o artigo",
"268": "ADR-007 — Tornar o ECP obrigatório antes de toda saída editorial",
"269": "ADR-008 — Langfuse no runtime e Promptfoo no CI",
"270": "ADR-009 — Persistir estado em SQLite e saídas no filesystem",
"271": "ADR-010 — Produzir resultado estruturado sempre e Markdown condicionalmente",
"272": "ADR-011 — Definir SLOs de custo e latência a partir de staging",
"273": "7. Checklist de release",
"274": "eval_runner.py",
"275": "ecp-profile.schema.json",
"276": "prompt_versions",
"277": "12. Preparação determinística",
"278": "15. Pequenos reparos textuais",
"279": "9. Contrato do ECP",
"280": "15. Higienização extrativa",
"281": "16. Pequenos reparos",
"282": "20. Model Gateway",
"283": "23. Observabilidade",
"284": "3. Limites do sistema",
"285": "9. Política de dependências",
"286": "12. Monitoramento",
"287": "14. Reprocessamento",
"288": "16. Falha do provider primário",
"289": "21. Falha do SQLite",
"290": "6. Configuração obrigatória",
"291": "build_release_metadata.py",
"292": "removal_reasons",
"293": "kept_image_ids",
"296": "test_prompts_contract.py",
"298": "Release Quality Summary Report",
"299": "Comandos e Utilitários CLI",
"300": "13. Candidatos e proveniência",
"301": "16. Imagens e links",
"302": "17. Gate ECP",
"303": "18. Enriquecimento",
"304": "5. Escopo",
"305": "14. Modelo de candidatos",
"306": "22. Renderer e arquivos",
"307": "Architecture Decision Records — Runtime de consolidação de artigos",
"308": "15. Falha de validação de entrada",
"309": "17. Falha semântica ou de grounding",
"310": "18. Falha do ECP",
"311": "20. Falha do Langfuse",
"312": "22. Falha de filesystem ou disco",
"313": "26. Rollback manual",
"314": "ci_check.py",
"315": "prepare_reference_20.py",
"316": "test_contract_parity.py",
"317": "test_zero_regex_enforcement.py",
"318": "sample_rss_xml",
"319": "runtime/__init__.py",
"320": "adapters/__init__.py",
"321": "tools/__init__.py",
"322": "test_normalize_list_author_url_filtering",
"323": "test_normalize_list_deduplication_preserves_case_and_order",
"324": "test_normalize_date_iso_8601_variants",
"325": "test_normalize_date_invalid_and_placeholders",
"326": "test_metadata_priority_original_url_all_fallbacks",
"327": "test_normalize_scalar_whitespace_collapsing",
"328": "test_normalize_scalar_non_string_types",
"329": "2. 📰 Extrator de Manchetes do Google News",
"331": "⚙️ Instalação e Setup",
"332": "3. 📄 Extrator e Parser Multimotor de Artigos"
}