Pipeline de Diarios Parlamentarios · ParlaIbero
diaries-*
21 skills nativos de Claude Code que transforman diarios de sesiones parlamentarias —PDF escaneado o digital, HTML, XML, DOCX o texto plano— en matrices estandarizadas de intervenciones. Desde el OCR hasta el esquema canónico final, con un sistema de confianza de tres niveles que mantiene al investigador en control de cada decisión automática.
Mapa del pipeline
De la fuente al corpus · 13 skills en secuencia · 8 de controlsource/{iso2}/raw/ (PDF / HTML / XML / DOCX / TXT fuente) │ ▼ /diaries-bootstrap ──► country_config/{iso2}.yaml │ state/{iso2}/pipeline_state.json │ ▼ /diaries-ocr ──────────► source/{iso2}/ocr/{id}/page_NNNN.txt (solo si pdf_image) [LightOnOCR-2:1b → fallback por país: glm-ocr] │ ▼ /diaries-extract ──────► source/{iso2}/extracted/{id}.txt (texto FIEL — NO limpia) [consolida OCR/PDF/HTML/XML/DOCX/txt · conserva ---PAGE N---] │ ▼ /diaries-correct ──────► source/{iso2}/corrected/{id}.txt (ÚNICO limpiador: 5 pasos) [mobiliario por país + deshifenización + reflujo] │ /diaries-meta ────────► source/{iso2}/meta/{id}.json (fecha, nº, tipo, legislatura, [heurística registrada o DESCUBIERTA] presidencia por TRAMOS) lee extracted/ — la capa fiel, con el cabecero íntegro │ ▼ /diaries-dedupe ──────► source/{iso2}/_quarantine_duplicates/ (⚠ ANTES de tag) [boletín + fecha real · reversible] dos clases: (A) misma sesión bajo >1 id · (B) filas dobladas por ingesta multi-track · después de tag, su inventario sale sesgado │ ├────────────► /diaries-deputies ──► source/{iso2}/deputies/deputies.csv │ (opcional aquí: si hay pase de lista nominal, el padrón │ sale de corrected/ y alimenta a tag con --deputies) ▼ /diaries-tag ──────────► source/{iso2}/tagged/{id}.txt (⚠ crítico, 0.80/0.60) [regex 2 niveles → Claude para sospechosos] Paso 0c: inventario estructural por FORMA (gate anti-falsos negativos) │ ▼ /diaries-matrix ────────► source/{iso2}/matrix/interventions_raw.csv (parse <int> → CSV) [gate incrustados ≤0,1% · Prolegomena orden 0] │ ├────────────► /diaries-deputies ──► source/{iso2}/deputies/deputies.csv │ (BD de diputados) [externo o RapidFuzz+Claude] ▼ /diaries-match ─────────► source/{iso2}/match/matching_table.csv (⚠ crítico, 0.90/0.70) [congelado + exact → fuzzy → Claude] │ ▼ /diaries-merge ─────────► source/{iso2}/merge/interventions_enriched.csv (join pandas, period-aware) [Paso 3-bis: presidencia por TRAMO (president_meta) — hasta el 42% del corpus · gate de integridad referencial] │ ▼ /diaries-standardize ───► source/{iso2}/standardize/{ISO2}_interventions.csv ⚠ canónico (16 columnas canónicas + {ISO2}_deputies.csv) │ ▼ /diaries-document ──────► docs/{iso2}/README.md docs/{iso2}/data_dictionary.md docs/{iso2}/dataset.jsonld ────────────────────────────────────────────────────────────────── CONTROL (disponibles en cualquier momento) /diaries-status → tabla de estado del pipeline /diaries-review → revisar FLAGs y HALTs interactivamente [A/C/E/S/Q] /diaries-feedback → inyectar corrección (punctual/rule/strategy) /diaries-decide → registrar una decisión metodológica CON SU EVIDENCIA state/{iso2}/decisions.jsonl · state/_transversal/ docs/_metodologia/generados/METODOLOGIA.md (generado) /diaries-report → informe completo del proceso (lee lo que registró decide) /diaries-validate → validación estructural por muestreo + calibración de fuga /diaries-teach → guía interactiva del sistema /diaries-refine → mejorar un skill a partir de testing real ──────────────────────────────────────────────────────────────────
AUTO · FLAG · HALT
El skill completó la tarea con alta confianza. El pipeline continúa automáticamente al siguiente paso sin ninguna intervención.
Sin acción requeridaEl resultado es válido pero hay incertidumbre. El pipeline continúa y el caso se registra para revisión posterior en /diaries-review.
La confianza es insuficiente para continuar o se produjo un error. El pipeline se detiene y se requiere intervención manual inmediata.
Intervención manual obligatoriaPipeline principal · 13 skills
Haz clic en cualquier skill para ver entradas, salidas, fórmula de confianza e invocación.
/diaries-bootstrap --country {iso2}
Skill de nivel país: no usa --session ni --batch. Se ejecuta una sola vez por país. Puede reejecutarse con --force para regenerar la configuración.
/diaries-ocr --country {iso2} --all
/diaries-ocr --country {iso2} --session 1931-07-14
/diaries-ocr --country {iso2} --batch 1931-07
Control de la ñ: tras cada lote se miden las variantes rotas de «señor» (seflor, sefior, senor…). Un ratio > 1–2% indica que el primario no preserva la ñ en esa fuente: pasar al fallback y registrar las variantes en ocr.enye_variants para que correct y tag las toleren.
/diaries-extract --country {iso2} --all
Capa fiel: extracted/ es el punto de retorno reproducible y no se limpia NUNCA; --strip-headers queda como legado opt-in, fuera del flujo canónico. XML por parser de país: la ruta de CL (parse_cl_xml.py) entra ya etiquetada y vinculada directo a matrix — esas sesiones se saltan extract/correct/tag. Config: extract.emit_page_marker · extract.page_marker_format · extract.page_break_marker.
/diaries-correct --country {iso2} --all
/diaries-meta --country {iso2} --all
Sin heurística no se asume formato: se usa la registrada en meta_patterns del config o se DESCUBRE y valida (resolución contra el padrón, contigüidad temporal, cardinalidad, reparto por género). El JSON registra presidency.segments — la lista de tramos, incluido el relevo sin nombre («reasume la Presidencia»). Si date no se resuelve, se deriva al menos el AÑO del session_id (date_year_only + date_source: "session_id_year") — nunca se inventan día y mes.
/diaries-dedupe --country {iso2} # dry-run
/diaries-dedupe --country {iso2} --write # cuarentena (reversible, idempotente)
El estado se registra POR SESIÓN: detect_duplicates.py marca complete en cada keeper y skipped en cada redundante — no hay entrada _country. La Clase B siempre informa y pide confirmación explícita; las filas retiradas van a cuarentena reversible con manifiesto, nunca se borran.
# si hay pase de lista, construye antes el padrón y pásalo:
/diaries-deputies --country {iso2}
/diaries-tag --country {iso2} --all
/diaries-tag --country {iso2} --session 1931-07-14 --dry-run
⚠ Gate anti-falsos-negativos (verify_tagging.py): una sesión con n_residual_markers ≥ 1 va a HALT — ABSOLUTE FAIL, nunca a complete ni a flag. diaries-matrix aborta mientras exista una sola sesión así: un marcador sin etiquetar atribuye su intervención entera al orador anterior, en silencio.
/diaries-matrix --country {iso2} --all
/diaries-deputies --country {iso2}
/diaries-match --country {iso2}
/diaries-match --country {iso2} --force # re-ejecutar todo
/diaries-merge --country {iso2}
/diaries-standardize --country {iso2}
/diaries-standardize --country {iso2} --force # sobreescribir canónico
⚠ Se niega a sobreescribir {ISO2}_interventions.csv sin --force. El archivo canónico es irrecuperable si se sobreescribe por accidente.
/diaries-document --country {iso2}
Dos tasas, dos archivos: el README enuncia la vinculación bruta (filas con id_dep / total) Y la efectiva (excluido el denominador no vinculable: mesa sin persona, NOT_SPEAKER, no-discurso). dataset.jsonld declara los DOS archivos de la distribución: {ISO2}_interventions.csv + {ISO2}_deputies.csv (unible por id_dep + legislature). La documentación se regenera SIEMPRE entera y por una sola puerta.
Comandos de control
Muestra el estado del pipeline en tabla: los 13 skills en su orden canónico (bootstrap → ocr → extract → correct → meta → dedupe → tag → matrix → deputies → match → merge → standardize → document) × niveles (completo / flag / halt / pendiente). dedupe se cuenta POR SESIÓN.
/diaries-status --country {iso2}
Revisión interactiva de casos FLAG y HALT. Para cada FLAG: evidencia, confianza y decisión [A]ceptar · [C]orregir · [E]scalar · [S]altar. Los HALT se listan con su error y se marcan resueltos tras la intervención manual.
/diaries-review --country {iso2}
Inyecta una corrección en el estado. Tres tipos: punctual (1 sesión), rule (desde fecha → re-procesa), strategy (todo el skill + --force).
/diaries-feedback --country {iso2} --skill diaries-tag \
--type rule \
--description "Nuevo patrón de orador" \
--pattern "^EL SR\." --action "tag_as_speaker" \
--from 1931-09-01
Genera el informe interno del proceso: línea temporal, distribuciones de confianza, historial de correcciones y tasa de automatización. Escribe pipeline_report.md, nunca process_report.md: ese es el informe público que produce la cadena del depósito (decisión ar-0029).
/diaries-report --country {iso2}
# Salida: docs/{iso2}/pipeline_report.md
Registra una decisión metodológica en el momento, con su evidencia. Capturar e informar son cosas distintas: lo que no se captura cuando se decide, se pierde. La evidencia es obligatoria y se valida — existe para impedir que se registre una preferencia como si fuera un hallazgo. Las decisiones superadas no se borran: se marcan y se enlazan desde la que las anula, y esa cadena es el historial de correcciones del corpus.
/diaries-decide # modo interactivo
# consultar lo registrado
python3 ~/.claude/skills/diaries-lib/lib/utils/record_decision.py \
--pais {iso2} --listar
# regenerar el documento metodológico
python3 scripts/generar_metodologia.py
# Salida: docs/_metodologia/generados/METODOLOGIA.md
Valida la integridad estructural del corpus por muestreo, con auto-filtro PASS/FLAG y calibración empírica de la tasa de fuga. Produce la cifra de calidad que el corpus puede afirmar, no la que se supone.
/diaries-validate --country {iso2}
Guía interactiva del sistema. Ofrece 8 caminos: visión general, nuevo país, retomar pipeline, problemas por skill, sistema AUTO/FLAG/HALT, correcciones, mapa completo y registro de decisiones metodológicas.
/diaries-teach
Mejora un skill a partir de una observación de testing real. Edita directamente el SKILL.md en ~/.claude/skills/, donde el cambio queda activo de inmediato, y lo registra en REFINEMENTS.md.
/diaries-refine --skill diaries-tag \ --issue "Los patrones multi-línea no se detectan" /diaries-refine # modo interactivo
Flujos de trabajo
Para un código ISO2 que no existe aún en el sistema.
source/{iso2}/raw/YYYY-MM-DD.pdf
/diaries-bootstrap --country {iso2}
/diaries-ocr --country {iso2} --all
/diaries-extract --country {iso2} --all
/diaries-correct --country {iso2} --all
/diaries-review --country {iso2}
# meta y dedupe ANTES de tag
/diaries-meta --country {iso2} --all
/diaries-dedupe --country {iso2}
# opcional: si hay pase de lista nominal
/diaries-deputies --country {iso2}
/diaries-tag --country {iso2} --all
/diaries-review --country {iso2}
/diaries-matrix --country {iso2} --all
/diaries-deputies --country {iso2}
/diaries-match --country {iso2}
/diaries-review --country {iso2}
/diaries-merge --country {iso2}
/diaries-standardize --country {iso2}
/diaries-document --country {iso2}
/diaries-report --country {iso2}
Cuando el proceso se detuvo por FLAGS sin resolver o un error HALT.
/diaries-status --country {iso2}
/diaries-review --country {iso2}
/diaries-feedback --country {iso2} \
--skill diaries-tag \
--type rule \
--description "descripción del patrón" \
--from YYYY-MM-DD
/{skill_detenido} --country {iso2} --all
Si no sabes por dónde empezar,
/diaries-teach ofrece diagnóstico interactivo guiado paso a paso.
Instalación
Los 21 skills y su biblioteca (diaries-lib) se publican en el repositorio parlaibero-tools. install_skills.sh los copia a ~/.claude/skills/, la ruta desde la que los llama Claude Code. Si ya tienes alguno, se detiene sin tocarlo; --force los sustituye y guarda antes una copia.
git clone https://github.com/rodrodr/parlaibero-tools.git cd parlaibero-tools bash install_skills.sh
En la carpeta que vaya a contener los datos, un único script instala las dependencias Python, verifica que los 21 skills estén en ~/.claude/skills/ y crea la estructura de directorios.
mkdir mi-corpus && cd mi-corpus bash ~/.claude/skills/diaries-lib/install.sh
Copia las fuentes en source/{iso2}/raw/, abre Claude Code desde la carpeta del proyecto y ejecuta la guía interactiva, o configura directamente el país.
/diaries-teach
/diaries-bootstrap --country {iso2}
Skills · dónde viven
Claude Code usa los 21 SKILL.md de ~/.claude/skills/diaries-*/, y es esa copia la que se edita — p.ej. con /diaries-refine, cuyo cambio queda activo de inmediato y se registra en REFINEMENTS.md. La carpeta skills/ del repositorio es la versión publicada: para pasar a una más nueva, git pull y bash install_skills.sh --force, que guarda antes una copia de la instalada (también de lo que hayas cambiado en ella).
Ollama · OCR local
Necesario solo para PDFs escaneados (pdf_image). El instalador avisa si falta.
ollama pull Maternion/LightOnOCR-2:1b # primario ollama pull glm-ocr # fallback por defecto (por país)
Al ejecutar /diaries-bootstrap por primera vez para un país, se crean todos los subdirectorios necesarios:
source/{iso2}/
├── raw/ ← fuentes originales (tú las colocas)
├── ocr/{session_id}/ ← páginas OCR por sesión
├── extracted/ ← texto FIEL (conserva ---PAGE N---)
├── corrected/ ← párrafos corregidos
├── tagged/ ← texto con <int> tags
├── meta/ ← JSON de metadatos
├── matrix/ ← interventions_raw.csv (acumulativo)
├── deputies/ ← deputies.csv
├── match/ ← matching_table.csv
├── merge/ ← interventions_enriched.csv
└── standardize/ ← {ISO2}_interventions.csv (canónico ⚠)
+ {ISO2}_deputies.csv (padrón publicable)
docs/{iso2}/
├── README.md ← documentación principal del corpus
├── data_dictionary.md ← diccionario de variables
├── dataset.jsonld ← metadatos Schema.org (CC BY 4.0)
├── corpus_info.json ← respuestas del procesador (reutilizable)
└── pipeline_report.md ← informe interno del proceso (/diaries-report)
El directorio docs/{iso2}/ es independiente de source/{iso2}/: la documentación de cada corpus nacional es un activo propio, separado de los datos de trabajo.
Lo que hace install.sh
pip
~/.claude/skills/ (no los copia: eso lo hace install_skills.sh)
state/, source/, country_config/, docs/