docs(sdd33): el §4 deja de ser pseudocódigo — el `h` que daba por existente ya se calcula
El §4 decide rearmar los medios por el CIERRE y no por el calendario, y su pseudocódigo empieza con `h = hash de la clausura del perfil`. Ese `h` **no existía**: el grafo sabía el hash de cada artefacto y nadie resumía el conjunto, así que el §4 era inejecutable sin que el documento lo dijera. Ya se calcula y se publica cada ciclo. Entra también la trampa, que es lo que habría dado cierres falsos en silencio: **la clausura se calcula en el grafo de SU COLA**, porque `base` son 86 nodos en el grafo del corpus y 78 en el de KDE — los 8 que «faltan» están ahí con otra membresía, ya que el nombre `openssl` es la variante de la cola. De ahí el corolario que hay que respetar al usar el número: un digest sólo es comparable consigo mismo a lo largo del tiempo. Y el pendiente queda ACOTADO en vez de abierto: falta que la imagen publicada declare de qué clausura salió, y hoy encima no hay imágenes publicadas, así que no hay con qué comparar. El día que se publique una, basta con que lleve su `cierres.json` al lado. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Semántico sayk'uy
Mana ima sutichaypas t'ikrakurqanchu: qillqalla, yachachiylla utaq willaylla t'ikrakurqan.
1 qillqakuna · +34 −3
diff --git a/docs/33-versionado-y-relojes.md b/docs/33-versionado-y-relojes.md
index 7d98f9d9..9574e058 100644
--- a/docs/33-versionado-y-relojes.md
+++ b/docs/33-versionado-y-relojes.md
@@ -47,7 +47,7 @@ que el sitio empiece a mentir — que es lo que ya pasó con un sha256 pegado a
|---|---|---|---|
| **cosecha** | 30 min | trae del worker lo que se selló, siembra recetas, regenera el estado y commitea | **anda** (`scripts/farm/cosecha-cron.sh`) |
| **río arriba** | 1 día | pregunta a cada fuente si hay algo más nuevo que el pin, y deja un informe | **la pieza implementada hoy** |
-| **medios** | cuando el cierre cambie | rearma imágenes e instaladores y publica | **falta** |
+| **medios** | cuando el cierre cambie | rearma imágenes e instaladores y publica | **la MITAD anda**: el hash de la clausura se calcula y se publica cada ciclo (§4); falta que la imagen publicada declare de cuál salió |
### 2.1 Río arriba — `scripts/fuentes/upstream-vigia.py`
@@ -141,8 +141,39 @@ por cada perfil publicado:
Y **publicar es lo último**, después de los arneses, nunca antes: hoy son 25 comprobaciones del
banco, 13 del salto y 13 del USB, y las tres corren sin intervención.
-⚠ **El paso que falta y hay que escribir: la imagen publicada tiene que declarar de qué clausura
-salió.** Sin eso, la comparación de arriba no se puede hacer y el cron vuelve a ser un calendario.
+✅ **La primera mitad está construida** (2026-10-10): `scripts/cierre-perfiles.py`, cableado al
+latido y publicando `docs/state/cierres.json`. Ese `h` **no existía** — el grafo sabía el hash de
+cada artefacto y nadie resumía el conjunto — y es lo que convertía el §4 en un pseudocódigo
+inejecutable. No construye nada: lee los grafos que el latido acaba de regenerar, en menos de un
+segundo. ⇒ **el `git log` de `cierres.json` ES la señal «este perfil se movió, su imagen quedó
+rancia»**, que hasta hoy no se podía saber sin rearmar para averiguarlo.
+
+| | |
+|---|---|
+| base | 86 nodos | cli | 153 | escritorio-cosmic | 294 |
+| escritorio-gnome | 359 | escritorio-kde | 431 | escritorio-mirada | 41 |
+| escritorio-sway | 281 | metal-tigerlake | 5 | servidor | 186 |
+| servidor-minimo | 117 | | | | |
+
+⚠ **La trampa, medida, que habría dado cierres falsos en silencio: la clausura se calcula en EL
+GRAFO DE SU COLA.** El perfil `base` tiene **86 nodos en `build-state.json` y 78 en
+`build-state-kde.json`**; los 8 que «faltan» —dbus, gmp, libgcrypt, libgpg-error, libnl, mpfr,
+openssl, util-linux— sí están en el grafo de KDE, pero con `perfiles=['escritorio-kde']`, porque
+ahí el nombre `openssl` es la variante de `incoming-kde/` y no la del corpus. Corolario: **un
+digest sólo es comparable consigo mismo a lo largo del tiempo**, nunca entre perfiles ni entre
+grafos. El control lo demuestra: moviendo el hash de `bash` en el grafo del corpus se mueven
+exactamente `base`, `cli`, `servidor` y `servidor-minimo`, y los cuatro escritorios quedan quietos.
+
+⚠ **Y el paso que SIGUE faltando: la imagen publicada tiene que declarar de qué clausura salió.**
+Sin eso la comparación «h ≠ el hash de la imagen publicada» no se puede cerrar y el cron volvería a
+ser un calendario. Hoy además **no hay imágenes publicadas** —el sitio no ofrece descargas—, así
+que no hay con qué comparar: lo que está listo es el lado nuestro, y el día que se publique una
+imagen basta con que lleve su `cierres.json` al lado.
+
+Dos cosas que este número NO resume, y las dos a propósito: un cierre **incompleto** no se hashea
+(un digest sobre una clausura parcial diría que la imagen cambió cuando lo que cambió es cuánto
+sabemos), y un nodo **`ajeno`** —xwayland, rust-toolchain-bin, steam-runtime-sniper— entra por
+NOMBRE pero su contenido queda fuera, porque no lo construimos nosotros.
## 5. Lo que este documento NO decide