@ -71,10 +71,10 @@ Estado: `LIMPIO` = leído sobre el original · `RELEER` = leído contaminado ·
| `testing-and-tooling.md` | 110 | LIMPIO — releída completa 2026-07-30 |
| `testing-and-tooling.md` | 110 | LIMPIO — releída completa 2026-07-30 |
| `CANON.md` | 305 | LIMPIO — releída completa 2026-07-30 |
| `CANON.md` | 305 | LIMPIO — releída completa 2026-07-30 |
| `architecture/morfo.md` | 888 | LIMPIO — leída completa 2026-07-30 |
| `architecture/morfo.md` | 888 | LIMPIO — leída completa 2026-07-30 |
| `architecture/active-app.md` | 351 | — |
| `architecture/active-app.md` | 351 | LIMPIO — leída completa 2026-07-30 |
| `architecture/agent.md` | 472 | — |
| `architecture/agent.md` | 472 | LIMPIO — leída completa 2026-07-30 |
| `architecture/packs.md` | 86 | LIMPIO — releída completa 2026-07-30 |
| `architecture/packs.md` | 86 | LIMPIO — releída completa 2026-07-30 |
| `architecture/blocks.md` | 113 | — |
| `architecture/blocks.md` | 113 | LIMPIO — leída completa 2026-07-30 |
> `morfo.md` era la prioridad y ya está leída (era la capa del contrato, la más
> `morfo.md` era la prioridad y ya está leída (era la capa del contrato, la más
> tocada durante la auditoría fallida, y se llegó a escribir criterio en su
> tocada durante la auditoría fallida, y se llegó a escribir criterio en su
@ -84,15 +84,15 @@ Estado: `LIMPIO` = leído sobre el original · `RELEER` = leído contaminado ·
| Doc | Líneas | Estado |
| Doc | Líneas | Estado |
| --- | --- | --- |
| --- | --- | --- |
| `canon/tsc.md` (Token Scope Contract) | 329 | — |
| `canon/tsc.md` (Token Scope Contract) | 329 | LIMPIO — leída completa 2026-07-30 |
| `canon/vocabularies.md` (conjuntos cerrados, generados) | 153 | — |
| `canon/vocabularies.md` (conjuntos cerrados, generados) | 153 | LIMPIO — leída completa 2026-07-30 |
| `canon/recipe-contract.md` | 184 | — |
| `canon/recipe-contract.md` | 184 | LIMPIO — leída completa 2026-07-30 |
### Theming y motion
### Theming y motion
| Doc | Líneas | Estado |
| Doc | Líneas | Estado |
| --- | --- | --- |
| --- | --- | --- |
| `theming/reference.md` | 1822 | PARCIAL — §20– §28 leídas (1406– 1535), incl. ** §25** (color) |
| `theming/reference.md` | 1822 | LIMPIO — leída **completa** 2026-07-30 |
| `theming/motion.md` | 791 | LIMPIO — releída completa 2026-07-30 |
| `theming/motion.md` | 791 | LIMPIO — releída completa 2026-07-30 |
| `theming/gradient-finish.md` | 475 | — |
| `theming/gradient-finish.md` | 475 | — |
| `theming/guide.md` | 241 | — |
| `theming/guide.md` | 241 | — |
@ -115,9 +115,11 @@ Estado: `LIMPIO` = leído sobre el original · `RELEER` = leído contaminado ·
| `building-a-component.md` | 55 | — |
| `building-a-component.md` | 55 | — |
| `rfcs/*` (7 ficheros) | 1860 | — |
| `rfcs/*` (7 ficheros) | 1860 | — |
Total ≈ 19.000 líneas. **Leídas sobre el original: 15 documentos** (≈ 7.100 L) —
Total ≈ 19.000 líneas. **Leídas sobre el original: 21 documentos (≈ 10.400 L)** —
todo el núcleo de arquitectura menos `active-app` , `agent` y `blocks` . Sin
el núcleo de arquitectura COMPLETO, el canon COMPLETO, y `theming/reference`
empezar: canon (3), theming (5 y media), guías y decisiones (9).
entera. Sin empezar: el resto de theming (gradient-finish · guide · notes ·
channels), las guías (`component-guide` 1568 es la gorda), `decisions/` y los
7 RFCs. ≈ 6.200 L.
## Hallazgos que SÍ se sostienen
## Hallazgos que SÍ se sostienen
@ -240,6 +242,32 @@ código**, que es la única autoridad que no puede haberla escrito un agente.
nombrar lo que es de eidos») era **falsa** . La categoría wrapper-only del
nombrar lo que es de eidos») era **falsa** . La categoría wrapper-only del
hallazgo nº 9 existe (`data-variant`, `data-size` , …) pero `data-color` no
hallazgo nº 9 existe (`data-variant`, `data-size` , …) pero `data-color` no
pertenece a ella: viene del prop y viaja por el morfo.
pertenece a ella: viene del prop y viaja por el morfo.
**AMPLIACIÓN (lectura de `theming/reference.md`, misma sesión).** El corpus
ya tenía la respuesta escrita, dos veces, y con más autoridad de la que yo
reuní:
- ** `reference.md` §1.bis** existe LITERALMENTE para impedir este error.
Se titula *«Theming lives in Eidos, not in Morfo (by design)»* y se abre
con *«This is the most frequent architectural question»* . Su
§«What SHOULD enter morfo regarding theming» (líneas 282– 291) es
inequívoco: *«A component exposing `color` as a prop → * *must declare
`data-color.values: ['primary', 'affirm', ...]` in its morfo**»*, y en la
misma lista, *«purely visual attrs (`data-variant`, `data-size` ) that
NOBODY else needs → they do NOT go in morfo»*. La tabla de la línea 248
asigna `data-color.values` a **Morfo** , «cross-layer: soma validates,
eidos targets, sema references». La sesión revertida hizo justo lo que
esta sección enumera como propuesta a rechazar.
- ** `reference.md` §39** (líneas 1750– 1757, 2026-07-15 — la doctrina más
reciente) da el **criterio mecánico** que faltaba, y el porqué:
*«`data-gradient` is an eidos-only WRAPPER attr … * *Rule of thumb: morfo
declares an attr only when its driving prop crosses the soma
boundary**»*, con el modo de fallo medido: si declaras en morfo un attr
cuyo prop no llega a soma, el runtime emite `undefined` y
`mergeProps(restProps, state.props)` pisa el sello del wrapper.
→ Con eso la frontera queda nítida y comprobable: `color` **cruza** la
frontera de soma (los 12 morfos lo resuelven con `v.propRef('color')` ) →
va al morfo. `variant` / `size` / `gradient` no la cruzan → los sella el
wrapper. No es una convención: es de dónde se resuelve el valor.
14. **Y la pregunta REAL que había debajo: el enum del morfo es más estrecho que
14. **Y la pregunta REAL que había debajo: el enum del morfo es más estrecho que
el prop que se envía.** `theming/reference.md` §25, líneas 1496– 1507
el prop que se envía.** `theming/reference.md` §25, líneas 1496– 1507
(decisión de diseño 2026-07-18, «reversión de los subconjuntos»): *«`color`
(decisión de diseño 2026-07-18, «reversión de los subconjuntos»): *«`color`
@ -251,11 +279,29 @@ código**, que es la única autoridad que no puede haberla escrito un agente.
`data-color` con **6 valores cerrados**
`data-color` con **6 valores cerrados**
(`['primary','secondary','neutral','affirm','risk','threat']`), y
(`['primary','secondary','neutral','affirm','risk','threat']`), y
`scripts/morfo-check.ts:167` falla cuando un attr con `values` emite algo
`scripts/morfo-check.ts:167` falla cuando un attr con `values` emite algo
fuera del conjunto. → `<Switch color="teal">` compila por diseño y emitiría
fuera del conjunto. Esa es la contradicción que merece decisión del
un valor que el morfo no declara. **NO verificado** si hoy salta: haría
usuario, no la de si `data-color` va en el morfo.
falta que una demo renderice un valor fuera del enum y correr `morfo:check`
(necesita dev server); no lo he ejecutado. Esa es la contradicción que
**CADENA COMPLETA, verificada extremo a extremo (misma sesión).** No es
merece decisión del usuario, no la de si `data-color` va en el morfo.
hipotética — seguí el valor desde el prop hasta el DOM:
1. `eidos/lib/component-color.ts` → `CANONICAL_COLOR` = `COLOR_ROLES` ** ∪
`PALETTE_SCALES` ** = **42 nombres** . `resolveComponentColor('teal')`
devuelve `dataColor: 'teal'` (sólo un color CSS **crudo** se desvía a
`data-color-custom` + `--color-custom` ).
2. `eidos/components/switch/switch.svelte:42` pasa ese `dataColor` al prop
`color` de soma.
3. `soma/components/switch/switch-provider.svelte.ts:88– 94` lo devuelve
**verbatim** (sólo intercepta el intent evaluativo y el caso custom).
4. El morfo declara `data-color` con **6** valores.
→ `<Switch color="teal">` emite `data-color="teal"` , fuera del enum.
Y no es un caso aislado — enums declarados hoy: **avatar 8 · button 8 ·
card 8 · switch 6 · toggle 6 · dialog 3**, contra los 42 que el wrapper
puede sellar. Los seis pueden emitir fuera de contrato **por diseño** .
**NO verificado** si hoy salta en CI: `morfo:check` sólo ve lo que las
demos renderizan de hecho, y no lo he ejecutado (necesita dev server). El
agujero es que el guard de «lo declarado se cumple» depende de que una
demo elija el valor infractor — justo en el eje que la decisión de
2026-07-18 abrió a 42.
15. ** `provider.commitState()` / `provider.emitEvent()` no existen en el
15. ** `provider.commitState()` / `provider.emitEvent()` no existen en el
código.** `grep -rn "commitState\|emitEvent"` sobre todo el repo (`.ts`,
código.** `grep -rn "commitState\|emitEvent"` sobre todo el repo (`.ts`,
`.svelte` , `.js` , sin `node_modules` ) → **cero coincidencias** . Los
`.svelte` , `.js` , sin `node_modules` ) → **cero coincidencias** . Los
@ -318,6 +364,27 @@ código**, que es la única autoridad que no puede haberla escrito un agente.
diff buscando más casos antes de dar por saneado el árbol. Fix pendiente:
diff buscando más casos antes de dar por saneado el árbol. Fix pendiente:
una línea, sin decidir (no lo toco: regla 5).
una línea, sin decidir (no lo toco: regla 5).
### De la tanda canon + núcleo restante + theming (2026-07-30, sesión 3)
22. ** `active-app.md` enumera a mano un catálogo que ya driftó.** Su tabla
§«Available services» lista **12** factories y el árbol §«Filesystem
layout» los repite uno a uno. En `git ls-files
src/arts/active-app/service-factories/` hay **15** : faltan ** `agent.ts` ,
`motion.ts` y `scene.ts` ** en ambos sitios. Es la misma enfermedad que el
«8 roles» del nº 21 y que la ley que el propio corpus escribió
(`authoring.md`: catálogos hardcoded → puntero). El árbol es la fuente;
la lista es el problema.
23. ** `canon/tsc.md` anuncia un scope que dos docs declaran superado.** Su
tabla «Available scopes» lista `event:${v}` → *«Motion token bound to a
perceptual signal»* sin nota alguna. Pero `reference.md` §13 se titula
*«Sema integration (`event:* ` scope)»* y su cuerpo entero es
** «⚠️ Superseded»**, y `motion.md` (líneas 46 y 699) lo da por
**descartado, «no real use»** . Comprobado: el tipo SIGUE existiendo
(`eidos/lib/config-types.ts:471,499`) y **cero recetas lo consumen** . O
sea que las tres frases son literalmente ciertas — pero quien construya
desde el canon (que es para lo que está el canon) lo leerá como
disponible. Severidad baja; coste de arreglo, una nota.
## Hallazgos RETIRADOS (eran autocita)
## Hallazgos RETIRADOS (eran autocita)
- ~~«los tests de provider son convención, no guard»~~ — era la edición
- ~~«los tests de provider son convención, no guard»~~ — era la edición
@ -337,20 +404,22 @@ código**, que es la única autoridad que no puede haberla escrito un agente.
falló en el método, y al revertirla se perdieron los dos. La lección no es
falló en el método, y al revertirla se perdieron los dos. La lección no es
«desconfía del hallazgo revertido», es: **un hallazgo doc↔código se verifica
«desconfía del hallazgo revertido», es: **un hallazgo doc↔código se verifica
contra el código**. Si sólo se puede sostener citando otro documento, no está
contra el código**. Si sólo se puede sostener citando otro documento, no está
verificado. Los nueve hallazgos nuevos de esta sesión llevan los dos anclajes.
verificado. Los once hallazgos nuevos de estas sesiones llevan los dos anclajes.
## Cómo continuar
## Cómo continuar
~~1. Releer los 7 marcados `RELEER` ~~ · ~~2. `morfo.md` completo~~ — hechos.
~~1. Releer los 7 marcados `RELEER` ~~ · ~~2. `morfo.md` completo~~ — hechos.
1. **Siguiente tanda** : el canon sin empezar (`canon/tsc.md` 329 ·
~~1. El canon + el núcleo restante~~ · ~~2. `theming/reference.md` entera~~ —
`canon/vocabularies.md` 153 · `canon/recipe-contract.md` 184) y lo que
hechos en la sesión 3.
queda del núcleo (`architecture/active-app.md` 351 ·
`architecture/agent.md` 472 · `architecture/blocks.md` 113). ≈ 1.600 L.
1. **Siguiente tanda** : las guías —`guides/component-guide.md` (1568, los
2. Después `theming/reference.md` **entera** (sólo van §20– §28) — es el
pasos 1– 40 + reglas A1– A37) y `guides/component-audit.md` (369). Es donde
documento vivo más citado y el que ancló la pregunta del color.
vive el criterio de autoría, y lo que más se cita al construir.
3. Luego guías y decisiones: `guides/component-guide.md` (1568, las reglas
2. Después `decisions/book-deviations.md` (851) — la bitácora de dónde el
A1– A37) y `decisions/book-deviations.md` (851) son los dos gordos.
framework se separa del libro, y por qué.
3. Luego el resto de theming (`gradient-finish` 475 · `guide` 241 · `notes`
179 · `channels` 143) y los 7 RFCs (1860).
4. Actualizar este fichero al final de cada sesión de lectura: estado por
4. Actualizar este fichero al final de cada sesión de lectura: estado por
documento y línea donde se paró.
documento y línea donde se paró.
5. **No escribir código ni doctrina hasta acabar.** Un hallazgo sólo se reporta
5. **No escribir código ni doctrina hasta acabar.** Un hallazgo sólo se reporta
@ -371,9 +440,11 @@ lectura, y quedan ≈ 11.900 líneas. En concreto **no se ha tocado**: el enum d
docs que documentan `commitState` /`emitEvent` (nº 15), las dos frases sobre el
docs que documentan `commitState` /`emitEvent` (nº 15), las dos frases sobre el
guard inexistente (nº 16), `soma-architecture.md` §12/§8.bis sobre `clsx`
guard inexistente (nº 16), `soma-architecture.md` §12/§8.bis sobre `clsx`
(nº 17), `packs.md` /`glossary.md` sobre Aura y `uix.scene` (nº 18), el
(nº 17), `packs.md` /`glossary.md` sobre Aura y `uix.scene` (nº 18), el
frontmatter de `CANON.md` (nº 19), el entry huérfano de `package.json` (nº 20)
frontmatter de `CANON.md` (nº 19), el entry huérfano de `package.json` (nº 20),
ni la línea que tiene `docs:check` en rojo (nº 21).
la línea que tiene `docs:check` en rojo (nº 21), la tabla de servicios de
`active-app.md` (nº 22) ni la nota que le falta al scope `event:` (nº 23).
De los nueve, **sólo el nº 14 pide decisión de usuario** (enum cerrado del
morfo vs. `color` abierto por diseño). Los otros ocho son deriva doc↔código
De los once, **sólo el nº 14 pide decisión de usuario** (enum cerrado del
con un único arreglo evidente cada uno.
morfo vs. `color` abierto a 42 por diseño; y con `morfo:check` cazándolo sólo
si una demo elige el valor). Los otros diez son deriva doc↔código con un único
arreglo evidente cada uno.