Commit Graph
1748 Commits
Author SHA1 Message Date
Sergio 2c8cd351c6 estado: cosecha granja 2026-09-02T07:31:59Z — avance del árbol KDE 2026-09-02 07:32:00 +00:00
Sergio 8338edee8c estado: cosecha granja 2026-09-02T07:01:58Z — avance del árbol KDE 2026-09-02 07:01:58 +00:00
Sergio cbe07af0cf estado: cosecha granja 2026-09-02T06:31:57Z — avance del árbol KDE 2026-09-02 06:31:57 +00:00
Sergio 0fa2ae8bba estado: cosecha granja 2026-09-02T06:02:02Z — avance del árbol KDE 2026-09-02 06:02:02 +00:00
Sergio 04d174bf6c estado: cosecha granja 2026-09-02T05:31:53Z — avance del árbol KDE 2026-09-02 05:31:53 +00:00
Sergio d6bfa475e3 estado: cosecha granja 2026-09-02T04:31:55Z — avance del árbol KDE 2026-09-02 04:31:55 +00:00
Sergio ee1a658328 estado: cosecha granja 2026-09-02T04:01:56Z — avance del árbol KDE 2026-09-02 04:01:56 +00:00
Sergio a72190b169 estado: cosecha granja 2026-09-02T01:01:49Z — avance del árbol KDE 2026-09-02 01:01:49 +00:00
Sergio 56bf168cce estado: cosecha granja 2026-09-02T00:31:48Z — avance del árbol KDE 2026-09-02 00:31:49 +00:00
Sergio 9afe0bb9d4 estado: cosecha granja 2026-09-02T00:02:07Z — avance del árbol KDE 2026-09-02 00:02:07 +00:00
Sergio aee9e55c54 estado: cosecha granja 2026-09-01T23:33:01Z — avance del árbol KDE 2026-09-01 23:33:01 +00:00
Sergio 1d06fce140 estado: cosecha granja 2026-09-01T23:02:08Z — avance del árbol KDE 2026-09-01 23:02:08 +00:00
Sergio 987aad25af estado: cosecha granja 2026-09-01T22:31:51Z — avance del árbol KDE 2026-09-01 22:31:51 +00:00
Sergio aa55981ad2 estado: cosecha granja 2026-09-01T22:02:10Z — avance del árbol KDE 2026-09-01 22:02:10 +00:00
Sergio 683eaeb79b estado: cosecha granja 2026-09-01T21:31:51Z — avance del árbol KDE 2026-09-01 21:31:51 +00:00
Sergio e29a1f2ebc estado: cosecha granja 2026-09-01T21:01:49Z — avance del árbol KDE 2026-09-01 21:01:49 +00:00
SergioandClaude Opus 5 42db2dfb35 gmp: las dos recetas son variantes DELIBERADAS, no un duplicado — queda escrito
Yo mismo las reporte como "la misma clase de colision que onda1" y me pase: no
lo son. onda1 tenia una copia RANCIA del mismo build; esto son dos builds
distintos, cada uno correcto para su frente:

    KDE     link=dynamic  --enable-shared --enable-cxx  => libgmp.so + libgmpxx.so
    COSMIC  link=static   --disable-shared              => libgmp.a, sin C++

Las dos citan libqalculate y llegan a conclusiones opuestas sobre gmpxx.h, y las
dos tienen razon para su cola. Unificarlas romperia una de las dos.

Lo que compartir nombre SI cuesta es que hace ambigua la clasificacion de
store-gc: un artefacto rancio de una puede caer como SUPERADO porque la otra
tiene sellado vigente. La condicion es precisa y esta medida — solo hay riesgo si
el hash vigente de una NO esta sellado, y hoy las dos lo estan => exposicion
CERO. Antes de podar con nombres compartidos hay que comprobar ESO, no el nombre.

La salida, si algun dia molesta, es renombrar la dinamica a gmp-shared (la
convencion que el corpus ya usa: zlib-shared, cairo-shared...). No se hizo
porque cuesta:  da 7 sellados de KDE que caen a deuda.  es
el mismo par por la misma razon.

