harkaq: HITO DE FASE 1 — wiring en Rust; veredicto por fase sobre una receta real
crates/hammer-build/src/harkaq.rs + Sandbox::bwrap_args_harkaq: harkaq sale de `hammer build`, no de un script. Deriva la política de la clausura declarada (D1), lanza el lector, mete harkaq-exec como último eslabón antes del `sh -c`, y recoge el Verdict por FASE (configure/compile/install son bwraps distintos ⇒ dominios distintos ⇒ un veredicto cada uno). EL HITO, sobre recipes/zlib.toml (receta real del catálogo): configure → Hermetico esperadas (14): /usr/bin/gcc deuda: ninguna ✓ compile → Impuro DEUDA (1): /usr/bin/make → rc=126, la jaula lo frenó El diagnóstico completo de zlib cabe en una frase: lo único que toma de Alpine sin declararlo es `make`. INERTE sin HARKAQ=1: mismos args de bwrap, mismo entorno, ningún proceso extra. Requisito duro, no cortesía — 700+ artefactos sellados no pueden cambiar de hash por encender un diagnóstico. Los 57 tests previos del crate siguen verdes sin tocar, que es la prueba. harkaq-policy es PURO y se testea sin kernel (4 tests nuevos, como pide §4): traduce store→sandbox, excluye la metadata `.hammer/` del artefacto, y deja listables los ancestros de cada fichero de la clausura. La integración se delató sola en su PRIMERA corrida real: faltaba /cache como superficie de contrato (ZIG_GLOBAL_CACHE_DIR=/cache/zig — zig CREA dirs ahí) y la fase moría con `fs.make_dir /cache/zig/tmp`. De ahí que las superficies de contrato las decida el Sandbox (que sabe qué montó) y no harkaq: /cache sólo existe si hay cache_dir, y una política que nombre un path inexistente aborta el build a propósito. libc en hammer-build: Child::kill() manda SIGKILL y el lector moriría MUDO, sin emitir el Verdict — justo lo que no queremos de un componente cuyo producto ES el veredicto. Hace falta SIGTERM. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+20
-1
@@ -671,7 +671,26 @@ Después: tomar **una** receta real de hammer. Derivar su política de la clausu
|
||||
Landlock+seccomp dentro del bwrap actual. Emitir el `Verdict` con `denials = []` **y el canario
|
||||
visto**.
|
||||
|
||||
**Estado (2026-07-15): la cadena corre de punta a punta.** `harkaq-audit` (lector, host,
|
||||
**✅ HITO DE FASE 1 CUMPLIDO (2026-07-15).** `hammer build` sobre una receta **real del catálogo**
|
||||
(`recipes/zlib.toml`), con la política derivada de la clausura declarada y el `Verdict` emitido
|
||||
**por fase**:
|
||||
|
||||
```
|
||||
configure → Hermetico esperadas (14): /usr/bin/gcc deuda: ninguna ✓
|
||||
compile → Impuro DEUDA (1): /usr/bin/make → build rc=126 (la jaula lo frenó)
|
||||
```
|
||||
|
||||
El diagnóstico completo de zlib cabe en una frase: **lo único que toma de Alpine sin declararlo
|
||||
es `make`**. Wiring en `crates/hammer-build/src/harkaq.rs`, detrás de `HARKAQ=1` e **inerte** sin
|
||||
él (requisito duro: 700+ artefactos sellados no pueden cambiar de hash por encender un
|
||||
diagnóstico). `harkaq-policy` es puro y se testea sin kernel (4 tests), como pide §4.
|
||||
|
||||
La integración se delató sola en su primera corrida: faltaba `/cache` (superficie de contrato —
|
||||
`ZIG_GLOBAL_CACHE_DIR=/cache/zig`, zig **crea** directorios ahí) y la fase moría con
|
||||
`fs.make_dir /cache/zig/tmp`. De ahí que las superficies de contrato las decida el `Sandbox`, que
|
||||
es quien sabe qué montó, y no harkaq: `/cache` sólo existe si hay `cache_dir`.
|
||||
|
||||
**Estado previo — la cadena corre de punta a punta.** `harkaq-audit` (lector, host,
|
||||
`CAP_AUDIT_READ`) + `harkaq-exec` (política, estático, dentro de bwrap) + `harkaq-run.sh`
|
||||
(orquesta y pone el canario). Los dos actos, con comandos sintéticos:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user