Commit Graph
971 Commits
Author SHA1 Message Date
Sergio 2db76cfb32 estado: cosecha granja 2026-09-04T13:32:00Z — avance del árbol KDE 2026-09-04 13:32:00 +00:00
Sergio c52b2737bd estado: KDE cierra 1001/1001 — saldadas las 8 que mató el disco lleno
dolphin filelight kate kinfocenter konsole kscreen plasma-integration
plasma-desktop. Ninguna era fallo de receta: las 8 murieron el 2026-09-03 con
«No space left on device» y el bucle las anotó ✗ igual que a una que no compila.
Reintentadas tal cual, sin tocar una sola receta, sellaron las 8 a la primera.

escritorio-kde pasa a 263/263 y drenaje.json queda en 0 en deuda en los cinco
perfiles: base, cli, escritorio-{gnome,kde,mirada}.
2026-09-04 13:21:12 +00:00
Sergio 6f145abe58 estado: cosecha granja 2026-09-04T13:01:50Z — avance del árbol KDE 2026-09-04 13:01:50 +00:00
Sergio cb7462249c estado: cosecha granja 2026-09-04T12:32:07Z — avance del árbol KDE 2026-09-04 12:32:07 +00:00
Sergio 728cbec07d estado: cosecha granja 2026-09-04T12:01:54Z — avance del árbol KDE 2026-09-04 12:01:54 +00:00
Sergio 3be39111c6 estado: cosecha granja 2026-09-04T11:31:54Z — avance del árbol KDE 2026-09-04 11:31:54 +00:00
Sergio bbbaf7141a estado: cosecha granja 2026-09-04T11:01:57Z — avance del árbol KDE 2026-09-04 11:01:57 +00:00
Sergio f41569beb1 estado: cosecha granja 2026-09-04T10:31:53Z — avance del árbol KDE 2026-09-04 10:31:53 +00:00
Sergio dbaf8d9a43 estado: cosecha granja 2026-09-04T10:01:53Z — avance del árbol KDE 2026-09-04 10:01:53 +00:00
Sergio a36124f38d estado: cosecha granja 2026-09-04T07:31:54Z — avance del árbol KDE 2026-09-04 07:31:54 +00:00
Sergio b2b261dd98 estado: cosecha granja 2026-09-04T07:01:52Z — avance del árbol KDE 2026-09-04 07:01:52 +00:00
Sergio 7db1522c14 estado: cosecha granja 2026-09-04T06:01:53Z — avance del árbol KDE 2026-09-04 06:01:53 +00:00
Sergio d67a7fa038 estado: cosecha granja 2026-09-04T05:01:49Z — avance del árbol KDE 2026-09-04 05:01:49 +00:00
Sergio 99f7f46c47 estado: cosecha granja 2026-09-04T04:31:42Z — avance del árbol KDE 2026-09-04 04:31:42 +00:00
Sergio 7e58b42987 estado: cosecha granja 2026-09-04T04:02:22Z — avance del árbol KDE 2026-09-04 04:02:23 +00:00
Sergio 9f513ade73 estado: cosecha granja 2026-09-04T03:31:59Z — avance del árbol KDE 2026-09-04 03:31:59 +00:00
Sergio 9c1910ffbd estado: cosecha granja 2026-09-04T03:02:26Z — avance del árbol KDE 2026-09-04 03:02:26 +00:00
Sergio 094b056cad estado: cosecha granja 2026-09-04T02:32:07Z — avance del árbol KDE 2026-09-04 02:32:07 +00:00
Sergio 937169da28 estado: cosecha granja 2026-09-04T02:02:16Z — avance del árbol KDE 2026-09-04 02:02:16 +00:00
SergioandClaude Opus 5 8c4e1a6b24 cursores: cosmic y sway corrían con el puntero INVISIBLE — receta propia, y el vigía medía mal
`vigia-imagen.py` daba ✗ en cursores en DOS de los cuatro escritorios. No es cosmético: con el
cursor por software —obligatorio en virtio-gpu y en todo render por CPU— el compositor dibuja la
imagen que le da el TEMA, y sin tema el ratón se mueve invisible. cosmic llegó a 43/43 y sway a
173/173 así, porque un tema de cursor no es dep de build de nadie: sólo entra si se DECLARA.

`adwaita-cursors` (corpus, 48.1, data-only): del mismo tarball que `adwaita-icon-theme` pero SÓLO
`Adwaita/cursors/` — 39 ficheros y 14 MB, sin un icono. Promover el tema entero habría regalado a
sway y a cosmic los iconos de GNOME, que está anotado como decisión pendiente y no como olvido.