Los comentarios NO entran en hash_inputs (medido: mismo hash antes y despues),
asi que esto no re-hashea nada.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LykB7vw38b4Ck1Zij15RQ4
2026-09-01 20:33:11 +00:00
Sergio a6ac3368ab estado: cosecha granja 2026-09-01T20:31:51Z — avance del árbol KDE 2026-09-01 20:31:51 +00:00
SergioandClaude Opus 5 75b402d1bf deferred: system-libs.patch es de kalker — va con su receta
Al verificar la resolucion estricta de parches salio la unica referencia rota
del arbol: `.deferred/kalker.toml` pide `system-libs.patch` y el fichero estaba
en `recipes/`. Los patches se resuelven `base_dir.join(nombre)` sin fallback, asi
que la receta nunca lo habria encontrado.

No es una rotura nueva: `.deferred/system-libs.patch` no existio jamas (el
importador dejo la receta en .deferred y el parche en recipes/). Y es
inequivocamente de kalker — parchea `kalk/Cargo.toml` — ademas de que ninguna
receta lo citaba desde recipes/, o sea que ahi era un huerfano.

Ningun hash se mueve por esto. Referencias de parche: 95 resuelven, 0 rotas.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LykB7vw38b4Ck1Zij15RQ4
2026-09-01 20:04:43 +00:00
SergioandClaude Opus 5 6205882b3a deferred: jubilar 5 aparcadas que ya sellan, y corregir lo que dice el comentario
`recipes/incoming/.deferred/` decia "24 recetas aparcadas con diagnostico, p.ej.
git con muro en libgit.a". Las dos mitades de esa frase eran falsas.

Cinco de las 24 ya estaban RESUELTAS en otro fichero y sellan hoy: dprint, git,
gmp, mise e yj (recipes/git.toml, recipes/mise.toml, incoming-kde/gmp.toml...).
La copia aparcada era la version anterior y seguia leyendose como deuda abierta
— y el ejemplo que daba el comentario era justamente uno de esos cinco. mise se
construyo esta misma tarde en el worker. Se van, con `gcc15.patch` que solo
citaba la gmp aparcada (ninguna de las dos gmp que sellan declara patches).

Y las 19 que quedan no estan "aparcadas con diagnostico": son volcado CRUDO del
importador, 15 de import-nix y 4 de import-alpine, todas con la cabecera "PUNTO
DE PARTIDA, no final". Nadie las intento todavia; no hay ningun muro que
respetar. Es una cola de trabajo sin empezar, no una lista de imposibles, y
leerla como lo segundo desanima de tocarla.

