'Session not found'? state.db ahora detecta la corrupción, la aísla y se cura solo


Abres Hermes para recuperar la sesión de ayer y te encuentras con un frío session not found — pero recuerdas perfectamente que existe. Peor aún: state.db (la base de datos SQLite donde Hermes guarda todo el historial de sesiones) se corrompe por completo y meses de conversaciones “desaparecen”. Antes, esta clase de problema era casi imposible de diagnosticar: el mensaje de error ocultaba la causa real (la corrupción de la base de datos), y el sistema seguía escribiendo en la base de datos dañada, haciendo que el daño creciera como una bola de nieve. Un lote de correcciones fusionado del 30 al 31 de agosto (PR #99513 y sus PRs hermanos) le da a Hermes, por primera vez, una forma sistemática de gestionar la corrupción de la base de datos: detectarla, ponerla en cuarentena, curar lo que se pueda curar y decírtelo con claridad cuando no se puede.

Por qué era tan difícil de diagnosticar antes

state.db es un archivo SQLite — robusto en teoría, pero igualmente corruptible tras un corte de luz, un disco lleno, un proceso que se estrella o aperturas concurrentes desde varios procesos. Antes, la actitud de Hermes ante la corrupción era “fingir que no ha pasado nada”:

  • Al leer datos corruptos, la interfaz solo mostraba session not found, tragándose el hecho de que “la base de datos está corrupta”;
  • Una base de datos estructuralmente rota seguía aceptando escrituras — datos nuevos vertidos en un almacén roto, como llenar un cubo agujereado;
  • Un archivo vacío de 0 bytes se confundía con una “base de datos nueva” y se abría con normalidad — hasta que la primera escritura real fallaba con attempt to write a readonly database;
  • Con varios procesos abriendo la misma base de datos, uno podía clasificar erróneamente la base de datos vacía y legítimamente recién creada de otro proceso como corrupta y ponerla en cuarentena.

Qué arregla este lote

Seis PRs, repartidos en cuatro fases: detección, cuarentena, curación y protección.

Detectar la corrupción en lugar de fingir

  • Reportar “corrupción” en lugar de “session not found” (PR #99529): la detección de corrupción se mueve a la ruta de lectura, así que el problema sale a la superficie con un mensaje claro en lugar de un error engañoso;
  • Las bases de datos estructuralmente corruptas dejan de aceptar escrituras (PR #99652): fail-closed — rechazar escrituras en lugar de verter datos en un almacén roto;
  • Las conexiones de lectura se acotan por archivo, no por instancia de SessionDB (PR #98691): antes cada instancia tenía su propio presupuesto de conexiones, así que los contadores se desbordaban con varias instancias — un detonante de agotamiento de descriptores de archivo y de caídas.

Poner en cuarentena los archivos de 0 bytes

  • Un state.db truncado a 0 bytes se pone en cuarentena (PR #98017): el archivo vacío se aparta al arrancar en lugar de abrirse como una base de datos normal;
  • Un bloqueo entre procesos arregla la carrera de la cuarentena (PR #99513, sub-cluster A): toda la secuencia comprobar → cuarentena → conectar → confirmar esquema se ejecuta ahora bajo un bloqueo entre procesos, con una guardia has_live_connection() que protege las bases de datos “vacías pero legítimamente en uso” — un proceso ya no puede poner en cuarentena la base de datos recién creada de un compañero.

Autocuración del índice de texto completo FTS

  • UnicodeDecodeError ya no rompe la sonda del índice (PR #99513, sub-cluster B): las tablas FTS corruptas pueden lanzar errores de decodificación, que antes mataban la inicialización de solo lectura y todos los endpoints de lectura posteriores; las rutas de sonda y curación ahora los capturan, y las tablas FTS rotas se eliminan y recrean.

Eliminar las carreras de clase de caída

  • Las lecturas sin sincronizar en la conexión de escritura compartida desaparecen (PR #99502): esta clase podía causar caídas a nivel de SIGSEGV en casos extremos;
  • Las carreras entre close() y las escrituras en segundo plano se autocuran (PR #99509): cuando la conexión de escritura se cierra mientras aún hay escrituras en vuelo, el sistema se repara solo en lugar de descartar datos en silencio.

Qué significa esto para ti

Si alguna vez tu historial de sesiones “desapareció misteriosamente”, este lote cambia toda la tubería de gestión: detección por delante → cuarentena del archivo dañado → curación de lo curable (tablas FTS) → y cuando no se puede curar, un error claro — sin seguir escribiendo nunca en el almacén roto. La fiabilidad de los datos de sesión pasa de “podría desaparecer algún día” a “al menos el problema está explicado y el daño deja de crecer”.

Cuándo puedes usarlo

Estos PRs se fusionaron del 30 al 31 de agosto de 2026 y están todos solo en main — todavía no están en ninguna release. Actualiza a la última versión de main para tener la protección completa; si antes te has topado con session not found o has perdido sesiones, merece la pena releer los mensajes de error tras la actualización — ahora te dicen directamente el estado de la base de datos.

Tu historial de sesiones es la memoria de trabajo entre tú y Hermes — su fiabilidad merece cuidados. Para otras formas de proteger los datos de sesión, consulta la guía de guardado y exportación de sesiones y el análisis post-mortem de la amnesia de 798 mensajes; cómo interactúa la compresión con el historial se cubre en la guía de compactación en una llamada.