Entiende el Nix Store: Por qué esos hashes interminables no son tan locos como parecen
Nix Store Paths: Por Qué Esos Hashes No Son Tan Misteriosos
Seguramente los has visto. Esos nombres de directorio intimidantes escondidos en /nix/store que parecen sacados de una licuadora criptográfica:
/nix/store/s0psayl7zvkvwdcqc8fy1sbv8rlf1yq8-bash-5.3p9
La parte legible es obvia: bash-5.3p9 te dice exactamente qué hay dentro. Pero esos 32 caracteres antes del guion... ahí está el misterio. Y lo cierto es que la mayoría de explicaciones que encontrarás por ahí están incompletas.
La Explicación Común (Y Equivocada)
"La tabla viene de los inputs" es lo que la mayoría te dirá. No están totalmente mal, pero les falta un matiz crucial. La pregunta real es: ¿cuáles inputs? ¿Estamos hashando los archivos fuente que escribiste? ¿La receta de build que Nix genera? ¿Los bytes producidos por la compilación? ¿Las dependencias?
La respuesta honesta es: depende.
Dos Esquemas de Nombres, Un Solo Directorio
Nix en realidad usa dos mecanismos diferentes para nombrar los paths del store, y ambos conviven felices bajo /nix/store. Mezclarlos es donde empieza la confusión.
Input-Addressed: Nombres Antes del Build
Para la mayoría de builds de paquetes, Nix trabaja como un arquitecto revisando planos. Cuando escribes una expresión .nix, Nix la evalúa en una derivación: una especificación concreta de qué construir, incluyendo:
- El script builder
- Argumentos de compilación
- Variables de entorno
- Outputs declarados
- Dependencias
Con esta receta en mano, Nix puede calcular un identificador único incluso antes de que el build corra. Los binarios terminados aún no existen, pero Nix ya sabe cómo llamarlos.
Esto explica por qué editar una expresión Nix no siempre cambia el store path. Si tus cambios no afectan la receta de build subyacente, Nix produce la misma identidad. Dos expresiones diferentes pueden evaluar a recetas idénticas, así que comparten el mismo path. Nix nombra lo que va a construir, no la ortografía de tu código.
Content-Addressed: Nombres de los Bytes
Nix también puede nombrar objetos del store directamente desde su contenido. Cuando corres nix store add, le estás pasando algo que ya existe, y hace el hash de los bytes de inmediato. Sin evaluación, sin receta: solo contenido.
Aquí, el path se determina por lo que realmente hay en el archivo. Cambia un solo byte, y el hash cambia.
Por Qué Importa Esta Distinción
Entender estos dos esquemas de nombres hace que varios comportamientos de Nix se vuelvan de repente obvios:
Predecir cambios de path. Si te preguntas "¿editar X afectará el store path?", pregúntate: ¿X cambia la receta de build o el contenido real? ¿Editar un comentario en una expresión Nix? Probablemente sin nuevo path. ¿Cambiar la versión de una dependencia? Nuevo path garantizado.
Entender builds coexistentes. ¿Por qué un resultado de build antiguo puede vivir junto a uno nuevo en el store? Porque tienen identidades diferentes. Nix no sobreescribe: simplemente no lo necesita.
El reuse de caché tiene sentido. Un binary cache puede servir un path pre-built con confianza porque el nombre identifica unívocamente los inputs del build. Mismo nombre significa mismo contenido, garantizado.
Más Que Solo un Nombre
Un store path nunca está realmente solo. Los paquetes compilados referencian otros store paths (librerías dinámicas, intérpretes, assets compartidos), y Nix rastrea estas relaciones como un grafo.
Esto no es solo metadata: es un mapa completo de dependencias. Desde cualquier path, puedes trazar su closure: todo lo que debe viajar con él para funcionar en otra máquina. Así es como funciona nix-copy-closure, y por qué los deployments con Nix son confiables.
La misma base de datos permite a Nix verificar integridad. Puede revisar si los bytes en disco todavía coinciden con lo que grabó cuando el path fue creado. Los store paths no son nombres de directorio opacos: son identidades consultables con un historial completo de auditoría.
La Conclusión
Esos hashes crípticos no son arbitrarios. Son el resultado de una decisión de diseño deliberada: Nix nombra las derivaciones por sus inputs y el contenido por sus bytes. Este enfoque dual es lo que hace a Nix reproducible, verificable, y sorprendentemente predecible una vez que lo entiendes.
Así que la próxima vez que veas un store path, no entres en pánico. Lee de derecha a izquierda: esa es la parte humana. El hash a la izquierda es simplemente la forma que tiene Nix de hacer una promesa: este nombre significa este build, y nada más.
¿Listo para profundizar? Ya sea que estés desplegando contenedores, gestionando infraestructura, o simplemente curioso sobre builds reproducibles, entender los internals de tu sistema siempre vale la pena. En NameOcean, creemos que los mejores desarrolladores son los que entienden qué está pasando realmente bajo el capó: no solo qué comandos correr.
¡Feliz building!