10 KiB
PLAN — un nombre de evento, una convención: {familia}-{verbo}[-{matiz}]
✅ CERRADO 2026-08-12 en
f44d1486d. La §6 Aceptación se cumplió entera y medida: 256 eventos declarados / 256 con prefijo de familia / 0 ambiguos, guard envalidateMorfovisto fallar con un nombre pelado inyectado a propósito, barrido de catálogo sobre los 172 morfos (components+internal
- fixtures), las cuatro escenas de F4 medidas en navegador,
eidos-lint-allsin inválidos nuevos ydocs:checken 0.Lo que este eje DESTAPÓ no es este eje. El barrido encendió una luz sobre catorce defectos que ya estaban ahí, y viven en
AUDIT-docs-code-ledger.md. Ese ledger es un artefacto de traspaso, no una lista de trabajo: se escribió para que una sesión futura los tome con su propio plan y su propia puerta. Ejecutarlo a goteo desde aquí fue el error de método del 2026-08-12 — la jornada se cerró a las 03:52 y siguió trabajando hasta las 20:43 sobre una iniciativa que nunca se nombró, hasta acabar borrando la librería de sonido (revertido,0d10b983e).Handoff:
CONTINUE-event-name-normalization.md.Kickoff (histórico): «Lee
docs/process/PLAN-event-name-normalization.mdy ejecútalo por fases, empezando por F0.» Fecha: 2026-08-10 · Decidido por el autor en la sesión del eje de superficie perceptual. Eje independiente: no bloquea ni lo bloqueaCONTINUE-perceptual-surface.md, pero comparte ficheros — no ejecutar los dos a la vez sobre los mismos componentes. Rama:alpha-0.1-dir-prefses COMPARTIDA (otra sesión trabaja enblocks):git reset -q+git addsólo lo propio, siempre.
1 · Por qué
El framework llama a la misma cosa de dos maneras. Medido:
| Convención | Componentes |
|---|---|
open / close pelados |
context-menu, dialog, drawer, dropdown-menu, float-panel, popover, menu-dial, onion-menu |
emerge-open / emerge-close |
combobox, navigation-menu, select |
Son el mismo evento con dos dialectos. En un framework de este tamaño eso no es
una inconsistencia estética: obliga a recordar qué componente habla qué dialecto
antes de escribir una regla de pack o una receta, y hace que un grep por
emerge-open mienta por omisión.
La decisión (autor, 2026-08-10): prefijo de familia SIEMPRE. El nombre pasa a declarar la familia que el motor va a resolver, y deja de ser un dialecto por componente.
2 · El censo — el trabajo es más pequeño de lo que parece
scratchpad/event-name-census.mjs (recréalo si hace falta; lee los morfos
textualmente, sin importarlos):
eventos declarados : 252 (91 morfos)
ya con prefijo : 216 ← 86 % ya cumple
SIN prefijo : 36
Cero nombres ambiguos: ningún nombre significa dos familias distintas en dos morfos. Eso hace que el mapeo sea 1:1 y determinista, que es lo que permite automatizarlo con seguridad. Compruébalo otra vez antes de empezar: si aparece un ambiguo, el codemod deja de ser seguro y hay que resolverlo a mano primero.
Los 36, con su renombrado
| Familia | Actual → nuevo | Morfos |
|---|---|---|
| emerge | open → emerge-open |
context-menu, dialog, drawer, dropdown-menu, float-panel, popover |
| emerge | close → emerge-close |
los mismos 6 |
| emerge | expand → emerge-expand |
accordion, collapsible |
| emerge | collapse → emerge-collapse |
accordion, collapsible |
| emerge | present → emerge-present |
toast, tooltip |
| emerge | dismiss → emerge-dismiss |
toast, tooltip |
| emerge | dismiss-escape → emerge-dismiss-escape |
tooltip |
| emerge | sub-open → emerge-open-sub |
context-menu, dropdown-menu |
| emerge | sub-close → emerge-close-sub |
context-menu, dropdown-menu |
| handle | drag-start → handle-drag-start |
drawer, float-panel |
| handle | drag-end → handle-drag-end |
drawer, float-panel |
| handle | drag-progress → handle-drag-progress |
drawer |
| handle | resize → handle-resize |
drawer |
| handle | resize-start → handle-resize-start |
float-panel |
| handle | resize-end → handle-resize-end |
float-panel |
| contact | trigger-picker → contact-trigger-picker |
file-upload |
| commit | select → commit-select |
tabs |
| signal | announce → signal-announce |
toast |
El matiz va al final (emerge-open-sub), no al principio. Precedente vivo:
commit-toggle-check / commit-toggle-uncheck (checkbox),
commit-select-range / commit-select-start (range-calendar),
commit-set-add (tags-input). Así el prefijo sigue siendo familia+verbo y el
[data-event^='emerge-open'] de una receta sigue capturando la variante.
⚠️ select → commit-select en tabs: comprobar antes que tabs no tiene ya
un commit-select (hoy no lo tiene). Es el único renombrado que podría colisionar.
3 · Los consumidores, y cuáles los caza el compilador
Esto es lo que hace el eje viable HOY y no hace seis meses: F1 tipó los
nombres de evento (SomaRuntime<M> sin default, EventNameOf<M>).
| Superficie | ¿La caza el compilador? | Cómo |
|---|---|---|
morfo/components/*.ts — la declaración |
— | es el origen del cambio |
soma/** — runtime.trigger('name') |
SÍ | trigger está tipado con EventNameOf<M> |
soma/** — events: { name: handler } |
SÍ | mapped type sobre EventNameOf<M> |
sema/components/*.ts — packs |
SÍ | semaSelector(morfo, part, { eventName }) está tipado |
SomaRuntimePart.trigger anclado |
SÍ | EventNameTargeting<M, K> |
eidos/lib/motion/presets/css.ts |
NO | strings sueltos — ver abajo |
CSS a mano ([data-event=...]) |
NO | scripts/eidos-lint.ts es la red |
| Tests, demos, READMEs | NO | grep |
El único punto ciego real son los presets de movimiento:
src/uix/eidos/lib/motion/presets/css.ts declara event: 'present',
event: ['dismiss', 'close'], event: 'announce', event: 'expand',
event: 'collapse'… y signatureSelectorList() (en lib/render-css.ts) los
convierte en [data-event^='...']. Son ~10 declaraciones que generan
eidos/generated/base.css.
Detalle que juega a favor: el operador es ^= (prefijo). Tras el renombrado,
[data-event^='emerge-open'] sigue capturando emerge-open-sub. Pero un
[data-event^='open'] sin actualizar deja de casar con NADA — falla en
silencio, sin error. Por eso F4 (medir en navegador) no es opcional en este
eje: un preset olvidado no rompe ninguna prueba, sólo deja de animar.
Fuera de ahí: 1 sola regla a mano en eidos/components/collapsible/collapsible.css
([data-event^='expand']).
4 · Fases
F0 · Reconfirmar el censo y congelar el mapa
Re-ejecutar el censo (los números de arriba son de 2026-08-10). Escribir el mapa 36→36 en un fichero de datos que el codemod y la verificación compartan, para que no haya dos listas que puedan divergir. Verificar el cero-ambiguos.
F1 · Renombrar en los morfos
Sólo morfo/components/*.ts. Al terminar, npm run check debe explotar con
los call sites rotos: esos errores SON el worklist, no un problema. Anotar
cuántos salen — es la medida de cobertura del compilador.
F2 · Seguir al compilador hasta cero
Soma, sema, SomaRuntimePart.trigger. No usar grep aquí: el compilador es
exhaustivo y el grep no. Terminar cuando check vuelva a su línea base.
⚠️ Medir la línea base con git stash, no de memoria. En esta sesión el «74»
resultó ser 74 posiciones únicas y 87 líneas del output machine: comparar por
MÉTODO, nunca por cifra.
F3 · El punto ciego: presets de movimiento + CSS a mano
eidos/lib/motion/presets/css.ts (~10) + la regla de collapsible. Regenerar
base.css (npm run generate:eidos-css). Pasar scripts/eidos-lint-all.ts.
F4 · Navegador — NO OPCIONAL
Un preset olvidado no rompe ninguna prueba. Medir con MutationObserver ligado
al NODO (no a un selector) + getAnimations(), al menos:
- dialog / drawer / popover —
emerge-open/emerge-closeaniman. - accordion / collapsible —
emerge-expand/emerge-collapseaniman. - toast —
signal-announce(5 presets lo usan: es el más expuesto). - tabs —
commit-select.
Trampas ya medidas en esta rama, no relearnearlas:
- Al exportar algo nuevo de un barrel, el grafo SSR de Vite va por detrás y la
página da 500 con
X is not definedmientras el cliente ya pinta bien. Se arregla navegando otra vez. No reiniciar el dev server. - Probar el gesto correcto: en esta sesión probé
Escapeesperando un collapse cuando la tecla eraBackspace, y unpointerleavesintético que la coordinación SafePolygon no dispara. El código estaba bien; la prueba, mal.
F5 · Docs, demos y guards
READMEs de los ~15 componentes tocados, docs/CANON.md si nombra alguno,
docs/architecture/sema.md. Las 68 demos que emiten. npm run docs:check.
F6 · Cerrar la puerta
Que esto no pueda volver a pasar: un guard que falle si un
morfo.events[].name no empieza por su semantic.family. Es una prueba de
~10 líneas sobre el censo que ya existe, y convierte la convención en contrato.
Sin esta fase el eje se re-abre solo — es la lección de los tres audits que
encontraron el mismo defecto sin cerrarlo.
5 · Riesgos
- Los presets de movimiento fallan en silencio (§3). Mitigación: F4.
- La rama es compartida.
git reset -q,git addexplícito, verificar congit diff --cached --name-only. sub-open/sub-closeson de hoy mismo (2026-08-10, sesión del eje perceptual): renombrarlos aemerge-open-subes coherente y barato, pero revisar que su prueba en navegador siga en pie.- No mezclar con el eje perceptual: F3 de aquel plan aún migra emisiones en los mismos providers. Ejecutar uno, verificar, y luego el otro.
6 · Aceptación
- Censo: 252 declarados / 252 con prefijo de familia / 0 sin prefijo.
checken la línea base medida con stash · suites server + navegador iguales.eidos-lint-allsin selectores inválidos nuevos ·docs:check0.- Las cuatro escenas de F4 medidas y animando.
- El guard de F6 en verde, y visto fallar antes con un nombre pelado introducido a propósito.