uix(theming): revisión adversarial del bloque — la pasada de HOVER envenenaba a todos los tokens de reposo

Cinco hipótesis, un hallazgo real, cuatro refutadas. Bloque de CATORCE
componentes; global del eje 56 % → **62 %**.

HALLAZGO REAL — la anomalía de `float-panel` tenía causa, y era del guard.

`resize-grip-fg` movía aislado y leía muerto en una corrida completa. Instrumenté
el propio guard para probar UNA clave y salió `moved=true`; luego, en la corrida
entera, muerto. La causa: **la pasada de HOVER deja el puntero sobre el último
nodo que tocó**, y una regla `:hover` gana a la de reposo con la que comparte
nodo — el asa re-apunta su color al acento al pasar el ratón. Es decir:
**cualquier token de reposo probado DESPUÉS de un token `hover-*` podía leer
muerto**. Es exactamente la clase que F2-A arregló con el clic-foco, una pasada
más tarde: allí se aparcó el puntero tras ABRIR, aquí faltaba aparcarlo tras
HOVERAR.

Arreglado. Y entonces el propio guard delató DOS excepciones STALE —
`float-panel.resize-grip-fg` y `media-player.track` —, retiradas: dos tokens que
el ledger daba por muertos están vivos. Se confirma la regla de F2-A: **un falso
negativo siempre tiene causa**; registrarlo como «sin causa» era el paso previo,
no el final.

REFUTADA «hay tokens huérfanos»: comprobación ESTRICTA —comentarios despojados,
que es el hueco por el que `popover.bg` sobrevivió, sobre todo el CSS del árbol—
de las **553 claves** de los catorce bloques: ninguna declarada sin que una regla
la lea.

REFUTADA «el cambio de instrumento rompió algo»: los **27 componentes con ledger
re-verificados** tras aparcar el puntero — cero regresiones. Los tres rojos que
quedan (`drawer` 24, `metrics` 16, `color-picker` 23) son ANTERIORES al bloque y
están anotados con lo que ya se descartó de cada uno.

REFUTADA «quedan fantasmas del barrido en lo tocado»: pasa de 9 a **8** — el
`--color-content-tertiary` de float-panel murió con su costura. Los ocho
restantes son de componentes que este bloque no tocó.

CONFIRMADO, y ya estaba escrito: hay gates FINOS. `popover` mide 1 nodo en reposo
(7 en abierto), `drawer` 1, `context-menu` 1 + 14 en abierto, `color-picker`
5 + 12. Cada veredicto lo dice, y lo que sostiene esas cifras es el forzado a
mano de sus estados, no la sonda.

Guards: `--names` sin desviadas · docs:check 0 · censo 62 % (2.877 públicos de
5.137 knobs; `global` 1.145 → 912).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
alpha-0.1-background
dev 2 months ago
parent 608e7d5507
commit cd6a9f4e3e

@ -116,12 +116,12 @@ cierre—, así que se forzaron el atributo de variante y se montó el botón do
el CSS lo selecciona; el radio del asa sólo pinta bajo `:focus-visible`. Las
once alcanzan.
**Y una ANOMALÍA registrada en vez de escondida**: `resize-grip-fg` MUEVE bajo
una réplica a mano de la secuencia del propio guard —congelar, blur, aparcar el
ratón, escribir en `:root` y en cada nodo con el prefijo, fotografiar con
pseudos— (oklch(0.5032 0 0) → rgb(1,2,3)), y aun así el guard lo da por muerto.
La causa no está encontrada. El token está vivo; lo que está en duda es la
lectura → next-features §13.
**La ANOMALÍA que registré aquí quedó RESUELTA el mismo día**, en la revisión
adversarial del bloque: `resize-grip-fg` movía aislado y leía muerto en una
corrida completa porque **la pasada de hover deja el puntero sobre el último
nodo que tocó**, y el asa re-apunta su color al acento bajo `:hover`. Con el
puntero aparcado tras esa pasada, el token vive y el guard delató su propia
excepción como STALE.
**Lo rojo que queda es ANTERIOR**: 12 tokens del bloque viejo, y seis de ellos
—`bg`, `border`, `border-width`, `shadow`, `font-family`,

