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.
This commit is contained in:
Sergio
2026-09-15 19:23:26 +00:00
parent 1de1fc31f6
commit 5b47cd596c
3 changed files with 83 additions and 22 deletions
+33 -5
View File
@@ -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
+19 -16
View File
@@ -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
}
]
}
+31 -1
View File
@@ -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 "?"