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 }
729 Commits (468a9d1134d697546f1b36231d6773d6324a5faa)
| Author | SHA1 | Message | Date |
|---|---|---|---|
|
|
468a9d1134 |
style: prettier de una sola vez sobre el repositorio (F5 del cierre, parte 3)
Formato puro: `npm run format` (dos pases; siete ficheros no convergían en el primero) sobre todo lo que .prettierignore no excluye (web/ congelado, .claude/, artefactos generados). Este commit va en .git-blame-ignore-revs. Neutralidad medida fichero a fichero, compilando y minificando con esbuild (y con el compilador de Svelte, cliente y servidor, para .svelte) la versión de HEAD y la formateada: 1 031 ficheros de código idénticos; 9 CSS que solo difieren en espacios pegados a un paréntesis (`var( --x )` frente a `var(--x)`), que CSS no tokeniza como significativos; 510 Markdown sin compilación posible (docs:check los valida). Los dos generados y el guard que dependía del formato se resolvieron en el commit anterior. Verificación sobre este árbol: npm run lint exit 0 · gate entero verde salvo focus-census, arreglado en el commit anterior y re-ejecutado (9/9): check:gate OK (src/ y scripts/ a cero) · docs:check 0/0 · arts/blocks/packs/rtl/ translations/agent · eidos:lint 0 inválidos · apps:check (boot 27/27, 0 errores) · suite 465/466 → 466/466 con el guard corregido · build de la raíz exit 0. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
3 weeks ago |
|
|
adb680899a |
fix(eidos,sema): el Button de eidos reenvía bind:ref, el aviso de opciones de sonido queda pineado desde la raíz y sema.md dice quién enciende announce (F4 del cierre)
Lote mínimo de honestidad de API del plan de cierre. Cuatro items, cada prueba
vista fallar; constructor y adversarial Opus (este con mutaciones propias y la
verificación global sobre los mismos bytes).
1. A-106 — `<Button bind:ref>` de eidos nunca recibía el elemento: el Button
pasaba `...headlessProps` al de soma y un spread de rest props transporta
el valor, no el binding (el proxy de rest props de Svelte 5.55 no tiene
setter). Ahora `ref = $bindable(null)` + `bind:ref`, el patrón de los 14
wrappers que ya lo hacían. Test client (Chromium) con raíz real: sin el
arreglo `Received: null`. El adversarial lo midió también con asChild,
loading y dentro de ButtonGroup (llega el nodo pintado en los cinco casos)
y mutando `bind:ref` → `{ref}` (rojo).
2. Opciones del motor de sonido con motor compartido — el censo viejo decía
«descartadas en silencio»; ya no lo eran (engine.ts aplica `masterGain` y
avisa de las claves inaplicables), pero nada lo pineaba. Test nuevo desde
`createActiveUix` con logger real: el gain cae en `uix.sound` y el aviso
nombra exactamente `audioContextFactory` y `fetcher`. Lo tumban cinco
mutaciones, una de ellas en la raíz (sema con un motor privado).
3. docs/architecture/sema.md §Announce decía «opt-in» a secas. Cierto para un
`EngineSemantic` desnudo; falso en las raíces, que registran el canal por
defecto (S-19(ii)). El título y el primer párrafo lo separan, con el
opt-out exacto de cada modo. Cada frase ejecutada por el adversarial contra
motor desnudo, standalone y attach.
4. SemaSignatureOverride, rama `Record<string, DeltaValue>` — NO se retira:
es por donde entran los ops que sema.md:257-263 documenta para overrides de
haptic (`{ op: 'add', value: 0.1 }`), y el resolver los honra en runtime
(medido: 0.5 → 0.6). Retirarla rompe 0 sitios en svelte-check (no los 8 del
plan) pero volvería error de tipos la forma doctrinal. El tipo exacto por
hoja con DeltaOp es fila del ledger; channels.ts byte-idéntico.
Filas que deja para el ledger: el mismo defecto de ref en 532 ficheros de 99
componentes de eidos (muestra runtime 3/3); la rama Record admite typos y
valores basura; applyOverride clona un DeltaOp literal como firma cuando la
familia no tiene slice haptic base (HapticChannel lanza); «opt-in» sin
calificar en book-deviations.md:508 y announce.ts:13; attach/motor desnudo sin
pin directo de announce.
Verificación (adversarial, lote con sha256 5/5 idéntico al commiteado):
check:gate OK (89 de web/ dentro del ledger, src/ a cero) · suite 466/466
ficheros · 5445/5445 tests (+2/+3) · docs:check 0/0 en 820 docs · eidos:lint
0 inválidos · apps:check verde (smoke boot 27/27, 0 errores) · el resto de
miembros del gate exit 0 · prettier limpio en lo nuevo (button.svelte arrastra
dos líneas de deuda previa, idénticas en HEAD; las cierra el one-shot de F5).
Coordinador: los tres ficheros de test tocados, 45/45; docs:check 0/0.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
3 weeks ago |
|
|
834e6c49a0 |
feat(apps): apps/base — la primera app que consume UIX como fuente desde un workspace, y su check entra en el gate (F3 del cierre)
Hasta hoy ninguna app consumía el framework fuera de su propio árbol de demos, y por eso la receta del boot pudo estar rota en producción sin que nadie lo supiera. apps/base es un esqueleto SvelteKit con adapter-static estricto y prerender, que sigue docs/consuming.md al pie de la letra: alias por resolveUixAliases, runas por config, raíz standalone (createActiveUix + setActiveUix + Soma + ActiveEidos con applyDom), boot compilado con SU esquema (es/en/ar), CSP por hash con el artefacto propio, fuentes y sonidos copiados al static/ de la app (assets:sync, con --check). La página es un AppShell con un Toggle de modo, un Select de idioma y un Dialog. Raíz: workspaces ["apps/*"] (una sola copia de svelte 5.55.0, vite 7.3.1, kit 2.55.0 y esbuild 0.27.4; lock +23 líneas); apps:check = check + build + smoke de la app, dentro del gate justo antes de la suite; .gitignore y .prettierignore para lo generado y lo copiado. El smoke sirve build/ por HTTP y pasa tres visitantes (es-ES, ar-EG, es-ES con modo oscuro y movimiento reducido), cada uno con los módulos abortados (sellos del boot) y con carga completa (0 pageerror, 0 console.error, 0 violaciones CSP, delta 0 entre boot e hidratación). Comprueba además que el tag del boot va DESPUÉS del <meta> CSP: encima, corre sin política y Kit no lo avisa. Constructor, adversarial y dos rondas de cierre (Opus). El adversarial escribió una segunda app solo con el contrato y la hizo arrancar en Chromium, Firefox y WebKit; midió la CSP en siete variantes y tres motores, y mutó la app para ver si el smoke muerde. Defectos cerrados: - D1: el smoke prometía contar traducciones ausentes y en una build de producción no hay señal (engine-langs las emite solo en DEV). Ya no lo promete; README y consuming §8 dicen dónde se ve cada cosa. - D2: el smoke nunca abría modo oscuro. Tercer visitante con el valor afirmado; un pin 'light' olvidado en la raíz ahora da exit 1. - D3: sin reset de documento el Dialog medía 409 px en un móvil de 375. La app lleva su reset de tres reglas (doctrina vigente: el reset es de la app); que la fundación lo traiga es fila del ledger. - D5: los textos del esqueleto seguían en castellano bajo lang=ar. Salen de src/lib/strings.ts por langs.ts(record), tipados. - D6: esa garantía de tipo la sostenía una unión de idiomas escrita a mano. Ahora hay UNA tupla (APP_LANGUAGES en prefs-schema.ts) que leen el esquema, los textos y el Select. Visto fallar: con 'fr' en la tupla, check exit 1 con 8 errores que nombran fr; restaurado byte a byte. - C1-C3: el contrato gana el tsconfig mínimo medido (rewriteRelativeImportExtensions, sin él 578 errores), las rutas de import de Soma/ActiveEidos/createThemeBaseEidosConfig y adapter-static + prerender. Cero cambios en src/**. Huecos del framework que la app destapa, al ledger: el Dialog modal no devuelve el foco al trigger (queda en BODY en los 3 motores: FocusScope enfoca mientras HideOthers aún tiene el inert), Select.Value muestra el value crudo hasta abrir el popup, los catálogos de componentes no tienen 'ar', la foundation se carga dos veces (482 KB enlazados + 426 KB inyectados por applyDom, 5 153 tokens duplicados), guide.md llama eidos.listThemes() dentro del hook, la regla 6 de active-uix.md está caducada, y uix.langs no lleva el tipo del catálogo de la app. Verificación: apps:check exit 0 (1391 ficheros 0 errores · build · smoke `boot 27/27 · unguarded 0 · pageerror 0 · console.error 0 · csp 0 · delta 0 · flips 0`) · boot de la app 15 365 B, byte-idéntico en dos compilaciones, su hash en el <meta> de build/index.html · docs:check 0/0 en 820 docs. Sobre el lote antes de D6 (D6 no toca src/, scripts/ ni la suite): gate entero exit 0 en 357 s, check:gate 89 dentro del ledger, suite 464/464 ficheros · 5442/5442 tests. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
3 weeks ago |
|
|
4f3425783b |
docs: el contrato de consumo — una app del workspace consume UIX como fuente (docs/consuming.md)
El framework no tenía ni una línea sobre cómo se consume desde fuera de su propio árbol de demos: todo el corpus asumía acceso al repositorio. El autor decidió que la app que viene después lo consume COMO FUENTE, en un workspace de este repositorio, sin paquete npm ni exports ni bin. docs/consuming.md es ese contrato, sección a sección, enlazando lo que ya tiene página propia en vez de copiarlo: dónde vive la app (apps/<name>, un solo node_modules y una sola copia de Svelte), los alias (resolveUixAliases en kit.alias), el modo runas por config, la raíz de composición standalone (attach existe y no lo consume nadie), el CSS y los assets servidos por URL (fuentes y sonidos se copian al static/ de la app), y el boot pre-hidratación (la receta de la guía de theming con <uix> = ../..). docs/README.md lo enlaza en E4 y en «I want to…». La guía de theming deja de llamar «fila abierta» al empaquetado: el consumo es un contrato de workspace. La app base de F3 es el primer consumidor real y la verificación del contrato: lo que no se sostenga al construirla se corrige aquí. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
3 weeks ago |
|
|
29e581c721 |
feat(active-uix)!: el boot lo compila el build del SITIO con su propio esquema, y lo que UIX escribe en <html dir> lleva marca de propiedad (fila 2 del boot, F1 del cierre)
F1 del plan de cierre del framework. Cierra el último trabajo del eje boot.
EL DEFECTO. El boot por defecto compilaba un catálogo de preferencias de UN
solo idioma (createDefaultUixPrefsSchema), y la raíz sembraba su entorno
leyendo el <html dir> que el boot acababa de escribir: un usuario árabe de
una app multiidioma no veía un parpadeo, se quedaba en LTR TODA la sesión,
porque el runtime tomaba la salida del boot como si la hubiera declarado la
página.
EL COMPILADOR POR SITIO. Una sola fusión, composeUixPrefsSchema, la consumen
createActiveUix y el boot: no puede derivar. El generador acepta --schema y
--out (el especificador boot/boot-schema.ts apunta al esquema del sitio o a
boot/default-schema.ts); los guards (sin runas, techo de tamaño, ASCII, sin
</script, valores string por atributo) son errores del COMPILADOR con mensajes
para el consumidor, porque ahora el artefacto lo produce el sitio. Un esquema
que importa el barrel $prefs se rechaza nombrándolo. scripts/uix-boot-check.ts
es el guard de rancidez: plugin de Vite que tumba el build con un artefacto
viejo (probado con vite build real) y función para CI. Delta cero por esquema:
por defecto, multiidioma con árabe, ejes redefinidos y esquema parcial.
LA MARCA DE PROPIEDAD, diseño firmado por el autor. El canon de dirección dice
que <html dir> es una proyección y nunca una fuente, con una sola excepción: el
dir del AUTOR en la plantilla o el servidor. El boot rompió la premisa de esa
excepción. Todo lo que UIX escribe en <html dir> lleva ahora
PREFS_DIR_PROJECTED_ATTR (el boot con valor «boot», cada proyección del runtime
con un token de instancia); la semilla solo adopta un dir SIN marca. Un dir
escrito por script no es una fuente: en ejecución la dirección se afirma con
prefs.setIntent('direction') o options.prefs.environment, que ganan a la
semilla. Se descartaron, midiendo, la marca con valor (cierra el script y
congela la dirección al navegar entre layouts) y la inferencia por valor.
dispose solo retira lo que todavía es SUYO: SvelteKit crea la raíz del layout
nuevo ANTES de destruir la vieja (medido), y un retiro a ciegas dejaba el
<html> de la raíz nueva sin dir, lang ni data-motion/sound/haptic (medido hoy:
los nueve atributos a null). Mismo principio que el unstamp de sema, que
comprueba data-event-id.
esbuild se declara como devDependency EXACTA 0.27.4: los bytes del boot y su
hash dependen del minificador, y una subida dentro de un rango rompería la
sincronía. Boot 15 198 B, sha256-hsqdGYcrRu3oEc0Q3G/A67ApQT3q9c/vT9zMDgxROg8=
(el hash se mueve: firmado por el autor).
VERIFICACIÓN. Constructor Opus en cuatro rondas y adversarial Opus en dos
pasadas independientes, con sus reproducciones repetidas tras cada cierre:
en Chromium, entrar en árabe y pasar a inglés y a español sigue al idioma, y al
revés también; el dir de plantilla gana antes y después de hidratar y en una
raíz recreada; una raíz recreada sobre una viva sigue al idioma con y sin boot;
tras create b → destroy a, <html> conserva lo que proyectó b. Diez defectos
declarados por el adversarial, cerrados (D1–D10): marca de propiedad, esquema
parcial que estampaba "undefined", vigilante de dev mudo, plugin sin test,
receta de CI que no cargaba en jsdom, cifras y prosa, y un vite build real que
se cae cuando el boot no compila. Mutaciones en rojo, restauradas byte a byte:
la proyección no marca · dispose sin guard de dueño (también repetida por el
coordinador: 3 rojos) · la semilla compara valor en vez de presencia · marcar
el dir del autor. Suite entera 463 ficheros / 5 437 tests, exit 0 · check 0 errores en src/ y en scripts/ (89 en web/, ledger intacto) ·
docs:check 0/0 · generate:boot dos veces byte-idéntico.
LO QUE NO CIERRA (al ledger de cierre): (1) PREEXISTENTE — en la misma
navegación entre layouts, el ActiveEidos.dispose de la raíz vieja sigue
retirando data-theme/mode/density/scaling de la raíz nueva; exige cambiar el
dispose de eidos, otra capa. (2) La propiedad de los atributos proyectados
cuelga de la marca de dir: si la plantilla declara la dirección, dispose deja
lang y data-motion puestos cuando la raíz se desmonta sin sustituta
(benigno). (3) Sin boot, un script que escribe dir antes de la primera raíz es
indistinguible de la plantilla y se adopta. (4) El vigilante de dev no
reacciona a ficheros nuevos ni a inputs fuera del root.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
3 weeks ago |
|
|
a6bc4ce900 |
docs(process): handoff de la familia commerce — diseño D-COM.1…5 firmado el 2026-08-10, cero código
338 líneas de diseño firmado que nunca entraron en el repo: la sesión que las escribió trabajaba por lista explícita en rama compartida y no las incluyó. Se anclan tal cual como parte del cierre del framework (F0 del plan); su trabajo pendiente queda congelado en el ledger de cierre, no se ejecuta. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
3 weeks ago |
|
|
233ffdac08 |
docs(process): handoff — boot fila 1 anclada 9ae58c236 (panel de 9 agentes: cuerpo constante, hash fijo, receta por hash, delta contra documento limpio, audit dev); fila 2 en vuelo y las filas que deja para el autor
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
3 weeks ago |
|
|
9ae58c2365 |
feat(active-uix)!: el boot viaja como CUERPO CONSTANTE con los parámetros en un atributo — un hash de CSP fijo, sin node:fs, y la delta deja de confirmarse a sí misma (fila 1)
La receta documentada del boot pre-hidratación no funcionaba en ningún despliegue
real, y el panel de diseño de nueve agentes que el autor pidió lo confirmó
midiendo: con el `render.ts` anterior, un build REAL de SvelteKit con
adapter-static revienta el prerender con `ENOENT …/output/server/generated/boot.js`
y devuelve un 500. La causa: `renderUixBootScript` leía el bundle DEL DISCO junto
a su propio módulo, y una vez empaquetado ese fichero no está ahí.
FORMA NUEVA. El generador compila una entrada propia (`boot/entry.ts`), sin
`globalName`, y emite el MISMO fichero de siempre (`generated/boot.js`, sin
borrar nada) como módulo con dos constantes: el texto exacto del script y su
`sha256-…`. `renderUixBootScript` pierde `node:fs`, `node:path`, `node:url`, la
caché y el envoltorio que estaba ESCRITO A MANO: al no haber `globalName`, la
llamada la hace la propia entrada compilada. «Compilado, no escrito» sale
reforzado, no rebajado.
LOS PARÁMETROS VIAJAN EN UN ATRIBUTO del mismo `<script>`, no dentro del cuerpo.
Consecuencia, que es el punto entero de la fila: el cuerpo es CONSTANTE, así que
su hash es constante por versión del framework, igual para todos los sitios y
todos los `themeIds`. La guía pasa a tener UNA sola receta, por hash, que cubre
prerender, SSR y hasta `mode: 'nonce'`; el nonce baja a salida de emergencia. Un
bloque `application/json` hermano se descartó con razón medida: rompería la
invariante de que el tag parsea a exactamente un `<script>` y un minificador de
HTML podría borrarlo sin que nadie se entere.
TRES MENTIRAS DE LA GUÍA, CORREGIDAS. `event.locals.nonce` no existe en Kit
2.55.0 (cero ocurrencias en su código; `respond.js:168` es `locals: {}`), así que
la receta anterior pasaba `undefined`, el navegador bloqueaba el script y volvía
el flash sin un solo error. El placeholder estaba ENCIMA de `%sveltekit.head%`,
donde la política de prerender de Kit no lo alcanza: eso es evadir la CSP, no
cumplirla, y no vale cuando la política llega por cabecera. Y el `html.replace`
con cadena interpreta `$'`, así que ahora la receta usa reemplazo FUNCIÓN. Se
añade el aviso que puede tumbarle la página al consumidor: añadir un hash a un
`script-src` que lleva `'unsafe-inline'` hace que el navegador IGNORE
`unsafe-inline` y bloquee los demás scripts inline del sitio, incluido el
arranque de Kit.
EL CRITERIO SE CORRIGE. `boot-delta.test.ts` gana un tercer snapshot contra un
documento LIMPIO. El anterior arrancaba el runtime sobre el documento ya sellado,
y como `directionDimension.derive` devuelve `env.direction` antes de derivar del
idioma y el entorno se siembra leyendo el `<html dir>` que el boot acaba de
escribir, la columna `dir` se confirmaba a sí misma. Medido con el boot clavado a
`rtl`: los cinco rojos caen todos en la lectura nueva y ninguno en la anterior.
AUDIT DEV. La raíz compara en desarrollo su primera proyección con lo que ya hay
en `<html>` y NOMBRA los ejes que discrepan. Convierte en ruidosos cinco fallos
que hoy son idénticos y mudos: pin olvidado, `themeIds` incompleto, `storageKey`
distinto, artefacto rancio y script bloqueado por la CSP.
Artefacto 14 666 B, `sha256-5fulJ/2Q6DttR258KqIhWSwfm5g7973BEzzzq14fapY=`,
generación determinista. Verificación: suite entera 461 ficheros / 5404 tests, exit 0 · check con
0 errores bajo `src/` y bajo `scripts/` (89 en `web/`, ledger intacto) ·
docs:check 0/0/819 · `npx vitest run src/uix/active-uix` 9 ficheros / 97 tests.
El test nuevo `boot/pack.test.ts` empaqueta `render.ts` y lo ejecuta: sale ROJO
contra el código anterior con el ENOENT literal, y es lo único que impide que
esta clase vuelva.
Adversarial Opus independiente (árbol byte-idéntico al terminar, 14 mutaciones
revertidas): midió el hash bajo CSP real contra un servidor HTTP en Chromium 145,
Firefox 146 y WebKit 26, con control negativo bloqueado; montó una app SvelteKit
real siguiendo la guía al pie de la letra y la vio construir, prerenderizar y
arrancar sin violaciones; y probó el ENOENT con un build real. Declaró 5 defectos
del lote, ninguno bloqueante, cerrados en una segunda ronda y re-verificados uno
a uno con su reproducción original: un universal falso en un comentario, la
puerta del artefacto sin validar el cuerpo (ahora con guard propio importable),
la constante del hash sin comillas para quien escriba su propia cabecera, el
audit que SÍ viaja al bundle de producción (1 428 B medidos, no un supuesto; no
CORRE, gracias a un ternario que el bundler no pliega) y el eje que se nombraba a
profundidad 2 y ahora va en el mensaje. La redacción del guard del artefacto,
último defecto de la segunda pasada, la corregí yo: corre en cada render, 76 us
con artefacto frente a 1,49 us sin él, medido.
Filas que deja para el autor: los 1 428 B del audit en producción, si se gatean
con una bandera que el bundler pliegue · el audit queda mudo si el runtime se
desecha en el mismo turno · la fila 2 debe decidir si la puerta verifica que el
hash describa al cuerpo.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
3 weeks ago |
|
|
3de47b73b7 |
docs(process): handoff — fila render.ts HECHA 418297a82; tres filas PREEXISTENTES del boot en produccion (ENOENT empaquetado, nonce de Kit que nunca llega, replace con cadena) registradas para firma del autor
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
3 weeks ago |
|
|
418297a82a |
test(active-uix): el boot se prueba por el tag REAL que inyecta el sitio, y el nonce se valida contra la gramática de CSP
`renderUixBootScript` es el único camino de producción al boot pre-hidratación (guía de theming, §59) y ningún test lo importaba. La suite de delta cero no lo llamaba: ejecutaba una COPIA de su envoltorio con `new Function`, la segunda implementación que la doctrina del boot prohíbe («compilado, no escrito»). Nadie vigilaba que `pins` llegase al boot, que el escape de `<` impidiera cerrar el tag antes de tiempo, ni el atributo `nonce`. Tres decisiones firmadas por el autor: 1. `boot/render.test.ts` (nuevo, jsdom): forma del tag (un `<script>`, un solo cierre, ningún `<!--`); nonce ausente, válido (base64 y base64url) e inválido; reenvío de TODOS los parámetros medido por comportamiento en `<html>` (`defaultLocale`, `pins`, `themeIds`, `storageKey`); ida y vuelta byte a byte de una clave y un themeId hostiles con `</script>` y `<!--` sin inyectar markup; ningún global tras ejecutar; higiene del bundle generado. 2. La suite de delta ejecuta el tag real: muere `runGeneratedBoot` con su `new Function` y `BOOT_SOURCE`. El único ejecutor vive en `test/boot-script-tag.ts` (DOMParser inerte + `vm.runInThisContext`, script clásico en ámbito global). No eval indirecto: el bundle abre con `"use strict"` y el eval estricto guarda sus `var` en un entorno propio, así que una fuga de `__uixBoot` habría sido invisible (medido en Node y Chromium; un control positivo lo pone en rojo si vuelve). 3. El nonce se valida contra CSP Level 3 `base64-value` y fuera de ella lanza `ActiveUixInvalidBootNonceError` (`uix::boot.invalid_nonce`, con la longitud, nunca el valor). `JSON.stringify` escapaba para JavaScript y no para un atributo HTML: `a"b` salía como `nonce="a\"` más un atributo basura, y `<` llegaba decodificado. La validación ES el escape. Razón precisa (corregida por el adversarial antes de anclar): fuera de la gramática el valor no es un `nonce-source` válido; Chromium 145 y Firefox 146 no lo casan, WebKit 26 tolera `=` de más, así que ninguna política portable puede apoyarse en él. El nonce de SvelteKit 2.55.0 (`btoa` sobre bytes aleatorios) siempre la cumple. `render.ts` localiza el bundle con una ruta de disco resuelta desde el módulo en vez del idioma `new URL(…, import.meta.url)`, que el entorno jsdom de Vitest reescribe a `self.location`. Medido por el adversarial con un build REAL de Vite 7.3.1: neutro en producción (build SSR suelto y con disposición tipo Kit: las dos formas se comportan igual), funciona en dev SSR, y solo la nueva funciona bajo Vitest jsdom. El barrel exporta la clase de error junto a las otras seis. Verificación: suite de `boot` + `test` 5 ficheros / 29 tests → 6 / 52 · check con 0 errores bajo src/ (89 en web/, ledger intacto) · docs:check 0/0 · suite entera 459 ficheros / 5389 tests, exit 0. Mutaciones del constructor, cada una restaurada byte a byte: `pins` fuera del reenvío 4 rojos (2 de ellos en la suite de delta: prueba de que ya pasa por el camino real) · sin escape de `<` 2 · sin envoltorio 1 · sin validación 10 · ejecutor vuelto a eval 1 · gramática sin `^` 6 · `storageKey` sin reenviar 2. Adversarial Opus independiente (árbol intacto al terminar): gramática = el ABNF exacto, 0 discrepancias en ~600 000 entradas contra un oráculo propio; suite sin dependencia de orden en 7 semillas; 3 defectos del lote cerrados en una segunda ronda — la frase absoluta sobre CSP en cuatro sitios, y dos mutaciones que sobrevivían (clave en minúsculas; regex con flag `g` según el orden), re-ejecutadas después por el coordinador: rojo en orden por defecto y con las semillas 42 y 777. Filas PREEXISTENTES que destapó el adversarial, no tocadas aquí (van al handoff para el autor): en cualquier build de servidor empaquetado `renderUixBootScript` lanza ENOENT al leer el bundle; la receta de la guía pasa `event.locals.nonce`, que Kit nunca rellena (el navegador bloquea y vuelve el flash, sin error); y el `html.replace` con cadena interpreta `$'` y puede cerrar el script. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
3 weeks ago |
|
|
ecfa8b616d |
chore(lint): el boot compilado entra en .prettierignore junto a eidos/generated
`src/uix/active-uix/generated/boot.js` es un artefacto: lo emite `scripts/generate-boot.ts` con esbuild (cabecera «GENERATED — do not edit», minificado, @ts-nocheck) y `generated-boot.test.ts` exige que coincida con una compilación fresca. Prettier no lo ignoraba: `prettier --check` fallaba sobre él (medido, exit 1), y un `npm run format` lo habría reescrito contra su generador, rompiendo la sincronía que su propio test vigila. Es la misma clase que `src/uix/eidos/generated/`, que ya estaba bajo «# Generated artifacts». Verificado con `prettier --file-info`: boot.js pasa de ignored false a true; la fuente `boot/boot.ts` sigue sin ignorar; eidos/generated sigue ignorado. El generador no usa prettier y nada lee `.prettierignore`, así que la salida no cambia (el artefacto queda sin diff). `lint` sigue fuera del gate por la deuda de formato preexistente, cuyo one-shot espera decisión del autor: esta línea es el requisito previo para devolverlo sin que el artefacto lo enrojezca. Fila nombrada del handoff CONTINUE-audit-p0.md marcada como hecha. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
3 weeks ago |
|
|
11307a85b3 |
docs(process): handoff — D-full + sema 3.9 ejecutados 035a74845; 3.9 CERRADA en la cola de sema; bloque PRIMERO con cifras (Escape→estado 258→9 ms), filas que deja y la pendiente del autor (pintura del cierre)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
3 weeks ago |
|
|
035a748450 |
feat(sema)!: la señal precede al commit — emit() devuelve {id, settled} síncrono, el hold no bloquea a nadie, y el motor enacta la reducción 'state' (D-full + sema §3.9)
D-full. `EngineSemantic.emit(signal)` deja de ser `Promise<string>` que resolvía
tras el hold y pasa a devolver SÍNCRONAMENTE `EmitHandle { id, settled }`: el id
se acuña sin await, la proyección sigue siendo síncrona en `replace`, y `settled`
cubre cola + proyección + despacho + hold + expresión + limpieza (la limpieza
ocurre ANTES de resolver). El runtime de soma, en `pre`/`coincident`, proyecta y
despacha ANTES del handler en el mismo tick (ya no espera el hold); en `post`,
handler → tick() → emit. `TriggerResult.settled` siempre presente. La a11y del
runtime (announce / foco) corre tras el despacho, no tras el hold. El modelo es
el de la plataforma (`element.animate()` → `Animation.finished`): el estado
cambia en el instante de la acción y la expresión corre en su propio reloj sobre
un nodo que retiene Presence. `pre`/`post`/`coincident` describen el ORDEN entre
proyección y mutación, nunca una espera; `coincident` pasa a ser literalmente lo
que declara.
Medido en Chrome real (servidor propio, misma sonda antes/después; Escape →
`data-state=closed`): dialog 258.6 → 9.1 ms · drawer 286.6 → 9.1 ·
popover 1757.8 → 8.5 · float-panel 1807.8 → 49.7 (n=1, pane oculto). Toggle con
`regime: 'queue'` conserva su forma (contact 20 · estado 28 · commit encolado 156). En los
cuatro el sello `emerge-close` se proyecta ANTES del cambio de estado y
`data-ending-style` aparece (Presence). El «hasta 1,5 s» del informe de auditoría
era real: el tope de `awaitExpression` se pagaba ante cualquier animación viva en
el target (popover, float-panel).
Condición 1 (censo, fase 0): 260 eventos; 39 `pre` + 21 `coincident` (0 sin
`sequence`). Solo 14 tienen handler registrado (los únicos donde D-full adelanta
la mutación; cifra del adversarial, el constructor contó 12); los otros 46 ya mutaban el estado en el mismo tick que un `void
trigger` (sidebar.css:363-375 y tooltip-provider:272 lo tenían escrito con
medición). Los 6 que desmontan (4 overlays + toast + tooltip) tienen Presence.
CERO migraciones necesarias. La regla transversal `[data-event^='emerge-close']
{ animation: dismiss-fade }` (base.css) existe en LETRA sobre los cuatro overlays,
pero el preset de Presence gana la cascada en todo instante (medido con
getComputedStyle): el refutador tenía razón en EFECTO.
Condición 2 (carrera nueva del id síncrono): `clear(id)` / `clearTarget` honran
ocurrencias EN VUELO (`inFlight` + `pendingClears`): la ocurrencia no se registra
como persistente al terminar y limpia como transitoria; `clear` devuelve true.
Reproducida en test (hold corriendo ⇒ tras `settled`, sin proyección residual y
`active` vacío). `dispose()` vacía ambas.
SO4 re-firmado: un target ausente NUNCA salta el handler ni lanza en ninguna
secuencia — se omite prewrite+emit, se reporta por logger con
`SomaRuntimeTargetError` como payload, y el handler corre («sema es ornamental;
una acción del usuario nunca se pierde por un adorno»).
sema §3.9. La política perceptual `'state'` bajo reduce pasa al MOTOR:
`ReducedMotionFallback` vive en sema (morfo lo importa), la señal lleva
`a11y.reducedMotionFallback` (cualquier valor declarado) y el motor, con
`motion.get() === 'reduce'` y `'state'`, devuelve el mismo retorno silenciado que
`channels: []` (antes de `queue`). Soma deja de forzar `channels: []`
(`a11yChannelsOverride` muere) y conserva `'text'`/`'focus'` con `sources.motion`.
S5 se conserva como doctrina (la preferencia gana al morfo y a la llamada); cambia
el enactor. Cierra el emit DIRECTO sin a11y (~76 en el docs site). Dato: hoy
ningún morfo declara `'state'` (9 declaran `'text'`); el valor es contrato y
simetría con la háptica, no un síntoma vivo.
Prosa re-firmada (CANON intacto, silente a propósito): engine.ts docblock ·
sema.md (emit contract, promise semantics, lifecycle, One door, overlays, error
policy, reductions, migration) · morfo.md · active-architecture.md (walkthrough)
· overview.md · soma-architecture.md · chans/types.ts req. 3 · sema/README ·
book-deviations D.9/D.10/D.12 · morfo/types.ts (MorfoEventSequence,
MorfoA11ySemantic) · comentarios del `sequence: 'post'` en dialog/drawer/popover/
float-panel (valor intacto).
Verificación (tras la ronda 2): sema 337/337 · runtime 63/63 · alcance del lote
201 ficheros / 2136 tests · suite entera 5366/5366 (458 ficheros, exit 0) · check 89 errores,
0 en src/, ledger intacto (los ~76 emit de web/routes son fire-and-forget y
compilan con el handle) · gate VERDE tras la ronda 1 (5359/5359; un flake de
gesture.test rotate-detent bajo carga, verde en solitario y dentro del gate) ·
+20 tests (engine 40→53, runtime 56→63) · 3 mutaciones enrojecen y revertidas
byte-idénticas (⚠ diferir la limpieza UN microtask es un no-op observable: la
mutación honesta cruza a macrotask) · adversarial Opus independiente (métodos
propios, árbol byte-idéntico al terminar): doctrina SANA; 8 defectos, cerrados
antes de anclar los 6 que eran del lote — D-1 código (el catch de `settled`
vivía en la rama onFulfilled del trigger: un handler que lanzaba en `pre` dejaba
la rechazada del canal visual sin manejar; ahora se engancha donde nace el
handle, con test de las tres vías) · D-2/D-3 prosa · D-4/D-5 tests (los cuatro
valores del fallback, y el par S5 vuelve a discriminar) · D-8 exactitud
(`clear`/`clearTarget` no honran ni cuentan transitorias en vuelo). Segunda
sonda de Chrome del adversarial: 11.6 · 11.0 · 5.1 · 42.7 ms. D-6 (alcance):
`contracts.test.ts` restaurado a HEAD (su diff era 100 % formateo); el
reformateo prettier de los docs tocados se queda. D-7 PREEXISTENTE, fila
nombrada: `dispose()` durante una ocurrencia en vuelo repuebla `active`
después y deja proyección residual (engine.ts, `finally` + `dispose`).
Pendiente del autor: mirar el cierre de Dialog y Toast en un Chrome que PINTE
(los panes de los agentes estaban ocultos: mutaciones y estilo computado
medidos, frame no visto).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
3 weeks ago |
|
|
d7bfabca8c |
docs(process): handoff — PRIMERO MAÑANA: sema 3.9 + D-full, filas nombradas y decisiones; P2 #5 cerrado y pusheado; routes descongelados se quedan (opcion 2)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
3 weeks ago |
|
|
165c5b33b6 |
docs(process): handoff — P2 #5-D ejecutado 2ed9c5493 (/blocks habla prefs); la puerta honesta de hidratacion de /blocks pasa a data-density/data-mode de html
Actualiza el bloque PRIMERO de CONTINUE-audit-p0.md (D ejecutado y verificado en Chrome, queda solo alpha, TERMINATED; asimetria de tipo de prefs.intent nombrada) y anade a CONTINUE-blocks.md la nota fechada: style#uix-blocks-display ya no existe, la preview nace con intent desde la URL y storage:false, y la precision del adversarial D sobre la migracion del blob (mismo precedente firmado que uix-docs-theme). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
3 weeks ago |
|
|
13293fe500 |
docs(process): handoff — P2 #5 ejecutado 6e0decb9e (A CSS sin media · B fuente de motion + soma · C ejes visuales siempre en prefs, cazado por el autor); fila 3.9 abierta en la cola de sema
Reescribe el bloque PRIMERO de CONTINUE-audit-p0.md como spec cerrada de P2 #5 (tres lotes + adenda soma, cuatro adversariales, verificacion en Chrome del docs site en oscuro), con nueve filas nombradas no ejecutadas (theming-sentinel, escena en montaje, WeakMap por dom, tres duenos de data-motion, idioma x5, casteo de harnesses, hueco del boot con esquema propio, (B) de blocks, SSR light) y las lecciones del dia. Actualiza la fila 5 de «Que queda» y la cabecera del brief de #5 (crónica). Abre la fila 3.9 en CONTINUE-sema-audit.md: la politica perceptual de reduce pasa al MOTOR (decision (b) del autor), junto a D-full. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
3 weeks ago |
|
|
6e0decb9ed |
feat(motion)!: una fuente de motion, y los cuatro ejes visuales SIEMPRE en prefs — eidos no lee medios, nadie en el árbol uix pregunta al SO, ningún esquema del app deja a eidos sin motor (P2 #5)
La preferencia efectiva de motion la decide prefs UNA vez (`resolveMotion`: la
intención `allow|reduce` gana al hint del SO, `system` deriva) y la proyección la
estampa en `<html data-motion>` — desde
|
3 weeks ago |
|
|
c482fc7a28 |
docs(process): handoff — (c') ejecutada f875f60b9, adversarial SANO, gate verde; queda #5, esbuild devDep y .prettierignore de generated/
Reescribe el bloque «PRIMERO» de CONTINUE-audit-p0.md como spec cerrada de (c') (pines · sources por eje fuera · sin throw · visual-preference.ts compartida · delta cero x5 · guard revocado retirado · ledger +22), con las dos decisiones del constructor (D1 dos parámetros, D2 pines en el envoltorio), las cifras del adversarial independiente y sus tres observaciones (standalone clavado ahora suscrito; .prettierignore sin generated/ desde e3c0899dd; render.ts sin test). Actualiza la fila 5 de «Qué queda». Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
4 weeks ago |
|
|
f875f60b97 |
feat(eidos)!: un escalar es una instancia CLAVADA — mueren el throw de la puerta 2 y las fuentes por eje (c')
Cierra el estado INTERINO de
|
4 weeks ago |
|
|
9c465a8445 |
docs(process): handoff — e3c0899dd es interino, (c') firmada para manana y el brief de #5
CONTINUE-audit-p0.md: bloque «PRIMERO MAÑANA» (el throw uix+escalar rompe todas las demos; forma firmada (c'): pines si, sources reactivas fuera, sin throw, pines en el boot; orden del dia con el adversarial cortado que hay que relanzar entero, el guard de contracts.test que codifica la doctrina revocada, y la decision de esbuild como devDependency), el acta de P2 #2 en el cuerpo y el brief completo de #5 al final. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
4 weeks ago |
|
|
e3c0899dd8 |
feat(prefs)!: un motor, un sobre, un codigo — mode/theme/density/scaling son prefs, sobre canonico y boot compilado
Auditoria P2 #2: los attrs de preferencias se estampaban solo en cliente tras hidratar (app.html sin script, build estatico sin servidor) — flash claro para todo usuario dark — y no podia existir un script de arranque porque no habia contrato de persistencia (PrefsIntentStorage lo aporta cada app) y eidos llevaba un SEGUNDO motor de preferencias (theme / modeSource / densitySource / scalingSource por opciones, sin persistir), por doctrina escrita en arts/prefs/README.md («UIX does not turn it into prefs.theme»). El autor REVOCA esa doctrina. UN MOTOR. `mode` es una dimension de prefs junto a `motion` (mismo patron, `resolveTheme` de $libs/theme, que ya existia como gemelo de `resolveMotion`); `theme` (id de familia), `density` y `scaling` las declara la RAIZ en un modulo PURO (src/uix/active-uix/prefs-schema.ts) — arts/prefs no importa src/uix. Eidos lee `uix.prefs` por su puerto `ActiveEidosPreferenceSource` (src/uix/eidos/prefs-source.ts), como ya consume uix.langs / uix.dom / uix.motion. El resolver de tema baja a una funcion pura `resolveThemeId(theme, mode, isRegistered)` (src/uix/eidos/lib/theme-id.ts); los cuatro nombres de attr de eidos a src/uix/eidos/lib/attrs.ts y los de la proyeccion a src/arts/prefs/dom-attrs.ts: modulos sin Svelte, porque el boot los comparte. UN SOBRE. src/libs/prefs/document.ts: `uix.prefs-intent` v1 bajo la clave `uix.prefs`, espejo del documento de eidos (kind + version estrictos, version desconocida se RECHAZA). Solo intencion — nunca efectivo ni entorno. Adaptador localStorage canonico creado en la raiz standalone (`prefs.storage`: propio gana, `false` desactiva). HIDRATACION SINCRONA: el bridge awaitea `load()` aunque sea sincrono y produciria una primera resolucion con defaults y un salto un tick despues — el flash movido de sitio; la raiz lee el sobre ANTES de crear el motor y lo pasa como `intent`; el bridge queda solo para persistir (skipHydrate). UN CODIGO. El boot no se escribe: se COMPILA con esbuild desde los mismos modulos puros (src/uix/active-uix/boot/boot.ts → generated/boot.js, 15.009 bytes / 5.625 gzip, IIFE sin globales, cero Svelte; test de sincronia, precedente generated/base.css). `renderUixBootScript(params)` (boot/render.ts) es Kit-agnostico: el framework entrega el string; el hook de Kit son tres lineas de la app (receta en docs/theming/guide.md, NO cableada: el layout congelado lleva persistencia propia). Estampa los NUEVE attrs (dir lang data-motion data-sound data-haptic data-theme data-mode data-density data-scaling) → DELTA CERO al hidratar, probado por integracion con la raiz REAL (boot/boot-delta.test.ts, tres casos) y por tres mutaciones (sin hidratacion sincrona → rojo; constante de attr cambiada en un solo lado → rojo; boot compilado con `data-modo` → los tres casos rojos). Hallazgo del test de delta cero: la raiz no aplicaba el entorno del navegador (esperaba que el app llamara detectBrowserEnvironment en onMount) — ahora lo siembra ella (guardado por `document`) y observa sus cambios (watchBrowserEnvironment → patchEnvironment), sustituyendo el listener que eidos tenia en createSystemColorSchemeSource. Cifras: vitest prefs+libs/prefs+active-uix+eidos+value-channels 57/593 · suite completa 453/5306 · check 73 (src/ a cero; ledger intacto) · check:gate OK · eidos:lint 0 · docs:check 0/0 · morfo:vocabulary, arts/blocks/packs/rtl/translations/agent:check OK. ESTADO INTERINO, firmado para manana (acta en CONTINUE-audit-p0.md): `resolvePreferences` LANZA con `uix` + escalar/source (forma firmada originalmente); medido despues, `ActiveEidos.create()` inyecta `uix` SIEMPRE y todas las demos pasan escalares o sources (>=12 sitios, incluido web/routes/uix/+layout@.svelte:511) → el sitio de demos lanza al arrancar hasta la forma (c'): pines si (escalar explicito gana, precedente `options.dom ?? options.uix?.dom`), sources reactivas por eje FUERA, sin throw, pines en el boot. Pendientes anotados: contracts.test.ts:1270-1276 codifica la doctrina revocada; esbuild no es dependencia declarada (transitiva de vite) — decision del autor con servidores parados. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
4 weeks ago |
|
|
3fba26e235 |
docs(process): la costura de la apariencia queda cerrada — e2c37f892, con lo que enseño
CONTINUE-audit-p0.md: la costura pasa de «a firma» a CERRADA con la forma
ejecutada, las cifras del adversarial (LOTE SANO EN CODIGO, 5 defectos de
docs/informe corregidos antes de commitear), las tres latentes anotadas
(el ledger enmascara la deuda de appearance en dos ficheros de rutas; la
render cruda sobre config no validada; el donante resuelto dos veces) y
dos lecciones: routes es provisional y NO puede condicionar el diseño (mi
(a) inicial rebajaba el campo a opcional por no tocar routes), y un agente
cortado a mitad de una mutacion se revisa entero antes de reanudarlo.
CONTINUE-theming.md, bloque «LO PRIMERO»: desde
|
4 weeks ago |
|
|
e2c37f8920 |
feat(eidos)!: un tema DICE lo que es — appearance obligatorio en ThemeDefinition, una sola fuente de verdad
|
4 weeks ago |
|
|
6505a0e095 |
docs(process): P2 eidos ejecutado — tres lotes, cuatro defectos del adversarial y la costura que va a firma
CONTINUE-audit-p0.md registra los hashes ( |
4 weeks ago |
|
|
bd7b9ba3ef |
docs(process): fila 15 — axe-core no es «instalar o no», es CUÁNDO
Deliberacion a tres bandas. La instalacion se RETIRO antes de tocar el lock: meterla en una ventana de coordinacion habria BLANQUEADO una decision que espera firma — el hecho consumado disfrazado de logistica. La objecion «viola la dependencia cero» quedo retirada al medir (2 dependencias embarcadas, 23 de andamio: la regla gobierna lo que se embarca). Y el argumento que decide es el TIMING: axe mide el DOM MONTADO, que vive en el arbol congelado que se reconstruye, y sin conduccion de estados solo veria el REPOSO — daria verde sobre lo que nadie ha mirado, y ese verde se cita como evidencia. Forma recomendada de la firma: «si, pero no ahora», con condicion de entrada escrita. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
1 month ago |
|
|
4040bacc67 |
docs(process): P2 arrancado y tres leyes de coordinacion que costaron sangre ajena
La regla de las dos manos NO escala a tres (hoy dos carriles tocaron el mismo fichero con un commit de diferencia y se salvaron por zonas disjuntas, no por protocolo) · el acoplamiento puede ser por DERIVACION y no por fichero (un guard que deriva su vocabulario restando el contrato a lo que emite el generador enrojece si cambias QUE emite o EN QUE ORDEN, aunque no escribas un nombre nuevo) · y la ley del «se anduvo»: al declarar que algo se emite UNA vez, asertar tambien que cada raiz declarada resolvio a ficheros — un contador a cero se lee igual de verde estando roto, que es la familia del continue mudo de nuestro propio morfo-check. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
1 month ago |
|
|
f1f686d097 |
feat(theming)!: SS16 - el guard vive donde NACE el valor, y el velo del drawer vuelve a pintar
Firma SS16, quinta aplicacion de la doctrina "la capa sostiene la pluma, no es
la dueña". El censo, el ledger y la ley del espacio cerrado auditaban SOLO
quien LEE (recetas de eidos); quien ESCRIBE la custom property por instancia
vive en soma/arts y ningun instrumento del eje lo habia enumerado jamas.
EL BUG VIVO QUE ESTO DESTAPO — y no se parcheo, se diagnostico
--drawer-overlay-opacity era DOS especies bajo un nombre: el knob de tema (el
contrato dice 62%) y el canal del arrastre (0..1). soma escribia el canal SIN
UNIDAD sobre el nombre del knob; color-mix() exige porcentaje, la funcion caia
invalida y el velo computaba rgba(0,0,0,0): NO PINTABA. Y el inline dejaba el
knob inalcanzable para cualquier tema. Se separan: el publico se queda como
knob (nadie lo escribe en runtime), el arrastre pasa a
--_drawer-overlay-progress (sin unidad, que para un multiplicador es lo
correcto) y la receta los COMPONE - calc(knob * progress) -, asi que el
arrastre ATENUA el tema en vez de destruirlo.
Medido en Chrome: reposo 0.408471 (antes rgba 0,0,0,0) - el tema LLEGA (20%
-> 0.1318, 62% -> 0.4085, 100% -> 0.6588; antes ninguno movia nada) - el
arrastre sigue (Escape real -> alpha 0; 0/0.25/0.5/1 lineal) - control
negativo: reinyectando la escritura vieja el velo vuelve a caer, o sea que la
unidad era el SINTOMA y las dos especies la enfermedad.
⚠ Estaba adjudicado EN PROSA en theming-sentinel-exceptions.ts:815 desde hacia
dias: la excepcion se trago el bug.
LOS 18 NOMBRES A SU SITIO
Clase B (11 en command/dialog/scroll-area/toast + 4 del drawer): forma publica
sin contrato y sin UN SOLO lector en el repo - una API publicada que el
framework no consume. A --_{c}-*, y los README de soma dejan de enseñarlos
como API del consumidor: ahora enseñan LA PARTE, con la formulacion verbatim
que SS15 ya habia verificado. Clase D (tree-view, gradient-picker): tenian
lector, verificados en navegador. --scrollbar-width NO se renombro por
inercia: es una escritura sobre el unico <body>, la doctrina no le llega, y
queda REGISTRADA con su razon en vez de inventarle un dueño.
LA AGUJA - src/uix/value-channels.test.ts (fichero propio, 6 tests)
Vitest y no script, porque el gate termina en la suite y eso es lo que
convierte la doctrina en ley. Deriva el vocabulario de sistema RESTANDO el
contrato a lo que emite el generador (lista derivada, nunca a mano). Barre
NUEVE raices - las siete nuevas verificadas a cero ANTES de asertarlas - y el
quinto test asserta que cada raiz declarada se anduvo de verdad: una raiz que
resuelve a cero ficheros es la puerta que nadie habria visto.
Dos correcciones al dimensionado, por medida: el arbol tiene SEIS formas de
escribir, no cuatro, y una de las que faltaban era LA CANONICA (la
--_${component}-... que SS14 y SS15 firmaron) - un guard ciego a ella habria
dado verde sobre su propio destino. Y un barrido mas ancho marcaba en rojo un
anchor-name, que en gramatica es identico a un nombre de propiedad: probado y
REVERTIDO. El instrumento miente primero.
Mutaciones: cinco, con el arbol byte a byte identico. Incluyen las dos que
prueban lo que las correcciones añaden (una clave _ DEL contrato pasa de verde
a rojo; un --_ legitimo en blocks pasa de rojo a verde).
LO QUE EL ADVERSARIAL CORRIGIO DE MI PROPIA LEY
Dictamen: "es LEY sobre la mitad que barre, y sigue siendo PROSA sobre el
absoluto que enuncia". Cierto: decia "toda escritura por instancia" y la aguja
no mira eidos, donde viven ONCE escrituras de nombres contratados. Corregido -
el enunciado nombra sus nueve raices y DECLARA sus dos fronteras (eidos, con
su expediente abierto; web/routes, congelado); las salidas son CUATRO y no
tres (la cuarta, sistema, es verde); y el registro se queda con cuatro campos
por entrada (since, reason, destination, heldBecause) con un test que exige
los cuatro - la diferencia entre un registro y un cajon.
Y la relectura con ojo de abogado encontro DOS absolutos mas, en direccion
contraria, escritos bajo "WHAT THE GUARD DOES NOT CHECK": "por instancia" no
es decidible estaticamente (el antecedente del guard es MAS ANCHO que el de la
doctrina), y el {c} de --_{c}-* no lo comprueba nadie, solo el guion bajo.
SS18 ABIERTO, y es la respuesta medida a "¿puede volver a nacer un nombre sin
dueño sin que nadie se entere?": SI, desde eidos. 11 contratadas + 18 sin
dueño, partidas en dos especies (la fundacion generando su vocabulario, que es
legitima, y las props ergonomicas del consumidor, que no es lo mismo).
dialog-overlay-opacity es el GEMELO EXACTO del velo del drawer y sigue vivo.
No es "añadir el root": distinguir las dos especies EXIGE FIRMA.
Guards: value-channels 6/6 - recipe-css-contract + reach-floor + generated-css
55/55 - docs:check 0/0 sobre 819 - --debt 1148/0/0 - tsc 0 propios - prettier
limpio.
BREAKING: los 18 nombres publicos ya no existen; el canal se lee --_{c}-* y
sigue sin ser de nadie para fijarlo. Y consumir un --{c}-* del contrato desde
un provider es ROJO desde hoy.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
1 month ago |
|
|
839f79eeb7 |
docs(theming): el registro dice la verdad de hoy - y los DOS expedientes que faltaban existen
El handoff describia un arbol de hace horas y apuntaba a dos expedientes que
NO EXISTIAN, justo en los dos items que declaraba prioritarios: el instrumento
era el propio handoff. Reparado, con su adversarial detras.
LOS DOS EXPEDIENTES, escritos con el dimensionado medido (aguja propia sobre
2014 ficheros de soma+arts):
- next-features SS16 - A-1 "el guard vive donde NACE el valor": el censo, el
ledger y la ley del espacio cerrado leen SOLO recetas de eidos; quien
ESCRIBE la custom property por instancia vive en soma/arts y nadie lo
enumero jamas. 49 nombres en 76 escrituras: 1 token que MIENTE, 15 de forma
publica sin contrato y con CERO lectores en todo el repo (API publicada que
el framework no consume), 3 sin dueño, 30 ya --_*. Quince README de soma
llevan "## CSS Variables": cinco publican los crudos y OTROS CINCO publican
--_{host}-floating-* diciendo "esto es interno" - la misma casa hace las dos
cosas, es el acta de una migracion a medias. Es la aplicacion al eje de la
ley que HEAD
|
1 month ago |
|
|
05dcb4db79 |
docs(process): LEY — web/routes congelado, y la consecuencia: el guard vive donde NACE el valor
El arbol de rutas se reconstruira, asi que escribir ahi es trabajo que se tira. Leerlo como evidencia sigue valiendo. La consecuencia mayor no es de alcance sino de METODO: morfo-check, permutation-check y component-audit validan NAVEGANDO a web/routes/uix/components/<kebab>/+page.svelte, de modo que el 161/161 que este handoff cita mide un arbol que se va — no es evidencia sobre el contrato. Lo construido en src/ sobrevive; lo apoyado en la ruta, no. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
1 month ago |
|
|
22278ee7d4 |
docs(process): P1 CERRADO — kinds de foco, server-only y el gate en 5239 verde
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
1 month ago |
|
|
35d0005de4 |
docs(focus): las seis especies se RENDERIZAN, y añadir una séptima romperá al compilar
- FocusPolicyTable ensancha de 2 a 6 especies, cada una con las columnas que
su forma tiene y una frase que dice qué SIGNIFICA para quien lee la demo
(el lector de esa pestaña quiere saber cómo se comporta el foco, no ver el
tipo). De paso muere el `{:else}` desnudo que renderizaba la tabla de
roving para CUALQUIER kind — el mismo bug que, al ensanchar la unión, dio
6 errores de tipo.
- Cableada en las 9 páginas declarantes (las 2 que el lote no alcanzó —
command y combobox — cableadas aquí con el patrón de la casa).
- morfo.md: la fila de runtime nombra las SEIS especies con su ejecutor, y la
convergencia queda escrita como doctrina: la declaración de foco nombra la
ESPECIE y el primitivo de teclado la EJECUTA.
EL `<h4>` HUÉRFANO, cerrado por el TIPO y no por una rama muerta (hallazgo
del adversarial): el encabezado vive fuera de la cadena de ramas, así que una
séptima especie sin rama imprimiría un título con nada debajo. Un fallback en
runtime NO puede expresar eso — TypeScript demuestra que la cadena es
exhaustiva HOY y la rama sería código muerto (medido: `Property 'kind' does
not exist on type 'never'`). En su lugar queda una prueba EN EL TIPO: añadir
un kind deja de compilar. Es la ley de la casa — lo que se añade rompe al
compilar, no deriva.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
1 month ago |
|
|
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 |
|
|
482bb5cd94 |
docs(process): la bolsa de 12 ejecutada — 8 lotes anclados, gate 5224 verde, y la fila 13 que nació de la 7
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
1 month ago |
|
|
7e23fe53be |
docs(process): C+ COMPLETO Y VERIFICADO — gate 5207 verde, morfo-check 161/161 con el gate ARIA dentro
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
1 month ago |
|
|
0da97636bd |
docs(morfo): la fila keyboard dice la arquitectura C+ — declaración única, ejecución por especies, dispatcher como conveniencia de hoja
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
1 month ago |
|
|
39f7dd1ed3 |
docs(process): C+ tanda de especies completa (4 primitivos, 4 commits) — bolsa de decisiones de autor consolidada
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
1 month ago |
|
|
9cca75a3ef |
docs(process): fila cero CERRADA (4 commits, cosecha a CERO, pase ARIA gatea) — cola descongelada, C+ arranca
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
1 month ago |
|
|
3fa4b7954f |
docs(process): hotfix f48acab37 + dossier unificado COMPLETO y presentado — ley de wave en cabecera
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
1 month ago |
|
|
c8db4c8d64 |
docs(process): gobernanza unificada confirmada por el autor — wave 1 anclado, cola en pausa hasta el dossier
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
1 month ago |
|
|
d1e955eef7 |
feat(soma)!: la GRIETA cierra — states/parts rompen en el tipo y el censo de fuentes vigila el resto
Firma C del autor (2026-08-27), ciclo completo con agentes Opus ultra
(expediente + C1 censo + C2 tipos + adversarial + C1-fix), sesion
coordinando y supervisando.
LAS DOS MITADES. (1) TIPOS: StateNameOf<M> desde part.states[] (terminador
de profundidad con su consecuencia escrita; degrada a string sobre el Morfo
ancho, jamas colapsa a never) y PartKebabOf<M>, estrictos en nivel
componente y nivel parte, con la clausula [Names] extends [never] ? never
(molde de dir?: never) — que cazo en compilacion un QUINTO defecto que
ningun censo podia contar: knob registraba states:{} sobre un morfo sin
estados. props queda SourceMap CON ACTA en el propio tipo (v.propRef tira
el literal; generificar arrastra 3 builders en fichero de otro eje) y un
type-test con 4 @ts-expect-error como guard permanente — el negativo de A1
reproducido en compilacion. (2) CENSO source-census.test.ts: 2 GATES
(huerfana nueva - fuente muerta per-parte nueva) + 78 filas advisory
c1a/c1b/c2 nominales para adjudicacion del autor + excepciones-vivas +
negativos PROBADOS en rojo.
Defectos REALES retirados (cada uno verificado sin regresion en navegador
real por el adversarial): button states.loading (error de CUBO — el morfo
lee loading como PROP; vivia de la duplicacion; data-loading intacto,
SSR incluido por curl) - tabs states.value y radio-group states.value
(huerfanos: nada los consumia) - media-player rate-button props.label
(fuente muerta con comentario falso; el aria-label resuelve por
translationRef) - knob states:{}.
Adversarial: 5 CONFIRMADOS + 2 parciales. El material: el descubrimiento
del censo ignoraba los .part() con parte por VARIABLE (9 sitios, no los 5
que el propio adversarial conto) => >=4 filas falsas en advisory y un
unreadable=0 que mentia. C1-fix con CONVERGENCIA contra el censo
independiente del adversarial: keys 729==729, props 602==602, orphans
20==20 fila a fila; el delta restante 100% definicional nombrado; las
filas alimentadas por spreads opacos se estampan UNCERTAIN en vez de
afirmarse. Mordidas verificadas con plantado y restauracion por sha256
(typo nuevo => check lo nombra con linea exacta; check en los 71 de linea
base EXACTOS, todos en web/).
TRES COMPROMISOS vigentes (acta en el tipo y en next-features):
(i) generificacion de stateRef/propRef/mapRef como eje propio al liberarse
types.ts — cierra props (594/729); (ii) flip del censo a gate BIDIRECCIONAL
cuando el autor adjudique las 78 filas (el tooltip deshabilitado mudo esta
ahi); (iii) wave c1b->bolsa (36 escrituras manuales) bajo la ley de
unica-tuberia de P0. Deudas nombradas: keyboard[]-deps invisibles a
CompiledPart.deps (poblacion CRECIENTE, dato vicen-42; el censo las une por
AST con retirada fechada; secuenciar con el dueño de compile.ts) -
StateNameOf en runtime (casa natural morfo/selectors.ts) - label del
rate-button huerfano (anotado) - MediaPlayer.RateButton no se renderiza en
ningun sitio del repo (hallazgo lateral).
Convivencia: types/schema/compile/resolver INTACTOS (wave ARIA del peer
aterrizado antes,
|
1 month ago |
|
|
b54bb3ad0c |
docs(process): las 3 decisiones de arquitectura FIRMADAS por el autor — cola de waves fijada
1/3 keyboard C+: declaración = contrato único; ejecución converge en PRIMITIVOS POR ESPECIE (grid-walk, segment-walk, highlight-typeahead, value-step) + actions por registración. 2/3 server-only: *.server.ts nativo en la PUERTA de cada motor svrs, alias absorbe el rename, censo como segunda capa, ley del tier. 3/3 foco: la unión gana walk / activedescendant / slider / segments — la taxonomía de foco CALCA la de los primitivos C+ (dos contratos, una taxonomía). Premisa que rige las tres: «lo mejor para la arquitectura, coherencia y diseño INDEPENDIENTEMENTE de lo que cueste». Cola: cosecha ARIA → C+ → kinds → server-only, cada wave sobre árbol asentado. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
1 month ago |
|
|
f00d1fc10e |
docs(process): P1 — cosecha ARIA advisory FIRMADA: 258 hallazgos en 32 morfos, byte-idéntica entre pasadas
161/161 PASS en caliente (los 2 fríos = clase documentada). Dossier de 5 clases en el handoff; chronos concentra 120/258 (roledescription ×59 + dropeffect deprecado ×42). El wave de adjudicación es el siguiente ejecutable y ESPERA al C2 de vicen-e1 (orden por canal); el flip del pase a gate va al final de ese wave. 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 |
|
|
b549cfee59 |
docs(theming): el hash del cableado motion en el handoff - e16c14dec
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
1 month ago |
|
|
e16c14dec7 |
feat(eidos): el ritmo de revelado sube a config — primitives.motion.staggerViewport, y su regla emigra a la foundation
Firma opción 1 del autor (cableado EidosConfig.motion → CSS, la última entrada de PENDING_PRIVATE_RENAME). Ejecutada con el esquema completo: expediente + dos constructores en serie + adversarial, todos Opus en ultra, coordinación y supervisión de la sesión. El gancho --motion-stagger-each-default era FICCIÓN: nadie lo declaraba y su único consumo (motion.css:42) resolvía siempre al literal 70ms. Ahora: primitives.motion.staggerViewport: '70ms' (tipo + default + validación + contrato + emisión --motion-stagger-viewport en :root, molde floating-gap verbatim) y la regla [data-stagger] > [data-animation-trigger='viewport'] EMIGRA a renderMotionBlocks — donde vive la máquina entera del stagger. Con ello motion.css queda en sus dos gates de opacity (su veredicto structural, más verdadero), la entrada del registro cayó STALE POR MECÁNICA y el registro, a cero, se DESMONTA con acta (un guard que inspecciona el vacío es un falso verde); la historia completa cierra en canon/recipe-contract.md. E14 (70→20ms) queda APLAZADA con nombre: firma de diseño propia, mueve 8 blocks. Adversarial 9/9 CONFIRMADO: neutralidad término a término contra la línea base histórica en Chrome real con el IntersectionObserver disparando (0/0.07/0.14/0.21/0.28/0.35s en /blocks/team/preview) - override 999ms reescribe la cascada - nombre muerto inerte (5s en :root, cero efecto) - <Cascade> intacto con control positivo quirúrgico (solo el hijo estampado toma el token) - cero empates de hoja posibles (tres escritores en .css, especificidad decide) - el guard del espacio cerrado muerde por mutación - 126 tests, censo 73%/66/1152-0-0, docs 0/0. Sus reservas, con acta en changelog §57: el contrato gana DOS filas (--motion-stagger-each entra como (derived) al emitirse — clase preexistente de index/index-rev) - gates divergentes latentes - path del contrato sin pin. Correcciones del adversarial incluidas: dos citas muertas del ledger de blocks anotadas, el presente falso de component-audit.ts, y el absoluto de canon matizado. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
1 month ago |
|
|
ab54a8821b |
docs+fix: correcciones del pase adversarial (3 Opus, refutar) sobre las firmas del dia
Las tres firmas SE SOSTIENEN (A1 7/7 con 4 refutaciones fracasadas; A2 8/8; A3 8/8). Toda refutacion aceptada era de PROSA y cae aqui: fechas 2026-08-27 -> 2026-08-26 en 17 sitios (los commits son del 26; deriva de sesion) - la promesa API-frozen del CONTINUE del floating layer enmendada (los --floating-* salieron de la lista congelada con la firma SS15; era la fuente del claim de vicen-41) - CONTINUE-direction anotado al alias vivo - el absoluto falso de 5 READMEs corregido (un !important de autor SI gana al inline, congelando la geometria - medido por A2) - precision del positivo de combobox (dependiente de viewport; exacto a 1440x620) - paridad ARIA completada (aria-hidden de los dos indicadores) - ficha de radio-group: seis alias, dos regimenes - residuos de prosa del item 2 anotados - fe de erratas precisada (
|
1 month ago |
|
|
0e63de76fd |
docs(process): cierre del eje focus-first en el handoff — morfo-check 161/161 caliente, perm-check 447/454 con los 10 adjudicados ajenos (2 chips lanzados)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
1 month ago |
|
|
b00544be5e |
docs(focus): la política de foco se RENDERIZA — morfo.md/eidos.md corregidos + 27 páginas
- morfo.md: fila runtime de focus reescrita (FocusScope.use({policy}) +
RovingFocusGroup + censo), ejemplo dialog con kind:'trap', paso 5 con las
dos familias comentadas, fila 2-de-3 de focus firmada (executor + censo +
render en docs: guard más fuerte que la clase grandfather).
- eidos.md: fila FALSA «focus.trap = layout hint» retirada (nunca fue
cierto; eidos no lee focus).
- FocusPolicyTable.svelte (web/routes/uix/lib): renderiza morfo.focus —
tabla trap (kind/atrapa-Tab/initial/return/restore) y roving
(kind/parts/eje/loop/ejecutor compartido vs custom firmado).
- Cableada en 27 páginas de demo tras el h2 de Accessibility (25 por
agente + dialog/toolbar de referencia). chronos NO tiene sección
Accessibility en su página: hueco anotado en el handoff, no inventado.
- PLAN-focus-first.md: el plan del eje con sus leyes.
- CONTINUE-audit-p0.md: sección del eje ejecutado.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
1 month ago |
|
|
53810cb5ec |
refactor(eidos): item 2 - los slots de forma de la capa deslizante llevan el _ del alias
Firma (a) del autor: --indicator-duration/-ease eran el ALIAS de la capa (la especie de --_indicator-x, opcionales-con-fallback), no un pomo de tema - la ortografia bare prometia una superficie que la cascada negaba. Flip a --_indicator-{duration,ease} (1 escritor radio-group.css alimentando desde sus claves de CONTRATO segmented-transition-*, 1 lector lib/sliding-indicator.css); reparto de propiedad escrito: la capa posee QUE propiedades deslizan (y su colapso reduced-motion), el anfitrion A QUE VELOCIDAD via contrato. Contrafactico MEDIDO pre-flip: bare en :root a 9s = 0.18s intacto (no se retira superficie); post 4/4: pixel identico, bare inerte y vacio en el pill, contrato alcanza (7s), alias en :root inerte. Comentarios themeable-so-bare reescritos; prosa del sentinel al nombre vivo (clave intacta). Lint 0 invalid, reach-floor 5/5, censo neutro.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
1 month ago |