> 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…
el OCTAVO lugar: nadie vigilaba que la receta no se quedara DETRÁS de su propio paquete
El guardián de coherencia de la bóveda miraba siete lugares y todos preguntaban lo
mismo: ¿la pieza ESTÁ? Ninguno preguntaba si la que está es la de hoy — y ésa es la
forma en que se rompió el §7.terdecies: `boveda` se quedó en `6f0408d40` mientras el
arreglo de `pacha-boveda-llimphi` se publicaba en `4f2b5eac7`. El artefacto sella,
reproduce, entra a las cuatro imágenes y abre su ventana; lo único que falla es que esa
ventana dice «se abre al entrar a la sesión» cuando el llavero es el que falló. Un
mensaje equivocado no tiene código de salida.
La pregunta se hace en la forma que NO envejece: no se busca el símbolo `SeedDeSesion`
—renombrarlo dejaría al guardián mintiendo en verde— sino que se le pregunta a git si
hay commits en `main` que TOQUEN el paquete que la receta construye y que el pin no
tenga. Y no dice «subí el pin»: dice cuántos y cuáles, porque un pin viejo puede ser
deliberado y «estás atrás» sin decir de qué no sirve para decidir.
Control positivo: el pin tiene que ser ancestro de `main`; si no lo es, el `pin..main`
da cero por una razón que no es «al día» y el verde sería falso.
Control negativo (`--negative-control-deriva`): se finge el pin viejo y se exige que lo
vea. Es el único de los cinco cuyo «mal» ya ocurrió de verdad — y al correrlo nombra
exactamente el commit que faltaba.
boveda.toml pineada (6f0408d40) está DETRÁS de 2 commit(s) que tocan su propio paquete
· pacha-boveda-llimphi: 4f2b5eac7 fix(pacha): «el llavero falló» se contaba como…
· pacha-llavero: 4f2b5eac7 fix(pacha): «el llavero falló» se contaba como…
diff --git a/scripts/test-atuq-boveda-coherente.py b/scripts/test-atuq-boveda-coherente.py
index 1e1dd6bf..75e6f65b 100755
--- a/scripts/test-atuq-boveda-coherente.py
+++ b/scripts/test-atuq-boveda-coherente.py
@@ -5,6 +5,7 @@
python3 scripts/test-atuq-boveda-coherente.py --negative-control
python3 scripts/test-atuq-boveda-coherente.py --negative-control-perfil
python3 scripts/test-atuq-boveda-coherente.py --negative-control-sembrador
+ python3 scripts/test-atuq-boveda-coherente.py --negative-control-deriva
── QUÉ MIRA, Y POR QUÉ ESTE GUARDIÁN EXISTE APARTE ───────────────────────────────────────────
Una extensión de `atuq` está enchufada en SIETE lugares distintos, y ninguno da error si falta:
@@ -306,6 +307,76 @@ def revisar_el_sembrador(sin_sembrador=None):
f"bóveda está declarada y NADIE puede abrirla — `locked:true` para siempre")
+# ── 11. EL OCTAVO LUGAR: ¿la receta está pineada DETRÁS de su propio paquete? ─────────────────
+# Los siete de arriba preguntan si cada pieza ESTÁ. Éste pregunta si la pieza que está es la de
+# HOY, y es la forma de fallo que costó el §7.terdecies: `boveda` se quedó en `6f0408d40` mientras
+# el arreglo de `pacha-boveda-llimphi` se publicaba en `4f2b5eac7`. Nada falló. El artefacto sella,
+# reproduce, entra a las cuatro imágenes, abre su ventana — y esa ventana dice «La bóveda está
+# cerrada. Se abre al entrar a la sesión», que es verdad si no hay seed sembrada y MENTIRA si el
+# llavero falló. Un mensaje equivocado no tiene código de salida.
+#
+# Es el mismo cuerpo del §7.quinquies —el cable tiene dos puntas en dos repos y se desincronizan en
+# silencio— pero un piso más abajo: allá la punta que se quedaba atrás era el HOST y el síntoma era
+# «verbo desconocido»; acá es la receta de la app y el síntoma es un texto.
+#
+# La pregunta se hace en la forma que NO envejece: no se busca un símbolo (`SeedDeSesion` se puede
+# renombrar y entonces el guardián miente en verde), se le pregunta a git si hay commits en `main`
+# que TOQUEN el paquete que la receta construye y que el pin no tenga. Cero commits ⇒ la receta
+# está al día. N commits ⇒ se nombran, porque «estás atrás» sin decir de qué no sirve para decidir.
+#
+# ⚠ Esto NO dice que haya que subir el pin siempre: un pin viejo puede ser deliberado. Dice que la
+# distancia EXISTE y cuál es, que es justo lo que nadie sabía el 2026-09-21.
+#
+# El control POSITIVO es que el pin sea ancestro de `main`: si no lo es, el `pin..main` da cero por
+# una razón que no es «al día» —un pin de otra rama, un clon sin fetch— y el verde sería falso.
+PAQUETES_DE = {
+ "recipes/boveda.toml": [
+ "shared/pacha/pacha-boveda-llimphi", # la app: su ventana es la que dio el mensaje falso
+ "shared/pacha/pacha-llavero", # el crate compartido donde vivía la causa
+ ],
+ "recipes/shuma-pregunta.toml": ["02_ruway/shuma/shuma-pregunta"],
+}
+
+
+def commits_por_delante(commit, ruta):
+ r = subprocess.run(
+ ["git", "-C", TAWASUYU, "log", "--oneline", f"{commit}..main", "--", ruta],
+ capture_output=True, text=True,
+ )
+ return [l for l in r.stdout.splitlines() if l.strip()]
+
+
+def revisar_la_deriva(pin_forzado=None):
+ if not os.path.isdir(os.path.join(TAWASUYU, ".git")):
+ mal(f"no hay clon de tawasuyu en {TAWASUYU}: el octavo lugar queda SIN COMPROBAR "
+ f"(se cambia con TAWASUYU=/ruta)")
+ return
+ for rel, rutas in PAQUETES_DE.items():
+ receta = os.path.join(ROOT, rel)
+ commit = pin_forzado or pin_de(receta)
+ if not commit:
+ mal(f"{rel} no pinea ningún commit")
+ continue
+ if subprocess.run(["git", "-C", TAWASUYU, "merge-base", "--is-ancestor", commit, "main"],
+ capture_output=True).returncode != 0:
+ mal(f"CONTROL ROTO: el pin {commit[:9]} de {rel} no es ancestro de `main` en el clon "
+ f"({TAWASUYU}) — puede faltar un `git fetch`, o ser otra rama. Un «cero commits "
+ f"por delante» calculado así no prueba nada")
+ continue
+ atrasados = []
+ for ruta in rutas:
+ atrasados += [(ruta, c) for c in commits_por_delante(commit, ruta)]
+ if not atrasados:
+ bien(f"{os.path.basename(rel)} pineada ({commit[:9]}) está al día con "
+ f"{', '.join(os.path.basename(r) for r in rutas)}")
+ else:
+ mal(f"{os.path.basename(rel)} pineada ({commit[:9]}) está DETRÁS de "
+ f"{len(atrasados)} commit(s) que tocan su propio paquete — el artefacto sella y "
+ f"reproduce igual, y lo que se ve es un comportamiento viejo sin un solo error:")
+ for ruta, c in atrasados:
+ print(f" · {os.path.basename(ruta)}: {c}")
+
+
fallas = []
@@ -323,7 +394,8 @@ def leer(p):
return f.read()
-def revisar(permisos_host, verbo_extra=None, sin_perfil=None, sin_sembrador=None):
+def revisar(permisos_host, verbo_extra=None, sin_perfil=None, sin_sembrador=None,
+ pin_deriva=None):
# 1. La extensión existe y declara el id que todos los demás nombran.
try:
m = json.loads(leer("extensions/boveda/manifest.json"))
@@ -393,12 +465,16 @@ def revisar(permisos_host, verbo_extra=None, sin_perfil=None, sin_sembrador=None
# 10. Y el séptimo: quién puede sembrar la identidad con la que esa bóveda se abre.
revisar_el_sembrador(sin_sembrador)
+ # 11. Y el octavo: si lo que está pineado es lo de hoy, o una versión vieja que no falla.
+ revisar_la_deriva(pin_deriva)
+
def main():
control = "--negative-control" in sys.argv
control_verbo = "--negative-control-verbo" in sys.argv
control_perfil = "--negative-control-perfil" in sys.argv
control_sembrador = "--negative-control-sembrador" in sys.argv
+ control_deriva = "--negative-control-deriva" in sys.argv
host = json.loads(leer("native-messaging/puriy_costura.json"))
permisos = list(host.get("allowed_extensions", []))
verbo_extra = None
@@ -423,8 +499,16 @@ def main():
sin_sembrador = "agora-cli"
print(f"⚠ control negativo: se saca {sin_sembrador} de los perfiles de escritorio")
+ pin_deriva = None
+ if control_deriva:
+ # El pin ANTERIOR, el que de verdad estuvo puesto hasta el 2026-09-22 y que se quedó atrás
+ # del arreglo del llavero: si el octavo chequeo no lo ve atrasado, no está preguntándole a
+ # git — está contestando que sí. Es el único de los cinco controles cuyo «mal» ya ocurrió.
+ pin_deriva = "6f0408d40d05d7961e811f9062ce5d5127987635"
+ print(f"⚠ control negativo: se finge el pin viejo {pin_deriva[:9]} (el del §7.undecies)")
+
print(f"── la bóveda en atuq ──")
- revisar(permisos, verbo_extra, sin_perfil, sin_sembrador)
+ revisar(permisos, verbo_extra, sin_perfil, sin_sembrador, pin_deriva)
if control:
if any("allowed_extensions" in f for f in fallas):
@@ -450,6 +534,12 @@ def main():
return 0
print("\n✗ el control del sembrador NO lo detectó: el séptimo chequeo no mide nada")
return 1
+ if control_deriva:
+ if any("está DETRÁS de" in f for f in fallas):
+ print("\n✓ el control negativo de la deriva lo detectó")
+ return 0
+ print("\n✗ el control de la deriva NO lo detectó: el octavo chequeo no mide nada")
+ return 1
if fallas:
print(f"\n✗ {len(fallas)} problema(s)")
return 1