# 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 entre `active-uix`, `morfo`, `soma`, `sema`, `eidos`, > `adom`, `langs`, `format` y `prefs` quedan descritos en > `active_architecture.md`, sección "Handoff 2026-05-14". Ya queda fijada la > regla principal de ownership: solo `ActiveApp` y `ActiveUix` standalone crean > servicios compartidos. La tabla ejecutable de contratos vive en `contracts.ts` > y se valida en `contracts.test.ts`. La tabla de naming canónico vive en > `active_architecture.md#01-naming-canonico`. Ownership DOM P1 queda cerrado: > las escrituras gestionadas por UIX pasan por `ActiveDom`. > > **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: - `texts` declara las ranuras de texto del componente como idlangrefs absolutos (`'#?components.{kebab}.{key}|fallback'`). El catálogo multilingüe vive en `src/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 contrato `data-*`. El catálogo de strings (`componentLangs` + `commonLangs`) lo registra `ActiveUix` al arrancar; el morfo nunca extiende `ActiveLangs` diná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 `Eidos` desde `ActiveUix`; - `ActiveEidos` asume authoring, validacion, generacion CSS, persistencia y contexto visual; - `events` es el servicio perceptivo runtime y `morfo.translations` es 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`, `eidos` y los > componentes no crean `dom`, `langs`, `prefs`, `format`, `clipboard` ni > 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/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: ```ts 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(); ```