astra
alpha-0.1-background
alpha-0.1-dir-prefs
alpha-0.1-sec-dom
menubar-v4-safe
active-uix
morfo-runtime
morfo-driven-soma
semantuix
glm-5
main
sium-v1.0
${ noResults }
164 Commits (3097cfcb69f711a6177a51e351127072c1d79a41)
| Author | SHA1 | Message | Date |
|---|---|---|---|
|
|
3097cfcb69 |
revert: deshacer la auditoría entera — se hizo sin leer la doctrina
Revert de los 7 commits de la sesión del 2026-07-29/30: |
2 months ago |
|
|
c9b83d0257 |
docs(morfo): qué hace pública a una parte, y tres hallazgos retirados
`morfo.md` §Step 2 — la guía de AUTORÍA, donde el autor decide — documentaba sólo `'public'` y `'virtual'` y omitía `'private'`. La sección de referencia sí tenía los tres, pero nadie declara partes leyendo la referencia. El criterio que queda escrito: **lo que hace pública a una parte es que el consumidor la decida, con independencia de la sintaxis**. La composición (`<Dialog.Trigger>`) es la vía habitual, no la única: un primitivo de API plana gobierna sus partes por props y snippets — `<Badge dot>` decide la parte Dot, `icon` la parte Icon. Ambas son públicas. `'private'` queda para lo que nada de lo que escribe el consumidor alcanza (el Track de `Spinner`, el Sentinel de `Sticky`). Importa el matiz porque la primera versión de esta nota decía lo contrario — que el test era mecánico y que sin `<Componente.Parte>` la parte no es pública — y eso habría reclasificado mal a Badge y a todo primitivo de API plana. ## Handoff: tres hallazgos retirados Los tres salieron de heurísticas de una sola vía dadas por hechas sin abrir el código. Es el mismo fallo que la auditoría denuncia en los guards, cometido al redactar el informe: - **D-3 `AgentTimersPort.once`** — el puerto SÍ está satisfecho: `defineActiveAgent()` adapta `core.timers.schedule` a `once` en la raíz de composición, que es el patrón previsto. No había nada roto. - **«5 derivas de scope»** — `avatar-group`, `path-trace` y `rotate-align` están implementados; el framework co-loca sub-componentes dentro del directorio del padre y la heurística asumía «directorio == kebab». - **«29 morfos con `kind:'public'` irreal»** — medía si existe `<Componente.Parte>` e ignoraba props y snippets. Sin recuento fiable hasta cruzar las tres vías. Añadido: `npm run lint` nunca ha pasado. Separando el ruido CRLF del checkout Windows (`--end-of-line auto`) quedan 1544 ficheros con deriva real de contenido. Es decisión del usuario porque el arreglo toca todo el repo de golpe. Y la lección de método: **un analizador que no puede resolver algo tiene que decir «no verificado», no emitir un hallazgo.** Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
2 months ago |
|
|
4e785d32bf |
feat(blocks): F2.7 `stats-band` — la cifra que se cuenta sola
La fila de números que respalda lo que la página acaba de afirmar. Compound
(`.Stat` repite, sin contexto): `<StatsBand>` + `.Stat` + `.Value` + `.Label`.
- **Compone, no reinventa**: la semántica de KPI es el `Metrics` del canon, leído
de su API y pasado tal cual (precedente `faq`/`Accordion`). `Metrics` es
surfaceless, que es exactamente lo que una banda necesita: no son tarjetas de
panel. Un delta, un icono o un sparkline son `Metrics.Delta`/`.Icon`/`.Chart`
que la app compone dentro — el block no los re-expone.
- **La superación literal del dossier**: `<StatsBand.Value count={12500} />`
compone `CountUp`, así que la cifra se cuenta sola al entrar en pantalla.
NINGUNA referencia puede shipearlo: todas entregan markup estático. El formato
locale-aware y el salto directo bajo reduced-motion vienen del `CountUp`, no
de aquí.
- **`count` es opt-in, nunca default**: una cifra que se anima sin que el lector
lo pida es ruido, y algunas no son contables («99,98 %»). Sin `count`, la
cifra la pone la app por children.
- **Ni una palabra ni un separador salen del block** (B-7): las palabras por
children, el formato por `uix.format` dentro del `CountUp`.
- Escalonado estructural: `data-stagger` en la banda y cada `.Stat` es un
`Motion trigger="viewport"`, así que las cifras aterrizan una tras otra sin un
solo milisegundo escrito a mano.
Verificado en navegador (con la banda bajo el pliegue, para cazar el conteo desde
el primer fotograma): 4 cifras con índices estructurales 0,1,2,3 contando
—9377→11.678 · 255→318 · 36→45—, el porcentaje quieto por no ser contable, y el
separador de millares por locale (`11.678`). Cero errores de página.
`blocks:check` verde (8 blocks) · `svelte-check` sin errores propios.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2 months ago |
|
|
c39170abbf |
fix(uix): la auditoría del sistema — lo que los guards no veían
Auditoría clean-room de todo ActiveUIX (excluido `web/`), componente a
componente. Lo que sale de aquí no es una lista de bugs: es un patrón.
El framework validaba que lo escrito fuese VÁLIDO, no que lo declarado
se CUMPLIESE — y sus guards fallaban ABIERTOS.
## El colapso de las uniones de props (95 → 0)
Un `Props` de eidos es `{ …props propias… } & <atributos nativos>`.
Cuando el elemento declara un atributo homónimo, la intersección funde
ambos y una unión estrecha contra el `string` nativo COLAPSA a `string`.
Causa: `Without<T, U> = Omit<T, keyof U>` invocado como `Without<T, {}>`
— `Omit<T, never>`, un no-op — 433 veces en soma; sólo 3 con argumento
real. Invisible para `svelte-check`: ensanchar un tipo no es un error,
es una garantía perdida.
Medido: 95 props en 72 componentes. `<Avatar color="nonsense">`
compilaba. `ComboboxInput.size` chocaba con el `<input size>` numérico
y era inusable. Migrado con codemod sobre AST (nunca regex) a
`Own & Omit<Nativos, keyof Own>`: 92 tipos en 73 ficheros + carousel a
mano. `check` no se movió.
Garantía nueva: `eidos/prop-surface.test.ts` (PROP-1) compara los
literales de la anotación del autor contra los de la propiedad pública.
Verificado que falla reintroduciendo el defecto.
## Los cuatro guards que fallaban abiertos
- `translations:check` crasheaba en CADA ejecución de su historia — un
stripper de comentarios borraba `//` dentro de strings. Sustituido por
import dinámico. Al arrancar destapó 8 slots `texts` sin traducción.
- `soma-attr-audit` agotaba el timeout de 5 s: sin veredicto, verde por
omisión.
- `component-audit` D-7.4 hacía `continue` mudo cuando el tipo no
resolvía. Ahora resuelve con el checker de TypeScript
(`scripts/prop-unions.ts`): puntos ciegos de 124 → 3.
- `component-audit` R-1.1: el regex casaba `[data-motion='reduce']` y
daba PASS por el motivo equivocado.
Regla adoptada: un guard que no puede evaluar TIENE que decirlo. El
informe lleva ahora bloque «Not verified» y recuento en el resumen.
## D-1 · tooltip y D-2 · card, cableados
`tooltip` declaraba 3 eventos `emerge` que nadie emitía. Ahora emiten;
`present` pasa a `sequence: 'post'` — con `'pre'` el hold de ~240 ms
gateaba el montaje del propio overlay.
`card` declaraba `commit-select` sin emisor posible (scope sin soma).
Puente headless en `soma/components/card/` con la forma ya establecida
por `menu-dial` / `onion-menu`: eidos posee estado y render, soma posee
sólo el `SomaRuntime` que emite.
## Documentación: 22 mentiras corregidas
`docs/` afirmaba guards inexistentes (`NO_MISSING_PROVIDER_TESTS`),
APIs con firma equivocada y un modelo de Motion que el código no
implementa. Corregido en CANON, arquitectura, glosario, theming/motion,
checklist y los README de `motion` / `callout` / `arts/motion`.
## Además
- CardGroup: la descripción se metía en la primera celda del grid.
- Motion: `data-state` siempre estampado, salida real en `leave()`,
token fantasma `--motion-stagger-each-default` eliminado.
- `engine-motion`: `handoffState` Map → WeakMap (fuga por nodo).
- `mockup`: primitivo crudo → token de rol (R-4.6).
- 5 catálogos de traducción que faltaban.
Handoff: `docs/process/CONTINUE-audit-2026-07-29.md`.
Batería: check 0 errores en src · vitest server 3701/3701 ·
docs:check 0/0 · component:audit 161 PASS / 2 NEEDS-WORK.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2 months ago |
|
|
cdc00bc117 |
fix(blocks): lo que la auditoría encontró DENTRO del tier
Una auditoría multi-agente (7 dimensiones doctrinales + refutación adversarial) confirmó 32 hallazgos sobre la pasada de calidad. Esto corrige los que caen dentro de `blocks/`; la deuda de fuera queda REGISTRADA, no tocada (`PLAN-blocks-quality.md` §6). - **B-7 roto en `pricing`**: el block traía tres strings castellanas propias como defaults del toggle — dos visibles y un nombre accesible. Hardcodeaba un idioma DENTRO del framework y esquivaba `langs`, en el mismo block cuyo README predica «cero strings propias». Ahora los tres son props REQUERIDAS y las pone la app. - **El block pintaba**: `pricing.Plan` metía `box-shadow` por `style=` porque `Card` no expone elevación. Retirado; el hueco queda registrado como candidato a canon en vez de falseado. - **El escalonado estaba roto y el comentario mentía**: puse `spring-pop` (driver JS) en los planes, y un driver JS no lee el `animation-delay` donde vive el stagger — entraban TODOS a la vez mientras el comentario afirmaba lo contrario. Vuelto al preset CSS: verificado, índices 0,1,2 a 70ms. - **Comentario falso en la demo del hero**: atribuía al `intent` visual una consecuencia sonora/háptica que ningún camino produce (el morfo del Button dice explícitamente que `contact-activate` NO lleva intent). Reescrito. - **Composition maps mentían**: los 6 blocks que ahora componen `Motion` no lo decían; el hero seguía diciendo `Heading` (es `Display`), sin `Backdrop` ni `decor`, y declaraba DIFERIDO un preset de cromo de media que ya está shipeado (`Mockup`). Al día, sin filas duplicadas ni datos rancios (el chip de feature-grid es `solid`, no `soft`). - **Handoff y plan**: el plan seguía prescribiendo un `<Reveal>` que esta misma sesión creó y retiró; el handoff daba `feature-split` por «sin decidir» estando hecho, y los gates con números falsos. Verificado: `blocks:check` verde (7) · `svelte-check` sin errores propios · en el navegador, pricing escalona de nuevo, las etiquetas vienen de la app y ninguna tarjeta pinta sombra. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
2 months ago |
|
|
a25be8903b |
docs(agent): el handoff deja de ser un diario y pasa a ser un punto de arranque
Se había convertido en un log por sesiones — la forma equivocada para abrir en frío, donde lo que hace falta es «qué hago ahora», no «qué pasó». Reordenado por lo que necesita quien llega: 1. lo PRIMERO al abrir (tres comandos; si no están verdes, eso es el trabajo) 2. lo BLOQUEADO — las dos firmas de §D, con el porqué de que §D.2 bloquee F4b (la escalada lleva razón pero no pregunta; la resolución no lleva respuesta) 3. lo DESBLOQUEADO — los dos manifiestos de F4b, que no dependen de §D 4. estado, flecos y lo que está sin firmar pero no bloquea 5. verificación 6. disciplina y gotchas, agrupados (git · verificación visual · trampas de código que ya mordieron) 7. la historia, comprimida al final Los gotchas ganan tres entradas nuevas que costaron tiempo esta sesión: el HEAD puede retroceder bajo tus pies en una rama compartida (comprobar con merge-base antes de alarmarse), `createEngineTimers()` como `timers` del motor tipa pero revienta, y `asserts condition` no se puede desestructurar. Sin cambios de código. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
2 months ago |
|
|
8b89c7f6b7 |
feat(agent): el kit de conformance del contrato de delegación — portable de verdad
El segundo vehículo que la spec exige (§0.5 · Annex C.1), y el que de verdad acredita: `agent-check` es un lint de NUESTRO repo; esto lo corre un tercero contra SU implementación. PORTABLE POR CONSTRUCCIÓN El kit no importa `createEngineAgent`. Habla con un `ConformanceSubject` estructural —start · run · authorize · reject · resolveEscalation · stop · disable— que el implementor adapta sobre su motor; `subject.ts` es el ejemplo trabajado de ese adaptador, no una dependencia. Vive fuera del barrel (precedente `adapters/*`, D-AG.1c): quien no corre conformance no lo paga. DIEZ CASOS, CADA FALLO CITANDO SU ID AG-2 · AG-4 (el control vuelve aunque el transporte reviente — la lectura más dura del requisito) · AG-5 · AG-6 (escalada no terminal + razón tipada) · AG-9 (interrumpir es volver, no un error) · AG-10 (kill global) · AG-21 (una capacidad inventada vuelve como resultado corregible, no mata el run) · AG-25 (lo irreversible no se ejecuta sin revisar ni con el techo más suelto) · AG-26 (clamp de iniciativa) · AG-50 (degradación sin transporte). Un caso que falla solo se falla A SÍ MISMO: una implementación a la que le falte un requisito recibe igualmente el informe completo del resto, que es la diferencia entre una suite de conformance y un smoke test. Y EL KIT SABE FALLAR Un kit que no puede fallar no prueba nada, así que hay un test que rompe AG-4 a propósito y comprueba que el informe lo nombra. No es lo mismo que `engine-agent.test.ts`: aquella suite prueba el MOTOR con acceso a sus interioridades; ésta prueba el CONTRATO por la misma puerta que tiene un tercero, y es la que nos pillaría enviando un eje que nuestra propia especificación rechaza. AG-35 y AG-41 quedan FUERA a propósito mientras §D de la spec siga abierta — un kit que afirmara un requisito sin decidir estaría inventando la decisión. Hay un test que fija esa ausencia. TRAMPA CAZADA, QUE ES LO QUE HACEN LAS SUITES Tres casos fallaban por lo mismo, y no era el motor: pasar `createEngineTimers()` como `timers` TIPA pero revienta — `EngineTimers` expone `schedule`, no `once`, así que el primer timeout llama a `undefined` y el run cierra como `transport-error`. La factory de `active-app` adapta el puerto justamente por eso. Anotado en el handoff. Verificado: agent 33/33 (10/10 conformance) · arts:check 24/24 · agent:check limpio · docs:check sin errores nuevos · check de vuelta en los 73 preexistentes (los 17 que aparecieron eran míos: `asserts condition` exige llamarse por un nombre anotado, y yo lo desestructuro del contexto). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
2 months ago |
|
|
31580f3b39 |
docs(spec): el contrato de delegación como especificación normativa (DRAFT)
Fase 1 del plan de corrección, y materialización de D-AG.12a firmada ayer: `docs/spec/delegation-contract.md`, versionada por fecha (2026-07-28). QUÉ ES 50 requisitos `AG-1…50` en RFC-2119, con escalera de estabilidad por sección (stable | provisional | reserved), identificadores estables que NUNCA se renumeran ni se reciclan (un requisito retirado conserva su número), y la exigencia de que ambos vehículos de conformance CITEN el identificador que incumplen — «una suite que no nombra lo que falla no acredita a nadie». La doctrina pasa a ser el PORQUÉ y lo declara explícitamente: si doctrina y spec discrepan sobre un requisito, manda la spec y la doctrina se corrige. Annex A lleva las dos reclamaciones de frontera con estado `claimed` (ninguna materializada) y su gate de promoción: ≥2 FORMAS DE DOMINIO con manifiesto conforme — y dice por qué dos participantes de texto no valen: un formato probado solo sobre texto secuencial asume texto secuencial en silencio. Annex B mapea el modelo de amenazas a requisitos concretos en vez de dejarlo como prosa. §0.6 declara la posición honesta (actos secuenciales, cliente- first, generalidad en prueba). LO QUE LA ESCRITURA SACÓ A LA LUZ — y no estaba en ninguna lista - **AG-35 (presencia)**: el invariante correcto NO es «Aura montada» sino «alguna superficie está expresando el ciclo». El playground de agnt ya expresa el ciclo SIN Aura, y exigir el componente lo rechazaría siendo correcto. Además resuelve el problema técnico: el motor es un arte sin DOM y no puede saber qué hay montado, pero sí puede contar adjuntos. - **AG-41 (elicitación)**: especificado y NO cumplido, con el porqué estructural — la escalada lleva razón tipada pero no la pregunta, y la resolución es binaria y no lleva respuesta. No era falta de superficie. - **AG-44**: «ningún estado se distingue solo por el color» sube de decisión de componente a requisito del contrato (ya lo fija `shapes.test.ts`). §D — DECISIONES ABIERTAS, VISIBLES Un DRAFT puede llevarlas; al promocionar, §D debe quedar VACÍA. Son dos y ninguna la firmo yo: `SHOULD` vs `MUST` en AG-35 (con recomendación razonada: SHOULD + política que lo eleve a MUST, porque rehusar por defecto rompería los 30 tests del motor y le quitaría al app el derecho a elegir su superficie) y la forma del canal de elicitación en AG-41. Registrada en el índice del corpus. `docs/README.md` lo edita otra sesión en paralelo: stageada SOLO mi fila (backup → HEAD → mi cambio → add → restaurar su versión + mi cambio), verificado que lo suyo queda sin stagear. Verificado: docs:check 542 docs, sin errores nuevos (el único es el ajeno preexistente de callout). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
2 months ago |
|
|
f190a2266e |
feat(eidos): `Reveal` + `Backdrop` + cascada por viewport — la capa de acabado
Auditoría del tier (docs/process/PLAN-blocks-quality.md): los 7 blocks de F2 componían EXCLUSIVAMENTE la capa de layout (Box/Stack/Grid/Section/Text/Card). Uso de la capa expresiva del framework: cero. Ni un Motion, ni un Cascade, ni un Display, ni un TextGradient, ni un CountUp. La causa es estructural, no de gusto: el contrato B prohíbe que un block traiga `.css`, así que **un block solo puede ser tan expresivo como los componentes del canon que compone** — y faltaban dos primitivas. El arreglo no es maquillar 14 blocks uno a uno, es construir lo que falta en el canon y componerlo. - **`Reveal`** — reproduce la ENTRADA de un preset al entrar en viewport. No posee keyframes ni timing: estampa `data-animation-style` + `data-state='open'` cuando dispara el observador, así que reduced-motion degrada DENTRO del preset. Mientras espera, el recipe lo mantiene invisible bajo `@media (scripting: enabled)`: sin JS la regla no aplica y el contenido se ve siempre — el fallo de una animación de scroll debe ser «sin animación», nunca «página en blanco». - **Escalonado gratis**: el foundation ya escribe `--motion-stagger-index` en cada hijo de `[data-stagger]` (por `:nth-child`, sin JS) y los presets retrasan por `índice × --motion-stagger-each`. El recipe de Reveal le da ritmo por defecto, así que una lista se escalona poniendo `data-stagger` en SU contenedor: cero delays a mano, cero números en el consumidor. - **`Cascade trigger="viewport"`** — la cascada existente esperaba a `open` (disclosure); ahora puede esperar también a ser vista. - **`Backdrop`** — la capa de profundidad que no existía: `glow` · `mesh` · `grid` · `dots`, pintada en un `::before` desde tokens (acento por el forward de paleta, mesh desde `--gradient-aurora`), con `fade` para no cortar en seco. **El hero como prueba del nuevo listón**: `Display` (el primitivo de tipografía de hero que existía y no usaba — el titular pasa de `Heading` a 80px reales), entrada escalonada de eyebrow/título/subtítulo/acciones, media con `scale-fade` y `decor` (glow por defecto) expuesto como control vivo en la demo. Verificado con Playwright: glow pintado desde el token de paleta, 4 Reveal con índices estructurales 0·1·2·3 a 70ms, titular H1 a 80px, y el patrón `grid` con su máscara. `blocks:check` verde (7 blocks) · `vitest src/uix/eidos` 361/361 · `svelte-check` sin errores propios. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
2 months ago |
|
|
54b8b838e7 |
feat(blocks): F2.6 `faq` — proxy fino del Accordion del canon
La sección de preguntas: una cabecera sobre un acordeón de P/R en columna estrecha. Compound (`.Item` repite) y —la regla al envolver un componente interactivo— un PROXY FINO del `Accordion` del canon: el block lee su API y la pasa tal cual, no reinventa el disclosure. `<Faq>` + `.Header` + `.List` + `.Item`. - `.List` **ES** el `Accordion`: toda su API pasa sin gate — `type` (single/multiple), `bind:value`, `collapsible`, `variant`, `size`. Defaults de FAQ: single, collapsible (el abierto se puede cerrar), outline. - `.Item` proxya `Accordion.Item > Header > Trigger`(snippet `question`) / `Content`(children) y autogenera el `value` (clave de estado) con `$props.id()` si no se pasa — la única conveniencia sobre el andamiaje. - El teclado (flechas, Home/End, Enter/Espacio), `aria-expanded` y `aria-controls` salen del `Accordion`; el block no toca la a11y del disclosure. `Container` estrecho (`md`) para una columna legible. Demo (`web/routes/blocks/faq/`): full-bleed + ruta `preview`, cinco preguntas en una columna, con la cola «¿aún tienes dudas?» que la app pone tras `.List`. Huecos a decisión del usuario (Gaps): la **lista estática 2/3 columnas** (6 de 7 en TW NO son acordeón, sino P/R siempre abiertas) — otra disposición, prop `layout` o hermano. Verificado en navegador: el acordeón abre/cierra, claro/oscuro × LTR/RTL. `blocks:check` verde (7 blocks) · `svelte-check` sin errores propios. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
3 months ago |
|
|
b59332132f |
feat(blocks): F2.5 `testimonials` — rejilla de citas con autor
Prueba social: una cabecera sobre una rejilla responsive de tarjetas de cita, cada una con su autor (avatar · nombre · cargo). Compound —la `.Item` se repite, como feature-grid— y SIN contexto (las partes no coordinan). `<Testimonials>` + `.Header` + `.Items` + `.Item` + `.Quote` + `.Author`(slot `avatar` + `.AuthorName`/`.AuthorRole`). - `AutoGrid` de tarjetas de igual alto; `.Author` fijada al borde inferior de la tarjeta (`margin-block-start: auto`) para que una fila de citas de distinto largo alinee las caras. - La cara es del app: un `<Avatar>` con imagen o un `Avatar.Fallback` de iniciales va en el slot `avatar` (B-7). - La tarjeta del quote usa `variant="outline"` — el `soft neutral` es casi invisible en claro. Encontrado al componer (en el README del block): el tema activa solo un SUBCONJUNTO de escalas donor (`green/indigo/orange/plum/teal`); una escala no activada (`cyan/ruby/amber/jade`) en `color` cae en SILENCIO a `primary` (la regla `[data-color]` hace `var(--scale-…, primary)`). Config del tema, no bug de componente; la demo usa escalas activadas. Hueco a decisión del usuario (Gaps): la **cita única en spotlight** (grande, centrada, logo+avatar+autor) — la variante modal del dossier, el grid es minoría. Otra disposición → candidato a hermano `testimonial-spotlight`. Demo (`web/routes/blocks/testimonials/`): full-bleed + ruta `preview`, cinco citas con avatares de iniciales en cinco colores distintos. Verificado en claro/oscuro × LTR/RTL, caras alineadas al fondo. `blocks:check` verde (6 blocks) · `svelte-check` sin errores propios. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
3 months ago |
|
|
594e5a5db4 |
feat(blocks): F2.4 `pricing` — el primer compound CON CONTEXTO del tier
La sección de planes: un toggle de periodo sobre una fila de planes, uno destacado. Es el primer block cuyas partes se COORDINAN de verdad (no solo se repiten como en feature-grid/split): el `Switch` escribe el periodo de facturación y cada `PlanPrice` lo lee. Esa coordinación es lo que gana un contexto compartido — la forma más fuerte de compound. `<Pricing bind:period>` + `.Header` + `.Switch` + `.Plans` + `.Plan`(featured, badge) + `.PlanName`/`.PlanDescription`/`.PlanPrice`/`.PlanFeatures`/ `.PlanFeature`/`.PlanAction`. - **Contexto reactivo** (`context.ts`): la raíz provee el periodo como getter sobre un `$bindable`; el `Switch` (un `ToggleGroup`) lo escribe, el `PlanPrice` lo lee y muestra el snippet `monthly` o `annual`. Mismo patrón que `CardGroup`. `period` es bindable por si la app quiere observarlo. - **El block NUNCA formatea moneda**: la app compone `FormatNumber` dentro de los snippets de precio (B-7). El block posee el switch, no el dinero. - `.PlanAction` fija el CTA al borde inferior de la tarjeta (`margin-block-start: auto`) para que una fila de planes alinee sus botones aunque tengan distinto nº de features; `.Plan` con `align="start"` deja los checks en columna limpia; `featured` da acento (borde primary) + elevación. Demo (`web/routes/blocks/pricing/`): full-bleed + ruta `preview`, tres planes (Pro destacado en el centro) con el toggle mensual/anual vivo. Hueco a decisión del usuario (Gaps del block): la **tabla de comparación** (features × planes) — la brecha recurrente del dossier en pricing. Es una tabla, no una fila de tarjetas: candidato a hermano `pricing-table`. Presentado, no resuelto. Verificado en navegador: el toggle cambia los TRES precios a la vez (0/29/99 → 0/23/79), tarjetas de igual alto con CTAs alineados, featured con acento, en claro/oscuro × LTR/RTL. `blocks:check` verde (5 blocks) · `svelte-check` sin errores propios. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
3 months ago |
|
|
08ea82d128 |
feat(blocks): F2.3b `feature-split` — la brecha nº1 del dossier, con Mockup
La sección que las 5 refs shippean y que va justo tras el hero: una afirmación de producto junto a un screenshot, alternando lados fila a fila. Otra disposición que la rejilla de iconos de `feature-grid`, así que block hermano (decisión del usuario), no una variante turbia dentro de aquél. Compound —la `.Row` se repite—: `<FeatureSplit>` + `.Row` (`reversed`, slot `media`) + `.Eyebrow` + `.Title` + `.Text` + `.Features`/`.Feature` (checklist) + `.Actions`. El block coloca; la app pone la copy y la media. - `reversed` mueve la media al lado de inicio vía `grid-column` (Box expone `gridColumn`/`order`), dejando la copy SIEMPRE primera en el DOM — el orden de lectura y el foco no cambian aunque el screenshot salte de lado. - El check de cada `.Feature` es decorativo (`aria-hidden`): la palabra lleva el significado. - La media se COMPONE con el primitivo `Mockup`: la demo enseña cromo de navegador (dashboard) y de teléfono (app), cerrando el hueco de «tratamiento de media» del dossier de raíz en vez de falsearlo. `.Row` usa un tipo limpio (no `HTMLAttributes`) porque su slot `media` colisiona con el atributo HTML homónimo; el resto de sub-partes extienden los props del componente canon que envuelven (lección de feature-grid). Demo (`web/routes/blocks/feature-split/`): full-bleed + ruta `preview`, con control del nº de filas y del lado inicial; 3 filas con Mockup navegador/teléfono. Verificado en navegador (Playwright, módulos frescos): filas alternas en claro/oscuro × LTR/RTL, `reversed`, el orden de lectura copy-primero, y los dos cromos de Mockup. `blocks:check` verde (4 blocks) · `svelte-check` sin errores propios. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
3 months ago |
|
|
d01b3e6af5 |
feat(blocks): F2.3 `feature-grid` — el primer block compound del tier
`<FeatureGrid>` + `.Header` + `.Items` + `.Item` + `.ItemIcon`/`.ItemTitle`/ `.ItemText`: una cabecera sobre una rejilla responsive de features (icono · título · texto). Es la sección que responde «qué hace», la nº1 tras el hero. Primer block COMPOUND del tier, y aplica la regla de forma que fijamos: el `.Item` se REPITE (el app mapea sobre N features) → gana sub-componentes, donde `hero`/`site-header` usan slots de snippet (partes fijas de layout). Las partes no coordinan —sin contexto ni estado entre ellas—: la rejilla es del padre, las celdas del app. `.Items` es el envoltorio honesto de la rejilla (`AutoGrid`), que deja la cabecera fuera sin un `grid-column: 1/-1` a pelo. - El block coloca (Section · Container · AutoGrid · Surface · Heading · Text); el app pone todo el contenido por children (B-7). - `.Items` fluido por `minChildWidth` (tantas columnas como quepan) o `columns` fijas; `.Item` `align` start/center; `.ItemIcon` chip `Surface`; `.ItemTitle` `Heading` h3; `.ItemText` `Text` apagado. - `align` de sección (center/start) coloca la cabecera coherente con las columnas. Dos cosas encontradas al construir, resueltas: - **Los sub-componentes de bloque extienden los props del componente canon que envuelven** (`BoxProps`, `StackProps`, `HeadingProps`…), **no `HTMLAttributes`**: el `style: string|null` del atributo HTML crudo choca con el `style: string` del canon al hacer spread (+ "union type too complex"). - **`.ItemIcon` por defecto `solid`, no `soft`**: el soft-primary en claro es casi blanco (oklch 0.99) → el chip era invisible; solid da el chip con glifo on-solid (la tinta de contraste la pone `Surface`). Demo (`web/routes/blocks/feature-grid/`): full-bleed + ruta `preview`, con control de columnas (fluido/2/3/4), align, nº de items y dir; 6 features con iconos del canon. Hueco a decisión del usuario (en los Gaps del block): el **feature-split/ alternante** (texto junto a un screenshot, lados alternos) — la brecha nº1 del dossier — es otra disposición (filas de 2 columnas, no rejilla de iconos): probablemente un block hermano `feature-split`. Presentado, no resuelto. Verificado en navegador (Playwright, módulos frescos): center/start × claro/ oscuro × LTR/RTL, columnas fluidas y fijas, 3/4/6 items, chips visibles. `blocks:check` verde (3 blocks) · `svelte-check` sin errores propios. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
3 months ago |
|
|
5125502486 |
feat(blocks): F2.2 `hero` — center · split · background, por slots
Segundo block del tier. API por SLOTS DE SNIPPET, no compound: la forma se razonó con el usuario y con el paisaje de referencia. Compound se reserva para partes que COORDINAN (estado/contexto/ARIA entre ellas — Accordion, Dialog); un hero son cinco slots de layout que no se hablan entre sí y que el root arregla, así que snippets. Además el campo entero shippea marketing como copy-paste plano —nadie aplica compound a una sección—, y los slots por zona son la historia de personalización que distingue al tier del copy-paste. `<Hero layout="center|split|background" level container size>` + `eyebrow/title/description/actions/media/background/children`. - El block **envuelve** título y subtítulo en `Heading`/`Text`: así posee el `id` que nombra el `<section aria-labelledby>` y el nivel del encabezado, mientras la app pone las palabras (B-7). `eyebrow`/`actions`/`media` son contenido libre (ahí los componentes del canon SON la API). - `center` = `Stack` centrado, media debajo (ancho-capado); `split` = `Grid` de dos columnas (una sola sin media), apila en estrecho. - **`background` (cover)** — añadido por scope-approval del usuario: la media a sangre detrás de la copy, con velo de contraste (`--color-overlay` a `--opacity-scrim`), texto `on-solid` y `object-fit: cover` vía un `<style>` justificado (D-BLK.2). Son las ÚNICAS reglas que el block posee, todas sobre tokens del ecosistema — cero color a mano. Capas por orden de fuente, sin `z-index`. Demo (`web/routes/blocks/hero/`): full-bleed en la página + ruta `preview` para anchos de dispositivo, cada prop un control vivo, y el backdrop del layout cover dogfooda el sistema de color — es un `Surface color="primary" gradient` (finish aurora = `--gradient-aurora`, derivado de los roles del tema; cambia con la paleta). Mini-site compartido por las dos superficies (`HeroSite.svelte`). Encontrado al componer, registrado no resuelto: `Box`/`Surface` `flex`/`grow` no hicieron crecer un hijo flex (bars a 0-width, `flex: 0 1 auto`; la prop no la usa ningún componente shipped). La demo usó `Grid` (tracks `1fr`). Flag en el README del block y en el handoff para revisar el cableado de `--box-flex`. Verificado en navegador (Playwright headless, módulos frescos): center/split/ background × claro/oscuro × LTR/RTL, media on/off, y el landmark nombrado (región con `aria-labelledby` que resuelve al título). `blocks:check` verde (2 blocks) · `svelte-check` sin errores propios. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
3 months ago |
|
|
356ebf92af |
feat(button): el CTA que navega y parece botón, por composición (opción D)
El hueco que registró `site-header`: un «Empezar gratis» de cabecera tiene que
NAVEGAR y parecer botón. `Button` no crece un `href` —`Link` posee la
navegación, y un ancla se activa con Enter, no con espacio, lo cual es
correcto—: presta la pintura por composición. Lo que hacía de esa forma un
downgrade era que el `child` (asChild) descartaba la decoración; se completa el
slot.
- **eidos `<Button>`**: el `child` recibe ahora `content`, el cuerpo YA
decorado (icono · etiqueta · endIcon · spinner) en su propio snippet que
comparten las dos ramas de render. Así
`<a href {...props}>{@render content()}</a>` conserva TODOS los slots en vez
de sustituirlos (antes la flecha del sitio alpha estaba escrita a mano).
Nuevo tipo exportado `ButtonChildProps`.
- **soma / morfo**: en la forma `child` el elemento es del consumidor, así que
soma deja de estampar `type` (un `<a type="button">` es una pista de MIME
falsa). El componente pasa `type: undefined` cuando hay `child`; el provider
lo REENVÍA verbatim (antes lo re-defaulteaba a `'button'` y pisaba el drop —
el default vive en el destructure del componente); el morfo declara el attr
`type` condicional (`prop-truthy`).
- **docs**: ejemplo rancio de `index.ts` corregido (anunciaba un `asChild`/
`variant="link"` que no existen); sección «CTA que navega» en el README de
eidos con el patrón y el footgun documentado (un `<button>` en un `<form>` vía
`child` se pone su propio `type`); nota en el README de soma.
- **site-header**: el CTA de la demo usa ya la forma real (`<a>` sólido con
flecha), y el hueco pasa de «candidato a canon» a CERRADO por composición —
`Button` sigue sin `href` y `Link` sigue poseyendo la navegación, las dos
decisiones firmadas se mantienen. Actualizados PLAN/CONTINUE-blocks.
- **demo de Button**: control `child (asChild → <a>)` vivo, snippet del código
y fila de a11y explicando por qué el ancla activa solo con Enter.
Verificado en navegador (dev, restart para módulos frescos): asChild ON →
`<a href="#pricing">` sin `type`, pintura sólida completa (bg primary, tinta
blanca, 36px, padding 16px), y el slot de icono SOBREVIVE dentro del ancla
(`[data-button-icon]` + svg + body); asChild OFF → `<button type="button">`
intacto (sin regresión de submit implícito); el CTA real de `site-header` sale
`<a>` con la flecha final y 0 errores de consola. `blocks:check` verde ·
`vitest src/uix/morfo` 114/114 · `svelte-check` sin errores propios nuevos.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
3 months ago |
|
|
d38bd63faa |
docs(blocks): registro de F2.1, doctrina de demo del tier y handoff
Documentación al día de lo que se cerró hoy y handoff para retomar mañana.
- `PLAN-blocks.md` §7: **F2.1 `site-header` HECHA** con sus siete commits, la
fase 0 contra el dossier §P1, el landmark que le faltaba a `NavigationMenu`
(arreglado en el canon, no parcheado en el block), el hueco del CTA que
navega y parece botón (registrado, no falseado) y el defecto de framework
que destapó la demo.
- `theming/changelog.md` §46: las 44 variables de cascada de `Box` dejan de
heredarse. Un `Section` regalaba su padding a cada descendiente —la galería
arrastraba ~300px de aire desde F0— y los hijos heredaban anchos y `display`
ajenos. `@property { inherits: false }`, radio verificado sin regresiones.
Lección: una variable que un componente escribe para SÍ MISMO debe declararse
`inherits: false`; si no, deja de ser un prop y se vuelve un contagio.
- `architecture/blocks.md` B-9: la demo de un block se construye sobre el
harness compartido y el block se enseña A SANGRE — nunca dentro de un marco
con relleno ni de una caja con scroll, porque eso cambia lo que el block
hace.
- `src/uix/blocks/README.md`: anatomía de la demo (harness, `{Name}Site`, ruta
`preview`, `DocRow`, catálogo único, ejes en el shell).
- `CONTINUE-blocks.md` (nuevo): handoff — qué toca (F2.2 `hero`), la plantilla
de ficheros para copiar, las reglas que ya costaron sangre (a sangre, iframe
solo para anchos de dispositivo, cada prop un control, nada de backticks en
`<Text>`, ojo con las variables que heredan), la deuda declarada que es
decisión del usuario y el estado exacto de los gates.
Gates al parar: `blocks:check` verde · `svelte-check` 73 errores, todos deuda
ajena (0 propios) · `vitest src/uix/eidos` 353/353 · `contracts.test` con los
3 fallos ajenos conocidos.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
3 months ago |
|
|
ee02c5c55f |
docs(agent): D-AG.12 y §5b firmadas — la spec, y quién prueba el eje
Dos decisiones que estaban pendientes, firmadas tras investigación a fondo
(precedente externo verificado a fecha, no de memoria).
D-AG.12 — EL CONTRATO COMO REFERENCIA
Spec normativa en `docs/spec/` (RFC-2119 + IDs `AG-n` + escalera
stable|provisional|reserved + versionado por fecha), en estado DRAFT para que
F4b se construya CONTRA ella y no al revés. La doctrina se queda con el PORQUÉ.
Conformance en DOS vehículos, que es lo que evita que la palabra sea retórica:
kit de fixtures del protocolo (PORTABLE — un tercero lo corre contra SU
implementación; semilla ScriptedAgentTransport) + agent-check (lint del repo),
ambos citando IDs de requisito en sus fallos. Las dos claims de frontera se
nombran con marcador claimed|shipped porque hoy ninguna está materializada.
Gate de promoción a 1.0: ≥2 formas de dominio + claims shipped + fixtures
verdes. Respaldo externo: MCP ya no promueve a Final sin escenario en su suite
(SEP-2484) y opera lifecycle formal con ventana de 12 meses; AG-UI se volvió
referencia por ADOPCIÓN (AWS Bedrock AgentCore, Microsoft Agent Framework), no
por publicar suite. La spec se escribe antes para gobernar; el título se gana
después.
§5b — QUIÉN PRUEBA EL EJE: form + table
El gate de F4 pedía «2 manifiestos reales» sin asignar dueños; esto rellena ese
hueco, no enmienda nada. El criterio deja de ser disponibilidad y pasa a ser
dificultad: un formato lo decide su caso peor. Y form+table no son preferencia,
son la ANATOMÍA del contrato — los args de una capacidad SON schemas (sium →
toJsonSchema, ya construido en F1) y un run ES una transacción sobre un
conjunto de ediciones. Form además dobla: agente→componente (args contra
campos) y componente→agente (elicitación) son la misma proyección en los dos
sentidos.
Chat y palabras quedan como CONSUMIDORES, no jueces. El riesgo que esto evita
era real: ambos son texto lineal, así que un manifiesto probado solo ahí
habría asumido texto en silencio (rango como selección, ediciones
secuenciales, args string) y el caso peor habría aparecido tarde. Inventario
al firmar: 170 morfos, 0 con capacidad delegate declarada.
COROLARIO — la elicitación no depende de superficie conversacional
Una pregunta tipada es un formulario en contexto (Form.AutoFields), descartable
y no-modal, que es justo lo que exige el contrato a11y (WCAG 2.2.4). La nota de
protocol.ts («materializes with the conversation surface») describía UNA opción
y se leía como necesidad: corregida ahí y en la doctrina §7.
DESCARTADO
Entrada de delegación global siempre-disponible: roza el modo ambiental, que
está FIRMADO FUERA (⚖️1), y no se recupera por la puerta de atrás. La entrada
es un patrón con pieles montado en app-land — mismo veredicto que la
review-card.
Handoff `continue-agente-2026-07.md` reescrito para mañana: la spec DRAFT es lo
primero, luego el kit de fixtures, luego F4b con los dueños ya firmados.
Verificado: agent 30/30 · agent:check limpio · docs:check sin errores nuevos
(el único es el preexistente ajeno de callout).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
3 months ago |
|
|
6b23aa7ef1 |
agent(guard): agent-check nace con la auditoría que ya tiene sujeto — anti-falsificación de actor
D-AG.11 (firmada) define SEIS auditorías. Cinco necesitan el árbol de manifiestos `src/uix/agent/components/`, que es trabajo de F4b — y el plan es explícito: el guard «nace CON el árbol, no después». Así que quedan DECLARADAS en el script y se reportan como pendientes: añadir un manifiesto las enciende, y el guard nunca puede ir por detrás de la superficie que vigila. La quinta SÍ tiene sujeto hoy y no la vigilaba nadie: F1 entregó el primitivo de actor (`$libs/actor` + el registro WeakMap privado del motor) y su invariante — que SOLO el motor acuña — no estaba protegida por nada. El token es una marca de compilación sin constructor en runtime: un forjado resuelve a null, pero un `as ActorToken` TIPA, y un contexto de actor construido a mano en el canon es exactamente la suplantación que el eje prohíbe (agent.md §5). Por eso D-AG.8 §2 dice literalmente que su defensa es el lint de agent-check, no el sistema de tipos. Dos reglas, sobre canon (uix · arts · libs · svrs · packs · web) excluyendo el arte agente: - `actor-forgery` — cast a ActorToken fuera de $agent - `actor-handbuilt` — `actor:` con valor literal (objeto/string/número) en vez de un token RECIBIDO; reenviar (`actor: opts.actor`) es la costura sancionada y calla. Los tests quedan exentos: ahí fabricar un forjado es precisamente lo que se prueba. Verificado en negativo, que un guard que nunca falla es teatro: inyectado un cast + un contexto a mano en `sema/signal.ts` → 2 hallazgos con fichero:línea y exit 1; revertido y de vuelta a limpio. `npm run agent:check` cableado junto a los demás guards del repo. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
3 months ago |
|
|
528af6f72d |
docs(blocks): F1 CERRADA (8/8) · registro de sidebar y su review
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
3 months ago |
|
|
59f20e2b1f |
uix(aura): el Status en dos líneas — cierra D1
La otra mitad de la dirección firmada: el anillo dice el estado como FORMA, pero la respuesta a «¿quién actúa?» es texto, y una palabra gris de 13px junto a un orbe vivo no la daba. Ahora el Status son dos renglones: Esperando tu revisión ← el estado, content-primary, peso medium la custodia es tuya ← qué significa para ti, secondary, un escalón menos Sin parte nueva: el Status ya existía y añadir un `Detail` habría sido abstracción prematura (y una pelea de layout — dos hermanos no apilan sin envoltorio). El soma renderiza las dos líneas por defecto y expone `detailText` en los snippet props, así que un consumidor que traiga sus children sigue mandando. La copia del detalle es FIJA por estado y localizada como la etiqueta (es/en): los contadores reales del run (turnos / actos) NO están en el puerto estructural, y ensancharlo para un subtítulo más bonito es una decisión, no un defecto. Queda dicho en el README por si algún día se firma. Tokens: `--aura-status-color` pasa a `content-primary` (era secondary: el peso informativo estaba en el sitio equivocado), + `-weight`, `-gap` y `-detail-color`. Verificado en Chrome real, claro y oscuro, con un run en `reviewing`: peso 500, primary sobre secondary, y las dos líneas escalando con `data-size`. Tests 478, eidos-lint 0 invalid / 0 class-hooks, morfo:vocabulary 0 errores, check en los 73 ajenos preexistentes. Con esto D1 queda cerrada entera (anillo + jerarquía). Handoff al día. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
3 months ago |
|
|
e10eed98cc |
uix(aura): la superficie visible del agente — anillo de custodia, orbe-contorno y desenlaces expresados
Rediseño dirigido por el usuario sobre un banco de mockups con el orbe REAL
corriendo dentro. Seis frentes, todos con maquinaria existente:
ANILLO DE CUSTODIA (parte nueva `Aura.Ring`, morfo+soma+eidos)
El estado se lee como FORMA y no solo como tinte: raíl punteado en reposo,
arco que respira al ofrecerse, segmentos = pasos del plan (laten), dos arcos
enfrentados y QUIETOS esperando tu revisión (la quietud lo separa de acting),
arco que gira actuando, anillo cerrado + pulso saliente cuando te necesita.
Envuelve al Indicator (es su marco de referencia, no un hermano posicionado a
mano). El movimiento continuo son loops REGISTRADOS (data-animation-style),
nunca @keyframes de receta (R-4.5) — vienen con su puerta de reduced-motion,
donde el dash sigue distinguiendo el estado. El attr va en los hijos del SVG,
jamás en la parte: motionAttrs() estampa además data-state, del morfo ahí.
EL ORBE ES UN CONTORNO
`thickness` en el efecto orb; el hueco es real (alfa propia) sobre cualquier
fondo. Se va la rama claro/oscuro y el parámetro backgroundColor: el shader
mezclaba con el fondo y derivaba el alfa del canal máximo, o sea pintaba un
disco OPACO del color de la superficie justo en el centro (en claro un círculo
relleno; en oscuro el azul del seed). Y la receta deja de pintar su disco en
cuanto monta el canvas (:has(canvas)) — solo sobrevive donde no hay render
vivo: SSR, tests, effect={false}, sin WebGL.
COLOR = TOKENS DE ROL, PINTADO Y NO ROTADO
colorA/colorB/colorDeep (solid / solid-hover / element) resueltos con
eidos.resolveToken y pasados como hex, que es el seam que el propio arte
documenta. El hue-delta anterior se medía en OKLCH y se aplicaba en YIQ: risk
salía VERDE junto a su propio anillo naranja.
ONION EN EL IDIOMA DEL ORBE
Prop `look="solid" | "luminous"` (defecto solid: nadie más se entera). En
luminous el sector no tiene relleno — filo de luz (pasada borrosa + nítida) y
etiqueta en el color del sector; la cuña sigue siendo área táctil. El trigger
con snippet propio va BARE: sin disco, sin sombra FAB y sin el salto del hover
(el orbe ES el trigger, no su contenido). Medio anillo bottom-center y radios
44/40. El halo respira (loop pulse) y en commit-select da UNA pasada de ping
pivotando en el centro real del menú — la firma genérica de commit anima
box-shadow, que sobre un path de SVG no hace nada.
DESENLACES EXPRESADOS (el hueco real: un fallo era indistinguible de un éxito)
Tres eventos terminales con intent INTRÍNSECO — delegate-return (fulfill) /
-aborted (sin intent: un decline es ausencia, no pérdida) / -failed (loss) —
en vez de un intent dinámico, que no tiene dónde vivir: TriggerOptions no
lleva intent y el fromProp del morfo ata a un prop PÚBLICO, no a estado de
máquina. Puerto `runs?` opcional en AuraAgentSource porque activeRun ya es
null al cerrar (§0: sin él, anuncio genérico). Primeras firmas de la familia
delegate en el registro; la de loss es MOVIMIENTO (return-recoil: retirada +
descenso), no tinte — no estrena ningún hue.
MAPA SEMÁNTICO DE COLOR (demo)
Un hue = un significado en toda la superficie: gris=sin agencia ·
naranja=tu revisión · morado=él actúa · rojo=escalated (exclusivo) ·
teal=tu sí. El anillo de autoridad reusa los colores de la custodia con el
MISMO sentido (Review=risk porque vivirás en reviewing; Auto=primary porque
actúa) y los declines pasan a neutral — canon: el intent de un cancel es
`absent`. Además el anillo en reposo DELEGA (las tres autoridades abren el
run) y se cierra por transición, no siempre que no hay run.
Dos guardas del framework corrigieron el diseño por el camino:
- BK-FRAME-NO-INTENT rechazó dar intent a una familia de marco sin
justificación escrita (excepción A-1): queda el intentRationale — el motor
no emite nada y no hay evento evaluable que enmarcar, así que el retorno
consolidado es el ÚNICO sitio expresivo del desenlace.
- fallbackTarget gana sobre el target del morfo (contrato de TriggerOptions):
el sello caía en el provider. Los terminales pasan el Ring cuando existe.
Verificado en Chrome real (ventana delante: en segundo plano el navegador
congela rAF y ResizeObserver y las medidas mienten): seis estados en claro y
oscuro, y un error de transporte REAL apuntando a un puerto muerto →
delegate-return-failed · loss · return-recoil sobre el Ring · región
«Agente: falló — control devuelto».
Tests 478 (morfo 114 · soma/aura 11, +5 casos de desenlace · eidos 353),
eidos-lint 0 invalid / 0 class-hooks nuevos, morfo:vocabulary limpio,
check en los 73 errores ajenos preexistentes.
Pendiente (handoff actualizado): la jerarquía tipográfica del Status (D1
llevaba dos líneas y solo se hizo el anillo) · el pulso de commit-select se
corta si el consumidor cierra el anillo al elegir (necesita retención tipo
Presence) · D5 la superficie de composición del encargo, decisión abierta.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
3 months ago |
|
|
e28df1817f |
docs(blocks): registro F1.7 fase morfo+soma en el plan
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
3 months ago |
|
|
ef6bd13be3 |
uix(nav-tree): `disabled` por nodo — destino no disponible
Decisión del usuario. Un nodo deshabilitado conserva su fila (sigue siendo parte del mapa) pero pierde el `href`: no hay nada que activar con clic, Enter ni «abrir en pestaña nueva». Un `pointer-events: none` de CSS solo habría tapado el ratón. - morfo: la parte `link` gana `data-disabled` (propRef) y `aria-disabled` (literal `true` bajo `prop-truthy: disabled`). - soma: `disabled` solo aplica con `href` (un grupo sin destino lo ignora); el toggle del grupo NUNCA se deshabilita — mostrar/ocultar es control de vista, no destino. - eidos: fila en `--color-content-disabled`, sin puntero y sin hover. - demo: «Agent» va deshabilitado con badge «Soon» + filas de API y a11y. Verificado en navegador real: `<a>` sin href, `aria-disabled="true"`, `data-disabled`, color 0.79 frente a 0.61 de una fila normal, clic sin efecto, fuera del orden de tabulación (44 focusables en vez de 45), badge dentro del control. `component:audit` PASS · eidos-lint 28 morfo-backed / 0 invalid · `vitest src/uix/eidos` 353/353 · svelte-check 0 errores míos. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
3 months ago |
|
|
a7e629f9ed |
uix(nav-tree): F1.8 CERRADA · demo + navegador + review adversarial
Cierra el árbol de navegación data-driven (E-1) de F1: demo canónica de 9
pestañas con el mapa real de docs (43 nodos, 3 niveles), verificación en
navegador real y review adversarial (5 dimensiones × 3 verificadores
escépticos; 22 hallazgos brutos, 10 confirmados) con todos los confirmados
arreglados.
Arreglos del review
- sema: la parte `group` —target de los eventos emerge— se registraba SIN
`ref`, así que `runtime.trigger` lanzaba `SomaRuntimeTargetError` en
silencio y el pack no sonaba nunca (cero `data-event-*` en el grupo frente
a los de collapsible). El provider posee ahora el ref del `<ul>`.
- eidos: en una fila navegable el chevron resolvía `inline-size: 100%` como
flex-basis y ocupaba media fila (101 de 231 px en «Soma»), robándole clics
al enlace. Toggle compacto con suelo de diana de 24 px (WCAG 2.5.8).
- soma: una clave duplicada podía volver cíclico `parentByKey` y colgar la
pestaña dentro de `trailKeys` (deriva en render) → clave sufijada + aviso
del logger + guarda de ciclo en el paseo.
- soma: el colapso es CONTEXTUAL (recuerda el `activeKey` bajo el que se
hizo): cerrar la sección que lees se respeta, pero caduca al navegar
DENTRO del grupo, para que la página actual nunca quede sin fila visible.
Sigue siendo query pura, sin `$effect` que escriba estado.
- soma: `child` recibe también `children` (el árbol renderizado); antes
dejaba el landmark vacío, porque un árbol data-driven no lo puede
reautorar el consumidor.
- morfo + langs: el nombre accesible del chevron se declara en el contrato y
se localiza («Alternar sección {label}»); ya no duplica el del enlace.
- eidos: RTL completo — el glyph espeja solo (bordes lógicos), lo que no
espeja es el giro, así que bajo `[dir='rtl']` las dos rotaciones se
intercambian. El Gap «dirección del chevron en RTL» queda RESUELTO.
- demo: paridad de snippet con los controles vivos; fuera el token fantasma
`--nav-tree-rail-width` del docblock del recipe.
badge en v1 (decisión del usuario, delegada)
Está en el suelo de paridad del dossier §P5 (los 6 refs lo llevan). Se
resuelve con SNIPPET, no con recursión a nivel de eidos: el morfo declara la
parte `badge`, soma renderiza el snippet recibido (sin él, el valor crudo —
sigue siendo headless) y el wrapper de eidos pasa el `Badge` canónico. Va
DENTRO del control de la fila, así su texto entra en el nombre accesible
(«TSC, New, enlace»). `disabled` se descarta en v1 (fuera del suelo, y un
enlace de navegación deshabilitado es semánticamente dudoso); ambos quedan
registrados en la tabla de Gaps.
Verificado: `component:audit` PASS · eidos-lint 26 morfo-backed / 0 invalid ·
`svelte-check` 0 errores en estos archivos · `vitest src/uix/eidos` 353/353 ·
navegador real (Playwright): trail auto-expandido, sema estampando en el
grupo, teclado nativo, foco visible, claro y oscuro, RTL, 375 px sin
desbordes, 0 errores de consola.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
3 months ago |
|
|
549c5e5abd |
docs(agent): D-AG.12 pendiente de firma — el contrato como referencia
PLAN §5: la decisión editorial planteada con el usuario (2026-07-22) queda firmable al retomar — (a) elevar agent.md a especificación publicable («el contrato de delegación») con agent-check como suite de conformance y el checklist de amenazas como anexo; (b) nombrar las dos reclamaciones de frontera que F4/F2 ya materializan: contexto por atención y delegación como transacción; (c) posición honesta declarada (acts secuenciales v1, cliente-first, generalidad pendiente del 2º/3º consumidor). continue-agente: punto 0 del orden de trabajo → firmar D-AG.12. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
3 months ago |
|
|
e835163103 |
uix(nav-tree): F1.8 WIP · data-driven docs nav tree (soma+sema+eidos)
Complete component, green on all static gates (audit PASS, eidos-lint 20/0, svelte-check 0, contracts clean for its parts). NOT tree-view: APG Disclosure Navigation (<nav> landmark + native links + disclosure groups), data-driven (E-1) — the app passes `nodes` + `activeHref`, the provider resolves the active node and auto-expands its ancestor trail. - morfo: nav/list/item/trigger/link/group; emerge-expand/collapse events - soma: NavTreeProvider (shared state, pure isExpanded query) + per-node NavTreeItemProvider (menubar pattern, recursive render) - sema pack: soft emerge on group disclosure (mirrors collapsible) - eidos: rail + per-depth indent recipe; own bespoke rows (not composed Link), Badge deferred to a Gap; aria-current="page" from data-active Remaining before F1.8 closes: demo + browser verify + adversarial review. Handoff: docs/process/CONTINUE-nav-tree.md Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
3 months ago |
|
|
1cc8a87722 |
docs(agent): continue-agente — handoff para la próxima sesión
Estado al cierre (F0/F1/F3/F4a cerradas + tabla de commits), verificación rápida al retomar, siguiente trabajo en orden (F4b chat → F2 gated → flecos), y la disciplina operativa de la rama compartida + gotchas de entorno (Ollama/OpenWebUI, pane, Chrome MCP, index:0 del stream). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
3 months ago |
|
|
0ab40cdcee |
uix(agnt): Aura al centro de un OnionMenu — afordancias radiales por estado
La composición que pidió el usuario: el orb es el trigger central de un OnionMenu placement="center" y las afordancias de custodia aparecen como sectores contextuales — reviewing→Authorize/Reject, escalated→Approve/Deny, activo→Stop — sin fila de botones. El anillo se abre SOLO mientras la custodia espera a un humano, con re-aserción (un cierre externo sin resolver re-abre: el efecto lee onionOpen como dependencia); por click en el centro mientras actúa; se pliega al devolver el control. App-land por doctrina (agent.md §7): el framework da estados + afordancias (Aura) y componentes (OnionMenu); el app da forma a la superficie de review. Patrón documentado en el README de aura (§Patrón). E2E verificado en Chrome real contra qwen3-coder: la escalada real por doc.clear abre el anillo con el orb rojo al centro → Deny en el sector → returned(aborted, user-cancel) + «Agente: terminó — control devuelto» + documento intacto. check 0 propios · smoke agnt PASS. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
3 months ago |
|
|
595040b73b |
feat(agnt): Aura como superficie de presencia de la demo con modelo real
La respuesta a «¿está pensando?» no se improvisa — es Aura, el componente
del eje construido para ello. La sección real de la página agnt bootea un
uix standalone mínimo (createActiveUix + Soma + ActiveEidos + eidos css):
legítimo porque un app compone ambos tiers, y la demo ES el app.
- Motor llama → createActiveAgent (mismas opciones bus+journal); activeRun
reactivo satisface AuraAgentSource; stream vía .engine.onEvent
- <Aura {agent}> con Indicator (orb $scene) + Status + Region + Cancel;
authorize/escalation quedan como afordancias app-level (doctrina §7)
- Verificado sobre el run real de qwen3-coder: «Inactivo» → «Propone un
plan» → announcement «Agente: terminó — control devuelto» en la Region,
doc mutado, answer en es; Cancel = Button disabled-en-idle; consola 0
check 0 propios · agent 30/30 · smoke agnt PASS.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
3 months ago |
|
|
447a87239c |
feat(agent): adaptador openai-chat real + carril de iniciativa del bus
El bus como eje del agente a nivel de app, cerrado en tres direcciones:
observar (agent.*), reaccionar (orca) e INICIAR — hecho de dominio → acción
orca → App.agent.start({initiative:'system'}) con clamp auto→review por
construcción. Nunca command-events. Sección doctrinal + ejemplo en la página.
Adaptador real `$agent/adapters/openai-chat` (fuera del barrel, D-AG.1c):
dialecto OpenAI chat-completions (Ollama/llama.cpp/LM Studio/proxy), SSE →
protocolo v1, sanitización bidireccional de capability ids con puntos, y
re-pairing de tool_calls al reproducir el transcript (memoria por callId).
Fix cazado en vivo: Ollama reutiliza index:0 para todas las calls del
stream — una call nueva se detecta por id distinto, jamás por index (los
args concatenados producían invalid-args en motor + 400 en el replay).
Demo viva en /active/docs/agnt contra qwen3-coder:30b real: capacidades
doc.* tipadas (sium), read snapshot-por-turno, streaming, escalada
irreversible. Ciclo completo verificado en navegador: 3 acts, 2 turnos,
doc mutado, respuesta en es, rastro entero en bus (correlationId=runId).
agent 30/30 · smoke agnt PASS · check 0 propios.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
3 months ago |
|
|
fa71890564 |
fix(agent): conformidad bus/orca — payload del bus sin contenido de usuario
Auditoría punto-a-punto contra los README de bus y orca (12/13 conforme).
La no-conformidad real: `goal` viajaba en AgentRunBusPayload, contra la
higiene documentada de ambos (bus: «pasa correlationId y que el suscriptor
resuelva el contexto sensible del módulo»; orca: «no unnecessary private
data — la acción lo resuelve del módulo al ejecutar la acción»).
- AgentRunBusPayload = SOLO metadata (runId/initiative/autonomy/state/
outcome/reason/acts/turns); el suscriptor resuelve vía App.agent.run(runId)
- spine test prueba el patrón: 'goal' in payload === false + resolución
desde el módulo con el orca REAL
- página agnt: nota de higiene + recomendación configureEvent(
'agent.run.state', { queuePolicy: ORCA_QUEUE_REPLACE_QUEUED }) para el
evento frecuente (doctrina de colas de orca)
- PLAN-agent F4a: acta de la auditoría de conformidad
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
3 months ago |
|
|
803b588ba5 |
feat(agent): F4a · marco de integración app — bus/orca/página del arte + fixes de auditoría
Auditoría del track (encargo): divergencias firmadas-sin-implementar corregidas y el marco de integración INDEPENDIENTE del componente — el agente como servicio del app, no como demo de un componente. Fixes de decisiones firmadas (con tests): - C3/D-AG.7: la iniciativa autónoma (system/scheduled) clampa auto→review — un run que el usuario no pidió jamás se auto-autoriza. - D-AG.5: presupuesto de contexto (maxContextBytes) con FIFO-trim byte-based (el goal sobrevive; resumen semántico diferido) + log del recorte. - F4c: tope por-arg (maxArgBytes) → invalid-args tipado. - D-AG.6d: schema Standard-Schema del resultado (`result?`); un mismatch vuelve como recoverable para auto-corrección y no cuenta como act. Integración app (patrón session EXACTO): - El arte posee el vocabulario `agent.*` (consts) + bus-helpers tipados que publican con bus INYECTADO (type-only $libs/bus): run.opened/state/ escalated/closed + act.applied, con source='agent' y correlationId=runId — la costura causal ligera (una delegación correlaciona de punta a punta). - defineActiveAgent cablea core.bus (junto a timers/logger). - Reacciones vía orca APP-LAND (el invariante intacto): probado con EngineOrca REAL reaccionando a agent.run.closed en integration.test. - Página del arte /active/docs/agnt (la convención que faltaba): sección Delegation en nav; artículo + playground VIVO con los 4 motores puros reales (bus log en vivo, journal WAL, contador orca, kill switch, compuertas deterministas) — cero componentes, integración pura de app. Gates: agent 26/26 · smoke agnt PASS · check 0 propios · verificado en navegador (pane + Chrome real): ciclo completo, orca archiva runs, kill switch reactivo. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
3 months ago |
|
|
2803d5dddc |
docs(blocks): registro F1.6 anchor-nav · F1 = 6/8
Adversarial-review outcome (fixes + documented v1 limits) and the two piggybacked sticky type-fixes recorded; scoreboard corrected (prose F1.5 had also landed). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
3 months ago |
|
|
e187ab6d72 |
docs(agent): F3 cerrada · doctrina «The review surface» — split framework/app
Cierra los dos flecos de F3 tras la corrección del usuario (la review-card con diff era anclaje en dev-tools, sin sentido a nivel framework): - agent.md §7 gana «The review surface»: el FRAMEWORK posee los estados del ciclo expresados perceptualmente (reviewing/escalated con afordancias authorize/reject/cancel — Aura ya las da) + la semántica de «propuesto por otro actor» + los anuncios atribuidos; el APP posee el CONTENIDO de lo que se revisa, en su propio dominio (un documento enseña sus bloques propuestos, un calendario sus eventos pendientes). Una tarjeta-diff estilo git es legítima en una aplicación concreta; jamás canon. - §6 fatiga de aprobación enmendada en el mismo sentido (el cambio concreto en el dominio del app, nunca prosa). - PLAN: F3 CERRADA — review resuelta como doctrina sin componente nuevo; `allowedFamilies` del primer componente actuado reubicada a F2 (su hogar natural es el piloto). Siguiente: F4 por la vía del chat. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
3 months ago |
|
|
2c175c5d95 |
feat(aura): fases 7–8 · README eidos + component:audit PASS — Aura completa (0–8)
Cierra el primer componente del eje agéntico de punta a punta (las 9 fases de la ruta). `component:audit` PASS. - README eidos con comparativa (5 refs adyacentes — thinking-indicators, CopilotKit activity, Vercel useChat.status, presencia colaborativa Figma/Docs, assistant-ui) reconociendo el paisaje escaso: nadie tiene una semántica perceptiva de la delegación con a11y (informe §8.3). Decisiones + Gaps con disposición. - Fixes del audit: opacity literal `0.5` → `var(--opacity-50)` (R-4.2); excepción R-1.5 documentada (único focusable = Cancel, que compone Button); `apg: 'none — …'` en el morfo (A-1.4). Gates: component:audit PASS · morfo:vocabulary limpio · eidos-lint aura 0 inválidos · recipe-contract verde. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
3 months ago |
|
|
6be7195f0f |
feat(agent): eje agéntico — motor $agent (F1) + Aura + promoción uix.scene
Materializa el eje ortogonal agéntico del ecosistema: la 8ª familia semántica
`delegate` («¿quién actúa ahora?») deja de estar sin materializar. El agente es
OTRO ACTOR (LLM, macro, regla, workflow) que actúa por la MISMA API pública del
provider; la ruta de llamada no se bifurca, la concreción semántica depende del
actor.
F0 · Doctrina
- docs/architecture/agent.md — la doctrina permanente (capítulo comparativo de
referencias + bibliografía de seguridad, máquina estados=verbos, contrato de
participación, fila §0, a11y, amenazas).
- docs/process/{PLAN,TRIAGE,INFORME}-agent — plan de ejecución con todas las
decisiones firmadas (D-AG.1–11 + ⚖️1/2/3), triage de 4 revisores externos, e
informe autocontenido para revisión externa.
F1 · Motor ($libs/actor + arts/agent, 24º arte)
- EngineAgent puro (sin DOM/runes, portable a servidor): máquina D-AG.4
(suggest/review/auto · escalated con reason+timeout · returned outcome-tipado
· kill switch · autorización journaled aunque sea auto), tool-loop D-AG.5
(acts secuenciales, fallos→verbos, unknown-capability acotado, idempotencia
por callId, presupuestos acts/turns/wall-clock vía puerto de timers), techo de
autonomía por origen no confiable (F8b).
- ActiveAgent (sesión reactiva, contrato ActiveEngine) · protocolo v1 espejo
AG-UI (5 categorías + dirección tipada + reservas) · ScriptedAgentTransport
determinista (adapters/ fuera del barrel) · journal WAL + puerto de trazas
OTel · emisor sium→JSON Schema.
- Acuñación del actor (⚖️2/F6b): ActorToken opaco en $libs/actor (hoja bajo
orca/agent), registro privado WeakMap — los forjados resuelven a null;
costura `actor?` en TriggerOptions→SemanticSignal (runtime copia verbatim;
sema no resuelve). defineActiveAgent (service-factory app-level, timers del
core — cero setTimeout a pelo).
F3 · Aura — primer componente del eje (ruta 9 fases 0–6)
- El materializador canónico de `delegate` (reservado en scene §F6): morfo con
los eventos del ciclo (offer/escalate-untilAction/return + sustain-processing
stateBound) — PRIMER morfo del ecosistema que emite familia delegate; provider
soma que observa un puerto estructural (sin importar $agent — degradación
total); orb eidos = aurora $scene modulada por estado (§F6) con fallback CSS
= render de reduced-motion; live region única atribuida (WCAG 4.1.3); cancel
compone Button (asChild). Demo v2 sobre el MOTOR REAL con compuertas
deterministas. Orb-size derivado de la primitiva Avatar (32/40/48).
D4 · Promoción uix.scene (Aura llegó)
- defineEngineScene + superficie ActiveUix/ActiveEidos/contracts; el orb prefiere
el motor compartido (presupuesto de escenas global) con fallback por-superficie.
Gates: arts/agent 18/18 · aura 6/6 · arts:check 24 · eidos battery + recipe
30/30 + eidos-lint aura 0 inválidos · morfo:vocabulary + esquemas · smoke aura
PASS · verificado en navegador (ciclo completo + estampa delegate en DOM +
aurora WebGL pintando). Los tokens de recipe base.ts + CSS generado ya entraron
en HEAD vía una sesión concurrente.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
3 months ago |
|
|
955c6a18b3 |
docs(blocks): registro F1.5 prose · 5/8 F1
|
3 months ago |
|
|
11ba4b906b |
docs(blocks): registro · review sticky + fix writing-mode · F1.1 CERRADO
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
3 months ago |
|
|
c6964496b4 |
docs(blocks): registro F1.1 sticky · 4/8 F1 hechas
Registra sticky (
|
3 months ago |
|
|
9124570e69 |
uix(callout): F1.4 · admonicion inline (morfo+eidos) al suelo del dossier
Tercera pieza F1 del plan blocks (alcance E-2, dossier §P3). Banner = tira de anuncio de pagina; Callout = el aside del documento (split deliberado). - morfo: 4 partes (provider role=note / icon / title / content) + texts con TITULOS DEFAULT LOCALIZADOS por intent (note/tip/warning/caution — patron GitHub de label visible: la semantica nunca viaja solo en color/icono); 0 eventos justificados (dismissible DIFERIDO a pasada soma+sema por la regla de admision — dismiss ES un evento real) - el hueco IMPORTANT resuelto con el modelo Radix, sin 5o enum: `intent` (neutral|affirm|risk|threat — mapea NOTE/TIP/WARNING/CAUTION) + `color` override SOLO bajo neutral (doctrina §4: intent evaluativo gana); IMPORTANT = intent neutral + color + titulo propio (preset en la demo) - pintura sobre la maquinaria C6/THM-2 (patron badge): forwarders por color + slots `_palette-track/text/solid` → el generador emite la cascada de 8 roles Y el forward presence-guarded al shared layer — 33 escalas y colores custom con CERO CSS extra - a11y: role=note NOMBRADO via aria-labelledby → Title SOLO mientras esta montado (registro reactivo por context local); escalacion tipada role=status|alert|none (el role=alert estatico de shadcn = bug de referencia que NO copiamos); Title NO es heading (protege el outline que escaneara anchor-nav); icono decorativo = mapa doctrinal IntentIcon - fix cazado en navegador: el `+=` del registro leia el estado dentro del tracking del $effect del hijo → effect_update_depth silencioso (contador a -997, attr nunca estampado) — untrack() en register/cleanup; leccion registrada en memoria (incidente 2 de la clase) - recipe: grid con acento logico border-inline-start (RTL-correcto), nesting tolerado (Docusaurus); demo v2 9 tabs con preset IMPORTANT + PalettePicker showIntent=false; README completo Verificacion: component:audit PASS 0E/0W · eidos-lint 8 morfo-backed/0 invalid · guards 37/37 · svelte-check 76E/51W = baseline exacto · navegador: «Nota»/«Atencion» localizados · risk=ambar hue 45-60 · IMPORTANT=plum hue 326 resuelto por shared layer · labelledby=titleId · cero errores de consola. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
3 months ago |
|
|
bf940c9a4a |
uix(result): F1.3 · estado terminal de flujo/pagina (morfo+eidos) al suelo del dossier
Segunda pieza F1 del plan blocks (alcance E-2 = suelo de paridad, dossier
§P3). Comparte el esqueleto de empty-state a proposito: EmptyState describe
AUSENCIA de datos, Result reporta un RESULTADO — un lenguaje de layout, dos
contratos (duplicacion consciente registrada en el README; revisable al 3er
consumidor).
- morfo: 6 partes display (provider/media/title/description/actions/extra;
extra SIN archetype — parte genuinamente propia), scope ['eidos'],
0 eventos justificados (el resultado ya OCURRIO antes de renderizar)
- status: enum de 7 = paridad AntD CON `warning` (decision firme del
dossier) y HTTP renombrados semanticos (forbidden/not-found/server-error,
nunca '404' stringly); default 'info'; data-status = attr eidos-only
- media default: compone el mapa doctrinal IntentIcon (success→fulfill ·
error→threat · warning→risk) + Info de catalogo; HTTP = codigo mono
grande NEUTRO aria-hidden (situaciones, no fallos — AntD jamas pinta 404
de rojo); children reemplazan el default entero (context local eidos-only
con getter reactivo)
- Title default h2 (vs h3 de empty-state — Result suele SER la pagina);
Actions con label→role=group; Extra alineado a inicio (detalle que lee)
- recipe: glifo display 3× xl bundle; tokens publicos
gap/actions-gap/measures + {status}-color como forwarders de rol
retintables; sin eje size (paridad AntD, gap diferido)
- demo v2 9 tabs con copy por status + entrada nav (Status) + README
(Comparativa · Decisiones · Passive justification · Gaps con disposicion)
Verificacion: component:audit PASS 0E/0W · eidos-lint 6 morfo-backed + 5
eidos-only sancionados · recipe/api/visual-attrs 37/37 · morfo:check verde
(los 7 fallos listados son deuda foranea preexistente) · svelte-check
76E/51W = baseline exacto · navegador: success=fulfill verde 84px ·
error=threat rojo · not-found=«404» mono neutro, copy conmutando, cero
errores de consola.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
3 months ago |
|
|
f19e91b985 |
uix(empty-state): F1.2 · componente base display (morfo+eidos) al suelo del dossier
Primera pieza F1 del plan blocks (PLAN-blocks.md; alcance E-2 = suelo de paridad, dossier §P3). Ruta de 9 fases completa: - morfo: 5 partes display (provider/media/title/description/actions), scope ['eidos'], 0 eventos con justificacion pasiva (patron renderEmptyState de las refs headless), Title role:'heading', texts.label - langs: components.empty-state.label (es/en) — el indice tambien recoge la retirada foranea del import de words (inseparable por staging de archivo; coherente con la migracion palabras ya enviada; words.ts sigue en su arbol) - eidos: compound EmptyState + Media(kind icon|media, placa 2x glifo) + Title(level 2-6, default h3 — modelo Atlaskit, tamano visual desacoplado) + Description(measure 45ch) + Actions(label -> role=group +aria-label, buttonGroupLabel); recipe sobre el bundle --size-* (titulo un paso discreto arriba; sm=in-collection, lg=hero); tokens publicos minimos (gap/actions-gap/media-bg/media-fg/media-radius/description-measure) - demo v2 9 tabs (harness: SystemAxes/MotionPanel/SemaPanel; snippet con paridad; escena in-collection via Card) + entrada nav (grupo Status) - README: Baseline · Comparativa (shadcn/Chakra/Atlaskit/AntD/Polaris) · Decisiones · Passive justification · Gaps con disposicion Verificacion: component:audit PASS · eidos-lint 5 morfo-backed + 4 eidos-only sancionados · morfo:check + morfo:vocabulary verdes · recipe-css-contract/api-contract/visual-attrs 37/37 · svelte-check 76E/51W = baseline exacto (cero regresion) · navegador claro Y oscuro por estilos computados (titulo 18->24px, placa 40->64px, chips vivos, cero errores de consola). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
3 months ago |
|
|
647db398ee |
blocks(plan): enmiendas E-1..E-5 firmadas — F1=8 (+nav-tree), F2=14, paridad=v1
Firmas del usuario (2026-07-21) tras el dossier de referencia: - E-1: componente canonico nav-tree (F1.8, data-driven — precedente Menubar) resuelve la colision sidebar-app vs arbol-docs/B-5; fiche nueva con fase 0 obligada contra nuestro tree-view; docs-shell compone NavTree. - E-2: suelo de paridad del dossier = alcance v1 (regla en intro F1). - E-3: F2 pasa de 10 a 14 (banner · team · contact · content-section); fiches nuevas + galeria actualizada (verificada en navegador: 28 badges). - E-4: distribucion registry/llms.txt/MCP → iniciativa propia (next-features §9; ese archivo sigue fuera del commit por diff foraneo). - E-5: ⌘K = listener app-land documentado (nota en F4.1). Doctrina: promotion path de architecture/blocks.md actualizado a 8. Verificacion: docs:check 0/0 (512). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
3 months ago |
|
|
aff42fee0f |
docs(blocks): dossier de referencia — 6 pistas, suelos de paridad + enmiendas E-1..E-5
Encargo del usuario (2026-07-21): estudio de referencia para "estar al menos a la par y cuanto menos superarlo". 6 agentes de investigación web en paralelo sobre fuentes oficiales vivas (varias verificadas a nivel de código fuente: sidebar.tsx del registry shadcn, styles.js de tailwind-typography, sources de Mantine/Starlight/Docusaurus/Ark). - docs/process/RESEARCH-blocks-references.md — el dossier: P1 catálogos de marketing (conteos+variantes) · P2 aplicación (ProTable/ProLayout, dashboard-01, Tremor 303, Clerk/Supabase) · P3 F1 ligeros (APIs a nivel de prop; scroll-state(stuck) como vocabulario de plataforma; role=alert de shadcn = bug a no copiar) · P4 prose+sidebar (not-prose/:where()+donut; shadcn 23 partes) · P5 docs shells (Fumadocs benchmark; colision F1.7 vs nav-tree/B-5; ruta svelte2tsx para props TS) · P6 ecosistema Svelte (shadcn-svelte 58 blocks solo-app; hueco "sistema integrado" VACIO) + sintesis: 5 conclusiones, enmiendas E-1..E-5 (presentadas, firmas pendientes), 10 angulos de superacion. - PLAN-blocks.md — regla nueva §4 (toda fase 0 contrasta contra el dossier), puntero de colision en F1.7, registro. Verificacion: docs:check 0/0 (512 docs). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
3 months ago |
|
|
0697596046 |
blocks(tier): F0 · infraestructura del tier (doctrina + $blocks + guard + galería)
Tier nuevo aprobado 2026-07-21 (D-BLK firmadas; D-BLK.1 enmendada: vive en src/uix/blocks/). Plan de ejecución completo en docs/process/PLAN-blocks.md. - docs/architecture/blocks.md — doctrina E1 (regla de admisión canon-vs-block, contrato B-1..B-11, promotion path); espejo de packs.md - alias $blocks → src/uix/blocks (vite + svelte.config + tabla CLAUDE.md) - src/uix/blocks/README.md — mapa del tier + template de README de block (B-9) - scripts/blocks-check.ts + npm run blocks:check — guard mecánico del contrato B con self-test de detectores (fixtures inline; 5532 archivos de canon/arts/libs/packs escaneados para dirección de imports) - web/routes/blocks/ — galería índice del catálogo planificado + layout de bootstrap propio (+layout@.svelte, espejo mínimo del de /uix sin packs sema) Verificación: docs:check 0/0 (511) · svelte-check 76E/51W = baseline exacto · blocks:check verde · galería comprobada en navegador (a11y-tree + estilos computados en light y dark; captura de píxel bloqueada por panel suspendido). Fuera del commit: fila E1 en docs/README.md y §8 en docs/next-features.md (diff foráneo de otra sesión sin separar — ver registro del plan). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
3 months ago |
|
|
5aa8090bad |
color: contraste Stage 2 — contrato §40 como datos + guard CI; solver descartado
La ejecución refutó la premisa del plan: el morph HEREDA el contraste del texto (steps 11/12 = curva-L del donante verbatim; ~invariante al croma bajo gamut-mapping), así que toda escala desde donantes §40-compliant cumple por construcción. Medido en 3 bancos (base, leave-one-out, 45 semillas OOD): 0 fallos del gate duro text-strong·12, min WCAG 9.7:1. El solver de luminancia no tenía nada que resolver → descartado por especulativo. D2 = base verbatim (sin migración base→seeds). - $color: CONTRAST_PAIRS (arts/color/contrast-contract.ts) — tabla §40 como datos compartidos: floor duro text-strong·12, banda text·11 (tope relacional, sin nº mágico), border·7 exento - scripts/contrast-audit.ts: muere la PAIRS pre-veredicto (4.5 duro contra §40), consume CONTRAST_PAIRS + banco de regresión morph-generado - eidos/lib/contrast-invariant.test.ts: guard de CI (4 tests) que bloquea la herencia - docs: reference.md §40, next-features.md §1, changelog.md §45, plan (OUTCOME) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
3 months ago |
|
|
44a016538c |
docs(color): plan verificado de Contraste Stage 2 (generador by-construction)
Plan de ejecucion para sesion aparte, VERIFICADO adversarialmente (workflow de
7 agentes contra codigo y docs) antes de escribirse — corrige 5 afirmaciones
de la respuesta que lo origino:
- "por delante de Radix (hex sRGB)": FALSO — el propio RFC §14 registra Radix
con APCA y P3 ("Radix style"); la posicion del repo es "on par"; nuestra
paleta enviada es sRGB-equivalente (oklch = siblings de hex).
- "el solver satisface la tabla §40": el UNICO floor duro ratificado es
text-strong·12 ≥ 4.5; text·11 quedo tier blando (decision D1); solid·9 esta
anclado exacto a la semilla; el script de auditoria aun codifica la tabla
PRE-veredicto (consumirla contradiria los veredictos → F0 = tabla como datos).
- "los tipos ya existen en parte": ColorScaleSeed/Source son solo prosa del
RFC; config-seeds imposibles hoy (solo applyColorScheme roles-only +
generatePalette full-33 como bancos).
- "792 hex en base.ts": exacto en total pero en DOS ficheros (288 base.ts +
504 color-scales.ts); 4 escalas ya autoradas desde semillas offline.
- "nada downstream cambia": nombres si (contract.ts), pero hay pins de VALOR
disenados para dispararse (hex literales, flip-set de polaridad,
generated/base.css byte-exacto) + persistencia rechaza version ≠ 1.
El plan: F0 tabla ratificada como datos + harness sobre output generado ·
F1 solver (biseccion contra sRGB gamut-mapeado, salida hex, desviacion minima
del donante) · F2 validacion en bancos de semilla + navegador · F3 (gated)
migracion base→seeds con re-ratificacion de pins y pase visual. 6 decisiones
de usuario ABIERTAS al frente (target text·11, semantica base+ΔE, modo
on-solid, colocacion/alcance, tipos Fase 0, normalizacion de la tabla).
next-features §1 enlaza el plan. (El hunk ajeno de chat-list en next-features
queda fuera del commit — danza clean-desde-HEAD.)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
3 months ago |
|
|
f0de4faf75 |
docs(color): handoff de cierre definitivo de la jaula del color
Actualiza el handoff y el changelog §43 al estado FINAL de la iniciativa (cerrada, cuarta sesión): - open-color-cage-2026-07.md: añade las 2 fugas transitivas cerradas (card-group-item · s-text) + el guard runtime, el fix del bug de Card/Avatar (`b93cc6c5c`), la lista completa de commits (sesiones 3–4), y una sección «Follow-ups» con lo menor que queda (override docs-chrome sobre `<Code>`, ringColor roles-only, límites de los 2 guards, comentarios históricos) + nota del estado del working tree (WIP de chat/palabras sin commitear, ajeno). - changelog.md §43: el bug de Card/Avatar pasa de «flageado, NO arreglado» a ARREGLADO con el resumen del fix (migración a resolveComponentColor + compose del seed + canales ring/badge separados intactos). Sin cambios de código. La iniciativa queda CERRADA sin huecos abiertos (qr-code excluido por diseño). Contract 30/30. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
3 months ago |
|
|
72a6569c3e |
uix(color): abre `color` en la familia chart (resolver SVG rol/escala/crudo)
Chart era el último hueco de la iniciativa. Su `color` NO tinta labels/ejes:
tinta la MARCA de datos (stroke de línea, fill de área/barra/burbuja, hue de
heatmap, arco de gauge, porción de pie/funnel/bar-list/polar, punto de smith).
Es SVG con resolución JS, así que NO usa el `data-color` + capa de paleta
compartida (eso es para cascadas CSS en HTML) — el mecanismo es propio.
Resolver central en `chart/context.ts`:
- `seriesColor` / `seriesSurface` reescritos + `seriesContrast` nuevo, todos
`number | ComponentColorProp`. Un índice cicla `SERIES_ROLES` (multi-serie,
sin cambios). Un valor explícito pasa por `resolveChartColor`:
· rol/intent → `var(--color-{role}-{solid,surface,contrast})`
· una de las 33 escalas → `var(--scale-{name}-{9,a2})` (steps solid /
surface-alpha del `PALETTE_SLOT_STEP`); contrast → white (no hay token)
· valor CSS crudo → verbatim (surface = `color-mix 15%`, contrast = white;
sin contraste garantizado, el trade-off de cualquier custom).
- `ChartContext.color` widenado a `number | ComponentColorProp`.
Todos los props `color?: ColorRole` (~14: ChartSeriesProps, Bubble, Sparkline,
ChartCategory, BarList, Funnel, Calendar/Heatmap, Smith×2, Gauge) →
`ComponentColorProp`. Los 3 builders que armaban el fill inline (funnel:
solid+contrast, heatmap:56, calendar-heatmap:118) refactorizados para pasar
por el helper — funnel pierde su `roleOf` local.
qr-code queda FUERA por decisión de diseño (color = tinta de módulos del QR,
contraste con el fondo, no encaja escalas).
Verificado en Chrome: las 3 ramas del resolver resuelven a color real
(--scale-teal-9→oklch, --scale-teal-a2→rgba translúcido, #3b82f6→verbatim,
mix translúcido ok); marcas existentes = primary-solid (roles behavior-
preserving). check chart limpio; contract 30/30. Docs: changelog §43 +
handoff actualizados (hueco chart cerrado, qr-code excluido por diseño).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
3 months ago |