Las dos cosas que el tarball no trae y la receta fabrica:
· los nombres X11 heredados (`left_ptr`, `xterm`, `watch`, `hand2`…) son enlaces que genera el
  `meson.build` de upstream. El mapa se PARSEA de ahí, no se copia: copiado envejece en silencio.
  Si el origen de un enlace no existe, la fase falla — upstream pone un `files()` como aserción.
· `/usr/share/icons/default/index.theme` con `Inherits=Adwaita`. Sin `XCURSOR_THEME` en el
  entorno, libXcursor y wlroots buscan el tema llamado literalmente `default`; sin él no hay
  puntero AUNQUE Adwaita esté instalado. Es el eslabón que hace que ande sin configuración.

⚠ no declarar esta receta junto a `adwaita-icon-theme`: chocan en `Adwaita/cursors/*`.

Y el vigía estaba midiendo el invariante de al lado: exigía `index.theme` en el directorio para
contar un tema, que es correcto para ICONOS —la búsqueda XDG recorre `Directories=`— y falso para
CURSORES, porque libXcursor abre `<tema>/cursors/<nombre>` directo y el índice sólo hace falta para
seguir un `Inherits=`. Con la receta instalada seguía diciendo «NINGÚN tema de cursor».

De paso queda anotado en `targets.toml` que el comentario de cosmic decía «sin ellos arranca sin
puntero» sobre `cosmic-icons`, que no trae cursores: describía una protección que no existía.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CGyBj4QyeCZiwLMkP9GJp6
2026-09-04 01:38:30 +00:00
Sergio a62ec9061d estado: cosecha granja 2026-09-04T01:33:16Z — avance del árbol KDE 2026-09-04 01:33:16 +00:00
Sergio 19a7bfb9e4 estado: cosecha granja 2026-09-04T01:02:07Z — avance del árbol KDE 2026-09-04 01:02:07 +00:00
Sergio 5fb557b274 estado: cosecha granja 2026-09-04T00:33:39Z — avance del árbol KDE 2026-09-04 00:33:39 +00:00
SergioandClaude Opus 5 fdce080d96 qorpa D8: sniper sellado al store, con la marca que evita que la cifra mienta
D8 decía que sniper «entra al store por `file_drop`». Dos correcciones, y la
primera es de vocabulario: **`file_drop` en hammer es otra cosa** — una
operación de `hammer apply` que coloca un fichero en el sistema instalado
verificando su hash. No tenía nada que ver con sellar. Lo que sella es lo de
siempre, una receta. Queda escrito en el ADR: un término inventado que suena a
mecanismo existente manda a buscar el código donde no está.

`recipes/steam-runtime-sniper.toml` sella el árbol del runtime (11196 ficheros)
pineado por el sha256 que ya estaba verificado. Entra donde Arch y Ubuntu no
pueden por una propiedad, no por simpatía: **no muta** —nadie le instala nada
adentro— así que el mismo tarball da siempre el mismo árbol y sellarlo es una
afirmación verdadera.

**La marca: `foreign = true`.** No cambia el build en un byte y **no entra en
`hash_inputs`** (describe procedencia, no identidad — hay test). Lo que cambia
es contable: `build-state.py` la clasifica `ajeno`, la resta del denominador de
las imágenes y la deja fuera del recuento de recetas. Sin eso, sellar un
prebuilt habría subido la cifra que todo el mundo lee como «cuánto
construimos» — el riesgo que el ADR escribió antes de que existiera la primera
instancia. Verificado: sigue diciendo 821 recetas, y aparte
`de las ajenas, 1 selladas al store (prebuilt pineado, sin procedencia de fuente)`.

Y la diferencia con el otro ajeno: `xwayland` no se hashea (no hay receta, y un
hash afirmaría que lo reproducimos); el sellado **sí conserva su hash**, porque
está en el store y que un artefacto exista mientras el grafo lo niega sería otra
forma de mentir. Comparten el estado, que es lo que protege la cifra.

