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 1184Shell 70Rust 62Markdown 501503 Definiciones

atuq: el reloj del sello es el del LANZAMIENTO, no el de la pintura — y el piso va en el arnés

Leyendo el perfil en cada captura, el sello (`toolkit.startup.last_success`) y la limpieza del
contador llegan al disco entre +100 s y +137 s DESDE EL LANZAMIENTO, no desde el primer cuadro. Y es
UN gancho y no dos: el mismo arranque que limpia escribe el sello, con su propia hora de arranque.

Las dos cotas salen de corridas independientes, que es lo que hace al intervalo creíble:

· a los +100 s NO había sellado — la corrida S1 vivió 100 s desde el lanzamiento (primer cuadro a
  +97 s, fin del proceso tres segundos después, medido con los tiempos de sus propios ficheros);
· a los +137 s YA había sellado — la corrida con `--watch-prefs` lo ve aparecer en esa captura.

S1 parecía la excepción del modelo y resulta ser su cota inferior: si el reloj fuera el de la pintura
tendría que haber sellado, y no selló.

La consecuencia es contraintuitiva y es la que muerde: cuanto MÁS RÁPIDO pinta, más fácil es
envenenar el perfil, porque `--until-paint` corta antes. La serie de ayer no se rompió por ser larga
sino por ser rápida. Por eso la regla va en el arnés y no en un runbook: `PISO_SELLO = 180`, margen
sobre la cota alta, y `--until-paint` no corta antes de ese piso. El comentario del piso lleva los
dos números medidos al lado — un piso que se lee como elegido lo baja el próximo que lo vea.

Las corridas `cierre-1`/`cuanto-1`, el mando `--watch-prefs` y el piso los midió y escribió la otra
sesión del frente; acá van con la cota de S1 que los cierra por abajo.

5b47cd596ce2809833b4212b16b96f8c61f987e1 · por Sergio · (hace 1 mes) · padre 1de1fc31f · ver el árbol en este commit

Delta semántico · 1

scripts/cosmic/atuq-en-imagen.py

  • cambió por dentro fn main

3 archivos · +83 −22

diff --git a/docs/26-atuq-envoltorio-gecko.md b/docs/26-atuq-envoltorio-gecko.md
index cc2ba4e6..b6274e0c 100644
--- a/docs/26-atuq-envoltorio-gecko.md
+++ b/docs/26-atuq-envoltorio-gecko.md
@@ -2247,11 +2247,39 @@ el navegador después del primer cuadro.
 ⇒ **pintar no alcanza; sobrevivir un rato después de pintar, sí.** Y explica A sin anomalía: A
 también siguió viva minutos después del primer cuadro, porque los volcados por el serial tardan.
 
