33 KiB
CONTINUE — eje Theming «theme-reach» (handoff, act. 2026-08-20)
Estado: EN EJECUCIÓN — bloque del vocabulario CERRADO. 7 componentes corregidos (auditados
contra la gramática nueva: 6 limpios, 1 corrección), 20 fichas revisadas, el
informe de auditoría vivo y regenerable. El 2026-08-20 el autor firmó las 14
decisiones pendientes: las D-TH.1…8 enteras (§4 del plan, con dos enmiendas)
más familia calendar, mandato Field y hover→capa de estado — el acta está en
§«Firmas del 2026-08-20». Y el bloque del vocabulario se ejecutó el mismo día
(tres commits, §«Lo ejecutado»): 269 claves renombradas, R-5.3 en error,
doctrina al día. Lo siguiente es la migración a la capa de estado (firma 3).
- Fuente viva del método:
PLAN-theming.md(§7 el protocolo, sin excepciones). - Informe por componente:
docs/audit/theming/— un README de conjunto + 170 fichas (162 recetas + 8 sin receta). Cada ficha lleva su análisis, su propuesta y, en §5, el veredicto escrito a mano, que sobrevive a la regeneración.
EJECUTADO 2026-08-20 — vocabulario de tokens: D-TH.6 (codemod) + R-5.3 (guard)
Por qué antes que nada (conversación 2026-08-20): el canon de nombres
existe (theming §6.7 slots + recipe-contract §1 dimensionales) pero no tiene
guard, y la medición del 2026-07-01 ya demostró que canon sin guard deriva
30-85 %. Está derivando: el backfill de ayer escribió la forma DOCUMENTADA
(modificador delante, 36 claves) mientras el catálogo habla al revés — cada
componente que se corrija sin firmar esto ensancha la brecha. El guard de
eventos (eidos-event-vocabulary.ts) es el precedente: nació de un
commit-resize muerto tres meses en una receta; R-4.4 es el otro (una regla de
nombres ya guardada, deuda muerta «en el mismo pass, sin allowlist»).
FIRMADO 2026-08-20 — el slot de tinta es fg; color como slot MUERE.
La sesión del 20 leyó lo que la del 19 no había leído (arts/color,
architecture/eidos.md entero, motion §17, §25/§38) y encontró que la
pregunta central no era «normalizar hacia lo documentado» sino una
CONTRADICCIÓN entre dos doctrinas: theming §6.7 r7 (fg) contra el principio
de plataforma del px/py («el token se llama como la propiedad»: color). El
autor adjudicó fg: el principio de plataforma gobierna los ejes
DIMENSIONALES, no la pareja bg/fg (si la gobernara, bg sería
background-color); color es la palabra más sobrecargada del sistema
(--color-*, data-color, 9 roles, arts/color); on-fg compone; Chakra
v3/Panda hablan la pareja.
Inventario CORREGIDO 2026-08-20 (instrumental: los scripts/__names-*.ts
de esta sesión — census, slots, owners, audit7, audit7b; el exacto y
regenerable lo produce --names en el paso 1). Sobre 3.333 claves públicas,
301 desviadas en 66 componentes — 193 con color como slot, 78 con el
modificador DETRÁS a nivel de receta, 30 con ambas. La semilla
__names-inventory.ts decía 370 porque contaba como desviadas 47 claves
{rol}-{slot-de-rol} que son CANÓNICAS (button.primary-solid-hover,
toggle.palette-hover… — COLOR_ROLE_SLOTS pone el modificador detrás POR
CONSTRUCCIÓN) — un codemod sobre las 370 las habría roto. Adopción viva:
196 -color contra 55 -fg (las fg son mayormente las del backfill de este
eje). Peores: tag-group 22 · toast 15 · field 13 · calendar 13 · tabs 12.
Tres familias, tres gramáticas (el guard codifica las tres): rol/paleta =
modificador DETRÁS (canon) · sistema (--state-hover, --opacity-hover) =
detrás, fuera del alcance del guard · recipe-level = §6.7 r7 (delante:
hover-bg, 13 claves conformes contra 22 bg-hover).
Falsos amigos (22) — FIRMADOS en el acta: *-focus-ring-color (3, espeja
la familia del SISTEMA) · aura.orb-color-* (6, color como sustantivo del
orbe) · gradient-builder.stop-color-* (4, stop-color ES la parte —
verificado: gradient-builder-stop-color.svelte + parts DOM) → se quedan ·
los 7 con modificador «fuera de vocabulario» resultaron ser DOS clases que el
morfo ya resuelve (valores de data-state/ejes declarados: active, partial,
read, failed; y current = aria, que entra al vocabulario universal) más
una de pseudo-partes (played/buffered) → se renombran (destinos en el
acta) · background.scrim-color-on-{dark,light} (2, chocaban con el prefijo
on-) → scrim-fg-over-{dark,light}.
Hovers neutros — firmado: NO se renombran, MIGRAN: §38 + R-4.3 deprecan el
hover neutro por componente (es la capa --state-*). dropdown-menu.item-bg-hover,
context-menu.item-bg-hover, scroll-area.track/thumb-bg-hover,
splitter.handle-bg-hover… la firma 3 del acta ordena su migración a la capa
de estado (captura + diff explicado por componente). El codemod los EXCLUYE y
el --names los lista aparte como cola de esa migración.
LOS CUATRO PASOS ESTÁN HECHOS (f09e04fab acta · bd916ef3f codemod ·
7781d6e4c guard + doctrina, sin pushear). Lo que queda del bloque, y sólo
esto:
- El tercer muro espera a la firma 3. El tipo en
defineRecipes(moldePhysicalAxisKey) está escrito y probado: dispara sobre 17 claves, que son los hovers neutros concoloren cola de migración. Meterlo hoy rompenpm run checka todo el mundo. Entra cuando la migración las vacíe — dos líneas: una ramaColorSlotKeyy las tres excepciones firmadas (*focus-ring-color,orb-color-*,stop-color-*) deletreadas. __names-inventory.tsquedó superado portheming-census --names(contaba 370 porque metía las 47 role-slot). No se borra sin que lo digas.
El registro de los pasos, para quien audite después:
Los pasos, en orden y con su gate (el paso 0 murió el 2026-08-20: D-TH.6
está firmada COMPLETA — ver §«Firmas del 2026-08-20»; la gramática ejecutable
es: slot fg · delante lo interactivo, detrás lo dimensional/contextual ·
modificador ∈ universal (+current) ∪ data-state/ejes del morfo · rol/paleta
detrás · hovers neutros excluidos · renombres nominales de los ex-falsos
amigos en el acta):
--namesen el censo: el inventario exacto por clase de desviación, regenerable, con las 47 role-slot reconocidas como canónicas, los falsos amigos resueltos por el acta (los 3 grupos que se quedan excluidos; los 4 renombrados contados como desviación con su destino) y los hovers neutros listados APARTE (van a la firma 3, no al codemod). Muta-prueba del instrumento: 3 desviadas conocidas salen, 3 role-slot NO salen.- Codemod value-preserving (molde: px/py del 2026-07-06 y su triple muro):
-color→-fg(196 + 49 mediales, menos los 3 grupos que el acta deja quedarse y los hovers neutros que migran aparte), los renombres nominales del acta (rating-group · chat-message · breadcrumb · waveform ·scrim-fg-over-*), y modificador detrás → delante a nivel receta (bg-hover→hover-bg, 22 claves); renombra la clave enrecipes/base.tsY todos los consumidores (var(--{c}-{clave})en css/svelte/ts/md — congit ls-files, no de memoria; los .md de HISTORIA — changelog, errores-toxico, PLAN-affix/background — NO se reescriben), regenera, y verifica: diff degenerated/= renombres 1:1, censo global IDÉNTICO (un rename no cambia alcance), sonda de computed en 3 componentes renombrados = 0 diffs. Un commit, script commiteado como registro. - Guard R-5.3 en
component-audit— de GRAMÁTICA, no de lista (a diferencia del de eventos, que valida pertenencia a un vocabulario cerrado), y POR FAMILIA:{rol|palette}-{slot-de-rol}con modificador detrás (COLOR_ROLE_SLOTS) ∪ recipe-level[variante-]?[modificador-]?[parte-]?[slot][-talla]?donde talla ∈ las 7 canónicas, modificador ∈ vocabulario cerrado y DELANTE, slot ∈ (§6.7 recipe-level ∪ ejes dimensionales de recipe-contract §1), y la PARTE contracompileMorfo(morfo).parts+ la allowlist eidos-only (el mismo criterio queeidos-lint). Severidaderrordirecto: tras el codemod no hay deuda que tolerar, y la rampawarnes como estos guards mueren. Muta-prueba obligatoria de tres caras antes de darlo por bueno:-bg-hoverrojo ·trigger-colorrojo ·primary-solid-hoverVERDE (memoriaa-guard-that-inspects-nothing-passes). - Docs en el mismo pass: recipe-contract §1 gana la fila del modificador
(hoy sólo la insinúa §6.7) y §4 la fila R-5.3; theming §6.7 nota fechada
con la firma de
fgy el acotamiento del principio de plataforma a los ejes dimensionales; T-TH.2 del plan se cierra.
Gates del bloque entero: censo global idéntico antes/después del codemod ·
suite eidos sin rojos nuevos · component:audit sin fallos nuevos fuera de
R-5.3 · docs:check 0 · rtl:check 0.
Después — por dónde seguir
node --import tsx/esm scripts/theming-census.ts— debe dar 162 recetas · 5.203 knobs · 1.841 públicos (37 %) · 56 sin contrato (antes del codemod; tras él, el MISMO alcance con nombres nuevos). Si no cuadra, alguien tocó recetas: regenerar el informe (--report) antes de nada.- Abrir la ficha del componente que toque y leer su §5 Veredicto: dice qué
de la propuesta es correcto, qué está mal y qué espera firma. Está verificado
contra el CSS; la §4 generada NO se sigue a ciegas. Ojo: los veredictos
se escribieron ANTES del acta del 2026-08-20 — sus «espera firma» se cruzan
con §«Firmas del 2026-08-20» (la mayoría ya están resueltos: calendar,
Field, hover→estado, D-TH.2) y sus nombres propuestos se pasan por la
gramática firmada (p. ej. el
guide-colorde la fila tree-grid de la cola esguide-fg). - Ejecutar con el protocolo §7 entero. Un componente = un commit.
PRIMERA POSICIÓN — repaso de los 7 ya corregidos contra la gramática nueva
Encargo del autor (2026-08-20): revisar lo ya ejecutado por si incumple las
reglas nuevas. Auditados los 7 con scripts/__names-audit7.ts y
__names-audit7b.ts (claves públicas + privados + consumo en css/README).
Resultado: 6 de 7 limpios, 1 hallazgo real.
| componente | claves | veredicto |
|---|---|---|
combobox |
106 | ✅ limpio — ya habla fg, sin modificador detrás, privados sanos |
natural-time-picker |
62 | ✅ limpio |
date-range-picker |
24 | ✅ limpio |
time-range-picker |
22 | ✅ limpio |
proof-of-human |
20 | ✅ limpio |
time-picker |
16 | ✅ limpio |
gradient-builder |
72 | ⚠ 1 corrección (abajo) |
Que los 6 salgan limpios NO es casualidad ni suerte: el backfill de este eje
venía escribiendo fg (55 de las ~55 claves -fg del catálogo son suyas),
que es exactamente lo que la firma ratificó. La firma valida el trabajo
hecho, no lo invalida.
La corrección — gradient-builder.checker-color → checker-fg (1 clave,
consumida 4 veces en gradient-builder.css:29-32). Es el color de los cuadros
del damero de transparencia: color ahí es slot, no sustantivo — cae de
lleno en la regla firmada. Las otras 4 claves que el audit marca
(stop-color-title-font-size, -font-weight, -fg, stop-color-sliders-gap)
son falso amigo verificado: stop-color es la PARTE
(gradient-builder-stop-color.svelte, [data-gradient-builder-stop-color-*]),
y una de ellas ya termina en -fg correctamente. No se tocan.
Ejecución: va DENTRO del codemod del paso 2 (misma mecánica, mismos gates), no como commit aparte — es una clave, y sacarla del codemod duplicaría la verificación. Si el codemod se retrasa por las firmas pendientes, se ejecuta sola con el protocolo §7.
BLOQUE F2-A — el próximo grupo: analizar y corregir (preparado 2026-08-20)
El primer bloque del backfill bajo TODAS las firmas. Ocho componentes con veredicto §5 verificado + una pieza de instrumento que va primero. Suma 330 knobs hoy a 0 %; al cerrar, el global debe rondar 37 % → ~42 %. Cada componente: protocolo §7 entero, un componente = un commit, con la gramática firmada (¡el guard R-5.3 y el muro de tipos ya vigilan!).
Pieza 0 — el instrumento ANTES del bloque (D-TH.2-b, firmada). La familia
tipográfica B5 mide su superficie por --style-* como sistema transversal: el
censo añade --style-* a la clase system PARA los primitivos tipográficos
(heading, text, display, code, s-text…), con gate: las cifras de TODOS los
demás componentes quedan idénticas, y heading pasa de «36 privados» a su
verdad (consume la capa semántica). Va primero porque cambia el suelo del
censo — hacerla a mitad de bloque falsearía los antes/después.
| # | componente | knobs | defectos medidos (censo + ficha) | corrección firmada por el veredicto |
|---|---|---|---|---|
| 1 ✅ | command |
52 | SIN bloque en base.ts; 35 globales · 9 privados sin derivar · 6 literales |
contrato entero con talla resuelta (patrón Sidebar); radius con la adaptación al Dialog como CONTEXTO (lee un público de dialog, legítimo — no partir en dos); list-padding-inline + scrollbar-inset (patrón combobox); sonda con el palette ABIERTO |
| 2 | table |
46 | 23 privados · 14 globales · 5 literales | root-height-{k} es la fila → row-height-{k} al bundle; el prefijo root- sobra en el resto; talla |
| 3 | media-player |
45 | 37 globales · 8 literales; privados --_mp-* ABREVIADOS (§6 r5 los prohíbe) |
renombrar --_mp-* al nombre completo (⚠ prettier: la anotación /* literal: */ en la MISMA línea — trampa de natural-time-picker) + tokens; su acento theme-stable está FIRMADO en base.ts — no tocarlo; el ⚠ de bg son DOS knobs (superficie y velo) |
| 4 | tree-grid |
42 | 29 privados · 8 globales | root-bg-image son las guías de indentación: el knob es la tinta (guide-fg — era guide-color pre-acta), los 5 gradientes se quedan en la receta; talla |
| 5 | gradient-picker |
38 | privados --gp-* ABREVIADOS · 23 globales |
renombrar --gp-* + tokens; content-width es por talla (20/18/22rem), no un solo knob |
| 6 | listbox |
38 | 23 globales · 9 privados; una fila FALSA en la propuesta | tokens; retirar la fila font-size = var(--list-font-size): es público de la capa list-surface — un consumidor no acuña lo que la capa posee |
| 7 | carousel |
36 | 12 globales · 14 privados · 5 literales | tokens + talla; los indicator-width-{k} son geometría propia (rem), ni bundle ni desviación |
| 8 | feed |
33 | 16 globales · 13 privados | tokens + talla; el título es por talla y el feed tipa por debajo del 1:1 (md → sm), verbatim — no «corregirlo» al 1:1 |
Cada componente engancha su tab Tokens en el MISMO commit (firmado
2026-08-20, a raíz de que el autor viera que la demo de command no enseñaba su
superficie de tema — y resultó que ninguna lo hacía). Es una línea:
<TokensPanel component="x" stage={stageRef} /> más el botón del tab; el panel
(web/routes/uix/lib/TokensPanel.svelte) lee el contrato vivo con
eidos.getRecipeTokens(), así que no hay tabla que mantener. Un componente
temable cuya demo esconde sus tokens está a medio entregar.
Gates de cada componente (§7.4/7.5, sin excepciones): censo --only {c} al
100 % o excepción escrita · sonda antes/después = 0 diffs · centinela
por token nuevo · component:audit PASS (R-5.3 incluida) · eidos-lint 0
invalid · suite eidos sin rojos nuevos · rtl:check 0 · docs:check 0 ·
check por fichero · README del componente con la tabla «Talla y tema»
(molde navigation-menu). Al cerrar el bloque: revisión adversarial §7.7
(molde Sidebar: refutar «idéntico», «alcanza», «píxel arriba» con medición
propia).
Al cerrar F2-A, lo desbloqueado por las firmas espera en este orden:
- Diseño de la capa
calendar-surface(firma 1) — se PRESENTA antes de escribirla (nombre, ejes, qué posee; moldelist-surfacey sus 4 reglas). Desbloquea los tres gordos del catálogo:range-calendar(98) +month-grid(61) +year-grid(61) y mediadate-range-picker— 220 knobs, el salto de ~42 % a ~47 %. - Mandato Field ejecutable (firma 2) —
field-langs(41) + las mitades detime-picker/time-range-picker/date-range-picker. - El resto del orden B1-B8 de D-TH.4 (
grid-list32 ·textarea28 · …).
AL TERMINAR EL EJE ENTERO — partir recipes/base.ts por componente
Firmado 2026-08-20, a raíz de la pregunta del autor «¿por qué todos los tokens viven en un fichero?». Va al final de TODO el themeable, no al cerrar un bloque: mientras quede un componente por tokenizar, ese fichero se toca en cada commit.
recipes/base.ts son 6.223 líneas y 128 componentes, y NO es un fichero de
tokens: es el valor del campo recipes de EidosConfig, serializable, que un
tema hidrata. Por eso los valores no pueden mudarse a components/{x}/ — se
intentó y se retiró (architecture/eidos.md: «The old tokens/components/*
were retired»). Lo que sí puede repartirse es la AUTORÍA:
// lib/recipes/table.ts
export const tableRecipe = { 'row-height-md': '…', … };
// lib/recipes/base.ts — el valor sigue siendo UNO
export const THEME_BASE_RECIPE_TOKENS = defineRecipes({ table: tableRecipe, … });
Verificado antes de proponerlo, no supuesto: el muro de tipos de
defineRecipes SIGUE disparando cuando las claves llegan por spread desde un
fichero suelto — probado con trigger-color (slot color) y padding-x (eje
físico), ambas dan error de compilación igual que inline. El único consumidor
sensible a la forma es eidos-purge.ts, que hace Object.keys() y es
indiferente. recipe-css-contract, el censo, R-5.3 y getRecipeTokens() leen
el objeto compuesto.
Los tres costes que paga el fichero único, todos medidos en la sesión del
2026-08-20: casi entra un SEGUNDO bloque table que el catálogo habría
descartado en silencio (la trampa está anotada abajo); una coma perdida
rompió el catálogo entero dos veces; y es el punto de conflicto de todas las
sesiones concurrentes. Repartido, un error afecta a un componente.
Por qué al final y no antes: son ~6.000 líneas movidas en el fichero que cada commit del backfill toca. Hacerlo con componentes pendientes garantiza conflicto con toda sesión que esté tokenizando; con el eje cerrado es un commit mecánico y aislado.
Gate: THEME_BASE_RECIPE_TOKENS idéntico antes/después (comparación
ESTRUCTURAL del objeto, no del fichero) · censo global idéntico ·
generated/base.css sin un solo cambio · el muro de tipos con su muta-prueba
(las dos claves malas siguen sin compilar).
FIRMA 3 en ejecución — hover → capa de estado (act. 2026-08-20)
El diagnóstico cambió al empezar. La firma decía «migrar los hovers neutros
a la capa de estado». Al hacerlo salió que el velo del sistema no llegaba a
ninguno, y no por el hover: por la regla BASE. archetypes.css pinta el velo
con :where(...), peso (0,0,0); cualquier receta que declare el ATAJO
background: sobre ese mismo nodo fija background-image: none con (0,1,0)
y lo cancela SIEMPRE — ni en hover ni nunca. El hover propio no era un
capricho: era la cicatriz de un velo que no llegaba.
Así que cada migración son DOS cambios: background: → background-color: en
la base, y fuera el hover propio.
| componente | commit | medido |
|---|---|---|
checkbox |
b35855c20 |
8 diffs, todos en hover: velo + fondo base (2.436 valores) |
splitter |
c66b73810 |
2 diffs en el asa (812 valores) |
switch |
3219a19c3 |
2 diffs en el track off (377); el swap del checked, verificado |
date-range-picker |
0c80a8efb |
sin medir el pintado — la demo no monta kind month/año |
Los 6 knobs de la cola eran 47 hasta que se midió la PROPIEDAD: el velo es
background-image, así que un hover de borde (22) o de tinta (19) no es la
capa de estado, sea cual sea su valor. Esos 41 eran deuda de nombre y se
renombraron (93017975c).
Lo que queda de la firma 3, y por qué no lo he hecho
scroll-area.thumb-bg-hover— pide DECISIÓN de morfo. El thumb llevaarchetype: 'thumb', que NO recibe velo. Migrarlo exige cambiar su arquetipo, y un arquetipo es morfo: se presenta, no se toca de oficio (§7.3-9). La alternativa es dejar su hover como excepción anotada.- El hallazgo sistémico: 141 declaraciones en 45 componentes cancelan el
velo del mismo modo, medido con
scripts/__statelayer-shorthand.ts(que comprueba contra el morfo que el atajo cae sobre el nodo VELADO, no sobre cualquiera). Peores: radio-group 12 · tag-group 8 · checkbox 7 · table 7 · combobox 6 · tabs 6. Esto explica la adopción 21/135 que midió la auditoría del 2026-07-01: el velo estaba escrito y estructuralmente derrotado. Es un barrido de catálogo que mueve píxel en 45 componentes: no entra en la firma 3, que se firmó sobre unos knobs concretos. - Hueco de demo:
date-range-pickerno exponekind='month'/'year'(norma N-6), así que la mitad de su API no se ve ni se mide.
Firmas del 2026-08-20 — el acta (las 14, «FIRMO TODAS»)
Presentadas con recomendación fundada y firmadas en bloque por el autor. El detalle razonado de cada una vive en la conversación del 2026-08-20 y en la fila correspondiente del plan §4; aquí el QUÉ ejecutable:
- Familia calendar = capa compartida (molde
lib/list-surface.css: attr de capa, un eje = token público + ranura privadavar(--_x, var(--x)), guardada porshared-layer-contract.test.ts+layer:check). NUNCA ~150 alias--calendar-*. Desbloquearange-calendar(98),month-grid(61),year-grid(61) y mediadate-range-picker. El diseño de la capa (nombre, ejes, qué posee) se presenta antes de escribirla. - Mandato Field: ejecutable. Los x-field/pickers componen el wrapper
Field; las alturas de segmento salen del eje size a nivel familia
(
--field-control-height-{k}); muere la re-duplicaciónheight-{xs..xl}por componente (theming-audit §2-B: computabanautodesde su nacimiento). - hover → capa de estado, donde reaparezca (empezando por los 3 knobs de
combobox). Mueve píxel hacia el canon §38/R-4.3 ⇒ cada migración lleva captura antes/después y su diff explicado en el commit. Desbloquea la poda D-2 (changelog §38 ◇: los--{x}-bg-hoverhuérfanos, incluidopagination.selected-bg-hover= capa sobre acento). - D-TH.6 completa — slot
fg+ modificador DELANTE con la regla: delante lo interactivo, detrás lo dimensional y contextual; modificador válido ∈ vocabulario universal (+current) ∪ valoresdata-state/ejes del morfo del componente;waveform.played/buffered= pseudo-partes;scrim-color-on-*→scrim-fg-over-{dark,light}; hovers neutros FUERA del codemod (migran por la firma 3). Renombres nominales de los ex-falsos amigos:item-fg/active-item-fg/partial-item-fg(rating-group),read-status-fg/failed-status-fg(chat-message),current-link-fg(breadcrumb),played-fg/buffered-fg(waveform). Se quedan:*-focus-ring-color(sistema),aura.orb-color-*(sustantivo),gradient-builder.stop-color-*(parte). - D-TH.1 R-5 dura · D-TH.3 tracks WIP en censo,
errorsólo fuera de carril · D-TH.5 el default no cambia (única excepción: la firma 3, con captura). - D-TH.2 con la opción (b) de
heading: la familia tipográfica B5 mide por--style-*como sistema transversal — no se acuñan--{c}-*tipográficos. La listaKNOB_PROPSes el perímetro; cambios = firma. - D-TH.4 con enmienda: la cola revisada de este CONTINUE prioriza sobre el orden de familias B1-B8.
- D-TH.7 con enmienda: R-5.3 a
errordirecto tras el codemod; R-5.1/5.2 esperan F3. - D-TH.8: panel de tokens en
/temas, en F4.
Lo ejecutado (censo antes → después)
Bloque del vocabulario, 2026-08-20 (tres commits, sin pushear):
| commit | qué |
|---|---|
f09e04fab |
el acta de las 14 firmas + la revisión de los 7 ya corregidos |
bd916ef3f |
codemod: 269 claves · 793 referencias · 101 ficheros · alcance IDÉNTICO · 0 diffs de computed |
7781d6e4c |
R-5.3 en error (muta-prueba de 3 caras) + recipe-contract §1/§4 + theming §6.7 + checklist |
Lo que el bloque enseñó (más caro de lo que parece):
- El plan del codemod se escribe ANTES de tocar nada. Releer el clasificador después da CERO desviaciones —ya están renombradas— y el verificador del diff pasa sobre el vacío. Costó dos vueltas.
- Un valor puede cambiar de texto sin cambiar de significado: 22 privados reapuntan a nombres nuevos. El gate normaliza por el plan antes de comparar, o los cuenta como cambio de valor y da rojo en falso.
- No pasar prettier sobre lo que el codemod tocó. El árbol tiene CRLF
(
autocrlf=true) y 88 de 101 ficheros ya salían «sucios» ANTES; un--writeen masa reformateó 300 ficheros de deriva ajena. Se midió lo que importaba —¿alarga el renombrado alguna línea?— y la respuesta fue no en todos, así que prettier no hacía falta. - Clasificar un hover por el NOMBRE es clasificarlo mal:
dropdown-menu.item-bg-hoverleevar(--color-primary-element)— es el palette swap con valencia de recipe-contract §2, no el hover bespoke que §38 deprecó. Lo decide el VALOR. Yo lo había listado mal en este mismo handoff.
| componente | alcance | commit |
|---|---|---|
gradient-builder (piloto) |
0 % → 80 % | 3cdb5b5f0 |
combobox |
0 % → 76 % | cef2d32f1 |
natural-time-picker |
0 % → 61 % | e774ca7e8 |
date-range-picker |
0 % → 42 % | 07778b597 |
time-range-picker |
0 % → 19 % | 68eb8af26 |
time-picker |
0 % → 18 % | e4fcdd62e |
proof-of-human |
0 % → 14 % | ae91573c3 |
Global del catálogo: 33 % → 37 % (1.621 → 1.841 knobs públicos).
Informe + instrumento: 2591ec2f0; revisión de las fichas 11-20: 3bfe0d413.
El instrumental (vive en scripts/, prefijo __ = temporal del eje)
node scripts/__theming-probe.ts <componente> <salida.json> # sonda antes/después
node scripts/__theming-diff.ts <antes.json> <después.json> # el gate: diff VACÍO
node scripts/__theming-sentinel.ts <componente> # ¿alcanza cada token?
node scripts/__shot.ts <componente> <salida.png> # captura 2× del stage
Se ejecutan con node, no con tsx (tsx inyecta helpers que rompen
page.evaluate) y desde la raíz del repo, contra el dev server en
localhost:5173. Los scripts/__dbg*.ts y __sentinel-targeted*.ts son de un
solo uso (verificaciones dirigidas de ayer); no se commitean.
Lo que el instrumento aprendió a fuerza de mentir
- La sonda congela
transition, NUNCAanimation: una propiedad transicionada devuelve su valor INICIAL justo tras escribir el token (un token vivo parecía muerto), pero congelaranimationimpide que Presence monte el panel — y entonces mides un popup que no existe. - Un token RESUELTO no se mueve desde
:root: se declara en[data-{c}]o en su parte, así que el tema mueve la coordenada. El centinela escribe en:rooty en el host, y aun así los resueltos salen «muertos» por diseño. - Un panel portalado no ve el ámbito del componente: sus tokens se emiten en
:root(o conparts), y un override scoped no lo alcanza. - La demo puede tapar el componente:
proof-of-humandeclara su propiomin-block-sizey fondo sobre el stage — ahí el centinela no sirve, y se dice. - Un valor centinela igual al real lee como «no efecto» (
9999pxcontra un--radius-fullque ya era 9999px).
Trampas que costaron un commit cada una (no repetirlas)
- Clave duplicada en
recipes/base.ts: añadir un bloque que ya existía lo descarta en silencio (gana la segunda). Guard antes de generar:grep -oE "^\t'?[a-z0-9-]+'?: \{" src/uix/eidos/lib/recipes/base.ts | sed "s/[\t':{ ]//g" | sort | uniq -d→ debe salir vacío. - Dejar vivos los bloques
[data-…][data-size='…']del CSS al emitir la cascada por el TSC: pisan los tokens nuevos con los valores viejos, y el diff de computed da 0 porque la ruta vieja sigue mandando. Lo cazó el centinela. - Correr
component:auditDESPUÉS deprettier, no antes: al renombrar un privado a su nombre completo, prettier partió tres declaraciones en varias líneas y separó la anotación/* literal: … */de su valor — R-2.1 la exige en la MISMA línea, así que el guard pasó a ver colores crudos donde antes veía excepciones anotadas. Se arregla con/* prettier-ignore */sobre la declaración: NO acortando el comentario ni tocando el valor. Regresión real ennatural-time-picker, cazada un día tarde por correr el audit antes del formateo. - Backticks en
node -e "…"desde bash: se ejecutan y vacían el texto. Para editar markdown con código, usar el editor, no el shell. prettier --writesobre un README no protege de que un Edit se coma un encabezado: comprobargrep -c "^## Gaps"después de insertar secciones.- Lo de ayer sigue vigente: medir el nodo que el usuario señala (píxel arriba),
el hover es del sistema, el default no cambia, rama compartida sin
stashni--amend,checkpor fichero.
Fuentes
- Plan y decisiones:
PLAN-theming.md· informe:docs/audit/theming/README.md. - Auditoría del SISTEMA (fase 1, cerrada):
theming-audit.md— §B familia calendar, §5.3-3 mandato de Field. - Doctrina:
docs/theming/reference.md(§5 talla, §6 nombres, §38 capa de estado) ·docs/canon/recipe-contract.md·docs/canon/tsc.md·docs/architecture/eidos.md(vertebración tipográfica, columnaunused) ·src/uix/eidos/components/README.md(capas compartidas). - Precedente de la forma por talla:
PLAN-sidebar.md§3 + F3 y el bloquesidebarderecipes/base.ts.