Saltar a contenido

DDR-007 — La relevancia en el tiempo se calcula, nunca se almacena

Versión: 0.1.0 | Fecha: 2026-09-24 | Estado: Aceptado

Contexto

La fase D de DDR-003 introdujo el decaimiento de la confianza. Hoy es un proceso por lotes, engrama decay, que solo se lanza desde el CLI y que reescribe los datos almacenados:

confidence ← confidence · exp(−rate · días_desde(updated_at))

El proceso reescribe confidence pero no toca updated_at, así que cada ejecución vuelve a aplicar todo el intervalo desde la última actualización real. El decaimiento se compone. Tras k ejecuciones diarias, un nodo sin tocar durante k días vale exp(−rate · k(k+1)/2) en lugar de exp(−rate · k). Con el valor por defecto rate = 0.01, un nodo sin tocar durante un mes cae a 0,0096 en vez de 0,74. Medido en un almacén SQLite, tres ejecuciones seguidas sobre un nodo de 10 días dan 0,905, 0,819 y 0,741, cuando el valor correcto es 0,905 todas las veces.

El resto del pipeline amplifica ese error:

  • Nada restablece la confianza. merge_node fija confidence solo ON CREATE, así que un nodo que se actualiza a menudo se queda en su valor decaído. Reflect regenera los mismos títulos de Insight, y esos Insights conservan su confianza decaída, así que un Insight "recién generado" puede marcar una confianza cercana a cero.
  • El archivado es ciego. Los nodos por debajo de --min-confidence se archivan sea cual sea su grado o su tipo, y al archivar se pone updated_at = now, así que el nodo archivado parece reciente para cualquier señal temporal. Los hubs bien conectados se archivan como cualquier otro nodo, y los nodos vivos cuyo único camino hacia el resto del grafo pasaba por ellos quedan aislados. Una vez archivado, el nodo desaparece de la búsqueda fulltext, pero la búsqueda de destinos de relaciones inline todavía puede enlazarlo.
  • El proceso no tiene scope. Recorre todos los tenants a la vez, y trata igual a los Insights, a los nodos Domain y a los hubs.
  • La importación pierde el historial. engrama import reproduce los nodos a través de merge_node, que descarta created_at y updated_at (#76). Un ciclo de exportación e importación data todos los nodos en el día de la importación, así que cualquier señal de recencia calculada después es errónea.

Una memoria de trabajo que abarca meses necesita la recencia para ordenar resultados, no para borrarlos.

Decisión

confidence significa creencia en el hecho. La fija quien escribe y solo cambia con una declaración explícita (supersesión mediante valid_to o una corrección). La recencia es una señal de ranking que se calcula al leer, a partir de la actividad. En almacenamiento no decae nada, y nada se archiva automáticamente.

En concreto

  1. last_activity_at. merge_node la fija en el nodo. merge_relation la fija en ambos extremos, así que un hub que sigue ganando aristas se mantiene reciente aunque sus propiedades no cambien. La primera vez que se usa, se rellena a partir de updated_at.
  2. Recencia al leer. temporal_score en core/search.py pasa a ser 2^(−edad / vida_media), con la edad medida desde last_activity_at. La vida media depende del tipo de nodo:
  3. nodos de dominio: 180 días;
  4. Insights de sistema (DDR-006, punto 7): 30 días;
  5. Domain y labels ancla: exentos (puntuación 1). Un factor de grado alarga la vida media de los hubs: vida_media · (1 + log2(1 + grado)). Todos los parámetros son configurables (ENGRAMA_RECENCY_*) y aparecen en engrama_status.
  6. engrama decay queda obsoleto. No cambia nada: acepta los mismos flags, muestra un aviso de obsolescencia que remite a la recencia calculada al leer y termina sin error, así que los scripts existentes siguen funcionando. Se mantiene durante una versión menor y después se elimina, junto con los métodos decay_scores / decay_confidence de los almacenes.
  7. El archivado siempre es explícito. Solo un forget explícito o un Insight de curación aprobado (archive_candidate, DDR-008) archivan un nodo. Archivar ya no toca updated_at, y registra archived_at y archived_reason. Si un nodo archivado todavía hace de puente entre nodos vivos, el Insight de curación lo señala.
  8. La confianza de reflect se refresca. Al regenerar un Insight se actualizan confidence y body ON MATCH (su evidencia puede haber cambiado), salvo que una persona ya lo haya juzgado (aprobado o descartado).
  9. La importación conserva los timestamps. El importador pasa created_at / updated_at por una vía de confianza. Las propiedades que envía quien llama siguen sin ser de confianza, así que #76 se mantiene para las escrituras por MCP y SDK.

Consecuencias

  • Positivas:
  • La recencia ya no puede destruir datos: un parámetro erróneo solo produce un mal ranking, y cambiar el parámetro lo corrige también hacia atrás.
  • No hace falta ningún cron. Tampoco hay nada que acotar por scope en despliegues multi-tenant, porque la señal se calcula en cada consulta dentro del scope de quien consulta.
  • Los hubs y los nodos que siguen recibiendo enlaces se mantienen visibles.
  • Negativas:
  • Los grafos ya decaídos conservan su baja confianza almacenada, porque este DDR no reescribe datos existentes. Quien quiera restablecerla puede poner confidence = 1.0 donde valid_to IS NULL con una línea documentada; no hay migración automática.
  • La búsqueda hace algo más de trabajo por resultado, una exponencial por candidato, despreciable frente a la recuperación.
  • Neutras:
  • La salida de engrama decay cambia de significado (informe en lugar de escritura), y se anuncia en el changelog.

Sustituye / Sustituido por

Sustituye la parte de decaimiento persistido de la fase D de DDR-003. La validez temporal (valid_from / valid_to, reactivación) no cambia.

Seguimientos abiertos (no bloqueantes)

  • Propagación de la actividad de los vecinos (un hub hereda una fracción de la recencia de sus vecinos). Se aplaza hasta haber medido el factor de grado en grafos reales.
  • Políticas de retención (borrado definitivo tras N meses) para despliegues con límites legales de conservación. Es un asunto distinto de la relevancia.

Referencias

  • DDR-003: razonamiento temporal (fase D).
  • DDR-008: Insights de curación, que sustituyen al archivado automático.
  • 76: timestamps gestionados por el servidor.