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 |
|---|---|---|---|
|
|
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 |
|
|
4a1a0c3907 |
refactor(sema): los 3 resolvers de gesto se retiran — esta vez desde el eje, y el registro se hace verdad
El rediseno del 2026-08-06 (gestos por REPETICION, sound:'step' por emision)
los dejo sin llamador, y book-deviations D.7 escribio en pasado un borrado que
nunca ocurrio. Hoy ocurre, firmado y desde una sesion del eje que empezo por
su handoff — la condicion que la retirada revertida de
|
2 months ago |
|
|
2f872ef864 |
feat(sound): $sound orquestador (buses+voces+media) y player v2 F1-F3 sobre el servicio
Rediseno clean-room del sonido (gate D-SR.1-12 firmado; la doctrina "la voz
es del art" de PLAN-sound-engine s16.1 queda revocada):
- Mezcla: master -> buses ui/content (gain/mute/duck refcount, gana la mas
fuerte; politica pre-contexto). prefs de UI jamas tocan la obra.
- Voces registradas: la calibracion es DATO del consumidor (sema registra
'sema'; el default conserva la calibracion historica - cero cambio audible,
A/B del usuario: "suena igual").
- Ciudadania de media: sound.media(el) PROVEE el transporte (la forma exacta
del puerto MediaProvider) + foco mixed/exclusive/duck PERSISTENTE (estado
derivado; el ducker mas reciente retiene la palabra) + duckUiWhileContent +
MediaSession de la fuente activa (play/pause/seekto + posicion, liberacion
y promocion) + visibilidad content-aware + attach() opt-in (irreversible,
CORS declarado). Re-registro idempotente por elemento.
- diagnostics.ts con catalogo tipado (contrato de arts) y guards post-dispose
(ningun camino abre un contexto huerfano). Auditoria AU-1..9 resuelta;
bundle medido: 16,2 KB min / 5,6 KB gz.
Player v2 (gate D-AP2.1-13 firmado) F1-F3:
- F1 gaps de framework: aria-valuetext en Slider (valueText por thumb) +
parte SecondaryRange con token --slider-secondary-bg (buffer/clip/capitulos)
+ formatDuration en $libs/days + fix del selector del pack (H-1: la regla
de play/pause construia sobre provider y el stamp aterriza en play-button).
- F2 morfo: 6 partes audio-only (artwork/artist/identity/transport/
rate-button/live-indicator), commit-set-rate, commit-set-time RETIRADO
(D-AP2.13: el scrubber delega en el commit-set del Slider compuesto),
sustain-loading cableado (H-9), teclado j/l, </> y 0-9 (con guard de
modificadores para no pisar atajos del navegador).
- F3 la migracion: el transporte default es uix.sound.media(el, {metadata})
(pineado con el motor real); nativeMediaProvider RETIRADO (media-provider.ts
queda como contrato puro del puerto, sin shim); G-5: los commits de
play/mute/rate cabalgan el evento de RESULTADO (play/pause saltando el
pause de ended, volumechange con transicion de muted, ratechange);
formatTime -> formatDuration; sub-providers + wrappers + exports de las 6
partes; prop metadata publica (captura al registrar, documentado).
Verificacion: 45 suites / 458 tests verdes en el alcance (sound, sema,
active-uix, active-app, morfo, slider, media-player, days) - check 74 =
baseline de la rama, 0 propios - docs:check 0 - invariante de UN AudioContext
intacta (e2e sin tocar). Planes de proceso y handoff al dia
(PLAN-sound-redesign, PLAN-audio-player-v2, CONTINUE-sound-engine).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2 months ago |
|
|
b48264902f |
docs(process): el gate del reproductor, consolidado — se presenta una vez y no se mueve
La sesión perdió convergencia: tres presentaciones del gate lo movieron tres veces (D-AP.7 corregida dos veces, D-AP.12 → v2, D-AP.13 apareció al final), y de sus commits los últimos corrigieron a los anteriores. Este pase consolida TODO en el cuerpo del plan para que la sesión siguiente firme en frío, sin re-excavar. Consolidación pura: sin código y sin hallazgos nuevos. - **D-AP.7, criterio final: incongruencia, no frecuencia** (D.7: «si el contenido ES audio, un tick de UI compite con la obra»). Con frecuencia como criterio, play/pausa —2 a 10 veces por escucha— quedaría fuera y la línea sería arbitraria. Se cancela el gain de lo que suena MIENTRAS suena la obra; se conserva lo que informa del estado de la obra (`commit-complete`, `commit-fail`), con `commit-complete` anotado como el discutible de los dos. - **D-AP.13, nueva**: `commit-set-time` duplica el `commit-set` del `Slider` embebido (`onValueCommit` → `seek()` → `trigger`, dos líneas leídas; el del Slider, medido en navegador). El rationale de radio-cards aplica literal, y el propio provider ya practica la delegación en `setVolume`. Recomendación: retirar y delegar; el coste va a F2 como cambio de contrato declarado. - **§8.7 — la postura de participación, resuelta**: `expression: 'pack'` es correcta (los eventos de ciclo de vida no los posee ningún hijo, y el guard S11d la exige mientras exista el pack); el player es un híbrido legítimo con UNA duplicación (D-AP.13) y UN defecto de timing (G-5). La premisa de D-AP.1 queda intacta — la pregunta que la última pasada dejó como abismo tenía suelo en la doctrina. - El clip queda condicionado a D-AP.12(b) en §5, F3 y F5, coherente con la recomendación v2; F2 recoge D-AP.13 y la ejecución de H-9. - La cabecera fija la regla de cierre: la cuarta presentación **se firma o se rechaza, no se re-excava** — y el kickoff de sesión nueva lo dice explícito. - El handoff (`CONTINUE-sound-engine.md`) queda en «firmar, sólo firmar», con la trampa que costó la sesión escrita donde las demás: **una medición no es un diagnóstico** — leer el contrato de la pieza (README → CANON §8 → book-deviations → código) antes de acusarla. `docs:check` 0 errores. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
2 months ago |
|
|
061d66299b |
fix(docs): D-AP.7 proponía un mecanismo que viola la regla dura de la cascada
Leyendo `book-deviations.md` D.5/D.7 —que llevo dos días citando sin abrir—
resulta que el mecanismo que propuse para el silencio en modo audio está mal, y
que el correcto ya estaba canonizado en el catálogo.
Proponía `channels: ['haptic']`: tirar el canal sonoro entero bajo
`[data-media-player][data-media='audio']`. Eso **contradice la regla dura que
está en `CLAUDE.md`** — *«Cascade rules add character, never the intent's
evaluative profile… to shift one, compose with `{ op: 'add', value: … }`»* — y
su consecuencia práctica es peor que el problema: borra también la carga
evaluativa, así que un `commit-fail` dejaría de oírse justo cuando hace falta.
El patrón correcto ya existe y está canonizado como D.5: `form.toggle.silent`
(`gain: { op: 'add', value: -0.3 }`) y `tooltip.silent` (-0.2) **restan
exactamente el gain de la familia**, de modo que lo cotidiano cae a 0 y los
deltas de intent siguen aflorando. Su propio comentario lo dice: «avoids fatigue
without erasing evaluative loading».
Aplicado al player, con una precisión que obliga un dato medido: **`risk` no
añade gain** (sólo `threat` +0.1 y `fulfill` +0.05), así que una cancelación
global también silenciaría el fallo de carga, que es `commit-fail + risk`. Por
eso la regla cancela el gain **sólo en los eventos frecuentes del transporte**
—`commit-toggle-play`, `commit-set-time`, `commit-toggle-mute` y el
`contact-activate` de los botones compuestos— y **deja intactos**
`commit-complete` y `commit-fail`, que son ocurrencias, no frecuencia.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2 months ago |
|
|
81378a6875 |
fix(docs): H-10 mal diagnosticado — el canon separa las dos voces, el player las junta
Cerré H-10 hace un commit diciendo que el doble earcon era «el patrón de composición del catálogo» y que la decisión —regla nueva en el árbitro, o canon que declarase el solape intencionado— era materia de `book-deviations.md`. Es al revés: **el canon ya lo prescribe, y quien lo incumple es el media-player.** El README del `Button` lo dice citando el libro (cap. 22 §8 y §10): `contact-activate` es `sequence: 'pre'` y sólo acusa la RECEPCIÓN del gesto; la consecuencia evaluativa la dispara el consumidor **cuando el resultado aterriza** — *«the celebration sound plays at the moment the save actually resolves, not when the click is received»*. Dos sonidos, sí, pero **separados en el tiempo** y con dos significados. En el diseño no hay solape. El solape lo mete el player: `togglePlay()` dispara `commit-toggle-play` síncronamente dentro del handler del clic, no cuando el medio arranca — y el resultado real llega después, en el evento `play`/`pause` que el provider YA recibe (ahí arranca el bucle de progreso, y `commit-complete` ya cabalga `ended` con ese patrón exacto). Mismo defecto en `toggleMute()` y `seek()`; `toggleFullscreen` y `togglePip` lo hacen bien, esperando a la plataforma. Consecuencias: - H-10 deja de ser materia de canon y pasa a **G-5** en §8: mover el commit del clic al evento de resultado, aplicando el patrón que el propio fichero usa. - **El árbitro de dominancia se queda como está.** Nunca tuvo que arbitrar dos ocurrencias que el diseño no quiere simultáneas; proponer una regla nueva era arreglar el síntoma en la capa equivocada. - El test conserva la medición (dos ocurrencias en el mismo tick = dos earcons, 4 osciladores) porque el dato es correcto y vale como guardia; lo que se reescribe es su lectura. Para D-AP.7 no cambia lo demás: ninguna de las dos señales vive en el provider, así que el silencio en modo audio tiene que cubrir descendientes. sema e2e 5/5 · `docs:check` 0. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
2 months ago |
|
|
5ac194cfe1 |
test(sema): un botón compuesto suena DOS veces, medido (H-10)
En F0 observé que el botón de play estampa dos señales por clic. Afirmé de ahí que sonaría dos veces, y eso era un salto: el motor tiene un árbitro de dominancia precisamente para esos casos. Medido: **4 osciladores, dos earcons**. Por qué el árbitro no los colapsa. `occurrenceRank = evaluable×10 + activación`: `contact-activate` del `Button` es estructural y sin intent → **0**; `commit-toggle-play` del player es evaluable con intent `neutral` → **10**. La regla silencia a un recién llegado sólo si una ocurrencia YA ACTIVA lo supera, y aquí llegan en orden 0 → 10: cuando entra el segundo, el activo no lo supera; y el primero ya había sonado. El modelo asume que la señal de más rango llega antes o sola — **el caso inverso, a microsegundos, no está arbitrado**. Tampoco hay pack de `button`, así que `contact-activate` usa la base de familia (800 Hz, 60 ms) y se solapa con el commit de 100 ms que entra encima. **No es del media-player**: es el patrón de composición del catálogo — la primitiva acusa el contacto, el componente confirma el valor. Cualquiera que componga `Button` y dispare su propio evento suena dos veces con el sonido activo. El test lo pinea donde se puede oír el camino entero (`sound-e2e.test.ts`), y la decisión —regla nueva en el árbitro, canon que declare el solape intencionado, o packs que silencien `contact` bajo componentes que hablan por sí mismos— queda fichada en el plan como materia de `book-deviations.md`, no de una sesión. Para el reproductor cambia una cosa y es la que importa para D-AP.7: el silencio en modo audio tiene que cubrir las DOS señales, y ninguna vive en el provider. sema + art 17 suites / 205 tests · `docs:check` 0. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
2 months ago |
|
|
7ae5a8117d |
docs(process): F0 del reproductor — las verificaciones, hechas antes de pedir la firma
La mitad de F0 que no necesita firma, ejecutada primero, porque tres de los cinco resultados cambian lo que hay que firmar. Sin código del player. - **H-1 confirmado con stamp real.** `data-event="commit-toggle-play"` aterriza en `<button data-media-player-play-button>`; el pack selecciona el provider y no puede casar. Es **1 de las 3 reglas** —`commit-complete` y `commit-fail` apuntan bien—, y el fix de una línea **cambia comportamiento** (empieza a sonar donde no sonaba), así que espera a la firma como G-4. - **El `Slider` compuesto sí sonoriza**, por composición y sin excepción: `TimeSlider` → `Slider.Provider` → `resolveSliderDragSound` en cada `handle-drag`. Stamp medido sobre `[data-slider]`. La regla propuesta funciona porque `Element.matches()` evalúa descendencia. - **Hallazgo nuevo**: el botón de play emite **dos** señales por clic — `contact-activate` del `Button` compuesto y `commit-toggle-play` del player, ambas en el propio `<button>`. Una regla de silencio anclada al provider no alcanza a ninguna: el silencio en audio tiene que cubrir los DESCENDIENTES. - **H-9 — `sustain-loading` es superficie de contrato muerta.** La pregunta de F0 («¿se auto-limpia?») era inválida: **no se emite nunca**. Está declarado en el morfo, verificado por su test y documentado en el README de soma como si viviera; no hay un solo `trigger`. El spinner lo mueve `data-buffering`, que es estado. `sustain-end` queda descartado, y qué hacer con el evento —cablearlo o retirarlo— entra en el gate. - **Segmentos: 1 de 6, no paridad.** Media Chrome no tiene componente de clip en su `main` (revisados `src/js` y `experimental`; el `media-clip-selector` que circula en buscadores es de una 0.x retirada), Plyr sólo `markers`, Red Hat no lo documenta, react-h5 no lo lleva. Sólo wavesurfer, por plugin. **D-AP.12 cambia de recomendación: v2**, con el diseño de §7.5 congelado. Diferirlo no acorrala —sin `clip` el dominio es `0…duration`, añadirlo luego es un modo nuevo, no un cambio de significado. - **vidstack#1195 caracterizado, NO reproducido**: abierto, sin respuesta, iOS 17.3.1 en Chrome y Safari móviles, escritorio sano, `webkit blob resource error 1`. Apunta a fuentes `blob:` + su forma de acotar el rango seekable, no a la idea de clip; nuestro diseño no toca la fuente. Pero *probable* no es *verificado*: exige un iOS real, y este entorno no lo tiene. Correcciones de método aplicadas al propio trabajo: `gh` no existe en este entorno y un `|| echo` lo convirtió en un falso negativo sobre media-chrome — rehecho por la API. Y la recomendación de D-AP.12 se cambia con los datos delante en vez de defender la que ya estaba escrita. `docs:check` 0 errores. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
2 months ago |
|
|
b27f2345fe |
docs(process): el motor cierra sus fases y abre 5 hallazgos; el player, al gate
`PLAN-sound-engine` pasa a CERRADO (F0…F5) y `PLAN-audio-player` a DESBLOQUEADO. Pero cerrar las fases no es dejar el diseño incuestionado, así que el plan gana una auditoría propia que lo contradice donde toca. - **§15 — la invariante, cerrada y medida.** Incluye lo que la medición DESMINTIÓ: el handoff anterior predecía un aviso por consola en `/temas/sema` que no podía aparecer, porque el aviso cuenta contextos VIVOS y allí sólo había uno. Y **E-8**, el agujero de attach que E-1 dio por cableado sin estarlo. - **§16 — 5 hallazgos ABIERTOS sobre el art**, tres con decisión pendiente: `analyze.ts` sigue abriendo su contexto (medido 1 → 2 al importar un `.wav`); el aviso de segundo contexto es ciego a los contextos crudos; **S-1 NO está cerrado** y §7 afirmaba lo contrario —queda tachado en su sitio—; el canal tira en silencio `masterGain` y compañía cuando le inyectan el motor; y `gainScale`, que es de UNA reproducción, se escribe en el master compartido. - **§16.1 — la pregunta de fondo**: el corte separa módulos, **no conocimiento**. La quinta a 1.5×, el ADSR recortado a 15 %/40 %, el contour de ±400 cents y el mapeo de `roughness` son diseño sonoro calibrado contra el vocabulario de sema, viviendo dentro de lo que el plan llama «maquinaria». El precedente de `$motion` —datos en la capa, mecanismos en el art— no se replica tan de cerca como §3 afirma. Y la superficie no sirve a dos de los tres consumidores que la justificaban: `Waveform` y el analizador necesitan los `AudioBuffer`, y `preload(urls)` los esconde en una caché privada. - **`sema.md` corregido**: «sema no importa el art» era cierto para la INSTANCIA y falso para el grafo de módulos. - **`PLAN-audio-player` con las 5 correcciones de su cabecera incorporadas al cuerpo**, que era la condición para presentar nada: segmentos en la matriz §2 y en el contrato §7.5; **G-2 sube a bloqueante** (buffer, ventana de clip, capítulos); las dos invariantes de §7.6 (`prefs.sound` NUNCA toca el volumen del contenido; el silencio de UI debe alcanzar al `Slider` compuesto). **D-AP.11 escrita contra el art** —su premisa, «no hay motor», era falsa— y **D-AP.12** (segmentos `clip`) añadida; las dos existían como referencia sin fila en §4. **D-AP.7 reescrita** como ducking. - El handoff añade dos reglas que costaron caro: **un guard que no has visto fallar no vale**, y acoplarse al dev server vivo del usuario en vez de levantar otro. D-AP.1…D-AP.12 siguen SIN FIRMAR: el gate es lo primero de F0 y no se escribe una línea de código del player antes. `docs:check` deja 1 error ajeno (`blocks/banner/README.md:15`, «8 roles» por 9). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
2 months ago |
|
|
6920684d09 |
refactor(sound): extraer el motor Web Audio de sema al art `$sound`
`sema/chans/sound.ts` tenía 407 líneas de las que ~255 (≈63%) eran maquinaria Web Audio —ciclo de vida del AudioContext, síntesis, samples, desbloqueo por gesto— mezclada con doctrina perceptiva. Deuda arrastrada, con tres síntomas medidos: el import era estático, así que toda app con sema metía el sintetizador en el bundle aunque el sonido estuviera apagado (que es el default); faltaba ciudadanía que `$scene` ya resuelve; y la costura de inyección (`audioContextFactory`) llevaba ahí sin usar desde el principio. Mismo movimiento que `$motion` hizo desde eidos: el art se lleva el RUNTIME, la capa conserva sus DATOS y su doctrina. - `$sound` / `EngineSound`: UN AudioContext por documento (los navegadores los limitan y el gesto de desbloqueo es por contexto), síntesis de earcon, samples con caché y fallback a síntesis, `autoSuspend` OPT-IN —suspender con la pestaña oculta es correcto para earcons y erróneo para contenido, así que es decisión de quien compone— y aviso cuando un segundo contexto va vivo. Puertos `SoundDom` / `SoundTimers` inyectados; no importa ningún otro art ni nada de `$uix/sema`, que es la prueba objetiva del corte. - `SoundChannel`: 407 → 136 líneas. Solo doctrina: el gate de `prepare`, la política de reducción y el reparto «el canal resuelve el NIVEL, el motor aplica la ganancia». Sema no gana ni un import: recibe el motor por puerto. - `uix.sound` en standalone y attach con `ownsSound` (idioma ya shipped: `ownsMotion` / `ownsScene`), fila `sound` en la tabla ejecutable `contracts.ts`, y `defineEngineSound()` para el camino de app. - Tests nuevos: `engine-sound.test.ts` (11), `sound-port.test.ts` (guard de deriva de tipos + la regla de propiedad) y `sound-e2e.test.ts`, que recorre `emit -> cascada -> canal -> art -> grafo real`: el camino que las 16 suites previas no cubrían porque paraban en canales falsos. Sin `diagnostics.ts` ni `errors.ts`, y es decisión: espejo de `$scene`, aquí todo fallo es degradación documentada, no error de programador. Verificación: 17 suites / 198 tests · `check` en la baseline exacta (73 errores, 0 propios) · `sound.test.ts` verde SIN tocar un solo assert, que era el criterio de que el movimiento fue value-preserving. Planes: `PLAN-sound-engine.md` (completo, con el registro de la revisión adversarial E-1..E-7), `PLAN-audio-player.md` (aparcado tras el análisis del reproductor, con sus correcciones en cabecera) y `CONTINUE-sound-engine.md` (handoff). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
2 months ago |