rag-service/docs/PENDIENTES_RAG.md

356 lines
35 KiB
Markdown

# Pendientes priorizados del RAG
**Ultima actualizacion:** 2026-09-25
**Responsable de la priorizacion:** Usuario
**Estado:** Activo
Este documento es la fuente canonica del orden de trabajo pendiente del modulo RAG. La numeracion ya refleja la prioridad final indicada por el usuario.
## Hoja de ruta OCR prioritaria
La prioridad actual es publicar y desplegar la correccion de rechazo/purga OCR, completar la limpieza sin alterar FacturaTech v1 y decidir despues si aporta valor una nueva ingesta del PDF original. No aprobar, indexar ni activar contenido de prueba.
### Fase 1. Corregir y verificar el codigo
**Estado:** Completada funcionalmente y verificada en produccion el 2026-09-17.
1. Completado: errores OCR estructurados, seguros y accionables.
2. Completado: recuperacion administrativa autenticada y auditada para candidatas con evidencia invalida.
3. Completado: RAG y OCR exponen versiones; los digests identifican las imagenes desplegadas.
4. Completado: errores, recuperacion, reinicios y versiones cubiertos localmente y verificados en produccion sin modificar v4.
**Salida:** el comportamiento nuevo esta validado y v4 permanece intacta. La etiqueta OCI de revision legible sigue como mejora operativa no bloqueante: actualmente el digest es la identidad verificable de la imagen.
### Fase 2. Resolver la candidata v4
**Estado:** Completada en produccion el 2026-09-20, con aprobacion explicita del usuario.
1. Completado: v4 respondio `409 OCR_ARTIFACT_UNAVAILABLE` y accion `use_admin_recovery` mediante el contrato autenticado.
2. Completado: confirmada la ausencia de la evidencia durable necesaria para su revision.
3. Completado: recuperacion administrativa auditada aplicada sobre la unica candidata heredada.
4. Completado: v4 quedo en estado `failed`, no activa, sin indexacion ni activacion; la fuente conserva su version activa.
5. Completado: no quedan candidatas `pending`, `indexing` ni `review_required` que bloqueen la fuente.
**Salida:** v4 queda resuelta de forma auditable como `failed`, sin crear otra candidata.
### Fase 3. Hardening OCR y aceptacion de FacturaTech
**Estado:** `0.2.1` revision `bfb2d48` desplegada y verificada conjuntamente en produccion. v8 completo la aceptacion no activa, pero fue rechazada por decision del usuario sin aprobarse, indexarse ni activarse; FacturaTech v1 sigue activa.
La candidata v5 `5f2317c6-7a8a-4e08-a614-f8189602ebb8` completo 25/25 paginas OCR, pero fallo despues cuando RAG solicito 25 imagenes de revision en paralelo. El rerender concurrente provoco un `SIGSEGV` de PDFium/FreeType, salida `139` y reinicio del contenedor; no hubo OOM. La candidata quedo fallida y la version activa no cambio.
#### Fase 3A. Hardening del runtime
1. Completado localmente: cola SQLite durable con un unico worker real y recuperacion tras reinicio.
2. Completado localmente: PNG privados durante el render inicial y servicio desde fichero sin volver a ejecutar PDFium.
3. Completado localmente: transferencia RAG secuencial, idempotente y reanudable mediante comprobantes privados por pagina.
4. Completado localmente: exclusion mutua defensiva de PDFium y cierre determinista de recursos.
5. Completado localmente: observabilidad segura, limites de cola/tiempo/disco, recuperacion por lease, sweeper periodico y vacuum incremental.
6. Completado: validacion independiente con PDF real de 25 paginas, reinicio durante el trabajo, concurrencia, reanudacion, ausencia de duplicados y limpieza cuantitativa.
#### Fase 3B. Aceptacion productiva
**Estado:** Ejecutada y no superada. v6 fallo por colision idempotente con un trabajo terminal `ocr-v1`. Tras la limpieza automatica, v7 proceso 25/25 paginas y persistio 25 PNG validos, pero un falso negativo de `p10Confidence` la cerro como `OCR_QUALITY_BLOCKED`. Las 34 entradas estan presentes; `FAT07`, `NSAV06` y `DSAU04` requieren correccion humana por confusion `0/o`. La version activa no cambio.
1. Completado: desplegados juntos OCR y RAG `0.2.0` con revision verificable.
2. Completado: candidatas v6 y v7 creadas con `activate=false`; ninguna fue indexada ni activada.
3. Completado: evidencia durable de v7, 25 imagenes y 34 entradas verificadas.
4. No superado: la puerta de calidad impidio llegar a revision y dos de los cuatro codigos criticos no son exactos antes de correccion humana.
5. Completado: version activa anterior confirmada intacta.
#### Fase 3C. Correccion post-aceptacion `0.2.1`
**Estado:** R1-R5 completados. `0.2.1` se centralizo en `VERSION`, supero la validacion local y se desplego conjuntamente en produccion con revision y digests verificables. La migracion `004`, health, cola, almacenamiento, PostgreSQL, Qdrant y reconciliador quedaron sanos. v8 completo la aceptacion no activa y fue rechazada posteriormente sin aplicar correcciones, indexar ni activar. Contrato completo en `CONTRATO_CICLO_VIDA_Y_OCR.md`, anexo "Hallazgos productivos v6-v7".
1. Completado localmente: R1, identidad `ocr-v2` completa, acknowledgement de los cuatro estados, recuperacion posterior a `succeeded` sin reenviar OCR y rechazo fail-closed de respuestas incompatibles.
2. Completado localmente: R2, `p10Confidence` bajo aislado como advertencia, bloqueos reales preservados y diagnostico determinista por pagina.
3. Completado localmente: R3, migracion `004` preparada sin aplicar, cadena de hashes durable, `quality-report.json` privado e inmutable y diagnostico seguro.
4. Completado localmente: R4, suites, revision independiente, fixture autocontenido de 25 paginas, simulaciones de recuperacion tras cada frontera de persistencia y hardening de errores administrativos. `004` se aplico mediante el runner en PostgreSQL Docker local aislado despues de controlar `001-003`; se verificaron la fila historica, columnas, restriccion, historial `001-004` e idempotencia. El contenedor reutilizable queda detenido; nunca se uso EasyPanel ni produccion.
5. Completado: R5 consumio `0.2.1` desde un unico `VERSION`, valido health y etiquetas OCI, desplego y probo RAG/OCR como una unica operacion y completo la aceptacion no activa con revision visual independiente del agente.
#### Checklist ejecutable de R5
R5 completo la revision no activa. La decision posterior fue rechazar y purgar v8, no aprobarla ni activarla.
- [x] Crear `VERSION` en la raiz con `0.2.1` y convertirlo en la unica fuente de version para RAG, OCR, health, pruebas y builds; cualquier version duplicada o divergente debe fallar.
- [x] Ejecutar la validacion local completa de RAG, OCR e imagenes y actualizar la documentacion afectada.
- [x] Revisar el worktree, crear un unico commit de entrega y hacer push a `main`; RAG y OCR se publicaron desde `0654ce5` y el registro documental se completo en `ec0d233`.
- [x] Antes del despliegue, identificar explicitamente la base y el entorno productivos, revisar `rag_schema_migrations` y confirmar que solo estan pendientes las migraciones esperadas. Preflight de solo lectura en VPS2 (2026-09-23): RAG usa `db_rag` con el rol `usr_rag`; `001-003` estan aplicadas con checksums coincidentes y solo queda `004_ocr_quality_diagnostics.sql`.
- [x] Configurar en ambos servicios `BUILD_REVISION=<commit publicado>` y mantener `OCR_INGEST_ENABLED=true`. Ambos servicios se construyeron con `BUILD_REVISION=0654ce5` y RAG conserva OCR habilitado.
- [x] Desplegar RAG y OCR desde el mismo commit como una unica operacion en EasyPanel; ambos servicios quedaron en ejecucion el 2026-09-23 con `BUILD_REVISION=0654ce5` y OCR habilitado.
- [x] Verificar conjuntamente `version=0.2.1`, revision, etiquetas OCI, digests, migracion `004`, health, cola OCR, almacenamiento, PostgreSQL, Qdrant y reconciliador. RAG: `sha256:9a22730406c09c6b773891d8953f451e6263bf9fb0033188f4479f0b93ec8bbf`; OCR: `sha256:6725991d3893a4f16ae6c75f28e9dd59b051bdbc344b28d79f1292224ddceda1`. Ambos exponen `0.2.1` y `0654ce5`; `004` esta aplicada, OCR esta `live/ready`, cola vacia y almacenamiento disponible.
- [x] Confirmar el estado auditado de v7 sin aprobarla, indexarla ni activarla. v7 `c9756e59-f91d-4b57-8f31-e7b5b2b09558` sigue `failed` por `OCR_QUALITY_BLOCKED`, conserva artefactos y la version activa anterior `3fc78163-9cfb-4979-985c-1520a63327b0` permanece intacta.
- [x] Crear una candidata nueva de FacturaTech con `activate=false` y supervisarla hasta `review_required` o fallo. v8 `f4fd1502-1d4d-454f-bbfb-4c3b6820ee97` alcanzo `review_required` sin activacion: 25/25 paginas OCR, 25 imagenes verificadas, 22 paginas aceptadas, tres advertencias `LOW_P10_CONFIDENCE` (2, 20 y 21) y cero bloqueos.
- [x] Ejecutar y reauditar la revision visual independiente definida en el contrato: v8 se revalido antes y despues, se descargaron temporalmente 25 imagenes, un modelo visual las transcribio sin recibir primero el OCR productivo, y se compararon despues imagen/candidata/referencia. La auditoria con un modelo mas potente corrigio el veredicto inicial: resultado `READY_FOR_APPROVAL`, 34/34 entradas, cero duplicados, cero ausencias y cero casos sin resolver. `CBG04a` y `DSAU08` ya son exactos; deben proponerse `FATo7` -> `FAT07`, `NSAvo6` -> `NSAV06` y `DSAUo4` -> `DSAU04`. El recorte de la pagina 22 pertenece a la imagen fuente y la candidata conserva el contenido visible. No hubo cambios productivos.
- [x] Resolver el destino de v8: rechazada sin aprobar, indexar ni activar; su purga espera el despliegue de la correccion de claves foraneas.
#### Plan ejecutable
Antes de ejecutar este plan, leer `SISTEMA_RAG_BASE.md`, esta seccion y el bloque `Revision de FacturaTech` de `CONTRATO_CICLO_VIDA_Y_OCR.md`. No desplegar, aprobar, indexar ni activar sin la autorizacion correspondiente.
##### A. Diagnostico de las confusiones `o/0` - completado
Este diagnostico se completo sin modificar codigo, configuracion, modelos, preprocesado, reconstruccion ni postproceso.
1. [x] Revalidar las referencias exactas: `FAT07` en pagina 8, `NSAV06` en pagina 15 y `DSAU04` en pagina 16; mantener separadas estas confusiones de precision de las advertencias `LOW_P10_CONFIDENCE` de las paginas 2, 20 y 21.
2. [x] Inventariar la evidencia durable ya existente para las paginas 8, 15 y 16: imagenes, resultado OCR, lineas, bounding boxes, confianzas, manifiestos, hashes, candidata y configuracion efectiva.
3. [x] Mapear el recorrido exacto del dato entre PDF, render a 200 DPI, entrada del reconocedor, adaptador de PaddleOCR, respuesta API, artefacto durable de RAG, reconstruccion de lineas y candidata.
4. [x] Construir una linea base por pagina e identificar la primera frontera observable de cada diferencia.
5. [x] Confirmar que los artefactos productivos existentes bastan para localizar la causa.
6. [x] Descartar la repeticion focalizada: no fue necesaria porque la evidencia durable resulto suficiente.
7. [x] Comparar imagen, respuesta OCR, artefactos RAG y candidata y clasificar la causa.
8. [x] Registrar confianzas, limites de reproducibilidad y efectos sobre el quality gate.
9. [x] Redactar el informe de diagnostico.
10. [x] Presentar el informe y obtener la aceptacion del usuario.
**Resultado:** los PNG verificados muestran `FAT07`, `NSAV06` y `DSAU04`; `ocr-result.json` ya contiene `FATo7`, `NSAvo6` y `DSAUo4`, con confianzas de linea `0.9775`, `0.9903` y `0.9808`. `candidate-pages.json` conserva exactamente esos valores. La primera frontera observable es imagen correcta -> reconocimiento PaddleOCR incorrecto. RAG, la reconstruccion y la composicion no sustituyen caracteres.
**Decision de aceptacion:** para la fase actual se acepta el OCR como servicio best-effort autonomo. Estos errores semanticos puntuales de alta confianza son una limitacion conocida, no un bloqueo tecnico. La ingesta sera orquestada por un agente y no dependera de una GUI ni de una persona corrigiendo cada documento. Esto no convierte el texto OCR en exacto ni elimina las correcciones y autorizaciones requeridas para una candidata concreta.
##### B. Mejora futura de precision OCR - no bloqueante
Este bloque queda diferido. No forma parte del cierre operativo actual y solo se reabrira con una decision explicita.
- [ ] Comparar sobre la linea base alternativas acotadas y generales, por ejemplo resolucion o preprocesado de imagen, configuracion del reconocedor o tratamiento de caracteres ambiguos respaldado por confianza y evidencia visual.
- [ ] Elegir la intervencion minima que actue en la etapa donde se demostro la causa. Documentar por que se descartan las demas alternativas y su impacto esperado en tiempo, memoria y compatibilidad.
- [ ] Implementar la mejora sin reglas especificas para FacturaTech ni sustituciones silenciosas como cambiar toda `o` por `0`.
- [ ] Conservar identidad, hashes, orden de lineas, bounding boxes, metricas, idempotencia y contrato `ocr-v2`; si la configuracion efectiva cambia semanticamente, versionarla y no reutilizar trabajos incompatibles.
- [ ] Mantener separadas la mejora general del OCR y las correcciones exactas que requeriria una futura candidata. La implementacion no reabre ni modifica v8, que fue rechazada.
##### C. Validacion futura de mejoras de precision - no bloqueante
Este bloque se ejecutara solo si se implementa el bloque B.
- [ ] Crear fixtures no sensibles que reproduzcan caracteres ambiguos en codigos y texto normal, con casos donde `o`, `O`, `0`, `u` y `U` sean correctos y deban conservarse.
- [ ] Ejecutar pruebas unitarias y de integracion sobre renderizado, reconocimiento, reconstruccion y resultado API segun la etapa modificada.
- [ ] Repetir, con autorizacion y fuera del repositorio, el OCR real exclusivamente para las paginas `[8, 15, 16]`; exigir `FAT07`, `NSAV06` y `DSAU04` exactos y confirmar que no se degradan el resto de sus lineas, posiciones ni metricas relevantes.
- [ ] Comparar antes y despues con evidencia estructurada. La mejora no pasa si solo corrige los tres tokens mediante una regla particular, introduce falsos cambios `o/0` o `u/U`, pierde contenido o rompe identidades y hashes.
- [ ] Medir tiempo y memoria de las tres paginas y ejecutar la suite Python completa. Si la alternativa aumenta materialmente el coste, justificarlo antes de integrarla.
##### D. Seguimiento rapido RAG -> OCR - siguiente bloque
- [x] Disenar un scheduler durable en RAG que use `next_attempt_at` como reloj de los trabajos OCR pendientes y mantenga un unico temporizador para el vencimiento mas cercano.
- [x] Al despertar, reclamar trabajos vencidos mediante PostgreSQL y `FOR UPDATE SKIP LOCKED`, consultar el estado remoto y reprogramar solo `queued` o `running` con backoff de 2 a 15 segundos.
- [x] Finalizar y dejar de seguir inmediatamente los trabajos `succeeded` o `failed`; conservar la transferencia durable, validacion de identidad y composicion existentes.
- [x] Reconstruir el scheduler al arrancar RAG y mantener `dispatchAvailable()` idempotente ante llamadas simultaneas.
- [x] Mantener el reconciliador de cinco minutos como red de seguridad global; no convertirlo en el mecanismo normal de latencia ni detenerlo cuando termine un trabajo.
- [x] Eliminar `pollUntilTerminal()` y su prueba especifica: el scheduler no usa un bucle en memoria sin limite, persistencia ni renovacion de lease. El dispatcher conserva las consultas discretas y persiste el backoff mediante `next_attempt_at`.
- [x] Retirar `OCR_PAGE_TIMEOUT_MS` y `OCR_TOTAL_TIMEOUT_MS`: eran configuracion no consumida y no representaban garantias reales del runtime RAG.
##### E. Validacion local conjunta
- [x] Probar que un trabajo que termina antes de cinco minutos se recupera en el siguiente intervalo corto sin esperar al reconciliador.
- [x] Probar secuencias `queued -> running -> succeeded` y `queued -> failed`, y que no quedan temporizadores activos para trabajos terminales.
- [x] Probar reinicio de RAG entre consultas: `next_attempt_at`, `remoteJobId` e idempotency key permiten continuar sin repetir PaddleOCR.
- [x] Probar dos dispatchers concurrentes y confirmar que `SKIP LOCKED`, leases y `activeDrain` evitan doble procesamiento.
- [x] Probar caida durante resultado, imagenes, informe y candidata; el reconciliador de cinco minutos sigue recuperando exactamente una vez.
- [x] Ejecutar una ingesta local end-to-end con un PDF controlado que combine paginas nativas y paginas OCR. La ejecucion fresca `94f1af75-b6b0-4fb1-8a93-f0f5c0c5f0a0` alcanzo `review_required` en 7 segundos: pagina 1 nativa, pagina 2 OCR, `2/2`, quality report y candidata durables, revision autenticada e imagen protegida correctas, `activateRequested=false` y cola OCR vacia. La prueba descubrio y corrigio el doble conteo de paginas OCR clasificadas como blank y la exigencia incorrecta de imagen OCR para paginas nativas.
- [x] Ejecutar suites Node/Python, regresiones focalizadas, chequeos de tipos, build de RAG y OCR, health de contenedores, validacion de imagenes y `git diff --check` antes de publicar.
Validacion completada: suite Node `121/121`, suite OCR `26/26`, regresiones del scheduler y reconciliador, `npm run check`, build RAG, PostgreSQL local con cuatro migraciones, builds finales de ambas imagenes `0.2.1`, health OCR con modelo, worker, sweeper y almacenamiento preparados, imagen de revision correcta y `git diff --check` superado. La revision final corrigio el `documentId` de las correcciones del playground, la nulabilidad OpenAPI 3.1 y las incoherencias de contrato y rollback. No existe Qdrant local: Qdrant y el health RAG completo se verifican exclusivamente en el gate productivo posterior al despliegue autorizado.
##### F. Publicacion y despliegue conjunto
- [x] Preparar una unidad versionada para el scheduler durable y la operacion autonoma, revisar el diff y registrar codigo, pruebas, contrato, operativa y rollback.
- [x] Solicitar y recibir autorizacion para commit/push. El despliegue conserva una autorizacion explicita posterior y separada.
- [x] Publicar y desplegar RAG/OCR juntos segun la regla operativa vigente, con OCR habilitado y version, revision y etiquetas coincidentes. La revision `bfb2d48` quedo desplegada el 2026-09-24.
- [x] Verificar migraciones esperadas, health, scheduler rapido, reconciliador de cinco minutos, cola OCR, almacenamiento, PostgreSQL y Qdrant. La validacion productiva conjunta paso y la version activa permanecio intacta.
##### G. Validacion productiva sin activar contenido
- [x] Ejecutar una ingesta productiva controlada y no activa para validar el circuito RAG -> OCR -> RAG, incluyendo que el scheduler recupera el resultado en el intervalo corto sin esperar cinco minutos. La candidata sintetica valida `c4646668-30e4-409e-800d-23a8ee465a42` alcanzo `review_required` en menos de 18 segundos y el trabajo OCR termino en unos 6 segundos.
- [x] Verificar seleccion de paginas, composicion, informe de calidad, candidata revisable, ausencia de activacion y continuidad del reconciliador como fallback. Pagina 1 `native`, pagina 2 `ocr`, `requested_pages={2}`, `next_attempt_at=NULL`, cola vacia y `activateRequested=false`.
- [x] Confirmar que cualquier error semantico residual conserva imagen, texto, lineas, bounding boxes, confianzas, hashes y trazabilidad suficientes para revision posterior; no exigir exactitud textual total al OCR best-effort. La pagina OCR conservo 14 lineas, 333 caracteres no blancos, bounding boxes, confianzas, hashes y PNG durable `1654x2339`.
- [x] Registrar IDs, estados, tiempos, hashes, versiones, revisiones y digests sin incorporar contenido del cliente al repositorio. La evidencia completa esta en `docs/HISTORIAL_SESIONES.md`; solo se uso contenido sintetico.
##### H. Limpieza de candidatas OCR y FacturaTech
- [x] Confirmar que FacturaTech v1 `3fc78163-9cfb-4979-985c-1520a63327b0` sigue activa e intacta, purgar v2 y rechazar v8 sin indexarla ni activarla.
- [x] Corregir la comparacion de `ocr_text_hash` para que las paginas `blank` con texto OCR vacio puedan aprobarse o rechazarse sin falso `REVIEW_CONFLICT`.
- [x] Corregir la purga de versiones OCR para eliminar de forma transaccional las filas hijas de `rag_review_corrections`, `rag_document_pages` y `rag_ocr_jobs` antes de `rag_version_documents`, respetando las claves foraneas y la reanudacion desde `purging`.
- [x] Eliminar idempotentemente los artefactos duraderos de la version antes de completar `purging -> purged`, evitando directorios huerfanos marcados como `retention_deleted`.
- [x] Anadir pruebas de regresion para ambos defectos y ejecutar la bateria local completa. Las regresiones finales `47/47`, Node `124/124`, OCR `26/26`, typecheck, build y builds Docker RAG/OCR pasan.
- [ ] Publicar la correccion autorizada mediante commit/push y desplegar conjuntamente RAG/OCR con la nueva `BUILD_REVISION`.
- [ ] Tras el despliegue por el usuario, rechazar y purgar la candidata sintetica blank `6011a4eb-3e42-4ea4-a7da-a3e930cc60ed`, completar la purga de la sintetica valida `c4646668-30e4-409e-800d-23a8ee465a42` y purgar FacturaTech v3-v8.
- [ ] Verificar al terminar que no quedan candidatas OCR de prueba utiles o bloqueadas y que FacturaTech v1 conserva el puntero activo.
- [ ] Decidir por separado, solo si aporta valor, si se realiza una nueva ingesta del PDF original de FacturaTech con el sistema ya validado.
**Paquete posterior no bloqueante:** implementar recuperacion automatica si la purga se interrumpe despues de eliminar artefactos y antes del CAS `purging -> purged`, y alinear el contrato historico de retencion con el comportamiento real. La operacion actual es recuperable repitiendo `DELETE`; este paquete no requiere ampliar ahora la bateria de pruebas ni bloquea la publicacion.
##### I. Criterio de servicio completamente operativo
- [ ] Confirmar en produccion que el PDF controlado hibrido no envia las paginas nativas, envia solo las visuales y compone un documento unico sin duplicar texto dentro de una pagina.
- [ ] Confirmar que las limitaciones de precision conocidas quedan trazables, el scheduler corto funciona tras reinicio, los leases evitan dobles procesamientos y el reconciliador recupera fallos residuales.
- [ ] Confirmar health, observabilidad, almacenamiento, cola, PostgreSQL, Qdrant, revision no activa y rollback documentado sin incidencias abiertas de severidad bloqueante.
- [ ] Declarar cerrado el trabajo tecnico solo cuando toda la evidencia anterior este registrada. Este cierre significa que el servicio RAG-OCR esta funcionando completamente y que las candidatas descartadas quedaron limpias; no implica una nueva ingesta de FacturaTech.
Las advertencias `LOW_P10_CONFIDENCE` de las paginas 2, 20 y 21 no son un defecto de comunicacion ni un bloqueo pendiente de codigo. Son senales de revision. Las confusiones puntuales `o/0` de las paginas 8, 15 y 16 son una limitacion aceptada del reconocimiento best-effort y, si aparece una futura candidata, deben corregirse explicitamente durante su revision, nunca mediante una autocorreccion silenciosa. Una futura consola podra incorporar revision humana y un revisor visual por IA podra proponer correcciones con imagen y contexto; ambos quedan fuera de esta fase.
Si aparece un fallo real cuyos sintomas justifiquen aislar servicios, valorar entonces `OCR_INGEST_ENABLED=false` y el despliegue por etapas. No aplicar ese modo preventivamente.
**Regla de despliegue:** R1-R4 no despliegan ni prueban produccion. Solo R5 puede desplegar; RAG y OCR se despliegan juntos con `OCR_INGEST_ENABLED=true` y la entrega no se considera completada hasta que ambos coincidan en version/revision y superen juntos la bateria de salud. No se desactiva OCR ni se despliega por etapas de forma preventiva: ese modo queda reservado para un fallo real cuyos sintomas justifiquen aislar un servicio. `BUILD_REVISION` sigue manual para esta entrega y se contrasta con el commit; los digests son la identidad exacta. No se introduce CI, registry ni automatizacion de EasyPanel sin aprobacion separada.
**Regla PostgreSQL de R4:** no usar la base configurada en EasyPanel ni cargar los ficheros locales que contienen sus secretos. Usar un contenedor local aislado y reutilizable, pasar una URL local solo al proceso de prueba y comprobar la secuencia de migraciones. El contenedor conserva su volumen para futuras pruebas, no tiene reinicio automatico y debe quedar detenido al terminar para que PostgreSQL no consuma CPU ni RAM activa. No apagar ni limpiar Docker globalmente. El runner aplica todas las migraciones pendientes. La aplicacion de `004` en produccion pertenece a R5 y necesita autorizacion explicita independiente.
**Evidencia:** las pruebas automatizadas deben ser autocontenidas. La comparacion con el documento manual de FacturaTech es evidencia externa producida por el agente mediante un modelo visual independiente y se registra separada del PASS automatizado. R5 debe dejar IDs, estados, recuentos, hashes, versiones, revisiones y digests suficientes para auditar la aceptacion sin depender de memoria conversacional.
El SDD `ocr-ingest-integration` se archiva con 29/30 tareas completas y 7.4 incompleta. La continuidad del hardening y de la aceptacion se controla mediante el contrato ODD canónico, sin declarar retrospectivamente superada la aceptacion fallida.
**Salida anterior:** `0.2.1` supero los criterios del anexo y FacturaTech alcanzo `review_required` con evidencia completa. v8 fue rechazada posteriormente por decision del usuario; el bloque A-I solo se cierra al desplegar la correccion de limpieza, purgar las candidatas descartadas y verificar que v1 sigue activa.
## 1. Documentacion y descubrimiento de la API
**Estado:** Completado y validado definitivamente en produccion el 2026-09-08.
- Implementar `/help` o una especificacion OpenAPI consultable.
- Actualizar documentos desfasados que todavia muestran como pendientes funciones ya desplegadas, como playground, logs y cleanup.
- Documentar los contratos, parametros, respuestas y errores reales de todos los endpoints.
- Mantener la documentacion alineada con produccion para que agentes e integradores no tengan que reconstruir el comportamiento desde el codigo.
## 2. Ciclo de vida del conocimiento
**Estado:** Completado y validado en produccion el 2026-09-13.
El contrato de implementacion esta cerrado en [`CONTRATO_CICLO_VIDA_Y_OCR.md`](./CONTRATO_CICLO_VIDA_Y_OCR.md). Antes de ejecutar las pruebas de migracion o activar el ciclo de vida hay que completar este prerrequisito:
### Prerrequisito bloqueante: preparar PostgreSQL
- Confirmar que existe la instancia y la base de datos que usara RAG en EasyPanel.
- Obtener el hostname interno, puerto, nombre de base de datos, usuario y requisitos SSL.
- Configurar `POSTGRES_URL`, `POSTGRES_SSL` y `LIFECYCLE_ADMIN_TOKEN` en el servicio RAG.
- Ejecutar las migraciones del esquema y verificar las tablas, permisos y `SELECT 1` desde RAG. Completado el 2026-09-13.
- Revisar que no falten variables, red interna, credenciales, almacenamiento persistente o permisos de migracion. Completado el 2026-09-13; la configuracion completa de backups queda diferida al paquete del punto 7.
- Inventariar las fuentes actuales de Qdrant y preparar su carga en el catalogo PostgreSQL.
### Resultado del dry-run legacy
- Ejecutado el 2026-09-13 sin `--apply`.
- Detectados 22.605 puntos en 7 fuentes de `rag_chunks`.
- `ok: true`; no se encontraron `blockedReasons`.
- Ventana de mantenimiento ejecutada con `INGEST_WRITES_ENABLED=false` y `rag_system_state.maintenance=true`.
- Migracion aplicada con el lote `17f05cae-c5a7-49a5-b3ad-729958e1a342` usando snapshot Qdrant remoto con checksum `a55b13d3b6b791e9b148f87491b9b2788ce5797ee997a9f6be2a6d424eb92302`.
- Catalogadas 7 fuentes y 22.605 puntos; todas las versiones quedaron `active` y sus recuentos PostgreSQL/Qdrant coinciden.
- `KNOWLEDGE_LIFECYCLE_ENFORCED=true`, `INGEST_WRITES_ENABLED=true`, `maintenance=false` y retrieval validado en produccion.
El punto 2 queda cerrado. El punto 3, OCR integrado en la ingesta, puede comenzar respetando el contrato secuencial.
- Crear un catalogo de fuentes y versiones ingeridas.
- Saber que documento esta vigente, obsoleto, reemplazado o pendiente de reingesta.
- Evitar duplicados y permitir actualizaciones incrementales controladas.
- Registrar fecha de indexacion, modelo de embeddings, proveedor y version del contenido.
- Facilitar el reemplazo o rollback de una fuente sin depender de operaciones manuales dificiles de auditar.
### Paquete de mejora posterior: seguimiento del corpus en API y frontend
**Prioridad:** Diferida, sin urgencia; no bloquea la preparacion de PostgreSQL ni el cierre funcional del punto 2. Retomar al trabajar en el frontend de gestion.
- Exponer por API los documentos que componen cada version de una fuente.
- Exponer el historial de intentos de ingesta, resultados y errores.
- Incluir fechas y detalles de error de las versiones en las respuestas de la API.
- Ampliar la vista basica del playground a una gestion de fuentes, documentos, versiones e ingestas con su estado e historial.
- Incorporar al frontend las operaciones ya disponibles por API: activacion, rollback, reintento y purga.
## 3. OCR integrado en la ingesta
**Diseño:** Contrato de implementacion cerrado en [`CONTRATO_CICLO_VIDA_Y_OCR.md`](./CONTRATO_CICLO_VIDA_Y_OCR.md). El punto 2 ya fue validado en produccion; su ejecucion queda habilitada.
- Detectar PDFs con capturas, imagenes o una capa textual insuficiente.
- Ejecutar OCR automaticamente o bloquear la ingesta para revision cuando no pueda garantizarse la cobertura.
- Generar un documento intermedio auditable cuando sea necesario.
- Verificar el resultado antes de sustituir una fuente vigente.
- Evitar que se repita el problema detectado con el PDF de FacturaTech.
### Paquete de mejora posterior: OCR reutilizable para entradas visuales
**Prioridad:** Diferida; no bloquea la correccion actual ni la aceptacion de FacturaTech.
- Mantener el contrato actual de trabajos PDF.
- Aceptar directamente `image/jpeg` y `image/png`, ademas de PDF.
- Normalizar cada entrada visual a un resultado por pagina con texto, lineas, posiciones y metricas.
- Emitir resultados OCR o errores estructurados sin depender del RAG.
- Mantener RAG como consumidor opcional del OCR y responsable de versionado, revision e indexacion de conocimiento.
- Definir limites de tamano, dimensiones y paginas, autenticacion, retencion y pruebas para cada formato.
## 4. Mejora del retrieval
- Anadir busqueda hibrida semantica y textual para codigos exactos como `FAT07`, `504` o `SQLSTATE[23505]`.
- Mejorar el ranking usando coincidencias de codigo, regla, modulo y mensaje, no solo proximidad semantica.
- Crear un conjunto estable de consultas de evaluacion basado en casos reales.
- Medir precision, resultados irrelevantes y consultas ambiguas.
- Refinar retrieval y chunking con evidencia de uso, no mediante cambios generales sin medicion.
## 5. Seguridad de la API
- Anadir autenticacion para consumidores autorizados.
- Proteger especialmente uploads, cleanup y operaciones sobre logs.
- Aplicar rate limiting y limites de tamano o tipo de archivo.
- Revisar CORS, exposicion publica, registros sensibles y permisos por operacion.
- Sustituir la configuracion sin credenciales de n8n cuando exista el mecanismo de autenticacion definitivo.
- Actualizar Express/`qs` para cerrar los avisos moderados pendientes de `npm audit`.
## 6. Pruebas automatizadas
- Incorporar un framework y scripts de pruebas; actualmente el proyecto no tiene suite automatizada.
- Cubrir ingesta, parsing, chunking, scopes, cleanup y retrieval.
- Probar contratos y respuestas de error de la API.
- Anadir pruebas de regresion con consultas reales como las validadas para FacturaTech.
- Separar pruebas unitarias, de integracion y verificaciones opcionales contra servicios remotos.
## 7. Operacion y mantenimiento
- Resolver la colision de `sourceRef` al ingerir carpetas homonimas.
- Separar claramente configuracion versionable y secretos locales.
- Verificar y cerrar documentalmente la migracion del repositorio raiz de RAG y su despliegue en EasyPanel.
- Revisar copias temporales o backups asociados a la migracion antes de eliminarlos.
- Mantener un procedimiento fiable de despliegue, verificacion y rollback.
### Paquete de mejora posterior: backups manuales del RAG
**Prioridad:** Diferida, sin urgencia; no bloquea la preparacion actual de PostgreSQL. Sin programacion automatica.
**Estado de la propuesta:** Diseno guardado para completar e implementar mas adelante.
- Configurar el destino de backups y diagnosticar el error observado al crearlo en EasyPanel.
- Preparar copias manuales de la nueva base del RAG y snapshots de Qdrant; `db_gestion_flujos_n8n` es ajena a este alcance.
- Definir una ventana sin escrituras para obtener copias coherentes de ambos almacenes.
- Documentar y comprobar la restauracion, incluyendo la recuperacion de los permisos necesarios.
- Este paquete difiere la solucion habitual de backups; el snapshot previo exigido por la migracion legacy sigue formando parte de esa operacion.
#### Diseno propuesto
- Mantener los datos primarios separados: PostgreSQL conserva el catalogo, Qdrant conserva chunks y embeddings, y un volumen privado del RAG conserva originales y artefactos.
- Montar un volumen `rag-ingestions` en `/data/ingestions` para conservar originales, manifiestos y futuros artefactos OCR por version.
- Cambiar la ingesta para guardar el original antes de procesarlo; el flujo actual usa `/tmp` y elimina los uploads al terminar.
- Respaldar PostgreSQL con un dump portable de `db_rag` y, cuando quede configurado, con Database Backups de EasyPanel hacia un destino S3-compatible.
- Respaldar Qdrant con snapshot de la coleccion o del almacenamiento completo, preferentemente hacia el mismo destino externo.
- Incluir los artefactos del volumen en el plan de backup y probar una restauracion completa antes de considerar portable el servicio.
- No tratar un volumen Docker del mismo VPS como backup externo: protege frente a reinicios, no frente a perdida del servidor.
- Mantener fuera de este alcance `db_gestion_flujos_n8n`.
## 8. Sistema de evaluacion
- Revisar periodicamente los logs de evaluacion almacenados en Qdrant.
- Convertir incidencias reales en casos de prueba permanentes.
- Anadir metricas de recuperacion, calidad y contexto insuficiente.
- Mantener trazabilidad entre una incidencia, el cambio aplicado y la validacion posterior.
- Diferenciar claramente observacion manual, alerta automatica y regresion confirmada.
## 9. Capa MCP
- Exponer capacidades del RAG como tools MCP reutilizables.
- Definir inicialmente retrieval y consulta de fuentes; limitar operaciones destructivas.
- Mantener HTTP como API base y MCP como adaptador, evitando duplicar la logica del servicio.
- Definir autenticacion, contratos y permisos antes de exponer operaciones adicionales.
## 10. Modelo de `answer`
- Evaluar y sustituir `openai/gpt-4.1-mini` por el modelo definitivo de respuesta.
- Comparar calidad, coste, latencia y dependencia del proveedor.
- Mantener `answer` construido sobre `retrieve` y evitar un segundo camino de recuperacion.
- Considerar esta tarea despues de las anteriores; integraciones como WhatsApp ya pueden usar `/retrieve` y dejar la respuesta final a su propio agente.
## Regla de mantenimiento
- No cambiar este orden sin confirmacion del usuario.
- Al completar un punto, registrar evidencia y marcar su estado sin renumerar silenciosamente los demas.
- Las tareas detalladas pueden vivir en documentos independientes, pero este archivo conserva la prioridad global del modulo.