From 28d98dc5f9f016b9dbe2894c0d45104dec43fecd Mon Sep 17 00:00:00 2001 From: Sergio Date: Fri, 4 Sep 2026 14:26:04 +0000 Subject: [PATCH] =?UTF-8?q?drenaje:=20med=C3=ADa=205=20de=207=20im=C3=A1ge?= =?UTF-8?q?nes=20y=20las=20otras=202=20desaparec=C3=ADan=20en=20silencio?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit targets.toml declara 7 perfiles; drenaje.json listaba 5. escritorio-cosmic (cola incoming-cosmic) y escritorio-sway (cola incoming-wlr) declaraban una cola que ningún grafo de GRAFOS contenía, así que cargar() devolvía None y --todos hacía `continue` pelado. Dos imágenes enteras fuera del artefacto sin dejar rastro, y los dos números —5 medidos, 7 declarados— no se cruzaban en ningún lado. Mismo olvido que ya costó 17 días de build-state-wlr.json congelado: la lista de grafos crece a mano y se queda atrás cuando se abre una cola. Tres cambios: - GRAFOS suma los grafos de cosmic y wlr. - Un perfil sin medir se anota en el artefacto (`sin_medir`), se grita por stdout y drenar.py sale 1. Regla 3 del repo: un ausente falla ruidosamente. - cosecha-cron deja de tragarse la salida; filtra las líneas ⚠ al log, que si no llegaban como un "falló" mudo que no dice cuál imagen falta. Medido: las 2 imágenes que nadie miraba estaban limpias, 0 en deuda. Ahora son 7/7 verificadas en vez de 5 verificadas y 2 supuestas. --- docs/state/drenaje.json | 21 ++++++++++++++++++++- scripts/drenar.py | 23 ++++++++++++++++++++++- scripts/farm/cosecha-cron.sh | 10 +++++++++- 3 files changed, 51 insertions(+), 3 deletions(-) diff --git a/docs/state/drenaje.json b/docs/state/drenaje.json index 9426b856..f476c9a8 100644 --- a/docs/state/drenaje.json +++ b/docs/state/drenaje.json @@ -20,6 +20,15 @@ "construibles_ya": [], "olas": [] }, + "escritorio-cosmic": { + "grafo": "docs/state/build-state-cosmic.json", + "nodos": 134, + "en_deuda": 0, + "ondas": 0, + "profundidad": 0, + "construibles_ya": [], + "olas": [] + }, "escritorio-gnome": { "grafo": "docs/state/build-state-gnome.json", "nodos": 158, @@ -46,6 +55,16 @@ "profundidad": 0, "construibles_ya": [], "olas": [] + }, + "escritorio-sway": { + "grafo": "docs/state/build-state-wlr.json", + "nodos": 174, + "en_deuda": 0, + "ondas": 0, + "profundidad": 0, + "construibles_ya": [], + "olas": [] } - } + }, + "sin_medir": [] } diff --git a/scripts/drenar.py b/scripts/drenar.py index b4a2eb9f..1385a5ba 100755 --- a/scripts/drenar.py +++ b/scripts/drenar.py @@ -28,8 +28,15 @@ import json, sys from pathlib import Path ROOT = Path(__file__).resolve().parent.parent +# UNA LÍNEA POR GRAFO, Y SE OLVIDAN (2026-09-04). Esta lista nació con corpus+kde+gnome y se quedó +# ahí mientras se abrían dos escritorios más: `escritorio-cosmic` (cola `incoming-cosmic`) y +# `escritorio-sway` (cola `incoming-wlr`) declaraban una cola que ningún grafo de la lista contenía, +# así que `cargar()` devolvía None y `--todos` los saltaba EN SILENCIO — 2 de las 7 imágenes fuera +# del drenaje sin que nada lo dijera. Es el mismo olvido que ya costó 17 días de +# build-state-wlr.json congelado (ver cosecha-cron.sh). Al abrir una cola nueva, se agrega ACÁ. GRAFOS = ["docs/state/build-state.json", "docs/state/build-state-kde.json", - "docs/state/build-state-gnome.json"] + "docs/state/build-state-gnome.json", "docs/state/build-state-cosmic.json", + "docs/state/build-state-wlr.json"] SEMILLA = ROOT / "docs/state/seed-edges.json" EN_DEUDA = ("debt", "never", "unhashable", "wanted") @@ -109,9 +116,18 @@ def todos_los_perfiles(): doc = {"schema": "hammer-drenaje/1", "nota": "DERIVADO del grafo de estado por scripts/drenar.py — no editar a mano.", "perfiles": {}} + sin_medir = [] for p in sorted(targets_mod.load()): ondas, deuda, ambito, cual = ondas_de(p) + # UN PERFIL QUE NO SE PUEDE MEDIR NO SE SALTA EN SILENCIO. Antes esto era un `continue` pelado + # y por eso dos imágenes enteras faltaban del artefacto sin dejar rastro: el JSON listaba 5 + # perfiles, targets.toml declaraba 7, y los dos números no se cruzaban en ningún lado. Ahora + # queda escrito EN el artefacto (`sin_medir`) y gritado por stdout — regla 3 del repo: un + # ausente falla ruidosamente, un vacío llega hasta el final diciendo que todo fue bien. if ondas is None: + sin_medir.append(p) + print(f" ⚠ {p:20} SIN MEDIR: ningún grafo de GRAFOS contiene su cola " + f"(¿falta build-state.py -- o la línea en GRAFOS?)") continue doc["perfiles"][p] = dict( grafo=cual, nodos=len(ambito), en_deuda=len(deuda), ondas=len(ondas), @@ -119,9 +135,14 @@ def todos_los_perfiles(): olas=[{"n": i + 1, "recetas": o} for i, o in enumerate(ondas)]) print(f" {p:20} {len(deuda):3} en deuda · {len(ondas):2} ondas · " f"onda 1 = {len(ondas[0]) if ondas else 0}") + doc["sin_medir"] = sin_medir salida = ROOT / "docs/state/drenaje.json" salida.write_text(json.dumps(doc, indent=1, ensure_ascii=False) + "\n") print(f" → {salida.relative_to(ROOT)}") + if sin_medir: + print(f" ⚠ {len(sin_medir)} de {len(targets_mod.load())} imágenes SIN MEDIR: " + f"{' '.join(sin_medir)}") + return 1 return 0 diff --git a/scripts/farm/cosecha-cron.sh b/scripts/farm/cosecha-cron.sh index c3b0f935..716d421a 100755 --- a/scripts/farm/cosecha-cron.sh +++ b/scripts/farm/cosecha-cron.sh @@ -202,7 +202,15 @@ if [ -x "$HAMMER" ]; then # Cola DERIVADA del grafo (P4): el orden de masticado por imagen, en ondas topológicas. No lanza # ningún build — sólo deja escrito qué conviene moler primero, para que la cola deje de ser una # lista escrita a mano. Barato (lee JSON, no hashea). - scripts/drenar.py --todos >/dev/null 2>&1 && echo " drenaje.json ✓" || echo " ⚠ drenar.py falló" + # NO se traga la salida entera: drenar.py sale 1 cuando alguna imagen quedó SIN MEDIR (una cola + # nueva sin su línea en GRAFOS), y con `>/dev/null 2>&1` eso llegaba al log como un "falló" mudo + # que no dice cuál. Se filtran las líneas ⚠, que son las únicas accionables. + if drenaje_out="$(scripts/drenar.py --todos 2>&1)"; then + echo " drenaje.json ✓" + else + echo " ⚠ drenar.py falló" + echo "$drenaje_out" | grep '⚠' | sed 's/^/ /' + fi # VIGÍA DE FUENTES (ADR 0013 §3). Desde que el mirror propio se consulta ANTES que upstream, # `hammer build` deja de avisar cuando una URL de terceros muere: sirve los bytes del mirror y # sigue. Eso es lo correcto para construir y sería CIEGO sin este contrapeso — las URLs se irían