yupana: drenar reckona honesto un perfil sin cierre (guardián GNOME)

drenar --perfil escritorio-gnome erraba 'no encontré un grafo (¿corriste
build-state.py?)' — mentira: el grafo GNOME existe, pero NINGUNA raíz del perfil
(mutter/gnome-shell/gdm) está autorada ⇒ 0 nodos etiquetados con el perfil, y la
comprobación por etiqueta en cargar() fallaba. Dos correcciones:
  · cargar(): una cola NO-corpus identifica su grafo unívocamente ⇒ matchear por
    cola; la etiqueta sólo desambigua dentro de corpus (perfiles solapados).
  · main(): ámbito vacío con perfil ≠ 'imagen completa' — es 'SIN CIERRE todavía:
    0 raíces autoradas', y apunta a autorar top-down.
KDE (162 sellados) y corpus (769/4-deuda) sin regresión. El yupana-gnome queda
armado en las 4 capas: objetivo, radio/grafo, keystones y drenar.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-24 14:23:12 -04:00
co-authored by Claude Opus 4.8
parent 9a028ba04f
commit afd867ea51
+15
View File
@@ -54,6 +54,14 @@ def cargar(perfil):
d = json.loads(p.read_text()) d = json.loads(p.read_text())
if cola not in (d.get("by_queue") or {}): if cola not in (d.get("by_queue") or {}):
continue continue
# Una cola NO-corpus identifica su grafo unívocamente (incoming-kde/gnome sólo viven en su
# propio grafo), así que basta con que la cola coincida. La comprobación por ETIQUETA de perfil
# sólo desambigua dentro de `corpus` (donde varios perfiles se solapan). Sin este atajo, un
# perfil cuyas RAÍCES aún no están autoradas (0 nodos etiquetados, p.ej. escritorio-gnome
# recién arrancado) no hallaba su grafo y drenar erraba "¿corriste build-state.py?" en vez de
# reckonar honestamente un perfil todavía sin cierre.
if cola != "corpus":
return d, f
if perfil is None or any(perfil in (r.get("perfiles") or []) for r in d["nodes"].values()): if perfil is None or any(perfil in (r.get("perfiles") or []) for r in d["nodes"].values()):
return d, f return d, f
return None, None return None, None
@@ -140,6 +148,13 @@ def main():
print(f"== drenaje de {etiqueta} ({cual})") print(f"== drenaje de {etiqueta} ({cual})")
print(f" {len(ambito)} nodos en ámbito · {len(deuda)} en deuda " print(f" {len(ambito)} nodos en ámbito · {len(deuda)} en deuda "
f"({len(ambito)-len(deuda)} ya sellados)") f"({len(ambito)-len(deuda)} ya sellados)")
if perfil is not None and not ambito:
# Ámbito vacío = ninguna raíz del perfil está autorada ⇒ el perfil NO tiene cierre todavía
# (top-down sin arrancar). Distinto de "completa": completa tendría nodos sellados en ámbito.
# Puede haber recetas SUELTAS en la cola (leaves) que ninguna raíz alcanza aún.
print(f" perfil SIN CIERRE todavía: 0 raíces autoradas — autorá desde las raíces "
f"declaradas en targets.toml (top-down feature-minimal), no al revés.")
return 0
if not deuda: if not deuda:
print(" nada que drenar: la imagen está completa.") print(" nada que drenar: la imagen está completa.")
return 0 return 0