Paso 2 del §Orden de trabajo del ADR 0015. Verbos en inglés (regla 4); el ADR decía traer/crear/correr y queda corregido, con una línea que dice por qué para que no se vuelva a proponer. `hammer qorpa pull <url> --sha256 <sha>` baja, VERIFICA y recién entonces desempaca — nunca al revés: un tar ajeno sin verificar es código ajeno que ya escribió en tu disco. Veredicto de ADR 0014: contenido distinto ⇒ ABORTAR, y no queda nada a medias. La identidad es el sha256 del ARCHIVO, no del árbol, así que la URL es informativa y espejar sale gratis (ADR 0013). `list` marca a gritos las imágenes vacías y sale ≠0 (regla 3). Los pasos 3-7 están declarados en la superficie y fallan diciendo a qué paso del ADR pertenecen. Nada de esto toca el store: es el espacio paralelo /var/lib/hammer/qorpa (D1). PROBADO de punta a punta contra las dos imágenes curadas — Ubuntu base 24.04.3 (2760 ficheros, 78 M) y Arch bootstrap 2026.09.01 (31748, 534 M), las dos con su glibc adentro, que es el montón B entero. Y probarlo de verdad destapó tres cosas que en verde no se ven: 1. `-p` sin `--delay-directory-restore` NO extrae un rootfs real sin ser root: /etc/ca-certificates/extracted/cadir es 0555 y tar lo crea con su modo final ANTES de llenarlo. 2. Mi limpieza mentía: `remove_dir_all().ok()` no puede con un árbol que trae directorios de sólo-lectura, así que el staging de un pull roto SOBREVIVÍA y el siguiente pull extraía encima. El síntoma («Permission denied» en un directorio recién creado) no se parece en nada a la causa. 3. Renombrar un DIRECTORIO exige escritura sobre el directorio mismo, y el root.x86_64 de Arch viene dr-xr-xr-x. Se abre, se mueve y se le devuelve su modo exacto. Y una regla que sonaba razonable y era falsa: «si hay un solo directorio arriba, ése es el rootfs». El bootstrap de Arch trae TRES entradas arriba (root.x86_64, version, pkglist) ⇒ no disparaba y el rootfs quedaba un nivel abajo, con todo verde y sin un error. Ahora se ancla por ESTRUCTURA (tiene etc/ y usr|bin), con --subdir como escape, y si no acierta FALLA en vez de adivinar: un rootfs mal anclado no rompe acá, rompe cuando la instancia no encuentra su loader. Los hermanos descartados quedan escritos en el manifiesto, no tirados en silencio. 5 tests nuevos, incluida la cicatriz de Arch. 35/35 en hammer-cli. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U5cQtQrYNjWJVXVE6aEpQ2
44 lines
1.1 KiB
TOML
44 lines
1.1 KiB
TOML
[package]
|
|
name = "hammer-cli"
|
|
version.workspace = true
|
|
edition.workspace = true
|
|
license.workspace = true
|
|
authors.workspace = true
|
|
repository.workspace = true
|
|
description = "El binario `hammer`: orquesta build, hydrate, try/commit, apply/export y ctl."
|
|
|
|
[[bin]]
|
|
name = "hammer"
|
|
path = "src/main.rs"
|
|
|
|
[features]
|
|
default = []
|
|
# Activa el traductor LLM real (Claude API) detrás del flag `hammer ai --llm`.
|
|
# Sin esta feature, `--llm` falla con un mensaje claro pidiendo recompilar.
|
|
llm-claude = ["hammer-agent/llm-claude"]
|
|
|
|
[dependencies]
|
|
hammer-core.workspace = true
|
|
hammer-build.workspace = true
|
|
hammer-bootstrap.workspace = true
|
|
hammer-mirror.workspace = true
|
|
hammer-upgrade.workspace = true
|
|
hammer-overlay.workspace = true
|
|
hammer-journal.workspace = true
|
|
hammer-agent.workspace = true
|
|
serde.workspace = true
|
|
serde_json.workspace = true
|
|
toml.workspace = true
|
|
base64.workspace = true
|
|
anyhow.workspace = true
|
|
clap.workspace = true
|
|
tracing.workspace = true
|
|
tracing-subscriber.workspace = true
|
|
tempfile.workspace = true
|
|
|
|
[dev-dependencies]
|
|
tempfile.workspace = true
|
|
base64.workspace = true
|
|
sha2.workspace = true
|
|
hex.workspace = true
|