gioser

sergio/takana

> Una distribución Linux construida con un laboratorio funcional y hermético en el > sótano, y una terminal mutable, clásica y anárquica en el piso de arriba — diseñada > desde el suelo para que una IA programadora entienda, modifique y co…

TOML 1534Shell 199Rust 109Markdown 993713 Sutichaykuna

yupana: rename khipu→yupana — el registro es el khipu, la yupana es el ábaco que reckona sobre él

`khipu` colisionaba con una app de tawasuyu. En vez de un nombre a dedo, el
significado más profundo RESUELVE la colisión: en los Andes el khipu GUARDABA
(el registro de nudos) y la yupana CALCULABA sobre él (el ábaco). Acá igual, y
la distinción es arquitectura:

  docs/state/build-state.json = el KHIPU  (el registro firme: nudos y cuerdas)
  scripts/yupana.py           = la YUPANA (el motor que reckona: radio, ondas, clausura)

Nunca fue del todo un khipu lo que construimos; era la yupana. La colisión
empujó al nombre más exacto.

git mv preserva historia. Verificado tras el rename: `yupana radio libdrm` da
126/132/[kde,mirada]; el guardián de regresión pasa; build-state importa yupana
y --check sigue en 0. Cero referencias `khipu` colgadas en código.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

e4a0237b6dc1a62b3ca4a4897f91574969f5528a · ruwaq sergio · (3 killa ñawpaq) · tayta 42f198f97 · kay commitpi sach'ata qhaway

Semántico sayk'uy · 23

scripts/build-state.py

  • ukhunpi t'ikrakurqan fn main

scripts/khipu.py

scripts/test-khipu-radio.py

scripts/test-yupana-radio.py

scripts/yupana.py

5 qillqakuna · +293 −289

diff --git a/scripts/build-state.py b/scripts/build-state.py
index 02118fbd..95ccfcc2 100755
--- a/scripts/build-state.py
+++ b/scripts/build-state.py
@@ -40,7 +40,7 @@ from pathlib import Path
 
 sys.path.insert(0, str(Path(__file__).resolve().parent))
 import targets as targets_mod
-import khipu  # el motor de dependencias INVERSAS: cruza TODAS las colas (ver por qué en su cabecera)
+import yupana  # la YUPANA: el motor de dependencias INVERSAS que cruza TODAS las colas (ver su cabecera)
 
 ROOT = Path(__file__).resolve().parent.parent
 os.chdir(ROOT)
@@ -224,11 +224,11 @@ def main():
     # MEMBRESÍA DE PERFIL y DEPENDIENTES INVERSOS: los dos se calculan sobre el GRAFO ENTERO (todas
     # las colas del disco), NO sobre los nodos que esta vista cargó. Es la corrección del bug de
     # libdrm: en la corrida del corpus, `perfiles` llegaba a decir `['escritorio-mirada']` sobre un
-    # paquete que sostiene KDE entero, porque no veía las recetas de incoming-kde. khipu las ve
-    # siempre y resuelve sibling-first ⇒ el nodo se identifica por (cola, nombre). Ver khipu.py.
-    todas = khipu.cargar_colas()
-    memb = khipu.membresia(todas, cargar_perfiles({q for q in todas}))  # TODOS los perfiles, no sólo los de esta vista
-    rev = khipu.dependientes(todas)
+    # paquete que sostiene KDE entero, porque no veía las recetas de incoming-kde. yupana las ve
+    # siempre y resuelve sibling-first ⇒ el nodo se identifica por (cola, nombre). Ver yupana.py.
+    todas = yupana.cargar_colas()
+    memb = yupana.membresia(todas, cargar_perfiles({q for q in todas}))  # TODOS los perfiles, no sólo los de esta vista
+    rev = yupana.dependientes(todas)
     for n, r in recs.items():
         clave = (r.get("queue", "corpus"), n)
         r["perfiles"] = sorted(memb.get(clave, ()))
diff --git a/scripts/test-khipu-radio.py b/scripts/test-yupana-radio.py
similarity index 91%
rename from scripts/test-khipu-radio.py
rename to scripts/test-yupana-radio.py
index 934a87c9..bd9c6509 100755
--- a/scripts/test-khipu-radio.py
+++ b/scripts/test-yupana-radio.py
@@ -1,17 +1,17 @@
 #!/usr/bin/env python3
-# test-khipu-radio.py — REGRESIÓN del bug de libdrm (2026-07-22). No es un test cualquiera: es la
+# test-yupana-radio.py — REGRESIÓN del bug de libdrm (2026-07-22). No es un test cualquiera: es la
 # cicatriz. Si el radio de un paquete compartido entre colas vuelve a medirse sobre una sola cola,
 # esto falla. La propiedad que blinda: el radio SIEMPRE cruza todas las colas del disco.
 import sys, subprocess
 from pathlib import Path
 ROOT = Path(__file__).resolve().parent.parent
 sys.path.insert(0, str(ROOT / "scripts"))