**`hammer qorpa import --from-store <hash>`** lo consume, y ahí está el detalle
que hace que valga: la imagen se registra bajo el **sha256 del archivo de
upstream**, no bajo el ArtifactHash. Al revés, la imagen del store y la traída
con `pull` serían dos imágenes distintas con los mismos bytes y las instancias
de dos máquinas dejarían de coincidir — justo lo que el pin existe para evitar.
El árbol se **enlaza**: una imagen nunca se escribe (lo que escribe la instancia
va a su `upper`), así que compartir inodos con un artefacto sellado y de sólo
lectura es correcto por construcción y la imagen cuesta ~0 bytes. La contracara
conocida de `.dmerge`: mientras el artefacto siga en el store, borrar la imagen
no libera disco; `--copy` lo evita.

Licencia `LicenseRef-qorpa-ajena-no-enumerable` a propósito: adentro hay cientos
de paquetes Debian y no podemos enumerarlos; vacío se leería como «todavía no la
poblamos». SDD 20 lo recoge y afila la distinción: replicarla a nuestras
máquinas es lo que ya hace ADR 0013 con las fuentes; publicarla a terceros sigue
pidiendo licencia y marca.

29 tests verdes. El sellado en sí corre aparte, esperando el lock de la granja.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QZjGRqvjWij9dew7NVFu4Q
2026-09-04 00:09:20 +00:00
Sergio 3329317737 estado: cosecha granja 2026-09-04T00:02:50Z — avance del árbol KDE 2026-09-04 00:02:50 +00:00
Sergio 8ca4fb035f estado: cosecha granja 2026-09-03T23:32:30Z — avance del árbol KDE 2026-09-03 23:32:30 +00:00
Sergio fc07286dbb estado: cosecha granja 2026-09-03T23:02:29Z — avance del árbol KDE 2026-09-03 23:02:29 +00:00
Sergio 6bfc201a50 estado: cosecha granja 2026-09-03T22:32:41Z — avance del árbol KDE 2026-09-03 22:32:41 +00:00
Sergio d0c1402267 estado: cosecha granja 2026-09-03T22:01:32Z — avance del árbol KDE 2026-09-03 22:01:32 +00:00
SergioandClaude Opus 5 914c1b72af kcoreaddons: prender el módulo QML — el menú de Plasma ABRE, y detrás de él konsole
`-DKCOREADDONS_USE_QML=OFF` estaba desde que se escribió la receta, con el argumento razonable de
que un framework tier-1 no debería arrastrar QML. El precio no se vio hasta hacer CLIC en el
lanzador dentro de QEMU: `kickoff` importa `org.kde.coreaddons` y ese módulo lo instala esta receta
y ninguna otra ⇒ **el menú de aplicaciones no abría**. La librería C++ salía completa, sus 70
consumidores enlazaban bien y el perfil reportaba 100%.

Es la forma más pura del «sellado ≠ arranca»: no falta una librería, falta una porción OPCIONAL de
una librería que sí está. Ninguna métrica de clausura puede verlo — mide recetas, no features.

`qtdeclarative` ya estaba en `[deps].build`, así que prenderlo no agrega una dep: deja de tirar lo
que ya se podía construir.

VERIFICADO CON UN SOLO BUILD (56 s), a propósito, en vez de pagar la cascada para averiguarlo:
  · panel → menú abre (usuario, buscador, Favoritos/Todas, Aplicaciones/Lugares/Sesión)
  · buscar «konsole» + Enter → la terminal arranca y corre:
        uname -a         → Linux (none) 6.16.12 #1 SMP PREEMPT_DYNAMIC … x86_64
        konsole --version → konsole 25.04.3
Es la cadena completa del escritorio por primera vez: panel → menú → búsqueda → app → shell.

COSTO, medido antes de tocar y confirmado después: `yupana radio kcoreaddons` predijo 71, y el grafo
regenerado da exactamente **71 en deuda** (`escritorio-kde 192/263`). Queda como deuda DECLARADA
para una campaña de granja; la imagen de hoy corre con un kcoreaddons más nuevo que aquel contra el
que enlazaron sus consumidores, lo que es legítimo porque cruza un SONAME (misma ABI, sólo se suma
un módulo QML) — la misma regla que decidió la promoción de pipewire.

De yapa: `export SHELL=/bin/sh` en plasma-start-qemu.sh. El aviso rojo de konsole («Could not find
'', starting '/bin/sh' instead») era real y no venía de /etc/passwd —que dice /bin/sh— sino de que
konsole lee $SHELL y este getty no es un login shell.

