El problema antes del problema

Antes de escribir una línea de código, cualquier sistema de cifrado personal plantea una pregunta que no es técnica: ¿de quién estás protegiéndote?

Cuando el almacenamiento de información sensible es para uso propio, el modelo de amenaza tiene una asimetría extraña. El adversario más probable no es un atacante externo que fuerza la red. Es el contexto: el historial del shell que registra un flag --body "texto secreto", la lista de procesos que expone argumentos, el scroll del terminal que deja plaintext visible, el repo de código que, si algún día se abre al público, no debería llevar consigo el vault. El adversario es la fricción cotidiana que empuja a tomar atajos.

Esto cambia el diseño antes de que empieces a pensar en algoritmos.

AES-GCM y el modelo de confianza implícito

AES-GCM es autenticado: cifra y verifica integridad en la misma operación. Cualquier manipulación del ciphertext produce un fallo en la autenticación, no texto corrupto silencioso. Esa propiedad no es un detalle de rendimiento; es un contrato de confianza. Le dice al sistema: si esto desencripta, es auténtico. Si no, no abras.

La clave no se almacena. Se deriva en cada sesión desde una contraseña maestra usando PBKDF2-HMAC-SHA256. PBKDF2 es deliberadamente lento: iterar miles de veces el hash cuesta tiempo a un atacante que intenta fuerza bruta, y ese costo se paga solo una vez por sesión legítima. La contraseña maestra no vive en ningún archivo. Si se pierde, el contenido es irrecuperable. Esa irrecuperabilidad no es un bug; es la garantía.

Este patrón, donde la clave es efímera y la permanencia pertenece solo al ciphertext, es el núcleo de la arquitectura. Todo lo demás es consecuencia.

El vault separado del código

Una de las decisiones de diseño más interesantes es la separación entre dos repositorios: el del programa y el del vault. .diario/ vive en su propio Git privado, completamente separado del código fuente. El repo del programa puede publicarse, auditarse, forkearse. El vault nunca aparece ahí.

Esto resuelve un problema que muchos sistemas domésticos ignoran: la superficie de exposición accidental. Si mezclas el vault con el código, basta un git push sin revisar para exponer ciphertext en un remoto público. Al separar físicamente los dos árboles, el hook pre-commit puede bloquear activamente ese error: detecta si .diario/ está siendo rastreado en el repo equivocado y aborta.

El backup de .diario/ sigue siendo Git, lo cual es elegante. Git garantiza integridad por contenido mediante hashes, tiene historial, y permite distribuir el ciphertext a un remoto privado sin necesidad de infraestructura adicional. El sistema no necesita una nube propietaria. Necesita un repo privado que tú controlas.

Hay una advertencia importante que el propio diseño documenta: el historial de Git conserva ciphertext antiguo. Si una contraseña vieja se filtró, el historial del remoto puede contener material cifrado bajo esa clave comprometida. La solución no es técnica en el sentido usual; requiere rotar la contraseña y purgar el historial. El sistema avisa de esto porque es una propiedad emergente del modelo, no un fallo en el algoritmo.

La TUI como superficie de seguridad

Un detalle que revela la seriedad del modelo de amenaza: la interfaz tiene un panic mode (F8 para camuflar pantalla) y un bloqueo manual explícito. Estas no son features de comodidad. Son reconocimientos de que el entorno físico importa. Alguien se asoma, un compañero camina detrás, una reunión interrumpe. El lock y el camuflaje son primitivas de seguridad operacional, no decoración.

El autosave configurable es análogo: reduce la pérdida de contenido en edición sin comprometer el ciclo de cifrado. Cada guardado pasa por el mismo pipeline: serializar, cifrar con AES-GCM, escribir ciphertext. No hay texto plano persistente en ningún archivo intermedio.

El comando diario doctor --verify y el verify standalone antes del backup son también decisiones arquitectónicas: el sistema verifica que todo el contenido desencripte correctamente antes de comprometer el ciphertext en el remoto. Así evita que un backup corrupto propague silenciosamente datos irrecuperables.

La contraseña de recuperación como problema filosófico

El README documenta una evolución importante: la nota de recuperación ya no almacena la contraseña maestra. Solo guarda la ruta, advertencias e instrucciones. Esto parece un retroceso en usabilidad, y técnicamente lo es. Si pierdes la contraseña, pierdes el contenido.

Pero es la decisión correcta. Almacenar la contraseña en cualquier forma, incluso cifrada, introduce una segunda superficie de ataque. El sistema de recuperación se convierte en el punto débil. Al eliminarlo, el diseño asume que el usuario es responsable de su propia clave y le dice explícitamente: usa un gestor de contraseñas externo, una nota offline separada. El sistema no puede protegerte de ti mismo en ese nivel; te advierte y se hace a un lado.

Eso es honestidad de diseño. No simular seguridad donde no puede garantizarla.

Lo que enseña este tipo de sistema

Construir infraestructura criptográfica para uso personal, sin usuarios externos, sin presión de producto, es un ejercicio de claridad conceptual. No hay que vender la decisión a nadie. Solo tiene que ser correcta.

Lo que emerge de un sistema así es una comprensión más limpia de qué significa confiar en una herramienta. AES-GCM no falla silenciosamente. PBKDF2 es opaco hacia afuera y transparente hacia adentro. Git preserva integridad por contenido. El hook pre-commit es un guardia sin excepciones.

Cada componente tiene una propiedad que se puede enunciar en una frase. Cuando puedes enunciar la propiedad de cada pieza, puedes razonar sobre el sistema entero. Eso es lo que hace que un diseño sea confiable: no la complejidad de los algoritmos, sino la claridad de las invariantes.