-import khipu
+import yupana
 
 def main():
-    colas = khipu.cargar_colas()
-    rev = khipu.dependientes(colas)
-    memb = khipu.membresia(colas)
+    colas = yupana.cargar_colas()
+    rev = yupana.dependientes(colas)
+    memb = yupana.membresia(colas)
     fallos = []
 
     # 1) libdrm lo consumen recetas de MÁS de una cola (corpus + incoming-kde). Medirlo sobre una
diff --git a/scripts/khipu.py b/scripts/yupana.py
similarity index 87%
rename from scripts/khipu.py
rename to scripts/yupana.py
index f76c7891..c195d567 100755
--- a/scripts/khipu.py
+++ b/scripts/yupana.py
@@ -1,12 +1,16 @@
 #!/usr/bin/env python3
-# khipu.py — el KHIPU del build: el registro vivo del estado de la distro y el motor de consultas
-# sobre su grafo. Es la BASE metodológica; el resto de los scripts de estado son sus órganos.
+# yupana.py — la YUPANA del build: el ábaco que RECKONA sobre el estado de la distro.
 #
-# QUÉ ES UN KHIPU. El dispositivo andino de contabilidad: cuerdas anudadas que registran cantidades
-# y relaciones. Este es el khipu del build — cada receta es un nudo, cada dep una cuerda, y el
-# conjunto es la única fuente de verdad sobre QUÉ hay, QUÉ falta, QUIÉN depende de quién y A QUIÉN
-# rompo si toco algo. Antes ese saber vivía disperso (en la cabeza, en `grep`, en docs que
-# envejecen) y cada medición a mano mentía distinto.
+# DOS OBJETOS ANDINOS, DOS ROLES. En los Andes el khipu GUARDABA (cuerdas anudadas que registran
+# cantidades y relaciones) y la yupana CALCULABA sobre ese registro (el ábaco inca). Acá es igual y
+# la distinción es la arquitectura, no adorno:
+#     · `docs/state/build-state.json` es el KHIPU — el registro firme y versionado: los nudos
+#       (recetas) y las cuerdas (deps), la única fuente de verdad de QUÉ hay y QUÉ falta.
+#     · este módulo es la YUPANA — el motor que reckona sobre el khipu: a QUIÉN rompo si toco algo
+#       (radio), qué imágenes dependen de un nudo (perfiles), en qué orden masticar (ondas).
+# Es la BASE metodológica y la PUERTA ÚNICA; el resto de los scripts de estado son sus órganos.
+# Antes este saber vivía disperso (en la cabeza, en `grep`, en docs que envejecen) y cada medición
+# a mano mentía distinto.
 #
 # POR QUÉ EXISTE ESTE FICHERO Y NO SÓLO build-state.py. El 2026-07-22 un cambio a `libdrm`
 # (default_library=both, para gtk4) invalidó 118 recetas KDE. El radio se midió contra
@@ -24,7 +28,7 @@
 # capas). Por eso los nodos se identifican por PAR `(cola, nombre)`, no por nombre: `corpus/fontconfig`
 # y `incoming-kde/fontconfig` son nudos distintos y romper uno no rompe a los consumidores del otro.
 #
-# khipu es la PUERTA ÚNICA de la metodología. Sus verbos son los órganos del ciclo, en el orden en
+# yupana es la PUERTA ÚNICA de la metodología. Sus verbos son los órganos del ciclo, en el orden en
 # que se usan (el mismo que la cadena del plan docs/plan-catalogo-objetivo.md):
 #
 #   radio <receta>    ¿a QUIÉN rompo si toco esto? (nativo; cruza TODAS las colas) ← ANTES de cambiar nada
@@ -35,9 +39,9 @@
 #   triaje            clasificar la frontera            → triaje.py
 #   drenar [--perfil] el orden de masticado, en ondas   → drenar.py
 #
-# Uso:  scripts/khipu.py radio <receta> [--json]
-#       scripts/khipu.py estado [--kde] | drenar [--todos] | triaje | frontera <perfil> | objetivo
-# Como módulo:  from khipu import cargar_colas, membresia, dependientes, resolver
+# Uso:  scripts/yupana.py radio <receta> [--json]
+#       scripts/yupana.py estado [--kde] | drenar [--todos] | triaje | frontera <perfil> | objetivo
+# Como módulo:  from yupana import cargar_colas, membresia, dependientes, resolver
 import glob, json, os, subprocess, sys, tomllib
 from pathlib import Path
 
@@ -189,7 +193,7 @@ def _por_cola(nodos):
     return dict(Counter(q for q, _ in nodos))
 
 
-# Delegación a los órganos: khipu es la puerta, cada script sigue siendo el músculo. Se delega por
+# Delegación a los órganos: yupana es la puerta, cada script sigue siendo el músculo. Se delega por
 # subproceso (no import) para no acoplar sus ciclos de vida ni sus flags — cada uno evoluciona solo.
 ORGANOS = {
     "estado":   ["build-state.py"],