Y el barrido que encuentra esto sin hacer clic queda escrito en el runbook: cruzar los `import` de
los `.qml` instalados contra los módulos con `qmldir`. Además de éste destapó `org.kde.kscreenlocker`
y `org.kde.newstuff.core`, sin diagnosticar.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YGXe6mShYYw6V8ea1dQ13u
2026-09-03 21:57:38 +00:00
SergioandClaude Opus 5 4a68dfe761 qorpa D9: el canal de evidencia, cableado — la única forma de auditar el montón B
De un binario ajeno no hay fuente que leer. Lo único observable es lo que el
kernel le NIEGA y anota, y hasta acá ese canal existía en el build pero ninguna
instancia lo abría. `hammer qorpa run <id> --evidence` levanta el lector
(`harkaq-audit`) en el HOST —el audit no está namespaceado— antes de que arranque
la instancia, y al terminar imprime uno de tres estados. Los tres, medidos:

  HERMÉTICO     0 denegaciones Y el canario las respalda
  IMPURO        `touch /usr/INTRUSO; mkdir /opt/INTRUSO` →
                  fs.make_reg · /usr     fs.make_dir · /opt
  SIN EVIDENCIA quitándole las capabilities al lector. NO es «limpio»

**El canario es lo que hace que «cero denegaciones» valga algo:** un fichero
donde la política no alcanza; al leerlo, el kernel emite una denegación que
revela el `domain=` de ESTE dominio Landlock, un número que desde fuera no se
adivina. Sin él, `denials=[]` sería el instrumento callado.

**Dos condiciones estructurales, y se FALLA en vez de dar un veredicto vacío:**
con `nesting` no hay Landlock (D9 conflicto 1) ⇒ o anidás o auditás; y sin
`seal_image` la política es `rw /` ⇒ no hay NADA denegable y el veredicto sería
limpio por construcción, no por mérito. No es un defecto de la implementación:
**la evidencia sólo existe donde algo puede ser negado.**

**Un bug del propio instrumento, que sólo salió usándolo:** sin CAP_AUDIT_READ
el kernel RESPONDE que no (`NLMSG_ERROR`/EPERM) y el lector ignoraba esa
respuesta esperando una que no iba a llegar — 8 s por consulta, 16 s en su
compuerta. Como `qorpa run` lo despierta al terminar, moría por señal dentro de
la compuerta **sin emitir nada**: un «no» tardío se parecía demasiado a un
cuelgue. Ahora atiende el NLMSG_ERROR y dice su motivo en 2 s. Y si aun así el
veredicto sale vacío, se reporta con el código de salida del lector, que es el
único dato que queda.

Guardián: `scripts/qorpa/evidence-probe.sh`, con las tres aserciones. La 2 es la
que sostiene a la 1 — sin algo que TIENE que salir sucio, «HERMÉTICO» lo cumple
igual un canal muerto. Comprueba también las capabilities del lector, que **se
pierden en cada recompilación** y son la forma más probable de que el canal
muera en silencio.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QZjGRqvjWij9dew7NVFu4Q
2026-09-03 21:57:26 +00:00
SergioandClaude Opus 5 e04fdf4599 evidencia: el panel de Plasma con iconos, y el lanzador que NO abre por un módulo QML
Verificado en QEMU tras declarar `breeze-icons`: el panel pasa de «reloj solo» a completo —
kickoff, gestor de tareas, bandeja (notificaciones, volumen, teclado, red), reloj y mostrar
escritorio. Confirma que el panel nunca estuvo roto: no tenía iconos que dibujar. Y el mensaje
`kf.iconthemes: Icon theme "breeze" not found` desapareció del log.

⚠ CORRIJO una atribución del commit anterior (d69c437): dije que la barra derecha vacía de la
captura de GNOME era el mismo hueco de iconos, y NO lo es — `scripts/gnome/hydrate-gnome.sh` SÍ
hidrata `adwaita-icon-theme`, así que ese rootfs tenía tema. El hueco de GNOME es real pero está
en el PERFIL (`targets.toml`, que es lo que define la imagen enviable), no en aquella corrida;
la barra derecha vacía tiene otra causa, sin diagnosticar.

Y la segunda captura es un hallazgo nuevo, encontrado haciendo CLIC en el lanzador desde el
monitor de QEMU:

    kickoff/main.qml:191:25: Type FullRepresentation unavailable
    Header.qml:18:1: module "org.kde.coreaddons" is not installed

`kcoreaddons.toml` pasa `-DKCOREADDONS_USE_QML=OFF` ⇒ el módulo QML no se construye ⇒ **el menú
de aplicaciones no abre**. `yupana radio kcoreaddons` = 71: prenderlo es campaña de granja.