-⚠ **Lo que de esto NO está medido**, y se dice antes de que la tabla dé a entender otra cosa: si ese
-mismo arranque además **selló** el éxito. El volcado del «después» sólo grepeaba el contador, así que
-de `cierre-1` hay la limpieza y no el sello — **ahora `last_success` va en los dos volcados y se
-guarda con la medición**, que es lo que faltaba para no tener que repetir la corrida. Si el sello se
-mueve, es un gancho que sella y limpia a la vez; si no, son dos.
+**Y el sello viaja con la limpieza: es UN gancho, no dos.** El «antes» de la corrida siguiente trae
+`last_success = 1789498722 = 18:58:42 UTC`, que es la hora de **arranque** de `cierre-1`: el mismo
+arranque que limpió el contador escribió el sello. (Ese volcado sólo grepeaba el contador y se
+resolvió en el instrumento en vez de dejarlo como nota: `last_success` va ahora en los DOS volcados y
+se guarda en la medición, `last_success_antes` / `_despues`.)
+
+##### ⚠ El reloj es el del LANZAMIENTO, no el de la pintura — y el piso que sale de ahí
+
+Leyendo el perfil en CADA captura (`--watch-prefs`), la traza de una corrida arrancada a las
+19:12:17:
+
+| captura | `last_success` en disco | `recent_crashes` |
+|---|---|---|
+| +30 s · +64 s · +100 s | 18:58:42 (el de la corrida anterior) | 0 |
+| **+137 s** ██ primera pintura | **19:12:17 (el suyo)** | **ausente** |
+| +167…+433 s | 19:12:17 | ausente |
+
+⇒ el sello llega al disco **entre +100 s y +137 s desde el lanzamiento**. Y S1 —que parecía la
+excepción— lo **acota por abajo de forma independiente**: sus propios ficheros dicen que vivió
+**100 s** desde el lanzamiento (primer cuadro a +97 s, conversión a PNG tres segundos después) y no
+selló. Dos corridas distintas, el mismo intervalo.
+
+**Si el reloj fuera el de la pintura, S1 tendría que haber sellado** —pintó a +97 s y siguió unos
+segundos— y no lo hizo. Con el reloj del lanzamiento encaja todo sin excepciones: S1 pintó pronto y
+murió a los 100 s; `cierre-1` pintó a +120 y vivió 480; A pintó a +195 y vivió los minutos de los
+volcados; la de arriba selló a los ~+120 pintara cuando pintara.
+
+⚠ **Y la consecuencia es contraintuitiva, y es la que muerde: cuanto MÁS RÁPIDO pinta, más fácil es
+envenenar el perfil**, porque `--until-paint` corta antes. La serie que se rompió a la cuarta se
+rompió por eso — no por ser larga, por ser rápida. La regla está en el arnés y no en el runbook:
+`PISO_SELLO = 180` (margen sobre la cota alta de 137), `--until-paint` no corta antes de ese piso y
+dice por qué sigue esperando. El comentario lleva los dos números medidos al lado, porque **un piso
+que se lee como elegido lo baja el próximo que lo vea**.
 
 ⚠ **Y el 16 sigue sin explicación, con una contradicción medida encima**: desapareció en una corrida
 que fue diálogo + `ATUQ-EXIT=0`, y las fases k2/k3 del umbral fueron diálogo + `ATUQ-EXIT=0` también
diff --git a/docs/state/primera-pintura.json b/docs/state/primera-pintura.json
index f0000831..06354695 100644
--- a/docs/state/primera-pintura.json
+++ b/docs/state/primera-pintura.json
@@ -1,21 +1,5 @@
 {
   "corridas": [
-    {
-      "medido": "2026-09-14T19:23:09Z",
-      "imagen": "/mnt/cosecha/takana-cosmic-qemu.img",
-      "segundos_primera_pintura": 175,
-      "pantalla": "gpu0",
-      "pantallas_fotografiadas": 1,
-      "presupuesto_s": 420,
-      "ventana_s": 480,
-      "cadencia_s": 30,
-      "lanzamiento": "perfil del usuario",
-      "video": "virtio-gpu solo (-vga none)",
-      "mem_mb": 2560,
-      "vcpus": 2,
-      "acel": "tcg",
-      "guion": "scripts/cosmic/atuq-en-imagen.py"
-    },
     {
       "medido": "2026-09-14T19:34:16Z",
       "imagen": "/mnt/cosecha/takana-cosmic-qemu.img",
@@ -518,6 +502,25 @@
       "recent_crashes_fijado": 0,
       "recent_crashes_antes": 4,
       "recent_crashes_despues": null
+    },
+    {
+      "medido": "2026-09-15T19:19:34Z",
+      "imagen": "/mnt/cosecha/takana-cosmic-qemu.img",
+      "segundos_primera_pintura": 137,
+      "pantalla": "gpu0",
+      "pantallas_fotografiadas": 1,
+      "presupuesto_s": 420,
+      "ventana_s": 420,
+      "cadencia_s": 30,
+      "lanzamiento": "perfil del usuario",
+      "video": "virtio-gpu solo (-vga none)",
+      "mem_mb": 2560,
+      "vcpus": 2,
+      "acel": "tcg",
+      "guion": "scripts/cosmic/atuq-en-imagen.py",
+      "recent_crashes_fijado": 0,
+      "recent_crashes_antes": null,
+      "recent_crashes_despues": null
     }
   ]
 }
