style: prettier de una sola vez sobre el repositorio (F5 del cierre, parte 3)

Formato puro: `npm run format` (dos pases; siete ficheros no convergían en el
primero) sobre todo lo que .prettierignore no excluye (web/ congelado,
.claude/, artefactos generados). Este commit va en .git-blame-ignore-revs.

Neutralidad medida fichero a fichero, compilando y minificando con esbuild (y
con el compilador de Svelte, cliente y servidor, para .svelte) la versión de
HEAD y la formateada: 1 031 ficheros de código idénticos; 9 CSS que solo
difieren en espacios pegados a un paréntesis (`var( --x )` frente a
`var(--x)`), que CSS no tokeniza como significativos; 510 Markdown sin
compilación posible (docs:check los valida). Los dos generados y el guard que
dependía del formato se resolvieron en el commit anterior.

Verificación sobre este árbol: npm run lint exit 0 · gate entero verde salvo
focus-census, arreglado en el commit anterior y re-ejecutado (9/9): check:gate
OK (src/ y scripts/ a cero) · docs:check 0/0 · arts/blocks/packs/rtl/
translations/agent · eidos:lint 0 inválidos · apps:check (boot 27/27, 0
errores) · suite 465/466 → 466/466 con el guard corregido · build de la raíz
exit 0.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
alpha-0.1-background
dev 3 weeks ago
parent 6d4aa05fbd
commit 468a9d1134

@ -1,18 +1,19 @@
# Name
### vicen
# Synopsis
# Description
# Example
# Install:
`npm install vicen`
# Test:
`npm test`
#License:

@ -13,17 +13,17 @@ el ejercicio: 8 de 9 cerrados; de **#7** (contrato CSS-vars soma→eidos) se cer
la dirección recipe→tema con un guard (opción C, cazó 3 fantasmas reales), y
queda solo el sub-contrato provider→recipe (opción A, opcional).
| # | Tropiezo | Estado | Cómo |
|---|---|---|---|
| 1 | Vocabularios invisibles | ✅ RESUELTO | `npm run docs:vocabularies` → `docs/canon/vocabularies.md` desde los consts + guard docs-check I7 (`116594e0`) |
| 2 | Drift `kind` public/virtual vs internal | ✅ RESUELTO | `MorfoPartKind = 'public' \| 'private' \| 'virtual'` (types.ts) y checklist A-2.2 alineado |
| 3 | No hay capa de gesto radial | ✅ RESUELTO | `Gesture.rotate` 4ª especialización en `soma/layers/gesture` (`18b0d44e`); el Knob lo consume |
| 4 | Doctrina `trigger()` continuo sin cerrar | ✅ RESUELTO | sección `## Continuous components` en `sema.md` (`1da36ca6`), fact-check adversarial |
| 5 | Falta condición `part-absent` | ✅ RESUELTO | `{ when: 'part-absent', part }` en morfo (`11504043`); el morfo del Knob la usa |
| 6 | Formato de `langs/components/{kebab}.ts` | ✅ RESUELTO | forma `LangNode` (`{ key: { es, en } }`, anidable, `satisfies`) documentada en morfo/soma/checklist |
| 7 | CSS-vars del provider sin contrato | 🟡 CASI | dirección **recipe→tema** guardada (opción C: guard de fantasmas de tema en `recipe-css-contract` — pilló 3 bugs reales); queda solo el sub-contrato **provider→recipe** (opción A, opcional) |
| 8 | Docs imprescindibles fuera del paquete | ✅ RESUELTO | `component-audit.md §0` lista el paquete mínimo como archivos exactos |
| 9 | Fricciones menores (docs) | ✅ RESUELTO | `### Authoring notes` en `soma.md` §6: `state<T>()` vs `$state`, `role` opcional en Provider, `Without<>`/`PrimitiveDivAttributes`, ownership de pointermove/up del gesture |
| # | Tropiezo | Estado | Cómo |
| --- | ---------------------------------------- | ----------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1 | Vocabularios invisibles | ✅ RESUELTO | `npm run docs:vocabularies` → `docs/canon/vocabularies.md` desde los consts + guard docs-check I7 (`116594e0`) |
| 2 | Drift `kind` public/virtual vs internal | ✅ RESUELTO | `MorfoPartKind = 'public' \| 'private' \| 'virtual'` (types.ts) y checklist A-2.2 alineado |
| 3 | No hay capa de gesto radial | ✅ RESUELTO | `Gesture.rotate` 4ª especialización en `soma/layers/gesture` (`18b0d44e`); el Knob lo consume |
| 4 | Doctrina `trigger()` continuo sin cerrar | ✅ RESUELTO | sección `## Continuous components` en `sema.md` (`1da36ca6`), fact-check adversarial |
| 5 | Falta condición `part-absent` | ✅ RESUELTO | `{ when: 'part-absent', part }` en morfo (`11504043`); el morfo del Knob la usa |
| 6 | Formato de `langs/components/{kebab}.ts` | ✅ RESUELTO | forma `LangNode` (`{ key: { es, en } }`, anidable, `satisfies`) documentada en morfo/soma/checklist |
| 7 | CSS-vars del provider sin contrato | 🟡 CASI | dirección **recipe→tema** guardada (opción C: guard de fantasmas de tema en `recipe-css-contract` — pilló 3 bugs reales); queda solo el sub-contrato **provider→recipe** (opción A, opcional) |
| 8 | Docs imprescindibles fuera del paquete | ✅ RESUELTO | `component-audit.md §0` lista el paquete mínimo como archivos exactos |
| 9 | Fricciones menores (docs) | ✅ RESUELTO | `### Authoring notes` en `soma.md` §6: `state<T>()` vs `$state`, `role` opcional en Provider, `Without<>`/`PrimitiveDivAttributes`, ownership de pointermove/up del gesture |
## 1. Vocabularios canónicos invisibles desde los docs
@ -32,11 +32,11 @@ explícitamente copiar la lista ("a copied list survived at 24 entries while
the code grew to 26"). Correcto contra el drift humano — pero un agente que
trabaja desde el docs-book **no puede asignar archetypes**: no sé si existe
`control`, `handle` o `indicator` para las partes del Knob, y A-2.2 los pide
en *todas* las partes (error-level en el audit). Lo mismo pasa con
en _todas_ las partes (error-level en el audit). Lo mismo pasa con
`SEMA_MAP.families[*].hold` (¿cuánto dura el hold de `handle`?), los `kind`
categóricos del HapticChannel, y el contenido de `commonLangs`.
**Fix sugerido**: apéndice *generado desde código* en el docs-book
**Fix sugerido**: apéndice _generado desde código_ en el docs-book
(`npm run docs:vocabularies`). Generado = sin objeción de drift. Para un
agente, ese apéndice es la diferencia entre declarar y adivinar.
@ -90,8 +90,8 @@ contrato-fuera-del-morfo que el framework existe para eliminar.
## 6. El formato del catálogo `langs/components/{kebab}.ts` nunca se muestra
Todos los docs referencian su *ubicación* (morfo.md, soma.md, guide A3,
checklist A-1.3) pero ninguno enseña su *forma*: ¿export nombrado?, ¿record
Todos los docs referencian su _ubicación_ (morfo.md, soma.md, guide A3,
checklist A-1.3) pero ninguno enseña su _forma_: ¿export nombrado?, ¿record
`{ key: { en, es } }` o `{ en: { key } }`?, ¿claves anidadas o planas con
puntos? Mi `knob.ts` de langs es una conjetura. A-1.3 es error-level: un
agente fallará el audit por un archivo cuyo formato no está documentado en
@ -135,10 +135,10 @@ selectors vía `style` no, pero soma+eidos ya son 2).
> `recipe-css-contract.test.ts`: toda `var(--x)` **sin fallback** de un recipe
> debe resolver a un token declarado en algún sitio del árbol CSS de eidos
> (foundation + capas + auto-declaraciones del componente); las `var(--x,
> default)` son runtime-opcionales (vars provider/floating con default) y quedan
default)` son runtime-opcionales (vars provider/floating con default) y quedan
> exentas por construcción. El guard cazó **3 fantasmas reales** además de los
> del Knob — `card-group --color-content-default`→`-primary`, `link-preview
> --leading-body`→`-normal`, `textarea --font-family-body`→`-primary` —
--leading-body`→`-normal`, `textarea --font-family-body`→`-primary` —
> arreglados. Queda solo la dirección **provider→recipe** (opción A).
>
> **A2 (grep) descartado — probado ambiguo (2026-07-03).** Un `var(--{c}-x)` que

@ -21,17 +21,17 @@ three docs after the canon moved to 8). Every other doc links here.
> default hold, the intents, haptic kinds, part archetypes, palette scales,
> sizes, variants, shared strings)? They are spelled out — GENERATED from the
> code, so they never drift — in [`canon/vocabularies.md`](./canon/vocabularies.md).
> This file is the *doctrine*; that one is the *enumerated lists*.
> This file is the _doctrine_; that one is the _enumerated lists_.
Two anchors hold this canon honest:
- **The book** — `docs/Disenando_lo_que_ocurre_HOMOGENEIZADO.pdf` ("Diseñando
lo que ocurre", edición homogeneizada). The editorial source. Each entry
cites its chapter.
- **The code** — the runtime is the executable form. Concrete *values* (per-family
- **The code** — the runtime is the executable form. Concrete _values_ (per-family
holds, channel signatures, the full verb lists with author extensions) live in
code and are **linked, not copied here**, on purpose. This doc fixes the
*doctrine*; the code fixes the *numbers*.
_doctrine_; the code fixes the _numbers_.
> Rule: if you need to state a family, an intent, a verb, or a composition rule
> in any other doc, **link this file** — do not paste a copy. A second copy is a
@ -51,14 +51,14 @@ The framework encodes this chain literally: **morfo declares** it, **soma
executes** it (`runtime.trigger`), **sema** carries the perceptual vocabulary and
dispatches channels, **eidos** materializes the visual channels. See
[architecture/active-architecture.md](./architecture/active-architecture.md) for the layer wiring;
this file is only the *vocabulary* that flows through it.
this file is only the _vocabulary_ that flows through it.
---
## 2. The 8 families
A family is **not** a component or an effect. It is *a recurring class of event
that answers one perceptual question* (book ch. 8, ch. 21). The eight are the
A family is **not** a component or an effect. It is _a recurring class of event
that answers one perceptual question_ (book ch. 8, ch. 21). The eight are the
reduction of a wider exploratory set down to a minimal-yet-sufficient grammar
(book ch. 8 §1–3).
@ -67,26 +67,26 @@ Canonical list: `SemaFamily` in [`src/uix/sema/types.ts`](../src/uix/sema/types.
active channels and hold: `SEMA_MAP.families` in
[`src/uix/sema/sema-map.ts`](../src/uix/sema/sema-map.ts).
| Family | Perceptual question | Accepts intent | Book |
| --- | --- | --- | --- |
| `contact` | ¿el sistema ha sentido mi acción? | leve / anticipatory | ch. 22 |
| `commit` | ¿qué quedó fijado o tuvo consecuencia? | **fully** | ch. 23 |
| `signal` | ¿algo reclama mi atención? | **fully** | ch. 24 |
| `handle` | ¿estoy manipulando directamente este objeto? | only on `drop` | ch. 25 |
| `emerge` | ¿algo entró o salió del campo perceptivo? | normally no | ch. 26 |
| `shift` | ¿cambió el contexto / régimen? | normally no | ch. 27 |
| `sustain` | ¿esto sigue ocurriendo? | normally no | ch. 28 |
| `delegate` | ¿quién actúa ahora? | no by default | ch. 29 |
| Family | Perceptual question | Accepts intent | Book |
| ---------- | -------------------------------------------- | ------------------- | ------ |
| `contact` | ¿el sistema ha sentido mi acción? | leve / anticipatory | ch. 22 |
| `commit` | ¿qué quedó fijado o tuvo consecuencia? | **fully** | ch. 23 |
| `signal` | ¿algo reclama mi atención? | **fully** | ch. 24 |
| `handle` | ¿estoy manipulando directamente este objeto? | only on `drop` | ch. 25 |
| `emerge` | ¿algo entró o salió del campo perceptivo? | normally no | ch. 26 |
| `shift` | ¿cambió el contexto / régimen? | normally no | ch. 27 |
| `sustain` | ¿esto sigue ocurriendo? | normally no | ch. 28 |
| `delegate` | ¿quién actúa ahora? | no by default | ch. 29 |
`contact`/`commit`/`signal`/`handle` are the **valenced** families;
`emerge`/`shift`/`sustain`/`delegate` are the **transitional** ones (book ch. 9).
That split is a *classification*; it no longer dictates the intent rule — the
That split is a _classification_; it no longer dictates the intent rule — the
policy (§4) does.
The perceptual question is a **demand on the expression**, not a label: a family
that fails to answer its own question has failed at the only thing it exists
for. `shift` is the case that proves it — its question IS the crossing, so a
`shift` nobody perceives crossing is the *shift invisible* of the antipattern
`shift` nobody perceives crossing is the _shift invisible_ of the antipattern
catalogue (ch. 34 §14), and it was exactly that here until 2026-08-11: it
sounded like a slide and did not slide (§8 rule 5; the sense it now travels in,
`data-event-direction`, in §9).
@ -102,20 +102,20 @@ Canonical list: `INTENTS` in [`src/uix/intent.ts`](../src/uix/intent.ts) — own
by UIX itself, not by a layer. Per-intent perceptual deltas: `SEMA_MAP.intents`
in [`sema-map.ts`](../src/uix/sema/sema-map.ts).
| Intent | Valence / activation | Reading | Book |
| --- | --- | --- | --- |
| `neutral` | low activation, no strong valence | notar sin tono | ch. 10 |
| `affirm` | positive, low activation | "todo va bien" (confirmación suave) | ch. 10 |
| `fulfill` | positive, mid-high activation | "objetivo cumplido" (resuelve tensión) | ch. 10 |
| `risk` | negative, moderate activation | "revisa esto" (corregible) | ch. 10 |
| `threat` | negative, high activation | "atiende ahora" (aún evitable) | ch. 10 |
| `loss` | negative, lower activation, posterior | "ya ocurrió" (consecuencia consumada) | ch. 10 |
| Intent | Valence / activation | Reading | Book |
| --------- | ------------------------------------- | -------------------------------------- | ------ |
| `neutral` | low activation, no strong valence | notar sin tono | ch. 10 |
| `affirm` | positive, low activation | "todo va bien" (confirmación suave) | ch. 10 |
| `fulfill` | positive, mid-high activation | "objetivo cumplido" (resuelve tensión) | ch. 10 |
| `risk` | negative, moderate activation | "revisa esto" (corregible) | ch. 10 |
| `threat` | negative, high activation | "atiende ahora" (aún evitable) | ch. 10 |
| `loss` | negative, lower activation, posterior | "ya ocurrió" (consecuencia consumada) | ch. 10 |
Three distinctions the inherited semaphore (`success`/`warning`/`danger`/`info`)
collapses, and that this canon keeps apart (book ch. 10 §4):
- **`threat` ≠ `loss`** — threat convokes action *before* the consequence; loss
registers it *after*. They must not look/sound the same.
- **`threat` ≠ `loss`** — threat convokes action _before_ the consequence; loss
registers it _after_. They must not look/sound the same.
- **`affirm` ≠ `fulfill`** — soft confirmation vs resolution of a tension.
- **`info` is not an intent** — it is attentional salience → `signal.* + neutral`.
@ -131,10 +131,10 @@ checkpoint (verdicts C1/C3 — historical record in
selecting it (calendar, select, combobox, grid-list, listbox). Un-marking a
binary (the uncheck direction of `commit.toggle`) = **`neutral`**.
Abandoning or clearing (`commit.reset`, `commit.cancel`) = **`neutral`**.
- **Binary toggles — two sanctioned models.** *Mark-done* semantics, where
- **Binary toggles — two sanctioned models.** _Mark-done_ semantics, where
the direction itself carries the evaluative load, use two static
directional events (checkbox: `commit-toggle-check` affirm /
`commit-toggle-uncheck` neutral). *Mode-switch* semantics, where the weight
`commit-toggle-uncheck` neutral). _Mode-switch_ semantics, where the weight
depends on WHAT is being switched, use one event with
`intent: { fromProp: 'intent', default: 'neutral' }` so the consumer grades
it (switch, toggle, toggle-group). Choose by the question: does the ON
@ -145,7 +145,7 @@ checkpoint (verdicts C1/C3 — historical record in
## 4. Intent policy — `SEMA_FAMILY_POLICY`
Whether intent is *required* is set **per family by policy**, not by the
Whether intent is _required_ is set **per family by policy**, not by the
valenced/transitional split (book ch. 8 §6, ch. 9). Two independent axes, in
[`src/uix/sema/types.ts`](../src/uix/sema/types.ts) (`SEMA_FAMILY_POLICY`):
@ -155,7 +155,7 @@ valenced/transitional split (book ch. 8 §6, ch. 9). Two independent axes, in
it today). Drives the `SemaEvent` / `MorfoEventSemantic` discriminated unions.
- **`intentGuidance`** (`'expected' | 'contextual' | 'discouraged'`) — doctrinal
hint, no type effect. `commit`/`signal` = `expected`; `contact` = `discouraged`
(book ch. 22 §11: *"el intent fuerte no debería vivir en el contacto"*); the
(book ch. 22 §11: _"el intent fuerte no debería vivir en el contacto"_); the
rest = `contextual`.
Runtime: `validateSemaEvent` throws when a `required` family is built without
@ -166,8 +166,8 @@ intent.
## 5. The evaluable-vs-structural rule
> **The intent lives in the evaluable event (the message), not in the structural
> container (the frame).** (book ch. 9 — *"Qué eventos son mensaje y qué eventos
> son marco"*; restated in Appendix A.)
> container (the frame).** (book ch. 9 — _"Qué eventos son mensaje y qué eventos
> son marco"_; restated in Appendix A.)
A modal that opens is `shift.enter-mode` (frame); the warning inside it is
`signal.warn + threat` (message). A spinner is `sustain.progress` (frame); the
@ -175,11 +175,11 @@ failure after it is `commit.fail + risk` (message). Cargar el intent en el marco
es el antipatrón capital (book ch. 34 §5 "Modal rojo", §4 "todo lo que aparece es
alerta").
In the framework this is enforced declaratively: the event that *carries* the
In the framework this is enforced declaratively: the event that _carries_ the
intent declares it in its morfo `events[].semantic.intent`; the frame event does
not. The runtime never infers intent (book **Appendix A**: *"El intent no se
not. The runtime never infers intent (book **Appendix A**: _"El intent no se
hereda implícitamente… El runtime no debe adivinar. La semántica debe estar
declarada."*). This is exactly the morfo → soma → sema → eidos contract.
declarada."_). This is exactly the morfo → soma → sema → eidos contract.
---
@ -214,8 +214,8 @@ Verbs that look like one family but belong to another (book canon): `select` /
## 7. Expression channels + the owner split
The book defines **8 expression channels** (book ch. 11–20): tiempo · motion ·
presencia · profundidad · forma · color · sonido · háptica. *"El color expresa el
intent, no lo define"* (ch. 16); *"ningún canal agota la semántica"* — robustness
presencia · profundidad · forma · color · sonido · háptica. _"El color expresa el
intent, no lo define"_ (ch. 16); _"ningún canal agota la semántica"_ — robustness
= a reading that survives the loss of a channel (ch. 19, ch. 33).
The framework **splits these channels by owner** (decision recorded in
@ -232,11 +232,11 @@ The framework **splits these channels by owner** (decision recorded in
channel; this says what a component actually WRITES, which is the part authors
get wrong:
| Channel | The component writes | Where the values live |
| --- | --- | --- |
| visual (motion / color / presence / depth / shape) | nothing — it declares the EVENT; eidos reacts in CSS to `data-event-*` | eidos recipes + the token engines |
| `sound` | **one NAME**, and only when it differs from its family's default | `SEMA_MAP.sounds` — the sound pack |
| `haptic` | a categorical `kind` (`tick` / `tap` / `pulse` / `success` / …) | `HapticChannel` maps kinds to patterns |
| Channel | The component writes | Where the values live |
| -------------------------------------------------- | ---------------------------------------------------------------------- | -------------------------------------- |
| visual (motion / color / presence / depth / shape) | nothing — it declares the EVENT; eidos reacts in CSS to `data-event-*` | eidos recipes + the token engines |
| `sound` | **one NAME**, and only when it differs from its family's default | `SEMA_MAP.sounds` — the sound pack |
| `haptic` | a categorical `kind` (`tick` / `tap` / `pulse` / `success` / …) | `HapticChannel` maps kinds to patterns |
The rule is the same in all three rows and it is the point: **a component says
WHAT occurs, never how loud, how bright or how long.**
@ -286,10 +286,10 @@ ch. 6 §13). The rules are derived from perceptual need, not decree (ch. 30 §3)
3. **threat precedes loss** — never `commit.delete + threat` (before/after the
consequence).
4. **emerge does not absorb the content's intent** — `emerge.open → signal.warn +
risk`, not `emerge.open + risk` (frame ≠ message).
risk`, not `emerge.open + risk` (frame ≠ message).
5. **shift must orient** the context change (focus + title + landmark) — and it
must be PERCEIVED crossing it. A frame that swaps with nothing moving is the
*shift invisible* of the antipattern catalogue (ch. 34 §14): the user is
_shift invisible_ of the antipattern catalogue (ch. 34 §14): the user is
somewhere else and was never told they travelled. Until 2026-08-11 `shift`
was exactly that in this framework — it sounded (`slide`) and did not slide,
because `BUILTIN_SIGNATURES` had a FAMILY-keyed visual signature for

@ -34,15 +34,15 @@ architecture in [`architecture/active-architecture.md`](./architecture/active-ar
The corpus is organized in layers of permanence, not by folder:
| Stratum | What it is | Where |
| --- | --- | --- |
| **E0 — orientation** | this file; the narrative entry; the glossary | `docs/README.md`, `architecture/overview.md`, `docs/glossary.md` |
| **E1 — architecture** | how the layers fit | `docs/architecture/` (the book chapters) + in-place stubs |
| **E2 — canon** | the fixed vocabulary & contracts | `CANON.md`, `canon/tsc.md`, `canon/recipe-contract.md` |
| **E3 — decisions / RFC** | *why* it is built this way | `decisions.md` + the RFCs & decision logs |
| **E4 — guides** | how to do a thing | `guides/`, `theming/guide.md` |
| **E5 — module reference** | per-artifact docs | `arts/*/README`, `libs/*`, `svrs/*`, `packs/*/README` |
| **process** | ephemeral (hand-offs, snapshots, audits) | `docs/process/` — never a source of truth |
| Stratum | What it is | Where |
| ------------------------- | -------------------------------------------- | ---------------------------------------------------------------- |
| **E0 — orientation** | this file; the narrative entry; the glossary | `docs/README.md`, `architecture/overview.md`, `docs/glossary.md` |
| **E1 — architecture** | how the layers fit | `docs/architecture/` (the book chapters) + in-place stubs |
| **E2 — canon** | the fixed vocabulary & contracts | `CANON.md`, `canon/tsc.md`, `canon/recipe-contract.md` |
| **E3 — decisions / RFC** | _why_ it is built this way | `decisions.md` + the RFCs & decision logs |
| **E4 — guides** | how to do a thing | `guides/`, `theming/guide.md` |
| **E5 — module reference** | per-artifact docs | `arts/*/README`, `libs/*`, `svrs/*`, `packs/*/README` |
| **process** | ephemeral (hand-offs, snapshots, audits) | `docs/process/` — never a source of truth |
Writing or editing docs? The conventions that keep this corpus drift-free —
link the canon, don't copy it; keep reference docs timeless; one source per
@ -62,60 +62,60 @@ invented vocabulary (morfo, archetype, hold, TSC, …) one line each.
### E1 — Architecture
| Doc | Layer |
| --- | --- |
| [`architecture/active-architecture.md`](./architecture/active-architecture.md) | The whole system — start here for depth |
| [`architecture/morfo.md`](./architecture/morfo.md) | The declarative contract (DNA) |
| [`architecture/soma.md`](./architecture/soma.md) · [`SOMA_ARCHITECTURE.md`](./architecture/soma-architecture.md) | Headless behavior — soma.md onboards, ARCHITECTURE is the deep reference |
| [`architecture/sema.md`](./architecture/sema.md) | Perceptual engine + channels (sound/haptic) + cascade |
| [`architecture/eidos.md`](./architecture/eidos.md) | The visual layer |
| [`architecture/active-uix.md`](./architecture/active-uix.md) | Composition root (boot modes) — first chapter migrated into the book tree ([`docs/process/PLAN-docs-book.md`](./process/PLAN-docs-book.md)) |
| [`architecture/active-app.md`](./architecture/active-app.md) | The arts composition root — fixed core (logger/bus/timers/orca/prefs) + declared services + orchestration; the App-side analogue of `active-uix` |
| [`arts/README.md`](../src/arts/README.md) | Runtime artifacts (`Engine*`/`Active*`) |
| [`architecture/packs.md`](./architecture/packs.md) | The pack tier — encapsulated opt-in collections above the layers (the canon-vs-pack admission rule, the P contract, the `Aura` promotion path) |
| [`architecture/agent.md`](./architecture/agent.md) | The agentic axis — the delegation model (`delegate` family), the actor primitive, the per-component participation contract, minimum contracts, a11y + threat doctrine |
| [`spec/delegation-contract.md`](./spec/delegation-contract.md) | **NORMATIVE** — the delegation contract as a citable specification (RFC-2119, stable `AG-n` requirement ids, date-versioned). `agent.md` is the WHY; this is the WHAT a conformant implementation must do. Status: DRAFT |
| [`architecture/blocks.md`](./architecture/blocks.md) | The blocks tier — page-function compositions above the canon (the canon-vs-block admission rule, the B contract, `blocks:check`) |
| Doc | Layer |
| ---------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| [`architecture/active-architecture.md`](./architecture/active-architecture.md) | The whole system — start here for depth |
| [`architecture/morfo.md`](./architecture/morfo.md) | The declarative contract (DNA) |
| [`architecture/soma.md`](./architecture/soma.md) · [`SOMA_ARCHITECTURE.md`](./architecture/soma-architecture.md) | Headless behavior — soma.md onboards, ARCHITECTURE is the deep reference |
| [`architecture/sema.md`](./architecture/sema.md) | Perceptual engine + channels (sound/haptic) + cascade |
| [`architecture/eidos.md`](./architecture/eidos.md) | The visual layer |
| [`architecture/active-uix.md`](./architecture/active-uix.md) | Composition root (boot modes) — first chapter migrated into the book tree ([`docs/process/PLAN-docs-book.md`](./process/PLAN-docs-book.md)) |
| [`architecture/active-app.md`](./architecture/active-app.md) | The arts composition root — fixed core (logger/bus/timers/orca/prefs) + declared services + orchestration; the App-side analogue of `active-uix` |
| [`arts/README.md`](../src/arts/README.md) | Runtime artifacts (`Engine*`/`Active*`) |
| [`architecture/packs.md`](./architecture/packs.md) | The pack tier — encapsulated opt-in collections above the layers (the canon-vs-pack admission rule, the P contract, the `Aura` promotion path) |
| [`architecture/agent.md`](./architecture/agent.md) | The agentic axis — the delegation model (`delegate` family), the actor primitive, the per-component participation contract, minimum contracts, a11y + threat doctrine |
| [`spec/delegation-contract.md`](./spec/delegation-contract.md) | **NORMATIVE** — the delegation contract as a citable specification (RFC-2119, stable `AG-n` requirement ids, date-versioned). `agent.md` is the WHY; this is the WHAT a conformant implementation must do. Status: DRAFT |
| [`architecture/blocks.md`](./architecture/blocks.md) | The blocks tier — page-function compositions above the canon (the canon-vs-block admission rule, the B contract, `blocks:check`) |
### E2 — Canon
| Doc | What it fixes |
| --- | --- |
| [`docs/CANON.md`](./CANON.md) | The semantic vocabulary — authoritative |
| [`canon/vocabularies.md`](./canon/vocabularies.md) | **The closed sets, GENERATED from the code** — archetypes, families+holds, verbs, intents, haptic kinds, palette scales, sizes, variants, shared strings. Build a component from exactly these (`npm run docs:vocabularies`; guarded by `docs:check`) |
| [`canon/tsc.md`](./canon/tsc.md) | Token Scope Contract — where every eidos token may be emitted |
| [`canon/recipe-contract.md`](./canon/recipe-contract.md) | Recipe Contract — which transversal theming systems every recipe must consume (enforced by `component-audit` R-4.x) |
| [`canon/direction-contract.md`](./canon/direction-contract.md) | Direction Contract — the `prop → prefs → 'ltr'` resolution chain, which attribute carries the direction (raw `dir` vs resolved `data-dir`) and which selector form may read it (`:dir()`; `[dir='rtl']` is forbidden) (enforced by `rtl-lint` RTL-1) |
| Doc | What it fixes |
| -------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [`docs/CANON.md`](./CANON.md) | The semantic vocabulary — authoritative |
| [`canon/vocabularies.md`](./canon/vocabularies.md) | **The closed sets, GENERATED from the code** — archetypes, families+holds, verbs, intents, haptic kinds, palette scales, sizes, variants, shared strings. Build a component from exactly these (`npm run docs:vocabularies`; guarded by `docs:check`) |
| [`canon/tsc.md`](./canon/tsc.md) | Token Scope Contract — where every eidos token may be emitted |
| [`canon/recipe-contract.md`](./canon/recipe-contract.md) | Recipe Contract — which transversal theming systems every recipe must consume (enforced by `component-audit` R-4.x) |
| [`canon/direction-contract.md`](./canon/direction-contract.md) | Direction Contract — the `prop → prefs → 'ltr'` resolution chain, which attribute carries the direction (raw `dir` vs resolved `data-dir`) and which selector form may read it (`:dir()`; `[dir='rtl']` is forbidden) (enforced by `rtl-lint` RTL-1) |
### E3 — Decisions / RFC
| Doc | What it records |
| --- | --- |
| [`docs/decisions.md`](./decisions.md) | The RFC/design index — entry to all rationale |
| [`docs/next-features.md`](./next-features.md) | The initiative registry — user-decided future work (scope, sequencing, dependencies), fed by audits and sessions |
| [`rfcs/`](./rfcs/) | The eidos engine RFCs: [`rfc-color-model`](./rfcs/rfc-color-model.md) · [`rfc-color-engine`](./rfcs/rfc-color-engine.md) · [`rfc-typography`](./rfcs/rfc-typography.md) · [`rfc-depth`](./rfcs/rfc-depth.md) · [`rfc-shape`](./rfcs/rfc-shape.md) · [`rfc-structure`](./rfcs/rfc-structure.md) · [`rfc-scaling`](./rfcs/rfc-scaling.md) |
| [`decisions/design-text-effects.md`](./decisions/design-text-effects.md) | The text-effects component family — why text animations are canon (not the pack tier), the CountUp-service vs `Text*`-decorative split, and the a11y / measurement doctrine every member obeys |
| [`decisions/book-deviations.md`](./decisions/book-deviations.md) | Where the implementation deviates from / extends the book (Spanish — the author's decision logbook) |
| [`decisions/guia-semantica-historica.md`](./decisions/guia-semantica-historica.md) | The founding implementation guide (Spanish, historical seed — superseded by `CANON.md` + code) |
| [`theming/channels.md`](./theming/channels.md) | The eight expression channels, synthesized |
| [`theming/notes.md`](./theming/notes.md) | Theming: comparison vs reference libs + FAQ |
| [`theming/changelog.md`](./theming/changelog.md) | The theming chronicle — the dated history behind the reference's standing decisions (§13, §20–§38) |
| Doc | What it records |
| ---------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [`docs/decisions.md`](./decisions.md) | The RFC/design index — entry to all rationale |
| [`docs/next-features.md`](./next-features.md) | The initiative registry — user-decided future work (scope, sequencing, dependencies), fed by audits and sessions |
| [`rfcs/`](./rfcs/) | The eidos engine RFCs: [`rfc-color-model`](./rfcs/rfc-color-model.md) · [`rfc-color-engine`](./rfcs/rfc-color-engine.md) · [`rfc-typography`](./rfcs/rfc-typography.md) · [`rfc-depth`](./rfcs/rfc-depth.md) · [`rfc-shape`](./rfcs/rfc-shape.md) · [`rfc-structure`](./rfcs/rfc-structure.md) · [`rfc-scaling`](./rfcs/rfc-scaling.md) |
| [`decisions/design-text-effects.md`](./decisions/design-text-effects.md) | The text-effects component family — why text animations are canon (not the pack tier), the CountUp-service vs `Text*`-decorative split, and the a11y / measurement doctrine every member obeys |
| [`decisions/book-deviations.md`](./decisions/book-deviations.md) | Where the implementation deviates from / extends the book (Spanish — the author's decision logbook) |
| [`decisions/guia-semantica-historica.md`](./decisions/guia-semantica-historica.md) | The founding implementation guide (Spanish, historical seed — superseded by `CANON.md` + code) |
| [`theming/channels.md`](./theming/channels.md) | The eight expression channels, synthesized |
| [`theming/notes.md`](./theming/notes.md) | Theming: comparison vs reference libs + FAQ |
| [`theming/changelog.md`](./theming/changelog.md) | The theming chronicle — the dated history behind the reference's standing decisions (§13, §20–§38) |
### E4 — Guides
| Doc | How to |
| --- | --- |
| [`docs/building-a-component.md`](./building-a-component.md) | **Build a component — start here.** The cross-layer route (9 phases, one doc per phase, one guard per phase) |
| [`guides/component-guide.md`](./guides/component-guide.md) | The soma phase in depth (ordered steps + rules A1–A37) |
| [`guides/completion-checklist.md`](./guides/completion-checklist.md) | Decide when a component is *done* (machine-audited) |
| [`theming/reference.md`](./theming/reference.md) · [`theming/guide.md`](./theming/guide.md) | Theming reference (E1) + the add-component / define-theme how-tos (E4) |
| [`theming/motion.md`](./theming/motion.md) | The motion model — two moments, F1–F7, the preset/signature system (reference) |
| [`theming/gradient-finish.md`](./theming/gradient-finish.md) | The gradient finish — a gradient is a MATERIAL of the fill, never a color identity: the anchored ramp («la rampa huye de la tinta»), the dial, the executable guard, and the full decision record (D1–D9) |
| [`eidos/components/README.md`](../src/uix/eidos/components/README.md) | The eidos component pattern |
| [`theming/motion-guide.md`](./theming/motion-guide.md) | Animate it — the `motion` prop, the preset catalog, loops, stagger, reduced-motion (links the model + the motion RFC) |
| [`guides/demo-authoring.md`](./guides/demo-authoring.md) | Author an interactive demo page |
| [`guides/component-audit.md`](./guides/component-audit.md) | The binding pre-flight audit before touching any component |
| [`docs/consuming.md`](./consuming.md) | Consume the framework from an app in this workspace — aliases, runes, composition root, CSS and assets, the pre-hydration boot |
| Doc | How to |
| ------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [`docs/building-a-component.md`](./building-a-component.md) | **Build a component — start here.** The cross-layer route (9 phases, one doc per phase, one guard per phase) |
| [`guides/component-guide.md`](./guides/component-guide.md) | The soma phase in depth (ordered steps + rules A1–A37) |
| [`guides/completion-checklist.md`](./guides/completion-checklist.md) | Decide when a component is _done_ (machine-audited) |
| [`theming/reference.md`](./theming/reference.md) · [`theming/guide.md`](./theming/guide.md) | Theming reference (E1) + the add-component / define-theme how-tos (E4) |
| [`theming/motion.md`](./theming/motion.md) | The motion model — two moments, F1–F7, the preset/signature system (reference) |
| [`theming/gradient-finish.md`](./theming/gradient-finish.md) | The gradient finish — a gradient is a MATERIAL of the fill, never a color identity: the anchored ramp («la rampa huye de la tinta»), the dial, the executable guard, and the full decision record (D1–D9) |
| [`eidos/components/README.md`](../src/uix/eidos/components/README.md) | The eidos component pattern |
| [`theming/motion-guide.md`](./theming/motion-guide.md) | Animate it — the `motion` prop, the preset catalog, loops, stagger, reduced-motion (links the model + the motion RFC) |
| [`guides/demo-authoring.md`](./guides/demo-authoring.md) | Author an interactive demo page |
| [`guides/component-audit.md`](./guides/component-audit.md) | The binding pre-flight audit before touching any component |
| [`docs/consuming.md`](./consuming.md) | Consume the framework from an app in this workspace — aliases, runes, composition root, CSS and assets, the pre-hydration boot |
### E5 — Module reference
@ -125,33 +125,33 @@ and the server-authoritative engines in `src/svrs/`.
## "I want to…"
| Goal | Go to |
| --- | --- |
| Run it and make a first change | [`docs/getting-started.md`](./getting-started.md) |
| Build an app on the framework | [`docs/consuming.md`](./consuming.md) — the workspace contract |
| Understand the framework | [`architecture/overview.md`](./architecture/overview.md) → [`architecture/active-architecture.md`](./architecture/active-architecture.md) |
| Know why UIX, not Radix / Mantine | [`docs/comparison.md`](./comparison.md) |
| Know what a family / intent / verb means | `docs/CANON.md` (doctrine) · [`canon/vocabularies.md`](./canon/vocabularies.md) (the generated closed sets) |
| Know which archetype / hold / haptic kind / scale a part or event may use | [`canon/vocabularies.md`](./canon/vocabularies.md) — the authoritative lists, generated from the code |
| **Build a new component** | [`docs/building-a-component.md`](./building-a-component.md) — the one door: the 9-phase route across all layers, with the guard for each phase and the known superseded-doc traps |
| Know if a component is finished | [`guides/completion-checklist.md`](./guides/completion-checklist.md) (`npm run component:audit`) |
| Theme it / add a token | [`theming/reference.md`](./theming/reference.md) + [`canon/tsc.md`](./canon/tsc.md) |
| Animate it (motion · loops · stagger · reduced-motion) | [`theming/motion-guide.md`](./theming/motion-guide.md) |
| Make it work in RTL (assert a direction · mirror the paint) | [`canon/direction-contract.md`](./canon/direction-contract.md) (`npm run rtl:check`) |
| Understand why a decision was made | `docs/decisions.md` → the relevant RFC / [`decisions/book-deviations.md`](./decisions/book-deviations.md) |
| Use a runtime artifact (auth, cache, http, …) | [`architecture/active-app.md`](./architecture/active-app.md) (the composition root) → [`arts/README.md`](../src/arts/README.md) (the map) → `src/arts/{name}/README.md` (per-artifact) |
| **Write or edit documentation** | [`docs/authoring.md`](./authoring.md) — the authoring rules |
| Test or validate a change | [`docs/testing-and-tooling.md`](./testing-and-tooling.md) — tests, validators, codegen, SSR |
| Goal | Go to |
| ------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Run it and make a first change | [`docs/getting-started.md`](./getting-started.md) |
| Build an app on the framework | [`docs/consuming.md`](./consuming.md) — the workspace contract |
| Understand the framework | [`architecture/overview.md`](./architecture/overview.md) → [`architecture/active-architecture.md`](./architecture/active-architecture.md) |
| Know why UIX, not Radix / Mantine | [`docs/comparison.md`](./comparison.md) |
| Know what a family / intent / verb means | `docs/CANON.md` (doctrine) · [`canon/vocabularies.md`](./canon/vocabularies.md) (the generated closed sets) |
| Know which archetype / hold / haptic kind / scale a part or event may use | [`canon/vocabularies.md`](./canon/vocabularies.md) — the authoritative lists, generated from the code |
| **Build a new component** | [`docs/building-a-component.md`](./building-a-component.md) — the one door: the 9-phase route across all layers, with the guard for each phase and the known superseded-doc traps |
| Know if a component is finished | [`guides/completion-checklist.md`](./guides/completion-checklist.md) (`npm run component:audit`) |
| Theme it / add a token | [`theming/reference.md`](./theming/reference.md) + [`canon/tsc.md`](./canon/tsc.md) |
| Animate it (motion · loops · stagger · reduced-motion) | [`theming/motion-guide.md`](./theming/motion-guide.md) |
| Make it work in RTL (assert a direction · mirror the paint) | [`canon/direction-contract.md`](./canon/direction-contract.md) (`npm run rtl:check`) |
| Understand why a decision was made | `docs/decisions.md` → the relevant RFC / [`decisions/book-deviations.md`](./decisions/book-deviations.md) |
| Use a runtime artifact (auth, cache, http, …) | [`architecture/active-app.md`](./architecture/active-app.md) (the composition root) → [`arts/README.md`](../src/arts/README.md) (the map) → `src/arts/{name}/README.md` (per-artifact) |
| **Write or edit documentation** | [`docs/authoring.md`](./authoring.md) — the authoring rules |
| Test or validate a change | [`docs/testing-and-tooling.md`](./testing-and-tooling.md) — tests, validators, codegen, SSR |
## Authoritative sources & rules
- **Editorial source**: [`docs/Disenando_lo_que_ocurre_FINAL.pdf`](./Disenando_lo_que_ocurre_FINAL.pdf) — the book *Diseñando lo que ocurre* (FINAL edition, 426 pp., tracked in-repo since 2026-07-11; the `.docx` sibling is the editable master), the origin of the semantic canon.
- **Editorial source**: [`docs/Disenando_lo_que_ocurre_FINAL.pdf`](./Disenando_lo_que_ocurre_FINAL.pdf) — the book _Diseñando lo que ocurre_ (FINAL edition, 426 pp., tracked in-repo since 2026-07-11; the `.docx` sibling is the editable master), the origin of the semantic canon.
- **Agent rules**: [`CLAUDE.md`](../CLAUDE.md) and [`AGENTS.md`](../AGENTS.md) — the build/test commands, code style, and the hard rules. Read these before editing.
## Process (ephemeral — not a source of truth)
[`docs/process/`](./process/) holds session hand-offs, architecture snapshots and
audits. They record *what happened*, not *what is true* — the docs above are the
audits. They record _what happened_, not _what is true_ — the docs above are the
truth. The active corpus-migration state is in
[`docs/process/CONTINUE-docs-corpus.md`](./process/CONTINUE-docs-corpus.md).

@ -168,24 +168,24 @@ error — the wrapping is cheap and uniform.
## Available services
| Factory | Slot | Notes |
| ---------------------------------------- | ------------- | ------------------------------------------------------------------------------------- |
| `defineActiveLangs(options)` | `langs` | Schema is required; follows `core.prefs.language` when that dimension exists. |
| `defineActiveStorage(options)` | `storage` | Memory adapter by default. |
| `defineActiveClipboard(options)` | `clipboard` | Lazy capability wrapper around `navigator.clipboard.writeText` or an injected writer. |
| `defineActiveDom(props)` | `dom` | Inert on the server. |
| `defineActiveFormat(options)` | `format` | Reads `core.prefs.locale` when that dimension exists. |
| `defineActiveCache(options)` | `cache` | Passive — invalidation is driven by orca presets. |
| `defineActiveSession<TUser, …>(options)` | `session` | Publishes `SESSION_EVENT_*` on the bus. |
| `defineActivePerm(options)` | `perm` | Auto-invalidation is OFF; use orca preset. |
| `defineActiveAuth(options)` | `auth` | Requires an HTTP client in `options`. |
| `defineActiveConnections(options)` | `connections` | Identity tracking via orca preset. |
| `defineEngineHttp(options)` | `http` | Engine only — no Active wrapper. |
| `defineEngineSium(options)` | `sium` | Wires to `langs` automatically when declared. |
| Factory | Slot | Notes |
| ---------------------------------------- | ------------- | ---------------------------------------------------------------------------------------- |
| `defineActiveLangs(options)` | `langs` | Schema is required; follows `core.prefs.language` when that dimension exists. |
| `defineActiveStorage(options)` | `storage` | Memory adapter by default. |
| `defineActiveClipboard(options)` | `clipboard` | Lazy capability wrapper around `navigator.clipboard.writeText` or an injected writer. |
| `defineActiveDom(props)` | `dom` | Inert on the server. |
| `defineActiveFormat(options)` | `format` | Reads `core.prefs.locale` when that dimension exists. |
| `defineActiveCache(options)` | `cache` | Passive — invalidation is driven by orca presets. |
| `defineActiveSession<TUser, …>(options)` | `session` | Publishes `SESSION_EVENT_*` on the bus. |
| `defineActivePerm(options)` | `perm` | Auto-invalidation is OFF; use orca preset. |
| `defineActiveAuth(options)` | `auth` | Requires an HTTP client in `options`. |
| `defineActiveConnections(options)` | `connections` | Identity tracking via orca preset. |
| `defineEngineHttp(options)` | `http` | Engine only — no Active wrapper. |
| `defineEngineSium(options)` | `sium` | Wires to `langs` automatically when declared. |
| `defineActiveAgent(options)` | `agent` | `timers` + `logger` come from the App core; identity / policy / transport are the app's. |
| `defineEngineMotion(options)` | `motion` | Engine only. Declares `serviceDependencies: ['dom']`; degrades without it. |
| `defineEngineScene(options)` | `scene` | Engine only — the ambient-scene runtime the canon shares as `uix.scene`. |
| `defineEngineSound(options)` | `sound` | Engine only — the Web Audio runtime extracted from sema's `SoundChannel`. |
| `defineEngineMotion(options)` | `motion` | Engine only. Declares `serviceDependencies: ['dom']`; degrades without it. |
| `defineEngineScene(options)` | `scene` | Engine only — the ambient-scene runtime the canon shares as `uix.scene`. |
| `defineEngineSound(options)` | `sound` | Engine only — the Web Audio runtime extracted from sema's `SoundChannel`. |
> This table is checked against the directory: `docs:check` (`I1-catalog`)
> fails when `service-factories/` grows a slot this list does not mention. It

@ -55,14 +55,14 @@ services they need — without components ever knowing `ActiveApp` directly.
> Executable source: [`src/uix/contracts.ts`](../../src/uix/contracts.ts).
| Module | Minimum required | Optional | Fallback when missing | Error when missing |
| --- | --- | --- | --- | --- |
| `ActiveUix` standalone | `langs` config | `clipboard:false`, `format`, `events`, `portal`, `dom:false` | creates `prefs`, core services and, with `dom:false`, a local `disabledDom` | missing `langs` config |
| `ActiveUix` attach | `ActiveApp` core + `langs`, `dom` services | `app.clipboard`, `app.format`, event engine, `portal` | none for required services | missing `langs` or `dom` on the app; the getter of an absent optional service fails explicitly |
| `SomaRuntime` | `dom` from `ActiveUix` | event engine, `langs`, `format` | none of its own | nonexistent morfo/event/part |
| `Sema` direct | `dom` or `projector` when `visual` is active | `sound`, `haptic`, `visual:false` | none of its own for UIX services | `SemaConfigError` without `dom/projector` while visual is active |
| `Eidos` | `dom` when `applyDom` | `langs`, `format`, `prefs`, mode/density sources | `applyDom:false` allows render/serialize without DOM | missing `dom` with `applyDom` active |
| `ADom` direct | caller's target/window/document | breakpoints/window | `disabledDom` only when the caller asks for it | ADom's own errors without a real DOM |
| Module | Minimum required | Optional | Fallback when missing | Error when missing |
| ---------------------- | -------------------------------------------- | ------------------------------------------------------------ | --------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| `ActiveUix` standalone | `langs` config | `clipboard:false`, `format`, `events`, `portal`, `dom:false` | creates `prefs`, core services and, with `dom:false`, a local `disabledDom` | missing `langs` config |
| `ActiveUix` attach | `ActiveApp` core + `langs`, `dom` services | `app.clipboard`, `app.format`, event engine, `portal` | none for required services | missing `langs` or `dom` on the app; the getter of an absent optional service fails explicitly |
| `SomaRuntime` | `dom` from `ActiveUix` | event engine, `langs`, `format` | none of its own | nonexistent morfo/event/part |
| `Sema` direct | `dom` or `projector` when `visual` is active | `sound`, `haptic`, `visual:false` | none of its own for UIX services | `SemaConfigError` without `dom/projector` while visual is active |
| `Eidos` | `dom` when `applyDom` | `langs`, `format`, `prefs`, mode/density sources | `applyDom:false` allows render/serialize without DOM | missing `dom` with `applyDom` active |
| `ADom` direct | caller's target/window/document | breakpoints/window | `disabledDom` only when the caller asks for it | ADom's own errors without a real DOM |
## Ownership and degradation rules

@ -232,7 +232,7 @@ Radix Themes, Ark/Panda, Chakra, Tailwind or shadcn as foundation tokens:
`--border-style`, `--border` + `--ring-inset-width`.
- `opacity`: a dual scale — numeric plus semantic
`ghost · disabled · scrim · muted · overlay · subtle · press · hover ·
full` (changelog §29).
full` (changelog §29).
- `zIndex`: `base · raised · sticky · dropdown · popover · tooltip · modal · toast`.
- `shadow`: a physical `1..6` scale plus per-theme semantic aliases
`none · subtle · raised · overlay`.
@ -496,15 +496,15 @@ components keep working headless because behavior belongs to Soma.
### From morfo (declaration)
| Piece | Eidos uses it for |
| -------------------------------------------------------------- | ----------------------------------------------------------- |
| `parts[].kebab` | `[data-{component}-{kebab}]` selectors |
| `parts[].archetype` | transversal rules `[data-archetype=trigger]` |
| `parts[].states` + `data[].values` | variants `[data-state=open]` |
| `parts[].data` with `data-starting-style` / `data-ending-style` | enter/exit animation hooks |
| `events[].name` | selectors `[data-event=emerge-dismiss]`, `[data-event^=commit]` |
| `events[].semantic.family` + `.intent` | semantic tinting of transitions |
| `events[].prewrite[]` (e.g. `data-last-action`) | tinting the exit anim by cause |
| Piece | Eidos uses it for |
| --------------------------------------------------------------- | --------------------------------------------------------------- |
| `parts[].kebab` | `[data-{component}-{kebab}]` selectors |
| `parts[].archetype` | transversal rules `[data-archetype=trigger]` |
| `parts[].states` + `data[].values` | variants `[data-state=open]` |
| `parts[].data` with `data-starting-style` / `data-ending-style` | enter/exit animation hooks |
| `events[].name` | selectors `[data-event=emerge-dismiss]`, `[data-event^=commit]` |
| `events[].semantic.family` + `.intent` | semantic tinting of transitions |
| `events[].prewrite[]` (e.g. `data-last-action`) | tinting the exit anim by cause |
### From Soma
@ -568,7 +568,7 @@ The third rule is where the layer split earns its keep. `shift` **sounds** like
a slide (`SEMA_MAP.families.shift.sounds.default = 'slide'`) and until
2026-08-11 it did not slide, because sema owns no motion and eidos had written
FAMILY-keyed signatures for `contact`, `commit` and `delegate` only (`emerge`
and `signal` are covered, but keyed by EVENT name) — the *shift invisible*
and `signal` are covered, but keyed by EVENT name) — the _shift invisible_
antipattern (book ch. 34 §14) living inside the framework that names it. The
missing half was always eidos's to write: sema stamps the SENSE
(`data-event-direction`, decided per emit, `forward` | `backward`) and eidos
@ -585,8 +585,7 @@ routinely needs to paint something the stamp never touches. That is a
```css
/* Splitter commits on the provider; the handle is what pulses. */
[data-splitter][data-event='commit-set'][data-event-phase='active']
[data-splitter-resize-trigger] {
[data-splitter][data-event='commit-set'][data-event-phase='active'] [data-splitter-resize-trigger] {
background: var(--splitter-active-handle-bg, var(--color-primary-solid));
}
```
@ -657,34 +656,34 @@ the R-4.x rules of `scripts/component-audit.ts`.
Quick map of what THEMING.md covers, to avoid duplicating here:
| Topic | Section in THEMING.md |
| --- | --- |
| Why theming lives in Eidos and not in Morfo | §1.bis |
| 7 token layers and override points | §3 |
| The 9 canonical color roles | §4 |
| The canonical sizes | §5 |
| Naming conventions | §6 |
| Token Scope Contract (TSC): type, scope algebra, cross-axis | §7 |
| TSC v2.2: multi-part scope (`parts: [...]`) + cross-recipe composition | §7 |
| How to add a new component | §8 |
| How to define a theme | §9 |
| How to override tokens at runtime | §10 |
| Bundle strategy + `eidos:purge` | §11 |
| Sema integration via `event:*` (superseded — see the stub) | §13 |
| Anti-patterns and FAQ | §16, §17 |
| Universal TSC coverage (no exceptions) | §18 |
| Variants are eidos canon, NOT the theme's (with `EIDOS_VARIANTS`) | §19 |
| Engine corrections: live density + on-solid `contrast` | §20 |
| The `scaling` axis (global zoom), separate from density | §23 |
| P2 corrections: on-solid text by luminance + translucent surfaces | §24 |
| Color model: palette (33 scales) + roles (aliases) + intents (auto-derived) | §25 |
| Runtime theme builder: `eidos.applyColorScheme(seed)` (`uix.color` engine) | §26 |
| Wide-gamut OKLCH output, default-on (hex fallback + `oklch()` sibling) | §27 |
| a11y forced-colors (focus outline fallback) + border ramp (slot 6→7) | §28 |
| Scale canon — the theming audit: blur · inset-shadow/ring · gradients · breakpoints+container · opacity · border-width · tracking | §35 |
| Focus ring: two parameterized rings (fields, box-shadow) + `outline` on surfaces | §32 |
| Touch-target — 44px on touch, gated by `pointer: coarse` | §37 |
| State layer `--state-*` — unified neutral feedback (MD3, theme-adaptive) | §38 |
| Topic | Section in THEMING.md |
| --------------------------------------------------------------------------------------------------------------------------------- | --------------------- |
| Why theming lives in Eidos and not in Morfo | §1.bis |
| 7 token layers and override points | §3 |
| The 9 canonical color roles | §4 |
| The canonical sizes | §5 |
| Naming conventions | §6 |
| Token Scope Contract (TSC): type, scope algebra, cross-axis | §7 |
| TSC v2.2: multi-part scope (`parts: [...]`) + cross-recipe composition | §7 |
| How to add a new component | §8 |
| How to define a theme | §9 |
| How to override tokens at runtime | §10 |
| Bundle strategy + `eidos:purge` | §11 |
| Sema integration via `event:*` (superseded — see the stub) | §13 |
| Anti-patterns and FAQ | §16, §17 |
| Universal TSC coverage (no exceptions) | §18 |
| Variants are eidos canon, NOT the theme's (with `EIDOS_VARIANTS`) | §19 |
| Engine corrections: live density + on-solid `contrast` | §20 |
| The `scaling` axis (global zoom), separate from density | §23 |
| P2 corrections: on-solid text by luminance + translucent surfaces | §24 |
| Color model: palette (33 scales) + roles (aliases) + intents (auto-derived) | §25 |
| Runtime theme builder: `eidos.applyColorScheme(seed)` (`uix.color` engine) | §26 |
| Wide-gamut OKLCH output, default-on (hex fallback + `oklch()` sibling) | §27 |
| a11y forced-colors (focus outline fallback) + border ramp (slot 6→7) | §28 |
| Scale canon — the theming audit: blur · inset-shadow/ring · gradients · breakpoints+container · opacity · border-width · tracking | §35 |
| Focus ring: two parameterized rings (fields, box-shadow) + `outline` on surfaces | §32 |
| Touch-target — 44px on touch, gated by `pointer: coarse` | §37 |
| State layer `--state-*` — unified neutral feedback (MD3, theme-adaptive) | §38 |
What follows in this chapter are the operational decisions of the **visual
layer as a module** (typography sourcing, picker patterns, API conventions,
@ -715,10 +714,10 @@ src/uix/eidos/lib/primitives/typography.ts
font-size,line-height,letter-spacing,font-weight,color}
```
| Layer | Who consumes it | For what |
|---|---|---|
| **Numerical foundation** (`--font-size-*`, `--font-family-primary`, …) | recipe tokens in `lib/recipes/base.ts` (+ the semantic leading `--leading-ui`, config data) | Component internals (Field labels, Combobox triggers, Button text, …) — they need **t-shirt scaling** (`xs/sm/md/lg/xl`) that does NOT map cleanly to a fixed semantic. |
| **Named styles** (`--style-label-*`, `--style-body-*`, `--style-caption-*`, `--style-h{1..6}-*`, `--style-{hero,prose,code}-*`) | typography primitives (`<Text>`, `<Heading>`, `<Display>`, `<Code>`, `<Link>`, …) | The user-facing API to compose content — the USER picked "label" or "body" and wants that semantic role honored. |
| Layer | Who consumes it | For what |
| ------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Numerical foundation** (`--font-size-*`, `--font-family-primary`, …) | recipe tokens in `lib/recipes/base.ts` (+ the semantic leading `--leading-ui`, config data) | Component internals (Field labels, Combobox triggers, Button text, …) — they need **t-shirt scaling** (`xs/sm/md/lg/xl`) that does NOT map cleanly to a fixed semantic. |
| **Named styles** (`--style-label-*`, `--style-body-*`, `--style-caption-*`, `--style-h{1..6}-*`, `--style-{hero,prose,code}-*`) | typography primitives (`<Text>`, `<Heading>`, `<Display>`, `<Code>`, `<Link>`, …) | The user-facing API to compose content — the USER picked "label" or "body" and wants that semantic role honored. |
**The two layers are not redundant**: they serve different contexts. The
numerical one vertebrates the system's _interior_; the semantic one
@ -738,25 +737,25 @@ authored value references the style.)
```css
/* generated/base.css (via render-css.ts) */
:root {
/* Named style — source of truth */
--style-label-font-family: var(--font-family-primary);
--style-label-line-height: 1.25;
/* Named style — source of truth */
--style-label-font-family: var(--font-family-primary);
--style-label-line-height: 1.25;
/* Semantic leading — config data anchored to the style */
--leading-ui: var(--style-label-line-height, 1.25);
/* Semantic leading — config data anchored to the style */
--leading-ui: var(--style-label-line-height, 1.25);
}
/* recipes/base.ts → generated/base.css */
:root {
--accordion-trigger-font-family: var(--style-label-font-family);
--field-label-line-height: var(--leading-ui);
--field-control-line-height: var(--leading-ui);
/* … dozens more recipe tokens */
--accordion-trigger-font-family: var(--style-label-font-family);
--field-label-line-height: var(--leading-ui);
--field-control-line-height: var(--leading-ui);
/* … dozens more recipe tokens */
}
/* components/field/field.css */
[data-field-label] {
line-height: var(--field-label-line-height);
line-height: var(--field-label-line-height);
}
```
@ -1007,15 +1006,15 @@ the morfo declares the component's whole BEHAVIORAL surface, not just its
paintable one — but it isn't noise either. The criterion:
- **Legitimate without a consumer** (the majority):
- *behavioral / a11y attrs* — state mirrors that exist for JS, tests,
- _behavioral / a11y attrs_ — state mirrors that exist for JS, tests,
assistive tech or app-land selectors (`data-state` on parts the recipe
styles via a parent, `aria-*` reflections);
- *composition artifacts* — a component whose visual lives in a SHARED
- _composition artifacts_ — a component whose visual lives in a SHARED
layer or in its composed children shows its own contract as "unused"
(css-field's 21 live in `spin-field.css`; collapsible is headless by
design and its consumers style it; picker roots restyle the composed
field/calendar contracts instead);
- *cross-component selectors* — entries like
- _cross-component selectors_ — entries like
`[data-popover-content] [data-year-grid]` are consumed from the
SIBLING's recipe, which the per-component report can't see.
- **Debt** (the minority worth burning): an attr that was declared FOR a

@ -50,14 +50,14 @@ canon** through the full route — never to grow the pack's privileges.
A pack is exempt from the acceptance matrix, NOT from discipline. Every pack
ships with these six obligations, guarded mechanically (`packs-check`):
| P | Obligation |
| --- | --- |
| P-1 | Every animated piece declares a `reduce` policy (`'static-frame'` \| `'hide'`) — no silent default; reduced motion is honored via the injected DOM port, never a raw `matchMedia`. |
| P-2 | Full teardown: every mount returns a handle whose `dispose()` releases frames, observers, GL resources and listeners. |
| P-3 | DOM only through the injected port (`dom.requestFrame` / `observeResize` / `observeIntersection` / `listen`) — raw `requestAnimationFrame` / `ResizeObserver` / `IntersectionObserver` / `addEventListener` in `src/packs/` is an error. |
| P | Obligation |
| --- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| P-1 | Every animated piece declares a `reduce` policy (`'static-frame'` \| `'hide'`) — no silent default; reduced motion is honored via the injected DOM port, never a raw `matchMedia`. |
| P-2 | Full teardown: every mount returns a handle whose `dispose()` releases frames, observers, GL resources and listeners. |
| P-3 | DOM only through the injected port (`dom.requestFrame` / `observeResize` / `observeIntersection` / `listen`) — raw `requestAnimationFrame` / `ResizeObserver` / `IntersectionObserver` / `addEventListener` in `src/packs/` is an error. |
| P-4 | Color parameters are token-aware: they accept an eidos custom-property name (resolved via `eidos.resolveToken`, re-resolved on mode change) or a raw CSS color as fallback; hardcoded palettes without a token path are an error for theme-facing params. |
| P-5 | Decorative DOM is `aria-hidden="true"`; pointer interactivity is opt-in per piece and never traps focus. |
| P-6 | Off-screen and hidden-tab work is paused; a scene budget guards against unbounded concurrent GL contexts (warn via logger). |
| P-5 | Decorative DOM is `aria-hidden="true"`; pointer interactivity is opt-in per piece and never traps focus. |
| P-6 | Off-screen and hidden-tab work is paused; a scene budget guards against unbounded concurrent GL contexts (warn via logger). |
## The promotion path (the agentic direction)

@ -6,32 +6,32 @@ Ejecución de fixes: 2026-07-08 → 2026-07-11. Rama `alpha-0.1-sec-dom`.
## Resultado final (gates del 2026-07-11)
| Puerta | Estado |
| --- | --- |
| Matriz de aceptación (`component-audit.ts`) | **134 PASS · 0 NEEDS-WORK · 0 BROKEN** (de 81 PASS al arrancar la ejecución) |
| Guards de capa (`contracts.test.ts`) | **37/37 verde** (primera vez; partía con 13 fallos) |
| Vocabulario morfo (`morfo-vocabulary-check`) | exit 0 (1 WARN conocido: `cropper.commit-crop`, descubribilidad) |
| Baseline de tipos (fuera de `alpha\|words\|palabras\|chronos`) | **57** — invariante durante todo el programa (59→57 en P7) |
| eidos-lint (catálogo) | 0 selectores inválidos · 0 class-hooks en lo tocado |
| Puerta | Estado |
| -------------------------------------------------------------- | ---------------------------------------------------------------------------- |
| Matriz de aceptación (`component-audit.ts`) | **134 PASS · 0 NEEDS-WORK · 0 BROKEN** (de 81 PASS al arrancar la ejecución) |
| Guards de capa (`contracts.test.ts`) | **37/37 verde** (primera vez; partía con 13 fallos) |
| Vocabulario morfo (`morfo-vocabulary-check`) | exit 0 (1 WARN conocido: `cropper.commit-crop`, descubribilidad) |
| Baseline de tipos (fuera de `alpha\|words\|palabras\|chronos`) | **57** — invariante durante todo el programa (59→57 en P7) |
| eidos-lint (catálogo) | 0 selectores inválidos · 0 class-hooks en lo tocado |
## Recorrido por paquetes (hashes)
| Paquete | Contenido | Commits |
| --- | --- | --- |
| P0–P3 | Doctrina · guardas · contratos morfo · 13 packs | `53b6f629` (lote inicial) |
| P4 naming N1–N10 | `selectionMode` · `onValueCommit` · `deselectable` · delays · razones tipadas… | `53b6f629` |
| P5 sistema | S1 codemod class-hooks · S5 outline · depth · touch · **S6 Field composition** (16 fields + poda 199 tokens + de-alias) · S8 calendar-surface | `5eb92132..d1670caa` · `83e13be6` |
| P6 | C6 `getWeekInfo` · C7 D13 textarea+censo · B.11 splitter bindable | `3b02fd11` · `444e05eb` · `0f0feb4f` |
| P7 baseline + S7 | 2 errores mandados (59→57) · papeleo pasivos/capas | `c0ae3de1` · `fe844c62` |
| **S4 dossiers** (5 lotes + drag-drop) | 30 READMEs eidos a forma dossier + README soma field-langs → **E-2.3 = 0** | `7b82aa79` · `20e2e7a1` |
| One-liners + §37 | delegated/apg/archetype + docblocks · **§37 resuelto (a)-con-nota** | `dd0637f6` · `bf573430` |
| compile.test | Test stale post dialog-001 adjudicado + guard nuevo | `e8f12aa1` |
| **S9 iniciativas** | gradient-\* (graduación ACTIVE_DEV_TRACK) · ntp integral (válvula `literal:` R-2.1 + README soma + suite 12/12) · metrics+suite (puente interno + helper + suites 7/7) | `45ae3691` · `dd249eac` · `8e3a67bd` |
| Censo contracts | 12→3: knob barrel+README · puentes internos · 6 barrels→`internals.ts` · track-filter · data-archetype + 4 morfos field-trigger | `cb554ae2` |
| Demos fuera del fix | **Decisión de producto (2026-07-10): frame NUEVO para las demos del sistema** → reglas D-\* verdict-neutral | `e53bf0e8` |
| Convergencia runtime | field `commit-submit` al Enter (doctrina de familia) · float-panel `writeProperty`/`uix.timers` + kb-gestos con handle-events · A-3.7 a acciones distintas · puerto media-provider exento → **contracts 37/37** | `33f346ed` · `bdd17f04` |
| Censo R-1.x | badge al velo §38 (fix real) + 8 exceptions con evidencia (pin-input ya pintaba en `[data-active]`) | `ee9786bc` |
| Lote 6 final | Los 5 últimos dossiers + apg timeline + literales anotados → **134/0/0** | `7f2bcc28` |
| Paquete | Contenido | Commits |
| ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------ |
| P0–P3 | Doctrina · guardas · contratos morfo · 13 packs | `53b6f629` (lote inicial) |
| P4 naming N1–N10 | `selectionMode` · `onValueCommit` · `deselectable` · delays · razones tipadas… | `53b6f629` |
| P5 sistema | S1 codemod class-hooks · S5 outline · depth · touch · **S6 Field composition** (16 fields + poda 199 tokens + de-alias) · S8 calendar-surface | `5eb92132..d1670caa` · `83e13be6` |
| P6 | C6 `getWeekInfo` · C7 D13 textarea+censo · B.11 splitter bindable | `3b02fd11` · `444e05eb` · `0f0feb4f` |
| P7 baseline + S7 | 2 errores mandados (59→57) · papeleo pasivos/capas | `c0ae3de1` · `fe844c62` |
| **S4 dossiers** (5 lotes + drag-drop) | 30 READMEs eidos a forma dossier + README soma field-langs → **E-2.3 = 0** | `7b82aa79` · `20e2e7a1` |
| One-liners + §37 | delegated/apg/archetype + docblocks · **§37 resuelto (a)-con-nota** | `dd0637f6` · `bf573430` |
| compile.test | Test stale post dialog-001 adjudicado + guard nuevo | `e8f12aa1` |
| **S9 iniciativas** | gradient-\* (graduación ACTIVE_DEV_TRACK) · ntp integral (válvula `literal:` R-2.1 + README soma + suite 12/12) · metrics+suite (puente interno + helper + suites 7/7) | `45ae3691` · `dd249eac` · `8e3a67bd` |
| Censo contracts | 12→3: knob barrel+README · puentes internos · 6 barrels→`internals.ts` · track-filter · data-archetype + 4 morfos field-trigger | `cb554ae2` |
| Demos fuera del fix | **Decisión de producto (2026-07-10): frame NUEVO para las demos del sistema** → reglas D-\* verdict-neutral | `e53bf0e8` |
| Convergencia runtime | field `commit-submit` al Enter (doctrina de familia) · float-panel `writeProperty`/`uix.timers` + kb-gestos con handle-events · A-3.7 a acciones distintas · puerto media-provider exento → **contracts 37/37** | `33f346ed` · `bdd17f04` |
| Censo R-1.x | badge al velo §38 (fix real) + 8 exceptions con evidencia (pin-input ya pintaba en `[data-active]`) | `ee9786bc` |
| Lote 6 final | Los 5 últimos dossiers + apg timeline + literales anotados → **134/0/0** | `7f2bcc28` |
## Método canonizado (reutilizable)

@ -8,81 +8,92 @@ evidencia y pide veredicto.
## A. Convenciones CONFIRMADAS catálogo-completo (canon de facto — solo falta escribirlo)
| Concepto | Patrón canónico | Evidencia |
|---|---|---|
| Valor + cambio (valued controls) | `value` (bindable) + `onValueChange: OnChangeFn<T>` | fields ×14, radio-group, toggle-group, rating-group, select, combobox, listbox, calendar, pickers — el par dominante |
| Estado binario semántico | nombre ARIA-alineado, NO value: `checked`/`onCheckedChange` (checkbox :15-19, switch :21-23) · `pressed`/`onPressedChange` (toggle :20-22) · + `indeterminate`/`onIndeterminateChange` (checkbox :16-21) | Convención Radix/bits seguida a rajatabla — REGLA: binarios hablan su ARIA |
| Apertura de overlay | `open` (bindable) + `onOpenChange` + **`onOpenChangeComplete`** (post-animación) | popover :11-15, dialog :12-51, drawer :46-73, tooltip :34-38, float-panel :20-24, dropdown-menu :18-22 — ×6 EXACTO, incluida la variante Complete |
| Cierre/outside | `onInteractOutside: (e: PointerEvent)` + `onFocusOutside` + `dismissible` + `restoreScrollDelay` | dialog :97-106, drawer :62-92, dropdown-menu :61-63 |
| Flotante | `side` + `align` + `forceMount` + `modal` (+ `updatePositionStrategy` en menús) | popover/dropdown-menu/float-panel |
| Flags de estado plano | `disabled` / `readonly` / `required` / `invalid` (booleans planos, OR-merge Field/Form) | catálogo entero; `is*` SOLO en snippetProps derivados (isFocused/isHovering/isPlaying — rating :21, carousel :18) — separación limpia |
| Form-bridge | `name` (+ hidden input; `value` enviado condicionado al estado) | checkbox/switch/toggle :67-69, radio-group, date-field (ISO), knob/radio-group como PARTE morfo |
| Navegación de lista | `loop` + `orientation` + `dir: Direction` | radio-group :39-41, toggle-group, select :46, combobox :45, listbox :55 |
| Localización | `locale?` (fallback reactivo soma.langs) + `dir` + `hourCycle` | familia date/time |
| Tipado de callbacks | `OnChangeFn<T>` para todo callback con dato | transversal (las excepciones, abajo B.2) |
| Concepto | Patrón canónico | Evidencia |
| -------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| Valor + cambio (valued controls) | `value` (bindable) + `onValueChange: OnChangeFn<T>` | fields ×14, radio-group, toggle-group, rating-group, select, combobox, listbox, calendar, pickers — el par dominante |
| Estado binario semántico | nombre ARIA-alineado, NO value: `checked`/`onCheckedChange` (checkbox :15-19, switch :21-23) · `pressed`/`onPressedChange` (toggle :20-22) · + `indeterminate`/`onIndeterminateChange` (checkbox :16-21) | Convención Radix/bits seguida a rajatabla — REGLA: binarios hablan su ARIA |
| Apertura de overlay | `open` (bindable) + `onOpenChange` + **`onOpenChangeComplete`** (post-animación) | popover :11-15, dialog :12-51, drawer :46-73, tooltip :34-38, float-panel :20-24, dropdown-menu :18-22 — ×6 EXACTO, incluida la variante Complete |
| Cierre/outside | `onInteractOutside: (e: PointerEvent)` + `onFocusOutside` + `dismissible` + `restoreScrollDelay` | dialog :97-106, drawer :62-92, dropdown-menu :61-63 |
| Flotante | `side` + `align` + `forceMount` + `modal` (+ `updatePositionStrategy` en menús) | popover/dropdown-menu/float-panel |
| Flags de estado plano | `disabled` / `readonly` / `required` / `invalid` (booleans planos, OR-merge Field/Form) | catálogo entero; `is*` SOLO en snippetProps derivados (isFocused/isHovering/isPlaying — rating :21, carousel :18) — separación limpia |
| Form-bridge | `name` (+ hidden input; `value` enviado condicionado al estado) | checkbox/switch/toggle :67-69, radio-group, date-field (ISO), knob/radio-group como PARTE morfo |
| Navegación de lista | `loop` + `orientation` + `dir: Direction` | radio-group :39-41, toggle-group, select :46, combobox :45, listbox :55 |
| Localización | `locale?` (fallback reactivo soma.langs) + `dir` + `hourCycle` | familia date/time |
| Tipado de callbacks | `OnChangeFn<T>` para todo callback con dato | transversal (las excepciones, abajo B.2) |
## B. DIVERGENCIAS reales (veredicto requerido — evidencia por celda)
### B.1 Multiplicidad de selección — TRES nombres para el mismo eje
| Nombre | Quién |
|---|---|
| `type: 'single' \| 'multiple'` | select :17, combobox :17 (+ calendar `type` single/multiple) |
| `selectionMode: 'single' \| 'multiple'` | listbox :6-51, tree-view :4-14 |
| `multiple: boolean` | file-upload :53 |
| Nombre | Quién |
| --------------------------------------- | ------------------------------------------------------------ |
| `type: 'single' \| 'multiple'` | select :17, combobox :17 (+ calendar `type` single/multiple) |
| `selectionMode: 'single' \| 'multiple'` | listbox :6-51, tree-view :4-14 |
| `multiple: boolean` | file-upload :53 |
**Propuesta**: un solo nombre (candidato `selectionMode` — no colisiona con el `type` nativo de button/input que ya significa otra cosa en el catálogo; `type` de select/combobox además choca con `PinInputType`/`data-type` que son OTRO eje). Decidir si `multiple: boolean` sobrevive como azúcar donde no hay modo-single-con-array.
### B.2 Callback terminal — CUATRO patrones (de la familia fields, confirmado)
(a) `onValueCommit: OnChangeFn` (mask, editable) · (b) `onSubmit(value)` crudo (search, password) · (c) solo evento sema (date/time/color) · (d) `onComplete` (pin-input). **Propuesta**: (a) como norma; (d) azúcar de completitud si se distingue patrón-lleno de commit.
### B.3 Valor primario: `value` genérico vs palabra de dominio
| Patrón | Quién |
|---|---|
| `value` genérico | fields, grupos, select/combobox/listbox, **carousel** (:83 — ¡para el índice de slide!) |
| Patrón | Quién |
| ------------------ | ---------------------------------------------------------------------------------------- |
| `value` genérico | fields, grupos, select/combobox/listbox, **carousel** (:83 — ¡para el índice de slide!) |
| Palabra de dominio | pagination `page`/`onPageChange` (:23-39) · file-upload `files`/`onFilesChange` (:38-40) |
**Cuestión**: ¿regla "value salvo que el dominio tenga palabra universal" (page, files)? Entonces carousel debería decir `index`/`onIndexChange` (su snippet YA habla de `index` :8-32) — hoy es el híbrido incoherente.
### B.4 Doble eje seleccionado/expandido
tree-view: `selectedValue` + `expandedValue` (+ `onExpandedChange`) :9-26 — sufijo `-Value` para desambiguar ejes (estilo Ark). Coherente internamente; PERO convive con el `value` a secas del resto. **Propuesta**: canonizar el sufijo SOLO para componentes multi-eje (tree, chronos) y documentarlo.
### B.5 Deseleccionabilidad — polaridad invertida
`deselectable?: boolean` (toggle-group :4) vs `preventDeselect?: boolean` (calendar :112). El MISMO concepto, nombres opuestos. **Propuesta**: uno de los dos catálogo-completo (candidato `deselectable` — positivo, sin negación mental).
### B.6 Delays de hover — dos convenciones
popover `openDelay`/`closeDelay` (:31-33) vs tooltip `delayDuration`/`skipDelayDuration` (:18-20, nombres Radix). **Propuesta**: unificar (candidato openDelay/closeDelay — simétrico y describe el efecto; skipDelayDuration se re-nombra a algo del grupo, p.ej. `groupSkipDelay`).
### B.7 Prefijos de capacidad
`allowsCustomValue` (combobox :53, estilo React-Aria "allows") vs adjetivos planos (`deselectable`, `dismissible`) vs `allowHalf` (rating :63 — "allow" singular). TRES micro-convenciones. **Propuesta**: adjetivo plano cuando exista (`deselectable`); `allowX` solo si no hay adjetivo natural; nunca `allowsX`.
### B.8 `defaultValue` — adopción parcial
editable :16-21 Y select :28 (¡no era único!). El resto del catálogo confía en `$bindable(inicial)`. **Veredicto**: canonizar en valued-controls (¿quién más lo necesita?) o podar ambos.
### B.9 Validación — tres firmas (de fields, confirmado)
`validate` + `onInvalid` razones TIPADAS (color-field) · sin tipar (date/time y ranges) · `validate` boolean + `onValueInvalid` (tags-input). **Propuesta**: nivelar a razones tipadas; un solo nombre de callback.
### B.10 Async-en-vuelo
`isPending`/`data-pending` (form) vs `loading` (button, field enum). Puede ser distinción legítima (form en vuelo vs control ocupado) — decidir si se unifica o se documenta.
### B.11 Callbacks de gesto sin par de valor
splitter `onResize(sizes)`/`onResizeEnd(sizes)` (:16-18) — datos por callback sin `sizes` bindable visible. Verificar si hay par bindable (por-Panel); si no, es el único flujo one-way del catálogo → veredicto.
## C. Filas heredadas del pass de fields (siguen vivas)
| Concepto | Norma emergente | Divergentes |
|---|---|---|
| Segundo valor temporal | `placeholder` + `onPlaceholderChange` | — (date/time + ranges coherentes) |
| Callbacks por sub-valor | `onStartValueChange`/`onEndValueChange` junto a `onValueChange` | — (ranges coherentes entre sí) |
| Valor multi-contexto | `values: Record<K,string>` + `LangSpec` + `required: K[]` | field-langs único |
| Doble valor colección+borrador | `value` + `inputValue` ambos bindables | tags-input; combobox :29 TAMBIÉN usa `inputValue` ✓ coherente ×2 |
| Eje conmutable | `X` + `onXChange` + `allowedXs` | color-field (format) |
| Debounce | `debounceMs` (sufijo-unidad) | search-field |
| Completitud | `data-complete`/`isComplete` | mask-field, pin-input |
| Visibilidad de contenido | `visible`/`onVisibilityChange` + `purpose` | password-field (concepto DISTINTO del `open` de overlays — legítimo, documentar la distinción) |
| Cardinalidad | `enabledSelections` + `whenFull` | toggle-group (dueño único ✓ por decisión 2026-06-27) |
| Render condicional | `onlyWhen{Required·Optional·Invalid}` | field ×3 |
| Identidad de item | `index` requerido + `value` (tags-input) | listbox/select items usan `value` sin índice — censo cerrado: el index-required es exclusivo de tags (¿necesario?) |
| Tamaño/variante (eidos) | `size` (ResponsiveProp) + `variant` + `rounded`/`shape`/`block` | catálogo coherente |
| Concepto | Norma emergente | Divergentes |
| ------------------------------ | --------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
| Segundo valor temporal | `placeholder` + `onPlaceholderChange` | — (date/time + ranges coherentes) |
| Callbacks por sub-valor | `onStartValueChange`/`onEndValueChange` junto a `onValueChange` | — (ranges coherentes entre sí) |
| Valor multi-contexto | `values: Record<K,string>` + `LangSpec` + `required: K[]` | field-langs único |
| Doble valor colección+borrador | `value` + `inputValue` ambos bindables | tags-input; combobox :29 TAMBIÉN usa `inputValue` ✓ coherente ×2 |
| Eje conmutable | `X` + `onXChange` + `allowedXs` | color-field (format) |
| Debounce | `debounceMs` (sufijo-unidad) | search-field |
| Completitud | `data-complete`/`isComplete` | mask-field, pin-input |
| Visibilidad de contenido | `visible`/`onVisibilityChange` + `purpose` | password-field (concepto DISTINTO del `open` de overlays — legítimo, documentar la distinción) |
| Cardinalidad | `enabledSelections` + `whenFull` | toggle-group (dueño único ✓ por decisión 2026-06-27) |
| Render condicional | `onlyWhen{Required·Optional·Invalid}` | field ×3 |
| Identidad de item | `index` requerido + `value` (tags-input) | listbox/select items usan `value` sin índice — censo cerrado: el index-required es exclusivo de tags (¿necesario?) |
| Tamaño/variante (eidos) | `size` (ResponsiveProp) + `variant` + `rounded`/`shape`/`block` | catálogo coherente |
## D. Reglas de API que el veredicto debe ratificar (el "style guide" de props)
@ -95,4 +106,4 @@ splitter `onResize(sizes)`/`onResizeEnd(sizes)` (:16-18) — datos por callback
7. Multi-eje: sufijo `-Value` (`selectedValue`/`expandedValue`) solo donde hay ≥2 ejes.
8. Unidades en el nombre cuando el número las tiene: `debounceMs`, `restoreScrollDelay` (ms implícito documentado) — decidir sufijo-unidad como norma.
*(Censo cerrado con el barrido de types 2026-07-07 — media-player provider y service components quedan para verificación dirigida en fixes; sus superficies no mostraron pares de valor divergentes.)*
_(Censo cerrado con el barrido de types 2026-07-07 — media-player provider y service components quedan para verificación dirigida en fixes; sus superficies no mostraron pares de valor divergentes.)_

@ -5,18 +5,18 @@ consolidan des-duplicados para el **checkpoint único post-barrido** (los
fixes — locales y de sistema — se ejecutan después de auditar todo el
catálogo). Formato: origen (fichas) · hallazgo · propuesta.
| # | Origen | Hallazgo de sistema | Propuesta |
|---|---|---|---|
| SYS-1 | button | **Hooks de selector como clases** (`.eidos-button-*`) conviviendo con data-attrs — las clases escapan a eidos-lint; segunda gramática de hooks | Norma de catálogo: hooks SIEMPRE `data-{c}-{kebab}`; + guard (lint de clases con estilos en CSS de componentes). El barrido censa qué componentes lo hacen |
| SYS-2 | button | **Política de tests**: cobertura heterogénea (button 0 tests; date-field 8KB ✓) | Decisión: suites por componente en la fase de fixes vs batch de testing posterior. Cada ficha registra su cobertura para dimensionar |
| SYS-3 | button | **Criterio de pack sema**: ¿cuándo un componente merece pack vs default de familia? (button sin pack = default contact; 38 packs sesgados a fields/pickers) | Canonizar el criterio por escrito (CANON/sema doctrine): default-de-familia legítimo para contacto genérico; pack donde el patrón añade significado |
| SYS-4 | button · date-field | **Nivel canónico del README**: la máquina exige eidos (E-2.3); button solo soma; date-field ambos | Ratificar: eidos = puerta del consumidor (API visual + tokens), soma = contrato headless; documentar en component-guide |
| SYS-5 | date-field | **Doctrina §32 vs segment-fields**: "los campos quedan en box-shadow" pero date-field usa outline flush con razón sólida (flicker en increment + forced-colors). Afecta a date/time/color-field + ranges | Decisión doctrinal: matizar §32 (text-fields = dos anillos box-shadow · segment-fields = outline flush, razón canonizada) — recomendada; el barrido censa la familia completa |
| SYS-6 | date-field (≡ mandato B.1) | **Composición Field**: soma participa (merge) pero el DOM no envuelve `[data-field][data-size]`; label propio; alturas `height-{k}` duplicadas por componente | Ya mandatado en `next-features.md` — el barrido acumula la lista de piezas por componente |
| # | Origen | Hallazgo de sistema | Propuesta |
| ----- | -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| SYS-1 | button | **Hooks de selector como clases** (`.eidos-button-*`) conviviendo con data-attrs — las clases escapan a eidos-lint; segunda gramática de hooks | Norma de catálogo: hooks SIEMPRE `data-{c}-{kebab}`; + guard (lint de clases con estilos en CSS de componentes). El barrido censa qué componentes lo hacen |
| SYS-2 | button | **Política de tests**: cobertura heterogénea (button 0 tests; date-field 8KB ✓) | Decisión: suites por componente en la fase de fixes vs batch de testing posterior. Cada ficha registra su cobertura para dimensionar |
| SYS-3 | button | **Criterio de pack sema**: ¿cuándo un componente merece pack vs default de familia? (button sin pack = default contact; 38 packs sesgados a fields/pickers) | Canonizar el criterio por escrito (CANON/sema doctrine): default-de-familia legítimo para contacto genérico; pack donde el patrón añade significado |
| SYS-4 | button · date-field | **Nivel canónico del README**: la máquina exige eidos (E-2.3); button solo soma; date-field ambos | Ratificar: eidos = puerta del consumidor (API visual + tokens), soma = contrato headless; documentar en component-guide |
| SYS-5 | date-field | **Doctrina §32 vs segment-fields**: "los campos quedan en box-shadow" pero date-field usa outline flush con razón sólida (flicker en increment + forced-colors). Afecta a date/time/color-field + ranges | Decisión doctrinal: matizar §32 (text-fields = dos anillos box-shadow · segment-fields = outline flush, razón canonizada) — recomendada; el barrido censa la familia completa |
| SYS-6 | date-field (≡ mandato B.1) | **Composición Field**: soma participa (merge) pero el DOM no envuelve `[data-field][data-size]`; label propio; alturas `height-{k}` duplicadas por componente | Ya mandatado en `next-features.md` — el barrido acumula la lista de piezas por componente |
| SYS-7 | spin-field · number/css-field · color-swatch | **Clasificación "capa compartida"/átomo pasivo sin escribir**: spin-field/list-surface/field-segment-state (capas) y color-swatch (átomo eidos-native sin `## Passive justification`) — vs la doctrina "morfo-first even leaf". Sin criterio formal ni doc de capa | Definir formalmente CAPA y ÁTOMO PASIVO (markers, README de capa, justificación formal, cómo los clasifica la máquina); documentar en component-guide |
| SYS-8 | calendar · range-calendar · month/year-grid · drp/dp (≡ mandato calendar-surface) | **La familia calendar vive de préstamo informal** (79+65+65+38+4 tokens cross-component); tras B.2, las marcas holiday/event solo pintan en calendar; month/year-grid ni declaran el privado de acento | Ya mandatado (next-features): capa `calendar-surface` y/o arquetipo de celda-día; las fichas de la familia listan las piezas por componente |
| SYS-9 | gradient-picker · gradient-builder (+ntp) | **Patrón "iniciativa a medias"**: componentes embarcados sin cerrar el paquete de estándares (expediente pre-flight F-1.x, APG, tests) — gradient-builder es el caso más agudo | Fase de fixes: cerrar por PAQUETES de iniciativa (gradient-* junto; natural-time-picker integral) — y valorar guard de embarque ("no se embarca sin expediente") |
| SYS-9 | gradient-picker · gradient-builder (+ntp) | **Patrón "iniciativa a medias"**: componentes embarcados sin cerrar el paquete de estándares (expediente pre-flight F-1.x, APG, tests) — gradient-builder es el caso más agudo | Fase de fixes: cerrar por PAQUETES de iniciativa (gradient-\* junto; natural-time-picker integral) — y valorar guard de embarque ("no se embarca sin expediente") |
| SYS-10 | field (re-audit) | **Enums de estado muertos**: el morfo de field declara `data-state` con enum de 5 valores × 3 partes y CERO consumidores CSS en TODO el catálogo (grep exhaustivo); loading no pinta nada. Contrato emitido que nadie honra = peso muerto y promesa falsa del contrato | Veredicto por enum: consumirlo (materializar loading/invalid vía el enum) o podarlo del morfo. El barrido censa más enums muertos en las familias restantes |
| SYS-11 | date-range-field · time-range-field · pickers (re-audit) | **El canon de delegación EXISTE y los compuestos no lo usan uniformemente**: `SemaExpressionMode = 'pack'\|'family-default'\|'delegated'\|'none'` está documentado en `morfo/types.ts` (decisión de autor 2026-05-26; `'delegated'` = "expression lives in children's packs"). date-picker/date-range-picker LO DECLARAN (`expression: 'delegated'` + evento propio solo para el gesto que el hijo no posee: commit-reset) — la regla practicada es exactamente la correcta. Pero date-range-field/time-range-field (compuestos equivalentes) NO declaran expression alguna, y la máquina (A-3.1) no usa `'delegated'` como marcador de exoneración | (a) Fix de una línea en los field-ranges: `expression: 'delegated'`; (b) afinar A-3.1: interactivo + 0 eventos + sin `'delegated'` = gap (caza pin-input y natural-time-picker, exonera a los delegados); (c) párrafo en CANON/sema citando la decisión 2026-05-26 y el patrón date-picker como ejemplo |
@ -34,7 +34,7 @@ catálogo). Formato: origen (fichas) · hallazgo · propuesta.
- ~~Demo (D-7.4 chip drift · D-1.2 plantilla · D-1.5/D-4.3/D-3.1 cableado)~~ — **FUERA DEL ALCANCE de esta auditoría** (corrección de alcance 2026-07-07: solo las capas del componente). Los datos siguen en tmp/component-audit.md como backlog de demos aparte; no computan en fichas ni en el checkpoint.
- **APG ausente (A-1.4)**: natural-time-picker, gradient-picker, gradient-builder, card (variante interactiva), drag-drop, media-player, virtual-list, metrics → y **regla nueva necesaria**: cómo satisfacer "sin patrón APG oficial" (media-player, drag-drop) — ¿`apg: 'none — rationale'`? **Actualización 2026-08-25**: la cara gemela —el `apg` PRESENTE pero MENTIROSO— tiene ya su primer miembro resuelto (`tags-input` F-1: se implementó el layout grid que citaba, en vez de corregir la cita) y dos miembros vivos medidos: `search-field` F-1 (`apg: combobox` sin popup) y **`tag-group`**, que declara el mismo `apg: grid` que `tags-input` y renderiza `role=row` SIN ninguna celda (`morfo/components/tag-group.ts:64` `:137` `:163` — cero `gridcell` declarados) más un `Label` colgando del `grid` que no es `row`. La regla que falta es UNA para las dos caras: qué se hace cuando no hay patrón, y qué se hace cuando el declarado no describe lo implementado.
- **Gramática de eventos (A-3.6/A-3.7)**: media-player ×4 nombres fuera de `{familia}-{verbo}` · float-panel 28 mutaciones/6 eventos (el mayor infra-declarado).
- **Interactivo con 0 eventos (A-3.1) — censo FINAL tras chequeos de delegación**: **pin-input = el único caso desnudo** (0 eventos + comentario :7-9 que promete un "commit-fill" imposible: sema ni está en scope — contradicción in-file). EXONERADOS: date-range-field/time-range-field (delegación real a los singles embebidos; les falta solo declararla — `expression: 'delegated'`) · natural-time-picker (header :4-19 documenta la composición entera; su hueco transaccional es deuda del Picker genérico) · **Picker genérico = tercera categoría: deuda DECLARADA** (:18-19 "candidate commit-* events for a later sema pass" — Accept/Cancel/Clear sin contrato, reconocido; UN fix ahí repara ntp + los 5 pickers de la migración deferValue). Afinar A-3.1: leer expression/scope/header antes de flaguear; añadir el Picker genérico al universo del script.
- **Interactivo con 0 eventos (A-3.1) — censo FINAL tras chequeos de delegación**: **pin-input = el único caso desnudo** (0 eventos + comentario :7-9 que promete un "commit-fill" imposible: sema ni está en scope — contradicción in-file). EXONERADOS: date-range-field/time-range-field (delegación real a los singles embebidos; les falta solo declararla — `expression: 'delegated'`) · natural-time-picker (header :4-19 documenta la composición entera; su hueco transaccional es deuda del Picker genérico) · **Picker genérico = tercera categoría: deuda DECLARADA** (:18-19 "candidate commit-\* events for a later sema pass" — Accept/Cancel/Clear sin contrato, reconocido; UN fix ahí repara ntp + los 5 pickers de la migración deferValue). Afinar A-3.1: leer expression/scope/header antes de flaguear; añadir el Picker genérico al universo del script.
- **Colores crudos (R-2.1)**: natural-time-picker ×9 (cielos physically-fixed SIN anotación) · tipografía literal (R-2.7): field-langs, timeline ×2.
- **Focus ausente (R-1.5)**: announce, clipboard.
- **Expediente pre-flight (F-1.x)**: gradient-picker/builder, color-swatch, radio-cards, metrics, timeline, onion-menu, scroll-frames, trans/format-date/format-number/relative-time, float-panel (parcial) — **13**.
@ -113,7 +113,7 @@ va SUSTITUYENDO fichas familia a familia.
s-text-virtual-list · accordion · collapsible. Correcciones: s-text y
s-text-virtual-list "morfo —" FALSOS (4ª y 5ª falsedad de la clase — el
pass superficial no abrió los morfos de los pasivos) · table/grid-list/
listbox/virtual-*/feed DECLARAN family-default (no son huecos) ·
listbox/virtual-\*/feed DECLARAN family-default (no son huecos) ·
**tree-view expand=EMERGE no shift** (corregí mi propio borrador) ·
unselect=affirm sube a ×5 (grid-list :29, listbox :30) · accordion
open/close vs collapsible expand/collapse = drift de verbos para el
@ -144,5 +144,5 @@ va SUSTITUYENDO fichas familia a familia.
piloto + ~34 pasivos por barrido declarado + 4 WIP usuario (slider, tabs,
number-field, css-field: re-visitar tras su pass) + 2 exclusiones.
- **CHECKPOINT: RESUELTO 2026-07-07** — 29 veredictos (N1–N10 · S1–S11 ·
C1–C8) ítem a ítem con el usuario → **[_veredictos.md](_veredictos.md)**
C1–C8) ítem a ítem con el usuario → **[\_veredictos.md](_veredictos.md)**
es LA fuente. Los fixes se ejecutan por paquetes sobre esas decisiones.

@ -15,51 +15,51 @@ DESPUÉS, por paquetes, sobre estas decisiones.
## Bloque N — Naming / API
| # | Veredicto |
|---|---|
| N1 | **`selectionMode`** en los de selección (migran select, combobox, calendar, toggle-group; listbox/tree-view ya). file-upload conserva `multiple` como **espejo-nativo documentado** (clase accept/name) |
| N2 | **`onValueCommit: OnChangeFn` norma ÚNICA** de callback terminal. pin-input renombra `onComplete`; search/password migran su `onSubmit` crudo; el trío date/time/color AÑADE el callback junto al evento sema |
| N3 | Regla **"`value` salvo palabra de dominio universal"** — `page` (pagination) y `files` (file-upload) se quedan; carousel corrige `value`→`index`/`onIndexChange` |
| N4 | Sufijo **`{eje}Value` SOLO multi-eje** (tree-view queda: `selectedValue`/`expandedValue`); mono-eje = `value` a secas |
| N5 | **`deselectable`** catálogo-completo (calendar migra `preventDeselect`) |
| N6 | **`openDelay`/`closeDelay`** (tooltip migra `delayDuration`; `skipDelayDuration`→`groupSkipDelay`) |
| N7 | Prefijos de capacidad: **adjetivo plano > `allowX` > nunca `allowsX`** (combobox → `allowCustomValue`; `allowHalf` queda) |
| N8 | **`defaultValue` PODADO** de editable y select — `$bindable(inicial)` cubre el caso |
| N9 | Validación nivelada a color-field: **razón tipada + `onInvalid` único** (tags-input migra `validate`-boolean y `onValueInvalid`) |
| N10 | `pending` (derivado, form) vs `loading` (prop del consumidor) — **distinción documentada**; data-attrs quedan |
| # | Veredicto |
| --- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| N1 | **`selectionMode`** en los de selección (migran select, combobox, calendar, toggle-group; listbox/tree-view ya). file-upload conserva `multiple` como **espejo-nativo documentado** (clase accept/name) |
| N2 | **`onValueCommit: OnChangeFn` norma ÚNICA** de callback terminal. pin-input renombra `onComplete`; search/password migran su `onSubmit` crudo; el trío date/time/color AÑADE el callback junto al evento sema |
| N3 | Regla **"`value` salvo palabra de dominio universal"** — `page` (pagination) y `files` (file-upload) se quedan; carousel corrige `value`→`index`/`onIndexChange` |
| N4 | Sufijo **`{eje}Value` SOLO multi-eje** (tree-view queda: `selectedValue`/`expandedValue`); mono-eje = `value` a secas |
| N5 | **`deselectable`** catálogo-completo (calendar migra `preventDeselect`) |
| N6 | **`openDelay`/`closeDelay`** (tooltip migra `delayDuration`; `skipDelayDuration`→`groupSkipDelay`) |
| N7 | Prefijos de capacidad: **adjetivo plano > `allowX` > nunca `allowsX`** (combobox → `allowCustomValue`; `allowHalf` queda) |
| N8 | **`defaultValue` PODADO** de editable y select — `$bindable(inicial)` cubre el caso |
| N9 | Validación nivelada a color-field: **razón tipada + `onInvalid` único** (tags-input migra `validate`-boolean y `onValueInvalid`) |
| N10 | `pending` (derivado, form) vs `loading` (prop del consumidor) — **distinción documentada**; data-attrs quedan |
Las reglas D1–D8 de [_naming.md](_naming.md) quedan ratificadas en consecuencia.
Las reglas D1–D8 de [\_naming.md](_naming.md) quedan ratificadas en consecuencia.
B.11 (splitter sin par bindable) = verificación dirigida, no veredicto.
## Bloque S — Sistema
| # | Veredicto |
|---|---|
| S1 | Hooks SIEMPRE `data-{c}-{kebab}` + **guard anti-`.eidos-*`** + codemod de los 22 (cropper 8, button 6, image-picker 6, toggle 1, image-adjustments 1) |
| S2 | Tests **DENTRO del paquete de fixes** de cada componente (goal-driven) |
| S3a | Criterio de pack **canonizado en la doctrina sema**: 3 categorías (pack / default-documentado / delegated) con citas + regla del "yet" (deuda declarada lleva plazo) |
| # | Veredicto |
| --- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| S1 | Hooks SIEMPRE `data-{c}-{kebab}` + **guard anti-`.eidos-*`** + codemod de los 22 (cropper 8, button 6, image-picker 6, toggle 1, image-adjustments 1) |
| S2 | Tests **DENTRO del paquete de fixes** de cada componente (goal-driven) |
| S3a | Criterio de pack **canonizado en la doctrina sema**: 3 categorías (pack / default-documentado / delegated) con citas + regla del "yet" (deuda declarada lleva plazo) |
| S3b | **Ascensos a pack: LOS 10** (veredicto del usuario, más allá de la recomendación 1–7): time-field+color-field (1º), range-calendar, Picker genérico (eventos+carácter), clipboard, drag-drop, listbox, media-player (tras renombrar), onion-menu/menu-dial, month-grid/year-grid, table |
| S4 | README dos niveles ratificado: **eidos = puerta del consumidor · soma = contrato headless** (date-field plantilla) + component-guide + pass masivo (28 eidos + soma field-langs + doc capa spin-field) |
| S5 | **CANONIZAR OUTLINE** como el modelo de focus (tras comparativa: Radix Themes/MD3/Chakra v3/RAC = outline; box-shadow = generación Tailwind/Bootstrap). §32 se reescribe con la razón (forced-colors + flicker de segmentos) + nota fechada; el remanente box-shadow de field.css migra |
| S6 | Mandato **Field composition CONFIRMADO**; R-1.3/R-1.4 (readonly/invalid ×9+2) se resuelven DENTRO como tratamiento único; 6 fields matan alturas duplicadas; `--field-segment-height` aterriza |
| S7 | **CAPA y ÁTOMO PASIVO definidos formalmente** (component-guide + markers para la máquina); color-swatch y radio-cards citas canónicas |
| S8 | **calendar-surface CONFIRMADO + tokens de rango como API PÚBLICA** de la capa (drp deja de tunear `--_calendar-range-*` ajenos) |
| S9 | Cierre por **paquetes de iniciativa** (gradient-* junto; ntp integral; metrics+suite) + **guard de embarque** F-1.x bloqueante SOLO para componentes nuevos |
| S10 | **PODAR el `data-state` muerto** de field (los flags son la representación — anti-alias) + **declarar enums donde hay unión viva** (calendar `data-type` + los que salgan) |
| S11 | Delegación, LAS 4: (a) `expression: 'delegated'` en los 2 field-ranges · (b) A-3.1 afinada · (c) párrafo en CANON con la decisión 2026-05-26 + cita radio-cards · (d) **guard coherencia pack↔expression** (FAIL pack∧≠'pack'; WARN pack∧sin-expression) |
| S4 | README dos niveles ratificado: **eidos = puerta del consumidor · soma = contrato headless** (date-field plantilla) + component-guide + pass masivo (28 eidos + soma field-langs + doc capa spin-field) |
| S5 | **CANONIZAR OUTLINE** como el modelo de focus (tras comparativa: Radix Themes/MD3/Chakra v3/RAC = outline; box-shadow = generación Tailwind/Bootstrap). §32 se reescribe con la razón (forced-colors + flicker de segmentos) + nota fechada; el remanente box-shadow de field.css migra |
| S6 | Mandato **Field composition CONFIRMADO**; R-1.3/R-1.4 (readonly/invalid ×9+2) se resuelven DENTRO como tratamiento único; 6 fields matan alturas duplicadas; `--field-segment-height` aterriza |
| S7 | **CAPA y ÁTOMO PASIVO definidos formalmente** (component-guide + markers para la máquina); color-swatch y radio-cards citas canónicas |
| S8 | **calendar-surface CONFIRMADO + tokens de rango como API PÚBLICA** de la capa (drp deja de tunear `--_calendar-range-*` ajenos) |
| S9 | Cierre por **paquetes de iniciativa** (gradient-\* junto; ntp integral; metrics+suite) + **guard de embarque** F-1.x bloqueante SOLO para componentes nuevos |
| S10 | **PODAR el `data-state` muerto** de field (los flags son la representación — anti-alias) + **declarar enums donde hay unión viva** (calendar `data-type` + los que salgan) |
| S11 | Delegación, LAS 4: (a) `expression: 'delegated'` en los 2 field-ranges · (b) A-3.1 afinada · (c) párrafo en CANON con la decisión 2026-05-26 + cita radio-cards · (d) **guard coherencia pack↔expression** (FAIL pack∧≠'pack'; WARN pack∧sin-expression) |
## Bloque C — Censos doctrinales
| # | Veredicto |
|---|---|
| C1 | Matriz de intent del deshacer **CANONIZADA tal cual** (colección-unselect=affirm ×5 · binario-uncheck=neutral · reset/cancel=neutral) — solo doc |
| C2 | *(reformulado tras corrección del usuario: los 8 verbos emerge son conjunto CERRADO del cap. 26 — eventos DISTINTOS, no drift)* **Pass de verificación verbo-a-verbo contra el cap. 26** en fixes; cada overlay justifica su elección con cita; accordion (`open/close`) ↔ collapsible (`expand/collapse`) primer caso a adjudicar |
| C3 | Regla de asignación de intent en toggles binarios **ESCRITA**: marcar-hecho = direccional estático (checkbox ejemplar) · conmutar-modo = `fromProp` default neutral (switch ejemplar) |
| C4 | **QUITAR `role='application'`** de los 4 (calendar/range-calendar/month-grid/year-grid) — línea bits/Radix/M3; verificar con lector de pantalla tras el cambio |
| C5 | Campo `apg` admite **`'none — {rationale}'`** + A-1.4 exige URL o none-con-razón (ausente = flag SIEMPRE) + pass de declaración |
| C6 | **`getWeekInfo(locale)` en `$libs/days` AHORA** (fallback sáb/dom documentado); calendar deriva `weekend` + verificar `firstDay` en el mismo fix |
| C7 | D13: fix de textarea **vía el `measure` del ActiveDom DEL CONTEXTO** (precisión del usuario: nunca DOM directo ni import de `$libs/dom` — solo la instancia inyectada) + censo dirigido (scroll-area prioritario, cropper, splitter, float-panel, virtual-*, carousel) + sonda reflowDetector |
| C8 | Afinar las 4 reglas del script (A-3.1, A-1.4, A-3.6 nombre↔verbo, universo completo con Picker) + **los escapados como fixtures de regresión** del propio script |
| # | Veredicto |
| --- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| C1 | Matriz de intent del deshacer **CANONIZADA tal cual** (colección-unselect=affirm ×5 · binario-uncheck=neutral · reset/cancel=neutral) — solo doc |
| C2 | _(reformulado tras corrección del usuario: los 8 verbos emerge son conjunto CERRADO del cap. 26 — eventos DISTINTOS, no drift)_ **Pass de verificación verbo-a-verbo contra el cap. 26** en fixes; cada overlay justifica su elección con cita; accordion (`open/close`) ↔ collapsible (`expand/collapse`) primer caso a adjudicar |
| C3 | Regla de asignación de intent en toggles binarios **ESCRITA**: marcar-hecho = direccional estático (checkbox ejemplar) · conmutar-modo = `fromProp` default neutral (switch ejemplar) |
| C4 | **QUITAR `role='application'`** de los 4 (calendar/range-calendar/month-grid/year-grid) — línea bits/Radix/M3; verificar con lector de pantalla tras el cambio |
| C5 | Campo `apg` admite **`'none — {rationale}'`** + A-1.4 exige URL o none-con-razón (ausente = flag SIEMPRE) + pass de declaración |
| C6 | **`getWeekInfo(locale)` en `$libs/days` AHORA** (fallback sáb/dom documentado); calendar deriva `weekend` + verificar `firstDay` en el mismo fix |
| C7 | D13: fix de textarea **vía el `measure` del ActiveDom DEL CONTEXTO** (precisión del usuario: nunca DOM directo ni import de `$libs/dom` — solo la instancia inyectada) + censo dirigido (scroll-area prioritario, cropper, splitter, float-panel, virtual-\*, carousel) + sonda reflowDetector |
| C8 | Afinar las 4 reglas del script (A-3.1, A-1.4, A-3.6 nombre↔verbo, universo completo con Picker) + **los escapados como fixtures de regresión** del propio script |
## Fixes obvios (aprobados sin veto durante el checkpoint)

@ -7,10 +7,10 @@
## Dimensiones (evidencia leída)
| # | Dimensión | Estado | Evidencia |
|---|---|---|---|
| 3 | Coherencia semántica | ✓ + dato censo | emerge **open/close** mientras su gemelo collapsible dice emerge **expand/collapse** (y tree-view expand/collapse) — el drift de verbos DENTRO de la familia emerge para el MISMO gesto disclosure: dato central del censo de verbos |
| resto | | ✓ | pack ✓; tests ✓; README ×2 ✓ |
| # | Dimensión | Estado | Evidencia |
| ----- | -------------------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| 3 | Coherencia semántica | ✓ + dato censo | emerge **open/close** mientras su gemelo collapsible dice emerge **expand/collapse** (y tree-view expand/collapse) — el drift de verbos DENTRO de la familia emerge para el MISMO gesto disclosure: dato central del censo de verbos |
| resto | | ✓ | pack ✓; tests ✓; README ×2 ✓ |
## Hallazgos y propuestas
@ -22,4 +22,4 @@ Censo verbos emerge (accordion open/close vs collapsible expand/collapse — mis
## Veredictos
*(pendiente — checkpoint post-barrido)*
_(pendiente — checkpoint post-barrido)_

@ -6,12 +6,12 @@
## Dimensiones (evidencia leída)
| # | Dimensión | Estado | Evidencia |
|---|---|---|---|
| 3 | Coherencia semántica | ✓ delegación documentada | 0 eventos CON razón in-place (:7-10): "Sema picks up Action/Cancel button events via the Dialog morfo's shared `commit-*`/`close-*` events — alert-dialog's morfo only declares the Action + Cancel button parts (Provider is virtual)"; `scope: ['soma','eidos']` sin sema — coherente (como ntp). Cuarto ejemplo del patrón delegación bien escrito |
| 4 | API | ✓ | Cancel = `Extract<ButtonVariant, ControlVariant>` (narrowing §19 ✓); el sitio canónico del `signal.warn + threat` PRE-acción (doctrina button cap. 22) |
| 8 | Contrato morfo | ✓ | APG alertdialog (:12); bloque focus propio (:19+) |
| resto | | ✓ | tests ✓; README ×2 ✓ |
| # | Dimensión | Estado | Evidencia |
| ----- | -------------------- | ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 3 | Coherencia semántica | ✓ delegación documentada | 0 eventos CON razón in-place (:7-10): "Sema picks up Action/Cancel button events via the Dialog morfo's shared `commit-*`/`close-*` events — alert-dialog's morfo only declares the Action + Cancel button parts (Provider is virtual)"; `scope: ['soma','eidos']` sin sema — coherente (como ntp). Cuarto ejemplo del patrón delegación bien escrito |
| 4 | API | ✓ | Cancel = `Extract<ButtonVariant, ControlVariant>` (narrowing §19 ✓); el sitio canónico del `signal.warn + threat` PRE-acción (doctrina button cap. 22) |
| 8 | Contrato morfo | ✓ | APG alertdialog (:12); bloque focus propio (:19+) |
| resto | | ✓ | tests ✓; README ×2 ✓ |
## Hallazgos y propuestas
@ -23,4 +23,4 @@ SYS-11 (cuarta cita del patrón).
## Veredictos
*(pendiente — checkpoint post-barrido)*
_(pendiente — checkpoint post-barrido)_

@ -6,18 +6,18 @@
## Dimensiones (evidencia leída)
| # | Dimensión | Estado | Evidencia |
|---|---|---|---|
| 3 | Coherencia semántica | ✓ declarado | 4 eventos + family-default escrito (el pass superficial lo daba "pack —" a secas); las firmas announce-* retuneadas en A.4/A.5 le pertenecen ✓ |
| 9 | A11y | hallazgo | **F-1**: R-1.5 — si su close/action es interactivo necesita focus visible; si es puro aviso, documentarlo |
| 14 | Docs | gap | Sin README eidos |
| # | Dimensión | Estado | Evidencia |
| --- | -------------------- | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| 3 | Coherencia semántica | ✓ declarado | 4 eventos + family-default escrito (el pass superficial lo daba "pack —" a secas); las firmas announce-\* retuneadas en A.4/A.5 le pertenecen ✓ |
| 9 | A11y | hallazgo | **F-1**: R-1.5 — si su close/action es interactivo necesita focus visible; si es puro aviso, documentarlo |
| 14 | Docs | gap | Sin README eidos |
## Hallazgos y propuestas
| ID | Hallazgo | Propuesta |
|---|---|---|
| ID | Hallazgo | Propuesta |
| ------- | ------------------------------- | ----------------------------------- |
| **F-1** | Focus del trigger/close (R-1.5) | Regla del arquetipo o justificación |
| **F-2** | README eidos | SYS-4 |
| **F-2** | README eidos | SYS-4 |
## Escalan al sistema
@ -25,4 +25,4 @@ SYS-4 · censo R-1.5.
## Veredictos
*(pendiente — checkpoint post-barrido)*
_(pendiente — checkpoint post-barrido)_

@ -3,4 +3,4 @@
- **Fecha**: 2026-07-07 · **Familia**: layout · **Método**: solo análisis
- **Capas**: morfo ✓ (scope eidos) · README eidos ✓ · consume `--aspect-ratio-*` ✓ · **Máquina: PASS limpio**.
— limpio. **Escalan**: —. · **Veredictos**: *(pendiente checkpoint post-barrido)*
— limpio. **Escalan**: —. · **Veredictos**: _(pendiente checkpoint post-barrido)_

@ -3,4 +3,4 @@
- **Fecha**: 2026-07-07 · **Familia**: layout (grid auto-fill por min-width) · **Método**: solo análisis
- **Capas**: morfo ✓ (scope eidos) · README eidos ✓ · **Máquina: PASS limpio**.
— limpio. **Escalan**: —. · **Veredictos**: *(pendiente checkpoint post-barrido)*
— limpio. **Escalan**: —. · **Veredictos**: _(pendiente checkpoint post-barrido)_

@ -3,4 +3,4 @@
- **Fecha**: 2026-07-07 · **Familia**: display · **Método**: solo análisis
- **Capas**: morfo ✓ · README eidos ✓ · **Máquina: PASS limpio** · excepción tipográfica canónica ✓ (inicial ∝ diámetro, documentada en §5).
— limpio (fallback de iniciales, estados de carga). **Escalan**: —. · **Veredictos**: *(pendiente checkpoint post-barrido)*
— limpio (fallback de iniciales, estados de carga). **Escalan**: —. · **Veredictos**: _(pendiente checkpoint post-barrido)_

@ -2,10 +2,10 @@
- **Fecha**: 2026-07-07 · **Familia**: display · **Método**: solo análisis
- **Capas**: morfo ✓ (scope eidos probable) · soma — (pasivo) · README eidos **✗** · pack — · soft translúcido §24.2 ✓ · 1:1 tipográfico ✓
- **Máquina**: **NEEDS-WORK** — `E-2.3` (*falta README eidos*).
- **Máquina**: **NEEDS-WORK** — `E-2.3` (_falta README eidos_).
| Hallazgo | Propuesta |
|---|---|
| F-1: README eidos | SYS-4 |
| Hallazgo | Propuesta |
| ----------------- | --------- |
| F-1: README eidos | SYS-4 |
**Escalan**: SYS-4. · **Veredictos**: *(pendiente checkpoint post-barrido)*
**Escalan**: SYS-4. · **Veredictos**: _(pendiente checkpoint post-barrido)_

@ -8,18 +8,18 @@
## Dimensiones (evidencia leída)
| # | Dimensión | Estado | Evidencia |
|---|---|---|---|
| 8 | Contrato morfo | ~~✓ ejemplar~~ → corregido (A-109) | era `<header data-banner role='banner'>` con la cita de la spec; hoy `<section data-banner>` sin rol propio. `data-intent` → canal color-role estándar |
| 10 | Theming | hallazgo | **F-1**: la variante `overlay` flota (banda z) sin estampar depth — al censo |
| 14 | Docs | gap menor | Clasificación formal → SYS-7 |
| # | Dimensión | Estado | Evidencia |
| --- | -------------- | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| 8 | Contrato morfo | ~~✓ ejemplar~~ → corregido (A-109) | era `<header data-banner role='banner'>` con la cita de la spec; hoy `<section data-banner>` sin rol propio. `data-intent` → canal color-role estándar |
| 10 | Theming | hallazgo | **F-1**: la variante `overlay` flota (banda z) sin estampar depth — al censo |
| 14 | Docs | gap menor | Clasificación formal → SYS-7 |
## Hallazgos y propuestas
| ID | Hallazgo | Propuesta |
|---|---|---|
| ID | Hallazgo | Propuesta |
| ------- | ------------------------------- | ----------------------------------------------------------------- |
| **F-1** | overlay-banner sin `data-depth` | Pass conjunto de depth (tooltip/toast/float-panel/banner-overlay) |
| **F-2** | Clasificación formal | SYS-7 |
| **F-2** | Clasificación formal | SYS-7 |
## Escalan al sistema
@ -27,4 +27,4 @@ SYS-7 · censo depth.
## Veredictos
*(pendiente — checkpoint post-barrido)*
_(pendiente — checkpoint post-barrido)_

@ -3,4 +3,4 @@
- **Fecha**: 2026-07-07 · **Familia**: layout (primitiva base) · **Método**: solo análisis
- **Capas**: morfo ✓ (scope eidos) · README eidos ✓ · **Máquina: PASS limpio** · `--box-max-width` compone con container ✓.
— limpio. **Escalan**: —. · **Veredictos**: *(pendiente checkpoint post-barrido)*
— limpio. **Escalan**: —. · **Veredictos**: _(pendiente checkpoint post-barrido)_

@ -6,16 +6,16 @@
## Dimensiones (evidencia leída)
| # | Dimensión | Estado | Evidencia |
|---|---|---|---|
| 3 | Coherencia semántica | ✓ consistente, sin la línea | 0 eventos coherente (nav landmark; sus items son Links con semántica nativa) pero SIN razón escrita — misma clase que link-preview F-2 (los ejemplares fab/banner/radio-cards la escriben) |
| 8 | Contrato morfo | ✓ | Nav landmark, current-page aria, apg ✓ |
| resto | | ✓ | tests ✓; README ×2 ✓ |
| # | Dimensión | Estado | Evidencia |
| ----- | -------------------- | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| 3 | Coherencia semántica | ✓ consistente, sin la línea | 0 eventos coherente (nav landmark; sus items son Links con semántica nativa) pero SIN razón escrita — misma clase que link-preview F-2 (los ejemplares fab/banner/radio-cards la escriben) |
| 8 | Contrato morfo | ✓ | Nav landmark, current-page aria, apg ✓ |
| resto | | ✓ | tests ✓; README ×2 ✓ |
## Hallazgos y propuestas
| ID | Hallazgo | Propuesta |
|---|---|---|
| ID | Hallazgo | Propuesta |
| ------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| **F-1** | Silencio sin razón escrita | Una línea en el morfo ("nav display: los items delegan en la semántica nativa de Link/anchor") — pass conjunto con link-preview |
## Escalan al sistema
@ -24,4 +24,4 @@ Censo "0-eventos sin línea de razón" (breadcrumb, link-preview — vs 6 ejempl
## Veredictos
*(pendiente — checkpoint post-barrido)*
_(pendiente — checkpoint post-barrido)_

@ -3,8 +3,8 @@
- **Fecha**: 2026-07-07 · **Familia**: acciones (iniciativa 06-22) · **Método**: solo análisis
- **Capas**: morfo — (composición eidos: contexto de defaults para Buttons) · soma — · README eidos ✓ · pack — · **Máquina: PASS limpio** · el contexto que button consume ✓ (prop explícita gana).
| Hallazgo | Propuesta |
|---|---|
| F-1: composición sin clasificar | SYS-7 |
| Hallazgo | Propuesta |
| ------------------------------- | --------- |
| F-1: composición sin clasificar | SYS-7 |
**Escalan**: SYS-7. · **Veredictos**: *(pendiente checkpoint post-barrido)*
**Escalan**: SYS-7. · **Veredictos**: _(pendiente checkpoint post-barrido)_

@ -4,51 +4,51 @@
- **Método**: solo análisis — los fixes se ejecutan tras auditar TODO el catálogo; esta ficha registra hallazgos + **propuestas de solución** (locales y las que escalan al sistema).
- **Tier**: control interactivo · **Morfo scope**: `['soma','sema','eidos']` · **Familia**: acciones
- **Capas**: [morfo](../../../src/uix/morfo/components/button.ts) · [soma](../../../src/uix/soma/components/button/) · [eidos](../../../src/uix/eidos/components/button/) · sema: **sin pack** (cascada por defecto)
- **Máquina** (`component:audit --only button`): **NEEDS-WORK** — `E-2.3` (falta README a nivel eidos). R-rules (color/tipografía/recipe-contract): **limpias**. *(Reglas D-\* de demo excluidas — corrección de alcance 2026-07-07: la auditoría cubre solo las capas del componente.)*
- **Máquina** (`component:audit --only button`): **NEEDS-WORK** — `E-2.3` (falta README a nivel eidos). R-rules (color/tipografía/recipe-contract): **limpias**. _(Reglas D-\* de demo excluidas — corrección de alcance 2026-07-07: la auditoría cubre solo las capas del componente.)_
- **Vigencia re-auditoría**: ficha piloto — YA a profundidad de referencia (todas las capas leídas con evidencia); este retrofit solo extrae las demos del alcance.
## Tabla de dimensiones
| # | Dimensión | Estado | Evidencia / nota |
|---|---|---|---|
| 1 | Composición vs declaración | ✓ | API compositiva; `child` (asChild) ✓; Spinner morfo-declarado con razón documentada (derivado de estado, no composición) |
| 2 | Naming de props | ✓ con hallazgo | Props canónicas (`disabled/loading/type/color/intent`); ver **S-1** (hooks CSS mixtos clase/data) |
| 3 | Coherencia semántica ecosistema/theming | ✓ ejemplar | `intent` = SOLO visual (cap. 22 §11 citado); contact sin intent; cascada intent-gana-sobre-color en provider; anti-patrón `contact+fulfill` documentado (cap. 22 §8) |
| 4 | API normalizada | ✓ | `OptsFromProps`; defaults documentados; `color` tipado laxo para paleta per THEMING §25.5 con re-type en eidos; `onPress` = feedback diagnóstico (no side-effect) |
| 5 | Tokens usados | ✓ | Piloto de la cascada `--button-palette-*`; recipe R-limpio; focus por `--focus-ring-*`; 0 usos de state-layer = **correcto** (todas las variantes son valenced — swap de paleta; sin tier neutro) |
| 6 | Parte semántica | validar | **F-6**: sin pack sema — `contact.activate` suena por el default de familia → ver S-3 |
| 7 | Animaciones | ✓ | Sin `@keyframes` perceptuales locales; press vía sistema (`--press-*`); spinner = periodo funcional |
| 8 | Contrato morfo | ✓ con hallazgo | Ejemplar: APG enlazado, keyboard declarado, textos localizados, `data-state` eliminado con la razón del clobbering (audit 05-27) documentada. **F-1**: Spinner con `archetype: 'item'` siendo parte display |
| 9 | Accesibilidad | ✓ | `aria-busy` en loading, `aria-disabled`, iconos `aria-hidden`, `iconOnly` conserva label sr-only, `loadingText` mantiene children sr-only, Enter/Space nativos, touch coarse por arquetipo trigger |
| 10 | Adopción theming | ✓ | Bundle de size vía recipe; depth n/a (no flota); focus modelo superficies (outline) ✓; palette cascade ✓ |
| 11 | Composición interna | ✓ | Participa en `Field.Provider` (disabled OR-merge); consume contexto `ButtonGroup` para defaults (prop explícita gana); es el COMPUESTO por IconButton/triggers |
| 12 | Estados y ciclo | ✓ | disabled/loading completos (click gated en ambos); `type` default 'button' (anti-submit implícito); controlled n/a (stateless) |
| 13 | Disciplina runtime | ✓ | Runtime-direct; sin DOM manual; sin timers; `$derived` limpios |
| 14 | ~~Demo testbed~~ | fuera de alcance | Demos excluidas de la auditoría (corrección 2026-07-07) — sus reglas D-\* viven en tmp/component-audit.md, no aquí |
| 15 | Docs + tests | **gap doble** | **F-4**: falta README eidos (el de soma completo con `## Sema events` ✓) · **F-7**: **CERO tests** de provider/wrapper · **F-2**: doc de `aria-label` en soma types referencia `iconOnly` (prop de eidos — fuga de capa) · **F-3**: docblock del wrapper cita `data-state` que el morfo eliminó |
| 16 | i18n | ✓ | `texts` del morfo localizados (`#?components.button.*`); `loadingText` del consumidor; sin strings hardcoded |
| # | Dimensión | Estado | Evidencia / nota |
| --- | --------------------------------------- | ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1 | Composición vs declaración | ✓ | API compositiva; `child` (asChild) ✓; Spinner morfo-declarado con razón documentada (derivado de estado, no composición) |
| 2 | Naming de props | ✓ con hallazgo | Props canónicas (`disabled/loading/type/color/intent`); ver **S-1** (hooks CSS mixtos clase/data) |
| 3 | Coherencia semántica ecosistema/theming | ✓ ejemplar | `intent` = SOLO visual (cap. 22 §11 citado); contact sin intent; cascada intent-gana-sobre-color en provider; anti-patrón `contact+fulfill` documentado (cap. 22 §8) |
| 4 | API normalizada | ✓ | `OptsFromProps`; defaults documentados; `color` tipado laxo para paleta per THEMING §25.5 con re-type en eidos; `onPress` = feedback diagnóstico (no side-effect) |
| 5 | Tokens usados | ✓ | Piloto de la cascada `--button-palette-*`; recipe R-limpio; focus por `--focus-ring-*`; 0 usos de state-layer = **correcto** (todas las variantes son valenced — swap de paleta; sin tier neutro) |
| 6 | Parte semántica | validar | **F-6**: sin pack sema — `contact.activate` suena por el default de familia → ver S-3 |
| 7 | Animaciones | ✓ | Sin `@keyframes` perceptuales locales; press vía sistema (`--press-*`); spinner = periodo funcional |
| 8 | Contrato morfo | ✓ con hallazgo | Ejemplar: APG enlazado, keyboard declarado, textos localizados, `data-state` eliminado con la razón del clobbering (audit 05-27) documentada. **F-1**: Spinner con `archetype: 'item'` siendo parte display |
| 9 | Accesibilidad | ✓ | `aria-busy` en loading, `aria-disabled`, iconos `aria-hidden`, `iconOnly` conserva label sr-only, `loadingText` mantiene children sr-only, Enter/Space nativos, touch coarse por arquetipo trigger |
| 10 | Adopción theming | ✓ | Bundle de size vía recipe; depth n/a (no flota); focus modelo superficies (outline) ✓; palette cascade ✓ |
| 11 | Composición interna | ✓ | Participa en `Field.Provider` (disabled OR-merge); consume contexto `ButtonGroup` para defaults (prop explícita gana); es el COMPUESTO por IconButton/triggers |
| 12 | Estados y ciclo | ✓ | disabled/loading completos (click gated en ambos); `type` default 'button' (anti-submit implícito); controlled n/a (stateless) |
| 13 | Disciplina runtime | ✓ | Runtime-direct; sin DOM manual; sin timers; `$derived` limpios |
| 14 | ~~Demo testbed~~ | fuera de alcance | Demos excluidas de la auditoría (corrección 2026-07-07) — sus reglas D-\* viven en tmp/component-audit.md, no aquí |
| 15 | Docs + tests | **gap doble** | **F-4**: falta README eidos (el de soma completo con `## Sema events` ✓) · **F-7**: **CERO tests** de provider/wrapper · **F-2**: doc de `aria-label` en soma types referencia `iconOnly` (prop de eidos — fuga de capa) · **F-3**: docblock del wrapper cita `data-state` que el morfo eliminó |
| 16 | i18n | ✓ | `texts` del morfo localizados (`#?components.button.*`); `loadingText` del consumidor; sin strings hardcoded |
## Hallazgos y propuestas de solución — del componente
| ID | Hallazgo | Propuesta de solución |
|---|---|---|
| **F-1** | Spinner declara `archetype: 'item'` siendo parte display (`aria-hidden`, no interactiva) — el gotcha conocido: item arrastra estilo interactivo | Quitar el archetype de la parte Spinner (omitirlo, como manda la doctrina para partes display); verificación visual antes/después del spinner en los 3 placements |
| **F-2** | En soma `types.ts`, el doc de `aria-label` dice "Required when `iconOnly` is true" — `iconOnly` es prop de EIDOS, no existe en soma (fuga de capa en docs) | Reescribir el JSDoc sin referencia cross-capa ("override del nombre accesible; obligatorio cuando el botón no tiene texto visible") |
| **F-3** | Docblock de eidos `button.svelte` dice "Soma owns … `data-state`" — button eliminó `data-state` (el propio morfo documenta por qué) | Actualizar el docblock (data-loading/data-disabled por presencia; sin data-state) |
| **F-4** | Falta `eidos/components/button/README.md` (convención que la máquina exige, `E-2.3`); el README de soma está completo | Crear el README eidos siguiendo el patrón de los existentes (css-field/number-field): API visual, variantes, tokens públicos del recipe, composición |
| ~~F-5~~ | *(retirado — hallazgo de demo, fuera del alcance de la auditoría)* | — |
| **F-6** | Sin pack sema propio: `contact.activate` materializa el default de la familia | Ver **S-3** (es cuestión doctrinal de catálogo, no de button) |
| **F-7** | **Cero tests** de provider/wrapper — el componente insignia sin suite | Suite browser del provider (click→contact-activate, gate disabled/loading, Field-merge, cascada intent/color, snippetProps) + wrapper (spinner placements, iconOnly sr-only, loadingText swap). Alcance/momento: ver **S-2** |
| ID | Hallazgo | Propuesta de solución |
| ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **F-1** | Spinner declara `archetype: 'item'` siendo parte display (`aria-hidden`, no interactiva) — el gotcha conocido: item arrastra estilo interactivo | Quitar el archetype de la parte Spinner (omitirlo, como manda la doctrina para partes display); verificación visual antes/después del spinner en los 3 placements |
| **F-2** | En soma `types.ts`, el doc de `aria-label` dice "Required when `iconOnly` is true" — `iconOnly` es prop de EIDOS, no existe en soma (fuga de capa en docs) | Reescribir el JSDoc sin referencia cross-capa ("override del nombre accesible; obligatorio cuando el botón no tiene texto visible") |
| **F-3** | Docblock de eidos `button.svelte` dice "Soma owns … `data-state`" — button eliminó `data-state` (el propio morfo documenta por qué) | Actualizar el docblock (data-loading/data-disabled por presencia; sin data-state) |
| **F-4** | Falta `eidos/components/button/README.md` (convención que la máquina exige, `E-2.3`); el README de soma está completo | Crear el README eidos siguiendo el patrón de los existentes (css-field/number-field): API visual, variantes, tokens públicos del recipe, composición |
| ~~F-5~~ | _(retirado — hallazgo de demo, fuera del alcance de la auditoría)_ | — |
| **F-6** | Sin pack sema propio: `contact.activate` materializa el default de la familia | Ver **S-3** (es cuestión doctrinal de catálogo, no de button) |
| **F-7** | **Cero tests** de provider/wrapper — el componente insignia sin suite | Suite browser del provider (click→contact-activate, gate disabled/loading, Field-merge, cascada intent/color, snippetProps) + wrapper (spinner placements, iconOnly sr-only, loadingText swap). Alcance/momento: ver **S-2** |
## Hallazgos que escalan al sistema / theming
| ID | Hallazgo (visto en button, alcance = catálogo) | Propuesta |
|---|---|---|
| **S-1** | **Hooks estructurales del wrapper como clases** (`.eidos-button-{body,icon,sr-only,loading-text}`, 6 selectores) conviviendo con data-attrs (`[data-button-icon]`). Las clases **escapan a eidos-lint** (solo valida `[data-*]`) y crean segunda gramática de hooks | **Norma de catálogo**: hooks de selector SIEMPRE data-attrs (`data-{c}-{kebab}`), nunca clases; clase permitida solo como utility sin selector en CSS (p. ej. contenedor neutro). + Guard: lint que detecte `\.eidos-` / clases con estilos en CSS de componentes. Aplicar en el fix-phase a todos los que salgan en el barrido |
| **S-2** | Ausencia de tests no es exclusiva de button — política de alcance pendiente | **Decisión de catálogo** (checkpoint post-barrido): (a) suite por componente durante fase de fixes, o (b) batch de testing como fase propia posterior. La ficha de cada componente registra su cobertura actual para dimensionar |
| **S-3** | Componentes de contacto genérico sin pack sema: ¿el default de familia ES la firma, o el catálogo quiere carácter per-componente en los buques insignia? | **Decisión doctrinal** (checkpoint): criterio de cuándo un componente MERECE pack (hoy: 38 packs, sesgo a fields/pickers). Propuesta: default-de-familia = firma legítima para contact genérico (button, link); pack solo donde el patrón añade significado (ya es el statu quo — canonizarlo por escrito en CANON/sema doctrine) |
| **S-4** | El README vive en DOS niveles (soma completo aquí; la máquina exige el de eidos) — heterogeneidad de dónde vive la doc del componente | **Norma**: definir el nivel canónico (propuesta: eidos = puerta del consumidor, con API visual + tokens; soma README = contrato headless). La máquina ya empuja a eidos (`E-2.3`) — ratificar y documentar en component-guide |
| ID | Hallazgo (visto en button, alcance = catálogo) | Propuesta |
| ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **S-1** | **Hooks estructurales del wrapper como clases** (`.eidos-button-{body,icon,sr-only,loading-text}`, 6 selectores) conviviendo con data-attrs (`[data-button-icon]`). Las clases **escapan a eidos-lint** (solo valida `[data-*]`) y crean segunda gramática de hooks | **Norma de catálogo**: hooks de selector SIEMPRE data-attrs (`data-{c}-{kebab}`), nunca clases; clase permitida solo como utility sin selector en CSS (p. ej. contenedor neutro). + Guard: lint que detecte `\.eidos-` / clases con estilos en CSS de componentes. Aplicar en el fix-phase a todos los que salgan en el barrido |
| **S-2** | Ausencia de tests no es exclusiva de button — política de alcance pendiente | **Decisión de catálogo** (checkpoint post-barrido): (a) suite por componente durante fase de fixes, o (b) batch de testing como fase propia posterior. La ficha de cada componente registra su cobertura actual para dimensionar |
| **S-3** | Componentes de contacto genérico sin pack sema: ¿el default de familia ES la firma, o el catálogo quiere carácter per-componente en los buques insignia? | **Decisión doctrinal** (checkpoint): criterio de cuándo un componente MERECE pack (hoy: 38 packs, sesgo a fields/pickers). Propuesta: default-de-familia = firma legítima para contact genérico (button, link); pack solo donde el patrón añade significado (ya es el statu quo — canonizarlo por escrito en CANON/sema doctrine) |
| **S-4** | El README vive en DOS niveles (soma completo aquí; la máquina exige el de eidos) — heterogeneidad de dónde vive la doc del componente | **Norma**: definir el nivel canónico (propuesta: eidos = puerta del consumidor, con API visual + tokens; soma README = contrato headless). La máquina ya empuja a eidos (`E-2.3`) — ratificar y documentar en component-guide |
## Veredictos
*(pendiente — checkpoint único post-barrido; las propuestas de arriba se ejecutan en la fase de fixes)*
_(pendiente — checkpoint único post-barrido; las propuestas de arriba se ejecutan en la fase de fixes)_

@ -7,34 +7,34 @@
## Dimensiones (evidencia leída)
| # | Dimensión | Estado | Evidencia |
|---|---|---|---|
| 1 | Composición | ✓ | 14 partes compositivas (Provider→Grid `<table>`→GridRow `<tr>`→Cell `<td>`→Day); MonthSelect/YearSelect `<select>` nativos; WeekNumber opcional |
| 2 | Naming | ✓ + censo | `type: 'single'\|'multiple'` (provider :63 — range va aparte en range-calendar, split limpio ✓); **`preventDeselect`** (types :112, Radix-style) — nuevo concepto para _naming; `CalendarView = 'day'\|'month'\|'year'` (:25, el view-switch) |
| 3 | Coherencia semántica | ✓ con cuestión | `commit-select`/`commit-unselect` (affirm, target day) + `shift-navigate` (sin intent ✓ shift); pack propio ✓; **F-5**: `commit-unselect` con intent **affirm** mientras date-field `commit-reset` es neutral y editable `commit-cancel` neutral — ¿la DES-selección es afirmativa? → censo transversal "intent de deshacer" |
| 4 | API | ✓ | min/maxValue + **minViewValue** (:118, límite del view-switch); preventDeselect; isDateHoliday inyectable (types :56) |
| 5 | Tokens | ✓ | Acentos por privados `--_calendar-accent-*` con 8 retunes por color ✓; antecedente B.2 resuelto |
| 6 | Sema | ✓ | Pack propio existe (`sema/components/calendar.ts`) — el único de la familia calendar con carácter |
| 7 | Animaciones | ✓ | Sin keyframes en morfo/recipe leídos |
| 8 | Contrato morfo | ✓ ejemplar con 2 gaps | **TRES razones de no-archetype escritas** (GridRow :248-250 "hover over the entire week bug" · Cell :271-274 chrome de listbox-row · Day :309-313 el item-tint pisaba el fill de selección) — memoria institucional del gotcha archetype-item ×3 ✓; ariaBoolean con nota de compat boolToStr ×6; **F-3**: `data-type` declarado SIN enum (morfo :54) cuando soma tiene unión cerrada (provider :63) — el compilador no puede validar valores |
| 9 | A11y | **2 hallazgos** | Teclado APG-grid COMPLETO en Provider (:70-81: flechas, PageUp/Down mes, Home/End semana, Enter/Space) ✓ — date-field F-1 (Home/End) aquí SÍ está; **F-1**: Provider `role='application'` (:51) — decisión pesada (desactiva el cursor virtual del lector para TODO el árbol) SIN razón documentada, en un morfo que documenta hasta 3 razones de archetype (react-aria la usa en Calendar; bits-ui no — es debate APG real, pero aquí está muda); **F-2**: Day `role='button'` lleva `aria-selected` (:340-344) — ARIA inválido (aria-selected solo soporta gridcell/option/row/tab/treeitem...); el Cell (role=gridcell :277,:292-297) YA la lleva legítimamente |
| 10 | Theming | ✓ | Focus outline (o1) → censo SYS-5; vocabulario de estado de celda rico (selected/today/weekend/holiday/unavailable/outside-month) |
| 11 | Composición interna | **el mandato de familia** | Es el DONANTE informal: range-calendar (79 tokens), month/year-grid (65), pickers (38+4) chupan su vocabulario cross-component → mandato calendar-surface (SYS-8, ya en next-features); chronos beberá de ella |
| 12 | Estados | ✓ | 8 data-attrs por celda/día; readonly/disabled/invalid en provider |
| 13 | Runtime | ✓ | `runtime.trigger('shift-navigate', {targetOverride})` (:328) — el patrón targetOverride correcto para partes doble-registradas |
| 14 | Docs+tests | ✓ | README ×2; tests ✓ |
| 15 | i18n | **hallazgo** | texts + commonRefs localizados ✓; PERO **F-4**: `weekend` = "Saturday or Sunday (weekend in Gregorian)" HARDCODEADO (types :53-54) — el weekend es por-LOCALE, no por calendario (ar-SA/IL = vie/sáb): `Intl.Locale.getWeekInfo()` existe; un framework con locale reactivo pintando `data-weekend` incorrecto en media región del mundo |
| # | Dimensión | Estado | Evidencia |
| --- | -------------------- | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| 1 | Composición | ✓ | 14 partes compositivas (Provider→Grid `<table>`→GridRow `<tr>`→Cell `<td>`→Day); MonthSelect/YearSelect `<select>` nativos; WeekNumber opcional |
| 2 | Naming | ✓ + censo | `type: 'single'\|'multiple'` (provider :63 — range va aparte en range-calendar, split limpio ✓); **`preventDeselect`** (types :112, Radix-style) — nuevo concepto para \_naming; `CalendarView = 'day'\|'month'\|'year'` (:25, el view-switch) |
| 3 | Coherencia semántica | ✓ con cuestión | `commit-select`/`commit-unselect` (affirm, target day) + `shift-navigate` (sin intent ✓ shift); pack propio ✓; **F-5**: `commit-unselect` con intent **affirm** mientras date-field `commit-reset` es neutral y editable `commit-cancel` neutral — ¿la DES-selección es afirmativa? → censo transversal "intent de deshacer" |
| 4 | API | ✓ | min/maxValue + **minViewValue** (:118, límite del view-switch); preventDeselect; isDateHoliday inyectable (types :56) |
| 5 | Tokens | ✓ | Acentos por privados `--_calendar-accent-*` con 8 retunes por color ✓; antecedente B.2 resuelto |
| 6 | Sema | ✓ | Pack propio existe (`sema/components/calendar.ts`) — el único de la familia calendar con carácter |
| 7 | Animaciones | ✓ | Sin keyframes en morfo/recipe leídos |
| 8 | Contrato morfo | ✓ ejemplar con 2 gaps | **TRES razones de no-archetype escritas** (GridRow :248-250 "hover over the entire week bug" · Cell :271-274 chrome de listbox-row · Day :309-313 el item-tint pisaba el fill de selección) — memoria institucional del gotcha archetype-item ×3 ✓; ariaBoolean con nota de compat boolToStr ×6; **F-3**: `data-type` declarado SIN enum (morfo :54) cuando soma tiene unión cerrada (provider :63) — el compilador no puede validar valores |
| 9 | A11y | **2 hallazgos** | Teclado APG-grid COMPLETO en Provider (:70-81: flechas, PageUp/Down mes, Home/End semana, Enter/Space) ✓ — date-field F-1 (Home/End) aquí SÍ está; **F-1**: Provider `role='application'` (:51) — decisión pesada (desactiva el cursor virtual del lector para TODO el árbol) SIN razón documentada, en un morfo que documenta hasta 3 razones de archetype (react-aria la usa en Calendar; bits-ui no — es debate APG real, pero aquí está muda); **F-2**: Day `role='button'` lleva `aria-selected` (:340-344) — ARIA inválido (aria-selected solo soporta gridcell/option/row/tab/treeitem...); el Cell (role=gridcell :277,:292-297) YA la lleva legítimamente |
| 10 | Theming | ✓ | Focus outline (o1) → censo SYS-5; vocabulario de estado de celda rico (selected/today/weekend/holiday/unavailable/outside-month) |
| 11 | Composición interna | **el mandato de familia** | Es el DONANTE informal: range-calendar (79 tokens), month/year-grid (65), pickers (38+4) chupan su vocabulario cross-component → mandato calendar-surface (SYS-8, ya en next-features); chronos beberá de ella |
| 12 | Estados | ✓ | 8 data-attrs por celda/día; readonly/disabled/invalid en provider |
| 13 | Runtime | ✓ | `runtime.trigger('shift-navigate', {targetOverride})` (:328) — el patrón targetOverride correcto para partes doble-registradas |
| 14 | Docs+tests | ✓ | README ×2; tests ✓ |
| 15 | i18n | **hallazgo** | texts + commonRefs localizados ✓; PERO **F-4**: `weekend` = "Saturday or Sunday (weekend in Gregorian)" HARDCODEADO (types :53-54) — el weekend es por-LOCALE, no por calendario (ar-SA/IL = vie/sáb): `Intl.Locale.getWeekInfo()` existe; un framework con locale reactivo pintando `data-weekend` incorrecto en media región del mundo |
## Hallazgos y propuestas
| ID | Hallazgo | Propuesta |
|---|---|---|
| **F-1** | `role='application'` sin razón documentada (morfo :51) | Decisión + doc in-place: mantenerla (estilo react-aria, intercepta flechas en SRs antiguos) documentando el porqué, o bajar a sin-role/`region` (estilo bits-ui) — el teclado ya vive en el grid APG. El barrido censa si otros overlays/grids la usan |
| **F-2** | `aria-selected` sobre `role='button'` (Day :340-344) — ARIA inválido; duplicada con el Cell | Quitar aria-selected del Day (el gridcell la posee) o cambiar Day a aria-pressed si se quiere estado en el botón; validar con el linter ARIA que la máquina use |
| **F-3** | `data-type` sin enum en morfo (unión cerrada en soma :63) | Declarar `enum: ['single','multiple']` en el morfo — el compilador valida y eidos puede selector por valor. Censar más data-attrs sin enum en la familia |
| **F-4** | `weekend` hardcodea sáb/dom (types :53-54) — incorrecto en locales vie/sáb | `$libs/days`: exponer weekInfo por locale (Intl.Locale.getWeekInfo con fallback) y derivar `weekend` de ahí; el hardcode queda como fallback documentado |
| **F-5** | `commit-unselect` intent affirm vs neutral de los deshacer de la familia fields | Censo transversal "intent de deshacer/des-seleccionar" (calendar unselect=affirm · date-field reset=neutral · editable cancel=neutral) → doctrina única en el veredicto |
| F-6 | Marcas holiday/event scoped al host — los prestatarios NO las reciben (antecedente B.2) | Cubierto por el mandato calendar-surface (SYS-8) |
| ID | Hallazgo | Propuesta |
| ------- | ------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **F-1** | `role='application'` sin razón documentada (morfo :51) | Decisión + doc in-place: mantenerla (estilo react-aria, intercepta flechas en SRs antiguos) documentando el porqué, o bajar a sin-role/`region` (estilo bits-ui) — el teclado ya vive en el grid APG. El barrido censa si otros overlays/grids la usan |
| **F-2** | `aria-selected` sobre `role='button'` (Day :340-344) — ARIA inválido; duplicada con el Cell | Quitar aria-selected del Day (el gridcell la posee) o cambiar Day a aria-pressed si se quiere estado en el botón; validar con el linter ARIA que la máquina use |
| **F-3** | `data-type` sin enum en morfo (unión cerrada en soma :63) | Declarar `enum: ['single','multiple']` en el morfo — el compilador valida y eidos puede selector por valor. Censar más data-attrs sin enum en la familia |
| **F-4** | `weekend` hardcodea sáb/dom (types :53-54) — incorrecto en locales vie/sáb | `$libs/days`: exponer weekInfo por locale (Intl.Locale.getWeekInfo con fallback) y derivar `weekend` de ahí; el hardcode queda como fallback documentado |
| **F-5** | `commit-unselect` intent affirm vs neutral de los deshacer de la familia fields | Censo transversal "intent de deshacer/des-seleccionar" (calendar unselect=affirm · date-field reset=neutral · editable cancel=neutral) → doctrina única en el veredicto |
| F-6 | Marcas holiday/event scoped al host — los prestatarios NO las reciben (antecedente B.2) | Cubierto por el mandato calendar-surface (SYS-8) |
## Escalan al sistema
@ -42,4 +42,4 @@
## Veredictos
*(pendiente — checkpoint post-barrido)*
_(pendiente — checkpoint post-barrido)_

@ -4,8 +4,8 @@
- **Capas**: morfo — (composición) · soma — (delega en ToggleGroup) · README eidos ✓ · pack sema — · **Máquina: PASS limpio**
- Decisión 2026-06-27 aplicada ✓: la cardinalidad la POSEE ToggleGroup (`enabledSelections`+`whenFull`) — card-group no la re-implementa.
| Hallazgo | Propuesta |
|---|---|
| Hallazgo | Propuesta |
| ---------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| F-1: composición eidos sin morfo — mismo debate que color-swatch/capas | SYS-7: clasificar formalmente (composición-de-componentes vs átomo vs capa); si el criterio exige justificación escrita, añadirla |
**Escalan**: SYS-7. · **Veredictos**: *(pendiente checkpoint post-barrido)*
**Escalan**: SYS-7. · **Veredictos**: _(pendiente checkpoint post-barrido)_

@ -2,22 +2,22 @@
- **Familia**: display/superficie (Tier B squircle ✓; data-motion-state pilot R-4.5 ✓) · **Método**: solo análisis · demos fuera
- **Capas leídas**: [morfo](../../../src/uix/morfo/components/card.ts) (198 líneas; **1 evento** con `family-default` declarado, apg=0)
- **Máquina**: NEEDS-WORK — `A-1.4` (sin APG para la variante clickable) · `E-2.3` *(su D-4.3 era demo — fuera)*
- **Máquina**: NEEDS-WORK — `A-1.4` (sin APG para la variante clickable) · `E-2.3` _(su D-4.3 era demo — fuera)_
## Dimensiones (evidencia leída)
| # | Dimensión | Estado | Evidencia |
|---|---|---|---|
| 3 | Coherencia semántica | ✓ declarado | 1 evento (la variante interactiva) + family-default ESCRITO — más contrato del que el pass superficial le reconocía ("pack —") |
| 8 | Contrato morfo | hallazgo | **F-1**: sin APG para la variante clickable/link-card (A-1.4) |
| 14 | Docs | gap | Sin README eidos |
| # | Dimensión | Estado | Evidencia |
| --- | -------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------ |
| 3 | Coherencia semántica | ✓ declarado | 1 evento (la variante interactiva) + family-default ESCRITO — más contrato del que el pass superficial le reconocía ("pack —") |
| 8 | Contrato morfo | hallazgo | **F-1**: sin APG para la variante clickable/link-card (A-1.4) |
| 14 | Docs | gap | Sin README eidos |
## Hallazgos y propuestas
| ID | Hallazgo | Propuesta |
|---|---|---|
| ID | Hallazgo | Propuesta |
| ------- | ------------------------------ | --------------------------------------------- |
| **F-1** | APG de la variante interactiva | Declarar (link/button según uso) o justificar |
| **F-2** | README eidos | SYS-4 |
| **F-2** | README eidos | SYS-4 |
## Escalan al sistema
@ -25,4 +25,4 @@ SYS-4 · censo A-1.4.
## Veredictos
*(pendiente — checkpoint post-barrido)*
_(pendiente — checkpoint post-barrido)_

@ -6,16 +6,16 @@
## Dimensiones (evidencia leída)
| # | Dimensión | Estado | Evidencia |
|---|---|---|---|
| 3 | Coherencia semántica | ✓ declarado | family-default escrito (corrección: no es hueco); si el paginado de slides merece carácter → SYS-3 candidato menor |
| 12 | Runtime | candidato D13 | El scroll-snap/medición de slides — verificar dom.measure en provider (censo D13) |
| resto | | ✓ | tests ✓; README ×2 ✓ |
| # | Dimensión | Estado | Evidencia |
| ----- | -------------------- | ------------- | ------------------------------------------------------------------------------------------------------------------ |
| 3 | Coherencia semántica | ✓ declarado | family-default escrito (corrección: no es hueco); si el paginado de slides merece carácter → SYS-3 candidato menor |
| 12 | Runtime | candidato D13 | El scroll-snap/medición de slides — verificar dom.measure en provider (censo D13) |
| resto | | ✓ | tests ✓; README ×2 ✓ |
## Hallazgos y propuestas
| ID | Hallazgo | Propuesta |
|---|---|---|
| ID | Hallazgo | Propuesta |
| ------- | --------------------------- | ----------- |
| **F-1** | ¿Carácter para el paginado? | SYS-3 menor |
## Escalan al sistema
@ -24,4 +24,4 @@ SYS-3 · censo D13 (candidato).
## Veredictos
*(pendiente — checkpoint post-barrido)*
_(pendiente — checkpoint post-barrido)_

@ -3,4 +3,4 @@
- **Fecha**: 2026-07-07 · **Familia**: layout (apilado en cascada) · **Método**: solo análisis
- **Capas**: morfo ✓ (scope eidos) · README eidos ✓ · **Máquina: PASS limpio**.
— limpio. **Escalan**: —. · **Veredictos**: *(pendiente checkpoint post-barrido)*
— limpio. **Escalan**: —. · **Veredictos**: _(pendiente checkpoint post-barrido)_

@ -3,8 +3,8 @@
- **Fecha**: 2026-07-07 · **Familia**: data (sobre `$libs/plots` — Fase 0 matemática hecha; morfo/soma/eidos = la iniciativa registrada) · **Método**: solo análisis
- **Capas**: morfo ✓ · README eidos ✓ · **Máquina: PASS limpio** (en su estado actual de fase temprana).
| Hallazgo | Propuesta |
|---|---|
| Hallazgo | Propuesta |
| ----------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| F-1: componente en fase temprana — su completitud (interacción, a11y de series, CVD de paletas de datos) llegará con las fases de la iniciativa plots | Registrado; no es drift sino roadmap. El hueco CVD de series comparte doctrina con meter (D-3) |
**Escalan**: D-3 (cuando lleguen las series). · **Veredictos**: *(pendiente checkpoint post-barrido)*
**Escalan**: D-3 (cuando lleguen las series). · **Veredictos**: _(pendiente checkpoint post-barrido)_

@ -6,18 +6,18 @@
## Dimensiones (evidencia leída)
| # | Dimensión | Estado | Evidencia |
|---|---|---|---|
| 3 | Coherencia semántica | ✓ **modelo direccional** | DOS eventos estáticos: `commit-toggle-check` **affirm** (:20-25) / `commit-toggle-uncheck` **neutral** (:38-43) — la doctrina "per-event intent is intrinsic" aplicada literalmente. **Dato de censo**: contrasta con el modelo fromProp de switch/toggle (UN evento, intent del consumidor, default neutral) — DOS respuestas de la familia a la misma pregunta "¿el on/off binario tiene dirección intrínseca?" → veredicto de coherencia (ambas razonables; debe quedar escrita la distinción: marcar-hecho ≈ affirm intrínseco vs conmutar-modo ≈ neutral parametrizable) |
| 8 | Contrato morfo | ✓ | APG checkbox; indeterminate/checked/disabled completos; hidden-input form ✓ |
| 10 | Theming | censo | Focus outline → SYS-5; **F-1**: touch-row 44px coarse pendiente (§37 ◇, con switch) |
| 12 | Estados | ✓ | Tri-estado completo |
| resto | | ✓ | pack ✓; tests ✓; README ×2 ✓ |
| # | Dimensión | Estado | Evidencia |
| ----- | -------------------- | ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 3 | Coherencia semántica | ✓ **modelo direccional** | DOS eventos estáticos: `commit-toggle-check` **affirm** (:20-25) / `commit-toggle-uncheck` **neutral** (:38-43) — la doctrina "per-event intent is intrinsic" aplicada literalmente. **Dato de censo**: contrasta con el modelo fromProp de switch/toggle (UN evento, intent del consumidor, default neutral) — DOS respuestas de la familia a la misma pregunta "¿el on/off binario tiene dirección intrínseca?" → veredicto de coherencia (ambas razonables; debe quedar escrita la distinción: marcar-hecho ≈ affirm intrínseco vs conmutar-modo ≈ neutral parametrizable) |
| 8 | Contrato morfo | ✓ | APG checkbox; indeterminate/checked/disabled completos; hidden-input form ✓ |
| 10 | Theming | censo | Focus outline → SYS-5; **F-1**: touch-row 44px coarse pendiente (§37 ◇, con switch) |
| 12 | Estados | ✓ | Tri-estado completo |
| resto | | ✓ | pack ✓; tests ✓; README ×2 ✓ |
## Hallazgos y propuestas
| ID | Hallazgo | Propuesta |
|---|---|---|
| ID | Hallazgo | Propuesta |
| ------- | ---------------------------------- | ------------------------------------------------- |
| **F-1** | Touch-row coarse pendiente (§37 ◇) | Patrón label-row en fase de fixes, junto a switch |
## Escalan al sistema
@ -26,4 +26,4 @@ Censo touch-row · **censo nuevo: modelos de intent en toggles binarios** (check
## Veredictos
*(pendiente — checkpoint post-barrido)*
_(pendiente — checkpoint post-barrido)_

@ -6,19 +6,19 @@
## Dimensiones (evidencia leída)
| # | Dimensión | Estado | Evidencia |
|---|---|---|---|
| 3 | Coherencia semántica | ✓ declarado, candidato fuerte | 2 eventos (copy + confirmación presumible) family-default ESCRITO; el "¡copiado!" sigue siendo el commit.fulfill de manual → SYS-3 candidato natural a ascenso |
| 9 | A11y | hallazgo | **F-1**: trigger sin focus visible (R-1.5) |
| 14 | Docs | gap | Sin README eidos |
| # | Dimensión | Estado | Evidencia |
| --- | -------------------- | ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 3 | Coherencia semántica | ✓ declarado, candidato fuerte | 2 eventos (copy + confirmación presumible) family-default ESCRITO; el "¡copiado!" sigue siendo el commit.fulfill de manual → SYS-3 candidato natural a ascenso |
| 9 | A11y | hallazgo | **F-1**: trigger sin focus visible (R-1.5) |
| 14 | Docs | gap | Sin README eidos |
## Hallazgos y propuestas
| ID | Hallazgo | Propuesta |
|---|---|---|
| **F-1** | Focus del trigger (R-1.5) | Regla del arquetipo trigger |
| **F-2** | README eidos | SYS-4 |
| **F-3** | ¿Asciende a pack? (fulfill de copia) | SYS-3 |
| ID | Hallazgo | Propuesta |
| ------- | ------------------------------------ | --------------------------- |
| **F-1** | Focus del trigger (R-1.5) | Regla del arquetipo trigger |
| **F-2** | README eidos | SYS-4 |
| **F-3** | ¿Asciende a pack? (fulfill de copia) | SYS-3 |
## Escalan al sistema
@ -26,4 +26,4 @@ SYS-3 · SYS-4 · censo R-1.5.
## Veredictos
*(pendiente — checkpoint post-barrido)*
_(pendiente — checkpoint post-barrido)_

@ -3,4 +3,4 @@
- **Fecha**: 2026-07-07 · **Familia**: tipografía (bloques con copy) · **Método**: solo análisis
- **Capas**: morfo ✓ · README eidos ✓ · compone Clipboard para el copy ✓ · **Máquina: PASS limpio**.
— limpio (hereda el R-1.5 de clipboard vía composición: se resuelve allí). **Escalan**: —. · **Veredictos**: *(pendiente checkpoint post-barrido)*
— limpio (hereda el R-1.5 de clipboard vía composición: se resuelve allí). **Escalan**: —. · **Veredictos**: _(pendiente checkpoint post-barrido)_

@ -3,4 +3,4 @@
- **Fecha**: 2026-07-07 · **Familia**: tipografía (inline code; comparte `plain` con Button §19) · **Método**: solo análisis
- **Capas**: morfo ✓ (scope eidos) · README eidos ✓ · `--font-family-mono` ✓ (post-A.9) · **Máquina: PASS limpio**.
— limpio. **Escalan**: —. · **Veredictos**: *(pendiente checkpoint post-barrido)*
— limpio. **Escalan**: —. · **Veredictos**: _(pendiente checkpoint post-barrido)_

@ -6,10 +6,10 @@
## Dimensiones (evidencia leída)
| # | Dimensión | Estado | Evidencia |
|---|---|---|---|
| 3 | Coherencia semántica | ✓ + dato censo | emerge expand/collapse (vs accordion open/close — mismo gesto, verbos distintos → censo) |
| resto | | ✓ | pack con nota doctrinal ✓; tests ✓ |
| # | Dimensión | Estado | Evidencia |
| ----- | -------------------- | -------------- | ---------------------------------------------------------------------------------------- |
| 3 | Coherencia semántica | ✓ + dato censo | emerge expand/collapse (vs accordion open/close — mismo gesto, verbos distintos → censo) |
| resto | | ✓ | pack con nota doctrinal ✓; tests ✓ |
## Hallazgos y propuestas
@ -21,4 +21,4 @@ Censo verbos emerge.
## Veredictos
*(pendiente — checkpoint post-barrido)*
_(pendiente — checkpoint post-barrido)_

@ -7,32 +7,32 @@
## Dimensiones (evidencia leída)
| # | Dimensión | Estado | Evidencia |
|---|---|---|---|
| 1 | Composición | ✓ | Partes compositivas + **FormatSelect** como parte propia (native `<select>` de formato — PrimitiveSelectAttributes, types :14) — composición, no prop-tree |
| 2 | Naming | ✓ conforme + patrón nuevo | `value/onValueChange`, `placeholder/…` ✓; **`format/onFormatChange/allowedFormats`** (types :64-75) — el patrón `X/onXChange/allowedXs` para ejes conmutables, candidato a canon en _naming.md; `enableAlpha` (:77-80) |
| 3 | Coherencia semántica | hallazgo de trío | Solo `commit-set` (verificado) — sin `commit-reset` como time-field → F-1; `onInvalid` con **razones tipadas** (`'custom' \| 'incomplete'`, types :34-38) ✓ mejor que sus hermanos (razón sin tipar) |
| 4 | API | ✓ | Validación estructurada; tipos de `$libs/color` (lib propia, doctrina cero-dep ✓) |
| 5 | Tokens | ✓ con dup | `height-{k}` duplicadas → SYS-6; canales 3ch fijos documentados en css (no reflow 99→100) |
| 6 | Sema | declarado, cuestionado | `family-default` explícito — mismo veredicto de trío que time-field (SYS-3) |
| 7 | Animaciones | ✓ | Patrón familia |
| 8 | Contrato morfo | verificar bloque ARIA | Espejo del trío; **incluir en F-3 de time-field**: ¿su Input lleva el bloque ARIA rico (readonly/invalid) o el pobre de date-field? — unificar los tres en el pass |
| 9 | A11y | con F-2 | Sin Home/End (especialmente útil aquí: canales 0-255/0-360) |
| 10 | Theming | censo | Focus outline → SYS-5 |
| 11 | Composición interna | mandato | Sin wrapper `[data-field]` (SYS-6/B.1) |
| 12 | Estados | ✓ | readonlySegments granular; hidden-input; `allowedFormats` de una entrada = select bloqueado (documentado) |
| 13 | Runtime | ✓ | targetOverride aplicado (antecedente) |
| 14 | Docs+tests | ✓ | README ×2, suite ✓ |
| 15 | i18n | ✓ | texts morfo; formatos por segmento localizados |
| # | Dimensión | Estado | Evidencia |
| --- | -------------------- | ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1 | Composición | ✓ | Partes compositivas + **FormatSelect** como parte propia (native `<select>` de formato — PrimitiveSelectAttributes, types :14) — composición, no prop-tree |
| 2 | Naming | ✓ conforme + patrón nuevo | `value/onValueChange`, `placeholder/…` ✓; **`format/onFormatChange/allowedFormats`** (types :64-75) — el patrón `X/onXChange/allowedXs` para ejes conmutables, candidato a canon en \_naming.md; `enableAlpha` (:77-80) |
| 3 | Coherencia semántica | hallazgo de trío | Solo `commit-set` (verificado) — sin `commit-reset` como time-field → F-1; `onInvalid` con **razones tipadas** (`'custom' \| 'incomplete'`, types :34-38) ✓ mejor que sus hermanos (razón sin tipar) |
| 4 | API | ✓ | Validación estructurada; tipos de `$libs/color` (lib propia, doctrina cero-dep ✓) |
| 5 | Tokens | ✓ con dup | `height-{k}` duplicadas → SYS-6; canales 3ch fijos documentados en css (no reflow 99→100) |
| 6 | Sema | declarado, cuestionado | `family-default` explícito — mismo veredicto de trío que time-field (SYS-3) |
| 7 | Animaciones | ✓ | Patrón familia |
| 8 | Contrato morfo | verificar bloque ARIA | Espejo del trío; **incluir en F-3 de time-field**: ¿su Input lleva el bloque ARIA rico (readonly/invalid) o el pobre de date-field? — unificar los tres en el pass |
| 9 | A11y | con F-2 | Sin Home/End (especialmente útil aquí: canales 0-255/0-360) |
| 10 | Theming | censo | Focus outline → SYS-5 |
| 11 | Composición interna | mandato | Sin wrapper `[data-field]` (SYS-6/B.1) |
| 12 | Estados | ✓ | readonlySegments granular; hidden-input; `allowedFormats` de una entrada = select bloqueado (documentado) |
| 13 | Runtime | ✓ | targetOverride aplicado (antecedente) |
| 14 | Docs+tests | ✓ | README ×2, suite ✓ |
| 15 | i18n | ✓ | texts morfo; formatos por segmento localizados |
## Hallazgos y propuestas
| ID | Hallazgo | Propuesta |
|---|---|---|
| **F-1** | Sin `commit-reset` (limpiar no suena) | Con time-field, en el veredicto de trío |
| **F-2** | Sin Home/End | Pass de familia |
| **F-3** | Bloque ARIA del Input a unificar en el trío | Adoptar el rico de time-field en los tres |
| **F-4** | `height-{k}` duplicadas | SYS-6 |
| ID | Hallazgo | Propuesta |
| ---------- | -------------------------------------------------------------------- | --------------------------------------------------------------------- |
| **F-1** | Sin `commit-reset` (limpiar no suena) | Con time-field, en el veredicto de trío |
| **F-2** | Sin Home/End | Pass de familia |
| **F-3** | Bloque ARIA del Input a unificar en el trío | Adoptar el rico de time-field en los tres |
| **F-4** | `height-{k}` duplicadas | SYS-6 |
| **Nota ✓** | Las razones tipadas de `onInvalid` son MEJOR API que la de date/time | Propagar el patrón al trío en la normalización (nivelar hacia arriba) |
## Escalan al sistema
@ -41,4 +41,4 @@ SYS-3 (trío: expression + reset + ARIA + onInvalid — un solo veredicto de niv
## Veredictos
*(pendiente — checkpoint post-barrido)*
_(pendiente — checkpoint post-barrido)_

@ -6,18 +6,18 @@
## Dimensiones (evidencia leída)
| # | Dimensión | Estado | Evidencia |
|---|---|---|---|
| 1 | Composición | ✓ | Compone `<ColorSwatch>` (átomo del redesign) + área/sliders; presets/save component-owned (decisión 2026-06-28) |
| 3 | Coherencia semántica | ✓ **estrena handle** | 4 eventos: `handle-pick` (:23-26) + `handle-drag` (:32-35) — PRIMERA aparición de la familia handle en el censo (manipulación continua del área/thumb) + `commit-set` **neutral** (:44-49 ✓ canon de fields: fijar valor = neutral) + `commit-reset` neutral; `expression: 'pack'` + pack ✓ COHERENTES (a diferencia de gradient-*) |
| 10 | Theming | ✓ | Focus outline (o4) → censo SYS-5 |
| 12 | Memoria | nota | Parte del redesign constaba "uncommitted" — verificar en fixes que todo lo decidido aterrizó |
| resto | | ✓ | tests ✓; README ×2 ✓ |
| # | Dimensión | Estado | Evidencia |
| ----- | -------------------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| 1 | Composición | ✓ | Compone `<ColorSwatch>` (átomo del redesign) + área/sliders; presets/save component-owned (decisión 2026-06-28) |
| 3 | Coherencia semántica | ✓ **estrena handle** | 4 eventos: `handle-pick` (:23-26) + `handle-drag` (:32-35) — PRIMERA aparición de la familia handle en el censo (manipulación continua del área/thumb) + `commit-set` **neutral** (:44-49 ✓ canon de fields: fijar valor = neutral) + `commit-reset` neutral; `expression: 'pack'` + pack ✓ COHERENTES (a diferencia de gradient-\*) |
| 10 | Theming | ✓ | Focus outline (o4) → censo SYS-5 |
| 12 | Memoria | nota | Parte del redesign constaba "uncommitted" — verificar en fixes que todo lo decidido aterrizó |
| resto | | ✓ | tests ✓; README ×2 ✓ |
## Hallazgos y propuestas
| ID | Hallazgo | Propuesta |
|---|---|---|
| ID | Hallazgo | Propuesta |
| ------- | -------------------------------------- | --------------------------------------------------------------- |
| **F-1** | Posible resto uncommitted del redesign | Diff dirigido contra las decisiones 2026-06-28 en fase de fixes |
## Escalan al sistema
@ -26,4 +26,4 @@ SYS-5 (censo) · censo familia handle (con gradient-builder, image-picker, cropp
## Veredictos
*(pendiente — checkpoint post-barrido)*
_(pendiente — checkpoint post-barrido)_

@ -7,17 +7,17 @@
## Dimensiones (evidencia leída)
| # | Dimensión | Estado | Evidencia |
|---|---|---|---|
| 8 | Contrato morfo | ✓ conforme | Morfo mínimo scope eidos (:19) — el patrón doctrinal para primitivas hoja, cumplido |
| 5/10 | Tokens | ✓ | Swatch con alpha-checkerboard; tokens limpios |
| 14 | Docs | gap de papeleo | Expediente pre-flight (F-1.1–1.4) + sección `## Passive justification` (F-1.5) sin escribir |
| # | Dimensión | Estado | Evidencia |
| ---- | -------------- | -------------- | ------------------------------------------------------------------------------------------- |
| 8 | Contrato morfo | ✓ conforme | Morfo mínimo scope eidos (:19) — el patrón doctrinal para primitivas hoja, cumplido |
| 5/10 | Tokens | ✓ | Swatch con alpha-checkerboard; tokens limpios |
| 14 | Docs | gap de papeleo | Expediente pre-flight (F-1.1–1.4) + sección `## Passive justification` (F-1.5) sin escribir |
## Hallazgos y propuestas
| ID | Hallazgo | Propuesta |
|---|---|---|
| **F-1** | Papeleo pasivo incompleto (F-1.5 + pre-flight) | Escribir `## Passive justification` (átomo display puro consumido por color-picker/gradient-*) + las 4 secciones — solo doc |
| ID | Hallazgo | Propuesta |
| ------- | ---------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| **F-1** | Papeleo pasivo incompleto (F-1.5 + pre-flight) | Escribir `## Passive justification` (átomo display puro consumido por color-picker/gradient-\*) + las 4 secciones — solo doc |
## Escalan al sistema
@ -25,4 +25,4 @@ SYS-7 (ejemplo del átomo BIEN construido a nivel contrato — cita para el crit
## Veredictos
*(pendiente — checkpoint post-barrido)*
_(pendiente — checkpoint post-barrido)_

@ -6,20 +6,20 @@
## Dimensiones (evidencia leída)
| # | Dimensión | Estado | Evidencia |
|---|---|---|---|
| 1 | Composición | ✓ | Provider/Input/Trigger/ClearButton/Content(+Item…) — el ClearButton como parte propia (:157) |
| 3 | Coherencia semántica | ✓ completa | 4 eventos: commit-select/unselect (affirm) + emerge-open/dismiss + `expression: 'pack'` + pack ✓; unselect=affirm → censo consistencia ×3 |
| 8 | Contrato morfo | ✓ ejemplar | Input `role='combobox'` + `aria-activedescendant` (:107) + **`aria-autocomplete='list'`** (:108) — el triplete APG correcto; listbox/option (:180-215) |
| 9 | A11y | ✓ | Teclado :117-123: flechas/Home/End/Enter/Escape + **Backspace remove-last** (borrado de chips multi-valor declarado en contrato) ✓ |
| 10 | Theming | ✓ | Focus outline (o7: input+listbox+items) → SYS-5; depth ×2 |
| resto | | ✓ | Multi/single, filtrado, creación; tests ✓; README ×2 ✓ |
| # | Dimensión | Estado | Evidencia |
| ----- | -------------------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| 1 | Composición | ✓ | Provider/Input/Trigger/ClearButton/Content(+Item…) — el ClearButton como parte propia (:157) |
| 3 | Coherencia semántica | ✓ completa | 4 eventos: commit-select/unselect (affirm) + emerge-open/dismiss + `expression: 'pack'` + pack ✓; unselect=affirm → censo consistencia ×3 |
| 8 | Contrato morfo | ✓ ejemplar | Input `role='combobox'` + `aria-activedescendant` (:107) + **`aria-autocomplete='list'`** (:108) — el triplete APG correcto; listbox/option (:180-215) |
| 9 | A11y | ✓ | Teclado :117-123: flechas/Home/End/Enter/Escape + **Backspace remove-last** (borrado de chips multi-valor declarado en contrato) ✓ |
| 10 | Theming | ✓ | Focus outline (o7: input+listbox+items) → SYS-5; depth ×2 |
| resto | | ✓ | Multi/single, filtrado, creación; tests ✓; README ×2 ✓ |
## Hallazgos y propuestas
| ID | Hallazgo | Propuesta |
|---|---|---|
| — | Sin hallazgos de componente en las capas leídas (el chip-drift era demo, fuera de alcance) | El más limpio de la familia selección |
| ID | Hallazgo | Propuesta |
| --- | ------------------------------------------------------------------------------------------ | ------------------------------------- |
| — | Sin hallazgos de componente en las capas leídas (el chip-drift era demo, fuera de alcance) | El más limpio de la familia selección |
## Escalan al sistema
@ -27,4 +27,4 @@ Censo "unselect=affirm" ×3.
## Veredictos
*(pendiente — checkpoint post-barrido)*
_(pendiente — checkpoint post-barrido)_

@ -7,20 +7,20 @@
## Dimensiones (evidencia leída)
| # | Dimensión | Estado | Evidencia |
|---|---|---|---|
| 1 | Composición | ✓ completa | Anatomía palette entera: Input/List/Viewport/Item/**LinkItem**/Group/GroupHeading/GroupItems/**Empty**/**Loading**/Separator (:34-219) — estados vacío/cargando como partes ✓ |
| 3 | Coherencia semántica | ✓ **razonada con el libro** | `commit-submit-invoke` affirm (:22-27) con la cita exacta: cap. 23 `commit.submit` + cap. 22 §8 — "the command's actual outcome fires downstream; celebrating at the click is *celebrate before time*. Same precedent as Button". `expression: "family-default"` (:9) = TERCERA delegación-a-default documentada (con field-langs y button) → la lista "default legítimo" del veredicto SYS-3 |
| 8 | Contrato morfo | ✓ | APG combobox citado (:8) — el patrón correcto para palette |
| 14 | Docs+tests | gap | Sin README eidos (E-2.3) → SYS-4; tests ✓ |
| resto | | ✓ | list-surface ✓; squircle Tier A ✓ |
| # | Dimensión | Estado | Evidencia |
| ----- | -------------------- | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1 | Composición | ✓ completa | Anatomía palette entera: Input/List/Viewport/Item/**LinkItem**/Group/GroupHeading/GroupItems/**Empty**/**Loading**/Separator (:34-219) — estados vacío/cargando como partes ✓ |
| 3 | Coherencia semántica | ✓ **razonada con el libro** | `commit-submit-invoke` affirm (:22-27) con la cita exacta: cap. 23 `commit.submit` + cap. 22 §8 — "the command's actual outcome fires downstream; celebrating at the click is _celebrate before time_. Same precedent as Button". `expression: "family-default"` (:9) = TERCERA delegación-a-default documentada (con field-langs y button) → la lista "default legítimo" del veredicto SYS-3 |
| 8 | Contrato morfo | ✓ | APG combobox citado (:8) — el patrón correcto para palette |
| 14 | Docs+tests | gap | Sin README eidos (E-2.3) → SYS-4; tests ✓ |
| resto | | ✓ | list-surface ✓; squircle Tier A ✓ |
## Hallazgos y propuestas
| ID | Hallazgo | Propuesta |
|---|---|---|
| **F-1** | README eidos ausente | SYS-4 |
| ~~F-2~~ | *(retirado — el family-default está razonado con citas del libro; ver dim 3)* | Citar command en el veredicto SYS-3 como ejemplo de default legítimo |
| ID | Hallazgo | Propuesta |
| ------- | ----------------------------------------------------------------------------- | -------------------------------------------------------------------- |
| **F-1** | README eidos ausente | SYS-4 |
| ~~F-2~~ | _(retirado — el family-default está razonado con citas del libro; ver dim 3)_ | Citar command en el veredicto SYS-3 como ejemplo de default legítimo |
## Escalan al sistema
@ -28,4 +28,4 @@ SYS-4 · SYS-3 (tercer ejemplo documentado de default legítimo).
## Veredictos
*(pendiente — checkpoint post-barrido)*
_(pendiente — checkpoint post-barrido)_

@ -1,11 +1,11 @@
# container — ficha de auditoría de componente
- **Fecha**: 2026-07-07 · **Familia**: layout · **Método**: solo análisis
- **Capas**: morfo ✓ (scope eidos) · README eidos ✓ · **Máquina: PASS** con `D-7.4` (*chip drift en demo*).
- **Capas**: morfo ✓ (scope eidos) · README eidos ✓ · **Máquina: PASS** con `D-7.4` (_chip drift en demo_).
- **Antecedente (Fase 1 A.2)**: su max-width fantasma (`--layout-container-width-xl, 80rem`) murió; hoy `var(--container-width-xl)` → breakpoints ✓ verificado en vivo.
| Hallazgo | Propuesta |
|---|---|
| Hallazgo | Propuesta |
| ----------------------- | ------------------- |
| F-1: chips desalineados | Pass D-7.4 conjunto |
**Escalan**: censo D-7.4. · **Veredictos**: *(pendiente checkpoint post-barrido)*
**Escalan**: censo D-7.4. · **Veredictos**: _(pendiente checkpoint post-barrido)_

@ -6,11 +6,11 @@
## Dimensiones (evidencia leída)
| # | Dimensión | Estado | Evidencia |
|---|---|---|---|
| 3 | Coherencia semántica | ✓ | open/close/select — gemelo exacto de dropdown-menu ✓ coherencia de par; pack ✓ |
| 8 | Contrato morfo | ✓ | Long-press táctil, posicionado en puntero |
| resto | | ✓ | depth ×3; list-surface ✓; tests ✓ |
| # | Dimensión | Estado | Evidencia |
| ----- | -------------------- | ------ | ------------------------------------------------------------------------------ |
| 3 | Coherencia semántica | ✓ | open/close/select — gemelo exacto de dropdown-menu ✓ coherencia de par; pack ✓ |
| 8 | Contrato morfo | ✓ | Long-press táctil, posicionado en puntero |
| resto | | ✓ | depth ×3; list-surface ✓; tests ✓ |
## Hallazgos y propuestas
@ -22,4 +22,4 @@ Censo verbos emerge (open/close — menús coherentes entre sí).
## Veredictos
*(pendiente — checkpoint post-barrido)*
_(pendiente — checkpoint post-barrido)_

@ -6,21 +6,21 @@
## Dimensiones (evidencia leída)
| # | Dimensión | Estado | Evidencia |
|---|---|---|---|
| 2 | Naming | hallazgo SYS-1 | **F-1: 8 hooks-clase** — el MAYOR ofensor del catálogo (button 6, image-picker 6) |
| 3 | Coherencia semántica | ✓ con desajuste | `handle-drag`/`handle-resize`/`handle-zoom` (:31-63 ✓ censo handle) + commit affirm (:64-69); **F-2**: el evento se llama `commit-crop` pero su verb es `'apply'` (:64-67) — el nombre rompe `{familia}-{verbo}` (sería commit-apply) y la regla A-3.6 no lo flagueó (cuarto agujero de regla) |
| 8 | Contrato morfo | hallazgo | **F-3**: sin cita `apg:` (censo = 0) con PASS — el A-1.4 tampoco lo cazó; caso "sin patrón oficial" |
| 12 | Runtime | pendiente familia | Candidato del censo D13 (write-then-read): sus gestos miden el box — verificar `dom.measure` en provider al ejecutar |
| resto | | ✓ | Gestos, aspect locks, teclado de nudge; pack ✓; tests ✓ |
| # | Dimensión | Estado | Evidencia |
| ----- | -------------------- | ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 2 | Naming | hallazgo SYS-1 | **F-1: 8 hooks-clase** — el MAYOR ofensor del catálogo (button 6, image-picker 6) |
| 3 | Coherencia semántica | ✓ con desajuste | `handle-drag`/`handle-resize`/`handle-zoom` (:31-63 ✓ censo handle) + commit affirm (:64-69); **F-2**: el evento se llama `commit-crop` pero su verb es `'apply'` (:64-67) — el nombre rompe `{familia}-{verbo}` (sería commit-apply) y la regla A-3.6 no lo flagueó (cuarto agujero de regla) |
| 8 | Contrato morfo | hallazgo | **F-3**: sin cita `apg:` (censo = 0) con PASS — el A-1.4 tampoco lo cazó; caso "sin patrón oficial" |
| 12 | Runtime | pendiente familia | Candidato del censo D13 (write-then-read): sus gestos miden el box — verificar `dom.measure` en provider al ejecutar |
| resto | | ✓ | Gestos, aspect locks, teclado de nudge; pack ✓; tests ✓ |
## Hallazgos y propuestas
| ID | Hallazgo | Propuesta |
|---|---|---|
| **F-1** | 8 hooks-clase | Codemod SYS-1 |
| ~~F-2~~ | *(RETIRADO en P1: `apply` ES canónico — extensión de autor, verbs.ts :97 — y `commit-crop` es etiqueta de dominio autorizada por el libro cap. 8 §1; vocab-check lo lista como warn de descubribilidad, no violación. Rename a `commit-apply-crop` = pulido opcional)* | — |
| **F-3** | Sin APG (regla no cazó) | Regla "apg: none — rationale" + fix del script |
| ID | Hallazgo | Propuesta |
| ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- |
| **F-1** | 8 hooks-clase | Codemod SYS-1 |
| ~~F-2~~ | _(RETIRADO en P1: `apply` ES canónico — extensión de autor, verbs.ts :97 — y `commit-crop` es etiqueta de dominio autorizada por el libro cap. 8 §1; vocab-check lo lista como warn de descubribilidad, no violación. Rename a `commit-apply-crop` = pulido opcional)_ | — |
| **F-3** | Sin APG (regla no cazó) | Regla "apg: none — rationale" + fix del script |
## Escalan al sistema
@ -28,4 +28,4 @@ SYS-1 (top) · censos A-3.6/A-1.4 (agujeros del script ×4 ya) · censo D13 (can
## Veredictos
*(pendiente — checkpoint post-barrido)*
_(pendiente — checkpoint post-barrido)_

@ -7,17 +7,17 @@
## Dimensiones — deltas
| Dim | Estado | Nota |
|---|---|---|
| 5/10 | ✓ | CSS = stub (§34, spin-field lleva el visual); focus o0 correcto |
| 6 sema | ✓ | Pack propio (fue el caso que fijó la doctrina commit-set por unidad) |
| 2/4 API | ✓ | Unidades (px/rem/%…) + scrubber — bajo revisión del usuario |
| 11 | ✓ | Consumidor de la capa spin-field |
| Dim | Estado | Nota |
| ------- | ------ | -------------------------------------------------------------------- |
| 5/10 | ✓ | CSS = stub (§34, spin-field lleva el visual); focus o0 correcto |
| 6 sema | ✓ | Pack propio (fue el caso que fijó la doctrina commit-set por unidad) |
| 2/4 API | ✓ | Unidades (px/rem/%…) + scrubber — bajo revisión del usuario |
| 11 | ✓ | Consumidor de la capa spin-field |
## Hallazgos y propuestas
| ID | Hallazgo | Propuesta |
|---|---|---|
| ID | Hallazgo | Propuesta |
| --- | ------------------------------------------- | -------------------------------- |
| F-1 | Nada propio a nivel análisis (WIP en curso) | Re-pasar tras el WIP del usuario |
## Escalan al sistema
@ -26,4 +26,4 @@ SYS-7 (consumidor de capa).
## Veredictos
*(pendiente — checkpoint post-barrido; re-visitar tras el WIP)*
_(pendiente — checkpoint post-barrido; re-visitar tras el WIP)_

@ -4,45 +4,45 @@
- **Método**: solo análisis — fixes tras el barrido completo; la ficha registra hallazgos + propuestas de solución (locales y las que escalan al sistema).
- **Tier**: campo compuesto (segmentos) · **Morfo scope**: `['soma','sema','eidos']` · **Familia**: fields
- **Capas**: [morfo](../../../src/uix/morfo/components/date-field.ts) · [soma](../../../src/uix/soma/components/date-field/) · [eidos](../../../src/uix/eidos/components/date-field/) · [sema pack](../../../src/uix/sema/components/date-field.ts) ✓
- **Máquina** (`component:audit --only date-field`): **PASS** — R-rules limpias. *(Reglas D-\* de demo excluidas — corrección de alcance 2026-07-07.)*
- **Máquina** (`component:audit --only date-field`): **PASS** — R-rules limpias. _(Reglas D-\* de demo excluidas — corrección de alcance 2026-07-07.)_
- **Vigencia re-auditoría**: ficha piloto — YA a profundidad de referencia; este retrofit solo extrae las demos del alcance.
## Tabla de dimensiones
| # | Dimensión | Estado | Evidencia / nota |
|---|---|---|---|
| 1 | Composición vs declaración | ✓ | Partes compositivas (`Provider/Input/Segment/Label` como children); snippet `segments` ordenados para render libre |
| 2 | Naming de props | ✓ | `value/onValueChange` + `placeholder/onPlaceholderChange` (patrón bindable canónico); `minValue/maxValue`; `readonlySegments`; `kind` ⊥ `granularity` con la ortogonalidad DOCUMENTADA (consistencia de trío) |
| 3 | Coherencia semántica | ✓ | `commit-set`/`commit-reset` post, intent neutral (canon de fields); expression `'pack'` |
| 4 | API normalizada | ✓ | Bindables declarados; `validate`/`onInvalid` (Standard-Schema-friendly); `locale` con fallback reactivo `soma.langs`; `dir` RTL invierte flechas; `hourCycle` con cadena de fallbacks |
| 5 | Tokens usados | ✓ | CSS consume SOLO sus tokens de recipe (`--date-field-*`) — TSC-canónico; segment-height fantasma eliminado en auditoría B.1 (antecedente resuelto) |
| 6 | Parte semántica | ✓ ejemplar | Pack con `semaSelector` tipado, targets al part `input` (nota de dónde estampa el engine), tunings COMPUESTOS (`form.commit.soft` / `subtle` + delta `{op:'add', -80}` + contour) — el patrón de doctrina exacto |
| 7 | Animaciones | ✓ | Transición SOLO de background con razón documentada (border-color instantáneo: el increment provoca blur/refocus y un border transicionado parpadea) |
| 8 | Contrato morfo | ✓ | APG spinbutton enlazado; `role='group'` en Input + `role='spinbutton'` por segmento con `aria-value{min,max,now,text}` completos; teclado declarado; `ariaBoolean` para aria-disabled con nota de por qué |
| 9 | Accesibilidad | ✓ con hallazgo | Labels/`aria-labelledby` condicionales por part-present; `errorMessageId` → describedby; **F-1**: faltan `Home`/`End` (APG spinbutton: saltar a min/max) |
| 10 | Adopción theming | hallazgo doctrinal | Focus = **outline flush** (`:has(segment:focus-visible)` + border swap) con razón técnica sólida — pero la doctrina §32 vigente dice "los CAMPOS quedan en box-shadow (anillo interior parametrizable)" → **S-1**. State-layer de segmentos vía capa compartida ✓ (`data-field-segment` estampado en soma) |
| 11 | Composición interna | **el mandato** | `FieldProvider` consumido en soma (merge) ✓ — pero **sin wrapper Field a nivel DOM/eidos**: `[data-field][data-size]` ausente (sondado en la familia), Label propio en vez de la base Field → **S-2** (mandato B.1 ya registrado) |
| 12 | Estados y ciclo | ✓ | invalid/disabled/readonly/required en data-attrs por parte; `readonlySegments` granular; hidden-input para FormData (`name` + ISO) ✓; controlled/uncontrolled ✓ |
| 13 | Disciplina runtime | ✓ | 0 timers/listeners crudos a nivel grep en 57KB de provider; memoria institucional dentro (incidencia range-placeholder 2026-05-20 #1 documentada con su porqué) |
| 14 | ~~Demo testbed~~ | fuera de alcance | Demos excluidas de la auditoría (corrección 2026-07-07) |
| 15 | Docs + tests | ✓ | README en AMBOS niveles (soma 14KB con `## Sema events`; eidos 4KB) — el patrón que S-4 de button propone ratificar; tests de provider (8KB) ✓ |
| 16 | i18n | ✓ | `langs.ts` propio; `texts` de morfo localizados; formatter por `locale` reactivo; tipos `$libs/days` (doctrina, nunca @internationalized/date) |
| # | Dimensión | Estado | Evidencia / nota |
| --- | -------------------------- | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1 | Composición vs declaración | ✓ | Partes compositivas (`Provider/Input/Segment/Label` como children); snippet `segments` ordenados para render libre |
| 2 | Naming de props | ✓ | `value/onValueChange` + `placeholder/onPlaceholderChange` (patrón bindable canónico); `minValue/maxValue`; `readonlySegments`; `kind` ⊥ `granularity` con la ortogonalidad DOCUMENTADA (consistencia de trío) |
| 3 | Coherencia semántica | ✓ | `commit-set`/`commit-reset` post, intent neutral (canon de fields); expression `'pack'` |
| 4 | API normalizada | ✓ | Bindables declarados; `validate`/`onInvalid` (Standard-Schema-friendly); `locale` con fallback reactivo `soma.langs`; `dir` RTL invierte flechas; `hourCycle` con cadena de fallbacks |
| 5 | Tokens usados | ✓ | CSS consume SOLO sus tokens de recipe (`--date-field-*`) — TSC-canónico; segment-height fantasma eliminado en auditoría B.1 (antecedente resuelto) |
| 6 | Parte semántica | ✓ ejemplar | Pack con `semaSelector` tipado, targets al part `input` (nota de dónde estampa el engine), tunings COMPUESTOS (`form.commit.soft` / `subtle` + delta `{op:'add', -80}` + contour) — el patrón de doctrina exacto |
| 7 | Animaciones | ✓ | Transición SOLO de background con razón documentada (border-color instantáneo: el increment provoca blur/refocus y un border transicionado parpadea) |
| 8 | Contrato morfo | ✓ | APG spinbutton enlazado; `role='group'` en Input + `role='spinbutton'` por segmento con `aria-value{min,max,now,text}` completos; teclado declarado; `ariaBoolean` para aria-disabled con nota de por qué |
| 9 | Accesibilidad | ✓ con hallazgo | Labels/`aria-labelledby` condicionales por part-present; `errorMessageId` → describedby; **F-1**: faltan `Home`/`End` (APG spinbutton: saltar a min/max) |
| 10 | Adopción theming | hallazgo doctrinal | Focus = **outline flush** (`:has(segment:focus-visible)` + border swap) con razón técnica sólida — pero la doctrina §32 vigente dice "los CAMPOS quedan en box-shadow (anillo interior parametrizable)" → **S-1**. State-layer de segmentos vía capa compartida ✓ (`data-field-segment` estampado en soma) |
| 11 | Composición interna | **el mandato** | `FieldProvider` consumido en soma (merge) ✓ — pero **sin wrapper Field a nivel DOM/eidos**: `[data-field][data-size]` ausente (sondado en la familia), Label propio en vez de la base Field → **S-2** (mandato B.1 ya registrado) |
| 12 | Estados y ciclo | ✓ | invalid/disabled/readonly/required en data-attrs por parte; `readonlySegments` granular; hidden-input para FormData (`name` + ISO) ✓; controlled/uncontrolled ✓ |
| 13 | Disciplina runtime | ✓ | 0 timers/listeners crudos a nivel grep en 57KB de provider; memoria institucional dentro (incidencia range-placeholder 2026-05-20 #1 documentada con su porqué) |
| 14 | ~~Demo testbed~~ | fuera de alcance | Demos excluidas de la auditoría (corrección 2026-07-07) |
| 15 | Docs + tests | ✓ | README en AMBOS niveles (soma 14KB con `## Sema events`; eidos 4KB) — el patrón que S-4 de button propone ratificar; tests de provider (8KB) ✓ |
| 16 | i18n | ✓ | `langs.ts` propio; `texts` de morfo localizados; formatter por `locale` reactivo; tipos `$libs/days` (doctrina, nunca @internationalized/date) |
## Hallazgos y propuestas de solución — del componente
| ID | Hallazgo | Propuesta de solución |
|---|---|---|
| **F-1** | Teclado de segmento sin `Home`/`End` (APG spinbutton los recomienda: saltar a `aria-valuemin`/`max`) | Añadir `{ key: 'Home', action: 'set-min' }` / `{ key: 'End', action: 'set-max' }` al morfo + implementación en provider; extensivo a time-field/color-field (misma familia de segmentos) |
| **F-2** | El outline de focus lleva `outline-offset: 0` hardcodeado (razonado: flush, sin hueco) y no participa `--focus-ring-inner-width` | Sin acción si S-1 canoniza el modelo outline-flush para segment-fields (el 0 es semántica del modelo, anotarlo como literal razonado); si S-1 devuelve a box-shadow, se resuelve solo |
| **F-3** | Alturas re-declaradas: el recipe date-field duplica `height-{xs..xl}` = `var(--size-{k}-control-height)` que la familia field ya expone | Cubierta por **S-2** (des-duplicación de familia — mandato B.1) |
| ID | Hallazgo | Propuesta de solución |
| ------- | --------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **F-1** | Teclado de segmento sin `Home`/`End` (APG spinbutton los recomienda: saltar a `aria-valuemin`/`max`) | Añadir `{ key: 'Home', action: 'set-min' }` / `{ key: 'End', action: 'set-max' }` al morfo + implementación en provider; extensivo a time-field/color-field (misma familia de segmentos) |
| **F-2** | El outline de focus lleva `outline-offset: 0` hardcodeado (razonado: flush, sin hueco) y no participa `--focus-ring-inner-width` | Sin acción si S-1 canoniza el modelo outline-flush para segment-fields (el 0 es semántica del modelo, anotarlo como literal razonado); si S-1 devuelve a box-shadow, se resuelve solo |
| **F-3** | Alturas re-declaradas: el recipe date-field duplica `height-{xs..xl}` = `var(--size-{k}-control-height)` que la familia field ya expone | Cubierta por **S-2** (des-duplicación de familia — mandato B.1) |
## Hallazgos que escalan al sistema / theming
| ID | Hallazgo | Propuesta |
|---|---|---|
| **S-1** | **Doctrina §32 vs realidad de los segment-fields**: §32/changelog dicen "los campos quedan en box-shadow (anillo interior parametrizable)", pero date-field migró a **outline flush** con razón técnica sólida y documentada (un border/box-shadow transicionado parpadea en cada increment por el blur/refocus del segmento; el outline sobrevive forced-colors). Afecta a toda la familia de segment-fields (date/time/color y sus range) | **Decisión doctrinal** (checkpoint post-barrido): (a) matizar §32 — *text-fields = dos anillos box-shadow; segment-fields = outline flush* (canonizar la razón del flicker, nota fechada en changelog §32) — **recomendada**; o (b) devolver los segment-fields a box-shadow resolviendo el flicker de otra forma. El barrido debe censar qué hace cada field (time/color/search/password/mask) para dimensionar |
| **S-2** | **Composición Field (mandato B.1, evidencia por-componente)**: el soma participa de `FieldProvider` (merge ✓) pero el DOM no envuelve en `[data-field][data-size]`; Label propio; alturas duplicadas; el token de familia `--field-segment-height` (size-driven, TSC scope `size:`) no puede aterrizar hasta esto | Ya mandatado en `next-features.md`: incorporar la base Field (wrapper + label/helper/error), token de familia con scope `size:`, morir las copias `height-{k}` y `segment-height` per-componente. Esta ficha aporta la lista concreta de piezas de date-field a tocar |
| ID | Hallazgo | Propuesta |
| ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **S-1** | **Doctrina §32 vs realidad de los segment-fields**: §32/changelog dicen "los campos quedan en box-shadow (anillo interior parametrizable)", pero date-field migró a **outline flush** con razón técnica sólida y documentada (un border/box-shadow transicionado parpadea en cada increment por el blur/refocus del segmento; el outline sobrevive forced-colors). Afecta a toda la familia de segment-fields (date/time/color y sus range) | **Decisión doctrinal** (checkpoint post-barrido): (a) matizar §32 — _text-fields = dos anillos box-shadow; segment-fields = outline flush_ (canonizar la razón del flicker, nota fechada en changelog §32) — **recomendada**; o (b) devolver los segment-fields a box-shadow resolviendo el flicker de otra forma. El barrido debe censar qué hace cada field (time/color/search/password/mask) para dimensionar |
| **S-2** | **Composición Field (mandato B.1, evidencia por-componente)**: el soma participa de `FieldProvider` (merge ✓) pero el DOM no envuelve en `[data-field][data-size]`; Label propio; alturas duplicadas; el token de familia `--field-segment-height` (size-driven, TSC scope `size:`) no puede aterrizar hasta esto | Ya mandatado en `next-features.md`: incorporar la base Field (wrapper + label/helper/error), token de familia con scope `size:`, morir las copias `height-{k}` y `segment-height` per-componente. Esta ficha aporta la lista concreta de piezas de date-field a tocar |
## Veredictos
*(pendiente — checkpoint único post-barrido)*
_(pendiente — checkpoint único post-barrido)_

@ -6,21 +6,21 @@
## Dimensiones (evidencia leída)
| # | Dimensión | Estado | Evidencia |
|---|---|---|---|
| 1 | Composición | ✓ **el patrón canónico** | Compone date-field + calendar + Popover (de-dialoged 2026-06-27: Popover = único `role=dialog`) ✓; partes propias solo para lo suyo (Trigger con `aria-haspopup=dialog`, MonthView/YearView del view-switch) |
| 3 | Coherencia semántica | ✓ **la referencia SYS-11** | **`expression: "delegated"`** (:18 — el canon 2026-05-26 aplicado) + UN evento propio `commit-reset` neutral (:30-36) = exactamente la regla "el compuesto declara solo los gestos que el hijo no posee". Los commit-select/set suenan por los embebidos (date-field pack ✓ tuneado — este picker suena bien HOY) |
| 8 | Contrato morfo | ✓ | apg ×2 (dialog + grid); censo de literales ingleses: LIMPIO (a diferencia del drp) |
| 12 | Estados | hallazgo máquina | R-1.3 readonly sin materializar (patrón familia) |
| 11 | Composición interna | ✓ menor | Borrower menor de calendar (4 tokens) — SYS-8 lo absorbe |
| 6 | Sema | ✓ by-design | Delegado; la asimetría del trío (SYS-3) le afectará cuando exista time-picker equivalente |
| resto | | ✓ | Hereda contratos de los embebidos; tests ✓; README ×2 ✓ |
| # | Dimensión | Estado | Evidencia |
| ----- | -------------------- | -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1 | Composición | ✓ **el patrón canónico** | Compone date-field + calendar + Popover (de-dialoged 2026-06-27: Popover = único `role=dialog`) ✓; partes propias solo para lo suyo (Trigger con `aria-haspopup=dialog`, MonthView/YearView del view-switch) |
| 3 | Coherencia semántica | ✓ **la referencia SYS-11** | **`expression: "delegated"`** (:18 — el canon 2026-05-26 aplicado) + UN evento propio `commit-reset` neutral (:30-36) = exactamente la regla "el compuesto declara solo los gestos que el hijo no posee". Los commit-select/set suenan por los embebidos (date-field pack ✓ tuneado — este picker suena bien HOY) |
| 8 | Contrato morfo | ✓ | apg ×2 (dialog + grid); censo de literales ingleses: LIMPIO (a diferencia del drp) |
| 12 | Estados | hallazgo máquina | R-1.3 readonly sin materializar (patrón familia) |
| 11 | Composición interna | ✓ menor | Borrower menor de calendar (4 tokens) — SYS-8 lo absorbe |
| 6 | Sema | ✓ by-design | Delegado; la asimetría del trío (SYS-3) le afectará cuando exista time-picker equivalente |
| resto | | ✓ | Hereda contratos de los embebidos; tests ✓; README ×2 ✓ |
## Hallazgos y propuestas
| ID | Hallazgo | Propuesta |
|---|---|---|
| **F-1** | readonly sin estilo (R-1.3) | Patrón familia (composición Field, SYS-6) |
| ID | Hallazgo | Propuesta |
| ----------- | ---------------------------------------------------------------------------------------- | ------------------------------------------ |
| **F-1** | readonly sin estilo (R-1.3) | Patrón familia (composición Field, SYS-6) |
| **Nota ✓✓** | `expression: 'delegated'` + evento-propio-mínimo = EL ejemplo a citar en el canon SYS-11 | Referencia para el fix de los field-ranges |
## Escalan al sistema
@ -29,4 +29,4 @@ SYS-11 (ejemplo positivo) · SYS-3 (herencia sonora) · censo R-1.3 · SYS-8 (bo
## Veredictos
*(pendiente — checkpoint post-barrido)*
_(pendiente — checkpoint post-barrido)_

@ -7,28 +7,28 @@
## Dimensiones (evidencia leída)
| # | Dimensión | Estado | Evidencia |
|---|---|---|---|
| 1 | Composición | ✓ ejemplar | Cada endpoint es un DateField COMPLETO ligado a `provider.startValue/endValue` (README :44); `Segment` re-export directo del single (exports :5-7) — cero re-implementación de la maquinaria de segmentos; validación/placeholder/granularity/locale compartidos simétricamente |
| 2 | Naming | ✓ + dato de censo | `value: DateRange` + `onValueChange` ✓; **`onStartValueChange`/`onEndValueChange`** — PRIMER patrón de callbacks por sub-valor del catálogo (censar en otros dobles); `placeholder` compartido único (la incidencia 2026-05-20 #1 — el END auto-paginaba al START — documentada en el provider del single con la regla `false` en endpoints) |
| 3 | Coherencia semántica | ✓ delegada + **cuestión de diseño** | El morfo propio declara 0 eventos: la semántica vive en los singles embebidos (cada endpoint comete su `commit-set` al fijarse). **F-1**: NO existe evento de *rango completo* — fijar el segundo extremo (el momento terminal del gesto, cuando `{start,end}` queda sellado) suena igual que fijar el primero. ¿Debe el sellado del par tener su propio commit (fulfill) o bastan los dos del single? → veredicto |
| 4 | API | ✓ | `validate: DateRangeValidator` + `onInvalid: DateOnInvalid` + min/max; hereda la razón de invalidez SIN tipar del single (censo validación) |
| 6 | Sema | condicionada | Sin pack propio (correcto: delega); el carácter depende del pack del single embebido → date ✓ tuneado. La decisión SYS-3 del trío debe cubrir los ranges explícitamente |
| 8 | Contrato morfo | ✓ | APG spinbutton citado; ARIA heredada de los segments del single (README :58) |
| 5, 7, 9-15 | | heredan del single | Wrapper de composición: tokens/recipe/i18n/a11y = los de date-field; focus delegado a los embebidos ✓ |
| # | Dimensión | Estado | Evidencia |
| ---------- | -------------------- | ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| 1 | Composición | ✓ ejemplar | Cada endpoint es un DateField COMPLETO ligado a `provider.startValue/endValue` (README :44); `Segment` re-export directo del single (exports :5-7) — cero re-implementación de la maquinaria de segmentos; validación/placeholder/granularity/locale compartidos simétricamente |
| 2 | Naming | ✓ + dato de censo | `value: DateRange` + `onValueChange` ✓; **`onStartValueChange`/`onEndValueChange`** — PRIMER patrón de callbacks por sub-valor del catálogo (censar en otros dobles); `placeholder` compartido único (la incidencia 2026-05-20 #1 — el END auto-paginaba al START — documentada en el provider del single con la regla `false` en endpoints) |
| 3 | Coherencia semántica | ✓ delegada + **cuestión de diseño** | El morfo propio declara 0 eventos: la semántica vive en los singles embebidos (cada endpoint comete su `commit-set` al fijarse). **F-1**: NO existe evento de _rango completo_ — fijar el segundo extremo (el momento terminal del gesto, cuando `{start,end}` queda sellado) suena igual que fijar el primero. ¿Debe el sellado del par tener su propio commit (fulfill) o bastan los dos del single? → veredicto |
| 4 | API | ✓ | `validate: DateRangeValidator` + `onInvalid: DateOnInvalid` + min/max; hereda la razón de invalidez SIN tipar del single (censo validación) |
| 6 | Sema | condicionada | Sin pack propio (correcto: delega); el carácter depende del pack del single embebido → date ✓ tuneado. La decisión SYS-3 del trío debe cubrir los ranges explícitamente |
| 8 | Contrato morfo | ✓ | APG spinbutton citado; ARIA heredada de los segments del single (README :58) |
| 5, 7, 9-15 | | heredan del single | Wrapper de composición: tokens/recipe/i18n/a11y = los de date-field; focus delegado a los embebidos ✓ |
## Hallazgos y propuestas
| ID | Hallazgo | Propuesta |
|---|---|---|
| **F-1** | Sin evento de rango-completo (el sellado del par no se distingue del commit de un extremo) | Decidir en checkpoint: (a) declarar `commit-set` a nivel range cuando ambos extremos fijan (fulfill — el "cierre" perceptible), o (b) documentar que los dos commits del single bastan. Si (a), resolver los DOS ranges en el mismo fix |
| **F-2** | Razón de invalidez sin tipar (heredada) | Veredicto de validación de la familia (nivelar a las razones tipadas de color-field) |
| **F-3** | Compuesto SIN `expression` declarada — el canon existe (`'delegated'`, morfo/types.ts, decisión 2026-05-26) y sus primos date-picker/drp lo usan | Añadir `expression: 'delegated'` (una línea) — SYS-11 |
| ID | Hallazgo | Propuesta |
| ------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **F-1** | Sin evento de rango-completo (el sellado del par no se distingue del commit de un extremo) | Decidir en checkpoint: (a) declarar `commit-set` a nivel range cuando ambos extremos fijan (fulfill — el "cierre" perceptible), o (b) documentar que los dos commits del single bastan. Si (a), resolver los DOS ranges en el mismo fix |
| **F-2** | Razón de invalidez sin tipar (heredada) | Veredicto de validación de la familia (nivelar a las razones tipadas de color-field) |
| **F-3** | Compuesto SIN `expression` declarada — el canon existe (`'delegated'`, morfo/types.ts, decisión 2026-05-26) y sus primos date-picker/drp lo usan | Añadir `expression: 'delegated'` (una línea) — SYS-11 |
## Escalan al sistema
SYS-3 (la decisión del trío debe nombrar a los ranges) · _naming (callbacks por sub-valor) · patrón "delegación semántica por composición" — segundo caso documentado tras field-langs (el morfo compuesto NO re-declara los eventos del embebido) → regla candidata para el canon.
SYS-3 (la decisión del trío debe nombrar a los ranges) · \_naming (callbacks por sub-valor) · patrón "delegación semántica por composición" — segundo caso documentado tras field-langs (el morfo compuesto NO re-declara los eventos del embebido) → regla candidata para el canon.
## Veredictos
*(pendiente — checkpoint post-barrido)*
_(pendiente — checkpoint post-barrido)_

@ -6,23 +6,23 @@
## Dimensiones (evidencia leída)
| # | Dimensión | Estado | Evidencia |
|---|---|---|---|
| 1 | Composición | ✓ con razón in-place | `expression: "delegated"` (:15) + `commit-reset` propio (:25-31) ✓ patrón canónico; **MonthView NO duplica month-grid**: es el "month-view range bridge for `kind='month'`" con su state machine empty/pending/complete + year stepper (razón :146-148) y partes flat por namespacing `month-view-*` (:165-166) — funcionalidad distinta (rango de meses vs mes único), legítima y documentada |
| 3 | Coherencia semántica | ✓ delegada | Suena por date-field (tuneado hoy); la coherencia del cuarteto range depende de SYS-3 |
| 8 | Contrato morfo | **2 hallazgos** | **F-1**: aria-label `v.literal('Select month range')` (:160) y `v.literal('Select year range')` (:248) — inglés HARDCODEADO no localizable, cuando calendar usa `v.commonRef(key, fallback)`; único caso de la familia · MonthViewCell/YearViewCell declaran `data-range-start/end` (:228-229,:316-317) ✓ caps; **verificar en fase de fixes** cómo pinta eidos el TRAMO MEDIO del rango pendiente (sin hook data-* de in-range visible en el morfo) |
| 10 | Theming | **hallazgo doctrina** | **F-2**: su CSS re-declara privados AJENOS `--_calendar-range-{start,end}-*` con roles hardcodeados (affirm/accent :21-28; secondary :111-114) — cross-component private tuning: el anti-patrón "override del compuesto desde el host" (doctrina respect-composed-styles) en su forma más densa; + re-declara alturas de date-field per-size ×5 |
| 12 | Estados | ✓ con memoria | Placeholder compartido de endpoints (incidencia 2026-05-20 #1) documentado en el provider del single ✓ |
| 9 | A11y | ✓ con F-1 | Content: Escape close + Tab/Shift+Tab trap declarado (:140-142) |
| resto | | ✓ / hereda | tests ✓; README ×2 ✓ |
| # | Dimensión | Estado | Evidencia |
| ----- | -------------------- | --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1 | Composición | ✓ con razón in-place | `expression: "delegated"` (:15) + `commit-reset` propio (:25-31) ✓ patrón canónico; **MonthView NO duplica month-grid**: es el "month-view range bridge for `kind='month'`" con su state machine empty/pending/complete + year stepper (razón :146-148) y partes flat por namespacing `month-view-*` (:165-166) — funcionalidad distinta (rango de meses vs mes único), legítima y documentada |
| 3 | Coherencia semántica | ✓ delegada | Suena por date-field (tuneado hoy); la coherencia del cuarteto range depende de SYS-3 |
| 8 | Contrato morfo | **2 hallazgos** | **F-1**: aria-label `v.literal('Select month range')` (:160) y `v.literal('Select year range')` (:248) — inglés HARDCODEADO no localizable, cuando calendar usa `v.commonRef(key, fallback)`; único caso de la familia · MonthViewCell/YearViewCell declaran `data-range-start/end` (:228-229,:316-317) ✓ caps; **verificar en fase de fixes** cómo pinta eidos el TRAMO MEDIO del rango pendiente (sin hook data-\* de in-range visible en el morfo) |
| 10 | Theming | **hallazgo doctrina** | **F-2**: su CSS re-declara privados AJENOS `--_calendar-range-{start,end}-*` con roles hardcodeados (affirm/accent :21-28; secondary :111-114) — cross-component private tuning: el anti-patrón "override del compuesto desde el host" (doctrina respect-composed-styles) en su forma más densa; + re-declara alturas de date-field per-size ×5 |
| 12 | Estados | ✓ con memoria | Placeholder compartido de endpoints (incidencia 2026-05-20 #1) documentado en el provider del single ✓ |
| 9 | A11y | ✓ con F-1 | Content: Escape close + Tab/Shift+Tab trap declarado (:140-142) |
| resto | | ✓ / hereda | tests ✓; README ×2 ✓ |
## Hallazgos y propuestas
| ID | Hallazgo | Propuesta |
|---|---|---|
| **F-1** | 2 aria-labels en inglés hardcodeado (`v.literal`) — no localizables | Migrar a `v.commonRef('date-range-picker.month-range', 'Select month range')` + entrada de texts; censar `v.literal` con texto humano en el resto del catálogo (guard candidato: literal con espacios = sospechoso) |
| **F-2** | Re-declaración masiva de privados ajenos (`--_calendar-range-*` con roles + alturas date-field ×5) | SYS-8 (capa calendar-surface con los tokens de rango COMO API pública de la capa) + SYS-6 (token de familia field); las dos capas formales eliminan las copias |
| **F-3** | Hook del tramo medio del rango sin declarar en morfo (solo caps) | Verificación dirigida al ejecutar SYS-8: si eidos pinta in-range por selector no-morfo, es drift del contrato |
| ID | Hallazgo | Propuesta |
| ------- | -------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **F-1** | 2 aria-labels en inglés hardcodeado (`v.literal`) — no localizables | Migrar a `v.commonRef('date-range-picker.month-range', 'Select month range')` + entrada de texts; censar `v.literal` con texto humano en el resto del catálogo (guard candidato: literal con espacios = sospechoso) |
| **F-2** | Re-declaración masiva de privados ajenos (`--_calendar-range-*` con roles + alturas date-field ×5) | SYS-8 (capa calendar-surface con los tokens de rango COMO API pública de la capa) + SYS-6 (token de familia field); las dos capas formales eliminan las copias |
| **F-3** | Hook del tramo medio del rango sin declarar en morfo (solo caps) | Verificación dirigida al ejecutar SYS-8: si eidos pinta in-range por selector no-morfo, es drift del contrato |
## Escalan al sistema
@ -30,4 +30,4 @@ SYS-3 · SYS-6 · SYS-8 (evidencia máxima del borrow) · SYS-11 (ejemplo positi
## Veredictos
*(pendiente — checkpoint post-barrido)*
_(pendiente — checkpoint post-barrido)_

@ -6,12 +6,12 @@
## Dimensiones (evidencia leída)
| # | Dimensión | Estado | Evidencia |
|---|---|---|---|
| 3 | Coherencia semántica | ✓ **cuna de la doctrina** | `emerge-open` con `fromProp: 'intent'` (:54) + `emerge-close`; per-event intent nació aquí (close-save=fulfill / close-cancel=absent — memoria) y alert-dialog delega en sus eventos compartidos (header de alert-dialog :7-10); pack ✓ |
| 1 | Composición | ✓ | trigger/close = `<Button>` asChild (composición canónica) |
| 8 | Contrato morfo | ✓ | Trap/return, scrim, banda z-modal |
| resto | | ✓ | tests ✓; README ×2 ✓ |
| # | Dimensión | Estado | Evidencia |
| ----- | -------------------- | ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 3 | Coherencia semántica | ✓ **cuna de la doctrina** | `emerge-open` con `fromProp: 'intent'` (:54) + `emerge-close`; per-event intent nació aquí (close-save=fulfill / close-cancel=absent — memoria) y alert-dialog delega en sus eventos compartidos (header de alert-dialog :7-10); pack ✓ |
| 1 | Composición | ✓ | trigger/close = `<Button>` asChild (composición canónica) |
| 8 | Contrato morfo | ✓ | Trap/return, scrim, banda z-modal |
| resto | | ✓ | tests ✓; README ×2 ✓ |
## Hallazgos y propuestas
@ -23,4 +23,4 @@ Censo verbos emerge.
## Veredictos
*(pendiente — checkpoint post-barrido)*
_(pendiente — checkpoint post-barrido)_

@ -4,7 +4,7 @@
- **Capas**: morfo ✓ (scope eidos) · README eidos ✓ · named styles hero/display ✓ · **Máquina: PASS limpio**.
| Hallazgo | Propuesta |
|---|---|
| — limpio | — |
| -------- | --------- |
| — limpio | — |
**Escalan**: —. · **Veredictos**: *(pendiente checkpoint post-barrido)*
**Escalan**: —. · **Veredictos**: _(pendiente checkpoint post-barrido)_

@ -2,23 +2,23 @@
- **Familia**: util (DnD) · **Método**: solo análisis · demos fuera
- **Capas leídas**: [morfo](../../../src/uix/morfo/components/drag-drop.ts) (155 líneas; 3 eventos con `family-default` DECLARADO, apg=0) · consumidor `--ring-inset-width` ✓
- **Máquina**: NEEDS-WORK — `A-1.4` · `E-2.3` *(D-4.3 demo fuera)* · tests ✓
- **Máquina**: NEEDS-WORK — `A-1.4` · `E-2.3` _(D-4.3 demo fuera)_ · tests ✓
## Dimensiones (evidencia leída)
| # | Dimensión | Estado | Evidencia |
|---|---|---|---|
| 3 | Coherencia semántica | ✓ declarado, candidato fuerte | 3 eventos family-default escrito; drag start/drop con haptic natural → SYS-3 candidato fuerte a ascenso |
| 8 | Contrato morfo | hallazgo | **F-1**: sin APG (DnD no tiene patrón oficial — con media-player/stepper/cropper: la regla "none — rationale") |
| 14 | Docs | gap | Sin README eidos |
| # | Dimensión | Estado | Evidencia |
| --- | -------------------- | ----------------------------- | -------------------------------------------------------------------------------------------------------------- |
| 3 | Coherencia semántica | ✓ declarado, candidato fuerte | 3 eventos family-default escrito; drag start/drop con haptic natural → SYS-3 candidato fuerte a ascenso |
| 8 | Contrato morfo | hallazgo | **F-1**: sin APG (DnD no tiene patrón oficial — con media-player/stepper/cropper: la regla "none — rationale") |
| 14 | Docs | gap | Sin README eidos |
## Hallazgos y propuestas
| ID | Hallazgo | Propuesta |
|---|---|---|
| **F-1** | Sin APG | Regla "none — rationale" |
| **F-2** | ¿Asciende a pack? | SYS-3 |
| **F-3** | README eidos | SYS-4 |
| ID | Hallazgo | Propuesta |
| ------- | ----------------- | ------------------------ |
| **F-1** | Sin APG | Regla "none — rationale" |
| **F-2** | ¿Asciende a pack? | SYS-3 |
| **F-3** | README eidos | SYS-4 |
## Escalan al sistema
@ -26,4 +26,4 @@ SYS-3 · SYS-4 · censo A-1.4 (caso "sin patrón").
## Veredictos
*(pendiente — checkpoint post-barrido)*
_(pendiente — checkpoint post-barrido)_

@ -6,11 +6,11 @@
## Dimensiones (evidencia leída)
| # | Dimensión | Estado | Evidencia |
|---|---|---|---|
| 3 | Coherencia semántica | ✓ **el overlay-handle completo** | 6 eventos: emerge present/close + la trilogía handle pick/drag/drop **más resize** — el arrastre del drawer (snap points) tiene contrato semántico COMPLETO, en contraste directo con float-panel (mismo tipo de gesto, 28 mutaciones sin señal — su F-1). Drawer es la referencia interna para ese fix; pack ✓ |
| 8 | Contrato morfo | ✓ | Snap points, direcciones, trap |
| resto | | ✓ | depth ✓; tests ✓; README ×2 ✓ |
| # | Dimensión | Estado | Evidencia |
| ----- | -------------------- | -------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 3 | Coherencia semántica | ✓ **el overlay-handle completo** | 6 eventos: emerge present/close + la trilogía handle pick/drag/drop **más resize** — el arrastre del drawer (snap points) tiene contrato semántico COMPLETO, en contraste directo con float-panel (mismo tipo de gesto, 28 mutaciones sin señal — su F-1). Drawer es la referencia interna para ese fix; pack ✓ |
| 8 | Contrato morfo | ✓ | Snap points, direcciones, trap |
| resto | | ✓ | depth ✓; tests ✓; README ×2 ✓ |
## Hallazgos y propuestas
@ -22,4 +22,4 @@ Censo handle (+drawer con resize) · censo verbos emerge (present/close).
## Veredictos
*(pendiente — checkpoint post-barrido)*
_(pendiente — checkpoint post-barrido)_

@ -6,11 +6,11 @@
## Dimensiones (evidencia leída)
| # | Dimensión | Estado | Evidencia |
|---|---|---|---|
| 3 | Coherencia semántica | ✓ | open/close/select (gemelo de context-menu ✓); pack ✓ |
| 8 | Contrato morfo | ✓ | Submenús, checkable items, typeahead |
| resto | | ✓ | depth ×3; list-surface; gap menú 0 (canon floating-gap) ✓ |
| # | Dimensión | Estado | Evidencia |
| ----- | -------------------- | ------ | --------------------------------------------------------- |
| 3 | Coherencia semántica | ✓ | open/close/select (gemelo de context-menu ✓); pack ✓ |
| 8 | Contrato morfo | ✓ | Submenús, checkable items, typeahead |
| resto | | ✓ | depth ×3; list-surface; gap menú 0 (canon floating-gap) ✓ |
## Hallazgos y propuestas
@ -22,4 +22,4 @@ Censo verbos emerge.
## Veredictos
*(pendiente — checkpoint post-barrido)*
_(pendiente — checkpoint post-barrido)_

@ -6,37 +6,37 @@
## Dimensiones (evidencia leída)
| # | Dimensión | Estado | Evidencia |
|---|---|---|---|
| 1 | Composición | ✓ | Area/Control/Preview/Input/EditTrigger(+Submit/Cancel) compositivos |
| 2 | Naming | **4 datos de censo** | **`defaultValue`** (types :16-21 — PRIMER uncontrolled-initial del catálogo, doc React-style "read once at mount") → ¿canon o redundante con `$bindable(inicial)`? · par `onValueChange` (cambia el comprometido) + `onValueCommit` (cada commit) :60-63 — distinción sutil que el resto no hace · **`onValueRevert: () => void`** crudo SIN payload (:64-65 — encaja la regla "crudo solo señal sin dato" ✓) · `editing/onEditingChange` par bindable ✓ |
| 3 | Coherencia semántica | ✓ | `shift-enter-mode` (shift, sin intent — cambio de contexto ✓) · `commit-save` affirm · `commit-cancel` **neutral** (commit exige intent por política de familia; neutral es correcto — verificado contra la doctrina) |
| 4 | API | ✓ rica | `activationMode: focus\|click\|dblclick\|none` + `submitMode: enter\|blur\|both\|none` (:32-49); `selectOnFocus`; hidden-input por `name` (:26-27) |
| 5 | Tokens | ✓ | Recipe canónico |
| 6 | Sema | ✓ | Pack ✓ (enter/save/cancel con carácter) |
| 7 | Animaciones | ✓ | Sin keyframes |
| 8 | Contrato morfo | ✓ | Preview `role='textbox'` en div (patrón Chakra/Ark del valor-como-textbox-readonly, :102-110); `data-editing/empty/placeholder-shown` flags; aria-required/invalid condicionales |
| 9 | A11y | ✓ | Activación por foco accesible por defecto; triggers con textos |
| 10 | Theming | ✓ | Focus o5 → censo SYS-5; state-hover preview ✓ tier neutro |
| 11 | Composición interna | verificar | Como tags-input: sin mención de OR-merge con Field en types → verificación dirigida (pass SYS-6) |
| 12 | Estados | ✓ con gap menor | editing/empty/disabled/readonly/invalid ✓; **F-1**: `maxLength` (:54-55) SIN señal de overflow (0 hits) — textarea tiene el contrato `signal-warn-count-overflow` untilFix para lo mismo |
| 13 | Runtime | ✓ **por diseño** | `autoResize` dimensiona por `ch` desde el valor + `min-width: 2ch` (provider :374-377) — **cero medición de DOM** (evita la clase de reflow de textarea F-1 por construcción); el contraste correcto: ch para una línea, medición-diferida para multilínea |
| 14 | Docs+tests | ✓ | README ×2, suite ✓ (+ el error de tipos baseline a absorber) |
| 15 | i18n | ✓ | texts morfo |
| # | Dimensión | Estado | Evidencia |
| --- | -------------------- | -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1 | Composición | ✓ | Area/Control/Preview/Input/EditTrigger(+Submit/Cancel) compositivos |
| 2 | Naming | **4 datos de censo** | **`defaultValue`** (types :16-21 — PRIMER uncontrolled-initial del catálogo, doc React-style "read once at mount") → ¿canon o redundante con `$bindable(inicial)`? · par `onValueChange` (cambia el comprometido) + `onValueCommit` (cada commit) :60-63 — distinción sutil que el resto no hace · **`onValueRevert: () => void`** crudo SIN payload (:64-65 — encaja la regla "crudo solo señal sin dato" ✓) · `editing/onEditingChange` par bindable ✓ |
| 3 | Coherencia semántica | ✓ | `shift-enter-mode` (shift, sin intent — cambio de contexto ✓) · `commit-save` affirm · `commit-cancel` **neutral** (commit exige intent por política de familia; neutral es correcto — verificado contra la doctrina) |
| 4 | API | ✓ rica | `activationMode: focus\|click\|dblclick\|none` + `submitMode: enter\|blur\|both\|none` (:32-49); `selectOnFocus`; hidden-input por `name` (:26-27) |
| 5 | Tokens | ✓ | Recipe canónico |
| 6 | Sema | ✓ | Pack ✓ (enter/save/cancel con carácter) |
| 7 | Animaciones | ✓ | Sin keyframes |
| 8 | Contrato morfo | ✓ | Preview `role='textbox'` en div (patrón Chakra/Ark del valor-como-textbox-readonly, :102-110); `data-editing/empty/placeholder-shown` flags; aria-required/invalid condicionales |
| 9 | A11y | ✓ | Activación por foco accesible por defecto; triggers con textos |
| 10 | Theming | ✓ | Focus o5 → censo SYS-5; state-hover preview ✓ tier neutro |
| 11 | Composición interna | verificar | Como tags-input: sin mención de OR-merge con Field en types → verificación dirigida (pass SYS-6) |
| 12 | Estados | ✓ con gap menor | editing/empty/disabled/readonly/invalid ✓; **F-1**: `maxLength` (:54-55) SIN señal de overflow (0 hits) — textarea tiene el contrato `signal-warn-count-overflow` untilFix para lo mismo |
| 13 | Runtime | ✓ **por diseño** | `autoResize` dimensiona por `ch` desde el valor + `min-width: 2ch` (provider :374-377) — **cero medición de DOM** (evita la clase de reflow de textarea F-1 por construcción); el contraste correcto: ch para una línea, medición-diferida para multilínea |
| 14 | Docs+tests | ✓ | README ×2, suite ✓ (+ el error de tipos baseline a absorber) |
| 15 | i18n | ✓ | texts morfo |
## Hallazgos y propuestas
| ID | Hallazgo | Propuesta |
|---|---|---|
| **F-1** | `maxLength` sin contrato de overflow (asimetría con textarea) | Adoptar `signal-warn-count-overflow` del hermano (untilFix + persistent-trace) o documentar por qué no aplica al in-place |
| **F-2** | `defaultValue` — patrón uncontrolled único en el catálogo | Veredicto _naming: ¿se canoniza (y entonces quién más lo necesita) o se poda (el `$bindable(inicial)` de Svelte 5 cubre el caso)? |
| **F-3** | Error de tipos preexistente en su suite (baseline check) | Fix trivial en fase de fixes |
| **F-4** | Participación Field sin documentar | Verificación dirigida (con tags-input) |
| ID | Hallazgo | Propuesta |
| ------- | ------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| **F-1** | `maxLength` sin contrato de overflow (asimetría con textarea) | Adoptar `signal-warn-count-overflow` del hermano (untilFix + persistent-trace) o documentar por qué no aplica al in-place |
| **F-2** | `defaultValue` — patrón uncontrolled único en el catálogo | Veredicto \_naming: ¿se canoniza (y entonces quién más lo necesita) o se poda (el `$bindable(inicial)` de Svelte 5 cubre el caso)? |
| **F-3** | Error de tipos preexistente en su suite (baseline check) | Fix trivial en fase de fixes |
| **F-4** | Participación Field sin documentar | Verificación dirigida (con tags-input) |
## Escalan al sistema
_naming (defaultValue · el par Change/Commit · Revert crudo ✓ como regla) · patrón "ch-sizing vs medición-diferida" como doctrina de autoResize (exportable).
\_naming (defaultValue · el par Change/Commit · Revert crudo ✓ como regla) · patrón "ch-sizing vs medición-diferida" como doctrina de autoResize (exportable).
## Veredictos
*(pendiente — checkpoint post-barrido)*
_(pendiente — checkpoint post-barrido)_

@ -7,17 +7,17 @@
## Dimensiones (evidencia leída)
| # | Dimensión | Estado | Evidencia |
|---|---|---|---|
| # | Dimensión | Estado | Evidencia |
| --- | ----------------------- | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| 1/3 | Composición y semántica | ✓ delegación documentada | Compone Button wholesale (contact + pack de button viajan gratis); morfo declara solo la identidad estructural `data-fab` — sexta cita del patrón delegación |
| 8 | Contrato morfo | ✓ | apg ✓; placement/shape en contrato |
| 14 | Docs | gap menor | Clasificación formal de composición → SYS-7 |
| 8 | Contrato morfo | ✓ | apg ✓; placement/shape en contrato |
| 14 | Docs | gap menor | Clasificación formal de composición → SYS-7 |
## Hallazgos y propuestas
| ID | Hallazgo | Propuesta |
|---|---|---|
| **F-1** | Clasificación formal (composición-sobre-Button) | SYS-7 |
| ID | Hallazgo | Propuesta |
| ------- | ----------------------------------------------- | --------- |
| **F-1** | Clasificación formal (composición-sobre-Button) | SYS-7 |
## Escalan al sistema
@ -25,4 +25,4 @@ SYS-7 · SYS-11 (sexta cita).
## Veredictos
*(pendiente — checkpoint post-barrido)*
_(pendiente — checkpoint post-barrido)_

@ -6,16 +6,16 @@
## Dimensiones (evidencia leída)
| # | Dimensión | Estado | Evidencia |
|---|---|---|---|
| 3 | Coherencia semántica | ✓ declarado | commit-submit (cargar más presumible) + shift-navigate; family-default escrito; APG feed ✓ (el patrón oficial existe y está citado) |
| 14 | Docs | gap | Sin README eidos |
| # | Dimensión | Estado | Evidencia |
| --- | -------------------- | ----------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| 3 | Coherencia semántica | ✓ declarado | commit-submit (cargar más presumible) + shift-navigate; family-default escrito; APG feed ✓ (el patrón oficial existe y está citado) |
| 14 | Docs | gap | Sin README eidos |
## Hallazgos y propuestas
| ID | Hallazgo | Propuesta |
|---|---|---|
| **F-1** | README eidos | SYS-4 |
| ID | Hallazgo | Propuesta |
| ------- | ------------ | --------- |
| **F-1** | README eidos | SYS-4 |
## Escalan al sistema
@ -23,4 +23,4 @@ SYS-4.
## Veredictos
*(pendiente — checkpoint post-barrido)*
_(pendiente — checkpoint post-barrido)_

@ -2,35 +2,35 @@
- **Familia**: fields (campo localizado; recién embarcado `0522efe0`) · **Método**: solo análisis; evidencia por dimensión · demos fuera
- **Capas leídas**: [morfo](../../../src/uix/morfo/components/field-langs.ts) completo (1-90+) · [soma types](../../../src/uix/soma/components/field-langs/types.ts) superficie · sema: `family-default` RAZONADO in-place
- **Máquina**: PASS con `R-2.7` (*`line-height: 1.2` literal sin anotar*) · tests **0** · README soma **✗** / eidos ✓
- **Máquina**: PASS con `R-2.7` (_`line-height: 1.2` literal sin anotar_) · tests **0** · README soma **✗** / eidos ✓
- **Corrección sobre el pass superficial**: el antiguo F-4 ("semántica del conmutador sin declarar") era FALSO — el morfo la declara y razona (abajo). La ficha superficial no había leído el contrato.
## Dimensiones (evidencia leída)
| # | Dimensión | Estado | Evidencia |
|---|---|---|---|
| 1 | Composición | ✓ ejemplar | Patrón picker A27 citado (morfo :9-13): compone el eidos `<Field>` + conmutador in-control cuya FORMA se adapta (segmented ≤3 idiomas · Select ghost >3 o forzado); **Switcher `kind: 'private'`** con razón doble (:77-84): el `commit-toggle` del ToggleGroup es semántica EQUIVOCADA para navegación de contexto + su chrome se colaría en el control — radiogroup propio en segmented |
| 2 | Naming | ✓ | `LangSpec = code \| {code,label?,dir?}` (RTL por idioma ✓); `values: Record<LangCode,string>` bindable; `switcherSide: start\|end` lógico; `switcherMode: auto\|segmented\|select` |
| 3 | Coherencia semántica | ✓ **declarada y razonada** | `shift-navigate` con cap. 27 citado (cambio de régimen entre valores por-idioma, NO fijación — :39-52); `expression: 'family-default'` RAZONADO (:29-33): el settle visual es la base de shift, el tap del press lo pone el pack del ToggleGroup compuesto — decisión sema COMPOSICIONAL documentada (modelo para el veredicto SYS-3: family-default puede ser elección arquitectural, no hueco) |
| 4 | API | ✓ | `languages` + `required: LangCode[]` + `missingRequired` derivado en snippet (validación por idioma) |
| 5 | Tokens | hallazgo | **F-1**: `line-height: 1.2` literal (R-2.7) |
| 6 | Sema | ✓ | Ver dim 3 — el caso canónico de default-por-composición |
| 7 | Animaciones | ✓ | Sin keyframes |
| 8 | Contrato morfo | ✓ | `data-active-lang` emit value + `data-switcher-side` enum + flags; switcher-label localizado |
| 9 | A11y | ✓ a verificar en fixes | Radiogroup del switcher (roles por verificar en las partes restantes al ejecutar) |
| 10-12 | | ✓ | Compone Field DE VERDAD (el recién llegado hace lo que el mandato SYS-6 pide a los veteranos) |
| 13 | Runtime | ✓ | Sin señales de indisciplina en lo leído |
| 14 | Docs+tests | **gap doble** | **Cero tests** (draft por idioma, missingRequired, switch de contexto) + README soma ausente (el contrato headless sin doc) |
| 15 | i18n | ✓ | Su razón de ser; texts + switcher-label |
| # | Dimensión | Estado | Evidencia |
| ----- | -------------------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| 1 | Composición | ✓ ejemplar | Patrón picker A27 citado (morfo :9-13): compone el eidos `<Field>` + conmutador in-control cuya FORMA se adapta (segmented ≤3 idiomas · Select ghost >3 o forzado); **Switcher `kind: 'private'`** con razón doble (:77-84): el `commit-toggle` del ToggleGroup es semántica EQUIVOCADA para navegación de contexto + su chrome se colaría en el control — radiogroup propio en segmented |
| 2 | Naming | ✓ | `LangSpec = code \| {code,label?,dir?}` (RTL por idioma ✓); `values: Record<LangCode,string>` bindable; `switcherSide: start\|end` lógico; `switcherMode: auto\|segmented\|select` |
| 3 | Coherencia semántica | ✓ **declarada y razonada** | `shift-navigate` con cap. 27 citado (cambio de régimen entre valores por-idioma, NO fijación — :39-52); `expression: 'family-default'` RAZONADO (:29-33): el settle visual es la base de shift, el tap del press lo pone el pack del ToggleGroup compuesto — decisión sema COMPOSICIONAL documentada (modelo para el veredicto SYS-3: family-default puede ser elección arquitectural, no hueco) |
| 4 | API | ✓ | `languages` + `required: LangCode[]` + `missingRequired` derivado en snippet (validación por idioma) |
| 5 | Tokens | hallazgo | **F-1**: `line-height: 1.2` literal (R-2.7) |
| 6 | Sema | ✓ | Ver dim 3 — el caso canónico de default-por-composición |
| 7 | Animaciones | ✓ | Sin keyframes |
| 8 | Contrato morfo | ✓ | `data-active-lang` emit value + `data-switcher-side` enum + flags; switcher-label localizado |
| 9 | A11y | ✓ a verificar en fixes | Radiogroup del switcher (roles por verificar en las partes restantes al ejecutar) |
| 10-12 | | ✓ | Compone Field DE VERDAD (el recién llegado hace lo que el mandato SYS-6 pide a los veteranos) |
| 13 | Runtime | ✓ | Sin señales de indisciplina en lo leído |
| 14 | Docs+tests | **gap doble** | **Cero tests** (draft por idioma, missingRequired, switch de contexto) + README soma ausente (el contrato headless sin doc) |
| 15 | i18n | ✓ | Su razón de ser; texts + switcher-label |
## Hallazgos y propuestas
| ID | Hallazgo | Propuesta |
|---|---|---|
| **F-1** | `line-height: 1.2` literal (R-2.7) | `var(--leading-ui)` o anotación `/* literal: razón */` |
| **F-2** | Cero tests | Suite: valores por idioma (persistencia del borrador al conmutar), missingRequired, modos del switcher — SYS-2 |
| **F-3** | README soma ausente (patrón invertido) | Crearlo — SYS-4 |
| **Nota ✓✓** | La razón escrita del `family-default` composicional (:29-33) es EL modelo para el veredicto SYS-3 | Citarla en el checkpoint: "default legítimo cuando el carácter lo aporta el compuesto" |
| ID | Hallazgo | Propuesta |
| ----------- | ------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- |
| **F-1** | `line-height: 1.2` literal (R-2.7) | `var(--leading-ui)` o anotación `/* literal: razón */` |
| **F-2** | Cero tests | Suite: valores por idioma (persistencia del borrador al conmutar), missingRequired, modos del switcher — SYS-2 |
| **F-3** | README soma ausente (patrón invertido) | Crearlo — SYS-4 |
| **Nota ✓✓** | La razón escrita del `family-default` composicional (:29-33) es EL modelo para el veredicto SYS-3 | Citarla en el checkpoint: "default legítimo cuando el carácter lo aporta el compuesto" |
## Escalan al sistema
@ -38,4 +38,4 @@ SYS-2 · SYS-4 · **SYS-3 gana su segundo criterio documentado** (composición a
## Veredictos
*(pendiente — checkpoint post-barrido)*
_(pendiente — checkpoint post-barrido)_

@ -6,37 +6,37 @@
## Dimensiones (evidencia leída)
| # | Dimensión | Estado | Evidencia |
|---|---|---|---|
| 1 | Composición vs declaración | ✓ | 10 partes como children compositivos (morfo field.ts:13-180); indicators/error con render condicional por prop (`onlyWhenRequired/Optional/Invalid`, types.ts:89/96/121) — no árboles declarativos |
| 2 | Naming de props | ✓ canónico | `value`+`onValueChange` (types.ts:107-109 — EL patrón del catálogo); `disabled/readonly/required/invalid` planos; overrides `dirty/touched/state` documentados (types.ts:63-78); patrón `onlyWhen*` ×3 coherente → alimenta [_naming.md](./_naming.md) |
| 3 | Coherencia semántica | ✓ con hallazgo | La base NO emite eventos y lo DECLARA en scope (field.ts:7 ✓); pero **F-2**: Field.Input (texto de una línea) no tiene contrato de commit mientras textarea tiene `commit-submit` (textarea.ts, verificado) — el par de inputs de texto es asimétrico |
| 4 | API normalizada | ✓ | Estado compuesto con precedencia documentada y verificada (provider 145-152: explicit > invalid > disabled > readonly); snippetProps completos (154-164); OR-merge con Form (types.ts:36-38, provider 138-142 markTouched→form) |
| 5 | Tokens usados | ✓ | Recipe 58 claves TODAS canónicas §1 (control-height-{k}, padding-inline, gap, radius, font-size 1:1, floating-label-top temable, segment-active-* de V4); css consume solo `--field-*` |
| 6 | Parte semántica | ✓ by-contract | Sin sema por scope (los commits los emiten los fields concretos) — coherente, salvo F-2 |
| 7 | Animaciones | ✓ | 4 `transition:` con tokens (R-limpio máquina); 0 `@keyframes`; floatingLabel = CSS-only (11 reglas `floating`), sin JS |
| 8 | Contrato morfo | **hallazgo doble** | **F-1**: enum `data-state` de 5 valores emitido en Provider/Control/Input (field.ts:24-27/88-91/106-110) con **0 consumidores en TODO el CSS de eidos** (verificado catálogo entero) — el estilo real va por los flags de presencia (data-invalid ×4, data-disabled ×7 en field.css); además emite `data-state="idle"` en reposo — el patrón exacto que button PURGÓ (su morfo documenta el clobbering, audit 05-27). Doble codificación: enum muerto + flags vivos |
| 9 | Accesibilidad | ✓ ejemplar | Auto-wiring completo: label for→input condicional part-present (field.ts:52-56), aria-invalid ariaBoolean (120), aria-busy loading (128-132), aria-required (134-138), ErrorText role=alert+aria-live (157-160); `describedBy` une helper+error-solo-si-invalid y SOBRESCRIBE el morfo con el valor más rico — documentado (provider 344-350 + 371-373) |
| 10 | Adopción theming | ✓ con remanente | Focus: el ÚNICO box-shadow dos-anillos superviviente del catálogo vive aquí → ancla del veredicto SYS-5; states-layer n/a (chrome no interactivo) |
| 11 | Composición interna | mandato | Es la base que los hijos DEBEN envolver (SYS-6/B.1): la familia de alturas + el chrome label/helper/error existen aquí y los segment-fields los re-implementan |
| 12 | Estados y ciclo | ✓ con gap visual | invalid/disabled/readonly estilados; **`loading` definido en el contrato (morfo+types+aria-busy) pero SIN visual en css** (0 reglas) — estado fantasma a nivel eidos (parte de F-1) |
| 13 | Disciplina runtime | ✓ | 0 timers/listeners crudos; focusout→markTouched vía prop de runtime (166-175); `$derived` puros |
| 14 | Docs + tests | ✓ | README ×2; suite 8KB (provider) |
| 15 | i18n | ✓ | texts localizados incl. indicadores `*`/`(optional)` (field.ts:8-12); langs.ts propio |
| # | Dimensión | Estado | Evidencia |
| --- | -------------------------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1 | Composición vs declaración | ✓ | 10 partes como children compositivos (morfo field.ts:13-180); indicators/error con render condicional por prop (`onlyWhenRequired/Optional/Invalid`, types.ts:89/96/121) — no árboles declarativos |
| 2 | Naming de props | ✓ canónico | `value`+`onValueChange` (types.ts:107-109 — EL patrón del catálogo); `disabled/readonly/required/invalid` planos; overrides `dirty/touched/state` documentados (types.ts:63-78); patrón `onlyWhen*` ×3 coherente → alimenta [\_naming.md](./_naming.md) |
| 3 | Coherencia semántica | ✓ con hallazgo | La base NO emite eventos y lo DECLARA en scope (field.ts:7 ✓); pero **F-2**: Field.Input (texto de una línea) no tiene contrato de commit mientras textarea tiene `commit-submit` (textarea.ts, verificado) — el par de inputs de texto es asimétrico |
| 4 | API normalizada | ✓ | Estado compuesto con precedencia documentada y verificada (provider 145-152: explicit > invalid > disabled > readonly); snippetProps completos (154-164); OR-merge con Form (types.ts:36-38, provider 138-142 markTouched→form) |
| 5 | Tokens usados | ✓ | Recipe 58 claves TODAS canónicas §1 (control-height-{k}, padding-inline, gap, radius, font-size 1:1, floating-label-top temable, segment-active-_ de V4); css consume solo `--field-_` |
| 6 | Parte semántica | ✓ by-contract | Sin sema por scope (los commits los emiten los fields concretos) — coherente, salvo F-2 |
| 7 | Animaciones | ✓ | 4 `transition:` con tokens (R-limpio máquina); 0 `@keyframes`; floatingLabel = CSS-only (11 reglas `floating`), sin JS |
| 8 | Contrato morfo | **hallazgo doble** | **F-1**: enum `data-state` de 5 valores emitido en Provider/Control/Input (field.ts:24-27/88-91/106-110) con **0 consumidores en TODO el CSS de eidos** (verificado catálogo entero) — el estilo real va por los flags de presencia (data-invalid ×4, data-disabled ×7 en field.css); además emite `data-state="idle"` en reposo — el patrón exacto que button PURGÓ (su morfo documenta el clobbering, audit 05-27). Doble codificación: enum muerto + flags vivos |
| 9 | Accesibilidad | ✓ ejemplar | Auto-wiring completo: label for→input condicional part-present (field.ts:52-56), aria-invalid ariaBoolean (120), aria-busy loading (128-132), aria-required (134-138), ErrorText role=alert+aria-live (157-160); `describedBy` une helper+error-solo-si-invalid y SOBRESCRIBE el morfo con el valor más rico — documentado (provider 344-350 + 371-373) |
| 10 | Adopción theming | ✓ con remanente | Focus: el ÚNICO box-shadow dos-anillos superviviente del catálogo vive aquí → ancla del veredicto SYS-5; states-layer n/a (chrome no interactivo) |
| 11 | Composición interna | mandato | Es la base que los hijos DEBEN envolver (SYS-6/B.1): la familia de alturas + el chrome label/helper/error existen aquí y los segment-fields los re-implementan |
| 12 | Estados y ciclo | ✓ con gap visual | invalid/disabled/readonly estilados; **`loading` definido en el contrato (morfo+types+aria-busy) pero SIN visual en css** (0 reglas) — estado fantasma a nivel eidos (parte de F-1) |
| 13 | Disciplina runtime | ✓ | 0 timers/listeners crudos; focusout→markTouched vía prop de runtime (166-175); `$derived` puros |
| 14 | Docs + tests | ✓ | README ×2; suite 8KB (provider) |
| 15 | i18n | ✓ | texts localizados incl. indicadores `*`/`(optional)` (field.ts:8-12); langs.ts propio |
## Hallazgos y propuestas — del componente
| ID | Hallazgo | Propuesta |
|---|---|---|
| **F-1** | Enum `data-state` (5 valores, 3 partes) sin NINGÚN consumidor CSS + `idle` emitido en reposo + `loading` sin visual — doble codificación con los flags | Dos salidas para el veredicto: (a) **podar el enum** (como button: flags de presencia bastan; `loading` se convierte en flag `data-loading` + visual definido) — recomendada por coherencia con la doctrina button; (b) adoptarlo (estilar error/loading/readonly por el enum y podar flags redundantes). En ambas: definir el visual de `loading` que hoy no existe |
| **F-2** | Field.Input sin contrato de commit vs textarea `commit-submit` — el par texto asimétrico. **Refinado tras leer password-field**: la doctrina de familia YA existe y está documentada con incidente (password-field morfo :40-47 — teclear NO es commit; `commit-submit` al Enter ES el patrón, alineado con editable/number/search/combobox) | Field.Input adopta `commit-submit` (Enter) siguiendo la doctrina escrita de password-field — morfo + provider; el veredicto es de adopción, no de diseño (el diseño ya está canonizado en el hermano) |
| **F-3** | El morfo declara `aria-describedby` solo desde helper-text; el valor real (helper+error) lo compone soma en override | Menor: reflejar en el morfo la relación con error-text (severity optional + condición) para que el contrato no infra-declare lo que se renderiza |
| ID | Hallazgo | Propuesta |
| ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **F-1** | Enum `data-state` (5 valores, 3 partes) sin NINGÚN consumidor CSS + `idle` emitido en reposo + `loading` sin visual — doble codificación con los flags | Dos salidas para el veredicto: (a) **podar el enum** (como button: flags de presencia bastan; `loading` se convierte en flag `data-loading` + visual definido) — recomendada por coherencia con la doctrina button; (b) adoptarlo (estilar error/loading/readonly por el enum y podar flags redundantes). En ambas: definir el visual de `loading` que hoy no existe |
| **F-2** | Field.Input sin contrato de commit vs textarea `commit-submit` — el par texto asimétrico. **Refinado tras leer password-field**: la doctrina de familia YA existe y está documentada con incidente (password-field morfo :40-47 — teclear NO es commit; `commit-submit` al Enter ES el patrón, alineado con editable/number/search/combobox) | Field.Input adopta `commit-submit` (Enter) siguiendo la doctrina escrita de password-field — morfo + provider; el veredicto es de adopción, no de diseño (el diseño ya está canonizado en el hermano) |
| **F-3** | El morfo declara `aria-describedby` solo desde helper-text; el valor real (helper+error) lo compone soma en override | Menor: reflejar en el morfo la relación con error-text (severity optional + condición) para que el contrato no infra-declare lo que se renderiza |
## Escalan al sistema
- **F-1 alimenta una regla de catálogo**: "enum de estado solo si el CSS lo consume; si los flags bastan, el enum es deuda" — censar en el resto de la re-auditoría quién más emite enums muertos (→ SYS-10 nuevo en _system al cierre de familia).
- **F-1 alimenta una regla de catálogo**: "enum de estado solo si el CSS lo consume; si los flags bastan, el enum es deuda" — censar en el resto de la re-auditoría quién más emite enums muertos (→ SYS-10 nuevo en \_system al cierre de familia).
- SYS-5 (ancla del focus) · SYS-6 (destino del mandato) — ya registrados.
## Veredictos
*(pendiente — checkpoint post-barrido)*
_(pendiente — checkpoint post-barrido)_

@ -6,10 +6,10 @@
## Dimensiones (evidencia leída)
| # | Dimensión | Estado | Evidencia |
|---|---|---|---|
| 3 | Coherencia semántica | ✓ el util más rico | 6 eventos + pack ✓ (drop states, validación tipo/tamaño, progreso por fichero) — contrato completo |
| resto | | ✓ | tests ✓; README ×2 ✓ |
| # | Dimensión | Estado | Evidencia |
| ----- | -------------------- | ------------------ | -------------------------------------------------------------------------------------------------- |
| 3 | Coherencia semántica | ✓ el util más rico | 6 eventos + pack ✓ (drop states, validación tipo/tamaño, progreso por fichero) — contrato completo |
| resto | | ✓ | tests ✓; README ×2 ✓ |
## Hallazgos y propuestas
@ -21,4 +21,4 @@ Limpio a nivel de capas leídas.
## Veredictos
*(pendiente — checkpoint post-barrido)*
_(pendiente — checkpoint post-barrido)_

@ -3,4 +3,4 @@
- **Fecha**: 2026-07-07 · **Familia**: layout · **Método**: solo análisis
- **Capas**: morfo ✓ (scope eidos) · README eidos ✓ · **Máquina: PASS limpio** · props responsive vía `ResponsiveProp` ✓.
— limpio. **Escalan**: —. · **Veredictos**: *(pendiente checkpoint post-barrido)*
— limpio. **Escalan**: —. · **Veredictos**: _(pendiente checkpoint post-barrido)_

@ -6,20 +6,20 @@
## Dimensiones (evidencia leída)
| # | Dimensión | Estado | Evidencia |
|---|---|---|---|
| 3/8 | Coherencia semántica | **la brecha teclas↔eventos más grande del catálogo** | **F-1**: declara pick/drop/resize pero NO `drag` (drawer sí lo tiene — la comparación directa: mismo gesto, contrato menor) y sus 28 mutaciones de teclado (move/resize/snap por flechas) no emiten señal — el usuario sordo-perceptual: mueve el panel y el sistema no lo "siente". Drawer = referencia interna del fix |
| 10 | Theming | hallazgo | **F-2**: depth SIN estampar (0) — panel flotante que consume `--ring-inset-width` ✓ pero no declara plano |
| 14 | Docs | gap | Expediente pre-flight a medias (sin Baseline; Comparativa 0 refs; Gaps sin disposición) |
| resto | | ✓ | pack ✓; tests ✓ |
| # | Dimensión | Estado | Evidencia |
| ----- | -------------------- | ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| 3/8 | Coherencia semántica | **la brecha teclas↔eventos más grande del catálogo** | **F-1**: declara pick/drop/resize pero NO `drag` (drawer sí lo tiene — la comparación directa: mismo gesto, contrato menor) y sus 28 mutaciones de teclado (move/resize/snap por flechas) no emiten señal — el usuario sordo-perceptual: mueve el panel y el sistema no lo "siente". Drawer = referencia interna del fix |
| 10 | Theming | hallazgo | **F-2**: depth SIN estampar (0) — panel flotante que consume `--ring-inset-width` ✓ pero no declara plano |
| 14 | Docs | gap | Expediente pre-flight a medias (sin Baseline; Comparativa 0 refs; Gaps sin disposición) |
| resto | | ✓ | pack ✓; tests ✓ |
## Hallazgos y propuestas
| ID | Hallazgo | Propuesta |
|---|---|---|
| ID | Hallazgo | Propuesta |
| ------- | ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **F-1** | 28 mutaciones / 6 eventos (A-3.7); sin `handle-drag` | Sesión de contrato: mapear a `shift.*`/`handle-drag` con la doctrina de holds (agregación al soltar, no evento-por-tecla) — usar drawer como plantilla |
| **F-2** | Sin `data-depth` | Pass conjunto de depth |
| **F-3** | Expediente incompleto | Baseline/Comparativa ≥3 refs/Gaps con disposición |
| **F-2** | Sin `data-depth` | Pass conjunto de depth |
| **F-3** | Expediente incompleto | Baseline/Comparativa ≥3 refs/Gaps con disposición |
## Escalan al sistema
@ -27,4 +27,4 @@ Censo depth · A-3.7 como clase (¿otros con teclado rico infra-declarado? — r
## Veredictos
*(pendiente — checkpoint post-barrido)*
_(pendiente — checkpoint post-barrido)_

@ -3,4 +3,4 @@
- **Fecha**: 2026-07-07 · **Familia**: layout (anclado flotante decorativo) · **Método**: solo análisis
- **Capas**: morfo ✓ (scope eidos) · README eidos ✓ · **Máquina: PASS limpio**.
— limpio. **Escalan**: —. · **Veredictos**: *(pendiente checkpoint post-barrido)*
— limpio. **Escalan**: —. · **Veredictos**: _(pendiente checkpoint post-barrido)_

@ -6,34 +6,34 @@
## Dimensiones (evidencia leída)
| # | Dimensión | Estado | Evidencia |
|---|---|---|---|
| 1 | Composición | ✓ | Provider(`<form>` real)/Submit/Reset/ErrorSummary compositivos |
| 2 | Naming | **dato de censo** | **`isPending`/`data-pending`** para async-en-vuelo (morfo :75, types) mientras button/field usan `loading` — DOS nombres para el concepto → _naming; `disableWhenPristine` en Reset ✓ expresivo; `submitCount` en snippet |
| 3 | Coherencia semántica | ✓ **referencia** | `commit-submit` con intent **fulfill** (:16-24 — el cierre terminal donde la doctrina de button dice que vive el intent fuerte ✓); **`signal-warn-invalid`** untilFix + `requiresFocusMove` + persistent-trace con §6.2 y §9.2 citados y el ciclo clearSignal/clearTarget documentado (:26-53) — CUARTO contrato de referencia de la familia; `commit-reset` neutral ✓ |
| 4 | API | ✓ | Standard-Schema (el adaptador always-async con `untrack` — antecedente de memoria); estados dirty/touched/submitted proyectados |
| 5 | Tokens | ✓ | Gaps por size vía recipe |
| 6 | Sema | ✓ | Pack ✓ — el submit ES el sitio del carácter |
| 7 | Animaciones | ✓ | Sin keyframes |
| 8 | Contrato morfo | ✓ | APG landmark form CORRECTO (:9); `data-{pending,dirty,touched,invalid,submitted}` + aria-busy condicional (:74-88) |
| 9 | A11y | ✓ ejemplar | El focus-move del warn aterriza en el form y `focusFirstInvalid()` perfora al primer campo inválido (documentado :43-48); ErrorSummary con títulos singular/plural interpolados (:12-13) |
| 10 | Theming | ✓ | Focus o1 contenedor |
| 11 | Composición interna | ✓ | ES el otro extremo del OR-merge: Field se registra y deriva dirty/touched/errors de aquí |
| 12 | Estados | ✓ | Ciclo completo submit/reset/pending |
| 13 | Runtime | ✓ | Validación async sin timers crudos (Standard-Schema) |
| 14 | Docs+tests | ✓ | README ×2, suite ✓ |
| 15 | i18n | ✓ | error-summary-title con `{{count}}` + variante singular |
| # | Dimensión | Estado | Evidencia |
| --- | -------------------- | ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1 | Composición | ✓ | Provider(`<form>` real)/Submit/Reset/ErrorSummary compositivos |
| 2 | Naming | **dato de censo** | **`isPending`/`data-pending`** para async-en-vuelo (morfo :75, types) mientras button/field usan `loading` — DOS nombres para el concepto → \_naming; `disableWhenPristine` en Reset ✓ expresivo; `submitCount` en snippet |
| 3 | Coherencia semántica | ✓ **referencia** | `commit-submit` con intent **fulfill** (:16-24 — el cierre terminal donde la doctrina de button dice que vive el intent fuerte ✓); **`signal-warn-invalid`** untilFix + `requiresFocusMove` + persistent-trace con §6.2 y §9.2 citados y el ciclo clearSignal/clearTarget documentado (:26-53) — CUARTO contrato de referencia de la familia; `commit-reset` neutral ✓ |
| 4 | API | ✓ | Standard-Schema (el adaptador always-async con `untrack` — antecedente de memoria); estados dirty/touched/submitted proyectados |
| 5 | Tokens | ✓ | Gaps por size vía recipe |
| 6 | Sema | ✓ | Pack ✓ — el submit ES el sitio del carácter |
| 7 | Animaciones | ✓ | Sin keyframes |
| 8 | Contrato morfo | ✓ | APG landmark form CORRECTO (:9); `data-{pending,dirty,touched,invalid,submitted}` + aria-busy condicional (:74-88) |
| 9 | A11y | ✓ ejemplar | El focus-move del warn aterriza en el form y `focusFirstInvalid()` perfora al primer campo inválido (documentado :43-48); ErrorSummary con títulos singular/plural interpolados (:12-13) |
| 10 | Theming | ✓ | Focus o1 contenedor |
| 11 | Composición interna | ✓ | ES el otro extremo del OR-merge: Field se registra y deriva dirty/touched/errors de aquí |
| 12 | Estados | ✓ | Ciclo completo submit/reset/pending |
| 13 | Runtime | ✓ | Validación async sin timers crudos (Standard-Schema) |
| 14 | Docs+tests | ✓ | README ×2, suite ✓ |
| 15 | i18n | ✓ | error-summary-title con `{{count}}` + variante singular |
## Hallazgos y propuestas
| ID | Hallazgo | Propuesta |
|---|---|---|
| **F-1** | `isPending` vs `loading` (dos nombres para async-en-vuelo en el catálogo) | Veredicto _naming: elegir uno (nota: `pending` es el término del form nativo/React 19; `loading` el de controles — puede ser DOS conceptos legítimos [form en vuelo vs control ocupado] — decidir si se unifica o se documenta la distinción) |
| ID | Hallazgo | Propuesta |
| ------- | ------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **F-1** | `isPending` vs `loading` (dos nombres para async-en-vuelo en el catálogo) | Veredicto \_naming: elegir uno (nota: `pending` es el término del form nativo/React 19; `loading` el de controles — puede ser DOS conceptos legítimos [form en vuelo vs control ocupado] — decidir si se unifica o se documenta la distinción) |
## Escalan al sistema
_naming (pending vs loading).
\_naming (pending vs loading).
## Veredictos
*(pendiente — checkpoint post-barrido)*
_(pendiente — checkpoint post-barrido)_

@ -1,7 +1,7 @@
# format-date — ficha de auditoría de componente
- **Fecha**: 2026-07-07 · **Familia**: service components · **Método**: solo análisis
- **Máquina**: **NEEDS-WORK** — `D-3.1` (*sin eidosSnippet*) · `F-1.1`/`F-1.4`/`F-1.5` (*expediente + justificación pasivo*).
- **Máquina**: **NEEDS-WORK** — `D-3.1` (_sin eidosSnippet_) · `F-1.1`/`F-1.4`/`F-1.5` (_expediente + justificación pasivo_).
- Ver **trans.md** — misma clase, mismo pass conjunto (expediente compartido + demo snippet). Recordar: `format.getLocale()` NO es reactivo — pasar locale per-call (la memoria del gotcha).
**Escalan**: SYS-7. · **Veredictos**: *(pendiente checkpoint post-barrido)*
**Escalan**: SYS-7. · **Veredictos**: _(pendiente checkpoint post-barrido)_

@ -1,7 +1,7 @@
# format-number — ficha de auditoría de componente
- **Fecha**: 2026-07-07 · **Familia**: service components · **Método**: solo análisis
- **Máquina**: **NEEDS-WORK** — `F-1.1`/`F-1.4`/`F-1.5` (*expediente + justificación pasivo*).
- **Máquina**: **NEEDS-WORK** — `F-1.1`/`F-1.4`/`F-1.5` (_expediente + justificación pasivo_).
- Ver **trans.md** — misma clase, pass conjunto.
**Escalan**: SYS-7. · **Veredictos**: *(pendiente checkpoint post-barrido)*
**Escalan**: SYS-7. · **Veredictos**: _(pendiente checkpoint post-barrido)_

@ -6,26 +6,26 @@
## Dimensiones (evidencia leída)
| # | Dimensión | Estado | Evidencia |
|---|---|---|---|
| 3 | Coherencia semántica | ✓ con infra-declaración | 4 eventos propios: `handle-pick`/`handle-drag` (:26-38 — familia handle, con color-picker) + `commit-set` neutral (:46-51) + 1 más; pack propio ✓; **F-1**: `expression` AUSENTE teniendo pack — legal para el guard actual (OK-si-pack-existe) pero infra-declarado: debería decir `'pack'` (misma clase que los field-ranges, resuelto con SYS-11 d) |
| 5/10 | Theming | ✓ | R-rules limpias (el CSS está sano) |
| 9 | A11y | gap | Sin APG → con gradient-picker |
| 14 | Docs+tests | gap doble | Expediente pre-flight ausente + cero tests → SYS-9/SYS-2 |
| resto | | ✓ | README ×2 ✓ |
| # | Dimensión | Estado | Evidencia |
| ----- | -------------------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| 3 | Coherencia semántica | ✓ con infra-declaración | 4 eventos propios: `handle-pick`/`handle-drag` (:26-38 — familia handle, con color-picker) + `commit-set` neutral (:46-51) + 1 más; pack propio ✓; **F-1**: `expression` AUSENTE teniendo pack — legal para el guard actual (OK-si-pack-existe) pero infra-declarado: debería decir `'pack'` (misma clase que los field-ranges, resuelto con SYS-11 d) |
| 5/10 | Theming | ✓ | R-rules limpias (el CSS está sano) |
| 9 | A11y | gap | Sin APG → con gradient-picker |
| 14 | Docs+tests | gap doble | Expediente pre-flight ausente + cero tests → SYS-9/SYS-2 |
| resto | | ✓ | README ×2 ✓ |
## Hallazgos y propuestas
| ID | Hallazgo | Propuesta |
|---|---|---|
| **F-1** | `expression` sin declarar (pack existe) | Añadir `expression: 'pack'` — SYS-11 (d) |
| **F-2** | Expediente pre-flight ausente | Con gradient-picker (una sesión ambos) |
| **F-3** | Sin APG · cero tests | Declarar patrón + suite — con gradient-picker |
| ID | Hallazgo | Propuesta |
| ------- | --------------------------------------- | --------------------------------------------- |
| **F-1** | `expression` sin declarar (pack existe) | Añadir `expression: 'pack'` — SYS-11 (d) |
| **F-2** | Expediente pre-flight ausente | Con gradient-picker (una sesión ambos) |
| **F-3** | Sin APG · cero tests | Declarar patrón + suite — con gradient-picker |
## Escalan al sistema
SYS-2 · SYS-9 (cerrar gradient-* como paquete) · SYS-11 (d) · **nota de proceso**: la etiqueta BROKEN del catálogo era un artefacto de demo — al excluir demos, ningún componente del catálogo está BROKEN a nivel de capas.
SYS-2 · SYS-9 (cerrar gradient-\* como paquete) · SYS-11 (d) · **nota de proceso**: la etiqueta BROKEN del catálogo era un artefacto de demo — al excluir demos, ningún componente del catálogo está BROKEN a nivel de capas.
## Veredictos
*(pendiente — checkpoint post-barrido)*
_(pendiente — checkpoint post-barrido)_

@ -2,26 +2,26 @@
- **Familia**: pickers (iniciativa gradient 2026-06-27) · **Método**: solo análisis · demos fuera
- **Capas leídas**: [morfo](../../../src/uix/morfo/components/gradient-picker.ts) (162 líneas; expression :19, eventos :29-53+) · pack ✓ existe
- **Máquina**: NEEDS-WORK — `F-1.1`–`F-1.4` (expediente pre-flight ausente) · `A-1.4` (sin APG) · tests **0** *(reglas D-\* de demo fuera de alcance)*
- **Máquina**: NEEDS-WORK — `F-1.1`–`F-1.4` (expediente pre-flight ausente) · `A-1.4` (sin APG) · tests **0** _(reglas D-\* de demo fuera de alcance)_
## Dimensiones (evidencia leída)
| # | Dimensión | Estado | Evidencia |
|---|---|---|---|
| 3 | Coherencia semántica | ✓ con **contradicción de vocabulario** | Eventos propios: `commit-reset` neutral (:29-35) + **`commit-save` FULFILL** (:42-48 — guardar a presets = fulfill, coherente con la doctrina del cierre terminal ✓) + `commit-remove`; **F-1**: declara `expression: 'delegated'` (:19 = "expression lives in children's packs") teniendo 3 eventos PROPIOS y pack PROPIO — la declaración miente; debería ser `'pack'`. El guard `morfo-vocabulary-check` NO lo caza (su regla :37-41 da OK con solo existir el pack, sin cruzar coherencia expression↔pack) |
| 9 | A11y | gap | Sin APG (stops draggables ≈ slider multi-thumb) → F-3 |
| 14 | Docs+tests | **gap doble de proceso** | Expediente pre-flight nunca escrito (F-1.1–1.4) + **cero tests** — la iniciativa quedó a medias (SYS-9) |
| 6 | Sema | ✓ | Pack propio ✓ (funciona pese a F-1: el engine registra por cascada, no por expression) |
| resto | | ✓ | README ×2 ✓ |
| # | Dimensión | Estado | Evidencia |
| ----- | -------------------- | -------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 3 | Coherencia semántica | ✓ con **contradicción de vocabulario** | Eventos propios: `commit-reset` neutral (:29-35) + **`commit-save` FULFILL** (:42-48 — guardar a presets = fulfill, coherente con la doctrina del cierre terminal ✓) + `commit-remove`; **F-1**: declara `expression: 'delegated'` (:19 = "expression lives in children's packs") teniendo 3 eventos PROPIOS y pack PROPIO — la declaración miente; debería ser `'pack'`. El guard `morfo-vocabulary-check` NO lo caza (su regla :37-41 da OK con solo existir el pack, sin cruzar coherencia expression↔pack) |
| 9 | A11y | gap | Sin APG (stops draggables ≈ slider multi-thumb) → F-3 |
| 14 | Docs+tests | **gap doble de proceso** | Expediente pre-flight nunca escrito (F-1.1–1.4) + **cero tests** — la iniciativa quedó a medias (SYS-9) |
| 6 | Sema | ✓ | Pack propio ✓ (funciona pese a F-1: el engine registra por cascada, no por expression) |
| resto | | ✓ | README ×2 ✓ |
## Hallazgos y propuestas
| ID | Hallazgo | Propuesta |
|---|---|---|
| ID | Hallazgo | Propuesta |
| ------- | --------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| **F-1** | `expression: 'delegated'` contradice pack+eventos propios | Cambiar a `'pack'` + **guard**: vocabulary-check debe FAIL con pack-existe∧expression≠'pack' y WARN con pack-existe∧sin-expression → SYS-11 (d) |
| **F-2** | Expediente pre-flight ausente | Escribir las 4 secciones — con gradient-builder en una sesión |
| **F-3** | Sin APG | Declarar (slider multi-thumb) |
| **F-4** | Cero tests | Suite provider (stops add/remove/drag, ángulo, tipo) — SYS-2 |
| **F-2** | Expediente pre-flight ausente | Escribir las 4 secciones — con gradient-builder en una sesión |
| **F-3** | Sin APG | Declarar (slider multi-thumb) |
| **F-4** | Cero tests | Suite provider (stops add/remove/drag, ángulo, tipo) — SYS-2 |
## Escalan al sistema
@ -29,4 +29,4 @@ SYS-2 · SYS-9 · **SYS-11 (d) nuevo: coherencia expression↔pack sin guard**
## Veredictos
*(pendiente — checkpoint post-barrido)*
_(pendiente — checkpoint post-barrido)_

@ -6,18 +6,18 @@
## Dimensiones (evidencia leída)
| # | Dimensión | Estado | Evidencia |
|---|---|---|---|
| 3 | Coherencia semántica | ✓ | select/unselect affirm (:29 — censo unselect=affirm ×5) + family-default declarado |
| 12 | Estados | hallazgo | readonly sin materializar (R-1.3) |
| 14 | Docs+tests | gap + baseline | Sin README eidos; error de tipos preexistente en suite (:307, `role` en attrs — línea base 59) |
| # | Dimensión | Estado | Evidencia |
| --- | -------------------- | -------------- | ---------------------------------------------------------------------------------------------- |
| 3 | Coherencia semántica | ✓ | select/unselect affirm (:29 — censo unselect=affirm ×5) + family-default declarado |
| 12 | Estados | hallazgo | readonly sin materializar (R-1.3) |
| 14 | Docs+tests | gap + baseline | Sin README eidos; error de tipos preexistente en suite (:307, `role` en attrs — línea base 59) |
## Hallazgos y propuestas
| ID | Hallazgo | Propuesta |
|---|---|---|
| **F-1** | README eidos | SYS-4 |
| **F-2** | readonly (R-1.3) | Censo |
| ID | Hallazgo | Propuesta |
| ------- | ----------------------- | ---------------------------- |
| **F-1** | README eidos | SYS-4 |
| **F-2** | readonly (R-1.3) | Censo |
| **F-3** | Error de tipos baseline | Fix trivial en fase de fixes |
## Escalan al sistema
@ -26,4 +26,4 @@ SYS-4 · censo R-1.3 · censo unselect=affirm (+1).
## Veredictos
*(pendiente — checkpoint post-barrido)*
_(pendiente — checkpoint post-barrido)_

@ -3,4 +3,4 @@
- **Fecha**: 2026-07-07 · **Familia**: layout · **Método**: solo análisis
- **Capas**: morfo ✓ (scope eidos) · README eidos ✓ · **Máquina: PASS limpio**.
— limpio. **Escalan**: —. · **Veredictos**: *(pendiente checkpoint post-barrido)*
— limpio. **Escalan**: —. · **Veredictos**: _(pendiente checkpoint post-barrido)_

@ -3,4 +3,4 @@
- **Fecha**: 2026-07-07 · **Familia**: layout (agrupación inline con divisores) · **Método**: solo análisis
- **Capas**: morfo ✓ (scope eidos) · README eidos ✓ · **Máquina: PASS limpio**.
— limpio. **Escalan**: —. · **Veredictos**: *(pendiente checkpoint post-barrido)*
— limpio. **Escalan**: —. · **Veredictos**: _(pendiente checkpoint post-barrido)_

@ -4,7 +4,7 @@
- **Capas**: morfo ✓ (scope eidos) · README eidos ✓ · named styles h1-h6 ✓ (óptica heredada per A.3) · **Máquina: PASS limpio**.
| Hallazgo | Propuesta |
|---|---|
| — limpio | — |
| -------- | --------- |
| — limpio | — |
**Escalan**: —. · **Veredictos**: *(pendiente checkpoint post-barrido)*
**Escalan**: —. · **Veredictos**: _(pendiente checkpoint post-barrido)_

@ -3,4 +3,4 @@
- **Fecha**: 2026-07-07 · **Familia**: tipografía (resaltado de coincidencias) · **Método**: solo análisis
- **Capas**: morfo ✓ (scope eidos) · README eidos ✓ · **Máquina: PASS limpio**.
— limpio. **Escalan**: —. · **Veredictos**: *(pendiente checkpoint post-barrido)*
— limpio. **Escalan**: —. · **Veredictos**: _(pendiente checkpoint post-barrido)_

@ -4,8 +4,8 @@
- **Capas**: morfo — (composición: **compone Button** per decisión, no lo re-implementa) · soma — · README eidos ✓ · pack — (hereda contact) · **Máquina: PASS limpio** · aria-label obligatorio ✓.
- Pendiente registrado de su iniciativa: el ítem ② del Lote 0 quedó abierto — revisar en checkpoint qué era y si sigue vigente.
| Hallazgo | Propuesta |
|---|---|
| Hallazgo | Propuesta |
| -------------------------------------------------------------- | ------------------------------------------------------ |
| F-1: composición sin clasificar + ítem ② de su lote sin cerrar | SYS-7 · rescatar el ítem del registro en el checkpoint |
**Escalan**: SYS-7. · **Veredictos**: *(pendiente checkpoint post-barrido)*
**Escalan**: SYS-7. · **Veredictos**: _(pendiente checkpoint post-barrido)_

@ -3,4 +3,4 @@
- **Fecha**: 2026-07-07 · **Familia**: display (glifos; escala `--icon-size-*` + stroke) · **Método**: solo análisis
- **Capas**: morfo ✓ (scope eidos) · README eidos ✓ · **Máquina: PASS limpio** · aria-hidden por defecto ✓.
— limpio. **Escalan**: —. · **Veredictos**: *(pendiente checkpoint post-barrido)*
— limpio. **Escalan**: —. · **Veredictos**: _(pendiente checkpoint post-barrido)_

@ -7,16 +7,16 @@
## Dimensiones (evidencia leída)
| # | Dimensión | Estado | Evidencia |
|---|---|---|---|
| 3 | Coherencia semántica | ✓ | 1 evento + pack ✓ |
| 2 | Naming | hallazgo menor | **F-1**: 1 hook-clase → censo SYS-1 |
| resto | | ✓ | tests ✓ |
| # | Dimensión | Estado | Evidencia |
| ----- | -------------------- | -------------- | ----------------------------------- |
| 3 | Coherencia semántica | ✓ | 1 evento + pack ✓ |
| 2 | Naming | hallazgo menor | **F-1**: 1 hook-clase → censo SYS-1 |
| resto | | ✓ | tests ✓ |
## Hallazgos y propuestas
| ID | Hallazgo | Propuesta |
|---|---|---|
| ID | Hallazgo | Propuesta |
| ------- | ------------ | ------------- |
| **F-1** | 1 hook-clase | Codemod SYS-1 |
## Escalan al sistema
@ -25,4 +25,4 @@ SYS-1 (censo menor).
## Veredictos
*(pendiente — checkpoint post-barrido)*
_(pendiente — checkpoint post-barrido)_

@ -6,19 +6,19 @@
## Dimensiones (evidencia leída)
| # | Dimensión | Estado | Evidencia |
|---|---|---|---|
| 1 | Composición | ✓ | Preview/Toolbar/Rotate/Remove (:88-133); compone cropper/zoom-pan (capa de la iniciativa 7da7285d) |
| 2 | Naming | hallazgo SYS-1 | **6 hooks-clase** en su CSS (segundo ofensor tras button/cropper) → censo SYS-1 |
| 3 | Coherencia semántica | ✓ | `commit-select` affirm + `commit-remove` neutral + `handle-rotate` neutral (:31-64); `expression: 'pack'` + pack ✓ coherentes |
| 8 | Contrato morfo | **hallazgo nuevo** | **F-2**: `apg:` AUSENTE (censo = 0) y la máquina lo dio por PASS — el censo A-1.4 del informe no lo lista: segundo agujero de regla detectado por la re-auditoría (con el A-3.1 de pin-input) |
| resto | | ✓ | R-rules limpias; tests ✓; README ×2 ✓ |
| # | Dimensión | Estado | Evidencia |
| ----- | -------------------- | ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1 | Composición | ✓ | Preview/Toolbar/Rotate/Remove (:88-133); compone cropper/zoom-pan (capa de la iniciativa 7da7285d) |
| 2 | Naming | hallazgo SYS-1 | **6 hooks-clase** en su CSS (segundo ofensor tras button/cropper) → censo SYS-1 |
| 3 | Coherencia semántica | ✓ | `commit-select` affirm + `commit-remove` neutral + `handle-rotate` neutral (:31-64); `expression: 'pack'` + pack ✓ coherentes |
| 8 | Contrato morfo | **hallazgo nuevo** | **F-2**: `apg:` AUSENTE (censo = 0) y la máquina lo dio por PASS — el censo A-1.4 del informe no lo lista: segundo agujero de regla detectado por la re-auditoría (con el A-3.1 de pin-input) |
| resto | | ✓ | R-rules limpias; tests ✓; README ×2 ✓ |
## Hallazgos y propuestas
| ID | Hallazgo | Propuesta |
|---|---|---|
| **F-1** | 6 hooks-clase | Migrar a `data-image-picker-*` con el codemod del censo SYS-1 (no parche aislado) |
| ID | Hallazgo | Propuesta |
| ------- | ---------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **F-1** | 6 hooks-clase | Migrar a `data-image-picker-*` con el codemod del censo SYS-1 (no parche aislado) |
| **F-2** | Sin cita APG y la regla A-1.4 no lo cazó | Declarar patrón (¿file-upload composite? sin APG oficial → usar la regla nueva "apg: none — rationale" que pide el censo) + arreglar la regla del script |
## Escalan al sistema
@ -27,4 +27,4 @@ SYS-1 · censo A-1.4 (+1 y agujero de regla) · la regla "sin patrón APG oficia
## Veredictos
*(pendiente — checkpoint post-barrido)*
_(pendiente — checkpoint post-barrido)_

@ -2,10 +2,10 @@
- **Fecha**: 2026-07-07 · **Familia**: media (imagen con estados de carga) · **Método**: solo análisis
- **Capas**: morfo ✓ · soma — · README eidos **✗** · pack —
- **Máquina**: **NEEDS-WORK** — `E-2.3` (*falta README eidos*).
- **Máquina**: **NEEDS-WORK** — `E-2.3` (_falta README eidos_).
| Hallazgo | Propuesta |
|---|---|
| F-1: README eidos | SYS-4 |
| Hallazgo | Propuesta |
| ----------------- | --------- |
| F-1: README eidos | SYS-4 |
**Escalan**: SYS-4. · **Veredictos**: *(pendiente checkpoint post-barrido)*
**Escalan**: SYS-4. · **Veredictos**: _(pendiente checkpoint post-barrido)_

@ -3,4 +3,4 @@
- **Fecha**: 2026-07-07 · **Familia**: tipografía (teclas) · **Método**: solo análisis
- **Capas**: morfo ✓ (scope eidos) · README eidos ✓ · mono ✓ · **Máquina: PASS limpio**.
— limpio. **Escalan**: —. · **Veredictos**: *(pendiente checkpoint post-barrido)*
— limpio. **Escalan**: —. · **Veredictos**: _(pendiente checkpoint post-barrido)_

@ -6,19 +6,19 @@
## Dimensiones (evidencia leída)
| # | Dimensión | Estado | Evidencia |
|---|---|---|---|
| 1 | Composición | ✓ ejemplar | Anatomía completa: Control/Indicator/Label/ValueText/**ValueField** (:159 — compone NumberField DENTRO, el patrón compound-in-component de memoria: aislamiento de eventos, maxLength) /**HiddenInput** (:172 — form-bridge declarado como radio-group) |
| 3 | Coherencia semántica | ✓ ciclo completo | **`handle-pick`/`handle-drag`/`handle-drop`** (:188-215 — la trilogía de manipulación MÁS completa del censo handle: incluye el drop que color-picker/gradient no declaran) + `commit-set` (:226) + `commit-reset` neutral (:242-248); pack ✓; `Gesture.rotate` (C7) ✓ |
| 8 | Contrato morfo | ✓ | APG citado |
| 10 | Theming | censo | Focus outline (o3) → SYS-5 |
| 14 | Docs | gap | Sin README eidos → SYS-4 |
| resto | | ✓ | tests ✓ |
| # | Dimensión | Estado | Evidencia |
| ----- | -------------------- | ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1 | Composición | ✓ ejemplar | Anatomía completa: Control/Indicator/Label/ValueText/**ValueField** (:159 — compone NumberField DENTRO, el patrón compound-in-component de memoria: aislamiento de eventos, maxLength) /**HiddenInput** (:172 — form-bridge declarado como radio-group) |
| 3 | Coherencia semántica | ✓ ciclo completo | **`handle-pick`/`handle-drag`/`handle-drop`** (:188-215 — la trilogía de manipulación MÁS completa del censo handle: incluye el drop que color-picker/gradient no declaran) + `commit-set` (:226) + `commit-reset` neutral (:242-248); pack ✓; `Gesture.rotate` (C7) ✓ |
| 8 | Contrato morfo | ✓ | APG citado |
| 10 | Theming | censo | Focus outline (o3) → SYS-5 |
| 14 | Docs | gap | Sin README eidos → SYS-4 |
| resto | | ✓ | tests ✓ |
## Hallazgos y propuestas
| ID | Hallazgo | Propuesta |
|---|---|---|
| ID | Hallazgo | Propuesta |
| ------- | ---------------------------- | ------------------------------------------- |
| **F-1** | README eidos ausente (E-2.3) | Crearlo (arcos, ticks, value-field) — SYS-4 |
## Escalan al sistema
@ -27,4 +27,4 @@ SYS-4 · censo handle (knob = el ciclo pick/drag/drop completo — referencia pa
## Veredictos
*(pendiente — checkpoint post-barrido)*
_(pendiente — checkpoint post-barrido)_

@ -3,4 +3,4 @@
- **Fecha**: 2026-07-07 · **Familia**: tipografía/forms (standalone Label, portado eidos-native en la iniciativa floating-label 07-05) · **Método**: solo análisis
- **Capas**: morfo ✓ (scope eidos) · README eidos ✓ · named style label = EL ancla de la tipografía UI (`--style-label-font-family` post-A.9, con validación de config) ✓ · **Máquina: PASS limpio**.
— limpio. **Escalan**: —. · **Veredictos**: *(pendiente checkpoint post-barrido)*
— limpio. **Escalan**: —. · **Veredictos**: _(pendiente checkpoint post-barrido)_

@ -6,16 +6,16 @@
## Dimensiones (evidencia leída)
| # | Dimensión | Estado | Evidencia |
|---|---|---|---|
| 3 | Coherencia semántica | ✓ consistente pero MUDA | 0 eventos + scope sin sema = silencio by-design coherente (hover-card: sonido en hover sería ruido)… pero es el ÚNICO 0-eventos de overlays SIN una línea de razón (ntp/alert-dialog/radio-cards/fab/banner todos la escriben) → F-2 |
| 14 | Docs | gap | Sin README eidos |
| # | Dimensión | Estado | Evidencia |
| --- | -------------------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| 3 | Coherencia semántica | ✓ consistente pero MUDA | 0 eventos + scope sin sema = silencio by-design coherente (hover-card: sonido en hover sería ruido)… pero es el ÚNICO 0-eventos de overlays SIN una línea de razón (ntp/alert-dialog/radio-cards/fab/banner todos la escriben) → F-2 |
| 14 | Docs | gap | Sin README eidos |
## Hallazgos y propuestas
| ID | Hallazgo | Propuesta |
|---|---|---|
| **F-1** | README eidos ausente | SYS-4 |
| ID | Hallazgo | Propuesta |
| ------- | ---------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **F-1** | README eidos ausente | SYS-4 |
| **F-2** | Silencio sin razón escrita (los 5 pares delegados/pasivos de la familia la tienen) | Una línea en el morfo ("hover-signal pasiva: present/dismiss viajan por el canal motion; sonido = ruido en hover") — cierra el caso como by-design documentado (SYS-3) |
## Escalan al sistema
@ -24,4 +24,4 @@ SYS-3 (candidato a silencio by-design — solo falta escribirlo) · SYS-4.
## Veredictos
*(pendiente — checkpoint post-barrido)*
_(pendiente — checkpoint post-barrido)_

@ -6,15 +6,15 @@
## Dimensiones (evidencia leída)
| # | Dimensión | Estado | Evidencia |
|---|---|---|---|
| 3/8 | Semántica y contrato | ✓ pasivo documentado | Header: "Passive on the morfo surface… renders `<a>` by default (or `<span aria-disabled>` when disabled). **Inherits ambient typography — no own style prop — so it composes mid-paragraph without breaking the text scale**" — la razón de diseño escrita (semántica nativa del anchor; sin robo de escala tipográfica) ✓ |
| 4 | API | verificación pendiente | **F-1**: la doctrina de primitivas tipográficas exigió que Link exponga size/color como Text (fue el ejemplo prop-less a NO imitar) — el header dice "no own style prop" A PROPÓSITO (composición mid-paragraph): puede haber TENSIÓN entre la doctrina y esta razón → el veredicto decide (¿props opcionales que preservan herencia por defecto?) |
| # | Dimensión | Estado | Evidencia |
| --- | -------------------- | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 3/8 | Semántica y contrato | ✓ pasivo documentado | Header: "Passive on the morfo surface… renders `<a>` by default (or `<span aria-disabled>` when disabled). **Inherits ambient typography — no own style prop — so it composes mid-paragraph without breaking the text scale**" — la razón de diseño escrita (semántica nativa del anchor; sin robo de escala tipográfica) ✓ |
| 4 | API | verificación pendiente | **F-1**: la doctrina de primitivas tipográficas exigió que Link exponga size/color como Text (fue el ejemplo prop-less a NO imitar) — el header dice "no own style prop" A PROPÓSITO (composición mid-paragraph): puede haber TENSIÓN entre la doctrina y esta razón → el veredicto decide (¿props opcionales que preservan herencia por defecto?) |
## Hallazgos y propuestas
| ID | Hallazgo | Propuesta |
|---|---|---|
| ID | Hallazgo | Propuesta |
| ------- | ----------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
| **F-1** | Doctrina typographic-props vs razón "inherits ambient" del header | Veredicto: props visuales OPCIONALES con default herencia (satisface ambas) o excepción documentada |
## Escalan al sistema
@ -23,4 +23,4 @@ La tensión doctrina↔header (dato para el veredicto de primitivas tipográfica
## Veredictos
*(pendiente — checkpoint post-barrido)*
_(pendiente — checkpoint post-barrido)_

@ -6,18 +6,18 @@
## Dimensiones (evidencia leída)
| # | Dimensión | Estado | Evidencia |
|---|---|---|---|
| 3 | Coherencia semántica | ✓ declarado, con pregunta | select/unselect affirm (censo ×5) + family-default DECLARADO — pero su hermano select (misma semántica de selección) tiene pack: la asimetría es la pregunta SYS-3 en su forma más nítida (¿el standalone hereda el criterio del compuesto?) |
| 12 | Estados | hallazgo | readonly sin materializar (R-1.3) |
| 14 | Docs | gap | Sin README eidos |
| # | Dimensión | Estado | Evidencia |
| --- | -------------------- | ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 3 | Coherencia semántica | ✓ declarado, con pregunta | select/unselect affirm (censo ×5) + family-default DECLARADO — pero su hermano select (misma semántica de selección) tiene pack: la asimetría es la pregunta SYS-3 en su forma más nítida (¿el standalone hereda el criterio del compuesto?) |
| 12 | Estados | hallazgo | readonly sin materializar (R-1.3) |
| 14 | Docs | gap | Sin README eidos |
## Hallazgos y propuestas
| ID | Hallazgo | Propuesta |
|---|---|---|
| **F-1** | README eidos | SYS-4 |
| **F-2** | readonly (R-1.3) | Censo |
| ID | Hallazgo | Propuesta |
| ------- | ----------------------------------------------- | ------------------------------------------------------------- |
| **F-1** | README eidos | SYS-4 |
| **F-2** | readonly (R-1.3) | Censo |
| **F-3** | select con pack / listbox sin — misma semántica | SYS-3: clonar el criterio del hermano o razonar la diferencia |
## Escalan al sistema
@ -26,4 +26,4 @@ SYS-3 (el par select↔listbox) · SYS-4 · censos R-1.3, unselect=affirm.
## Veredictos
*(pendiente — checkpoint post-barrido)*
_(pendiente — checkpoint post-barrido)_

@ -3,4 +3,4 @@
- **Fecha**: 2026-07-07 · **Familia**: tipografía (resaltado semántico) · **Método**: solo análisis
- **Capas**: morfo ✓ (scope eidos) · README eidos ✓ · **Máquina: PASS limpio**.
— limpio. **Escalan**: —. · **Veredictos**: *(pendiente checkpoint post-barrido)*
— limpio. **Escalan**: —. · **Veredictos**: _(pendiente checkpoint post-barrido)_

@ -3,4 +3,4 @@
- **Fecha**: 2026-07-07 · **Familia**: display (puntos/pins) · **Método**: solo análisis
- **Capas**: morfo ✓ · README eidos ✓ · **Máquina: PASS limpio** · excepción tipográfica canónica ✓ (glifo ∝ diámetro, §5) · variantes solid/soft/outline (§19) ✓.
— limpio. **Escalan**: —. · **Veredictos**: *(pendiente checkpoint post-barrido)*
— limpio. **Escalan**: —. · **Veredictos**: _(pendiente checkpoint post-barrido)_

@ -6,36 +6,36 @@
## Dimensiones (evidencia leída)
| # | Dimensión | Estado | Evidencia |
|---|---|---|---|
| 1 | Composición | ✓ | Single-input compositivo; el morfo RAZONA por qué NO se fragmenta en fake-segments (eso es de Date/Time — :18-20) |
| 2 | Naming | ✓ con dato nuevo | `value/onValueChange` ✓ + **`onValueCommit: OnChangeFn`** para blur/Enter (types :75-76) — TERCER patrón de callback terminal del catálogo (vs `onSubmit` crudo de search/password) → fila clave en _naming; `showMask/placeholderChar/definitions` (decisiones locked); `unmaskedValue` como derivado read-only en snippet (:19-20) |
| 3 | Coherencia semántica | ✓ | `commit-set` solo en confirmación — la doctrina teclear≠commit citada y alineada (morfo :43-47); `expression: 'pack'` + pack ✓ |
| 4 | API | ✓ ejemplar | Alfabeto de tokens documentado con escape y cola opcional (`\9`, `[ ... ]` — types :47-53); `definitions` merge-over con RegExp por slot (:55-60); modelo de valor = string enmascarado con la convención de la industria citada (morfo :25-28) |
| 5 | Tokens | ✓ con dup | `height-{k}` duplicada (SYS-6); tokens 9-A-* del engine per decisión |
| 6 | Sema | ✓ | Pack ✓ |
| 7 | Animaciones | ✓ | `showMask` revela esqueleto sin keyframes |
| 8 | Contrato morfo | ✓ | APG textbox CORRECTO (:41 — un solo textbox, no combobox como search); `data-complete` con razón (intrínseco a máscara, gate de submit sin re-derivar — :74-77); flags focused/empty ✓ |
| 9 | A11y | ✓ con doctrina propia | **Valor anunciado siempre veraz**: los keystrokes rechazados REVIERTEN visiblemente en vez de tragarse en silencio (el lector siempre relee el valor comprometido — morfo :21-23) — doctrina exportable a cualquier input con formateo |
| 10 | Theming | hallazgo | R-1.3 readonly sin estilo (patrón familia) |
| 11 | Composición interna | ✓ documentada | Field integration EXPLÍCITA: el Input se registra en `Field.inputId` → Label/Helper/Error se auto-cablean (types :35-38) — de lo poco de la familia que documenta el wiring |
| 12 | Estados | ✓ | complete/focused/empty + OR-merge; `name` envía el valor ENMASCARADO (documentado :89) |
| 13 | Runtime | ✓ | Engine puro con suite propia; sin timers/DOM crudo |
| 14 | Docs+tests | ✓ el mejor de la familia | 2 suites (engine + provider) |
| 15 | i18n | ✓ | translationRef en aria-label; texts morfo |
| # | Dimensión | Estado | Evidencia |
| --- | -------------------- | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1 | Composición | ✓ | Single-input compositivo; el morfo RAZONA por qué NO se fragmenta en fake-segments (eso es de Date/Time — :18-20) |
| 2 | Naming | ✓ con dato nuevo | `value/onValueChange` ✓ + **`onValueCommit: OnChangeFn`** para blur/Enter (types :75-76) — TERCER patrón de callback terminal del catálogo (vs `onSubmit` crudo de search/password) → fila clave en \_naming; `showMask/placeholderChar/definitions` (decisiones locked); `unmaskedValue` como derivado read-only en snippet (:19-20) |
| 3 | Coherencia semántica | ✓ | `commit-set` solo en confirmación — la doctrina teclear≠commit citada y alineada (morfo :43-47); `expression: 'pack'` + pack ✓ |
| 4 | API | ✓ ejemplar | Alfabeto de tokens documentado con escape y cola opcional (`\9`, `[ ... ]` — types :47-53); `definitions` merge-over con RegExp por slot (:55-60); modelo de valor = string enmascarado con la convención de la industria citada (morfo :25-28) |
| 5 | Tokens | ✓ con dup | `height-{k}` duplicada (SYS-6); tokens 9-A-\* del engine per decisión |
| 6 | Sema | ✓ | Pack ✓ |
| 7 | Animaciones | ✓ | `showMask` revela esqueleto sin keyframes |
| 8 | Contrato morfo | ✓ | APG textbox CORRECTO (:41 — un solo textbox, no combobox como search); `data-complete` con razón (intrínseco a máscara, gate de submit sin re-derivar — :74-77); flags focused/empty ✓ |
| 9 | A11y | ✓ con doctrina propia | **Valor anunciado siempre veraz**: los keystrokes rechazados REVIERTEN visiblemente en vez de tragarse en silencio (el lector siempre relee el valor comprometido — morfo :21-23) — doctrina exportable a cualquier input con formateo |
| 10 | Theming | hallazgo | R-1.3 readonly sin estilo (patrón familia) |
| 11 | Composición interna | ✓ documentada | Field integration EXPLÍCITA: el Input se registra en `Field.inputId` → Label/Helper/Error se auto-cablean (types :35-38) — de lo poco de la familia que documenta el wiring |
| 12 | Estados | ✓ | complete/focused/empty + OR-merge; `name` envía el valor ENMASCARADO (documentado :89) |
| 13 | Runtime | ✓ | Engine puro con suite propia; sin timers/DOM crudo |
| 14 | Docs+tests | ✓ el mejor de la familia | 2 suites (engine + provider) |
| 15 | i18n | ✓ | translationRef en aria-label; texts morfo |
## Hallazgos y propuestas
| ID | Hallazgo | Propuesta |
|---|---|---|
| **F-1** | readonly sin estilo (R-1.3) | Tratamiento único de familia |
| **F-2** | `height-{k}` duplicada | SYS-6 |
| **Nota ✓** | `onValueCommit` (OnChangeFn) es candidato a CANON del callback terminal (vs `onSubmit` crudo) — coincide con la convención Radix/bits del slider | Veredicto _naming: unificar el trío de patrones |
| ID | Hallazgo | Propuesta |
| ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------ |
| **F-1** | readonly sin estilo (R-1.3) | Tratamiento único de familia |
| **F-2** | `height-{k}` duplicada | SYS-6 |
| **Nota ✓** | `onValueCommit` (OnChangeFn) es candidato a CANON del callback terminal (vs `onSubmit` crudo) — coincide con la convención Radix/bits del slider | Veredicto \_naming: unificar el trío de patrones |
## Escalan al sistema
_naming (callback terminal: onValueCommit vs onSubmit vs solo-evento) · SYS-5 · SYS-6 · doctrina "valor anunciado veraz" exportable.
\_naming (callback terminal: onValueCommit vs onSubmit vs solo-evento) · SYS-5 · SYS-6 · doctrina "valor anunciado veraz" exportable.
## Veredictos
*(pendiente — checkpoint post-barrido)*
_(pendiente — checkpoint post-barrido)_

@ -2,24 +2,24 @@
- **Familia**: media (genérico, sin baseline APG per registro 06-29) · **Método**: solo análisis · demos fuera
- **Capas leídas**: [morfo](../../../src/uix/morfo/components/media-player.ts) (525 líneas — el más grande del catálogo; **12 eventos** con `family-default` declarado, apg=0)
- **Máquina**: NEEDS-WORK — `A-3.6` (4 nombres fuera de gramática: `enter-fullscreen`, `exit-fullscreen`, `enter-pip`, `exit-pip`) · `A-1.4` *(D-\* demo fuera)* · tests ✓
- **Máquina**: NEEDS-WORK — `A-3.6` (4 nombres fuera de gramática: `enter-fullscreen`, `exit-fullscreen`, `enter-pip`, `exit-pip`) · `A-1.4` _(D-\* demo fuera)_ · tests ✓
## Dimensiones (evidencia leída)
| # | Dimensión | Estado | Evidencia |
|---|---|---|---|
| 3 | Coherencia semántica | ✓ declarado con 2 hallazgos | 12 eventos (el contrato interactivo más rico) + family-default ESCRITO; **F-1**: 4 nombres violan `{familia}-{verbo}` (los únicos A-3.6 confirmados del catálogo junto al commit-crop de cropper) · **F-2**: family-default para play/pause/seek/volume — SYS-3 candidato mayor (12 eventos con carácter genérico) |
| 8 | Contrato morfo | hallazgo documentado | Sin APG — decisión REGISTRADA (06-29: no existe patrón de media player) pero el morfo no la lleva → la regla "apg: none — rationale" nació de este caso |
| 12 | Gap registrado | | **F-4**: Slider sin buffered-range (la pista de buffer) — diseño en fase de fixes (slider WIP usuario) |
| # | Dimensión | Estado | Evidencia |
| --- | -------------------- | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| 3 | Coherencia semántica | ✓ declarado con 2 hallazgos | 12 eventos (el contrato interactivo más rico) + family-default ESCRITO; **F-1**: 4 nombres violan `{familia}-{verbo}` (los únicos A-3.6 confirmados del catálogo junto al commit-crop de cropper) · **F-2**: family-default para play/pause/seek/volume — SYS-3 candidato mayor (12 eventos con carácter genérico) |
| 8 | Contrato morfo | hallazgo documentado | Sin APG — decisión REGISTRADA (06-29: no existe patrón de media player) pero el morfo no la lleva → la regla "apg: none — rationale" nació de este caso |
| 12 | Gap registrado | | **F-4**: Slider sin buffered-range (la pista de buffer) — diseño en fase de fixes (slider WIP usuario) |
## Hallazgos y propuestas
| ID | Hallazgo | Propuesta |
|---|---|---|
| ID | Hallazgo | Propuesta |
| ------- | ------------------------------------ | ----------------------------------------------------------------------------------------------------- |
| **F-1** | 4 nombres fuera de gramática (A-3.6) | Renombrar (p.ej. `shift-fullscreen-enter` o par `shift.mode`) — decisión de vocabulario en checkpoint |
| **F-2** | 12 eventos a default | SYS-3 (pack tras F-1) |
| **F-3** | APG "none" sin campo | La regla nueva + anotar la referencia de diseño usada |
| **F-4** | Buffered-range del Slider | Con el pass del slider post-WIP |
| **F-2** | 12 eventos a default | SYS-3 (pack tras F-1) |
| **F-3** | APG "none" sin campo | La regla nueva + anotar la referencia de diseño usada |
| **F-4** | Buffered-range del Slider | Con el pass del slider post-WIP |
## Escalan al sistema
@ -27,4 +27,4 @@ SYS-3 · censo A-3.6 (con cropper) · la regla "sin patrón APG" (caso fundador)
## Veredictos
*(pendiente — checkpoint post-barrido)*
_(pendiente — checkpoint post-barrido)_

@ -12,8 +12,8 @@ open/close/select coherentes con los menús. La pregunta del carácter radial
## Hallazgos y propuestas
| ID | Hallazgo | Propuesta |
|---|---|---|
| ID | Hallazgo | Propuesta |
| ------- | --------------------------- | -------------------- |
| **F-1** | ¿Pack para el gesto radial? | SYS-3 con onion-menu |
## Escalan al sistema
@ -22,4 +22,4 @@ SYS-3.
## Veredictos
*(pendiente — checkpoint post-barrido)*
_(pendiente — checkpoint post-barrido)_

@ -6,17 +6,17 @@
## Dimensiones (evidencia leída)
| # | Dimensión | Estado | Evidencia |
|---|---|---|---|
| 3 | Coherencia semántica | ✓ razonada in-place | `expression: 'pack'` con la nota (:8-10): "subtle commit + tap haptic for **high-frequency top-level menu triggers**" — el pack existe Y su porqué está escrito; UN evento select (los submenús delegan en dropdown-menu compuesto) |
| 8 | Contrato morfo | ✓ | APG menubar (:12); morfo thin coherente con la delegación |
| 14 | Docs | gap | Sin README eidos → SYS-4 |
| # | Dimensión | Estado | Evidencia |
| --- | -------------------- | ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 3 | Coherencia semántica | ✓ razonada in-place | `expression: 'pack'` con la nota (:8-10): "subtle commit + tap haptic for **high-frequency top-level menu triggers**" — el pack existe Y su porqué está escrito; UN evento select (los submenús delegan en dropdown-menu compuesto) |
| 8 | Contrato morfo | ✓ | APG menubar (:12); morfo thin coherente con la delegación |
| 14 | Docs | gap | Sin README eidos → SYS-4 |
## Hallazgos y propuestas
| ID | Hallazgo | Propuesta |
|---|---|---|
| **F-1** | README eidos ausente | SYS-4 |
| ID | Hallazgo | Propuesta |
| ------- | -------------------- | --------- |
| **F-1** | README eidos ausente | SYS-4 |
## Escalan al sistema
@ -24,4 +24,4 @@ SYS-4 · quinta cita del patrón delegación (submenús → dropdown-menu).
## Veredictos
*(pendiente — checkpoint post-barrido)*
_(pendiente — checkpoint post-barrido)_

@ -4,8 +4,8 @@
- **Capas**: morfo ✓ · soma (tests: 1 ✓) · README soma ✓ / eidos ✓ · pack — · **Máquina: PASS limpio**.
- **HUECO CVD ABIERTO documentado** (G3 §25 + decisión D-3 del informe de theming): las zonas son SOLO-color (WCAG 1.4.1) — es EL caso pendiente del catálogo.
| Hallazgo | Propuesta |
|---|---|
| Hallazgo | Propuesta |
| -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| F-1: zonas solo-color (hueco G3) | Resolver con la decisión D-3 del informe (cue no-cromático: patrón/tick por zona, o dev-warning) — el veredicto es del checkpoint de theming, este es su componente |
**Escalan**: D-3 (theming). · **Veredictos**: *(pendiente checkpoint post-barrido)*
**Escalan**: D-3 (theming). · **Veredictos**: _(pendiente checkpoint post-barrido)_

@ -2,22 +2,22 @@
- **Familia**: data (KPIs/value-flash) · **Método**: solo análisis · demos fuera
- **Capas leídas**: [morfo](../../../src/uix/morfo/components/metrics.ts) (225 líneas; 2 eventos con `family-default` declarado, apg=0)
- **Máquina**: `F-1.1`–`F-1.4` (expediente ausente) · `A-1.4` · tests **0** *(su D-1.2 era demo — fuera)*
- **Máquina**: `F-1.1`–`F-1.4` (expediente ausente) · `A-1.4` · tests **0** _(su D-1.2 era demo — fuera)_
## Dimensiones (evidencia leída)
| # | Dimensión | Estado | Evidencia |
|---|---|---|---|
| 3 | Coherencia semántica | ✓ declarado | 2 eventos family-default; value-flash por intent = materialización per-component del canal signal (patrón materials R-4.5 ✓) |
| 8 | Contrato morfo | gap | Sin APG (display de datos → probablemente "none — rationale") |
| 14 | Docs+tests | gap doble | Expediente ausente + **cero tests** |
| # | Dimensión | Estado | Evidencia |
| --- | -------------------- | ----------- | ---------------------------------------------------------------------------------------------------------------------------- |
| 3 | Coherencia semántica | ✓ declarado | 2 eventos family-default; value-flash por intent = materialización per-component del canal signal (patrón materials R-4.5 ✓) |
| 8 | Contrato morfo | gap | Sin APG (display de datos → probablemente "none — rationale") |
| 14 | Docs+tests | gap doble | Expediente ausente + **cero tests** |
## Hallazgos y propuestas
| ID | Hallazgo | Propuesta |
|---|---|---|
| **F-1** | Expediente + APG | Secciones + regla "none" |
| **F-2** | Cero tests | Suite (value-flash por intent) — SYS-2 |
| ID | Hallazgo | Propuesta |
| ------- | ---------------- | -------------------------------------- |
| **F-1** | Expediente + APG | Secciones + regla "none" |
| **F-2** | Cero tests | Suite (value-flash por intent) — SYS-2 |
## Escalan al sistema
@ -25,4 +25,4 @@ SYS-2 · SYS-9 · censo A-1.4.
## Veredictos
*(pendiente — checkpoint post-barrido)*
_(pendiente — checkpoint post-barrido)_

@ -6,24 +6,24 @@
## Dimensiones (evidencia leída)
| # | Dimensión | Estado | Evidencia |
|---|---|---|---|
| 1 | Composición | ✓ | Provider/Header/Heading/Prev/Next/Grid/Cell — SIN Day interno: el Cell `role='gridcell'` (:187) es el objetivo directo con `data-focused` (:194) → roving sobre gridcells, APG-válido, y **`aria-selected` AQUÍ SÍ es legal** (:200 sobre gridcell) — la estructura de 2 niveles del calendar (Cell+Day button) no se replicó y eso EVITA el ARIA inválido ✓ |
| 2 | Naming | ✓ | `data-current` (:192 — el "hoy" de meses) + data-value/selected/disabled/focused |
| 3 | Coherencia semántica | ✓ | `commit-set` (affirm :17-22 — fija mes, coherente con date-field) + `shift-navigate-step` (:31-34, cualificador legal de la gramática) |
| 6 | Sema | gap | Sin pack → SYS-3 (censo familia: 0 packs salvo donante) |
| 8 | Contrato morfo | con censo | **F-1**: `role='application'` (:47) heredado sin razón — censo familia ×4 |
| 14 | Docs+tests | gap | **Cero tests** (navegación de grid, select, rangos disabled) → SYS-2 |
| 11 | Composición interna | **borrower doble-roto** | 65 `--calendar-*` + `event-shadow` SIN declarar siquiera el privado de acento (0 declaraciones — B.2): marcas doblemente muertas → SYS-8 |
| resto | | ✓ | Espejo estructural del donante en grid de meses |
| # | Dimensión | Estado | Evidencia |
| ----- | -------------------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| 1 | Composición | ✓ | Provider/Header/Heading/Prev/Next/Grid/Cell — SIN Day interno: el Cell `role='gridcell'` (:187) es el objetivo directo con `data-focused` (:194) → roving sobre gridcells, APG-válido, y **`aria-selected` AQUÍ SÍ es legal** (:200 sobre gridcell) — la estructura de 2 niveles del calendar (Cell+Day button) no se replicó y eso EVITA el ARIA inválido ✓ |
| 2 | Naming | ✓ | `data-current` (:192 — el "hoy" de meses) + data-value/selected/disabled/focused |
| 3 | Coherencia semántica | ✓ | `commit-set` (affirm :17-22 — fija mes, coherente con date-field) + `shift-navigate-step` (:31-34, cualificador legal de la gramática) |
| 6 | Sema | gap | Sin pack → SYS-3 (censo familia: 0 packs salvo donante) |
| 8 | Contrato morfo | con censo | **F-1**: `role='application'` (:47) heredado sin razón — censo familia ×4 |
| 14 | Docs+tests | gap | **Cero tests** (navegación de grid, select, rangos disabled) → SYS-2 |
| 11 | Composición interna | **borrower doble-roto** | 65 `--calendar-*` + `event-shadow` SIN declarar siquiera el privado de acento (0 declaraciones — B.2): marcas doblemente muertas → SYS-8 |
| resto | | ✓ | Espejo estructural del donante en grid de meses |
## Hallazgos y propuestas
| ID | Hallazgo | Propuesta |
|---|---|---|
| **F-1** | `role='application'` sin razón | Decisión única de familia (con calendar F-1) |
| **F-2** | Marcas de evento doblemente muertas (borrow + privado ausente) | SYS-8: con la capa formal recibe marcas Y acentos |
| **F-3** | Cero tests | SYS-2 |
| ID | Hallazgo | Propuesta |
| ---------- | ------------------------------------------------------------------------------ | ------------------------------------------------------- |
| **F-1** | `role='application'` sin razón | Decisión única de familia (con calendar F-1) |
| **F-2** | Marcas de evento doblemente muertas (borrow + privado ausente) | SYS-8: con la capa formal recibe marcas Y acentos |
| **F-3** | Cero tests | SYS-2 |
| **Nota ✓** | La estructura Cell-directo (sin Day button) evita el ARIA inválido del donante | Citar en el fix de calendar F-2 como referencia interna |
## Escalan al sistema
@ -32,4 +32,4 @@ SYS-2 · SYS-3 · SYS-8 · censo `role='application'`.
## Veredictos
*(pendiente — checkpoint post-barrido)*
_(pendiente — checkpoint post-barrido)_

@ -3,4 +3,4 @@
- **Fecha**: 2026-07-07 · **Familia**: util (wrapper declarativo del canal motion: presence/presets) · **Método**: solo análisis
- **Capas**: morfo ✓ · README eidos ✓ · **Máquina: PASS limpio** · consume `uix.motion` (el art) ✓ — no re-implementa.
— limpio. **Escalan**: —. · **Veredictos**: *(pendiente checkpoint post-barrido)*
— limpio. **Escalan**: —. · **Veredictos**: _(pendiente checkpoint post-barrido)_

@ -7,26 +7,26 @@
## Dimensiones (evidencia leída)
| # | Dimensión | Estado | Evidencia |
|---|---|---|---|
| 1 | Composición | ✓ documentada | Header :10-15: solo el gradiente daylight es bespoke; todo lo demás compone primitivos del sistema — el espíritu "compose existing components" cumplido y ESCRITO |
| 3 | Coherencia semántica | **gap heredado, no propio** | **F-1**: la cadena semántica tiene un eslabón hueco — el valor comete por TimeField (commit-set ✓ del embebido), pero Listo/Cancelar/Borrar fluyen por el Picker genérico cuyo morfo declara 0 eventos (deuda RECONOCIDA en picker :18-19 "candidate commit-* events for a later sema pass"). El "Listo" de un picker (el gesto más commit del patrón) suena a Button contact genérico |
| 5 | Tokens | hallazgo matizado | Los 9 hex (R-2.1) son los CIELOS — la excepción *physically-fixed* existe justo para esto PERO exige anotación `/* literal: … */` línea a línea y no la llevan → F-2 (anotar, NO tokenizar) |
| 8 | Contrato morfo | ✓ moderno | `data-state` CON values `['open','closed']` enumerados (:39,:75,:96 — el patrón que calendar F-3 pide) + `data-starting-style`/`data-ending-style` condicionales (:97-106, hooks de motion) + flags disabled/readonly/required/invalid |
| 9 | A11y | gap menor | Trigger completo (haspopup dialog + expanded + label vía translationRef ✓ :76-85); Content con Escape/Tab trap (:109-113); **F-3**: sin cita APG (A-1.4) — la razón "Popover posee el diálogo" merece la cita del patrón compuesto como hace date-picker (apg ×2) |
| 12 | Estados | hallazgo máquina | R-1.3/R-1.4 readonly/invalid sin materializar |
| 14 | Docs+tests | **gap triple** | Sin README (ninguno de los dos niveles), sin tests |
| 15 | i18n | ✓ | texts + translationRef localizados (:24-27,:82) |
| # | Dimensión | Estado | Evidencia |
| --- | -------------------- | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1 | Composición | ✓ documentada | Header :10-15: solo el gradiente daylight es bespoke; todo lo demás compone primitivos del sistema — el espíritu "compose existing components" cumplido y ESCRITO |
| 3 | Coherencia semántica | **gap heredado, no propio** | **F-1**: la cadena semántica tiene un eslabón hueco — el valor comete por TimeField (commit-set ✓ del embebido), pero Listo/Cancelar/Borrar fluyen por el Picker genérico cuyo morfo declara 0 eventos (deuda RECONOCIDA en picker :18-19 "candidate commit-\* events for a later sema pass"). El "Listo" de un picker (el gesto más commit del patrón) suena a Button contact genérico |
| 5 | Tokens | hallazgo matizado | Los 9 hex (R-2.1) son los CIELOS — la excepción _physically-fixed_ existe justo para esto PERO exige anotación `/* literal: … */` línea a línea y no la llevan → F-2 (anotar, NO tokenizar) |
| 8 | Contrato morfo | ✓ moderno | `data-state` CON values `['open','closed']` enumerados (:39,:75,:96 — el patrón que calendar F-3 pide) + `data-starting-style`/`data-ending-style` condicionales (:97-106, hooks de motion) + flags disabled/readonly/required/invalid |
| 9 | A11y | gap menor | Trigger completo (haspopup dialog + expanded + label vía translationRef ✓ :76-85); Content con Escape/Tab trap (:109-113); **F-3**: sin cita APG (A-1.4) — la razón "Popover posee el diálogo" merece la cita del patrón compuesto como hace date-picker (apg ×2) |
| 12 | Estados | hallazgo máquina | R-1.3/R-1.4 readonly/invalid sin materializar |
| 14 | Docs+tests | **gap triple** | Sin README (ninguno de los dos niveles), sin tests |
| 15 | i18n | ✓ | texts + translationRef localizados (:24-27,:82) |
## Hallazgos y propuestas
| ID | Hallazgo | Propuesta |
|---|---|---|
| ID | Hallazgo | Propuesta |
| ------- | --------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **F-1** | El footer transaccional no tiene semántica (deuda del Picker genérico, reconocida allí) | Resolver EN el Picker genérico (commit-set fulfill en Accept / commit-cancel neutral / commit-clear neutral) — ntp y los 5 pickers a migrar lo heredan gratis; NO declarar eventos propios aquí (rompería la delegación correcta) |
| **F-2** | 9 hex sin anotación (R-2.1) | Anotar cada uno `/* literal: physically-fixed sky/astro color */`; NO tokenizar |
| **F-3** | Sin cita APG (A-1.4) | Citar el patrón compuesto (dialog vía Popover) como date-picker; valorar además slider APG para la banda |
| **F-4** | readonly/invalid sin estilo | Patrón familia |
| **F-5** | Sin README ×2, sin tests | Paquete de estándares completo (SYS-9: iniciativa a medias) |
| **F-2** | 9 hex sin anotación (R-2.1) | Anotar cada uno `/* literal: physically-fixed sky/astro color */`; NO tokenizar |
| **F-3** | Sin cita APG (A-1.4) | Citar el patrón compuesto (dialog vía Popover) como date-picker; valorar además slider APG para la banda |
| **F-4** | readonly/invalid sin estilo | Patrón familia |
| **F-5** | Sin README ×2, sin tests | Paquete de estándares completo (SYS-9: iniciativa a medias) |
## Escalan al sistema
@ -34,4 +34,4 @@ SYS-2 · SYS-4 · SYS-9 · **corrección del censo A-3.1**: ntp EXONERADO con ma
## Veredictos
*(pendiente — checkpoint post-barrido)*
_(pendiente — checkpoint post-barrido)_

@ -7,16 +7,16 @@
## Dimensiones (evidencia leída)
| # | Dimensión | Estado | Evidencia |
|---|---|---|---|
| 3 | Coherencia semántica | ✓ | commit-select + pack ✓ |
| 8 | Contrato morfo | ✓ | apg ✓; el contrato del Indicator es el caso documentado en memoria (soma posiciona, eidos da forma) |
| 14 | Docs | gap | Sin README eidos — el sitio natural para formalizar el contrato del Indicator que hoy vive en memoria/notas → SYS-4 |
| # | Dimensión | Estado | Evidencia |
| --- | -------------------- | ------ | ------------------------------------------------------------------------------------------------------------------- |
| 3 | Coherencia semántica | ✓ | commit-select + pack ✓ |
| 8 | Contrato morfo | ✓ | apg ✓; el contrato del Indicator es el caso documentado en memoria (soma posiciona, eidos da forma) |
| 14 | Docs | gap | Sin README eidos — el sitio natural para formalizar el contrato del Indicator que hoy vive en memoria/notas → SYS-4 |
## Hallazgos y propuestas
| ID | Hallazgo | Propuesta |
|---|---|---|
| ID | Hallazgo | Propuesta |
| ------- | -------------------- | ---------------------------------------- |
| **F-1** | README eidos ausente | SYS-4 (con el contrato Indicator dentro) |
## Escalan al sistema
@ -25,4 +25,4 @@ SYS-4.
## Veredictos
*(pendiente — checkpoint post-barrido)*
_(pendiente — checkpoint post-barrido)_

@ -7,18 +7,18 @@
## Dimensiones — deltas
| Dim | Estado | Nota |
|---|---|---|
| 5/10 | ✓ | CSS propio = stub (§34 ✓: el visual vive en spin-field); focus o0 = correcto (la capa lo lleva) |
| Dim | Estado | Nota |
| -------------- | ---------- | -------------------------------------------------------------------------------------------------------------------- |
| 5/10 | ✓ | CSS propio = stub (§34 ✓: el visual vive en spin-field); focus o0 = correcto (la capa lo lleva) |
| 11 composición | ✓ ejemplar | Es el patrón memoria "compound-in-component": NumberField se compone DENTRO de Knob.ValueField; consume spin-field ✓ |
| 6 sema | ✓ | Pack propio ✓ |
| 2/4 API | ✓ | Scrubber (drag numérico) — en revisión del usuario ahora mismo |
| 12 | ✓ | min/max/step, gates |
| 6 sema | ✓ | Pack propio ✓ |
| 2/4 API | ✓ | Scrubber (drag numérico) — en revisión del usuario ahora mismo |
| 12 | ✓ | min/max/step, gates |
## Hallazgos y propuestas
| ID | Hallazgo | Propuesta |
|---|---|---|
| ID | Hallazgo | Propuesta |
| --- | ------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ |
| F-1 | Ninguno propio detectado a nivel análisis (el WIP del usuario está tocando README/scrubber) | Re-pasar la ficha cuando su WIP aterrice (marcar en el checkpoint) |
## Escalan al sistema
@ -27,4 +27,4 @@ SYS-7 (consumidor de capa — evidencia del patrón).
## Veredictos
*(pendiente — checkpoint post-barrido; re-visitar tras el WIP del usuario)*
_(pendiente — checkpoint post-barrido; re-visitar tras el WIP del usuario)_

@ -6,17 +6,17 @@
## Dimensiones (evidencia leída)
| # | Dimensión | Estado | Evidencia |
|---|---|---|---|
| 3 | Coherencia semántica | ✓ declarado | family-default ESCRITO (:14,:20) — legal per guard; si el radial MERECE carácter propio (shifts por capas) es la pregunta SYS-3, pero ya no es hueco silencioso |
| 14 | Docs | gap | Expediente pre-flight ausente → SYS-9 (paquete action-components) |
| resto | | ✓ | tests ✓; README ×2 ✓ |
| # | Dimensión | Estado | Evidencia |
| ----- | -------------------- | ----------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 3 | Coherencia semántica | ✓ declarado | family-default ESCRITO (:14,:20) — legal per guard; si el radial MERECE carácter propio (shifts por capas) es la pregunta SYS-3, pero ya no es hueco silencioso |
| 14 | Docs | gap | Expediente pre-flight ausente → SYS-9 (paquete action-components) |
| resto | | ✓ | tests ✓; README ×2 ✓ |
## Hallazgos y propuestas
| ID | Hallazgo | Propuesta |
|---|---|---|
| **F-1** | Expediente ausente | Las 4 secciones — paquete SYS-9 con menu-dial |
| ID | Hallazgo | Propuesta |
| ------- | ----------------------------- | -------------------------------------------------------------------------------- |
| **F-1** | Expediente ausente | Las 4 secciones — paquete SYS-9 con menu-dial |
| **F-2** | ¿El gesto radial merece pack? | SYS-3 (con menu-dial — familia radial junta); hoy es default DECLARADO, no hueco |
## Escalan al sistema
@ -25,4 +25,4 @@ SYS-3 · SYS-9.
## Veredictos
*(pendiente — checkpoint post-barrido)*
_(pendiente — checkpoint post-barrido)_

@ -6,16 +6,16 @@
## Dimensiones (evidencia leída)
| # | Dimensión | Estado | Evidencia |
|---|---|---|---|
| 3 | Coherencia semántica | ✓ | `commit-set` (fijar página = set neutral, canon fields aplicado ✓) + pack ✓ |
| 8 | Contrato morfo | hallazgo | **F-1**: sin cita `apg:` con PASS — pagination no tiene patrón APG oficial: quinto caso "apg: none — rationale" (con stepper/cropper/image-picker/media-player), y el agujero A-1.4 del script otra vez |
| resto | | ✓ | tests ✓; README ×2 ✓ |
| # | Dimensión | Estado | Evidencia |
| ----- | -------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 3 | Coherencia semántica | ✓ | `commit-set` (fijar página = set neutral, canon fields aplicado ✓) + pack ✓ |
| 8 | Contrato morfo | hallazgo | **F-1**: sin cita `apg:` con PASS — pagination no tiene patrón APG oficial: quinto caso "apg: none — rationale" (con stepper/cropper/image-picker/media-player), y el agujero A-1.4 del script otra vez |
| resto | | ✓ | tests ✓; README ×2 ✓ |
## Hallazgos y propuestas
| ID | Hallazgo | Propuesta |
|---|---|---|
| ID | Hallazgo | Propuesta |
| ------- | ----------------------- | ----------------------------------------- |
| **F-1** | Sin APG (regla no cazó) | Regla "apg: none — rationale" + fix A-1.4 |
## Escalan al sistema
@ -24,4 +24,4 @@ Censo A-1.4 (+1).
## Veredictos
*(pendiente — checkpoint post-barrido)*
_(pendiente — checkpoint post-barrido)_

@ -6,39 +6,39 @@
## Dimensiones (evidencia leída)
| # | Dimensión | Estado | Evidencia |
|---|---|---|---|
| 1 | Composición | ✓ | Surface consensuada contra 5 refs (Ark/Chakra/Mantine/Prime/Ant — documentado morfo :13-20); partes Input/VisibilityTrigger/CapsLockIndicator/StrengthMeter compositivas |
| 2 | Naming | ✓ conforme | `value/onValueChange` ✓; `visible/onVisibilityChange` (par bindable ✓, types :56-59); `onSubmit` crudo (mismo F-4 de search → _naming); `purpose: 'current'\|'new'` → autocomplete (types :61-66 — API password-manager-aware); `strength` pluggable con default `$libs/secs` (:95-110) |
| 3 | Coherencia semántica | ✓ **DOCTRINA DE REFERENCIA** | El morfo documenta con INCIDENTE por qué teclear NO es commit (`commit-input` por tecla disparaba pulse 260ms + beep por letra; alineado con editable/number/search/combobox — :40-47); `commit-toggle-visibility` = commit.toggle + affirm con cita cap. 23 (:59-72); **`signal-notify-caps-state` con `persistence: 'stateBound'`** + ciclo clearSignal razonado (el indicador seguiría 240ms y moriría con CapsLock aún activo — :73-93) |
| 4 | API | ✓ | min/maxLength; strength con resultado estructurado (score/label/warnings) y override zxcvbn/OWASP documentado; snippetProps completos (:17-30) |
| 5 | Tokens | ✓ con dup | `height-{k}` duplicada (SYS-6); strength-segment 6px = geometría del meter |
| 6 | Sema | ✓ | Pack ✓ + el contrato de eventos más fino del catálogo |
| 7 | Animaciones | ✓ | Sin keyframes; el settle del commit lo evitó la doctrina de :40-47 |
| 8 | Contrato morfo | ✓ ejemplar | APG textbox + ARIA toggle-button del trigger — citas CORRECTAS (:38, :10-11); innovación CapsLock documentada como gap 10/10 refs (:22-26); flags visible/caps-active/focused/empty (:118-121) |
| 9 | A11y | ✓ resuelto a nivel contrato | **`a11ySemantic: { requiresLiveRegion: true, reducedMotionFallback: 'text' }`** en el evento de caps (:99-102) — el anuncio para AT es parte del CONTRATO, no un extra; aria-label↔Field.Label documentado |
| 10 | Theming | hallazgo | R-1.3 readonly sin estilo (patrón familia) |
| 11 | Composición interna | ✓ | OR-merge con Field documentado (types :38-40, :73) |
| 12 | Estados | ✓ | visible/caps/focused/empty proyectados; purpose para autofill |
| 13 | Runtime | ✓ | Caps vía `getModifierState` en keydown del propio input (documentado :24-26) — sin listeners globales |
| 14 | Docs+tests | **gap doble** | Sin README eidos (E-2.3) y **cero tests** — el contrato más rico de la familia sin suite que lo proteja |
| 15 | i18n | ✓ | texts show/hide/caps-warning localizados (:32-37); warnings del meter traducibles vía langs (documentado types :103-105) |
| # | Dimensión | Estado | Evidencia |
| --- | -------------------- | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1 | Composición | ✓ | Surface consensuada contra 5 refs (Ark/Chakra/Mantine/Prime/Ant — documentado morfo :13-20); partes Input/VisibilityTrigger/CapsLockIndicator/StrengthMeter compositivas |
| 2 | Naming | ✓ conforme | `value/onValueChange` ✓; `visible/onVisibilityChange` (par bindable ✓, types :56-59); `onSubmit` crudo (mismo F-4 de search → \_naming); `purpose: 'current'\|'new'` → autocomplete (types :61-66 — API password-manager-aware); `strength` pluggable con default `$libs/secs` (:95-110) |
| 3 | Coherencia semántica | ✓ **DOCTRINA DE REFERENCIA** | El morfo documenta con INCIDENTE por qué teclear NO es commit (`commit-input` por tecla disparaba pulse 260ms + beep por letra; alineado con editable/number/search/combobox — :40-47); `commit-toggle-visibility` = commit.toggle + affirm con cita cap. 23 (:59-72); **`signal-notify-caps-state` con `persistence: 'stateBound'`** + ciclo clearSignal razonado (el indicador seguiría 240ms y moriría con CapsLock aún activo — :73-93) |
| 4 | API | ✓ | min/maxLength; strength con resultado estructurado (score/label/warnings) y override zxcvbn/OWASP documentado; snippetProps completos (:17-30) |
| 5 | Tokens | ✓ con dup | `height-{k}` duplicada (SYS-6); strength-segment 6px = geometría del meter |
| 6 | Sema | ✓ | Pack ✓ + el contrato de eventos más fino del catálogo |
| 7 | Animaciones | ✓ | Sin keyframes; el settle del commit lo evitó la doctrina de :40-47 |
| 8 | Contrato morfo | ✓ ejemplar | APG textbox + ARIA toggle-button del trigger — citas CORRECTAS (:38, :10-11); innovación CapsLock documentada como gap 10/10 refs (:22-26); flags visible/caps-active/focused/empty (:118-121) |
| 9 | A11y | ✓ resuelto a nivel contrato | **`a11ySemantic: { requiresLiveRegion: true, reducedMotionFallback: 'text' }`** en el evento de caps (:99-102) — el anuncio para AT es parte del CONTRATO, no un extra; aria-label↔Field.Label documentado |
| 10 | Theming | hallazgo | R-1.3 readonly sin estilo (patrón familia) |
| 11 | Composición interna | ✓ | OR-merge con Field documentado (types :38-40, :73) |
| 12 | Estados | ✓ | visible/caps/focused/empty proyectados; purpose para autofill |
| 13 | Runtime | ✓ | Caps vía `getModifierState` en keydown del propio input (documentado :24-26) — sin listeners globales |
| 14 | Docs+tests | **gap doble** | Sin README eidos (E-2.3) y **cero tests** — el contrato más rico de la familia sin suite que lo proteja |
| 15 | i18n | ✓ | texts show/hide/caps-warning localizados (:32-37); warnings del meter traducibles vía langs (documentado types :103-105) |
## Hallazgos y propuestas
| ID | Hallazgo | Propuesta |
|---|---|---|
| **F-1** | Cero tests para el contrato más fino de la familia (toggle+aria, caps stateBound+clearSignal, strength plugable, debounce n/a) | Suite prioritaria en fase de fixes (SYS-2): el stateBound del caps es EXACTAMENTE lo que una regresión rompería en silencio |
| **F-2** | Sin README eidos | SYS-4 |
| **F-3** | readonly sin estilo (R-1.3) | Tratamiento único de familia |
| **F-4** | `onSubmit` crudo (tipado heterogéneo) | Veredicto _naming |
| **F-5** | `height-{k}` duplicada | SYS-6 |
| **Nota ✓✓** | La doctrina teclear≠commit (:40-47) y el a11ySemantic del caps son CANON exportable | Citarlos como referencia en el veredicto de field F-2 (Field.Input debe adoptar `commit-submit` al Enter, el patrón que este morfo documenta) y en la doctrina sema |
| ID | Hallazgo | Propuesta |
| ----------- | ------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **F-1** | Cero tests para el contrato más fino de la familia (toggle+aria, caps stateBound+clearSignal, strength plugable, debounce n/a) | Suite prioritaria en fase de fixes (SYS-2): el stateBound del caps es EXACTAMENTE lo que una regresión rompería en silencio |
| **F-2** | Sin README eidos | SYS-4 |
| **F-3** | readonly sin estilo (R-1.3) | Tratamiento único de familia |
| **F-4** | `onSubmit` crudo (tipado heterogéneo) | Veredicto \_naming |
| **F-5** | `height-{k}` duplicada | SYS-6 |
| **Nota ✓✓** | La doctrina teclear≠commit (:40-47) y el a11ySemantic del caps son CANON exportable | Citarlos como referencia en el veredicto de field F-2 (Field.Input debe adoptar `commit-submit` al Enter, el patrón que este morfo documenta) y en la doctrina sema |
## Escalan al sistema
SYS-2 · SYS-4 · SYS-6 · _naming (onSubmit crudo) · **la doctrina de :40-47 resuelve el field F-2 a nivel de familia** (commit-submit-en-Enter como patrón de inputs de texto).
SYS-2 · SYS-4 · SYS-6 · \_naming (onSubmit crudo) · **la doctrina de :40-47 resuelve el field F-2 a nivel de familia** (commit-submit-en-Enter como patrón de inputs de texto).
## Veredictos
*(pendiente — checkpoint post-barrido)*
_(pendiente — checkpoint post-barrido)_

@ -4,9 +4,9 @@
- **Vigencia re-auditoría 2026-07-07**: capa (SYS-7) — la ficha vale; el footer Accept/Cancel/Clear que registra fluye por el handle del [Picker genérico](picker.md), cuya deuda semántica declarada (picker F-1) es donde se repara la cadena
- **Capas**: soma (tests: **0**) · README eidos ✓ · pack — (capa) · **Máquina: PASS limpio**.
| Hallazgo | Propuesta |
|---|---|
| Hallazgo | Propuesta |
| ------------------------------------------------------------------------------- | ------------------------------------------------- |
| F-1: capa sin tests propios (la cubren los pickers consumidores indirectamente) | Decidir en SYS-2 si las capas llevan suite propia |
| F-2: clasificación formal de capa | SYS-7 (con spin-field/list-surface) |
| F-2: clasificación formal de capa | SYS-7 (con spin-field/list-surface) |
**Escalan**: SYS-2 · SYS-7. · **Veredictos**: *(pendiente checkpoint post-barrido)*
**Escalan**: SYS-2 · SYS-7. · **Veredictos**: _(pendiente checkpoint post-barrido)_

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save

Powered by TurnKey Linux.