@ -1060,18 +1060,18 @@ Lo que `chart` destapó (2026-08-22):
de `data-size`) ni que el guard no vea sus nodos (ya se le dieron las dos
familias que le faltaban).
- **⚠ Un falso negativo del centinela SIN causa encontrada** (2026-08-22):
`float-panel.resize-grip-fg`. Réplica a mano de la secuencia del propio guard
—congelar transiciones, blur, aparcar el ratón, escribir en `:root` y en cada
nodo con el prefijo, fotografiar los mismos props con `::before`/`::after`/
`::placeholder`— y el color del asa SÍ se mueve (oklch(0.5032 0 0) →
rgb(1,2,3)). El guard lo reporta muerto. Descartado: que el nodo no lleve el
atributo (lo lleva), que la regla necesite un estado (es la regla base), que
sea el valor centinela (es el mismo) y que sea HMR (dos corridas). Queda
adjudicado con la medición y marcado como anomalía: **el token está vivo; lo
que está en duda es la lectura**. La revisión adversarial del bloque debería
empezar por aquí — el precedente de F2-A dice que estos casos SÍ tienen causa
(22 falsos negativos de 26, tres causas distintas).
- **~~Un falso negativo del centinela sin causa~~ — RESUELTO en la revisión
adversarial del bloque (2026-08-22).** `float-panel.resize-grip-fg` movía
aislado y leía muerto en una corrida completa. La causa: **la pasada de HOVER
deja el puntero sobre el último nodo que tocó**, y una regla `:hover` gana a
la de reposo con la que comparte nodo — el asa re-apunta su color al acento
al pasar el ratón. Así que CUALQUIER token de reposo probado después de un
token `hover-*` podía leer muerto. Es la misma clase que el envenenamiento
por clic-foco que F2-A arregló, una pasada más tarde. Arreglado aparcando el
puntero tras la pasada de hover; el propio guard delató entonces DOS
excepciones STALE (`float-panel.resize-grip-fg` y `media-player.track`),
retiradas. Confirma la regla de F2-A: **un falso negativo siempre tiene
causa.**
**Deps**: ninguna. Son mejoras del instrumental del eje, ejecutables cuando
estorben.

@ -455,6 +455,42 @@ de commit. Sin artefacto, el paso no se ha hecho.
## 8. Registro
- 2026-08-22 — **REVISIÓN ADVERSARIAL DEL BLOQUE (§7.7): 5 hipótesis, 1
hallazgo real, 4 refutadas.** Bloque de CATORCE componentes; global 56 % →
**62 %**.
**HALLAZGO REAL — la anomalía de `float-panel` tenía causa, y era del guard.**
`resize-grip-fg` movía aislado y leía muerto en una corrida completa. La
causa: **la pasada de HOVER deja el puntero sobre el último nodo que tocó**, y
una regla `:hover` gana a la de reposo con la que comparte nodo (el asa
re-apunta su color al acento). Es decir: **cualquier token de reposo probado
después de un token `hover-*` podía leer muerto** — misma clase que el
envenenamiento por clic-foco que F2-A arregló, una pasada más tarde.
Arreglado aparcando el puntero tras la pasada de hover. El propio guard
delató entonces DOS excepciones STALE —`float-panel.resize-grip-fg` y
`media-player.track`—, retiradas: dos tokens que se daban por muertos están
vivos. Se confirma la regla de F2-A: **un falso negativo siempre tiene causa**;
registrarlo como «sin causa» era el paso previo, no el final.
**REFUTADA «hay tokens huérfanos»**: comprobación ESTRICTA (comentarios
despojados —el hueco que dejó vivo el `popover.bg`— sobre todo el CSS del
árbol) de las **553 claves** de los catorce bloques: ninguna declarada sin que
una regla la lea.
**REFUTADA «el cambio de instrumento rompió algo»**: los **27 componentes con
ledger re-verificados** tras aparcar el puntero — cero regresiones. Los tres
rojos que quedan (`drawer` 24, `metrics` 16, `color-picker` 23) son
ANTERIORES al bloque y están anotados.
**REFUTADA «quedan fantasmas del barrido en lo tocado»**: el barrido pasa de
9 a **8** — el `--color-content-tertiary` de float-panel murió con su costura.
Los ocho restantes son de componentes que este bloque no tocó.
**CONFIRMADO, y ya estaba escrito: hay gates FINOS.** `popover` mide 1 nodo en
reposo (7 en abierto), `drawer` 1, `context-menu` 1 + 14 en abierto,
`color-picker` 5 + 12. Cada veredicto lo dice; el forzado a mano de sus
estados es lo que sostiene esas cifras, no la sonda.
- 2026-08-22 — **`password-field` 41 % → 62 %** (7 claves) **y el guard en
VERDE**: sus siete silencios quedan medidos, incluidos los tres que arrastraba
de antes.