El barrido que lo generaliza (cruzar los `import` de los `.qml` instalados contra los módulos con
`qmldir` del rootfs) encontró además `org.kde.kscreenlocker` y `org.kde.newstuff.core`.

El runbook queda con las tres piezas que hacen falta en gioser, que no tiene ni ventana ni socat:
STAGE en el volumen (o EXDEV), monitor por socket unix desde python, y cómo hacer CLIC con un
ratón RELATIVO (fijar contra una esquina y moverse desde ahí).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YGXe6mShYYw6V8ea1dQ13u
2026-09-03 21:32:46 +00:00
Sergio ee21787713 estado: cosecha granja 2026-09-03T21:31:25Z — avance del árbol KDE 2026-09-03 21:31:26 +00:00
SergioandClaude Opus 5 d69c437051 escritorios: KDE y GNOME corrían SIN tema de iconos — el panel vacío no era el panel
Medido sobre los artefactos del cierre de cada imagen, contando qué `usr/share/icons/*/`
trae un `index.theme` (que es lo que convierte un directorio en un tema):

    escritorio-kde      sólo Breeze_Light y breeze_cursors — que son CURSORES
    escritorio-gnome    CERO, ni siquiera hicolor
    escritorio-cosmic   Cosmic + hicolor            <- el único que estaba bien
    escritorio-sway     CERO

Las dos capturas de QEMU de hoy ya lo mostraban y se leyeron como «arranca»:

- `plasma6-qemu-2026-09-03-kactivitymanagerd.png`: panel con el reloj y nada más. Los `.so`
  de los applets estaban TODOS instalados; lo que faltaba era qué pintar. `kickoff`,
  `systemtray`, `showdesktop` y `trash` SON un icono, así que sin tema quedan de ancho cero
  — el reloj se ve porque dibuja TEXTO. El log lo decía en una línea:
  `kf.iconthemes: Icon theme "breeze" not found.`
- `gnome-shell-qemu-2026-09-03-libs-compartidas.png`: barra superior con la fecha y el pill
  de espacios, y la DERECHA vacía — red, volumen y batería son iconos.

`breeze` (ya declarado) es el tema de WIDGETS y CURSORES; los ~14.000 iconos viven en
`breeze-icons`, receta aparte, sellada desde siempre y declarada por NADIE. Igual
`adwaita-icon-theme` en GNOME, que además trae los XCursor (su cabecera dice por qué:
sin tema de cursor no hay puntero visible con el cursor por software de virtio-gpu).

Es la figura de las fuentes y de `foot` otra vez: data de RUNTIME, ninguna arista de BUILD
la alcanza, y la métrica de clausura no la echa de menos porque mide lo declarado.

`hicolor-icon-theme` —el fallback obligatorio de freedesktop— se promueve al corpus para que
lo alcancen las cuatro imágenes: hash IDÉNTICO desde la cola y desde el corpus
(b3:98ad44a5), y sus 4 consumidores (adwaita-icon-theme, cosmic-icons, cosmic-app-library,
cosmic-launcher) miden el mismo hash antes y después ⇒ un solo artefacto, CERO rebuilds.

Cierre tras declararlos, todo sellado y sin deuda:
  kde 263/263 (+2) · gnome 158/158 (+2) · sway 173/173 (+1) · cosmic 133/133 (igual)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YGXe6mShYYw6V8ea1dQ13u
2026-09-03 21:18:17 +00:00
Sergio 08d27f0e2f estado: cosecha granja 2026-09-03T21:01:46Z — avance del árbol KDE 2026-09-03 21:01:46 +00:00
SergioandClaude Opus 5 50d1dbcc31 qorpa D3: packages se instala solo — el manifiesto deja de ser un adorno
Hasta acá el ADR afirmaba «el manifiesto es la verdad, el upper es caché»
mientras `recreate` confesaba en su propia salida que «instalarlos todavía es a
mano». Con eso el `upper` SÍ era el activo: un blob irreemplazable, que es justo
lo que hammer existe para no tener.

`hammer qorpa provision <id>` instala lo declarado, y **`recreate` lo llama
solo** (`--no-provision` para saltarlo).

Cuatro decisiones, cada una con su porqué:

- **El gestor se DETECTA** en la vista merged (apt, pacman, dnf, apk), no se
  configura: cada imagen trae el suyo. Y no se multiplexa detrás de un comando
  único —el `pmm` de Bedrock que el ADR rechaza—: se elige cuál correr.
