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 }
10 Commits (468a9d1134d697546f1b36231d6773d6324a5faa)
| Author | SHA1 | Message | Date |
|---|---|---|---|
|
|
062384ccaa |
docs(morfo)!: filas 13 y 14 — los TRES estados de una entrada sin fuente, y la regla de alpha deja de vivir solo en prosa
FILA 13(c), firmada: una entrada declarada sin `value` tiene tres estados y la diferencia era invisible. (1) con value: la emite la bolsa y la verifican compilador, resolver e instrumento. (2) sin value, required, sin condición: la emite el PROVIDER y morfo-check EXIGE el attr en el elemento — la única forma sin fuente que alguien verifica. (3) sin value con optional o con condición: CONTRATO-ONLY — nadie la emite y nadie la exige; legitima el attr cuando aparece y documenta que el provider puede emitirlo, nada más. El tercer estado se QUEDA porque es la única forma de decir «el provider lo posee Y es condicional» — descartadas (a) exigir siempre (pondría rojo el caso legítimo) y (b) prohibir la condición (quita expresividad honesta). Se escribe donde se lee: el JSDoc del campo, el comentario del pase (d) que prometía más de lo que el código hace, y una tabla en morfo.md. Dato para no optimizar lo minúsculo: en ese pase `severity` es el filtro DOMINANTE y `condition` el marginal. FILA 14(a), firmada: `web/routes/alpha` (TERMINATED) pasa de doctrina en prosa a entrada de .gitignore con su acta. La lección que la motiva es del peer vicen-e1: `git add <directorio>` consulta .gitignore, JAMÁS doctrina — una regla que solo vive en prosa no la hace cumplir nadie, y anoche entró en un commit por eso. De paso deja de ensuciar el status de las tres sesiones. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
1 month ago |
|
|
0556b9a1ac |
feat(morfo)!: decisión 7 — `value` es OPCIONAL en aria[]/attrs[]: declarar la EXISTENCIA sin poseer el valor
Firmada por el autor (bolsa de 12, 2026-08-27). La asimetría con data[] —que
siempre admitió la entrada sin fuente— hacía INEXPRESABLE la cura del lote L5
(un attr cuya aritmética el morfo no puede computar: depth+1, colIndex+1);
un constructor lo midió con tsc y paró. Ahora el contrato puede decir «este
attr existe, el provider posee su valor», que es la forma que data[] practica.
- types.ts: `value?`, con la doctrina en el JSDoc.
- compile.ts: guard `if (!entry.value) continue` en ambos cubos, réplica
LITERAL del de data[] (:452): sin plan y sin deps, pero la entrada consta.
- schema.ts: `value` opcional + invariante nuevo — `ariaBoolean` sin value
LANZA (pedir stringificación booleana de un valor inexistente es
declaración incoherente).
- resolver.ts: consecuencia OBLIGADA que el lote destapó — `resolvePartAttrs`
escribía `undefined` en la bolsa para una entrada sin fuente, y `dom.apply`
lee undefined como BORRA: habría pisado el valor del provider (la ley de
wave por la otra puerta). Ahora salta, simétrico a data.
- morfo-check: el pase ARIA ya distinguía «declarado sin fuente» de «no
declarado» por construcción (declaredAria mapea por attr); queda la ley
escrita y la mitad «required sin condición» SIGUE exigiéndose: que el
provider posea el valor es la promesa de que emite uno.
PROVENIENCIA CORREGIDA en los 3 sitios (JSDoc de schema, JSDoc del flag y el
MENSAJE QUE SE LANZA): citaban la regresión
|
1 month ago |
|
|
5027c135fb |
feat(morfo)!: la ARISTA es ley — instrumento composition-aware, residuo a cero y el pase ARIA GATEA
El instrumento de la fila cero, en su forma magra firmada por ambos carriles: la identidad del compuesto YA viaja por la tubería única (cada parte compuesta estampa su attr identificador namespaced en el mismo elemento), así que morfo-check resuelve la arista desde los ATTRS CO-LOCALIZADOS — la cláusula del pase data («allow other components' part attrs») generalizada al ARIA que esas partes declaran. Cero superficie nueva de contrato. Índice de 919 attrs con guardia de colisión ruidosa (cero hoy, medido). Límites DECLARADOS en el header: ARIA de consumidor sigue flagged (search-field) · lo que no monta es invisible (clase RateButton) · dos-contratos-mismo-attr = check futuro nombrado. Disparador NOMBRADO para el marcador explícito: si el flip bidireccional del censo de fuentes destapa filas que lo estático no adjudica. Resultado medido: cosecha 258 → 16 → CERO (la clase de composición cayó al 100 % por construcción; dos pasadas byte-idénticas + confirmación con gate armado: 161/161, exit 0). El residuo, adjudicado leyendo: - card-group: la causa raíz era UN STRIP — la eidos amputaba data-collapsible-trigger/content «para que solo pinte Button/grid» (comentario literal). El attr identificador ES contrato, jamás un toggle de estilo: RESTAURADO, y el conflicto de pintura se resuelve con la arista EN CSS — collapsible guarda sus 4 bloques de trigger con :not([data-button]) (un Button del sistema trae su pintura — §15, el canal sigue al dueño) y card-group neutraliza el padding con el selector de DOS attrs [data-collapsible-content][data-card-group-content] (la arista como selector, especificidad 2). Verificado en vivo: pintura de Button intacta, padding 0, clip del colapso conservado, ambas aristas presentes. (El no-toggle con dispatch sintético es limitación de sonda — el Collapsible plano tampoco; perm-check con clicks reales lo ejercita.) - gradient-builder.angle-dial: forma de parte corregida — era un WRAPPER de layout declarando role slider + trío de un elemento que eidos renderiza como div contenedor del <Slider> compuesto (el Slider posee su semántica en SUS partes). - table demo: la celda FALSA deja de reclamar data-table-cell (attr de parte sin su parte = mentira al instrumento); su pintura prestada queda re-escrita demo-side. - Excepciones FIRMADAS ×2 con dueño de la cura: search-field.input ×3 (harness combobox escrito por LA DEMO) · palabras.status aria-live (la eidos escribe el div a mano por su propia doctrina 4.1.3 — fila del eje palabras). FLIP: el pase ARIA deja de ser advisory y GATEA (la ley P0: el gate se arma DESPUÉS del cero). La maquinaria advisory queda documentada como patrón de rollout de la casa para el próximo pase. morfo 264/264 · confirmación gateada 161/161 exit 0. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
1 month ago |
|
|
17c6adddcb |
feat(morfo)!: P1 — split attrs[]/aria[] y vocabulario ARIA cerrado: cada cubo su territorio
El cubo aria[] mentía un 13,5 %: 989 entradas medidas — 847 aria-*, 8 role, y 134 impostores (type ×130, tabindex ×2, for, contenteditable). - MorfoPart.attrs[]: cubo nuevo para atributos HTML genéricos, misma forma de entrada y mismo compilado (un solo builder para ambos cubos). - aria[] se CIERRA por tipo: MorfoAriaAttr = 'role' | unión del spec (53 nombres, DERIVADA del array ARIA_ATTR_VOCABULARY — nunca lista paralela, la lección MorfoElement). aria-grabbed/aria-dropeffect deprecados-en-1.2 con acta (verdad embarcada de drag-drop); braille*/description son 1.3 y entran anotados. Un typo muere en el tipo. - Esquema guarda el territorio en AMBAS direcciones: aria[] con no-aria LANZA sugiriendo attrs[]; attrs[] con aria-*/role o data-* LANZA. - Codemod: 134 entradas movidas en 62 morfos (133 bloques). Orden de emisión MEDIDO y conservado: data → attrs → aria (132/133 bloques declaraban el impostor como prefijo contiguo de aria[]); snapshot de los 921 parts × 168 morfos: 920/921 byte-idénticos — la única divergencia (breadcrumb.ellipsis, type tras un aria-label consumerWins) no cambia la bolsa renderizada. - Consumidores de part.aria censados: compile/resolver/schema actualizados; morfo-check pierde un filtro MUERTO (el cubo ya llega cerrado por tipo+schema); landmark-census y tests de la mitad aria sin cambio. - morfo.md documenta los dos cubos. 13 tests nuevos (8 schema territorio + 5 compile paridad). morfo 262/262 · soma entera 1314/1314 · check 71. Nota de árbol compartido: src/uix/morfo/source-census.test.ts (sin trackear) es el eje SourceMap de vicen-e1 y NO viaja aquí (add -u); su censo re-medirá sobre este árbol asentado, orden acordado por canal. Ejecutado por agente Opus 5, sesión coordinando y verificando (guardas de territorio probadas en vivo, suite re-corrida). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
1 month ago |
|
|
da9f342c61 |
feat(scripts): P1·A11Y — morfo-check gana el pase ARIA en modo ADVISORY
Presencia de entradas aria required SIN condición · role declarado vs renderizado · aria-* sin declarar (tría A-85 del consumidor exenta: aria-label/labelledby/describedby). Imprime y cuenta APARTE, no gatea: la cosecha se adjudica primero y entonces se voltea a gate (la lección de P0 — medir, adjudicar, y solo después armar). El handoff registra el estado P1 completo con deudas nombradas. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
1 month ago |
|
|
9dffa541ef |
fix(uix): fase A cierre — los seis rojos del censo morfo:check, adjudicados
Cada uno leído antes de tocarlo; tres clases distintas: - combobox.input y gradient-builder.track: el morfo declara el data-* SIN value (soma posee el valor — el idioma que el propio trigger de combobox documenta) y nadie lo escribía. El comentario del input además afirmaba que la bolsa lo resolvía, cosa que una declaración sin fuente no puede hacer. Escritura manual, como sus hermanos. - menu-dial.trigger: componente de scope eidos (contrato espejado a mano); el trigger estampaba marker y aria pero olvidó data-state — la lista de al lado sí lo lleva. Espejo del idioma existente. - calendar (data-calendar-surface) y fab (data-fab-size): attrs visuales de wrapper / hooks compartidos de eidos, sancionados FUERA del morfo por la doctrina firmada (precedente: data-combobox-control). El instrumento no conocía la doctrina: nace scripts/eidos-only-attrs.ts como lista ÚNICA que consumen morfo-check y eidos-lint-all, para que los dos instrumentos no puedan divergir. - palabras.handle: el grip porta el escape del focus-scope a propósito (comentario in situ con la razón); la declaración alcanza a la implementación sancionada. Los otros cuatro rojos del censo previo no eran contrato: accordion, background y link eran timeouts de compilación fría (pasan en caliente) y color-field lo sanó la unificación de la bolsa por sí sola. Verificación: morfo:check 160/161 con los seis en PASS — el único rojo restante (natural-time-picker) es la clase flaky del instrumento «demo que navega bajo el eval» (no falló en ninguna de las dos pasadas previas; la ruta verificada a mano en navegador con su contrato completo) · schema sweep 89/89 · eidos:lint exit 0 · combobox 11/11 · palabras 84/84. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
1 month ago |
|
|
cf7c83a6d3 |
Reconnect morfo DOM check
|
5 months ago |
|
|
91257e8526 |
soma/morfo: rename root part → provider + fix toolbar effect loop
Naming coherence across the part layer: the root part's `kebab` field now
matches its `name: 'Provider'`. The `createAttrs` special case still emits
`data-{component}` (no suffix) for the provider part — the DOM contract is
unchanged, only the authoring name changes.
Affected:
- createAttrs special-case: 'root' → 'provider'
- 66 morfos: kebab 'root' → 'provider'
- 77 soma provider files: `attrs.root` → `attrs.provider`, constructor
part arg 'root' → 'provider'
- Docs: A2 rule rewritten, morfo/README, soma/README example updates
- Test / schema / morfo-check: updated for new kebab
Toolbar fix: remove `itemsVersion` counter and per-item `$effect` blocks
that called `notifyItemsChanged()`. The pattern was an A30 violation —
each item's $effect read `ref.current`/`disabled` and wrote back to the
provider, which cascaded through `firstTabStop` → per-item `props`
$derived → DOM reattach → effect re-run, triggering
`effect_update_depth_exceeded` on page load. `isTabStop` now uses
`untrack` around the DOM walk so per-item `props` derivations only
depend on `lastFocusedElement`.
Verification: 7/7 morfo tests, 65/65 smoke, 66/66 morfo-check, no effect
loops detected across any demo page.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
6 months ago |
|
|
8a5b402dd3 |
morfo: port 65 components + sium.lazy + morfo-check passes 66/66
All 65 soma components now consume their morfo as the cross-layer contract.
createAttrs(morfo) and registerContract(morfo) overloads removed — the
Morfo form is now mandatory. Each component provider has a 3-line morfo
import + wire-up block instead of 20+ lines of inline declarations.
Additions:
sium/core/lazy.ts — lazy() combinator for recursive schemas (unblocks
morfo's eventual lazy part-tree validation; tests included).
sium/examples/ — booking, color, login, settings, signup, survey, tree
form demos.
Route demos at src/routes/test/sium/{booking,color,login,settings,
signup,survey,tree}.
Tooling:
morfo-check.ts — now tolerates sibling parts sharing a physical element
(Link variant of Item, etc.). Queries via allPartAttrs cross-scope.
morfo-vocabulary-check.ts — 28 WARN (legitimate per-component
vocabularies or subsets like switch missing "indeterminate"). All
reviewed, none are bugs.
Fixes caught by morfo-check:
table: data-sorted / data-pinned marked severity:'optional' (only
emitted when sorting/pinning active, not always).
tree-grid: data-expanded on Row severity:'optional' (branches only).
menubar: data-menubar-value declared on Trigger.
splitter: data-splitter-panel-id declared on Panel.
Verify:
npm run check — 0 morfo errors (4 pre-existing in sium/examples,
unrelated).
npx vitest run src/uix/morfo — 7/7 tests pass.
npm run smoke — 65/65 routes pass.
npm run morfo:check — 66/66 morfos validate against real DOM.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
6 months ago |
|
|
8c16ffac81 |
morfo: cross-layer contract + 14 new WAI-ARIA components + Dialog wired
Morfo (src/uix/morfo/): machine-readable contract of a component's public DOM surface, shared between soma/sema/eidos. Shape v5 consolidated across three independent AI reviews (Gemini, Grok, ChatGPT) plus Sema alignment. Types, sium-based validator with cross-field invariants, dialog.ts as the first canonical morfo with data-last-action for Sema-causal exits, 7 passing unit tests. createAttrs(morfo) and registerContract(morfo) now consume a Morfo — legacy inline signature removed. Dialog provider refactored to derive parts + data contract from dialogMorfo. The other 65 soma components need porting (svelte-check lists them) — tracked work. Tooling: scripts/smoke-check.mjs — Playwright smoke over 65 soma demo routes scripts/morfo-check.ts — validates emitted DOM vs morfo scripts/morfo-vocabulary-check.ts — canonical vocabulary consistency npm run smoke / morfo:check / morfo:vocabulary WAI-ARIA APG components added (100% APG coverage now): Announce, Avatar, Clipboard, DragDrop, Feed, GridList, Meter, Progress, SearchField, TagGroup, TreeGrid + Table.RowDetail/Trigger (detail panel pattern; hierarchical Table rows deprecated — use TreeGrid instead). air: Link, Banner. Sema prep: src/uix/sema/sema_pre.md documents the semantic layer's DOM requirements. Morfo already provides everything Sema needs (data-last-action patterns, transition markers, enumerable state values, cross-component consistency). Sema implementation deferred. COMPONENT_GUIDE updated: items 37-39 (translation namespace grep, DOM topology vs .require() audit, npm run smoke is part of done) + A34 rule with incident log. WAI-ARIA pattern listed as soma membership criterion. Pagination translation bug fixed (soma.pagination.page -> idlangref PAGINATION_LANGS.PAGE). Table demo namespace fix (soma.table.* -> components.table.*). Avatar demo now offline-safe (SVG data URL). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
6 months ago |