feat: add deterministic content extractor selector engine with F1 consensus
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
# CLI Interface Contract: Deterministic Article Content Selection
|
||||
|
||||
**Branch**: `004-deterministic-content-selection` | **Date**: 2026-08-20 | **Spec**: [spec.md](../spec.md)
|
||||
|
||||
---
|
||||
|
||||
## 1. Command Syntax
|
||||
|
||||
```bash
|
||||
python scripts/select_article_extractor.py <input_file> [-o OUTPUT] [--indent INDENT] [--verbose]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Arguments and Flags
|
||||
|
||||
| Argumento / Flag | Tipo | Obrigatório | Padrão | Descrição |
|
||||
|---|---|:---:|---|---|
|
||||
| `input_file` | `Path` (Posicional) | Sim | - | Caminho para o arquivo JSON contendo a coleção `articles` extraída. |
|
||||
| `-o`, `--output` | `Path` | Não | `<input_file_without_ext>_selected.json` | Caminho do arquivo JSON de destino. Se omitido, grava no mesmo diretório com sufixo `_selected.json`. |
|
||||
| `--indent` | `int` | Não | `2` | Número de espaços para indentação do JSON de saída. Use `0` para JSON compacto em linha única. |
|
||||
| `-v`, `--verbose` | `flag` | Não | `False` | Exibe no `stderr` detalhes da pontuação e justificativa de escolha por artigo. |
|
||||
|
||||
---
|
||||
|
||||
## 3. Standard Streams (I/O)
|
||||
|
||||
- **`stdout`**:
|
||||
- Emite o sumário operacional em JSON ou texto resumido ao término da execução:
|
||||
```json
|
||||
{
|
||||
"status": "success",
|
||||
"input_file": "out/river_plate_extracted.json",
|
||||
"output_file": "out/river_plate_extracted_selected.json",
|
||||
"total_articles": 20,
|
||||
"distribution": {
|
||||
"newspaper4k": 9,
|
||||
"readability": 9,
|
||||
"trafilatura": 2
|
||||
}
|
||||
}
|
||||
```
|
||||
- **`stderr`**:
|
||||
- Mensagens de log, progresso da barra/processamento de artigos e erros de validação ou exceções.
|
||||
|
||||
---
|
||||
|
||||
## 4. Exit Codes
|
||||
|
||||
| Código | Significado | Comportamento |
|
||||
|:---:|---|---|
|
||||
| `0` | **Sucesso** | Todos os artigos foram processados e o arquivo final foi gravado atomicamente com sucesso. |
|
||||
| `1` | **Erro de I/O ou JSON Inválido** | Arquivo não encontrado, JSON malformado ou permissão negada. Nenhum arquivo de saída é gerado. |
|
||||
| `2` | **Erro de Validação de Estrutura** | Raiz não é objeto ou chave `articles` não é uma lista. Nenhum arquivo de saída é gerado. |
|
||||
@@ -0,0 +1,80 @@
|
||||
# JSON Schema Contract: Deterministic Article Content Selection
|
||||
|
||||
**Branch**: `004-deterministic-content-selection` | **Date**: 2026-08-20 | **Spec**: [spec.md](../spec.md)
|
||||
|
||||
---
|
||||
|
||||
## 1. Input JSON Schema
|
||||
|
||||
O arquivo de entrada deve conter uma lista de artigos sob a chave `articles`.
|
||||
|
||||
```json
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"type": "object",
|
||||
"required": ["articles"],
|
||||
"properties": {
|
||||
"articles": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"trafilatura": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"text": { "type": ["string", "null"] },
|
||||
"error": { "type": ["string", "null"] }
|
||||
}
|
||||
},
|
||||
"newspaper4k": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"text": { "type": ["string", "null"] },
|
||||
"error": { "type": ["string", "null"] }
|
||||
}
|
||||
},
|
||||
"readability": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"cleaned_text": { "type": ["string", "null"] },
|
||||
"error": { "type": ["string", "null"] }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Output JSON Schema
|
||||
|
||||
O arquivo de saída mantém todos os campos, metadados e ordem originais, adicionando obrigatoriamente `selected_extractor`.
|
||||
|
||||
```json
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"type": "object",
|
||||
"required": ["articles"],
|
||||
"properties": {
|
||||
"articles": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": ["selected_extractor"],
|
||||
"properties": {
|
||||
"selected_extractor": {
|
||||
"type": "string",
|
||||
"enum": ["trafilatura", "newspaper4k", "readability"]
|
||||
},
|
||||
"trafilatura": { "type": "object" },
|
||||
"newspaper4k": { "type": "object" },
|
||||
"readability": { "type": "object" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
Reference in New Issue
Block a user