diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 00000000..d4ed0751 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,43 @@ +# Reglas del repo compartido + +Este repo lo trabajan **varios agentes a la vez** (hoy: frente granja/store y frente kernel). Lo de +aquí abajo no son preferencias de estilo: son las dos formas conocidas de que un agente destruya el +trabajo de otro sin enterarse. El resto del diseño está en `docs/`. + +## 1. Todo `hammer build` va envuelto en `flock` + +```sh +flock work/.farm-build.lock ./target/release/hammer --store ./store build +``` + +Para una tanda, tomar el lock una sola vez y no por receta: + +```sh +flock work/.farm-build.lock bash -c 'for r in ...; do ./target/release/hammer --store ./store build "$r"; done' +``` + +**Por qué.** `hammer build` comparte `work/sources/-` entre todas las recetas. Dos builds +concurrentes que compartan una dependencia se pisan el árbol de fuentes: uno hace fetch y lo borra +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, barrido por +el fetch concurrente de otra receta. Es el **ADR 0012**, sin decidir; hasta que se decida +(lock por árbol / árbol privado / caché inmutable + copia), serializar es la única mitigación +correcta. Por eso el worker corre con `JOBS=1`. + +`scripts/farm/farm-worker-loop.sh` y `campana-deuda.sh` ya toman **ese mismo fichero de lock**, así +que usarlo nos serializa con la granja además de entre nosotros. **No está dentro de `hammer build` +a propósito**: esos scripts lo toman por fuera y hammer se bloquearía contra ellos. + +## 2. Nunca `git add -A` + +Sólo rutas explícitas. Un `add -A` arrastra al commit los ficheros a medias de otro agente. Commits +granulares, en español, directo sobre `main`, y `git push` tras cada unidad de trabajo (el `origin` +empuja a gitea **y** al espejo privado de GitHub; ver `scripts/espejo-setup.sh`). + +## 3. Antes de dar un artefacto por presente, mirá que tenga contenido + +Un directorio **vacío** en el store no es un artefacto: es un nombre. `Store::has` ya lo rechaza y +`respaldo-storagebox.sh --listar` los separa a `work/respaldo-vacios.txt`, pero la regla general +sigue valiendo para cualquier código nuevo — **un ausente falla ruidosamente; un vacío llega hasta +el final diciendo que todo fue bien**.