- **`provision` ensancha la política y lo dice en la cara.** Instalar pide las
  tres cosas que una instancia bien declarada no tiene: red, root y la imagen
  sin sellar. Se ensancha SÓLO durante esa operación, el manifiesto no se toca
  y el siguiente `run` vuelve a lo escrito. En silencio sería lo que D7 prohíbe.
- **El registro vive FUERA del `upper`** (`provisioned.toml`): dentro se iría
  con la capa. Por eso `recreate` lo borra — un registro que afirma paquetes
  sobre una capa recién vaciada es la forma más pura del error de la regla 3.
- **Los nombres se validan y se comillan**: salen de un fichero que escribe una
  persona, así que `strace; rm -rf /` no llega al guión.

**Las dos manías que sólo salen provisionando de verdad:** el bootstrap de Arch
trae la mirrorlist ENTERA comentada (pacman muere con «no servers configured») y
el llavero sin inicializar (toda firma inválida). El guión pone el mirror geo
oficial avisando cuál, y hace `pacman-key --init && --populate` sólo si falta.
`apt` no necesita ni un workaround: es el dividendo del rango de subuid.

Probado de punta a punta en los dos gestores —apt sobre Ubuntu base, pacman
sobre el bootstrap de Arch—: instalan, el binario corre después con la red
apagada, y un `recreate` tira la capa y la deja igual. 27 tests verdes.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QZjGRqvjWij9dew7NVFu4Q
2026-09-03 21:00:10 +00:00
SergioandClaude Opus 5 7e1474d135 evidencia: Plasma 6 pintando en QEMU tras declarar kactivitymanagerd
Fondo Breeze + panel + reloj, sobre virtio-gpu con llvmpipe y SIN KVM (TCG puro:
gioser es un vServer sin virtualización anidada). Antes de 8df2559 esta misma imagen
daba pantalla negra con kwin=1 plasmashell=1.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0164nrZWZc78Mr2srrsnoM8U
2026-09-03 20:46:33 +00:00
SergioandClaude Opus 5 74fec60281 qorpa §Orden 6: pressure-vessel ANIDA bajo la jaula — sin cuenta, sin juego y sin pantalla
El paso 6 quedaba parcial por esta frase: «pressure-vessel con un juego real
sigue sin ejercitarse», porque el runtime sniper sólo se baja al instalar un
juego y eso pide credenciales. Era un techo falso: el depot está publicado y
ahora pineado, así que se coloca a mano y la pregunta que ordenaba D6 se
responde entera.

**La evidencia**, dentro de una instancia qorpa sobre Ubuntu base, con `nesting`
y la jaula puesta:

  os-release   Ubuntu 24.04.3 LTS  →  Steam Runtime 3 (sniper)
  ns de montaje  mnt:[4026532468]  →  mnt:[4026532526]
  /usr/lib/x86_64-linux-gnu        →  675 libs de sniper, libSDL2 incluida

Contenedor de Valve anidado dentro del nuestro, con el runtime real adentro.

**Y la concesión resultó de verdad:** con `nesting = false` el mismo comando
muere en `bwrap: Creating new namespace failed: Operation not permitted`. Queda
como guardián (`scripts/qorpa/pressure-vessel-probe.sh`), que exige las DOS
mitades — sin la negativa, «no salió sniper» lo cumpliría también un cuelgue.

Tres cicatrices del camino, todas en los comentarios:

1. **`ldd --version` es la comprobación equivocada** y es la primera que uno
   escribe: pressure-vessel importa la libc del host cuando es más nueva que la
   del runtime, así que ver la glibc de afuera adentro es lo correcto y no
   prueba nada. El veredicto es `os-release`.
2. **`SALIDA=$(timeout … qorpa run …)` se cuelga para siempre** aunque timeout
   mate al hijo: la sustitución no espera al PROCESO, espera a que se cierre el
   PIPE, y pressure-vessel deja descendientes con el fd abierto. A fichero
   termina y devuelve su código.
3. **Dos `run` seguidos sobre la misma instancia fallaban** con `Can't make
   overlay mount … Device or resource busy`. El kernel niega dos overlays vivos
   con el mismo `upper` porque eso corrompe la capa — o sea que el EBUSY es un
   guardián correcto a destiempo: la corrida anterior ya devolvió el prompt y su
   namespace no terminó de reaparse. `run` reintenta acotado y, si sigue tomado,
   dice la causa en vez de soltar el mensaje crudo de bwrap.

