SDD 30: el doc al día con §4a y §4c — incluido el hallazgo de los dos compat sin perfil

This commit is contained in:
Sergio
2026-09-12 11:09:01 +00:00
parent 1b56b16402
commit 30c8d18924
+52 -8
View File
@@ -1,6 +1,6 @@
# SDD 30 — Los servicios que trae un paquete
> **Estado:** §3 IMPLEMENTADO (2026-09-12), §4 y §5 abiertos. Nace de una pregunta directa:
> **Estado:** §3 y §4a IMPLEMENTADOS (2026-09-12), §4b/§4c y §5 abiertos. Nace de una pregunta directa:
> *«los paquetes que tienen sus servicios para systemd, openrc u otros, ¿ya saben empaquetarse en
> takana con arje?»*. La respuesta medida era **no**, y este documento dice exactamente qué faltaba,
> qué se cerró y qué queda.
@@ -116,9 +116,31 @@ afirmación del SDD 06 queda marcada como falsa aquí.
## 4. Lo que queda: del card a la imagen
**(a) El perfil habilita.** `targets.toml` lista raíces por perfil; falta el `services = [...]` que
diga cuáles de los servicios declarados arrancan en esa imagen. Sin esto, «declarado» y «arranca»
siguen siendo lo mismo, que es justo el error que `arje-absorb` evita.
**(a) El perfil habilita — HECHO.** `servicios = [...]` por perfil en `targets.toml` (se hereda como
`paquetes`), y `scripts/targets.py --services <perfil>` resuelve label → receta → exec cruzando las
declaraciones del corpus con la membresía de perfil de los grafos de estado (los CINCO: el del
corpus más los de cada cola, porque las recetas de un escritorio viven en `recipes/incoming-<x>/` y
su membresía está en el grafo de SU cola).
Lo que más valió no fue resolver, fue **la comprobación inversa**: avisar de los paquetes que están
en la imagen, TRAEN un demonio y el perfil no arranca. Y encontró algo el primer día:
> **`arje-logind-compat` y `arje-polkit-compat` estaban en CERO perfiles** — y sin embargo
> `scripts/gnome/qemu-desktop-image.sh` los copia al rootfs a mano y el de COSMIC hace `exit 1` si
> falta logind-compat. Dos binarios imprescindibles, presentes en la imagen y ausentes del destino
> declarado. Es la misma forma del agujero de `foot`, encontrada esta vez por una comprobación en
> vez de por una imagen inusable. Corregido: son raíces de `escritorio-gnome` (los dos) y de
> `escritorio-cosmic` (sólo logind-compat; sus scripts no nombran polkit-compat).
**Precedencia, y no es un detalle:** una RAÍZ del perfil está en el perfil por definición, aunque el
grafo todavía no lo diga. `build-state.json` es DERIVADO de `targets.toml` y lo regenera el cron cada
30 min; preguntarle primero al derivado haría que añadir una raíz se leyera como error hasta la
siguiente cosecha — castigar al que arregla el manifiesto.
El guardián se prueba solo: `scripts/targets.py --selftest` corre 7 casos —**el primero es el
CONTROL, que tiene que pasar en verde**— incluidos «dos recetas del mismo perfil declaran el mismo
label» (ERROR) y «el mismo label en dos colas distintas» (NO es colisión: `upower` existe
legítimamente en incoming-gnome y en incoming-kde, y son la misma unidad en dos imágenes).
**(b) El emisor, y la trampa del sidecar rancio.** `seal_product_rootfs()` sirve a las dos vetas
(`product` desde recetas locales, `product_from_repo` desde el repo firmado) y **sólo una tiene el
@@ -139,8 +161,26 @@ que el árbol nuevo hay que compararlo contra el viejo antes de darlo por bueno.
que bootea en QEMU sin ese control es exactamente cómo se cuela una regresión que nadie ve.
Hasta entonces `product_seed_card()` **sigue usando la constante**, a propósito y dicho acá.
**(c) Los ocho de GNOME.** Convertir `gnome-start-qemu.sh` en cards es el caso que prueba el diseño
de verdad, y depende de §5.
**(c) Los de GNOME: DECLARADOS, no todavía arrancados por arje.** Las nueve unidades que
`gnome-start-qemu.sh` levanta con `&` están declaradas en sus recetas y habilitadas en el perfil
(`dbus-system`, `logind-compat`, `polkit-compat`, `accounts-daemon`, `upowerd`, `colord` de sistema;
`pipewire`, `pipewire-pulse`, `wireplumber` de sesión). Verificado que ninguna movió su hash: 9/9
idénticos a los que los grafos ya registraban.
Dos cosas que NO son transcripción y hay que saber:
1. **`dbus-daemon --fork` no se puede traducir tal cual.** arje supervisa al **hijo directo**:
`Type=forking` no existe en su modelo, así que un daemon que forkea y sale deja a arje viendo
morir al padre con éxito y reencarnándolo para siempre. La Card usa `--nofork --nopidfile`.
2. **`scope = "system" | "session"`.** No es cosmético: decide DÓNDE va la Card. Las de sesión
necesitan `XDG_RUNTIME_DIR` y un usuario logueado, así que en el `genesis` arrancarían antes de
que exista ninguna de las dos cosas. Y su destino **no está resuelto fuera de mirada** — ahí las
arma el compositor (`mirada-compositor/src/session.rs`, `requires = [wayland_floor()]`, entregadas
a PID 1 por `RunCard`), pero mutter y kwin no tienen esa integración. `--services` avisa por cada
una: el hueco queda contado, no omitido.
Falta el paso final: que el ensamblado de la imagen ponga las cards de sistema en el `genesis` en vez
de que el script las lance con `&`. Eso ya es §4b (el emisor) y el arranque supervisado en QEMU.
## 5. El hueco que no es nuestro: no hay readiness
@@ -165,8 +205,12 @@ arriba en arje.
| Fuera de `hash_inputs` (medido, hash de openssh sin mover) | ✅ |
| Equivalencia receta → card hardcodeada de sshd | ✅ test en `takana-bootstrap` |
| `openssh` declara su servicio | ✅ `recipes/openssh.toml` |
| El perfil habilita (`targets.toml`) | §4a |
| El perfil habilita (`servicios` + `targets.py --services`) | §4a |
| Guardián con roturas a propósito + control (`--selftest`) | ✅ 7/7 |
| Los dos compat que no estaban en ningún perfil | ✅ corregido §4a |
| Los 9 de GNOME declarados y habilitados (hash sin mover, 9/9) | ✅ §4c |
| Emisor desde el sidecar + re-sellado de openssh | ◑ §4b (con control de reproducibilidad) |
| Los ocho demonios de GNOME como cards | ◻ §4c |
| Que la imagen los arranque por arje y no por el script `&` | ◻ §4c, depende de §4b |
| `escritorio-cosmic`: auditar su `cosmic-start.sh` y habilitar | ◻ hoy sale con 5 AVISO |
| Derogar `/etc/hammer/init.d/*.rule` en el `.swm` | ◻ §3.2 |
| Readiness por unidad en arje | ◻ §5 — río arriba |