21 KiB
Hand-offs — May 2026 (extracted from the layer READMEs)
These session hand-off notes used to live inline at the top of the layer
READMEs (UIX and arts). They were pulled out so those reference docs read as
timeless. Kept here for traceability; the rules they fixed are now reflected in
the docs themselves and enforced by src/uix/contracts.ts + contracts.test.ts.
The
active_architecture.md§0 hand-off (the largest one) is not here yet: it embeds the referenced "contratos mínimos" table that other docs link to, so it gets separated from its handoff framing during the architecture (E1) pass, not in this mechanical extraction.
From src/uix/README.md (intro blockquote) — 2026-05-14
Visión de conjunto: para entender las cuatro capas (morfo, soma, sema, eidos) en una sola lectura, motivaciones y articulación incluidas, ir a
active_architecture.md. Este README mantiene la introducción más narrativa.Hand-off de continuación: el estado actual de migración y los próximos pasos viven en
continue.md. Handoff 2026-05-14: pausa deliberada antes de seguir programando. Los contratos mínimos entreactive-uix,morfo,soma,sema,eidos,adom,langs,formatyprefsquedan descritos enactive_architecture.md, sección "Handoff 2026-05-14". Ya queda fijada la regla principal de ownership: soloActiveAppyActiveUixstandalone crean servicios compartidos. La tabla ejecutable de contratos vive encontracts.tsy se valida encontracts.test.ts. La tabla de naming canónico vive enactive_architecture.md#01-naming-canonico. Ownership DOM P1 queda cerrado: las escrituras gestionadas por UIX pasan porActiveDom.Convenciones doctrinales del API (intent ↔ color, subset por componente, root visual con partes attached en eidos, sound prepare-time priming): viven en
src/docs/GUIA_IMPLEMENTACION_SEMAUIX.md. Autoritativo para todo wrapper / migración nueva.
From src/uix/morfo/README.md — Handoff 2026-05-14
Morfo debe seguir siendo declarativo: no instancia servicios y no conoce
ActiveUix. Sus campos solo entran en el contrato cuando son superficie
cross-layer real; si un dato pertenece a una sola capa, vive en esa capa.
Decisiones cerradas:
textsdeclara las ranuras de texto del componente como idlangrefs absolutos ('#?components.{kebab}.{key}|fallback'). El catálogo multilingüe vive ensrc/uix/langs/components/{kebab}.ts(fuera del morfo).- Textos comunes usan
v.commonRef(...)o un idlangref absoluto; no se duplican en cada morfo. registerMorfo(morfo)registra el contratodata-*. El catálogo de strings (componentLangs+commonLangs) lo registraActiveUixal arrancar; el morfo nunca extiendeActiveLangsdinámicamente.- Si Soma, Sema y Eidos necesitan un dato compartido, pasa por morfo o por un contrato publico; no por imports laterales entre capas.
- La regla 2-de-3 sigue vigente para extender morfo.
From src/uix/sema/README.md — Handoff 2026-05-13
Sema ya tiene contrato explicito de DOM: si el canal visual esta activo,
EngineSemantic debe recibir dom o projector. Si se construye desde
ActiveUix, recibe el dom de ActiveUix; si se usa directamente fuera de
UIX, el integrador debe pasar un writer explicito o usar visual:false.
Sema no cae a escrituras DOM directas por defecto.
Tambien queda por decidir si emit debe seguir siendo secuencial estricto de
forma global o si la secuenciacion pertenece al evento/morfo. No cambiar esto
sin documentar antes la tabla de contratos minimos en ../active_architecture.md.
From src/uix/soma/README.md — Handoff 2026-05-14
Soma no debe crecer ahora con ActiveSoma/EngineSoma por simetria. El
contrato minimo de SomaRuntime con ActiveUix (dom, events, langs,
format, prefs) queda descrito en src/uix/contracts.ts. La regla de
ownership ya queda cerrada: Soma no crea servicios compartidos. Recibe dom
desde el scope Soma.runtime(...); si no hay una superficie ActiveDom, falla
en la raiz activa, no dentro de un componente.
Punto critico para manana: confirmar que todo atributo mutable sigue pasando
por el servicio DOM activo, y que ninguna ausencia de dom hace que Soma o
Sema caigan a escrituras directas.
From src/uix/eidos/README.md — Handoff 2026-05-14
Eidos queda congelado a nivel de componentes hasta reauditar la arquitectura
de UIX. No tocar src/uix/eidos/components/* salvo orden explicita.
Actualización 2026-05-17: la migración de componentes se reanudó por orden
explícita. La regla vigente no cambia: cada componente nuevo debe seguir
components/README.md, envolver partes públicas de Soma directamente y añadir
sólo superficie visual de Eidos.
Antes de seguir con wrappers o recipes por componente hay que respetar estas decisiones:
- que contrato minimo consume
EidosdesdeActiveUix; ActiveEidosasume authoring, validacion, generacion CSS, persistencia y contexto visual;eventses el servicio perceptivo runtime ymorfo.translationses el catalogo declarativo de texto owned por el componente;- que parte se genera desde codigo y que parte puede venir solo por CSS;
- como se mantiene la regla de escritura DOM unica en standalone
dom:false.
La referencia de arranque esta en ../active_architecture.md, seccion
Handoff 2026-05-14.
From src/uix/active-uix/README.md — Handoff 2026-05-14
La regla de ownership queda cerrada:
Solo los composition roots crean servicios compartidos. Si hay
ActiveApp,attachActiveUix(app)consume sus servicios y falla si falta alguno requerido. Si no hay app,createActiveUix(...)es el composition root local y crea los servicios/prefs de UIX.morfo,soma,sema,eidosy los componentes no creandom,langs,prefs,format,clipboardni equivalentes.
La revision de naming queda cerrada asi: events es el nombre publico del
motor perceptivo en ActiveUix y tambien el nombre del servicio que
defineUixServices(...) registra en ActiveApp. semantic queda reservado
para el payload declarativo de morfo.events[].semantic, no para servicios
runtime. morfo.translations queda como catalogo declarativo owned por el
componente. prefs es el unico nombre para preferencias: ActiveUix expone
el ActivePrefs bruto y las capas inferiores consumen vistas acotadas cuando
no deben mutar.
From src/arts/README.md — Handoff 2026-05-14
La frontera entre arts y uix queda fijada por la tabla de contratos de
src/uix/contracts.ts. ActiveApp compone servicios y mantiene prefs;
ActiveUix consume esos servicios cuando se adjunta a una app o los crea en
modo standalone. El antiguo artefacto frontend queda retirado: la proyeccion
cross-modal pertenece a arts/prefs (createActivePrefsDomProjection(...)) y
la proyeccion visual pertenece a ActiveEidos.
From src/arts/active-app/README.md — Handoff 2026-05-13
ActiveApp no absorbe decisiones propias de UIX. Mantiene el core
(logger, bus, timers, orca, prefs) y compone solo los servicios que
la aplicacion declara en services.
El antiguo servicio frontend fue retirado. Las preferencias transversales
(direction, motion, sound, haptic) se proyectan mediante
createActivePrefsDomProjection(...) cuando la app lo cablea con un
ActiveDom. Las preferencias visuales (theme, mode, density) pertenecen
a Eidos. Si una ruta UIX necesita un toggle claro/oscuro, debe pasarlo a
ActiveEidos.modeSource; no debe declarar ni escribir App.prefs.theme salvo
que sea una dimension custom de una app ajena a UIX.
La tabla ejecutable de contratos entre ActiveApp, ActiveUix y las capas
UIX vive en src/uix/contracts.ts.
From src/arts/adom/README.md — Handoff 2026-05-14
ActiveDom es la unica superficie permitida para mutar DOM gestionado desde
UIX. La decision P1 queda cerrada en ActiveUix: dom:false inyecta un
disabledDom no-op compartido por Soma/Sema/Eidos. No puede haber fallback
silencioso a escrituras directas dentro de UIX.
From src/arts/format/README.md — Handoff 2026-05-14
Format debe seguir prefs.locale, no prefs.language ni el servicio
langs. Los ejemplos historicos que hablan de App.langs.setLocale(...)
representan el modelo viejo y no son doctrina actual.
El objetivo es que una app tenga una sola verdad:
App.prefs.locale.set('es-AR');
App.format.numbers.format(1234.5);
App.format.currency.getCurrency(); // ARS
App.format.units.getSystem(); // metric
App.format.dates.getDateOrder();
From src/uix/eidos/README.md — Cambios 2026-05-21
Extracted 2026-07-02 (docs reconciliation): dated change-log block that lived inline in the eidos README. Kept verbatim; counts and citations reflect the state at the time (e.g.
DEMO_AUTHORING_GUIDE §12.8is the v1 guide — the v2 replaced it with §6/§7).
- Tokens muted añadidos al contrato.
SurfaceColorRolesyContentColorRolesahora incluyenmuted(entreoverlay+backdropy entresecondary+disabledrespectivamente). Mapeo base:--color-surface-muted: var(--primitive-neutral-3)(light + dark) y--color-content-muted: var(--primitive-neutral-10). Antes existían 17+3 referencias rotas en recipes/components que el browser caía a initial-value (texto invisible para placeholders, separadores, weekday del calendar, group-heading del select, etc.). Solucionado víathemes/base.ts+render-css.ts+ regen. - Typo
--color-neutral-element-hovercorregido enform.css:76→--color-neutral-hover(el token correcto existente). - Raw colors removidos.
archetypes.css:122(hsl indigo fijo para[aria-selected]) yevents.css:eidos-commit-settle(rgba indigo fijo) sustituidos porcolor-mix(var(--color-primary-solid) …). Ya no quedan hex/rgb/hsl crudos ensrc/uix/eidos/**/*.cssni enrecipes/base.ts. - Cobertura de tamaños expandida. 20 componentes pasan de
sm·md·lgaxs·sm·md·lg·xl(form controls + text inputs + progress/meter + field/form) o axs·sm·md·lg(nav controls: breadcrumb, pagination, tag-group, toolbar). Categorización documentada enDEMO_AUTHORING_GUIDE §12.8(v1). Paneles compuestos (calendar, date-picker, date-range-picker, file-upload, stepper, tooltip) mantienensm·md·lg. La elección responde a uso real, no a artificio: barras y controles tactiles escalan limpio en 5 escalones; paneles compuestos no se benefician por debajo desm. - Paridad de chips en demos.
field.variantytoolbar.variantdejaron de narrowarControlVarianta 2 valores; ahora exponen los 3 (surface | outline | ghost). El CSS añade selectores[data-variant='outline']con bg transparente + border visible para ambos componentes. La norma queda fijada en CHECKLIST §D-7.4. - Scrollbar portaled. Las reglas
::-webkit-scrollbar*viven sin scope enweb/routes/uix/uix.css(sólo se carga bajo/uix).--uix-linese duplica en:rootcon override:root[data-mode='dark'](atributo escrito porActiveEidos), permitiendo que portals (Combobox listbox, Popover, Dialog, Drawer) resuelvan el token aunque vivan fuera de[data-uix-docs].
From src/uix/eidos/README.md — Estado actual (2026-05-17)
Extracted 2026-07-02 (docs reconciliation): frozen status snapshot (the wrapper list stops at ~20; the real catalog kept growing). The live component inventory is the directory tree +
npm run component:audit, never a list in a doc.
- ActiveEidos: implementado como runtime/contexto visual y superficie de
configuracion. Gestiona primitivas, roles canonicos, themes, validacion,
contrato CSS, persistencia y render CSS (
renderStaticCss,renderThemeCss). - Authoring API:
defineEidosConfig,extendEidosConfigycreateThemeBaseEidosConfigpermiten crear configuraciones completas o extender el theme base sin mutar las constantes del sistema.getCssContract()expone el contrato estructurado,renderContractCss()lo materializa como CSS para themes externos,renderCssVariables()permite escribir overrides runtime contract-aware ytoDocument()/serialize()exponen el envelope versionado para persistencia. - Runtime CSS:
ActiveEidosreacciona a supreferencescompuesto o a fuentes explicitasmodeSource/densitySource, soporta themes de config y CSS-only viathemeSource, acepta variables runtime en un style block propio, y conapplyDom:falseno escribe en el DOM. - Wrappers por componente: la superficie migrada desde Soma ya incluye
toggle,switch,collapsible,dialog,drawer,popover,toast,accordion,avatar,tooltip,tabs,checkbox,radio-group,meter,progress,slider,pagination,rating-group,search-field,number-fieldybreadcrumb. Todos usan root visual + partes attached, sinProviderpúblico ni API flat. - Color: basado en roles canonicos de jerarquia e intents
(
primary,secondary,tertiary,neutral,affirm,fulfill,risk,threat,loss) y escalas de 12 pasos. Por cada escala genera alpha tokensa1..a12, derivadas automaticamente o sobrescribibles concolor.alphaScalespor theme. Los roles semanticos validos son solo los declarados por el contrato de Eidos. - Size:
xxs..xxlse renderiza como map global coordinado (control-height, font, icon, padding, gap, radius).fullqueda como valor de layout, no como primitiva fisica. Cada componente declara el sub-rango que su recipe mapea — la categorización canónica está enDEMO_AUTHORING_GUIDE.md §12.8(v1; form controls + text inputs + progress/meter + field/form usanxs..xl; nav controls usanxs..lg; paneles compuestos mantienensm..lg). - Border / opacity / z-index / shadow: ya forman parte del contrato
generado. Border define escala de width/style y aliases globales; opacity
cubre estados de UI y overlays; z-index cubre capas comunes; shadow combina
escala fisica
1..6con aliases semanticos por theme. - Layout: ya forma parte del contrato generado. Incluye
containerWidth,containerPaddingInline,contentWidthyaspectRatiocomo tokens estables y authorables desdeEidosConfig. - Density: ya forma parte del contrato generado. Incluye
spaceScaleycontrolScalepara los tres niveles canonicoscompact,comfortableyspacious, conectados aldata-densityque proyectaActiveEidos. Mueve ritmo de layout y altura de controles; NO escala la tipografia. - Scaling: eje de zoom global independiente de la densidad (paridad
con el
scalingde Radix). Niveles90/95/100/105/110proyectados viadata-scaling; escalaspace,control-height,font-sizeeicon-size(SI incluye tipografia), no radius/border/ sombra. Se multiplica con la densidad. Ver THEMING.md §23. - Tipografia: usa tamaños canonicos
xxsaxxxl, familias libres por key y estilos tipograficos (h1,h2,body, etc.) comoRecord<string, TypographyStyle>. - Convencion del API de componentes: disciplined option C esta
documentada en
components/README.md. La migracion de componentes avanza por tandas pequenas y no debe arrastrar cambios de demos/rutas ni reimplementar comportamiento que pertenece a Soma. - CSS generado:
generated/base.cssya se genera desde la config base de Eidos connpm run generate:eidos-cssy se importa como foundation estatica. Los CSS historicos decontracts/ythemes/base/ya no existen en el arbol activo; el contrato se publica desdeActiveEidosy los valores base desdegenerated/base.css. Los antiguostokens/components/*tambien salen del entrypoint:EidosConfig.recipesgenera los aliases de recipe estables. - Recipes: quedan deliberadamente como
RecipeTokenSetplano. No se crea jerarquia estructurada hasta que una recipe tenga un builder/consumer real que necesite mas semantica que aliases CSS. La guardiarecipe-css-contract.test.tsevita que el theme base declare aliases no consumidos o que un CSS de componente use variables fuera del contrato. - Check del repo:
npm run checkno reporta errores ni warnings en este punto.
From src/uix/eidos/components/README.md — Estado de la migración (2026-05-20)
Extracted 2026-07-02 (docs reconciliation): frozen migration-status table. The migration completed on 2026-05-22 (every component + 5 pickers + 2 grids); the live inventory is the
components/tree +npm run component:audit.
La tanda 2026-05-17 reanuda la migración Soma -> Eidos por orden explícita.
Los wrappers nuevos siguen el mismo criterio: envolver partes públicas de Soma,
añadir sólo props visuales (size en esta tanda) y dejar comportamiento,
estado, ARIA, traducciones y escritura headless en Soma/Morfo.
| Componente | Forma canónica | Notas |
|---|---|---|
| toggle | ✅ single-part | piloto |
| switch | ✅ multi-part | Thumb |
| collapsible | ✅ multi-part | Trigger, Content |
| dialog | ✅ multi-part | Trigger, Portal, Overlay, Content, Title, Description, Close, Header, Footer |
| drawer | ✅ multi-part | + Handle |
| field | ✅ multi-part | Label, RequiredIndicator, Control, Input, HelperText, ErrorText, Prefix, Suffix |
| form | ✅ multi-part | Submit, Reset, ErrorSummary, AutoFields |
| popover | ✅ multi-part | Arrow, Anchor, Title, Description |
| toast | ✅ multi-part | + Toaster separate |
| accordion | ✅ multi-part | Item, Header, Trigger, Content |
| avatar | ✅ multi-part | Image, Fallback (eidos-native) |
| breadcrumb | ✅ multi-part | List, Item, Link, Separator, Ellipsis |
| calendar | ✅ multi-part | Header, Heading, Prev/Next, Month/YearSelect, Grid, Cell, Day |
| date-picker | ✅ multi-part | DateField + Popover + Calendar composition |
| icon | ✅ single-part | + 1697 lucide glyphs |
| meter | ✅ multi-part | Indicator |
| number-field | ✅ multi-part | Input, IncrementTrigger, DecrementTrigger, Scrubber |
| pagination | ✅ multi-part | FirstTrigger, PrevTrigger, NextTrigger, LastTrigger, Item, Ellipsis |
| progress | ✅ multi-part | Label, ValueText, Indicator |
| rating-group | ✅ multi-part | Item |
| search-field | ✅ multi-part | Input, ClearTrigger |
| select | ✅ multi-part | Trigger, Value, Indicator, Portal, Content, Viewport, Item, ItemIndicator, Group |
| combobox | ✅ multi-part | Control, Input, Trigger, Indicator, Portal, Content, Viewport, Item, ItemIndicator |
| slider | ✅ multi-part | Range, Thumb, Tick |
| tooltip | ✅ multi-part | + Group |
| tabs | ✅ multi-part | List, Trigger, Content, Indicator |
| checkbox | ✅ multi-part | Indicator, HiddenInput, Group, GroupLabel |
| radio-group | ✅ multi-part | Item, Indicator, HiddenInput, Label |
| toolbar | ✅ multi-part | Button, Link, Group, GroupItem, Separator |
| tag-group | ✅ multi-part | Label, Item, Link, RemoveButton |
| tags-input | ✅ multi-part | Control, Input, Item, ItemText, ItemDeleteTrigger, ClearTrigger |
| file-upload | ✅ multi-part | Label, Dropzone, Trigger, HiddenInput, FileList, Item, preview/progress/actions |
| editable | ✅ multi-part | Area, Control, Preview, Input, EditTrigger, SubmitTrigger, CancelTrigger |
| stepper | ✅ multi-part | List, Item, Trigger, Indicator, Separator, Content, CompletedContent, Prev/Next |
Orden recomendado para continuar
- Componentes grandes sólo con tabla previa de migración:
date-range-picker,time-field,time-picker.