test(qa): add exhaustive 38-scenario test suite covering happy, sad, borderline, LLM fallback, CLI contracts, and multilingual matrix

This commit is contained in:
2026-08-21 11:11:35 -03:00
parent a874b98dac
commit 2cdd3547b2
17 changed files with 6111 additions and 1287 deletions
@@ -99,7 +99,7 @@
"97": "🧠 TextNLPClassifierApp",
"98": "Extraction Pipeline Checklist: Article Content Multi-Engine Extractor",
"99": "parametrize",
"100": "models.py",
"100": "main",
"101": "ECPSnapshot",
"102": "Feature Specification: Multilingual NLP Entity Inherence Classifier (POC)",
"103": "4. Requisitos Funcionais (FR)",
@@ -151,7 +151,7 @@
"149": "sample_rss_xml",
"150": "13. Estratégia de testes",
"151": "6. Contrato de entrada",
"152": "InherenceClassifier",
"152": "LLMFallbackAdapter",
"153": "convert_html_to_markdown",
"154": "JSON Schema Contract: Deterministic Article Content Selection",
"155": "5. Escopo",
@@ -164,7 +164,7 @@
"162": "test_normalize_date_iso_8601_variants",
"163": "test_metadata_priority_original_url_all_fallbacks",
"164": "test_normalize_scalar_non_string_types",
"165": ".disambiguate",
"165": "InherenceClassifier",
"166": "remove_duplicate_initial_h1",
"167": "test_normalize_scalar_whitespace_collapsing"
}
+37 -37
View File
@@ -1,16 +1,16 @@
# Graph Report - TextNLPClassifierApp (2026-08-21)
## Corpus Check
- 201 files · ~110,615 words
- 202 files · ~112,197 words
- Verdict: corpus is large enough that graph structure adds value.
## Summary
- 1554 nodes · 1970 edges · 168 communities (120 shown, 48 thin omitted)
- Extraction: 97% EXTRACTED · 3% INFERRED · 0% AMBIGUOUS · INFERRED: 59 edges (avg confidence: 0.95)
- 1579 nodes · 2030 edges · 168 communities (120 shown, 48 thin omitted)
- Extraction: 96% EXTRACTED · 4% INFERRED · 0% AMBIGUOUS · INFERRED: 73 edges (avg confidence: 0.95)
- Token cost: 0 input · 0 output
## Graph Freshness
- Built from commit: `31152d50`
- Built from commit: `bae14405`
- Run `git rev-parse HEAD` and compare to check if the graph is stale.
- Run `graphify update .` after code changes (no API cost).
@@ -110,7 +110,7 @@
- 🧠 TextNLPClassifierApp
- Extraction Pipeline Checklist: Article Content Multi-Engine Extractor
- parametrize
- models.py
- main
- ECPSnapshot
- Feature Specification: Multilingual NLP Entity Inherence Classifier (POC)
- 4. Requisitos Funcionais (FR)
@@ -160,7 +160,7 @@
- sample_rss_xml
- 13. Estratégia de testes
- 6. Contrato de entrada
- InherenceClassifier
- LLMFallbackAdapter
- convert_html_to_markdown
- JSON Schema Contract: Deterministic Article Content Selection
- 5. Escopo
@@ -173,16 +173,16 @@
- test_normalize_date_iso_8601_variants
- test_metadata_priority_original_url_all_fallbacks
- test_normalize_scalar_non_string_types
- .disambiguate
- InherenceClassifier
- remove_duplicate_initial_h1
- test_normalize_scalar_whitespace_collapsing
## God Nodes (most connected - your core abstractions)
1. `ECPSnapshot` - 40 edges
2. `InherenceClassifier` - 29 edges
3. `DecisionCategory` - 28 edges
4. `LLMFallbackAdapter` - 26 edges
5. `ClassificationResult` - 24 edges
1. `ECPSnapshot` - 49 edges
2. `InherenceClassifier` - 36 edges
3. `DecisionCategory` - 35 edges
4. `LLMFallbackAdapter` - 32 edges
5. `ClassificationResult` - 26 edges
6. `select_article_extractor()` - 23 edges
7. `ExtractorName` - 21 edges
8. `PRD — Conversão de artigo JSON para Markdown` - 16 edges
@@ -347,12 +347,12 @@ Cohesion: 0.29
Nodes (6): 1.1 Arguments & Options, 1. Command Line Interface, 2.1 Exit Codes, 2.2 Standard Output (`stdout`) / Standard Error (`stderr`), 2. Standard Streams & Exit Codes, CLI Contract & Interface Specification (POC)
### Community 45 - "ClassificationResult"
Cohesion: 0.11
Nodes (17): ABC, BaseNLPAdapter, Base abstract adapter interface for optional Tier 2 / Tier 3 NLP enhancers., Abstract interface for pluggable NLP classification adapters., Return True if the underlying provider or model is installed and configured., Compute semantic similarity score between text and a set of candidate terms., Optionally refine an ambiguous classification result., LocalEmbeddingsAdapter (+9 more)
Cohesion: 0.10
Nodes (20): ABC, BaseNLPAdapter, Base abstract adapter interface for optional Tier 2 / Tier 3 NLP enhancers., Abstract interface for pluggable NLP classification adapters., Return True if the underlying provider or model is installed and configured., Compute semantic similarity score between text and a set of candidate terms., Optionally refine an ambiguous classification result., LocalEmbeddingsAdapter (+12 more)
### Community 46 - "test_adversarial.py"
Cohesion: 0.10
Nodes (19): Any, RelatedEntity, Adversarial and robustness test suite for Multilingual NLP Entity Inherence…, Run CLI via subprocess without --output and verify stdout is pure parseable…, Run CLI via subprocess with empty content and verify error code and exit code., Content about city/state governance of São Paulo against ECP for São Paulo FC., Run CLI via subprocess with missing target_name and verify error payload., Run CLI via subprocess with corrupted JSON and verify error payload. (+11 more)
Cohesion: 0.11
Nodes (19): RelatedEntity, Adversarial and robustness test suite for Multilingual NLP Entity Inherence…, Run CLI via subprocess without --output and verify stdout is pure parseable…, Run CLI via subprocess with empty content and verify error code and exit code., Run CLI via subprocess with missing target_name and verify error payload., Run CLI via subprocess with corrupted JSON and verify error payload., Content about apple fruit/culinary recipe against Apple Inc. tech entity., High-weight related entity mentioned in passing without required domain anchors. (+11 more)
### Community 47 - "classifier.py"
Cohesion: 0.16
@@ -434,13 +434,13 @@ Nodes (34): 1. Requirement Completeness, 2. Requirement Clarity & Non-Ambiguity,
Cohesion: 0.22
Nodes (9): parametrize, Garante aceitação de URLs absolutas com esquema HTTP e HTTPS válidos., Garante rejeição de esquemas não permitidos, URLs relativas e strings vazias., Garante que a ausência de corpo no extrator selecionado NUNCA faça fallback…, Garante que todos os placeholders documentados no PRD sejam descartados…, test_normalize_scalar_placeholders_discarded(), test_resolve_article_body_strict_isolation_all_extractors(), test_validate_url_invalid_schemes() (+1 more)
### Community 100 - "models.py"
Cohesion: 0.15
Nodes (17): emit_error(), main(), parse_args(), Namespace, ClassificationError, ErrorCode, MatchedGraphEntity, Enum (+9 more)
### Community 100 - "main"
Cohesion: 0.17
Nodes (15): emit_error(), main(), parse_args(), Namespace, ClassificationError, ErrorCode, Enum, str (+7 more)
### Community 101 - "ECPSnapshot"
Cohesion: 0.24
Nodes (10): ECPSnapshot, classifier(), fixture, parametrize, Controlled 24-case benchmark suite for Multilingual NLP Entity Inherence…, test_benchmark_case(), Unit tests for ECP models, schema validation, and structured error handling., test_ecp_snapshot_defaults() (+2 more)
Cohesion: 0.18
Nodes (12): ECPSnapshot, Any, classifier(), fixture, parametrize, Controlled 24-case benchmark suite for Multilingual NLP Entity Inherence…, test_benchmark_case(), Unit tests for ECP models, schema validation, and structured error handling. (+4 more)
### Community 102 - "Feature Specification: Multilingual NLP Entity Inherence Classifier (POC)"
Cohesion: 0.14
@@ -520,7 +520,7 @@ Nodes (16): detect_language(), extract_words(), normalize_text(), Lightweight mu
### Community 122 - "test_select_article_extractor.py"
Cohesion: 0.18
Nodes (16): generate_shingles(), normalize_text(), Executa a normalização determinística para comparação: 1. Decodificar entidades…, Gera conjunto de shingles ordenados de tamanho window_size (padrão 5). - Se…, Suíte de Testes Automatizados para o Seletor Determinístico de Extrator. Cobre…, Garante que marcação de imagem Markdown ![alt](url) seja descartada e link…, E2E: Executa scripts/select_article_extractor.py como subprocesso real na linha…, test_e2e_cli_subprocess_real_execution() (+8 more)
Nodes (16): generate_shingles(), normalize_text(), Executa a normalização determinística para comparação: 1. Decodificar entidades…, Gera conjunto de shingles ordenados de tamanho window_size (padrão 5). - Se…, Suíte de Testes Automatizados para o Seletor Determinístico de Extrator. Cobre…, Garante que marcação de imagem Markdown ![alt](url) seja descartada e link…, E2E: Executa CLI com arquivo inexistente e valida código 1 e mensagem no stderr., test_e2e_cli_subprocess_missing_file() (+8 more)
### Community 123 - "Feature Specification: Deterministic Content Selection"
Cohesion: 0.17
@@ -634,9 +634,9 @@ Nodes (4): 13.1 Testes unitários, 13.2 Testes de integração do CLI, 13.3 Caso
Cohesion: 0.50
Nodes (4): 6.1 Formato, 6.2 Valores aceitos para `selected_extractor`, 6.3 Campos obrigatórios após a resolução, 6. Contrato de entrada
### Community 152 - "InherenceClassifier"
Cohesion: 0.11
Nodes (31): LLMFallbackAdapter, Optional adapter for LLM fallback boundary disambiguation., InherenceClassifier, Any, Tier 1 Deterministic NLP Entity Inherence Classifier with optional Tier 2 /…, DecisionCategory, Unit tests for deterministic classification decision logic., test_contextual_inherent() (+23 more)
### Community 152 - "LLMFallbackAdapter"
Cohesion: 0.08
Nodes (26): LLMFallbackAdapter, Executes LLM fallback for ambiguous boundary cases. Returns a refined…, Parses and validates structured JSON response from LLM., Optional adapter for LLM fallback boundary disambiguation., Returns True if an API key or custom provider function is configured., Constructs an expert-engineered prompt for multilingual entity inherence…, Any, Suíte de Testes para o Adaptador de Fallback para LLM (Tier 3) do Classificador… (+18 more)
### Community 153 - "convert_html_to_markdown"
Cohesion: 0.33
@@ -650,9 +650,9 @@ Nodes (3): 1. Input JSON Schema, 2. Output JSON Schema, JSON Schema Contract: De
Cohesion: 0.67
Nodes (3): 5.1 Incluído, 5.2 Fora do escopo, 5. Escopo
### Community 165 - ".disambiguate"
Cohesion: 0.25
Nodes (4): Executes LLM fallback for ambiguous boundary cases. Returns a refined…, Parses and validates structured JSON response from LLM., Returns True if an API key or custom provider function is configured., Constructs an expert-engineered prompt for multilingual entity inherence…
### Community 165 - "InherenceClassifier"
Cohesion: 0.11
Nodes (30): InherenceClassifier, Tier 1 Deterministic NLP Entity Inherence Classifier with optional Tier 2 /…, DecisionCategory, Content about city/state governance of São Paulo against ECP for São Paulo FC., test_adversarial_sao_paulo_city_vs_fc(), Unit tests for deterministic classification decision logic., test_contextual_inherent(), test_direct_inherent() (+22 more)
### Community 166 - "remove_duplicate_initial_h1"
Cohesion: 0.50
@@ -667,16 +667,16 @@ Nodes (4): Remove o primeiro título H1 do corpo somente quando ele for igual ao
_Questions this graph is uniquely positioned to answer:_
- **Why does `PRD — Conversão de artigo JSON para Markdown` connect `PRD — Conversão de artigo JSON para Markdown` to `8. Regras funcionais`, `12. Critérios de aceite`, `11. Requisitos não funcionais`, `9. Interface CLI`, `13. Estratégia de testes`, `6. Contrato de entrada`, `5. Escopo`?**
_High betweenness centrality (0.008) - this node is a cross-community bridge._
- **Why does `Implementation Plan: Convert Article JSON to Markdown` connect `Implementation Plan: Convert Article JSON to Markdown` to `005-convert-json-markdown/plan.md`?**
_High betweenness centrality (0.004) - this node is a cross-community bridge._
_High betweenness centrality (0.006) - this node is a cross-community bridge._
- **Why does `Tasks: Convert Article JSON to Markdown` connect `Tasks: Convert Article JSON to Markdown` to `005-convert-json-markdown/plan.md`?**
_High betweenness centrality (0.004) - this node is a cross-community bridge._
- **Are the 10 inferred relationships involving `ECPSnapshot` (e.g. with `main()` and `BaseNLPAdapter`) actually correct?**
_`ECPSnapshot` has 10 INFERRED edges - model-reasoned connections that need verification._
- **Are the 6 inferred relationships involving `InherenceClassifier` (e.g. with `LocalEmbeddingsAdapter` and `LLMFallbackAdapter`) actually correct?**
_`InherenceClassifier` has 6 INFERRED edges - model-reasoned connections that need verification._
- **Are the 18 inferred relationships involving `DecisionCategory` (e.g. with `LLMFallbackAdapter` and `InherenceClassifier`) actually correct?**
_`DecisionCategory` has 18 INFERRED edges - model-reasoned connections that need verification._
- **Why does `ECPSnapshot` connect `ECPSnapshot` to `main`, `InherenceClassifier`, `ClassificationResult`, `test_adversarial.py`, `classifier.py`, `LLMFallbackAdapter`?**
_High betweenness centrality (0.004) - this node is a cross-community bridge._
- **Are the 16 inferred relationships involving `ECPSnapshot` (e.g. with `main()` and `BaseNLPAdapter`) actually correct?**
_`ECPSnapshot` has 16 INFERRED edges - model-reasoned connections that need verification._
- **Are the 7 inferred relationships involving `InherenceClassifier` (e.g. with `LocalEmbeddingsAdapter` and `LLMFallbackAdapter`) actually correct?**
_`InherenceClassifier` has 7 INFERRED edges - model-reasoned connections that need verification._
- **Are the 24 inferred relationships involving `DecisionCategory` (e.g. with `LLMFallbackAdapter` and `InherenceClassifier`) actually correct?**
_`DecisionCategory` has 24 INFERRED edges - model-reasoned connections that need verification._
- **Are the 4 inferred relationships involving `LLMFallbackAdapter` (e.g. with `ClassificationResult` and `DecisionCategory`) actually correct?**
_`LLMFallbackAdapter` has 4 INFERRED edges - model-reasoned connections that need verification._
File diff suppressed because it is too large Load Diff
+12 -6
View File
@@ -330,9 +330,9 @@
"semantic_hash": ""
},
"src/adapters/llm.py": {
"mtime": 1787320797.2485664,
"seen": 1787320818.2953389,
"ast_hash": "a5cd6f66048ee1d443c2c91ae9947a14",
"mtime": 1787321086.752706,
"seen": 1787321205.5144775,
"ast_hash": "21ac74a13ac5dfad7db498b17165f8b3",
"semantic_hash": ""
},
"src/classifier.py": {
@@ -654,9 +654,9 @@
"semantic_hash": ""
},
"README.md": {
"mtime": 1787320219.5852203,
"seen": 1787320239.0933797,
"ast_hash": "ce59670fbaebc5e408a30a1009a58d12",
"mtime": 1787321187.0812356,
"seen": 1787321205.5201268,
"ast_hash": "aedfaf7a245288227952a2e28e7e7b13",
"semantic_hash": ""
},
"scripts/extract_article_contents.py": {
@@ -916,5 +916,11 @@
"seen": 1787320818.2967606,
"ast_hash": "e5d98de814ceeecd8bd601a7c206e92d",
"semantic_hash": ""
},
"tests/test_e2e_text_analysis_pipeline.py": {
"mtime": 1787321086.751707,
"seen": 1787321205.5156026,
"ast_hash": "3a2d47f2ffcf8371ffdf90bb797b5346",
"semantic_hash": ""
}
}