# CONTINUE — eje Theming «theme-reach» — **CERRADO 2026-08-25** ## EMPIEZA AQUÍ **EL EJE ESTÁ CERRADO** (gate de F3 rediseñado y en verde el 2026-08-25; sección §«EL CIERRE, EJECUTADO» abajo). Lo que vigila el estado desde hoy no es este documento sino los guards: `theming-reach-floor.test.ts` (newDebt=0 · STALE=0 · reach ≥ 73 % · **≥67** al 100 %), `component-audit` R-5.1/5.2/5.3 en `error`, y el centinela R-5.4. La deuda restante vive NOMBRADA clave a clave en `scripts/theming-census-debt.ts` (**1148** entradas que sólo pueden menguar; eran 1150 hasta el 2026-08-27 — ver el handoff de cierre). Trabajo nuevo de theming se abre como entrada nueva de §13/next-features, no heredando de aquí. Las DOS firmas que el cierre dejó pendientes están **EJECUTADAS**: la de los 318 privados no-derivados (§«FIRMA EJECUTADA — los 318» abajo) y la del idioma `var(--{c}-x, fallback)` sin contrato (§«FIRMA EJECUTADA — la ley del espacio cerrado»). Heredada de la segunda queda la re-clasificación de los 117 nombres `--palabras-*` que el censo puntúa `public` siendo canal de VALOR, más DOS deudas nuevas de eje propio que ella misma nombró: el codemod de los 14 canales públicos a `--_{c}-*` — **EJECUTADO 2026-08-26 (14 de 14: 13 en el codemod + el 14.º por firma propia, ver §«FIRMA EJECUTADA — el indicador de navigation-menu»)** — y el cableado `EidosConfig.motion` → CSS (las dos, con su lista, en `next-features.md`) — **el cableado de motion también está EJECUTADO** (`e16c14dec`; ver el punto 3 del handoff del 26). **Lo que sigue pendiente en este carril: la re-clasificación de `palabras` · la `timeline` §5 pre-B′.** **El eje tiene HOY dos colas, y ninguna es la que se cerró.** La que se agotó el 2026-08-25 fue la de CIERRE: los 16 componentes que nunca habían pasado están cerrados o adjudicados, la deuda de artefactos está saldada, y **§12.9 y la firma B′ quedaron FIRMADAS Y EJECUTADAS** — las dos decisiones más caras. Lo que hay abierto es posterior a ese cierre: - **cola de EJECUCIÓN — TRES entradas** (eran cuatro; **A-1 está EJECUTADA**, ver el handoff de cierre del 27 justo debajo): C-1 · `palabras` + `timeline` · los 7 sitios del absoluto de cascada. - **cola de FIRMA** — la lista §5 «Lo que espera TU FIRMA», **VIVA**: once entradas, **nueve esperando** (el bloque (c) la resume). > **LO PRIMERO, si entras sin contexto**: **§16 (A-1) está EJECUTADA** > (2026-08-27). La ley vive en `docs/canon/recipe-contract.md` §4 como > **R-5.5**, hermana de la ley del espacio cerrado; el guard es > `src/uix/value-channels.test.ts`; el acta con los números está en > `docs/next-features.md` **§16-bis**. Lo siguiente de la cola es **§17 (C-1)**, > que **sigue esperando firma** — una línea: ¿la cascada de atajos de > `box`/`grid` es DEUDA o es IDIOMA? > > **Y hay un expediente NUEVO, §18**, abierto por el pase de alcance que cerró > §16 esa misma tarde: **eidos también escribe por instancia** — 11 nombres del > contrato y 18 formas sin dueño que R-5.5 **no barre y ahora declara por > escrito** que no barre. Su caso urgente es el gemelo del velo del drawer, > `--dialog-overlay-opacity`. Está **redactado y NO ejecutado**, y espera firma. > El detalle, en §«El PASE DE ALCANCE del cierre» de este mismo handoff. > > **Anotación 2026-09-13 (carril de la auditoría, P2 eidos; nadie del eje > theming estaba vivo para recibirlo en caliente)**: la fuente de la que > R-5.5 deriva el vocabulario de sistema, `renderGeneratedBaseEidosCss()`, > sigue emitiendo **5751 nombres únicos / 8034 ocurrencias** (lost=[] > gained=[]) tras `39edbc8db` — los bloques `[data-theme]` de `base.css` > declaran ahora `color-scheme`, declaración estándar, ningún `--nombre`. > Pero desde `598ea460e` hay **DOS sedes estáticas**: `src/uix/eidos/index.css` > (intacto, byte a byte) y su hermano `src/uix/eidos/index-runtime.css` > (= index.css sin `@import './generated/base.css'`; guard de deriva > `src/uix/eidos/index-runtime-css.test.ts`). Si `value-channels.test.ts` o > §18 miran UNA sede, deben mirar la UNIÓN. vicen-0b lo pidió así antes de > irse; no se re-apuntó nada porque el autor no lo ha pedido. > Desde `e2c37f892` el tema DECLARA su apariencia (`appearance` obligatorio en > `ThemeDefinition`, documento v2): `generated/` byte-idéntico, 5751/8034 quietos. > > _(Anotación 2026-08-27 al cierre. El párrafo original de este bloque decía: > «lee el expediente §16 … marcado PENDIENTE — redactado, NO ejecutado … Es lo > único de la cola que mueve un píxel hoy». Era cierto esa mañana; el velo del > drawer ya pinta.)_ Global **73 %** (68 % antes de la clase `structural`, 69 % antes de `bridge`/`channel`), **67 componentes al 100 %**. ## HANDOFF 2026-08-27 (cierre) — **A-1 / §16 EJECUTADA** > El handoff de más abajo, «2026-08-27 (noche)», es de esa misma mañana y daba > A-1 por pendiente. Se conserva entero: era cierto cuando se escribió. Esto es > lo que pasó después. **Lo firmado**: _toda escritura de custom property POR INSTANCIA vive en `--\_{c}-_`; si el nombre está en el contrato es un TOKEN QUE MIENTE, porque un tema no puede ganarle jamás.\* Quinta aplicación de la doctrina del canal de valor (§14 tercera, §15 cuarta). **Dónde quedó cada cosa:** | pieza | dónde | | ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | | la LEY | `docs/canon/recipe-contract.md` §4 — **R-5.5** en la tabla + el pasaje hermano de la ley del espacio cerrado | | la AGUJA | `src/uix/value-channels.test.ts` — fichero propio, 5 tests, corre en `npm run test` ⇒ en el gate | | el ACTA con los números | `docs/next-features.md` **§16-bis** | | las DOS FORMAS, ya sin empate | `docs/architecture/soma-architecture.md` §9 — el bloque listaba las dos como si valieran las dos; ahora dice que sólo hay una y quién la hace cumplir | **Los números de cierre**: **1.729** ficheros de código de soma + arts · **61** nombres en **72** sitios · `--_{c}-*` **53** · **token que MIENTE 0** (era 1) · **forma pública sin dueño 8**, las ocho REGISTRADAS · `blocks` y `packs` en **0**, ahora asertado. Contrato 4.693 nombres, vocabulario de sistema 1.058 (derivado restando el contrato a lo que emite la fundación, nunca a mano). **Las dos correcciones que sólo aparecen midiendo:** 1. **El árbol tiene SEIS formas de escritura, no cuatro**, y una de las que faltaban era **la CANÓNICA**: la clave computada ``[`--_${component}-floating-anchor-width`]`` que §14 y §15 firmaron. Un guard ciego a ella es ciego al destino que hace cumplir. La otra, `out['--x'] = v`. De ahí 61 nombres y no 49. 2. **«Los 15 de clase B tienen CERO lectores» era falso para dos**: `--scroll-area-corner-{width,height}` tenían lector vivo, un `var()` inline **dentro de soma** — invisible a un censo de lectores acotado a la capa que lee. Barrer por STEM lo cazó; barrer por el nombre pelado no lo habría hecho. **Mutaciones: seis caras, árbol restaurado byte a byte** — nombre sin prefijo → rojo nombrándolo · clave DEL CONTRATO → rojo «token que MIENTE» · `--_` correcto → verde · nombre de SISTEMA → verde (única rama sin caso vivo, probada sólo por inyección) · entrada de registro huérfana → rojo STALE · la forma canónica en variante pública → rojo `--{}-…`. **El ledger se movió, y no fue la aguja**: **1.150 → 1.148 · 0 new · 0 stale**. Lo mueve la clase D: al dejar `--gp-current-gradient` de ser un nombre pelado, el censo reclasificó sus dos lectores de `global` a `channel` y las dos líneas salieron STALE. Renombrar privados no toca el ledger — por eso el resto de la firma lo deja quieto. ⚠ La tabla (a) del handoff de la mañana dice **1.150**: era la cifra de esa mañana y se conserva; la de hoy es 1.148. **Lo que queda con dueño ajeno** (nada de esto es recorte silencioso): los tres comentarios de `base.ts` (`:2530`, `:3201`, `:3268`) que citan los nombres viejos y hoy MIENTEN, vetados por brief · 4 sitios en `web/routes/**`, congelado · la cabecera de `scripts/theming-census-debt.ts`, que sigue diciendo «582 of the 1150 keys» · `theming-sentinel-exceptions.ts:815`, que declara que el velo no pinta cuando ya pinta (es un acta: se anota) · el ejemplo `'0.5'` de `types.ts` en `drawer` **y** `dialog`, que produce exactamente el bug cerrado y pide firma conjunta. **Lo siguiente**: **§17 (C-1)**, que sigue esperando su firma de una línea. Gana con esto — su violación más nítida vive en soma, el espacio que A-1 abrió. ### El PASE DE ALCANCE del cierre — la ley acotada, y §18 abierto > Los dos pases adversariales reprodujeron los números de arriba **al dígito** y > no encontraron una sola medida falsa. Lo que encontraron fue un **alcance sin > escribir**, y el veredicto del crítico es la frase que ordena este bloque: > _«es LEY sobre la mitad que barre, y sigue siendo PROSA sobre el absoluto que > enuncia»_. Tres correcciones, ninguna un eje nuevo, todas ejecutadas el mismo > día. La tabla de «lo que queda con dueño ajeno» de arriba se conserva entera: > su tercera entrada (la cifra de 1150) **ya está corregida** — se anota aquí en > vez de reescribirla. 1. **EL ALCANCE, ESCRITO.** R-5.5 enunciaba «_every_ per-instance write» mientras su aguja barría dos raíces. Hoy la ley nombra sus **nueve** — `soma` · `arts` · `blocks` · `packs` · `libs` · `svrs` · `sema` · `morfo` · `active-uix` — y **declara sus dos fronteras**: `src/uix/eidos` (que NO está vacío: 11 nombres contratados + 18 formas sin dueño) y `web/routes` (congelado, y sin la cláusula de QUIÉN que haría juzgable una demo). 2. **LAS SALIDAS SON CUATRO.** Decía «tres, y no hay cuarta» mientras su propia tabla de mutaciones enseñaba la cuarta en verde: el **vocabulario de sistema**. Reescritas en el orden en que el guard las pregunta. 3. **EL REGISTRO SE QUEDA, con cuatro campos.** Es el patrón de la casa (transitorio, sólo mengua, STALE lo vacía solo) y ahora responde por escrito a la objeción de que `PENDING_PRIVATE_RENAME` se desmontó 24 h antes: aquélla era una COLA de renombres ya decididos, y una cola sin plazo es un cajón; éstas son adjudicaciones que la ley no alcanza. Cada entrada lleva **fecha · razón · destino · por qué NO se movió hoy**, y el guard asserta que los cuatro están rellenos. Las 8 entradas están completas. **Dos menores, medidos antes de decidir**: `classify` preguntaba por `--_` antes que por el contrato, de modo que las **124** claves `_` de `base.ts` se escribían inline gratis — **0 de 64** escrituras privadas de soma+arts y **0 de 46** de eidos nombran una clave contratada, así que invertir el orden cerró el agujero **sin enrojecer nada**. Y `SILENT_ROOTS` prohibía TODA escritura en `blocks`/`packs`: un bloque que estampe geometría privada legítima nacía rojo. Hoy esas raíces se barren bajo los mismos dos rojos, **nunca contra cero**. **Mutaciones del pase** (backup + restauración en la misma invocación, SHA idéntico): re-corridas **b′** (clave del contrato → ROJO «token that LIES») y **f′** (la forma canónica computada, variante pública → ROJO `--{}-…`), que prueban que la aguja **sigue mordiendo tras los cambios**; y tres nuevas — **g** `--_avatar-badge-bg` (clave `_` DEL CONTRATO) → ROJO, **era verde** · **h** `--_hero-private-leak` en `blocks` → VERDE, **era rojo sin ser violación** · **i** `--hero-public-leak` en `blocks` → ROJO, en una raíz que esa mañana no barría nadie. **§18 ABIERTO — la respuesta medida a «¿por dónde vuelve a nacer un nombre público sin dueño?»: desde eidos.** 3.034 ficheros, 90 escrituras, **11 tokens que MIENTEN + 18 formas sin dueño**, en dos especies que no son la misma: 13 sitios de `eidos/lib/*` son **la fundación generando su vocabulario** (legítimos, y añadir el root los pondría rojos el primer día) y 16 de `eidos/components/*` son **props ergonómicas del consumidor**. El caso que lo hace urgente: **`--dialog-overlay-opacity` es el gemelo exacto del velo del drawer** —misma línea, mismo `color-mix()`— vivo porque `dialog` no tiene canal de progreso y no se tocó. **Mientras soma COMPONE (`knob × progress`), eidos sigue PISANDO el knob.** Marcado **PENDIENTE — redactado, NO ejecutado**, con opciones, «no hacer nada» y su precio, y recomendación. **No es «añadir el root»: distinguir fundación de prop-del-consumidor exige FIRMA**, igual que §16 exigió las suyas. **Corregido de paso**: `scripts/theming-census-debt.ts:59` decía «582 of the **1150** keys» con **1148** vivos (verificado con `--debt`: 1148 · 0 new · 0 stale; las pistas no se mueven — `palabras` 359 + `chronos` 223 = 582). El fichero estaba sucio sólo por el acta de clase D de esta misma firma, no por un peer, así que se heredó y se corrigió con acta propia en su cabecera. **Sigue esperando firma**: **§17 (C-1)**, una línea · **§18**, la especie de eidos + el gemelo `dialog` + el `'0.5'` de los dos `types.ts` · y las **dos adjudicaciones** que viven en el registro de `src/uix/value-channels.test.ts`. ## HANDOFF 2026-08-27 (noche) — POR AQUÍ MAÑANA ### (a) El estado REAL de hoy, con los números vivos Medidos en serie hoy, todos sobre árbol quieto salvo donde se dice: | instrumento | hoy | nota | | --------------------- | -------------------------------------- | ------------------------------------------------------------------------- | | censo — knobs | **4.915** | | | censo — alcanzados | **3.073 (73 %)** | denominador tematizable **4.223** | | censo — sin contrato | **16** | venía de 24 | | ledger de deuda | **1.150** | **760** global + **324** literal + **66** private | | `newDebt` / `STALE` | **0 / 0** | | | `theming-reach-floor` | **5/5** | `reachPct` 73 · `minAtHundred` **67** | | `recipe-css-contract` | **43/43** | `PENDING_PRIVATE_RENAME` **DESMONTADO a cero** | | `docs:check` | **0 errores / 0 avisos** | | | `component:audit` | **161 PASS / 5 NEEDS-WORK / 0 BROKEN** | 166 componentes · **cifra de CIERRE**, re-medida el 27 sobre árbol quieto | **El ledger cuadra por dos vías**, que es la razón para fiarse de él: la suma por clase da 1.150, y **4.223 − 3.073 = 1.150** — registra exactamente cada declaración no alcanzada, una a una. (Se midió sobre el blob COMMITEADO de `scripts/theming-census-debt.ts` porque el peer lo tenía sucio; al cierre del 27 el fichero está **limpio**, así que blob y árbol de trabajo coinciden.) **El 161/5 es CIFRA DE CIERRE, no señal.** Se anotó primero con la salvedad «medido sobre árbol MODIFICADO por un peer»; el 2026-08-27 el árbol quedó quieto en `scripts/` (los cuatro instrumentos del eje están limpios, ver bloque (d)) y **se re-midió: mismo 161 PASS / 5 NEEDS-WORK / 0 BROKEN sobre 166 componentes**. La salvedad se retira — la cifra se sostiene sobre árbol limpio. **Los CINCO, con su único error cada uno** (report en `tmp/component-audit.md`): | componente | regla | de quién es | | ----------------- | ------------------------------------------------------------------------ | -------------------------------------------------------------- | | `color-picker` | **A-3.7** — 8 acciones de teclado que mutan estado, 4 eventos semánticos | **P1/morfo — ajeno**; es el que cayó al pasar de 162/4 a 161/5 | | `badge` | **R-1.5** — sin tratamiento de foco | eidos, preexistente | | `gradient-picker` | **R-1.2** — sin estilos `[data-disabled]` | eidos, preexistente | | `mockup` | **E-2.3** — README ausente | eidos, preexistente (§«ley del espacio cerrado») | | `motion` | **R-1.1** — falta el selector raíz `[data-motion]` | eidos, preexistente | **Ninguno de los cuatro preexistentes es deuda que este eje abriera**, y el quinto —el único movimiento respecto del 162/4 histórico— es del eje P1/morfo. **Los DOS commits del día que este handoff no registraba** (ya no): - **`830cd7671` — la GRIETA de la aguja.** `classify` decidía la clase de cada knob con seis agujas que exigían `var(--` literal, y el valor llega normalizado: una declaración que **Prettier había roto en dos líneas** llegaba como `var( --x` y la aguja fallaba. **El censo clasificaba por ORTOGRAFÍA** — el mismo knob puntuaba distinto según si su línea cabía en 100 columnas. Dos víctimas (`palabras.css:227`, la zebra, `literal`→`public`; `split-button.css:66`, `global`→`channel`). Movió el ledger **1.152 → 1.150** y `atHundred` **66 → 67**. NO es deuda perdonada: ninguna receta cambió, se corrigió una misclasificación en su origen. Las otras tres agujas llevaban el mismo defecto con cero víctimas y se corrigieron igual — dejarlas ciegas deja la bomba armada para la próxima línea que Prettier rompa. _(Estela: `c91dd68be` encontró que eran **OCHO** agujas ciegas al corte de Prettier, no una.)_ - **`ab54a8821` — la cosecha del pase adversarial** (3 Opus con mandato de refutar). **Las tres firmas SE SOSTIENEN** (A1 7/7 con 4 refutaciones fracasadas; A2 8/8; A3 8/8); toda refutación aceptada era de PROSA. De ahí salió el **absoluto falso de cascada** corregido en 5 READMEs — y el barrido del 27 encontró **DOCE sitios más** que su mandato no cubría — 5 en `docs/` (ya cerrados, dos de ellos por anotación fechada) y **7 fuera de `docs/`, sin tocar**: son la cola del bloque (b-bis). Acta y lista en `next-features.md` §14-bis, «Fe de erratas 2026-08-27». **Cosecha registrada SIN ejecutar**, que es cola nueva: grieta del `SourceMap` sin tipar · `lib/*.css` sin linter · `available-width` sin lector ×9 · la nativa sin `available-*` · regla 2 de capas contra el catálogo. ### (b) Lo que queda, por orden de VALOR > _(Anotación 2026-08-27 al cierre — el punto 1, A-1, está **EJECUTADO**: ley > R-5.5 en `canon/recipe-contract.md` §4, guard `src/uix/value-channels.test.ts`, > acta en `next-features.md` §16-bis. Se conserva como el diagnóstico que fue. > ⚠ Dos de sus cifras las corrige el acta por medida: son **61 nombres en 72 > sitios**, no 49/76 —el barrido previo enumeró cuatro formas de escritura y el > árbol tiene seis— y **dos de los 15 «sin lectores» sí tenían lector**, > `--scroll-area-corner-{width,height}`, dentro de soma.)_ 1. **A-1 — «el guard vive donde NACE el valor».** El censo, el ledger, R-5.1 y la ley del espacio cerrado leen `src/uix/eidos/components` **y nada más** (`scripts/theming-census.ts`, `const ROOT`). Quien ESCRIBE la custom property por instancia vive en `src/uix/soma` y `src/arts`, y **ningún instrumento del eje lo ha enumerado jamás**: el guard mira el lado que LEE, el valor nace en el lado que ESCRIBE — que es literalmente la ley que firma HEAD `05dcb4db7`. Censo medido: **49 NOMBRES reales en 76 escrituras** (1 token que MIENTE · 15 nombres públicos sin contrato, con **CERO lectores** en todo el repo · 30 `--_*` ya correctos · 3 del vocabulario sin dueño; el bruto de 52 no descontaba 3 nombres de ruido). Radio de explosión cerrado: `blocks` y `packs` escriben 0. **Lleva un fallo de pintura VIVO dentro**: `--drawer-overlay-opacity` se escribe inline SIN UNIDAD y `drawer.css` lo consume dentro de un `color-mix()` que exige porcentaje ⇒ la función entera se invalida y **el velo del drawer no pinta**; está adjudicado EN PROSA en `theming-sentinel-exceptions.ts:815`, no arreglado — la excepción se tragó el bug. **Es lo único de la cola que mueve un píxel hoy.** → **Expediente completo (problema · censo · opciones con coste · recomendación · qué exige firma): `docs/next-features.md` §16**, marcado **PENDIENTE — redactado, NO ejecutado**. Ficheros clave `src/uix/soma/components/drawer/drawer-provider.svelte.ts:372,1145` · `src/uix/eidos/components/drawer/drawer.css:49-51` · `src/uix/eidos/lib/recipes/base.ts:1474` (⚠ el dimensionado decía `:1201`, que es la clave de **`dialog`**; el bloque `drawer` va de `:1457` a `:1522`). 2. **C-1 — el corolario 2 no tiene aguja.** La ley del espacio cerrado (recipe-contract §4, corolario 2) dice que una vez declarada la clave, el fallback inline sobre el nombre público MUERE. **Nunca recibió guard**: hoy **147 sitios · 115 nombres · 16 componentes** leen una clave declarada con un default de repuesto al lado. **Cero píxeles hoy** (cada clave en disputa se emite en `:root`, así que el `var()` nunca cae al fallback) — pero son 147 líneas muertas y **6 pistolas cargadas**: el día que alguien pode o acote una clave, esos sitios pintan otro valor EN SILENCIO y ningún guard chista, porque `recipe-css-contract` **sanciona la forma con fallback** por escrito. Las 6 discrepancias reales: `context-menu` ×3 · `splitter` (0.4 vs 0.6) · `calendar` `select-padding-inline` ×2 (`8px` literal, ignora densidad y zoom). ⚠ **La cifra vieja de 171/124 medía OTRO corolario** (el 3, que está limpio). → **Expediente completo: `docs/next-features.md` §17**, marcado **PENDIENTE — redactado, NO ejecutado**; reusa `collectOwnPublicVariables` de `src/uix/eidos/recipe-css-contract.test.ts:140`. ⚠ Los punteros de línea del dimensionado estaban TODOS desviados y se re-localizaron en §17: comprueba cada línea antes de editarla. 3. **Re-clasificar `palabras`** (117 nombres `--palabras-*` que el censo puntúa `public` siendo canal de VALOR del `scheme-style` del documento) y **reabrir `timeline`** (§5 pre-B′) — los dos con expediente escrito en `next-features`. 4. **COLA NUEVA — el absoluto falso de cascada: 7 sitios fuera de `docs/`.** Detalle completo en el bloque (b-bis), justo debajo. **A-1 va PRIMERO, y C-1 no puede cerrarse bien antes**: la violación más nítida de C-1 (`scroll-area`, contrato `--space-2-5` escalado contra un `8px` que soma y el README documentan) **vive en soma**, donde una aguja de corolario 2 escrita hoy no mira. Escribir C-1 primero es construir un guard sobre medio espacio y cobrarlo como verde — la versión suave de «un guard que inspecciona el vacío pasa». ### (b-bis) COLA NUEVA — el absoluto falso de cascada (7 sitios, NINGUNO tocado) **El hallazgo.** El pase adversarial ajeno `ab54a8821` corrigió el absoluto falso en **CINCO READMEs de soma** (`popover`, `tooltip`, `context-menu`, `link-preview`, `menubar`) y **se le escapó el SEXTO de la misma especie**: > `src/uix/soma/components/navigation-menu/README.md:182` — «_They are written > INLINE on the element, so a stylesheet — yours or a theme's — **can never win > against them**; a rule that tried would be a rule that lies._» **Por qué se escapó, y por qué escuece.** El mandato del pase era **§15** (la capa flotante) y ese README es **§14/(a)** (`MeasuredIndicator`): otro mecanismo, idéntico absoluto. Y es **justo el README que la firma «(a) completada» (`de2e136a0`) reescribió** — la firma **arregló QUÉ enseñar (la PARTE, no las medidas) y dejó viva la mentira de POR QUÉ.** **La formulación correcta, VERBATIM de `ab54a8821`** (cópiala, no la reinventes): > «_…so no theme can win them (only an author `!important` rule overrides the > inline write, and that freezes the live geometry)…_» **Los 7 sitios, con su cita** (tabla completa y redacción propuesta en `next-features.md` §14-bis). ⚠ **Los identificadores de la columna «#» son los del BARRIDO del absoluto y no tienen nada que ver con el expediente A-1 del bloque (b)**: coinciden en las letras por accidente de numeración. | # (barrido) | sitio | qué dice | | ----------- | ------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | A-1 | `src/uix/soma/components/navigation-menu/README.md:182` | «_can never win against them_» — **el sexto README de la especie** | | A-2 | `src/uix/eidos/components/navigation-menu/README.md:104` | «ninguna hoja de tema **puede ganarles**» — **se auto-contradice en `:112`**, que ya dice «sólo una regla `!important` de autor llega» | | A-3 | `scripts/theming-sentinel-exceptions.ts:802` (`drawer.content-width-sm`) | «\*so **no cascade can beat it\***» — su propia cabecera `:798-801` sí acota, «cannot win **from :root**» | | A-4 | `scripts/theming-sentinel-exceptions.ts:1231` (`radio-group.dot-size`) | «\*an inline declaration **beats any stylesheet rule\***» — y **la MISMA entrada** propone arreglarlo con un `!important` («_the `!important` shape recipe-contract §3 allows for exactly this_») | | A-7 | `src/uix/eidos/components/radio-group/README.md:122` | «un inline gana a cualquier regla» | | B-1 | `src/uix/eidos/components/color-swatch/README.md:76` | «la declaración inline **gana siempre**» | | B-3 | `src/uix/eidos/components/background/README.md:333` | «no lo alcanzaría **(el inline gana)**» | **⚠ NO los corrijas de paso.** Dos de los siete (A-3, A-4) viven en `scripts/theming-sentinel-exceptions.ts`, que es **acta del ledger** y merece su propia pasada con su propio rigor; y A-2/A-4 se auto-contradicen dentro de la propia entrada, así que la corrección es de RAZÓN, no de frase. **No mueve píxel ni número**: el fichero de excepciones guarda razones, no claves — el conteo no cambia. **Ninguna de las dos firmas del eje queda invalidada — la medida las REFUERZA.** Medido en Chrome (1440×900, `:5180`, transiciones congeladas): con `--_navigation-menu-indicator-w: 333px !important` armado sobre el propio indicador, `inline-size` pinta **333px** mientras soma sigue escribiendo el rect verdadero (107 → 108,56px) y `left` sigue deslizando (111 → 0px). Es decir: **el `!important` de autor no redimensiona bien, CONGELA** — el subrayado deja de casar con su trigger. Un nombre cuyo único modo de «llegar» es desincronizar la geometría viva **es exactamente el token-que-miente que la firma retiró**, así que la firma pasa de UNA prueba a DOS. El item 2 de `53810cb5e` está intacto y su prosa también: venía acotada por escrito a `:root`, y su contrafáctico aguanta **incluso bajo `!important`**. ### (c) Lo que espera TU FIRMA - **§5 «Lo que espera TU FIRMA» sigue VIVA**: **once** entradas, **nueve esperando** (contadas una a una el 27 sobre la lista ya renumerada; las 3 y 10 quedaron marcadas como ejecutadas ese día, llevaban cerradas desde el 25 y el 24 sin tachar). La más urgente sigue siendo la **1**: el plano `overlay` impone tipografía a veinte componentes — hasta que se firme, **no acuñes `font-family` ni `line-height` en ninguna superficie `overlay`**. - _(Anotación 2026-08-27 al cierre — el bullet siguiente está **CUMPLIDO**: las dos cosas se firmaron y se ejecutaron el mismo día. El velo pinta —medido en Chrome real— y los 15 nombres están retirados. Lo que A-1 deja abierto no es ninguna de esas dos: son las **dos adjudicaciones registradas** —`--scrollbar-width` y los siete `--palabras-scheme-_`— que esperan firma en el registro de `src/uix/value-channels.test.ts`.)\* - **De A-1, sólo dos cosas exigen firma** (el resto es ejecutable bajo doctrina vigente, y es la QUINTA aplicación de la doctrina «la capa es la pluma, no la dueña»; la CUARTA es **§15** de `next-features.md`): (i) arreglar el velo del drawer **mueve píxel** — pasa de transparente a pintado; (ii) retirar los 15 nombres públicos sin contrato **rompe una API documentada**, aunque nunca haya tenido implementación del lado lector (0 lectores, medido y recontado con grep crudo por lo extremo del número). - **De C-1, una sola línea**: ¿la cascada de atajos de `box`/`grid` es DEUDA o es IDIOMA? De eso depende si el rojo del guard son **6, 22 o 26**. Criterio de quien lo midió: **no es deuda** — no discrepa, es una resolución longhand→shorthand que termina en el mismo `revert-layer` del contrato. - **El peldaño de «cabecera pegajosa»** sigue esperando (viene del handoff del 26, coordinación con el peer P0 sobre `header-z`). ### (d) Estado de COORDINACIÓN de la rama - **Rama COMPARTIDA `alpha-0.1-background`, con sesiones peer ACTIVAS.** Remoto `gita/alpha-0.1-background` = `05dcb4db7`; HEAD local `c91dd68be`, **ahead 2** — los dos sin pushear (`eb2a62fb8`, `c91dd68be`) son del eje P0/P1 del peer, no de theming. - **El hook pre-push está ARMADO** (`.git/hooks/pre-push`, byte a byte idéntico a `scripts/hooks/pre-push`) y el gate corrió en verde en los pushes de hoy. **No lo toques** — es de otra sesión. ⚠ Su comentario interno todavía dice «NOT ARMED until fase A is green»: prosa rancia del propio fichero, no el estado. - **Los CUATRO instrumentos del eje están LIMPIOS** — medido el 2026-08-27 al cierre: `git status --porcelain --` sobre `scripts/theming-census.ts` · `scripts/theming-census-debt.ts` · `scripts/theming-sentinel.ts` · `scripts/component-audit.ts` devuelve **vacío**, y `git diff HEAD` por fichero, también. **Consecuencia: el eje vuelve a poder medirse sobre árbol propio** — por eso el 161/5 de la tabla (a) es cifra de cierre y no señal. ⚠ Una versión anterior de este mismo bloque los daba a los cuatro por sucios de un peer: lo estuvieron durante el día y al re-medir ya no. **Vuelve a medirlo tú antes de fiarte de esta línea** — la rama es COMPARTIDA, y el estado del fichero de otro es OBSERVACIÓN, no estado. - **La regla de las DOS MANOS sigue vigente aunque hoy no muerda**: en rama compartida se hace ping, no se repara el fichero del otro. Y aunque hoy el censo esté limpio, si la aguja de A-1 quiere reusar su lector de contrato, **que nazca como fichero propio** igualmente: el peer vuelve. - **`web/routes/**`está CONGELADO por ley** (HEAD`05dcb4db7`): leer sí, escribir no. ⚠ Y `morfo-check`/`perm-check`/`component-audit` **validan contra ese árbol** — R-5.4, el guard de la especie «token que no mueve nada», corre a mano contra él. - **Deuda de formato preexistente**: ~2.300 ficheros nunca formateados; por eso `lint` sigue FUERA del gate. No la barras de paso. ## HANDOFF 2026-08-26 (noche) — histórico **El día ejecutó CINCO firmas más, todas con su adversarial**: la clasificación de los 318 privados (`e812d3ffd`+`a74aeec7b`+`90b93a79e`, adversarial 13/13) · la ley del ESPACIO CERRADO (`6499eb2a4`, 7/7) · el codemod de los 13 canales (`e100ea520`, atómico verificado) · el indicador de navigation-menu, (a) completada (`de2e136a0`, 6/6 — la especie `output` se propuso y se RECHAZÓ por abrir excepciones) · **§14, MeasuredIndicator con nombre poseído** (`8ac23047f` — «la capa es la pluma, no la dueña»; `tabs` cierra al 100 %). La familia de indicadores entera habla UNA doctrina. ### Lo PRIMERO mañana, por orden de valor 0. ~~**Los DOS guards rojos de `contracts.test.ts` que tocan el indicador**~~ — **✅ EJECUTADO 2026-08-26 (`1cb07c1e1`, firma ii del autor)**: no la declaración desnuda — la PLENA. `ready` es ESTADO de la parte (la especie de `checked`, no un prop): los dos morfos declaran `{ attr: 'data-ready', value: v.stateRef('ready'), severity: 'optional' }` con `states: ['ready']`, los providers registran la fuente (`() => this.indicator.ready`) y **el estampado manual muere** — la bolsa es la única tubería también aquí. `data-ready` SALE de `EIDOS_ONLY_ATTRS` con acta (ya no es eidos-only: es contrato). Verificado: guard sin los 2 rojos · morfo 222/222 · suites 3/3 · eidos-lint `[data-tabs-indicator]:not([data-ready])` morfo-backed, 0 invalid · check 0 atribuibles POR FICHERO · dinámica CDP: tabs `ready=""` desliza (0→103.9px), radio-group `segmented` ídem; control negativo GRATIS: pane oculto (rAF congelado) ⇒ sin medida ⇒ sin attr ⇒ `opacity: 0` — la puerta anti-flash aguanta. Coordinación con el peer P0 (vicen-42) por canal: `eidos-only-attrs.ts` era edición COMPARTIDA (sus altas de aura/waveform viajaron en mi commit con atribución declarada; su commit va detrás por dependencia de su guard). ⚠ Su adjudicación THEME-SYS-1 sobre `header-z` fue OBJETADA con tres hechos (token MEDIDO VIVO en sentinel-exceptions:410/437 · dos STALE · decisión del autor pendiente en `next-features.md:808` en dirección CONTRARIA) y ACEPTADA: revirtió entero y su guard registra la deuda NOMBRADA. El peldaño de «cabecera pegajosa» sigue esperando TU firma. Expediente original: (aviso de cierre del peer P0: su primera corrida histórica de la suite completa destapó 8 rojos preexistentes; 6 son suyos para su mañana, DOS son de este eje). El guard «hardcoded Soma component data attrs» flaguea `data-ready` estampado a mano en `tabs-provider.svelte.ts:473` y `radio-group-provider.svelte.ts:366`. **Proveniencia VERIFICADA: NO es de §14** (0 apariciones en `8ac23047f`) — lo introdujo `76f18a5e8`, cuyo propio mensaje ya avisaba «aparece un punto ciego del guard». La adjudicación está pre-masticada: `data-ready` es contrato REAL — lo leen `tabs.css:329` y `sliding-indicator.css:64-66` (la puerta anti-flash hasta la primera medida) — así que se DECLARA en los morfos de las dos partes indicadoras (tabs + radio-group), que es lo que el guard exige; ni exención ni retirada. Cambio de morfo ⇒ con su rigor, no de madrugada. ⚠ El hook pre-push sigue SIN ARMAR por esto (el peer no arma puerta en rojo — promesa cumplida); detalle de los 8 en `CONTINUE-audit-p0.md`. _(Anotación 2026-08-27: CADUCADO. El hook está **ARMADO** — `.git/hooks/pre-push` existe y es byte a byte idéntico a su fuente `scripts/hooks/pre-push`— y el gate corrió en verde en los pushes de hoy (reflog de `gita/alpha-0.1-background`, último `05dcb4db7`). ⚠ El COMENTARIO de dentro del hook sigue diciendo «NOT ARMED until fase A is green»: es prosa rancia del propio fichero, no el estado. No se tocó aquí — el hook es de otra sesión.)_ 1. ~~**§15 — el GEMELO un piso arriba**~~ — **✅ EJECUTADO 2026-08-26 (firma A del autor: §14 literal)**. Canal en el namespace del ANFITRIÓN: `FloatingContentOpts.component` (kebab del morfo, 11 hilos / 9 hosts), `--_{host}-floating-{transform-origin,available-w/h,anchor-w/h}`; el sexto nombre (`native-offset`) = canal INTERNO de capa `--_floating-native-offset`; el preset `scale-fade` lee el alias neutro `--_floating-transform-origin` declarado por cada receta (cableado sliding-indicator ×9); `getFloatingContentCSSVars` MUERTO. Matiz destapado: el content de menubar compone DropdownMenu ⇒ su canal es de dropdown-menu y el alias de menubar se acota al PANEL — el canal sigue al DUEÑO de la composición flotante; split-button/palabras leen canal ajeno en el punto de composición, anotado. Verificado: suites 96+60+78 · lint ×10 0 invalid · reach-floor 5/5 · audit 162 PASS · **dinámica CDP 9/9** con viejos VACÍOS, positivo exacto (tooltip 525.033 == canal; panel menubar 886px = barra) y negativo en `:root`. Acta completa: `next-features.md` §15. _Fe de erratas de atribución_: los tres hunks de `soma-architecture.md` que el cuerpo de `c494fb395` declara del peer eran de **vicen-41** (eje P0-docs; su commit hermano `70c01870a` los RECLAMA en su cuerpo — el fichero mismo viajó en `c494fb395`, 13 s antes), no de vicen-42. Ley del día, ya en el handoff P0: quien barre por RUTA se lleva los hunks del otro — la atribución se declara, y si se yerra el nombre, se corrige por acta, nunca por amend. 2. ~~**La especie de FORMA sin dueño**: `--indicator-duration`/`-ease`~~ — **✅ EJECUTADO 2026-08-26 (firma (a) del autor)**: ninguna de las dos opciones del expediente — son el ALIAS de la capa (especie de `--_indicator-x`, opcionales-con-fallback). Flip a `--_indicator-*`; la superficie de tema queda donde ya estaba y alcanza (las claves de contrato del anfitrión). Reparto de propiedad escrito: la capa posee QUÉ desliza, el anfitrión A QUÉ VELOCIDAD. Contrafáctico medido PRE-flip (el bare en `:root` jamás alcanzó: no se retiró superficie); post 4/4 caras. Acta completa: `next-features.md`, hueco flagged de §14. 3. ~~**Cableado `EidosConfig.motion`→CSS**~~ — **✅ EJECUTADO 2026-08-26 (firma opción 1 del autor; `e16c14dec`)**: `primitives.motion. staggerViewport: '70ms'` → `--motion-stagger-viewport`, y la regla `[data-stagger] > [data-animation-trigger='viewport']` EMIGRA de `motion.css` a `renderMotionBlocks`. `motion.css` deja de consumir `--motion-*`, así que la última entrada del registro murió **por mecánica** (cero guards tocados) y `PENDING_PRIVATE_RENAME` **se DESMONTÓ a cero**, no se dejó `{}`. Cero cambio de píxel (70 ms verbatim, medido en Chrome real). Acta: `changelog.md` §57 + `docs/canon/recipe-contract.md`. 4. **Re-clasificar `palabras`** (canal de valor del scheme, no tema) y **reabrir `timeline`** (§5 pre-B′) — los dos con expediente escrito. ### Estado de la RAMA al cerrar el día (léelo antes de tocar nada) - ~~**SIN PUSH desde `e100ea520`**~~: el codemod de canales, navigation-menu, §14 (`8ac23047f`) y el cierre documental del día. El resto del día está pusheado hasta `cec75d04e`. _(Anotación 2026-08-27: CADUCADO — **todo eso está PUSHEADO**. El remoto `gita/alpha-0.1-background` está en `05dcb4db7`, que contiene el codemod, navigation-menu, §14 y el cierre documental. Estado de HOY, medido: HEAD local `c91dd68be`, **ahead 2** sobre el remoto — los dos sin pushear (`eb2a62fb8`, `c91dd68be`) son del eje P0/P1 del peer, no de theming.)_ - **Sesión peer `vicen-63` ACTIVA en la rama** (auditoría P0): su C2c retiró los `syncAttrs` (los de tabs/radio-group VIAJARON en `8ac23047f` con atribución declarada y acuerdo por canal), su cirugía del runtime y su commit venían detrás, y **re-armará el hook pre-push** (`scripts/hooks/ pre-push` es la fuente; el gate ya pasa en verde sobre HEAD con el lint fuera hasta el one-shot de formato). Si un push falla, el mensaje del gate dice qué. La sesión de fichas (`vicen-3c`) commiteó `cc2894b36`. - **Protocolo de rama compartida que el día confirmó tres veces**: staging por RUTA explícita (nunca `add -A` — 375 ficheros a punto de colarse una vez), la RAÍZ del repo también se stagea (STUMBLES.md se quedó fuera una vez), y antes de medir un fichero, `git diff HEAD -- ` por si el peer lo movió. ### Las leyes nuevas del día (además de las firmas) - **El nombre dice la verdad en las DOS direcciones** — ni knobs que un tema no puede mover (el inline gana), ni privados que un README enseña como API. Cuando ninguna de las dos ortografías dice la verdad, la respuesta NO es una especie nueva: es preguntar qué está mal en el DISEÑO (así cayó `output`, y así el README de navigation-menu aprendió a enseñar la PARTE). > _Anotación 2026-08-27 — el inciso «(el inline gana)» es un ABSOLUTO FALSO._ > _La ley se queda con las palabras del 26 y NO se reescribe; esto es la > medida posterior que invalida ese paréntesis y sólo ese paréntesis: un > inline gana a toda regla **NORMAL** y **pierde ante un `!important` de > autor**. `docs/canon/recipe-contract.md:174` ya listaba «bypassing a soma > inline style» entre las tres formas legítimas de `!important`, así que el > canon nunca creyó el absoluto — lo escribió mal esta prosa._ **La ley no > cambia de sentido, se refuerza**: _cuando ese `!important` alcanza un canal > de VALOR no lo tematiza, lo **CONGELA** (medido en Chrome sobre el > indicador de `navigation-menu`: pineado a 333px, soma sigue midiendo el > rect verdadero 107 → 108,56px y `left` sigue deslizando, así que el > subrayado pinta 333px bajo triggers de 107px). Un nombre cuyo único modo de > «llegar» es desincronizar la geometría viva sigue siendo un knob que un > tema no puede mover. Acta larga y lista de sitios: `next-features.md` > §14-bis._ ⚠ **Disciplina de acta, que esta anotación existe para no volver a romper**: una sección FECHADA es REGISTRO HISTÓRICO. Se ANOTA —una entrada añadida, con su fecha, que dice qué medida posterior la invalida— y **nunca se reescribe en su sitio**. La primera pasada del 27 corrigió este paréntesis EN LÍNEA, de modo que el acta del 26 pasó a decir algo que el 26 no escribió y sin citar el original; se revirtió al texto de `613215fe7` y la corrección bajó aquí. - **El grep literal es ciego a la forma con llaves** (`--x-{a,b,c}`) — se barre por STEM. - **La sonda estándar es CIEGA a los canales** (PROPS sin translate/rotate/gridTemplateColumns/animationDuration): su 0-diff prueba lo circundante; el canal se verifica en DINÁMICA por CDP con control negativo y positivo. - **Un alias sin prefijo propio ni siquiera entra al clasificador** — y una causa escrita sin su contrafáctico medido acaba corregida por el adversarial (pasó dos veces hoy). ## HANDOFF 2026-08-25 (noche) — histórico **Las CINCO firmas del eje están EJECUTADAS y pusheadas** (`2daa683fa` file-upload · `df3a4d054` form/compuesto · `2ce43db56` tags-input aria · `1f8ce293b` avatar · `466b24f34` chip/suelo §55). Después cayeron los expedientes de §13: `d5a27b87e` (árbol ARIA de tags-input, cierra F-1) · `3bf7930ba` (el velo no muere por un atajo + pin de chronos, §56) · `318aac207` (la talla de form LLEGA, doctrina anchura-vs-densidad). ### Lo PRIMERO mañana: dos firmas de INSTRUMENTO, en este orden 1. ~~**«La mitad gratis»**~~ — **✅ FIRMADA Y EJECUTADA 2026-08-25** (`047464389`; ver §«FIRMA EJECUTADA — la mitad gratis» justo abajo). Expediente original: scratchpad de la sesión `6314e22b…/scratchpad/bprime/exped/va/informe.md` (1.019 líneas). 2. ~~**La GRANDE: cuatro cegueras + TRES BARRIDOS escalonados.**~~ — **✅ FIRMADA Y EJECUTADA 2026-08-25** (`6392d6003` S1 · `b4dd5a906` S2 · `b9cef9a43` S3; ver §«FIRMA EJECUTADA — la GRANDE» abajo). Se ejecutó exactamente con el plan de VA: tres barridos escalonados, sin fusionar S2 y S3, y la atribución quedó limpia. ### FIRMA EJECUTADA (2026-08-26) — el codemod de los 14 canales (13 de 14) **Qué se ejecutó**: los nombres públicos-con-forma que soma o el envoltorio escriben POR INSTANCIA pasan a privados `--_{c}-*` — el destino que la firma de los 318 ya había firmado (clase `channel`) y que el registro `PENDING_PRIVATE_RENAME` sólo contaba. **Trece renombrados, sus trece entradas del registro RETIRADAS con acta**; el registro queda en **DOS** (no en una): la de motion, que era la prevista, y una PARADA. **El método, y es la mitad del resultado**: barrido `git ls-files` **de cada nombre por el árbol trackeado entero** (94 ocurrencias en 36 ficheros), y flip **ATÓMICO por nombre** — escritor y TODOS los lectores en la misma edición. Nada de grepear los propios patrones: el barrido destapó lectores que ninguna lista traía (el comentario del morfo de `knob`, las dos páginas de demo, nueve menciones en `PLAN-background.md`). **✅ RESUELTO — `--navigation-menu-indicator-h`, con (a) FIRMADA Y EJECUTADA (2026-08-26, tarde).** Estuvo PARADO porque no era un canal suelto: el provider escribe **CUATRO hermanas** en un mismo literal, el README de soma las enseñaba las cuatro bajo `## CSS Variables` como forma controlada por el consumidor (con dos ejemplos leyendo `-h`), y **`-w` era clave DECLARADA del contrato** — la única razón por la que el guard veía a `-h` sola. Ver §«FIRMA EJECUTADA — el indicador de navigation-menu» abajo. **El registro queda en UNA** (motion). **⚠ LA TRAMPA DEL CENSO NO MORDIÓ, y la predicción estaba MAL por un orden de magnitud.** Se esperaba que ~15 knobs pasaran de `public` a `channel` y que el suelo pudiera rozar el redondeo. Medido: **UNA sola clave** se reclasifica —`color-swatch.background`— porque el censo cuenta **knobs de APARIENCIA**, y las otras doce viven en declaraciones de GEOMETRÍA (`translate`, `rotate`, `inline-size`, `grid-template-columns`, `animation-duration`) o en declaraciones que **conservan un público hermano** y siguen puntuando `public` (el `conic-gradient` de `knob` lee `--knob-track-bg`; el panel de `menubar` lee `--menubar-panel-min-width` como fallback). Números: `public` 3074 → **3073**, `channel` 36 → **37**, denominador 4228 → 4227, reach **73 %**, `atHundred` **65**, ledger **1154 · 0 NEW · 0 STALE**. **El suelo NO se toca** — no hubo nada que ajustar ni que fingir. **Neutralidad, medida en dos planos.** Estática: sonda estándar antes/después sobre los 7 componentes, **0 diffs reales**; el único diff (`emoji-picker`, un `background-image` de velo en el trigger, bloque `open`) se **reprodujo 2/2 sobre código idéntico** — ruido del instrumento. ⚠ `color-swatch` **no tiene ruta de demo** (404) y la sonda devuelve **0 nodos**: su «0 diffs» es un guard que no inspecciona nada y NO cuenta como prueba; se midió donde de verdad monta. Dinámica (donde estos canales viven y la sonda no llega), 7/7 por CDP: `background` puntero →`_x −0.7/0.8`, `_y −0.6/0.7`, `_px 15 %/90 %`, `_py 20 %/85 %`, translate `−28px −24px` → `32px 28px` (= x × depth 40px, exacto) y el foco del spotlight `at 15 % 20 %` → `at 90 % 85 %`; el quinto canal (`--_background-progress`) es la rama `@supports not(view())` que Chrome nunca corre, verificada forzando el gate: `0.379 → 1` al scrollear · `knob` accionado por teclado, `_angle −27deg → 0deg`, `_progress 0.4 → 0.5`, el indicador rota igual y la parada del arco `108deg → 135deg` (= progress × sweep) · `color-swatch` tres chips, `#7c3aed/#06b6d4/#f59e0b` → `rgb(124,58,237)` / `rgb(6,182,212)` / `rgb(245,158,11)` · `emoji-picker` privado 9 → 9 tracks, y moverlo a 6 y a 12 da 6 y 12 tracks, **mientras fijar el nombre VIEJO a 3 no mueve nada** (control negativo) · `menubar` panel anclado, `_anchorWidth 886px` = barra 886 = panel 886 · `navigation-menu` (el PARADO) sin regresión, `-h` sigue pública en 36px = altura del trigger activo · `text-gradient` inline `8s` → `animation-duration: 8s` en el hijo `[data-text-gradient-fill]`. **En los siete, el nombre VIEJO computa vacío.** **Guard mutado por sus dos caras**: reintroducir una entrada retirada → **STALE nombrándola**; devolver un nombre público viejo a una receta → **`missing` nombrándolo**. Suites de los tocados 18/18, `component:audit` **162 PASS / 4 NEEDS-WORK** idéntico, `docs:check` **0/0**, `--names` **0 desviadas**, `npm run check` **0 errores atribuibles** (verificado POR FICHERO). **Docs: se ANOTARON, no se reescribieron** — fichas medidas, README de `color-swatch`, `PLAN-background.md` (una anotación fechada cubre sus nueve) y `STUMBLES.md` §7. El nombre nuevo sí se volcó donde el texto describe código VIVO (READMEs de componente y las dos demos). Queda anotada la fila GENERADA `audit/theming/background.md:72`, que la regenerará el `--report` pendiente. **Hallazgo lateral, ajeno**: el control `columns` de la demo de `emoji-picker` es un `` DESNUDO y `slider.svelte` renderiza sólo su provider — un `div[data-slider]` **vacío**, sin raíl ni pulgar. No se puede accionar. ### FIRMA EJECUTADA (2026-08-26) — el indicador de navigation-menu **Qué se firmó**: la opción **(a)** del PARADO. Las CUATRO medidas del trigger activo pasan a privadas — `--_navigation-menu-indicator-{x,y,w,h}`, flip ATÓMICO escritor + todos los lectores, con barrido `git ls-files` por nombre —, **`indicator-w` se RETIRA del contrato** (44 → 43 filas) y la sección `## CSS Variables` del README de soma se reescribe al camino de la casa: el consumidor estiliza **la PARTE** (`[data-navigation-menu-indicator]` y su `data-state`) con los tres pomos de forma, no las medidas. **Lo que se RECHAZÓ, y por qué importa**: (b) declarar `-x/-y/-h` para casar con el README bendeciría como superficie de tema cuatro medidas por instancia — justo lo que la clase `channel` de la firma de los 318 existe para negar. Y se rechazó una especie nueva, **`output`** (tercera clase entre público y privado): abre excepciones sobre una clase barata con frontera de PROSA, patrón ya rechazado dos veces. **`-w` era un token-que-miente, MEDIDO** (CDP, transiciones CONGELADAS — en esta parte `inline-size` va transicionada y una lectura inmediata devuelve el valor VIEJO; el probe informaba «no se movió» de TODO hasta congelarlas): con el subrayado pintado, escribirlo en la raíz del componente —lo que hace el centinela— deja `inline-size` en **107px**, y en `:root` igual; **sólo una regla `!important` de autor llega** (1234px), porque soma escribe INLINE en el elemento. La única ventana donde la declaración asomaba es el indicador montado **SIN rect todavía** (`isOpen` true, `triggerRect` aún null; o `forceMount`): ahí `inline-size` lee el `0px` que daba esta clave y un write en el host lo mueve a 1234px. Es decir, llegaba **sólo donde no pintaba nada**. ⚠ El indicador está montado CONDICIONALMENTE (`{#if state.isOpen || forceMount}`): con la barra cerrada hay **0 nodos** en la página. **Números**: `public` 3073 → **3072**, `channel` 37 → **38**, denominador 4227 → 4226, reach **73 %** y `atHundred` **65** intactos, `--names` 4567 → **4566** (0 desviadas), ledger **1154 · 0 new · 0 stale**. Centinela `navigation-menu` **43/44 → 42/43**, misma única adjudicación (`disabled-trigger-fg`): el total baja porque la clave sale del contrato, no porque nada deje de llegar — **el fichero de excepciones no se toca**. `component:audit` **162 PASS / 4 NEEDS-WORK** idéntico. **Dinámica, que es la que vale aquí** (la sonda estándar es ciega a estos canales): Products `w=107px h=36px` = rect del trigger, Solutions `w=108.5625px h=36px`, `inline-size` las sigue (107 → 108.562) y `left` **0px → 111px** — el subrayado DESLIZA — con `translateY(36px)` estable. **Control negativo**: los nombres viejos computan **VACÍO** en el indicador, y fijarlos en la raíz a 777px/333px no mueve nada. **Control positivo**: los tres pomos del contrato siguen llegando (`block-size` 2 → 9px, `background` → `rgb(1,2,3)`). **Guard**: `PENDING_PRIVATE_RENAME` queda en **UNA** entrada (motion), con acta en el propio registro. Mutado por sus dos caras: reintroducir la entrada retirada → **STALE nombrándola**; devolver `--navigation-menu-indicator-w` a la receta → **`missing` nombrándolo**. _(Anotación 2026-08-26, más tarde el mismo día: esa última entrada cayó con el cableado de `staggerViewport` y el registro **se desmontó a CERO** — ver el punto 3 de «SIGUIENTE» arriba.)_ **⚠ Trampa del barrido**: el grep del nombre LITERAL es CIEGO a la forma con llaves `--…-indicator-{x,y,w,h}`, que escondía tres menciones más (el comentario de `navigation-menu.svelte` de eidos y dos filas de la demo). Hay que barrer también la familia. **Hueco FLAGGED, no acuñado**: el ejemplo viejo de _píldora / fondo de trigger_ no tiene traducción a pomos — la receta clava el `block-size` al grosor. Queda en §13 de `next-features.md`, sin inventar un eje de forma. **Abre expediente**: §14 de `next-features.md` — unificar `tabs` bajo la misma adjudicación (`--indicator-{x,y,w,h}` SIN prefijo, escritos por la capa compartida `MeasuredIndicator`, 2 entradas `global` en el ledger). **EJECUTADA el mismo día**; ver la firma inmediatamente debajo. _Fe de erratas 2026-08-27 — el absoluto de cascada viajó por SEIS READMEs, no por cinco._ El pase adversarial `ab54a8821` corrigió la frase «_so no theme **or consumer stylesheet** can win them_» → «_so no theme can win them (only an author `!important` rule overrides the inline write, and that freezes the live geometry)_» en los **cinco** READMEs de §15 (`popover`, `tooltip`, `context-menu`, `link-preview`, `menubar`). Se le escapó el **sexto**: `src/uix/soma/components/navigation-menu/README.md`, que dice «\*a stylesheet — yours or a theme's — **can never win against them\***». Motivo de la fuga: el mandato del pase era §15 (la capa flotante) y ese README es **§14/(a)** (`MeasuredIndicator`) — otro mecanismo, idéntico absoluto. Es además el README que ESTA firma reescribió: **arregló qué enseñar y dejó viva la mentira de por qué.** Su gemelo de eidos (`src/uix/eidos/components/navigation-menu/ README.md`) se contradice a nueve líneas de distancia: dice «ninguna hoja de tema puede ganarles» y luego «sólo una regla `!important` de autor llega». **La firma NO queda invalidada — la medida del 27 la REFUERZA.** Medido en Chrome (1440×900, `:5180`, transiciones congeladas, un solo nodo, serie única): con `--_navigation-menu-indicator-w: 333px !important` armado sobre el propio indicador, `inline-size` pinta **333px** mientras soma sigue escribiendo el rect verdadero (107px → 108,56px) y `left` sigue deslizando (111px → 0px). Es decir: **el `!important` de autor no redimensiona bien, CONGELA** — el subrayado deja de casar con su trigger. Un nombre cuyo único modo de «llegar» es desincronizar la geometría viva es exactamente el token-que-miente que esta firma retiró, así que la firma pasa de UNA prueba a DOS. Discriminantes de la misma sesión: el nombre PÚBLICO retirado, con `!important` y sobre el elemento, **no mueve nada** (0 consumidores — la retirada es neutra bajo cualquier régimen de cascada); el canal en `:root` con `!important` tampoco llega (herencia no compite con la declaración propia del elemento); y sin `!important` sobre el elemento, tampoco. **Los cuerpos de commit no necesitan fe de erratas**: `de2e136a0` ya decía «sólo una regla `!important` de autor le llegaba», `53810cb5e` ya acotaba a `:root`, y `6499eb2a4` / `8ac23047f` no contienen ningún absoluto de cascada. **El canon tampoco se equivocó**: `docs/canon/recipe-contract.md:174` lista «_bypassing a soma inline style_» entre las tres formas legítimas de `!important`. Sólo lo escribió mal la prosa de componente. Acta larga y lista de sitios: `next-features.md` §14-bis. ### FIRMA EJECUTADA (2026-08-26) — §14, MeasuredIndicator con nombre POSEÍDO **Qué se firmó**: la geometría que una capa COMPARTIDA publica es **canal** y aterriza en el **namespace del ANFITRIÓN** —`--_{c}-indicator-{x,y,w,h}`—, no en uno de capa. Tercera aplicación de la doctrina (`navigation-menu` fue la segunda). **La capa es la PLUMA, no la dueña**: el rect es un hecho de cada instancia del host. Un solo nombre de capa habría repetido el defecto un piso más abajo — una medida por instancia en un espacio que nadie posee. **Cómo llega el nombre**: `MeasuredIndicatorOpts` gana **un** campo, `component: string`, y los dos hosts —los únicos, `git grep "new MeasuredIndicator"`— pasan `tabsMorfo.kebab` / `radioGroupMorfo.kebab`, **nunca un literal**: el canal queda atado a la declaración de morfo que lo posee. **Cableado del CSS compartido** (`lib/sliding-indicator.css`, que no puede deletrear el nombre del host): cada receta declara su alias local explícito —`--_indicator-x: var(--_radio-group-indicator-x)`— y el compartido lee el alias. Forma del puente THM-2, la misma que `calendar-surface.css` usa para `--_calendar-surface-accent`: contrato EN el artefacto. `tabs` no consume la capa (tiene bloque propio) y lee el nombre poseído directo. **Números**: `tabs` **97 % → 100 %** (global 2 → 0, canal 0 → 2; 77 knobs y 79 claves de contrato INTACTOS — ni una acuñada ni retirada). Catálogo `atHundred` **65 → 66**, global 763 → 761, canal 38 → 41, reach global **73 % intacto**, `--names` 4566 · 0 desviadas. Ledger: las **2 entradas de `tabs` retiradas** (la clave entera desaparece), **1154 → 1152 · 0 NEW · 0 STALE**, con acta en la cabecera de `theming-census-debt.ts`. `radio-group` no mueve una cifra. **⚠ La trampa de clasificación, prevista y resuelta** — _causa CORREGIDA por el adversarial el mismo día_: la premisa del alias que «esquiva y cae a residuo» era CONTRAFACTUAL — el alias de §14 no lleva prefijo propio, el censo lo descarta antes de coleccionar privados, y un knob que lo lea clasifica `global` con la razón CORRECTA (medido construyéndolo: `1 new`, rojo). La extensión TRANSITIVA del tercer paso se justifica por `tooltip` (alias con prefijo propio sobre canal propio, reclasificado `exception` → `channel` como su comentario firmado afirmaba); molde de `derivesFromPublic`. **Mutación de rigor**: un alias hacia un privado que SÍ está declarado NO clasifica canal — `refs.length > 0` es la línea que lo impone. Y el ORDEN de pasos es carga estructural: el segundo (deriva de un público) corre antes, y por eso `--_tooltip-max-width` sigue siendo público. **⚠ Un knob AJENO se reclasificó, con acta**: `tooltip.css:27` pasó de `exception` a `channel`. **No es regresión**: el comentario firmado de esa declaración ya decía «per-instance VALUE CHANNEL» con esas palabras — faltaba el mecanismo, no el criterio, que es literalmente lo que el cuarto paso del censo dice de sí mismo. `tooltip` no mueve su alcance. Acta en su ficha, §2-quater. **⚠ La sonda estándar es CIEGA a esta clase de firma**: lee valores computados, no nombres de var, así que un flip de nombre correcto le sale idéntico por construcción. Sus **0 diffs en 2528 valores × 10 estados** prueban lo CIRCUNDANTE, no el flip. Quien prueba el flip es la dinámica, y hay que CONGELAR transiciones o `inline-size` devuelve el valor viejo: `tabs` desliza (`translate 0 → 183.719px`, `inline-size 99.906 → 71.359px`, indicador exacto sobre el trigger activo), `radio-group` sólo manifiesta su indicador en la variante **`segmented`** y desliza igual (`4px 32px → 4px 60px`). Los cuatro nombres viejos computan **cadena vacía** en ambos; control negativo en `:root` a cero; control positivo probando además la CADENA del alias. **Hueco FLAGGED, no acuñado**: ~~`--indicator-duration` / `--indicator-ease` siguen bare~~ — **RESUELTO el item 2 (2026-08-26, `53810cb5e`)**: eran el ALIAS de la capa, no contrato ni vocabulario; hoy son `--_indicator-{duration,ease}`. Acta en `next-features.md` (hueco flagged de §14). ### FIRMA EJECUTADA (2026-08-26) — la ley del espacio cerrado **Qué se firmó**: el espacio de nombres público es **CERRADO sobre el contrato** — un `--{c}-*` existe **si y sólo si** `base.ts` lo declara, no hay tercer estado. Corolarios: el fallback es dispositivo de seguridad de VALOR, no escapatoria de contrato; declarada la clave, el fallback inline sobre el nombre público PROPIO muere (el default vive en UN sitio); el guard de fantasmas pasa al «si y sólo si» — un `--{c}-*` propio fuera de contrato es rojo, con o sin fallback. El vocabulario AJENO (préstamo de otro componente) y el de sistema conservan sus reglas: el guard filtra por prefijo propio y no los ve. **Lo que el barrido previo encontró — y por qué importa**: no eran dos componentes. El catálogo tenía **25 nombres propios con fallback fuera de contrato en 10 componentes** (27 sitios), y se parten en DOS CLASES: - **11 knobs de tema de verdad** → declarados: `mockup` ×9, `text-scramble` ×2. - **14 CANALES DE VALOR** que soma o el envoltorio escriben inline por instancia → **NO se declaran** (declararlos revertiría la firma medida del 2026-08-23 que retiró `--color-swatch-fill` del contrato) **ni se renombran aquí** (es codemod de otro eje). Van a un REGISTRO nombrado y fechado dentro del propio test, `PENDING_PRIVATE_RENAME`, con razón y destino por entrada. \+ `--motion-stagger-each-default`, que no es canal (nadie lo escribe): su default pertenece a `EidosConfig.motion`. **15 entradas.** El registro es el patrón ledger de la casa: **no bendice, cuenta**, y **sólo puede menguar** — una entrada que deja de describir un consumo (renombrada, declarada, muerta) se reporta **STALE** y sigue roja hasta borrar la línea. _(Anotación 2026-08-26, al cierre del día: menguó hasta **CERO** el mismo día en que nació —13 por el codemod, `--navigation-menu-indicator-h` por firma, y `--motion-stagger-each-default` por el cableado de `staggerViewport`— y **se DESMONTÓ**, no se dejó `{}`: un `it` sobre un registro vacío no afirma nada.)_ **La mentira que la ley mató, en concreto**: `--mockup-shadow` cargaba DOS defaults bajo un nombre — `var(--shadow-4)` en el marco, `var(--shadow-5)` en el bisel del teléfono — así que un tema que lo moviera no podía saber cuál de los dos tocaba. Se acuñó `--mockup-phone-shadow`: superficie distinta, nombre distinto. El TSC no podía expresarlo de otro modo (sus ejes de scope son cerrados y `data-chrome` no es uno). **Neutra en píxel, medida dos veces**: el diff de `generated/` son esas 11 líneas con su default verbatim y NADA más; y el A/B en navegador — cada token nuevo forzado a `initial` con las declaraciones viejas restauradas inline — dio computed idéntico en los tres mockups de `/blocks/feature-split` (ambos cromos; el bisel conserva `shadow-5` y el marco `shadow-4`, que era justo lo que la acuñación protegía) y en `text-scramble`. ⚠ `mockup` **no tiene ruta de demo propia**: se mide donde de verdad monta, en `/blocks/*`. **Números**: `no contract entry` **18 → 16**; todo lo demás QUIETO — reach 73 %, 65 al 100 %, ledger 1154 · 0 NEW · 0 STALE, audit **162 PASS / 4 NEEDS-WORK** idéntico, `--names` 0 desviadas, `docs:check` 0/0. El suelo NO sube: la ley cerraba un hueco de CONTRATO, no de alcance (esas declaraciones ya puntuaban `public` — lo que faltaba era declarar el NOMBRE). **Muta-prueba de tres caras**: `var(--mockup-inventado, red)` (propio, CON fallback) → **rojo nombrando la clave** · el mismo inyectado con un nombre AJENO y fallback → **verde** · una entrada del registro que deja de describir un consumo → **rojo STALE nombrándola**. **Efecto lateral que hay que saber**: el crudo `var(--primitive-neutral-12)` migró verbatim de `mockup.css:73` a `base.ts` como default de `mockup.phone-bezel`. Sigue siendo deuda R-4.6 — pero la regla escanea CSS de componente y ya no lo ve, así que la fila de `mockup` perdió ese error **sin que nadie lo arreglara**. Queda anotado en la propia clave y en `next-features.md`; `mockup` sigue NEEDS-WORK por su E-2.3 (README ausente). ### FIRMA EJECUTADA (2026-08-26) — los 318 privados no-derivados **Qué se firmó**: la «clasificación de los 318», en tres piezas — `e812d3ffd` (F1: el censo aprende a MEDIR puente y canal) · `a74aeec7b` (F2: el residuo adjudicado clave a clave) · este commit (F3: el suelo sube y la prosa se salda). Cierra el agujero que la cabecera del ledger nombraba: la tercera clase no-alcanzada ya no vive sólo bajo el `reachPct` grueso. **La aritmética, sin resto**: 318 = **132 puente** + **36 canal** + **84 anotados** + **66 al ledger**. Las dos primeras las decide la MEDIDA (el puente contra la salida real de `renderRecipePaletteForward`, no contra la forma del nombre; el canal contra quién escribe el privado — nadie lo declara, lo pone soma o el envoltorio por instancia); las otras dos son actos: la válvula nueva `/* private: */` sobre la declaración (clase `exception`, la de siempre, no un tier nuevo) y una entrada de ledger con `private` como `DebtClass` de pleno derecho, con `newDebt` y STALE simétricos. **Los cuatro números que quedan vigentes**: reach **73 %** (3074/4228 — el numerador NO se movió, cayó el denominador 4480 → 4228) · **65 componentes al 100 %** · ledger **1154** claves (763 global + 325 literal + 66 private) · **162 PASS** en `component:audit`, idéntico. > _Anotación 2026-08-27 — los CUATRO se movieron. El acta de arriba NO se > reescribe (es el registro del 26); esto es la medida posterior que la > invalida como cifra de HOY:_ > > - _reach **73 %**, pero **3073/4223** — no 3074/4228. Lo movió `830cd7671` > («la aguja del censo dejaba de ver lo que Prettier partía en dos líneas»): > dos knobs mal clasificados por una aguja que exigía `var(--` literal > mientras Prettier había escrito `var( --`. NO es deuda perdonada — ninguna > receta cambió — es una mala clasificación corregida en su fuente._ > - **\*67** componentes al 100 %, no 65 (`atHundred` 66 → 67 por la misma > grieta). Es el número que el suelo `FLOOR.minAtHundred` exige hoy.\* > - _ledger **1150** claves = **760** global + **324** literal + **66** > private (1152 → 1150 por la misma corrección). Se midió sobre el blob > COMMITEADO de `scripts/theming-census-debt.ts` porque el peer lo tenía > sucio; al cierre del 27 el fichero está limpio y ambos coinciden. Cuadra > por dos > vías: la suma por clase da 1150, y 4223 − 3073 = 1150 — el ledger registra > exactamente cada declaración no alcanzada, una a una._ > - **_161 PASS / 5 NEEDS-WORK_** en `component:audit`, no 162 PASS. El caído > es **`color-picker` por A-3.7** (cobertura evento/teclado), que es del eje > **P1/morfo — NO de theming**. Se anotó primero con la salvedad de estar > medida sobre un árbol MODIFICADO por un peer (`component-audit.ts` sucio); > **re-medida ese mismo día sobre árbol quieto da el MISMO 161 PASS / 5 > NEEDS-WORK / 0 BROKEN sobre 166 componentes**, así que la salvedad se > retira y el número vale como cifra de cierre.\* **Las cuatro contradicciones con ficha que la medida destapó** (F2 las dejó señaladas; ninguna se resolvió a ojo): - `metrics` — su §5 firmado decía que el conmutador del icono derivaba ENTERO de públicos. Cierto para `track`/`text`, **falso** para `solid`/`contrast`, que leen roles crudos. Resuelto POR MEDIDA: 3 anotados, 2 al ledger. - `timeline` — su §5 es **pre-B′** y se respetó tal cual (10 knobs, 5 notas). Queda SEÑALADO para reabrir si la escalera de paleta de B′ pesa más que aquel veredicto. - `proof-of-human` — 17 knobs adjudicados por DOS notas, **sin §5 propia** que lo dijera: la base del alias es verbatim la que el forward declara para ese slot (medido dos veces). El alias `--_proof-of-human-accent{,-soft}` es **borrable a coste cero de píxel** — leer el puente directo clasificaría `bridge` sin anotación; registrado como trabajo futuro en §13. - `listbox` — sus 6 knobs (5 notas) dicen «adopto la capa `list-surface`», y son **reversibles** el día que §13 le dé receta propia a esa capa (diez componentes de golpe). ### FIRMA EJECUTADA (2026-08-25) — «la mitad gratis»: cegueras 4 y 5, coste de ledger CERO **Qué se firmó** (`047464389`): las dos piezas del expediente VA que NO compartían el coste caro — el codemod ciego a la IIFE con sus dos hermanos, y los cinco huecos de la sonda más el sexto propio (el pase de FOCO prometido e inexistente). Tres ficheros, **ni una entrada del ledger**. Ejecutada por cuatro agentes (tres constructores + uno ADVERSARIAL con mandato de refutar), con bases capturadas ANTES de editar. **Los números**: centinela `label` 1/2 y `switch` 27/52 **byte a byte idénticos** a las bases pre-firma; sonda de `card` **0 diffs en sus 7 bloques viejos**; `editable` estrena bloque `open` (25 filas, 6 con `data-editing`) y dos corridas sobre código idéntico dan **0 diffs en TODOS los bloques**; `menubar` abre por la entrada del centinela (6 nodos → 7, con el panel) y `chat-message` 24 filas × 2 corridas = 0 diffs; codemod 145/145 bloques, avatar `depth 3` con **97** claves (86 públicas + 11 privadas), laboratorio sobre copias (duplicado inyectado DETECTADO, renombrado = 1 línea); importar el centinela: 0,85 s sin navegador. **Las decisiones que deja escritas**: - `COMPONENT_OVERRIDES` es **UNA tabla**: la sonda la importa y `OPEN_TRIGGER` se poda de sus copias literales. La guarda de entrypoint lleva `realpathSync` — hallazgo del adversarial: sin el realpath muere a través de un junction (exit 0 sin inspeccionar nada), y este repo usa worktrees con junctions. - La vía de carga del codemod **SE QUEDA en tsx**: «el censo corre con node pelado» era FALSO (todo `src/uix/morfo` importa sin extensión). - `prepareWith` en la sonda sólo corre sin fila en `DEMO_VARIANTS` (re-clicar APAGA los checkboxes que `prepare()` ya encendió) — y eso deja a la vista la deuda de `search-field` (§13). - El no-determinismo de `chat-message` quedó ACOTADO al bloque `rest` de la sonda (13 vs 16 nodos, chips sin cuajar al medir) — dato para la GRANDE. **Lo que quedó fuera, con su registro en §13**: el barrido de variantes de la sonda (ensanche diferido por el propio expediente) · el clear-trigger de `search-field` en el pase `open` · la asimetría de escenario de los seis con `prepareWith` sin fila · el cortocircuito `alreadyOpen` que la sonda no tiene · y **TRES lectores independientes** de la estructura de `base.ts` (codemod, censo, centinela — la próxima forma nueva se enseña tres veces). El `catch` del `prepareWith` del CENTINELA sigue MUDO **a propósito**: es la ceguera 6, S1 de la GRANDE. ### FIRMA EJECUTADA (2026-08-25) — «la GRANDE»: el guard deja de estar ciego, en tres barridos **Qué se firmó** (`6392d6003` · `b4dd5a906` · `b9cef9a43`): las cegueras 6+1+3+2 del expediente VA, UNA firma, TRES barridos del ledger ENTERO (91 componentes cada uno), ejecutada con el mismo esquema de agentes que «la mitad gratis» (tres constructores en serie + adversarial con mandato de refutar: **12/12 claims confirmados**). - **S1** — el `prepareWith` GRITA (lo que cae en su catch es un control que estaba y falló — la fuente de las muertes fantasma) y el STALE ve los PATRONES (`reasonFor`, mensaje que distingue «retira la exacta» de «ESTRECHA el patrón»). Barrido: 91/91 verdes, 40,8 min, 0 avisos. Cosecha: los dos patrones `PLANE_SUPERSEDED` de `toast` (18 claves), rancios desde la noche de §12.9, RETIRADOS con 3/3 de reproducción. - **S2** — el chooser tipa la sonda por el VALOR por defecto leído de `base.ts`, no por el nombre (357 claves cambian de sonda; 320 de la clase A «vivo por accidente» IACVT). MONÓTONO medido: 91/91, sólo `avatar` +1 y `stepper` +1, sus dos exactas retiradas. Ni `%` ni enteros se clasifican (tipar el `0` habría matado en falso 7 claves vivas). - **S3** — tono+estado: tono en el pase de hover · tono MEDIAL `(^|-)` (las 16 de `tag-group`) · hover para claves de tono muertas (las 21 de `file-upload`) · seis ejes de estado como DATO, valores del morfo/receta/DOM real. Barrido: 91/91, 43,8 min, exactamente los 9 previstos, **+140 claves (catálogo 2776 → 2918, 78 % → 82 % de claves vivas)**. **130/132 `TONE_UNREACHED` reviven; las 2 que no eran `PALETTE_FLOOR`** (el tono HOST por defecto — test de dos caras en checkbox y radio-group, firma idéntica en los ocho componentes). **El ledger después**: 10 patrones retirados + 2 estrechados + 7 exactas retiradas + la constante `TONE_UNREACHED` RETIRADA (la muerte que su docstring pedía). Tier de patrones **28 → 16, 15 de los 16 son el único hecho `PALETTE_FLOOR`**, y el adversarial verificó que los 16 cubren SOLO claves muertas — cero zombis — y que ninguna clave muerta quedó sin razón (659 muertas, 0 sin adjudicar). **Dos correcciones al expediente, reproducidas dos veces antes de tocar**: las `-text` de `tags-input` SÍ reviven (la causa del arquetipo sólo tapa el ítem RESALTADO; la escena no tiene ninguno, y el token pinta además dos nodos hermanos fuera de esa regla) · `tag-group.hover-item-fg` la callaba su `data-state='selected'` nativo — el nodo es un `` que ninguna regla de arquetipo toca. **Deuda nueva registrada en §13** (adversarial, ninguna bloquea): la asimetría del estampado (`data-color` en TODOS los nodos vs sólo el proveedor en producción — medido que NO es la causa de ninguna revivida) · el ternario falsy de la restauración de atributos (un `attr=""` se borra en vez de restaurarse; hoy inocuo) · `checkbox.stroke-ease` con sonda de color (única de las 51 de easing) · el residuo del recorte del hover (`button.palette-element`, escrito en su propia razón). ### EL CIERRE, EJECUTADO (2026-08-25) — deuda B + clase `structural` + R-5 a `error` con LEDGER **✅ EJECUTADO** con el mismo esquema de agentes (tres constructores + un adversarial que confirmó 11 claims y refutó dos números de prosa). Cinco commits: `2c61946fb` (clase `structural`) · `ef47f3447` (deuda B) · `69d69d43c` (el ledger de deuda) · `1ba518fcc` (correcciones del adversarial). - **Deuda B saldada**: `proof-of-human` (20 claves derivadas) · `audio-player` (README nuevo; es un skin sobre media-player que consume sus 61 claves y añade 8; sin demo propia a propósito) · `palabras` (sección honesta SIN tabla: sin contrato en `base.ts`, y sus 117 nombres `--palabras-*` son la proyección del `scheme-style` del documento — canal de VALOR, otro eje; la clasificación del censo sobre él queda EN CUESTIÓN, §13). - **Clase `structural`**: los cinco 0 %-por-naturaleza (`aspect-ratio` · `text-blur` · `cascade` · `motion` · `date-picker`) salen del denominador con su razón EN el artefacto (forma `LAYER_VOCABULARY`). Reach 68 → 69 %, no-contract 23 → 18, el gate deja de ser inalcanzable por construcción. - **R-5 a `error` con LEDGER DE DEUDA — la firma que rediseñó F3**: la deuda real (1088 claves: 763 global + 325 literal, carriles WIP DENTRO) se registra UNA vez por clave en `scripts/theming-census-debt.ts` — deuda registrada, NO excepciones; la válvula sigue intacta y nunca ciega el ratchet. R-5.1/5.2 a `error` contra el ledger (R-5.3 ya lo estaba): deuda nueva = rojo NOMBRADO, entrada rancia = STALE hasta borrarla. Los techos burdos del suelo RETIRADOS (el ratchet es por clave); `atHundred` corrige su criterio (`public > 0`, 14 → 45). El gate de F3 queda redefinido honesto: **«censo 100 % ADJUDICADO»** — y está EN VERDE. - **Pendiente de TU firma, nombrado en §13 y en la cabecera del ledger**: ~~los **318 privados no-derivados**~~ — **✅ FIRMADA Y EJECUTADA 2026-08-26** (`e812d3ffd` · `a74aeec7b` + F3; ver §«FIRMA EJECUTADA — los 318» arriba) · ~~el idioma **`var(--{c}-x, fallback)` sin contrato**~~ — **✅ FIRMADA Y EJECUTADA 2026-08-26** (§«FIRMA EJECUTADA — la ley del espacio cerrado» arriba) · QUEDA la **re-clasificación de `palabras`** (117 nombres `--palabras-*` puntuados `public` que son canal de VALOR) y las DOS deudas de eje propio que la ley nombró (14 canales → `--_{c}-*` · cableado `EidosConfig.motion`), ambas detalladas en `next-features.md`. · Deuda menor registrada: las fichas de `docs/audit/theming/` esperan un `--report` supervisado post-`structural` (tarea aparte). ### FUERA del carril de theming (registrados HOY, no se ejecutan desde aquí) - **E1 — los botones del array de form COMPONEN el Button** (clase A-112): expediente completo de VC en `exped/vc/` + la corrección de E-talla: E2 ahorró el CONTEXTO pero no la LECTURA — E1 debe pasar `size` al Button que inyecte o es la regresión medida (26→36 px en xs). Y las partes son MUDAS (morfo sin evento; verbos canon: `commit-set-add`/`commit-remove`). - Lo abierto por el ARIA: `tag-group` filas SIN celdas (el «precedente» refutado midiendo) · `search-field` F-1 · la regla del censo de citas APG. - El párrafo anchura-vs-densidad querría vivir TAMBIÉN en `reference.md` junto a la norma tapada (dicho por E-talla, fuera de su alcance). ### Las leyes que dejó el día (sesión 2) - **Una interrupción del autor MATA a los agentes en vuelo** — informe.md a disco INCREMENTAL siempre; el disco sobrevive (V1 se recuperó íntegro). - **El supervisor MIRA las capturas antes de cada commit** (regla del autor). - **Las demos del sistema NO entran** ni como prueba central de una firma (reafirmada sobre la captura del velo; la prueba citable es el barrido de las 14 identidades del catálogo). - **F5 compartidas se RETIENEN y liberan EN SERIE** cuando varios ejecutores comparten `next-features`/`CONTINUE` — tres ejecutores hoy, cero pisadas. - La sonda estándar ganó DOS mentiras registradas (se pisa el `data-size` forzado sobre nodos compuestos · los `clamp()` fluidos no comparan sin declarar viewport) — están en §«Lo que el instrumento aprendió». Lo que queda de firma vieja NO cambia, y las entradas EJECUTADAS de hoy están intercaladas tras esta sección. _Corrección 2026-08-27: la frase original decía que «la lista “Lo que espera TU FIRMA” de más abajo quedó VACÍA el 2026-08-25», y es FALSA — confundía DOS listas. La que se vació es la del handoff del 24 (arriba, todos sus puntos tachados). La de **§5 «Lo que espera TU FIRMA»** sigue **VIVA: once entradas, ninguna tachada** entonces, de las cuales dos ya estaban ejecutadas y esperaban esta anotación — la 3 (clase `structural`, ejecutada en `2c61946fb`, §«EL CIERRE, EJECUTADO») y la 10 (la cascada de paleta, ejecutada como §«FIRMA B′ EJECUTADA»). **Las otras nueve siguen esperando firma.** (Conteo re-verificado el 27 sobre la lista ya renumerada: son 1…11.)_ ### FIRMA EJECUTADA (2026-08-25) — el velo del sistema no muere por un ATAJO **Qué se firmó** (changelog §56, reverso de §55 el mismo día): al bajar el sobre de trigger de `popover.css` al suelo, §55 lo dejó a **(0,0,0) — el mismo peldaño que `archetypes.css`**, que es quien pinta el velo de estado del sistema. Y el suelo declaraba su superficie con el ATAJO `background:`, que expande a `background-image: none` — **la propiedad exacta donde vive ese velo**. Resultado: el velo de hover de todo trigger desnudo dependía de qué hoja cayera después. No sólo por la regla de hover: el `:where()` deja también la de REPOSO empatada con la de hover del arquetipo, y ésa sola bastaba. La corrección son DOS PALABRAS — `background-color:` en `popover.css:60` y `:75`. **Los números**: **0 px** en el barrido de las **14 identidades del catálogo** que montan un `[data-popover-trigger]` (68 lecturas en reposo → 0 movidas, 68 en hover → 0 movidas, `rules split=2` en las 14) con control negativo diff 5 / 4; las dos sondas del eje a **0 diffs** (`popover` 448 valores / 8 estados, `chronos` 36 832 / 7); y **el velo sobrevive al orden invertido**, donde con el atajo moría (`linear-gradient(…8 %…)` → `none`). Cae con la firma el pin `chronos.css:417` (cinco declaraciones a (0,3,0) que ya no defendían nada): **0 diffs en 20 combinaciones `variant` × `size`**, control negativo 20/20 — §13 lo había adjudicado mal, al velo del `+N more` lo mata `button.css:69`/`:88`. Guarda §55 apartado **(f)** en `active-eidos-config.test.ts`, **4 mutaciones / 4 mordidas** (las dos primeras muerden la mitad positiva, las dos segundas —el atajo AÑADIDO junto al longhand— la negativa). **Lo que quedó fuera, con su número en `next-features.md` §13**: el residuo `transition` del MISMO empate (suelo `background, border-color` vs arquetipo `opacity, background-color`, las dos a (0,0,0) — hoy el `border-color` del hover de popover salta en vez de animarse), la decisión de producto «popover deja de declarar hover propio» (no es coste cero: 0.9821 → 0.931 **más** el velo hoy, sólo el velo después) y `calendar-select.css:14`, que **no es un pin** — retirarlo rompe el tipo en 3 de 4 tallas (12 / 14 / 20 → 16 px). **Fichas y prosa saneadas**: `chronos.md` (censo 202→198, propuesta 50→47, en bloques `` para que sobrevivan a `--report`), `calendar.md` (su ⚠ HALLAZGO «no determinista» lo cerró §55 y ya no apunta a §13), `emoji-picker.md` y los tres comentarios de código que seguían afirmando **(0,2,0)** del sobre (`emoji-picker.css`, `gradient-picker.css` —sólo su mitad base, la de estados sigue viva— y `lib/recipes/base.ts`). Se ANOTAN, no se reescriben: cada medida fue correcta con la cascada de su día. ### FIRMA EJECUTADA (2026-08-25) — el eje `size` de `form` LLEGA a sus acciones **Qué se firmó**: ceder el cromo de `submit`/`reset` al `Button` compuesto (firma del 2026-08-24) destapó el reverso. `form-submit.svelte:20` y `form-reset.svelte:15` traían su propio `size = 'md'` y **nada les pasaba la talla del formulario**, así que un `
` los renderizaba con `data-size="md"` —36 px de alto y 16 px de letra— **en las cinco tallas**; del eje sólo sobrevivía el `row-gap`. Quitar el default no arreglaba nada (el `Button` tiene el suyo): hacía falta el puente, y el precedente es literal. Nuevo `eidos/components/form/context.ts` calcado **1:1 de `toolbar/context.ts`** (`Symbol('form-eidos-ctx')` + getter de propiedad), `form.svelte` publica el `resolvedSize` que ya calculaba, y las dos acciones leen `size={size ?? form?.size}` — la prop explícita gana, y standalone cae en el `md` del propio `Button` sin re-declararlo. **Sólo eidos: cinco ficheros, cero morfo / soma / sema; el contrato de 64 claves y el ledger, intactos.** **Los números**: alto **−10 / −6 / 0 / +8 / +16** px y letra **−4 / −2 / 0 / +4 / +12** px, sobre `submit` y `reset` por igual; **`md` no mueve un solo valor**; 84 diffs en total y **cero** en los cuatro nodos del array, el widget y el resumen de errores. Sonda estándar antes/después **0 sobre 832 valores en 7 estados**; instrumento propio reproducible (dos pasadas sobre código idéntico ⇒ 0 diffs). `vitest src/uix/eidos` 443/444 (el rojo es el ajeno conocido `skin-media-player`), `check` 0 errores atribuidos a los cinco ficheros, `docs:check` 0/0. **La doctrina que hubo que adjudicar**: **VERBATIM, no la norma tapada en `md`**. La tapa de `reference.md` §«Container→part derivation» gobierna contenedores cuyo eje es ANCHURA (su primer consumidor es `Dialog.Close`); el de `form` es DENSIDAD declarada, y su propia receta ya había escrito los cinco peldaños distintos de la acción. Escrita en `next-features.md` §13 §«Anchura vs densidad», con el corolario de que a `alert-dialog` —mismo agujero, eje de anchura— le toca la TAPADA. **Lo que quedó fuera, con su entrada en §13**: `alert-dialog` (no medido), `Form.ErrorSummary` con un `data-size` que ninguna regla lee, la escalera de fuente `12·12·14·14·16` de la acción de `form` (que corrige E1 en su carril) y la cita colgada de `dialog/context.ts:9`. ### FIRMA B′ EJECUTADA (2026-08-24) — la cascada de paleta es una ESCALERA **Qué se firmó**: los tres escritores de `--{c}-palette-*` pasan a tres peldaños que **no empatan** — suelo `:where([data-{c}])` `(0,0,0)` < forward `[data-{c}]:where([data-color], [data-color-custom])` `(0,1,0)` < tono `[data-{c}][data-color='X']` `(0,2,0)`. Antes el forward genérico se emitía el ÚLTIMO empatado a `(0,2,0)` con los bloques por tono, así que **ganaba por orden de emisión** y 419 claves públicas de tono en 49 recetas no pintaban nunca. **Por qué B′ y no reordenar la emisión** (que es lo que §13 proponía): el orden es **contrato invisible** —no se lee en el artefacto, no lo verifica un guard sin recorrer la hoja entera, se rompe moviendo una línea—. La especificidad es **contrato EN el artefacto**. Y es la misma ley que §12.9 acababa de firmar para el plano de profundidad: **una doctrina aplicada dos veces**, no dos parches. **Los números**: neutra en píxel sobre **~297.000 valores computados** comparados antes/después (70.912 + 34.336 planos en dos lotes, 57.720 en el tercero, 134.464 con los tonos ESTAMPADOS en las 49 unidades) — **0 diffs reales**, y los 17 crudos probados ruido reproduciéndolos sobre código idéntico. **207 de 353 claves** de tono volvieron a mover un valor computado. Guarda por **mutación** en `active-eidos-config.test.ts:1761` (6 mutaciones, 6 mordidas; cierre estructural: toda declaración de paleta vive en uno de los tres peldaños; anti-vacío `> 40`). Contrato del forward **ensanchado de 2 a 49 recetas** — vigilaba sólo las de paleta pública y era ciego a las 47 privadas. Suite 35/36 (el rojo `skin-media-player` es AJENO y conocido). **Dónde vive todo**: doctrina en [`theming/changelog.md`](../theming/changelog.md) §53 · contrato en [`theming/reference.md`](../theming/reference.md) (bloque THM-2) · emisor `src/uix/eidos/lib/render-css.ts` (`isPaletteSlotToken` parte el bucket host — **sólo las ranuras de paleta bajan**, el chasis se queda a `(0,1,0)`) · guarda `active-eidos-config.test.ts` · ledger `scripts/theming-sentinel-exceptions.ts`. **Tres leyes que deja escritas, y las tres costaron una medida**: 1. **El silencio del guard NO es señal cuando la adjudicación es por PATRÓN.** `theming-sentinel.ts` detecta STALE sólo contra el ledger EXACTO (`k in ledger`), nunca contra `SENTINEL_PATTERN_EXCEPTIONS`. Las 207 claves resucitadas no dispararon ni un aviso: el estrechamiento hubo que hacerlo comparando a mano contra las 13 entradas. La única que el guard sí vio fue `editable.risk-border`, que era exacta. 2. **Un tono por defecto ESTAMPADO resuelve por el forward, no por el suelo.** El envoltorio estampa `data-color` en toda instancia, la default incluida, así que `