El punto 3 salió porque el guardián exige evidencia POSITIVA de la denegación:
con «no apareció sniper» habría dado OK tapando un fallo distinto.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QZjGRqvjWij9dew7NVFu4Q
2026-09-03 20:36:32 +00:00
SergioandClaude Opus 5 8df2559556 escritorio-kde: declarar kactivitymanagerd (plasmashell ABORTA sin él)
Arrancando la imagen KDE en QEMU: kwin toma el DRM, expone wayland-0, plasmashell
arranca… y la pantalla se queda EN NEGRO con los dos procesos vivos. El serial
repetía 'STATUS: kwin=1 plasmashell=1' durante minutos, que se lee como salud.

La causa estaba en el log de Qt, no en el estado de procesos:

  kde.plasmashell: Aborting shell load: The activity manager daemon
  (kactivitymanagerd) is not running.

No sale de la clausura de las 7 raíces porque NO es dep de build de nada: plasmashell
lo pide por D-Bus al arrancar. scripts/kde/plasma-start-qemu.sh ya lo lanzaba (l.188);
lo que faltaba era que el paquete entrara al rootfs. Ya estaba sellado — declararlo no
cuesta un build.

Misma figura que las raíces de runtime de GNOME (imports.gi.*): lo que se invoca por
bus es invisible al grafo de deps.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0164nrZWZc78Mr2srrsnoM8U
2026-09-03 20:31:28 +00:00
Sergio ea51dc833a estado: cosecha granja 2026-09-03T20:31:20Z — avance del árbol KDE 2026-09-03 20:31:20 +00:00
SergioandClaude Opus 5 abda7d3cc1 contrato de kernel: alta de pidfd, y los consumidores dejan de describir un bug ya arreglado
Handoff de vuelta desde tawasuyu (SDD 25 §8): las seis tareas del otro lado
estan cerradas, y eso dejo este contrato mintiendo de dos formas.

- Alta de `proceso-por-descriptor` (pidfd_open / pidfd_send_signal). Se usa
  desde W1 y no estaba declarada. `symbols` vacio a proposito: no depende de
  ningun CONFIG_*, es interfaz del core desde Linux 5.3. Al no estar en ningun
  perfil no se comprueba contra un .config; entra porque el contrato es la
  lista de lo que se USA, y si manana el minimo de kernel baja de 5.3, esta
  linea es la que lo dice.
- Los cinco consumidores de cgroup llevaban numero de linea y quedaron viejos
  con W1-W4. Van por nombre de funcion, y la regla de escritura queda arriba.