Gate --check OK, grafo CIERRA, corpus 786/787; las 5 que sellan intactas.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LykB7vw38b4Ck1Zij15RQ4
2026-09-01 20:03:39 +00:00
Sergio 17b6a284f7 estado: cosecha granja 2026-09-01T20:02:56Z — avance del árbol KDE 2026-09-01 20:02:56 +00:00
SergioandClaude Opus 5 3231c43cdd granja: jubilar incoming-clib — 0 recetas y 26 parches inalcanzables
Era la cola de staging de las tandas base-system/foot y sus recetas ya se
habian PROMOVIDO a canonicas commit a commit ("promover 7 tier-2", "promover
cadena crypto", "promover tllist/utf8proc/scdoc/fcft/foot"). Lo que quedaba
eran 0 .toml y 26 .patch: 5 copias byte a byte de la version canonica de
recipes/ y 21 de recetas que ya no viven ahi.

No eran "probablemente inutiles": son inalcanzables POR CONSTRUCCION.
`fetch::apply_patches` resuelve `recipe.base_dir.join(nombre)` y `base_dir` es
el directorio de la receta, sin fallback a `recipes/` — un parche en una cola
sin recetas no lo puede pedir nadie.

⚠ El corolario queda escrito en farm-worker-loop.sh: al promover una cola, los
`.patch` NO viajan con la receta, y la cola queda en un estado que PARECE vivo
(tiene ficheros) sin moler nada.

Sale de QUEUES en farm-worker-loop.sh y de la lista de promote de farm-down.sh.
`incoming-go` se queda en las dos aunque el directorio no exista: es la cola
aislada del frente Go y el guard `ls $Q/*.toml` salta las vacias; quitarla seria
dejarla muerta el dia que ese frente la recree.

Verificado con la regla ESTRICTA de resolucion de parches sobre todo el corpus:
94 referencias resuelven, 0 rotas. (El chequeo que use al jubilar onda-2 era mas
laxo que hammer — aceptaba recipes/<parche> como fallback; su conclusion se
sostiene, pero el metodo queda corregido.)

Gate --check OK, grafo CIERRA, corpus 786/787.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LykB7vw38b4Ck1Zij15RQ4
2026-09-01 19:45:27 +00:00
Sergio 0ae7e18a6a estado: cosecha granja 2026-09-01T19:32:25Z — avance del árbol KDE 2026-09-01 19:32:25 +00:00
SergioandClaude Opus 5 8b2ff3cfd4 digest: blake3 pelado, no length-prefijado — el mismo archivo tenía dos hex
Lo destapó escribir la contraparte del ADR 0014 para churay: churay direcciona sus blobs
con blake3(bytes) pelado y hammer iba a sellar el digest con of_inputs(&[bytes]), los dos
bajo el prefijo `b3:`. El mismo archivo con dos hex distintos, y un CAS compartido que no
falla ruidosamente: cada lado busca un nombre distinto para los mismos bytes.

Con una sola entrada el length-prefijado no desambigua ninguna concatenación — sólo hace
que el nombre deje de ser verificable por un tercero con b3sum en la mano.

`ArtifactHash::of_bytes` YA EXISTÍA y ya era blake3 pelado: es la convención de of_file y
la del expected_hash de un .swm, así que of_inputs era además la pieza fuera de sitio
dentro del propio repo. of_inputs se queda para lo que fue escrito: hashear una LISTA.

Coste: una línea, porque ningún índice publicado lleva todavía el campo. Es el argumento
del ADR aplicado a sí mismo — decidir antes de que haya usuarios. La corrección queda en
el ADR, no reescrita en silencio.

Guardián: digest_es_blake3_pelado_y_no_length_prefijado, con vector fijo de b3sum y un
assert_ne contra of_inputs que nombra la consecuencia.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CK6HpSoHcN9M4GBpqRSusR
2026-09-01 19:10:07 +00:00
Sergio fbf402d51e estado: cosecha granja 2026-09-01T19:01:57Z — avance del árbol KDE 2026-09-01 19:01:57 +00:00
SergioandClaude Opus 5 48b3c5be3f ADR 0014: distribución multi-origen — el origen no necesita confianza
Se decide ahora, antes de tener usuarios, porque toca el formato del índice y el
comportamiento de clientes instalados en máquinas ajenas: después de la primera descarga
pública el cambio rompe a alguien o se arrastran dos formatos para siempre.

La decisión entera cuelga de una asimetría medida: ~51 G de cuerpo inmutable y verificable
por contenido, contra KB de raíz mutable que es lo único que necesita ser fresco y
auténtico. El cuerpo puede servirse desde cualquier host, incluso hostil ⇒ conseguir
espejos deja de ser un problema de infraestructura.

Cloudflare R2 como primer origen público por el egress a 0, pero es INSTANCIA, no
arquitectura: lo que se decide es que R2 sea una entrada más de una lista. No depender de un
servidorcito no se logra contratando un proveedor grande, sino pudiendo perder cualquiera
sin enterarse. Regla derivada: nunca menos de dos orígenes en dos proveedores.

Verificado de punta a punta con dos orígenes HTTP y un .swm con UN byte cambiado bajo el
mismo nombre: origen muerto ⇒ failover; origen manipulado ⇒ aborta y NO cae al bueno de
detrás. Sin ese segundo caso la lista sería un mecanismo para tapar espejos mentirosos.

Queda pendiente y anotado: el vigía sólo mira upstream, no nuestros orígenes.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CK6HpSoHcN9M4GBpqRSusR
2026-09-01 18:45:10 +00:00
SergioandClaude Opus 5 832ade63b4 repo: el índice firmado ancla el digest del .swm, y --repo acepta lista de orígenes
La cadena de confianza estaba rota en el último eslabón y no se veía. La firma del índice
cubre la lista de entradas, pero `file` es una RUTA, no un contenido: quien sirviera los
bytes podía devolver otro .swm bajo el mismo nombre y la firma seguía casando. La red de
aguas abajo no alcanza — `expected_hash` es opcional y el .swm se lee mucho antes (el gate
de colisiones de `install` ya decide con su contenido).

`PackageEntry::digest` (BLAKE3, la misma función que sella artefactos) se sella al publicar
y se verifica antes de escribir un byte: raíz → firma del índice → digest → bytes. Con eso
el origen deja de necesitar confianza, que es la condición para replicar en N espejos.

Ausencia ⇒ se sigue al siguiente origen. Contenido distinto ⇒ ABORTA, no cae al siguiente:
el fallback ahí convertiría una manipulación en silencio, con el paquete instalándose desde
el espejo bueno y nadie enterándose de que uno miente.

Campo Option con skip_serializing_if ⇒ un índice ya firmado serializa idéntico y su firma
sigue siendo válida (test). Sin digests informa CUÁNTOS no verificó, para que un índice
viejo servido desde un espejo ajeno no parezca verificado.

El mensaje nombra el origen que sirvió de verdad, no la lista entera. 2 tests.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CK6HpSoHcN9M4GBpqRSusR
2026-09-01 18:45:10 +00:00
SergioandClaude Opus 5 927dee60cf fuentes: HAMMER_MIRROR es una LISTA — un espejo propio era el mismo punto único de fallo
El ADR 0013 existe para no depender de 79 servidores ajenos, y lo resolvió creando una
dependencia de UNO nuestro. Las dos variables aceptan ahora varios orígenes separados por
comas y se prueban todos antes de caer a upstream.

El orden se ROTA con una semilla determinista tomada del hash del propio objeto: el mismo
objeto sale siempre del mismo origen (un fallo se reproduce), pero objetos distintos se
reparten ⇒ una tanda del corpus ejercita la lista entera. Con orden fijo, el segundo origen
no se tocaría jamás hasta la emergencia — que es literalmente «un espejo que nadie prueba»,
la lección del 0013 un nivel más arriba.

La parte pura sale a `rotar_bases` para poder probarla sin tocar el entorno del proceso
(que es global y haría los tests dependientes del orden en que corren). 3 tests.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CK6HpSoHcN9M4GBpqRSusR
2026-09-01 18:44:50 +00:00
SergioandClaude Opus 5 a2c2c4d968 gnome onda-2: jubilar la cola — 22 recetas y 22 hashes identicos a incoming-gnome
El caso LIMPIO del mismo fenomeno que onda-1, sin ninguna de sus asperezas: las
22 recetas son byte a byte identicas a las de incoming-gnome Y las 22 dan el
MISMO ArtifactHash, o sea la misma direccion del store. Sin divergencias, sin
colision de nombre y sin un solo artefacto que podar al retirarla.

La comprobacion que decide NO es `diff` sino `hammer hash`: la resolucion de
deps es hermano->padre, asi que dos ficheros identicos en colas distintas pueden
sellar distinto. Aca coinciden los 22.

Se va tambien `cairo-ctime-r.patch`, verificado identico al de incoming-gnome, y
comprobado que ninguna receta de ninguna cola queda apuntando a un parche
inexistente.

El andamio ya no sostenia nada: el trabajo de la isla dinamica vive en
incoming-gnome, que es la cola que el perfil usa. Sale de QUEUES en el mismo
commit, por la simetrica de la regla que ese fichero documenta.

Gate --check OK, grafo CIERRA, escritorio-gnome sigue 119/119, corpus 786/787.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LykB7vw38b4Ck1Zij15RQ4
2026-09-01 18:35:53 +00:00
Sergio b2e92de2f3 estado: cosecha granja 2026-09-01T18:31:57Z — avance del árbol KDE 2026-09-01 18:31:57 +00:00
Sergio 5053723239 estado: cosecha granja 2026-09-01T18:02:02Z — avance del árbol KDE 2026-09-01 18:02:03 +00:00
SergioandClaude Opus 5 cf42cd9049 gnome onda-1: jubilar la cola entera — molia para nadie
Cierra la jubilacion empezada con gnome-desktop. Las 5 recetas que quedaban:

- glib, glib-introspected, gobject-introspection, py3-setuptools: byte a byte
  identicas a las de incoming-gnome Y con el MISMO ArtifactHash, o sea que
  sellaban en la misma direccion y entraban por cache-hit. Coste de build cero;
  coste real: un segundo sitio donde editar, que se separa en silencio.
- gsettings-desktop-schemas: la unica distinta, y es la version ANTERIOR al
  2026-07-28 (introspection=false + link=static). La vigente lo activo porque el
  gir de Meta de mutter incluye GDesktopEnums-3.0.gir, que sale de ahi, y sin el
  el g-ir-scanner corta en el ultimo target de mutter (721/722).

Lo caro no era el tiempo sino el NOMBRE: el gsettings viejo competia con el
bueno, dos artefactos homonimos con hash distinto en el store. Podado el
huerfano (0fb1703d, 155 KiB exclusivos) y anotado en el ledger anti-churn; los
otros cuatro artefactos siguen vigentes porque los produce incoming-gnome.

Y al jubilar gnome-desktop las dos hojas de la cola se habian quedado sin
consumidor: la cola se alimentaba a si misma y terminaba en el aire.

Sale tambien de QUEUES en farm-worker-loop.sh, por la simetrica de la regla que
ese fichero ya documenta dos veces: una cola ausente de la lista no da error,
da silencio — y una cola retirada que sigue en la lista, tambien.

Gate --check OK, grafo CIERRA, escritorio-gnome sigue 119/119, corpus 786/787.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LykB7vw38b4Ck1Zij15RQ4
2026-09-01 17:52:42 +00:00
Sergio 78fc56b266 estado: cosecha granja 2026-09-01T17:32:03Z — avance del árbol KDE 2026-09-01 17:32:04 +00:00
Sergio a82b4ec0cc estado: cosecha granja 2026-09-01T17:02:43Z — avance del árbol KDE 2026-09-01 17:02:43 +00:00
SergioandClaude Opus 5 12c24a984a tasas: la 7ª sorpresa quedaba suelta del punto 6 de la lista
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ACUcwo9mZsE5ocYVE9npih
2026-09-01 17:00:19 +00:00
SergioandClaude Opus 5 9591e69b70 harkaq: el salto del check de arquitectura ya no se apoya en UB (SDD 25 T17)
`f[k++] = BPF_JUMP(..., I_KILL - k - 1 + 1)` leía y modificaba `k` en la misma
expresión, sin punto de secuencia: UB en C11. Andaba porque gcc y clang leen `k`
después del incremento y ese `+1` era la compensación exacta, pero si algún
compilador leyera antes el salto caería una instrucción más allá del final.

El índice se fija ahora en `I_ARCH` antes de usarlo. El código generado es
IDÉNTICO —mismo objdump del objeto a -O1 y a -O2, la única línea que difiere es
el nombre del fichero—, que es lo que prueba que es la misma cuenta escrita sin
UB y no un arreglo que además mueve el salto. Comprobado además que la jaula
sigue puesta: ptrace desde dentro da EPERM y un ejecutable fuera de la clausura
no arranca.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ACUcwo9mZsE5ocYVE9npih
2026-09-01 16:59:22 +00:00
SergioandClaude Opus 5 1df77985fa tasas: T19 — el sandbox apila una capa overlay por dep, y lo caro no es lo que parece
Nadie había medido qué cuesta el apilado de capas de `bwrap_args`. El 95% de las
recetas (1 108 de 1 171) construye con las deps APILADAS, hasta ~27.

Un lookup que FALLA cuesta +1 925 ns por capa (a 64 capas, 124 µs = 1 580 syscalls
nulas), pero se paga UNA VEZ POR RUTA: la dentry fusionada queda cacheada y el
montaje dura toda la fase. Un `cc -O2 -c` toca 381 rutas distintas que fallan ⇒
2,9 ms por fase a 24 capas, la misma décima de por ciento que la jaula de T17/T18.

⇒ `merge_deps_layer` no es una optimización de velocidad: sólo se pagaría sola a
partir de ~35 200 primeros fallos en una misma fase. Es el rodeo de un muro, y el
muro quedó bisecado al byte: `mount(2)` monta 41 capas (4 059 B de opciones) y
falla en 42 con un `ENOENT` que miente. El `mount(8)` de util-linux se rinde entre
8 y 12, así que bisecarlo desde la shell da un muro FALSO.

Consecuencias anotadas en sandbox.rs: no bajar el umbral «para que vaya más
rápido», y podar `.dmerge` es gratis en rendimiento. Y hay puerta medida: la API
de montaje nueva (`fsconfig lowerdir+`) monta las 64 capas que `mount(2)` rechaza.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ACUcwo9mZsE5ocYVE9npih
2026-09-01 16:56:12 +00:00
SergioandClaude Opus 5 b4a7235c59 estado: regenerar los 5 grafos tras jubilar gnome-desktop de onda-1
Ningun nodo cambia de estado y el gate `--check` sigue OK: lo unico que se
mueve es `dependientes_total` de sus deps, un dependiente menos cada una. Es
la yupana cruzando TODAS las colas, onda-1 incluida, aunque ningun grafo la
cargue como cola propia.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LykB7vw38b4Ck1Zij15RQ4
2026-09-01 16:36:30 +00:00
SergioandClaude Opus 5 03cd366c0f gnome onda-1: jubilar gnome-desktop, copia anterior de la que ya sella
Mismo paquete que `recipes/incoming-gnome/gnome-desktop.toml`: name, version
44.5 y sha256 identicos. La unica diferencia son las `[deps]`, y son las de
antes: a la de onda1 le faltan xkeyboard-config, iso-codes, libseccomp y todas
las variantes `-shared` que la canonica documenta como imprescindibles para el
scanner de introspeccion. Por eso moria con

    Run-time dependency xkeyboard-config found: NO (tried pkg-config)
    meson.build:64:17: ERROR: Dependency "xkeyboard-config" not found

que se leia como deuda de build y no lo era: arreglarla habria sido reescribirla
hasta volverla identica a la otra.

Nadie dependia de ella (los dependientes -mutter, gnome-shell, gnome-session,
gnome-settings-daemon, xdg-desktop-portal-gnome- viven en incoming-gnome y
resuelven contra su propia hermana). El gate `--check` sigue en OK y ningun
nodo cambia de estado; en los grafos solo baja `dependientes_total` de sus
deps, que es justo lo que tenia que pasar.

Sus dos artefactos quedaban sin receta que los produjera: podados y anotados en
el ledger anti-churn para que la cosecha no los devuelva.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LykB7vw38b4Ck1Zij15RQ4
2026-09-01 16:35:48 +00:00
SergioandClaude Opus 5 e5d56a4168 grafo de estado: un directorio VACIO se contaba como sellado
`state_of` decidia `sealed` con `os.path.isdir`, o sea por presencia del
nombre y no del contenido. Hoy se vio en vivo: una cosecha que murio a mitad
dejo `...-mise` sin un solo fichero y el grafo lo conto sellado — misma cifra,
misma linea, indistinguible de la corrida buena.

Es el eslabon que describe la regla 3 del CLAUDE.md: `Store::has` ya rechaza
los vacios, pero cada consumidor que mire `isdir` los vuelve a leer como
presencia. Un ausente falla ruidosamente; un vacio llega hasta el final
diciendo que todo fue bien.

Los cinco grafos salen identicos tras el cambio (no hay vacios en el store
ahora mismo), asi que corrige el criterio sin mover ningun numero.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LykB7vw38b4Ck1Zij15RQ4
2026-09-01 16:31:55 +00:00
Sergio 67c49a77e0 estado: cosecha granja 2026-09-01T16:31:54Z — avance del árbol KDE 2026-09-01 16:31:54 +00:00
Sergio eaa04a12a5 estado: cosecha granja 2026-09-01T16:01:55Z — avance del árbol KDE 2026-09-01 16:01:55 +00:00
SergioandClaude Opus 5 6558b7c8de granja: la cosecha llenaba el disco — rsync sin -H y bajando .dmerge
La bajada del store murio con "No space left on device" con 95 G libres y un
store remoto de 25 G. Dos causas que se multiplican:

- `rsync -a` NO preserva hardlinks (eso es `-H`). El store es CAS y .dmerge
  hardlinkea los artefactos, asi que los 25 G que mide `du` en el origen -que
  deduplica por inodo- se escriben en destino como copias enteras, una por enlace.
- `.dmerge` es cache pura: hammer la reconstruye sola, no aporta un artefacto y
  es la parte mas pesada del arbol (132 G en el hub, 111,7 GiB exclusivos).

Ademas el fallo a mitad deja directorios creados sin ficheros, que es un
cache-hit envenenado: `mise` se cosecho asi, como nombre vacio. Se anade un
guardian que barre los vacios al terminar la bajada y avisa de re-correr.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LykB7vw38b4Ck1Zij15RQ4
2026-09-01 15:53:35 +00:00
Sergio 95679adb6f estado: cosecha granja 2026-09-01T15:32:55Z — avance del árbol KDE 2026-09-01 15:32:55 +00:00
Sergio 914e841433 estado: cosecha granja 2026-09-01T15:21:46Z — avance del árbol KDE 2026-09-01 15:21:46 +00:00
SergioandClaude Opus 5 f2b289e6a9 harkaq: un portón de compilación para el techo de la denylist (SDD 25 T17)
`jt`/`jf` de la BPF clásica son __u8 y en la forma de poner_seccomp() el salto más largo mide n+3:
pasadas ~252 entradas el desplazamiento da la vuelta y el filtro deja de decir lo que dice el
fichero, sin error y sin aviso. Hoy son 25 y sobra sitio — el riesgo es que agregar syscalls a una
denylist es exactamente lo que uno hace sin pensarlo.

_Static_assert, o sea cero código generado: comprobado en las dos direcciones —baja el techo a 10 y
el compilador para; y la sección .text del binario es byte a byte la misma con y sin el assert—,
que es el requisito de este fichero (nada que re-hashee).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ACUcwo9mZsE5ocYVE9npih
2026-09-01 15:08:41 +00:00
SergioandClaude Opus 5 46dba58616 tasas: T17/T18 — la jaula cobra por syscall, y el filtro largo no es lo que cobra
SDD 25 tenía medido el sandbox por namespaces (T14, ~1 ms por proceso) pero no el grano fino que
harkaq pone dentro, que cobra por SYSCALL. `bench_jaula.c` lo mide con control negativo en las dos
mitades (si la jaula no quedó puesta, sale con 2).

seccomp: el filtro de harkaq es una denylist lineal, así que toda syscall legítima recorre la
cadena entera — y aun así es PLANO en su longitud (86,9 ns con 4 entradas, 88,3 con 250, sobre un
piso de 75,0). Lo que lo hace plano es el bitmap de acción constante del kernel, y eso no se supone:
un gemelo de la misma longitud con una carga de args[0] —que hace que el analizador se rinda— sí
crece, 111,6 → 139,9 ns. La regla que sale de ahí es que un filtro es gratis mientras no mire un
argumento. El bitmap se paga al instalar (1,5 µs por entrada) y se amortiza en 2 830 syscalls, o
sea una invocación y media de gcc, una sola vez por fase de build.

landlock: el precio es ESTAR enjaulado (+473 ns por open), no cuántas reglas hay — pasar de 1 regla
a las 16 384 de una clausura fichero a fichero agrega +225 ns más. La política por-fichero de D1,
que era la decisión discutible, resulta casi gratis. Y dos negativas medidas: `stat` no paga
(Landlock no engancha getattr) y un open DENEGADO sale más barato que uno concedido, al revés de lo
que se esperaba al medirlo.

En total, la jaula le cuesta a un compilado 0,23–0,31%: una décima parte del presupuesto de <5% de
SDD 16.

De paso, dos cosas del filtro que salieron de mirarlo para medirlo: la denylist tiene un techo de
~252 entradas por el __u8 de los saltos de la BPF clásica, y el jf se calcula leyendo y modificando
`k` en la misma expresión (UB en C11, benigno con gcc y clang, comprobado).

Y §9.6 queda con el experimento de PTI bien planteado: no es «el laptop daría peor» (compara dos
máquinas y mezcla cuatro variables) sino la misma máquina con pti=on y pti=off. momento no sirve ni
forzándolo: este invitado no expone PCID, así que mediría el peor caso y no el de un TigerLake.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ACUcwo9mZsE5ocYVE9npih
2026-09-01 15:08:33 +00:00
Sergio 3e935a09c2 estado: cosecha granja 2026-09-01T15:01:57Z — avance del árbol KDE 2026-09-01 15:01:57 +00:00
Sergio b088eab4ef estado: cosecha granja 2026-09-01T14:31:55Z — avance del árbol KDE 2026-09-01 14:31:55 +00:00
Sergio bbe2285161 estado: cosecha granja 2026-09-01T14:02:03Z — avance del árbol KDE 2026-09-01 14:02:03 +00:00