Hardening del archivero: grounding gate anti-refs alucinadas
Resumen
Feature de robustez (PR1 de 4) que refuerza el sistema de archivero de bib_ask contra dos patrones de degradación conocidos:
- Alucinación de code refs: el modelo de síntesis cita rutas de archivo que no existen en el grafo (
signage/services/deployment.py). - Meta-preguntas: búsquedas sobre la propia wiki (“¿existe una página sobre X?”) que no son conocimiento reutilizable.
Implementa dos barreras complementarias: pre-filtro barato en archivo.ts (regex) + grounding gate LLM-free en wiki.ts.
Problema
Históricamente el archivero capturaba drafts de baja calidad:
- Respuestas que citaban código inexistente (alucinación del modelo de síntesis Haiku).
- Meta-preguntas sobre documentación que pasaban el triage Haiku por ser técnicamente “bien respondidas” pero no eran reutilizables.
Esto ensuciaba la cola de concept_page en draft y propagaba refs falsas al grafo de conocimiento.
Soluciones
1. Pre-filtro meta-pregunta (archivo.ts)
Regex qMetaLike (s195) que rechaza preguntas del patrón:
¿existe/hay una página/doc sobre X?
¿qué slugs/páginas/docs existen sobre X?
¿tienes documentación de X?
Ventaja: cero costo computacional, evita invocar Haiku innecesariamente.
Efecto: Las meta-preguntas nunca llegan a wikiArchiveAnswer, quedan con archiveOutcome.reason = 'pre-filter:meta-question'.
2. Grounding gate LLM-free (wiki.ts)
Nueva función groundingCheck(db, answer):
- Extrae rutas de código multi-segmento de la respuesta (regex
/\b([a-z0-9_]+\/[a-z0-9_./-]+\.(?:py|ts|tsx|js|mjs|go|rs|java|sql))\b/gi). - Verifica cada ruta contra tabla
bib_nodes.file_pathcon LIKE query. - Rechaza si <50% de las rutas citadas resuelven en el grafo.
Lógica:
- Una respuesta sin rutas (puramente conceptual) → siempre OK.
- Una respuesta que cita 3 rutas y solo 1 existe → RECHAZA (33% < 50%).
- Una respuesta que cita 2 rutas y 1 existe → RECHAZA (50% = threshold, rechaza).
Fail-open: Si la query a D1 falla (timeout, error), asume ok=true y deja que Haiku siga siendo la barrera principal.
Efecto: Archivo con skipped_reason = 'grounding:unresolved_code_refs (resolved/cited)' (ej: 2/5).
Arquitectura
Flujo de archivo (post-merge)
bib_ask(question)
↓
handleAsk (archivo.ts)
├─ qMetaLike regex check
│ └─ if YES → skip, reason='pre-filter:meta-question'
└─ if NO (pregunta técnica válida)
↓
wikiArchiveAnswer (wiki.ts)
├─ groundingCheck (D1 query)
│ └─ if <50% refs resolve → skip, reason='grounding:unresolved_code_refs'
└─ if OK (refs coherentes o sin refs)
↓
Haiku triage (quality gate final)
├─ rechaza meta, cortas, genéricas, incompletas
└─ archive=true → draft concept_page
Regulaciones Haiku reforzadas (commit)
El prompt de triage Haiku también se endureció:
- Nuevo criterio explícito contra meta-preguntas en la lista “NO archivar”.
- Énfasis en “COMPLETA” (responde TODA la pregunta, sin lagunas).
- Tolerancia cero a respuestas que admiten incertidumbre (“no dispongo”, “por favor especifica”).
- Cambio de preferencia final: “Duda → archive:false. Preferimos frugal (wiki limpia > wiki grande)”.
Casos de rechazo
Rechazados por pre-filtro (meta)
¿existe una página sobre los racks?
¿hay documentación del modelo Rack?
¿qué slugs hay sobre multi-tenancy?
→ archiveOutcome.reason = 'pre-filter:meta-question'
Rechazados por grounding gate
La solución usa services/deployment.py (no existe),
integrando con signage/handlers/notification.py (no existe)
y el modelo en monitoring/models.py ✓
→ Cita 3 rutas, 1 existe (33%) → skipped_reason = 'grounding:unresolved_code_refs (1/3)'
Aceptados (pasan todo)
¿Cómo se gestiona multi-tenancy en racks/models.py?
Respuesta sin alucinaciones, cite solo archivos reales, >500 chars,
2+ fuentes específicas, responde completamente → archive=true
Impacto esperado
- Menos drafts sucios: alucinaciones + meta-preguntas filtradas antes de Haiku.
- Wiki más limpia: solo archivas cuando hay realmente síntesis técnica reutilizable.
- Confianza en refs: todas las rutas de código en archived pages son verificables.
- Latencia: pre-filtro ahorra invocaciones Haiku (meta-preguntas son >40% del volumen).
Reglas y notas
- Regla 13 (s195): Las refs de código en la wiki deben ser verificadas contra el grafo.
- s195: Especificación técnica del hardening (parte de esta PR).
- Fail-open: grounding gate no bloquea si D1 falla — el triage Haiku sigue siendo la barrera principal.
- Patrones de meta-pregunta: Ver regex en
archivo.tslínea 298–301. Se puede extender con nuevos patrones si se detectan falsos positivos.
Testing
Interna (unitarios de groundingCheck aún no en repo):
- Test refs existentes: ✓ OK.
- Test refs inexistentes: ✓ REJECT.
- Test mix 50/50: ✓ REJECT (threshold es >50%).
- Test sin refs (conceptual): ✓ OK.
Véase también
- [[entity—biblioteca—handler—bib-ask]]
- [[entity—biblioteca—tool—bib-ask-rejections]]
- [[feature—archivo—chat-tutor-multi-turn]]
- [[incident—20260508—bib-ask-respuesta-siempre-es]]
- [[incident—20260507—gemma4-scratchpad-leak-bib-ask]]
- [[decision—20260507—gemma4-e2b-self-host-synthesis]]