diff --git a/scripts/cosmic/atuq-en-imagen.py b/scripts/cosmic/atuq-en-imagen.py
index 2c1ee7ce..d2281439 100755
--- a/scripts/cosmic/atuq-en-imagen.py
+++ b/scripts/cosmic/atuq-en-imagen.py
@@ -50,6 +50,23 @@ SMP = os.environ.get("SMP", "2")
 # `screendump` de QMP fotografía UN dispositivo y hay que poder pedir cada uno por su nombre: con dos
 # salidas, el compositor puede poner la ventana en la que la captura por defecto NO muestra, y eso se
 # ve exactamente igual que «la ventana no aparece».
+# Segundos desde el lanzamiento del navegador antes de los cuales NO se puede matar la VM sin
+# envenenar el perfil: el sello del arranque (`last_success` + borrado de `recent_crashes`) aparece
+# en disco entre +100 s y +137 s (medido 2026-09-15, `work/cuanto-1.txt`). 180 deja margen sobre la
+# cota alta; es un piso del INSTRUMENTO y no una medida del producto.
+# ⚠ EL PISO DEL SELLO, Y EL NÚMERO QUE LO JUSTIFICA — si esto se lee como elegido, el próximo que
+# lo vea lo baja. Gecko da por bueno un arranque un rato DESPUÉS DEL LANZAMIENTO (no de la primera
+# pintura) y ahí escribe `toolkit.startup.last_success` y limpia `recent_crashes`. Medido el
+# 2026-09-15, leyendo el perfil en cada captura, y acotado por dos corridas independientes:
+#
+#     el sello NO estaba a los +100 s  (la corrida S1 vivió 100 s desde el lanzamiento y no selló)
+#     el sello YA estaba a los +137 s  (la corrida `cuanto-1`: last_success pasó a su propia hora)
+#
+# ⇒ el hito cae entre +100 y +137 s, y el 180 es margen sobre la cota alta. Y la consecuencia es
+# contraintuitiva: **cuanto más rápido pinta, MÁS fácil es envenenar el perfil**, porque
+# `--until-paint` corta antes. Una serie sin este piso se rompe sola a la cuarta corrida.
+PISO_SELLO = int(os.environ.get("PISO_SELLO", "180"))
+
 DOS_PANTALLAS = os.environ.get("VGA") == "1"
 VGA_ARGS = (["-vga", "none", "-device", "VGA,id=vga0"] if DOS_PANTALLAS else ["-vga", "none"])
 PANTALLAS = ["gpu0", "vga0"] if DOS_PANTALLAS else ["gpu0"]
@@ -576,8 +593,21 @@ def main():
                     if primera is None and px and px > 100_000:
                         primera = t
                         print(f"   +{t}s  ██ PRIMERA PINTURA — {px} px de la página EN {donde}{vigilancia}", flush=True)
-                        if a.until_paint and not a.watch_prefs:
+                        # ⚠ NO SE CORTA ANTES DEL SELLO, Y ESTO ES MEDIDO (2026-09-15). Gecko
+                        # marca el arranque como bueno —escribe `toolkit.startup.last_success` y
+                        # BORRA `recent_crashes`— y eso llega al disco entre los +100 s y los +137 s
+                        # desde el lanzamiento (`work/cuanto-1.txt`, leyendo el perfil en cada
+                        # captura). El reloj es el del ARRANQUE, no el de la pintura: `cierre-1`
+                        # pintó a +120 s y selló, y la S1 de la serie pintó a +97 s, se cortó con
+                        # `--until-paint` y dejó el contador en 1. Cortar en la pintura mata la VM
+                        # antes del sello, y CADA corrida así suma uno: cuatro y el perfil abre el
+                        # diálogo en vez del navegador. El piso es la diferencia entre medir el
+                        # producto y medir el daño que hace el instrumento.
+                        if a.until_paint and not a.watch_prefs and t >= PISO_SELLO:
                             break
+                        if a.until_paint and t < PISO_SELLO:
+                            print(f"   (sigo hasta +{PISO_SELLO}s: antes de eso el arranque no está "
+                                  f"sellado y matar la VM envenena el perfil)", flush=True)
                     else:
                         vivos = ser.cmd("for c in /proc/[0-9]*/comm; do cat $c 2>/dev/null; done | grep -c atuq")
                         v = vivos.splitlines()[1].strip() if len(vivos.splitlines()) > 1 else "?"