- Los `silent` de esos cinco describian el bug que W4 arreglo ("solo emite un
  warn!", "silencio total"). Un guardian que dice que hay un punto ciego donde
  ya no lo hay es peor que no tenerlo.
- `contabilidad-por-tarea` decia que sandokan sondea /proc para medir una
  unidad. Desde W2 eso sale del cgroup en O(1); el que sigue sondeando /proc es
  el monitor de procesos del SISTEMA, que es otro consumidor.

Y en SDD 25 §8, el estado real: las seis cerradas, mas W4.bis, donde el hallazgo
no fue el que este documento suponia. En arje el limite no se descartaba: NO SE
PEDIA. El camino `plain` -el de casi todas las Cards- no creaba cgroup, y
`apply_rlimits_to_cgroup` la llamaba solo shuma.

Verificado con el binario, no de memoria: `hammer kernel contract --list` carga
las 14 capacidades, y `hammer kernel contract --profile anfitrion-cards` sigue
en verde (11 exigidas presentes, 13 miradas).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GiYsdSwF1nxjBTTsa1empe
2026-09-03 20:27:05 +00:00
SergioandClaude Opus 5 099e84703f imagen: inyectar libffi/expat/bzip2 COMPARTIDAS desde el store
El cierre hidratado sólo trae los .a de estas tres (sus recetas canónicas son
--disable-shared), pero libgobject, libgirepository, libwayland-{client,server},
libp11-kit y libgjs salen con símbolos ffi_*, mesa entero (iris/swrast/kms_swrast,
libEGL, libgbm) con XML_* y freetype con BZ2_*. En el host eso resuelve contra el
sysroot Alpine del LAB —así que el artefacto sella y el perfil da 100%— y en la
imagen el loader de musl aborta:

  Error relocating /usr/lib/libgobject-2.0.so.0: ffi_call: symbol not found

gnome-shell moría con código 127 antes de exponer wayland-0, y con él login1,
Accounts, UPower, colord y wireplumber. Es el punto ciego que documenta
scripts/vigia-sonames.py, visto desde el lado de la imagen.

Con la inyección: 'compositor OK (wayland-0)' y el shell pinta (evidencia adjunta).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0164nrZWZc78Mr2srrsnoM8U
2026-09-03 20:16:51 +00:00
Sergio 03dc5633b0 estado: cosecha granja 2026-09-03T20:02:14Z — avance del árbol KDE 2026-09-03 20:02:15 +00:00
SergioandClaude Opus 5 3f560de8af qorpa D8: el pin de sniper verificado, y el pin deja de ser una cita
Cierra el ⚠ que quedaba en la tabla de D8. Tres cosas, y la del medio es la que
más duele.

1. **Sniper pineado, y por la versión correcta.** No se pinea «la última» sino
   la que `latest-container-runtime-depot.txt` dice que despliega el cliente de
   Steam — 3.0.20260805.254768. Pinear otra sería pinear algo que nadie corre.
   Se pinean DOS artefactos: la imagen (rootfs, 302 MB, 11196 ficheros) y el
   depot `SteamLinuxRuntime_sniper.tar.xz` con pressure-vessel adentro. El
   segundo es el que destraba el paso 6: ese runtime sólo se baja al instalar un
   juego (credenciales), y pineado se coloca a mano ⇒ pressure-vessel se puede
   ejercitar sin cuenta, sin juego y sin pantalla.

2. **Los digests estaban en prosa y ABREVIADOS, y eso no es un pin.** Cuando la
   poda se llevó las imágenes, `895661bd…` no alcanzó para volver a traerlas:
   hubo que ir a buscar los sha256 otra vez a upstream. Ahora enteros y
   verificados en `docs/state/qorpa-imagenes.toml`, con de qué lista salieron y
   **si esa lista está firmada** — que no todas: Ubuntu firma su SHA256SUMS,
   Arch firma el tarball pero no la lista, y Valve no firma nada.

3. **`--retry` de curl no cubría el fallo que de verdad pasa.** Los 302 MB de
   sniper murieron al 73% con `HTTP/2 INTERNAL_ERROR` y curl NO reintentó: sin
   `--retry-all-errors` sólo considera transitorios los timeouts y los 5xx. Y
   aun reintentando, sin `-C -` cada intento vuelve a empezar de cero. Con las
   dos banderas el mismo pull sobrevivió dos cortes más y llegó. El parcial ya
   no se borra al fallar (es lo que permite reanudar); es seguro porque quien
   decide es el sha256 de después, y `prune` ya lo barre.

De paso, dos comprobaciones en vez de suposiciones: el rootfs de sniper viene en
`files/` con un hermano `metadata` y el anclaje por estructura lo elevó solo
(tercera forma real de empaquetado), y traer el depot como rootfs FALLA en vez
de adivinar («no encuentro un rootfs en el archivo»).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QZjGRqvjWij9dew7NVFu4Q
2026-09-03 19:56:29 +00:00
Sergio 6794604a76 estado: cosecha granja 2026-09-03T19:31:25Z — avance del árbol KDE 2026-09-03 19:31:25 +00:00
Sergio 9700a87637 estado: cosecha granja 2026-09-03T19:01:22Z — avance del árbol KDE 2026-09-03 19:01:22 +00:00
Sergio 2ce8addfab estado: cosecha granja 2026-09-03T18:31:58Z — avance del árbol KDE 2026-09-03 18:31:58 +00:00
SergioandClaude Opus 5 bcd026f3b4 plan: el X11 de Firefox no era un muro — está detrás de CONFIG[MOZ_X11]
La tabla lo listaba como muro duro por los libxt/libxcomposite del APKBUILD. En el árbol
de Gecko todo el código X11 cuelga de CONFIG["MOZ_X11"] (widget/gtk/moz.build:131): es
una perilla de build y existen builds Wayland-only. El muro real es GTK3 + el toolchain
wasi. Cuarta corrección a esta tabla en el día; el método viejo contaba nombres de
paquete de Alpine y no miraba el árbol.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XB2iEmxeLZgzqNfhWChrLo
2026-09-03 18:19:47 +00:00
Sergio e2ef0df29f estado: cosecha granja 2026-09-03T18:02:49Z — avance del árbol KDE 2026-09-03 18:02:49 +00:00
Sergio 70c6690fa1 estado: cosecha granja 2026-09-03T17:32:04Z — avance del árbol KDE 2026-09-03 17:32:04 +00:00