You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
svelte-kit-vice/docs/process/PLAN-component-coherence.md

112 lines
26 KiB

# PLAN — Coherencia del catálogo de componentes (fase 1: debilidades)
> **Kickoff para sesión nueva**: _"Lee docs/process/PLAN-component-coherence.md
> y continúa la tanda que toque."_ Decisión de usuario (2026-07-02): primero
> resolver las debilidades medidas del sistema; la **web de información y de
> componentes** (ficha canónica + demos v3 + docs site) es la FASE SIGUIENTE —
> por eso las reglas D-\* (demos) quedan explícitamente FUERA de esta fase.
## Diagnóstico (auditoría 2026-07-02)
`npm run component:audit`: **130 componentes → 75 PASS · 50 NEEDS-WORK · 5
BROKEN** (`cascade` · `gradient-builder` · `menu-dial` · `motion` · `qr-code`).
Por dimensión:
| Dimensión | Estado medido |
| --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Ejes transversales | Paleta-31 (`paletteScaleDecls`) en **7** recipes; size-bundle (`--size-*`) en **1** (pilot toggle); `data-variant` en 55 CSS |
| Estados (recipe) | `:focus-visible` falta en **11** (error) · `data-invalid` en 10 · `data-disabled` en 6 · `data-readonly` en 15 (warn) |
| Tokens | **17** recipes con tipografía literal (R-2.7) |
| Sema | 82 morfos con eventos → solo **41** declaran `expression:` (13 pack · 13 family-default · 1 delegated parseados); `persistence:` en 13; `a11ySemantic` en 9 |
| Motion | 15/15 recipes sin `@keyframes` locales ✓; firma de evento (CSS `data-event`) en **10** componentes; prop `motion` en 18 |
| A11y ancla | **33** interactivos sin URL APG (A-1.4, warn) |
| Docs por componente | **28** sin README (E-2.3); F-1.x (Baseline/Comparativa/Decisiones/Gaps) faltan en ~12–18 más |
| Demos (FUERA de fase) | 4 tab-union viejo · 7 sin snippet · 8 sin trace · 12 ▶ play sin wire · 7 chip-parity |
## Reglas de trabajo
- Sin agentes/workflows; responder en castellano, código/docs en inglés.
- NUNCA tocar `words/`, `palabras/`, `chronos/`, `media-player` (foráneo WIP).
- Una tanda = cambios + verificación (`component:audit --only` por componente
tocado + `npm run check` scope) + commit. `git reset -q` antes de add.
- Sweeps: UN componente primero, verificar, luego el resto (no-cascade rule).
- Cada fix sistémico lleva su guard (regla nueva en audit o generador).
## Tandas
| Tanda | Contenido | Estado |
| ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- |
| **C0** | **Auditoría de conteos** (hallazgo usuario: "31 escalas" era 33 — UI+docs): guard I1 extendido a palette=33 · roles=9 · slots=12 (extracción sin comentarios); harness PALETTE_GROUPS +fuchsia+steel con assert de completitud; 14 menciones corregidas. **Pendiente**: misma medicina para steps=12 · planos depth=5 · sizes · weights · estilos tipográficos · packs | **HECHA (núcleo) 2026-07-02** |
| **C1** | **BROKEN mecánicos → 0 BROKEN**: válvula `R-x.y exception:` en audit (R-1.1/R-1.2/R-1.5/E-2.2 + filas checklist); cascade/motion/gradient-builder `texts.label`+langs; menu-dial default export; READMEs contrato (cascade·motion·menu-dial·qr-code: Baseline/Comparativa/Decisiones/Gaps/Passive+excepciones). cascade·motion·menu-dial → PASS; gradient-builder·qr-code → NEEDS-WORK (resto = D-\* fase demos + C8) | **HECHA 2026-07-02** |
| **C2** | **Estados error-severity**. **(a) R-1.5 HECHA 2026-07-02**: el audit ahora reconoce las 4 evidencias sancionadas (`:focus-visible` · `:focus-within` · `:has(:focus)` · `[data-focused]` canónico) — añadir rings por recipe habría sido el anti-patrón "double border" (archetypes.css:164 ya da ring universal por arquetipo); 6 excepciones citadas (css-field/number-field → spin-field compartido; date-picker/dialog → foundation+content-exclusion; metrics/timeline → sin parte enfocable); clipboard+announce esperan su README (C8). **(b) R-1.2/1.3/1.4 HECHAS 2026-07-03**: válvula cableada también en R-1.3/R-1.4; fixes REALES verificados en navegador (switch/toggle/rating-group invalid=threat-element como checkbox·pin-input; toggle+pin-input readonly; spin-field readonly NUEVO en la capa compartida; ntp disabled); excepciones citadas (spin-field para css/number-field; dialog provider virtual; color-picker→color-field; date-range-field overlay de attrs; time-picker→time-field). ntp conserva R-1.3/R-1.4 warn para su pasada C8. media-player NO tocado (foráneo) | **HECHA** |
| **C3** | **R-2.7 tipografía literal HECHA 2026-07-03** — 16 recipes: 8 font-weights → `var(--font-weight-*)` (verificado resolve=500 en navegador); ~13 proporcionales/identidad anotados `/* literal: */` con razón (avatar ∝ diámetro; `calc(1em − (md−sm))` = label one-step-down con delta token-derived; `1em` identidad de contexto; captions ×0.85; optical −1px) | **HECHA** |
| **C4** | **A-1.4 APG HECHA 2026-07-03** — 20 morfos con patrón real (pickers/command/search→combobox · date-field→spinbutton espejo de time-field · rating→radio · nav-menu→disclosure · splitter→windowsplitter · tag-group/tags-input/virtual-grid→grid · file-upload/clipboard→button · announce→alert · form→landmark · image-adjustments→slider · table→table); válvula A-1.4 + notas en 5 READMEs (cropper·pagination·stepper·timeline·image-picker — sin patrón APG real). Restan 4 esperados: card/drag-drop/virtual-list (nota aterriza con su README en C8) + media-player (foráneo) | **HECHA** |
| **C5** | **Sema `expression:` HECHA 2026-07-03** — los 30 morfos eventful sin declaración TODOS tienen pack en `sema/components/` → `expression: 'pack'` (clasificación sin ambigüedad; D.4). `morfo:vocabulary` limpio (solo warn naming de media-player, foráneo). `persistence`/`a11ySemantic` adicionales NO añadidos de oficio — la tabla D.9 es referencia y los 6 consumidores reales ya declaran; ampliar solo con caso real | **HECHA** |
| **C6** | **Paleta universal HECHA 2026-07-03** — `universalPaletteDecls` en el generador (`normalizeRecipeTokens`): `palette-{slot}` = vocabulario reservado → cascade de PALETTE_SCALES completo automático (declaraciones de autor ganan; solo se añaden escalas ausentes). Spreads manuales de button retirados (base.ts); button regenera byte-idéntico; **toggle se universalizó solo** (+330 líneas generadas — ya exponía tokens palette-\*). Lint: valores de escala en `data-color` = eidos-only sancionado (la enum del morfo sigue siendo los roles). Guard: test en recipe-css-contract fija la ÚLTIMA escala de la const. Verificado en navegador: toggle color=teal/steel resuelven | **HECHA** |
| **C7** | **Size-bundle sweep HECHA 2026-07-03** — 366 refs de coordenada cruda (`--control-height-{k}` · `--font-size-{k}` · `--icon-size-{k}`) → coordenada del bundle (`--size-{k}-{coord}`) en base.ts; 34 recipes consumen el bundle (era 1, pilot toggle), 0 crudos restantes. El bundle = alias puro → CSS generado idéntico en VALOR computado (verificado en navegador: cadena `--accordion-trigger-min-height-md` = `--size-md-control-height` = `--control-height-md` = `calc(36px*1*1)`). Guard: test en recipe-css-contract prohíbe la coordenada cruda en recipes. `base`/`xxxl` sin bundle → siguen en el primitivo tipográfico | **HECHA** |
| **C8** | **READMEs** — 28 nuevos + F-1.x incompletos (~18). Baseline/Comparativa (≥3 refs reales)/Decisiones/Gaps; passive → justificación. El más pesado: requiere investigación por componente | pendiente |
| **C9** | **Motion eventful gap** — decidir qué interactivos deben expresar firma de evento (hoy 10) y cablearla; criterio: alta frecuencia = sobrio (doctrina D.5) | pendiente |
| **C10** | **Tiers de madurez — REFRAMEADO 2026-07-03**: el veredicto del audit ES el oráculo de madurez. Clasificación objetiva: **stable** = PASS (82); **preview** = NEEDS-WORK solo por docs/demo (E-2.3/F-1.x/D-\*) — funcionalmente sano, subdocumentado (~35, incl. button/table/listbox — maduros con gap de README, NO inmaduros); **experimental/WIP** = gap FUNCIONAL real o foráneo (pocos: float-panel A-3.7, card-group sin morfo, natural-time-picker A-3.1, media-player+words/palabras/chronos foráneos). C10 se pliega en C8 (documentar tier + excepciones al escribir READMEs). Cerrados esta pasada los flags funcionales limpios: 4 service E-2.2 (format-date/number, relative-time, trans), alert-dialog R-1.1 (compone dialog), card A-1.3 (texts.label+langs) | **parcial (reframe + flags limpios)** |
| **Gaps reales tracked** | NO silenciados: **float-panel A-3.7** (28 teclas mutantes, 6 eventos — completitud de morfo); **card-group** sin morfo; **natural-time-picker A-3.1** (interactive sin eventos declarados) + R-2.1 (sky fixed-tone, excepción cuando tenga README); announce/clipboard R-1.5 (live-region/composed-focus, excepción cuando tengan README en C8) | pendiente |
docs+fix: old docs quarantined in docs/old-deprecated; STUMBLES doc-class fixes Two user findings from the Knob build exercise (an agent building a new component from the docs alone — STUMBLES.md). Quarantine: the superseded fossils no longer share shelf space with the live corpus. docs/old-deprecated/ (with an index README explaining what lands there and pointing readers at docs/README.md) now holds the executed audits and fix plans: fable_audit, fable-eidos-audit, inherit_audit + inherit_fix_plan, ARCHETYPE_COHERENCE_AUDIT_2026-06-19 (still citable — the component-guide banner and the eidos components README repoint to it), COMPONENT_COHERENCE_AUDIT. pendiente.md (a live pending list, not a fossil) moved to docs/process/. docs-check treats the folder as sealed chronicle (I1/I2 exempt; I6 skips its internal links, as its README promises). Root-level *.md is now: README, CLAUDE, AGENTS + the user's own working files. STUMBLES fixes applied on the spot (the doc-class ones): - #2 kind drift: the REAL enum is 'public' | 'private' | 'virtual' (MorfoPartKind, 671/9/14 uses) — morfo.md omitted 'private', the checklist invented 'internal' (0 uses). Both fixed; I2 gains the phantom-'internal' guard. A-2.1's row now says what the audit script actually checks (kebab only — the archetype may vary, the Toggle provider-IS-trigger doctrine). - #6: the langs catalog SHAPE (flat keys, per-language leaves, named export, index registration) is now shown in morfo.md instead of only its location. - #8: component-audit s0 defines the minimum brief package as an explicit 8-file list. The engineering-class stumbles are registered as plan batches S1-S6 (generated vocabularies appendix, continuous-gesture trigger doctrine, part-absent condition, Gesture.rotate, the soma->eidos CSS-var contract, minor frictions). docs:check 0 errors, 11-warn baseline. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
## Tandas S — hallazgos del ejercicio Knob (STUMBLES.md, 2026-07-03)
El usuario encargó a otro agente construir un Knob SOLO desde los docs; su
STUMBLES.md mide la construibilidad — dimensión que las auditorías de
conformidad no cubrían. Ya corregido en el acto (2026-07-03): #2 drift `kind`
(la enum real es public|private|virtual; morfo.md y checklist mentían distinto
- guard I2 fantasma `'internal'`; fila A-2.1 alineada con lo que el script
chequea — doctrina Toggle), #6 forma del catálogo langs (snippet en morfo.md),
#8 paquete mínimo (lista de archivos en component-audit §0).
| Tanda | Contenido | Estado |
| ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------- |
feat(docs): S1 — generated canonical-vocabulary appendix (STUMBLES #1) An agent building a component from the docs-book alone could not assign archetypes / holds / haptic kinds: the closed sets live only in code consts and the corpus (correctly) forbids copying them into prose, so they were invisible from the docs. STUMBLES #1, the top stumble. Fix: docs/canon/vocabularies.md is GENERATED from the consts by 'npm run docs:vocabularies' — the ONE sanctioned place the lists are spelled out (generated = no drift objection), which every other doc links to. It covers part archetypes (with a one-line role each), sema families with their default hold/persistence + per-intent overrides, verbs by family, intents, the perceptual-duration scale, haptic kinds, the 33 palette scales, sizes, variant archetypes, and the shared common.* strings. - scripts/docs-vocabularies.ts imports the consts (robust — no fragile JSDoc/regex parsing) and formats them; the generation is an exported function so docs-check can compare. - Added ARCHETYPE_DESCRIPTIONS to morfo/types.ts (co-located with ARCHETYPE_VOCABULARY, satisfies Record<MorfoArchetype,string>) as the authoritative one-liners the appendix reads — descriptions become first-class data instead of inline union JSDoc a tool would have to parse. - docs-check gains I7: it regenerates in-memory and fails if the committed file drifts from the consts (negative-tested: corrupt -> error, regen -> green). The appendix's own counts pass I1, so I1 doubles as a second guard. - Linked from README (E2 canon row + two 'I want to' shortcuts), CANON.md (doctrine here, enumerated lists there), architecture/morfo.md (pick a part's archetype), and the component-audit minimum-package list (STUMBLES #8). docs:check 0 errors; npm run check unchanged in my files. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
| **S1** | **HECHA 2026-07-03** — `npm run docs:vocabularies` → `docs/canon/vocabularies.md` GENERADO desde los consts (archetypes+one-liner vía nuevo `ARCHETYPE_DESCRIPTIONS`, families+holds/persistence/overrides, verbos por familia, intents, haptic kinds, palette 33, sizes, variants, common strings 38). Import-based (robusto, no regex). Guard **I7** en docs-check (regenera in-memory, compara; test negativo OK). Enlazado desde README E2 + 'I want to', CANON, morfo.md, component-audit paquete mínimo. Cierra stumble #1 (vocabularios invisibles) | **HECHA** |
| **S2** | Doctrina "Continuous components" en architecture/sema.md — trigger() vs emitEvent en gestos, retención de turno con sequence:'post', throttling de commit-set en key-repeat; documentar la resolución REAL de Slider (stumble #4) | pendiente |
| **S3** | Condición `part-absent` en morfo (aria-label solo sin Label) — schema + compiler + runtime (stumble #5) | pendiente |
| **S4** | `Gesture.rotate` (centro + sweep + wrap + detents + velocidad angular) — consumidores: Knob, AngleSlider, hue ring, esfera de reloj; hoy FLAGGED GAP en el provider del Knob (stumble #3) | pendiente |
| **S5** | Contrato de CSS custom properties soma→eidos (`--x-progress`/`--x-angle`) — extensión del morfo, pasa 2-de-3 (soma escribe, eidos consume); hoy solo prosa en soma-architecture §9 (stumble #7) | pendiente |
| **S6** | Fricciones menores (#9): state<T>() vs $state (cuándo cada uno) · role en Provider-con-DOM · Without<>/PrimitiveDivAttributes definidos · ownership de pointermove/up en gesture layers — notas en soma docs | pendiente |
docs+fix: old docs quarantined in docs/old-deprecated; STUMBLES doc-class fixes Two user findings from the Knob build exercise (an agent building a new component from the docs alone — STUMBLES.md). Quarantine: the superseded fossils no longer share shelf space with the live corpus. docs/old-deprecated/ (with an index README explaining what lands there and pointing readers at docs/README.md) now holds the executed audits and fix plans: fable_audit, fable-eidos-audit, inherit_audit + inherit_fix_plan, ARCHETYPE_COHERENCE_AUDIT_2026-06-19 (still citable — the component-guide banner and the eidos components README repoint to it), COMPONENT_COHERENCE_AUDIT. pendiente.md (a live pending list, not a fossil) moved to docs/process/. docs-check treats the folder as sealed chronicle (I1/I2 exempt; I6 skips its internal links, as its README promises). Root-level *.md is now: README, CLAUDE, AGENTS + the user's own working files. STUMBLES fixes applied on the spot (the doc-class ones): - #2 kind drift: the REAL enum is 'public' | 'private' | 'virtual' (MorfoPartKind, 671/9/14 uses) — morfo.md omitted 'private', the checklist invented 'internal' (0 uses). Both fixed; I2 gains the phantom-'internal' guard. A-2.1's row now says what the audit script actually checks (kebab only — the archetype may vary, the Toggle provider-IS-trigger doctrine). - #6: the langs catalog SHAPE (flat keys, per-language leaves, named export, index registration) is now shown in morfo.md instead of only its location. - #8: component-audit s0 defines the minimum brief package as an explicit 8-file list. The engineering-class stumbles are registered as plan batches S1-S6 (generated vocabularies appendix, continuous-gesture trigger doctrine, part-absent condition, Gesture.rotate, the soma->eidos CSS-var contract, minor frictions). docs:check 0 errors, 11-warn baseline. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
FASE SIGUIENTE (no aquí): ficha canónica generada por componente, demos v3
(D-\*), web de docs. Ver conversación 2026-07-02.
test(eidos): triage the 15 long-red suite failures — 289/289 green, check 61→59 Accumulated test debt (the eidos suite had been red across several feature landings — THEME-SYS-1 named z-index, palette-first static donor library, spin-field extraction, icon stroke-map refinement — none of them regressions; baselined against HEAD). Each triaged stale-vs-bug by confirming current behavior in code before touching a line. Stale tests (code correct/improved, assertion not updated): - z-index '76' -> 'var(--z-index-overlay-tooltip)' (the code is guarded by THEME-SYS-1 in contracts.test.ts — the raw integer is forbidden). - frost '80%' -> 'var(--depth-overlay-translucency, 80%)' (parameterized). - C7 size-bundle coordinate ('--control-height-md' -> '--size-md-control-height'). - icon visual-stroke ratios 1.5->1.125, 1->0.923 (stroke map md 2->1.5, xxl icon 48->52px; the arithmetic follows). - delegate/CSS-only purple-9: the slim foundation legitimately emits the role-referenced donor scales (purple=primary) as overridable :root defaults; the real delegation guarantee is 'no baked [data-theme] block', which the assertion now checks. Test over-flagging (fixed the test, not the code): - CSS-only shared layer: spin-field (no wrapper/index) excluded from the wrapper/barrel/namespace contracts (CSS_ONLY_LAYERS). - soma-runtime vars: 'var(--x, fallback)' is runtime-optional (the STUMBLES #7 soma->eidos surface) — only bare 'var(--x)' requires a recipe declaration. - orphan check made corpus-wide: composition means a sibling consumes a component's tokens (date-picker/month-grid consume calendar-control-*). - natural-time-picker fixed-tone sky colors documented-exempt (Words-rail doctrine). - dialog drift-detector converted to a synthetic fixture (dialog.css no longer ships the dead rule it self-tested against). Real code fixes: - declare '--pin-input-cell-readonly-bg' (I consumed it in C2b without declaring it). - remove 5 truly-dead tokens (drawer content-bg + 4 color-field format-select/segment — 0 consumers anywhere in eidos/soma/web). - clamp time-picker's 'size' to PopoverSize before forwarding (xs->sm): TimePickerSize has xs, PopoverSize doesn't — a latent type bug my recipe change surfaced via a complexity-budget flip. The fix dropped check 61->59, also clearing navigation-menu-content of the same class. card-group flagged as a REAL gap (KNOWN_MISSING_MORFO): it ships parts + chrome but no morfo (morfo-first violation) — tracked, not silenced. Verified: vitest src/uix/eidos 23 files / 289 tests green; npm run check 59 (better than the 61 baseline); component:audit 0 BROKEN. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
## Triage suite eidos — HECHA 2026-07-03 (289/289 verde)
Los **15 fallos preexistentes** (deuda acumulada, el suite llevaba rojo tiempo;
baselined contra HEAD — no eran regresiones) triados uno a uno, stale-vs-bug
confirmado en código antes de tocar:
test(eidos): triage the 15 long-red suite failures — 289/289 green, check 61→59 Accumulated test debt (the eidos suite had been red across several feature landings — THEME-SYS-1 named z-index, palette-first static donor library, spin-field extraction, icon stroke-map refinement — none of them regressions; baselined against HEAD). Each triaged stale-vs-bug by confirming current behavior in code before touching a line. Stale tests (code correct/improved, assertion not updated): - z-index '76' -> 'var(--z-index-overlay-tooltip)' (the code is guarded by THEME-SYS-1 in contracts.test.ts — the raw integer is forbidden). - frost '80%' -> 'var(--depth-overlay-translucency, 80%)' (parameterized). - C7 size-bundle coordinate ('--control-height-md' -> '--size-md-control-height'). - icon visual-stroke ratios 1.5->1.125, 1->0.923 (stroke map md 2->1.5, xxl icon 48->52px; the arithmetic follows). - delegate/CSS-only purple-9: the slim foundation legitimately emits the role-referenced donor scales (purple=primary) as overridable :root defaults; the real delegation guarantee is 'no baked [data-theme] block', which the assertion now checks. Test over-flagging (fixed the test, not the code): - CSS-only shared layer: spin-field (no wrapper/index) excluded from the wrapper/barrel/namespace contracts (CSS_ONLY_LAYERS). - soma-runtime vars: 'var(--x, fallback)' is runtime-optional (the STUMBLES #7 soma->eidos surface) — only bare 'var(--x)' requires a recipe declaration. - orphan check made corpus-wide: composition means a sibling consumes a component's tokens (date-picker/month-grid consume calendar-control-*). - natural-time-picker fixed-tone sky colors documented-exempt (Words-rail doctrine). - dialog drift-detector converted to a synthetic fixture (dialog.css no longer ships the dead rule it self-tested against). Real code fixes: - declare '--pin-input-cell-readonly-bg' (I consumed it in C2b without declaring it). - remove 5 truly-dead tokens (drawer content-bg + 4 color-field format-select/segment — 0 consumers anywhere in eidos/soma/web). - clamp time-picker's 'size' to PopoverSize before forwarding (xs->sm): TimePickerSize has xs, PopoverSize doesn't — a latent type bug my recipe change surfaced via a complexity-budget flip. The fix dropped check 61->59, also clearing navigation-menu-content of the same class. card-group flagged as a REAL gap (KNOWN_MISSING_MORFO): it ships parts + chrome but no morfo (morfo-first violation) — tracked, not silenced. Verified: vitest src/uix/eidos 23 files / 289 tests green; npm run check 59 (better than the 61 baseline); component:audit 0 BROKEN. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
- **Stale tests** (código correcto/mejorado, test no actualizado): z-index `76`
→ `var(--z-index-overlay-*)` (guard THEME-SYS-1 lo prueba); frost `80%` →
`var(--depth-overlay-translucency, 80%)`; C7 size-bundle (`--control-height-md`
→ `--size-md-control-height`); icon stroke (mapa refinado md 2→1.5, xxl 48→52
→ 1.125 / 0.923); purple-9 en delegate (foundation slim emite legítimamente
escalas de roles → assert cambiada a la garantía real: no hornear bloque
`[data-theme]`).
- **Test over-flagging** (arreglado el test): spin-field capa CSS-only
(`CSS_ONLY_LAYERS`); vars soma-runtime con fallback (`var(--x, default)` =
runtime-opcional, no exige declaración); orphan cross-component (calendar-\*
test(eidos): triage the 15 long-red suite failures — 289/289 green, check 61→59 Accumulated test debt (the eidos suite had been red across several feature landings — THEME-SYS-1 named z-index, palette-first static donor library, spin-field extraction, icon stroke-map refinement — none of them regressions; baselined against HEAD). Each triaged stale-vs-bug by confirming current behavior in code before touching a line. Stale tests (code correct/improved, assertion not updated): - z-index '76' -> 'var(--z-index-overlay-tooltip)' (the code is guarded by THEME-SYS-1 in contracts.test.ts — the raw integer is forbidden). - frost '80%' -> 'var(--depth-overlay-translucency, 80%)' (parameterized). - C7 size-bundle coordinate ('--control-height-md' -> '--size-md-control-height'). - icon visual-stroke ratios 1.5->1.125, 1->0.923 (stroke map md 2->1.5, xxl icon 48->52px; the arithmetic follows). - delegate/CSS-only purple-9: the slim foundation legitimately emits the role-referenced donor scales (purple=primary) as overridable :root defaults; the real delegation guarantee is 'no baked [data-theme] block', which the assertion now checks. Test over-flagging (fixed the test, not the code): - CSS-only shared layer: spin-field (no wrapper/index) excluded from the wrapper/barrel/namespace contracts (CSS_ONLY_LAYERS). - soma-runtime vars: 'var(--x, fallback)' is runtime-optional (the STUMBLES #7 soma->eidos surface) — only bare 'var(--x)' requires a recipe declaration. - orphan check made corpus-wide: composition means a sibling consumes a component's tokens (date-picker/month-grid consume calendar-control-*). - natural-time-picker fixed-tone sky colors documented-exempt (Words-rail doctrine). - dialog drift-detector converted to a synthetic fixture (dialog.css no longer ships the dead rule it self-tested against). Real code fixes: - declare '--pin-input-cell-readonly-bg' (I consumed it in C2b without declaring it). - remove 5 truly-dead tokens (drawer content-bg + 4 color-field format-select/segment — 0 consumers anywhere in eidos/soma/web). - clamp time-picker's 'size' to PopoverSize before forwarding (xs->sm): TimePickerSize has xs, PopoverSize doesn't — a latent type bug my recipe change surfaced via a complexity-budget flip. The fix dropped check 61->59, also clearing navigation-menu-content of the same class. card-group flagged as a REAL gap (KNOWN_MISSING_MORFO): it ships parts + chrome but no morfo (morfo-first violation) — tracked, not silenced. Verified: vitest src/uix/eidos 23 files / 289 tests green; npm run check 59 (better than the 61 baseline); component:audit 0 BROKEN. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
consumidos por date-picker/month-grid → corpus completo); natural-time-picker
colores fijos del cielo (`FIXED_TONE_COMPONENTS`, doctrina rail Palabras); dialog
test(eidos): triage the 15 long-red suite failures — 289/289 green, check 61→59 Accumulated test debt (the eidos suite had been red across several feature landings — THEME-SYS-1 named z-index, palette-first static donor library, spin-field extraction, icon stroke-map refinement — none of them regressions; baselined against HEAD). Each triaged stale-vs-bug by confirming current behavior in code before touching a line. Stale tests (code correct/improved, assertion not updated): - z-index '76' -> 'var(--z-index-overlay-tooltip)' (the code is guarded by THEME-SYS-1 in contracts.test.ts — the raw integer is forbidden). - frost '80%' -> 'var(--depth-overlay-translucency, 80%)' (parameterized). - C7 size-bundle coordinate ('--control-height-md' -> '--size-md-control-height'). - icon visual-stroke ratios 1.5->1.125, 1->0.923 (stroke map md 2->1.5, xxl icon 48->52px; the arithmetic follows). - delegate/CSS-only purple-9: the slim foundation legitimately emits the role-referenced donor scales (purple=primary) as overridable :root defaults; the real delegation guarantee is 'no baked [data-theme] block', which the assertion now checks. Test over-flagging (fixed the test, not the code): - CSS-only shared layer: spin-field (no wrapper/index) excluded from the wrapper/barrel/namespace contracts (CSS_ONLY_LAYERS). - soma-runtime vars: 'var(--x, fallback)' is runtime-optional (the STUMBLES #7 soma->eidos surface) — only bare 'var(--x)' requires a recipe declaration. - orphan check made corpus-wide: composition means a sibling consumes a component's tokens (date-picker/month-grid consume calendar-control-*). - natural-time-picker fixed-tone sky colors documented-exempt (Words-rail doctrine). - dialog drift-detector converted to a synthetic fixture (dialog.css no longer ships the dead rule it self-tested against). Real code fixes: - declare '--pin-input-cell-readonly-bg' (I consumed it in C2b without declaring it). - remove 5 truly-dead tokens (drawer content-bg + 4 color-field format-select/segment — 0 consumers anywhere in eidos/soma/web). - clamp time-picker's 'size' to PopoverSize before forwarding (xs->sm): TimePickerSize has xs, PopoverSize doesn't — a latent type bug my recipe change surfaced via a complexity-budget flip. The fix dropped check 61->59, also clearing navigation-menu-content of the same class. card-group flagged as a REAL gap (KNOWN_MISSING_MORFO): it ships parts + chrome but no morfo (morfo-first violation) — tracked, not silenced. Verified: vitest src/uix/eidos 23 files / 289 tests green; npm run check 59 (better than the 61 baseline); component:audit 0 BROKEN. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
drift-detector → fixture sintético.
- **Fixes reales de código**: `--pin-input-cell-readonly-bg` declarado (lo
introduje en C2b sin declarar); 5 tokens muertos borrados (drawer content-bg +
4 color-field format-select/segment, 0 consumidores en TODO el repo);
**time-picker `size` clampado a PopoverSize** (`xs`→`sm`: `TimePickerSize`
tiene `xs`, `PopoverSize` no — bug de tipos latente que mi cambio de recipe
afloró vía flip de complejidad; el fix bajó check 61→**59**, arreglando también
navigation-menu-content de la misma clase).
- **card-group** flaggeado como GAP REAL tracked (`KNOWN_MISSING_MORFO`): tiene
partes + chrome pero no morfo (viola morfo-first); NO silenciado — pendiente
de build pass.
Verificado: `npx vitest run src/uix/eidos` 23 archivos / 289 tests verde;
`npm run check` **59** (mejor que baseline 61); `component:audit` 0 BROKEN.
feat(eidos): C6 — universal palette cascade moves into the generator palette-{slot} is now RESERVED recipe vocabulary: normalizeRecipeTokens (render-css) appends the full per-scale color:{scale} cascade for every donor scale in PALETTE_SCALES to any token named palette-track/element/ border/solid/solid-hover/text/contrast — author-declared color:* declarations win, only absent scales are appended. This is the structural end of the hand-maintained-subset era: a recipe opts into the per-instance palette by naming the token, and the generator guarantees all scales (the 31-vs-33 drift class cannot recur at this layer). Applies to app-config recipes too, since the hook sits where every RecipeTokenSet is normalized. Button's seven manual spreads are gone from base.ts (the helpers moved into the generator); its generated output is byte-identical. Toggle — which already exposed palette-* tokens — universalized itself: +330 generated lines, and <Toggle color="teal"> / color="steel" verified resolving in a live browser (steel and fuchsia are exactly the two scales the hand-kept lists used to miss). eidos-lint now classifies donor-scale values on data-color as sanctioned eidos-only vocabulary (the TSC color:* axis extension) instead of invalid — the morfo enum keeps declaring the semantic roles, per the pilot's deliberate runtime-open design. Guard: recipe-css-contract pins the LAST scale of PALETTE_SCALES for every palette-bearing recipe in the generated css. Also: the stale '31 physical color scales' test TITLE says 33 (its body already asserted 33). Recorded in the plan: the eidos suite carries 15 pre-existing failures in 6 files (baselined against HEAD before this change) — their triage is its own batch. npm run check at the 61-error baseline; lint toggle baseline green again. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
## Verificación de cierre de fase
`npm run component:audit` → 0 BROKEN, NEEDS-WORK solo por reglas D-\* (demos,
fase siguiente); paleta y size-bundle universales con guard activo.

Powered by TurnKey Linux.