@ -37,8 +37,6 @@ export const SENTINEL_EXCEPTIONS: Record<string, Record<string, string>> = {
},
'media-player': {
'accent-strong': 'consumed by the live indicator, which only paints under [data-live]',
track:
'forwarded into the composed Slider — paints on [data-slider-*] nodes, outside this component attribute space',
'buffered-bg':
'forwarded into the composed Slider (SecondaryRange) — outside this component attribute space',
'captions-bg': 'captions are conditional and the demo video carries no track',
@ -354,14 +352,7 @@ export const SENTINEL_EXCEPTIONS: Record<string, Record<string, string>> = {
'action-font-size': 'same button; mounted -> reaches (16px -> 1234px)',
'hover-action-bg': 'same button, and only under :hover; same mounting pass',
'hover-action-fg': 'same button, and only under :hover; same mounting pass',
'resize-grip-radius': 'only under :focus-visible; focused the grip -> reaches (4px -> 1234px)',
// ANOMALY, registered rather than hidden: this one MOVES under a hand
// replication of the guard's own sequence (freeze, blur, park, write on
// :root + every prefix node, snapshot with pseudos): oklch(0.5032 0 0) ->
// rgb(1,2,3). The guard still reports it dead and the cause is not found
// yet — 2026-08-22, next-features §13. The token is alive; the reading is
// what is in doubt.
'resize-grip-fg': 'MEASURED ALIVE by hand under the guard own conditions (oklch(0.5032 0 0) -> rgb(1,2,3)); the guard reports no effect and the cause is open - next-features 13'
'resize-grip-radius': 'only under :focus-visible; focused the grip -> reaches (4px -> 1234px)'
},
drawer: {
// The guard OPENS the drawer before testing, and the overlay then covers the

@ -489,7 +489,17 @@ async function main() {
await reopen();
const value = sentinelFor(key);
let moved = await staticPass(key, value);
if (!moved && /hover/.test(key)) moved = await hoverPass(key, value);
if (!moved && /hover/.test(key)) {
moved = await hoverPass(key, value);
// PARK THE POINTER AFTERWARDS. The hover pass leaves the cursor on the
// LAST node it hovered, and a hover rule outweighs the rest-state one it
// shares a node with: every rest token tested after a hover token could
// read dead. Measured 2026-08-22 on float-panel — `resize-grip-fg` moved
// in isolation and read dead in a full run, because the grip's own
// `:hover` rule re-points its colour to the accent. Same class as the
// click-focus poisoning fixed in F2-A, one pass later.
if (override.openBy !== 'hover') await page.mouse.move(0, 0);
}
if (moved) live.push(key);
else stillDead.push(key);
}

Loading…
Cancel
Save

Powered by TurnKey Linux.