runbook del armador: el hammer build de la receta derivada va bajo el lock compartido

work/.farm-build.lock, el mismo que toman farm-worker-loop.sh y campana-deuda.sh.

hammer build comparte work/sources/<dep>-<sha> entre todas las recetas: dos builds
simultáneos que compartan una dep se pisan (uno hace fetch y borra el árbol mientras el
otro lo usa) y el árbol queda roto PARA SIEMPRE — reintentar no lo arregla. Medido: al
invalidar libdrm, ~93 de 205 recetas KDE murieron por el wrapper .zwrap/cc barrido del
árbol de fuente. ADR 0012, sin decidir.

El runbook era el único sitio de este frente que mandaba a construir. El resto del armador
no toca el store: plan calcula el ArtifactHash con cómputo puro sobre las recetas, y
probe/gate/bundles/closure sólo leen.

Aviso de la sesión de granja/store, que comparte el repo.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Sergio
2026-08-10 14:01:37 +00:00
co-authored by Claude Opus 5
parent fe382b0d26
commit 8ed57dee34
+20
View File
@@ -96,6 +96,26 @@ construir**.
⚠ Para construir la receta derivada hay que dejarla **junto a la receta base**, o sus `deps.build`
no resuelven. `plan` no escribe en `recipes/` por su cuenta: ese directorio es el corpus compartido.
**Y al construirla, `hammer build` va SIEMPRE bajo el lock compartido:**
```sh
flock work/.farm-build.lock ./target/release/hammer --store ./store build recipes/linux-derivada.toml
```
`hammer build` comparte `work/sources/<dep>-<sha>` entre todas las recetas. Dos builds simultáneos
que compartan una dependencia se pisan: uno hace fetch y borra el árbol mientras el otro lo usa, y
**el árbol queda roto para siempre** — reintentar no lo arregla. Medido a escala: al invalidar
`libdrm`, ~93 de 205 recetas KDE murieron con «`/src/.zwrap/cc` is not a full path to an existing
compiler tool», que es el wrapper de zig que la receta deja **en el árbol de fuente**, barrido por el
fetch concurrente de otra. Es el ADR 0012, todavía sin decidir.
Es el mismo fichero de lock que toman `scripts/farm/farm-worker-loop.sh` y `campana-deuda.sh`, así
que con esto quedan serializados los tres. Deliberadamente **no** está dentro de `hammer build`: los
scripts de la granja ya lo toman por fuera y hammer se bloquearía contra ellos.
Nada más del armador toca el store: `plan` calcula el `ArtifactHash` con `hammer_build::artifact_hash`,
que es cómputo puro sobre las recetas, y `probe`/`gate`/`bundles`/`closure` sólo leen.
## 4. El gate de no-regresión — **por objetivo**
La regla es «todo dispositivo en uso debe seguir teniendo driver». Aplicada global rechazaría