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 }
8 Commits (c494fb395226888516543c02201a551842685f69)
| Author | SHA1 | Message | Date |
|---|---|---|---|
|
|
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 |
|
|
0d10b983e5 |
revert(sema): la libreria de sonido vuelve byte a byte — la retirada no era de esta sesion
Revierte la mitad D10 de `5571f3bf7` por orden del autor. La sesion era normalizar nombres de evento; la retirada de los 3 resolvers de gesto nacio de perseguir un homonimo que cree yo mismo al renombrar `SoundDirection` → `SoundContour` sin mirar el namespace de destino, y se ejecuto sin leer primero el handoff vivo del eje (`CONTINUE-sound-engine.md` — la memoria del proyecto lo marca PRIMERO) ni `PLAN-audio-player-v2.md` (gate firmado), que ni siquiera sabia que existia. La verificacion posterior salio limpia — ninguno de los seis documentos no leidos nombra los resolvers — pero limpia por suerte no es limpia por metodo. Restaurados byte a byte a su estado anterior al borrado (diff contra `5571f3bf7^` = 0 lineas): - `sema/sounds.ts` (160 lineas otra vez: resolvers, `DragSoundParams`, `SoundContour`, `clamp`, `lerp`) · `sounds.test.ts` (los 2 tests de arrastre) · `exports.ts` (los 5 re-exports) - las 4 prosas que se habian reescrito describiendo el borrado: `sema/types.ts`, `sema/components/splitter.ts`, `soma/splitter-provider.svelte.ts`, `arts/motion/types.ts` - `scripts/docs-vocabularies.ts` + `docs/canon/vocabularies.md` regenerado - la nota fechada que se añadio al §4 de `PLAN-sound-engine.md` Lo que NO se revierte, porque no depende de la libreria: D9 (el acarreo de chronos) y el guard de eventos inertes — verificados en verde tras el revert. El ledger deja constancia: D10 pasa a CONFIRMADO (retirada REVERTIDA), con el analisis conservado como evidencia PARA la sesion propia del eje de sonido — `git log -S` (un solo commit en la vida de los resolvers), `book-deviations.md` dandolos por borrados el 2026-08-06, los dos planes cerrado/rechazado — y la regla explicita: sounds.ts no se toca sin una sesion que empiece por su handoff. Verificado: sema 300/300 (con los tests restaurados dentro), guard de eventos inertes en verde, `check` 70 errores (linea base), `docs:check` 0/623. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
2 months ago |
|
|
5571f3bf7e |
feat(soma,sema): el acarreo de chronos habla, los 3 resolvers se van, y un guard cierra la clase
D10 · no era una decision abierta: era una firmada sin ejecutar
---------------------------------------------------------------
Mi correccion de mi propia propuesta estaba sobre-corregida: lei la linea 95 de
un plan y la 367 de otro, no los documentos.
- `PLAN-sound-engine.md` esta CERRADO (2026-07-30) y su columna «sema conserva»
miente en 4 de 5 celdas: `SOUND_LIBRARY` no existe, `SOUND_TUNINGS` se retiro
el 2026-08-06 (con guard que lo mantiene retirado), el sonido salio de la
cascada, y «que firma para que familia × intent» lo sustituyo la ley del
nombre. Es un inventario del 30 de julio, no un mandato.
- `PLAN-audio-player.md` esta ⛔ GATE RECHAZADO — SUSPENDIDO, y su cabecera dice
«nada de lo de abajo se implementa».
- La fuente que gobierna es `docs/decisions/book-deviations.md`, de DECISIONES,
que el 2026-08-06 escribio en pasado: «un gesto continuo suena por REPETICION …
y los tres resolvers se borraron con el». `git log -S` sobre `sounds.ts`
devuelve UN SOLO COMMIT en toda su vida (mayo): nunca se borraron. El registro
dio por ejecutado lo que no se ejecuto.
Retirados los tres, `DragSoundParams`, el `SoundContour` de sema, sus exports,
los dos tests que solo se probaban a si mismos y los helpers `clamp`/`lerp` que
quedaron huerfanos: `sounds.ts` pasa de 160 a 79 lineas. Con ellos cae el
homonimo `SoundContour` — el nombre queda para el art, sin renombrar nada. El
plan cerrado no se reescribe, pero su §4 lleva ya una nota fechada porque me
engaño a mi.
D9 · el acarreo habla
---------------------
`handle` pregunta «¿estoy manipulando directamente este objeto?», y una familia
que no responde su propia pregunta ha fallado en lo unico para lo que existe
(CANON §2). Chronos es el componente mas manipulable del catalogo y hablaba solo
el suelte: el acarreo entero estaba mudo. El *handle invisible*.
No se autora nada — `handle` ya declara `sounds: { default: 'step' }` y los dos
canales, asi que el RITMO es el sonido. Estrangulado a ~14 Hz como slider y
splitter, y ANCLADO: los destinos son partes repetidas, asi que es aplicacion
directa de la ley de `e5811e422`.
Donde el acarreo NO es de chronos: arrastrar un chip con puntero pasa por el
`DragDrop` compuesto, que declara tres eventos y emite tres, sin acarreo continuo
(CANON regla 6). Dos componentes narrando un gesto seria peor. Asi que
`handle-drag` es el acarreo de TECLADO y `handle-resize` cubre las dos vias.
Medido: el arrastre del tirador con puntero da 6 `handle-resize` en 6 pasos,
todos sobre `event-resize-handle`.
El guard, y dos hallazgos que salieron de medirlo
--------------------------------------------------
`book-deviations.md` tipifica el defecto hermano como «mecanicamente comprobable
y merece guard». Este es la misma forma un piso arriba, y es la clase que produjo
D1, D3, D4 y D9. La prueba NO es `trigger('literal')` — chronos despacha por
variable y eso me dio dos falsos negativos durante la auditoria; se comprueba que
el nombre aparezca como literal donde el provider alcance: su directorio soma mas
las librerias compartidas (sin `$libs/selection` en el ambito, combobox y select
se leen como inertes y no lo son).
D13 — quedan 7 eventos inertes en 4 componentes, enumerados en
`INERT_EVENT_DEBT`, que no son exenciones sino la cola. El peor: `tooltip` 3 de
3, cero `trigger(` en todo su directorio, abriendo y cerrando sin firma alguna.
D14 — midiendo D9 salio un defecto anterior: `restoreChipFocus` reenfoca en un
`queueMicrotask` que corre ANTES de que Svelte reponga el nodo, asi que enfoca la
nada y el foco cae al `<body>`. La segunda flecha ya no llega al manejador y el
Escape tampoco: la interaccion que el propio componente anuncia («Grabbed. Arrow
keys move, Enter drops, Escape cancels») muere al primer paso. No lo toco aqui —
es de foco, no de firma, y merece su propia medicion en navegador real.
Verificado: guard visto fallar deshaciendo D9 (caza los dos eventos); `check` 70
errores en linea base; 2250 tests del uix — los 6 fallos de `contracts.test.ts`
siguen siendo de la otra sesion; `docs:check` 0/623 tras regenerar
`vocabularies.md`.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2 months ago |
|
|
d2e841c65d |
fix(sound): la auditoría del art, cerrada — niveles por reproducción y opciones que no mienten
Los tres hallazgos que quedaban de `PLAN-sound-engine` §16, firmados y aplicados.
Dos con código, uno con una medición que cambia la doctrina.
**A-5 — `gainScale` es de la reproducción, no del documento.**
`play()` escribía `master × gainScale` en el nodo master, del que cuelgan TODOS
los earcons. Un parámetro transitorio corrompía un mando de política: el nivel
se filtraba entre reproducciones, una nota en vuelo saltaba de volumen, y los
dos consumidores que motivan el motor compartido —la reducción de sema y el
ducking de un reproductor— se pisaban sobre un único valor. Ahora el factor
multiplica el pico de la envolvente de ESA reproducción, y **también la
profundidad del AM**: dejarla absoluta habría hecho que un earcon atenuado
sonara relativamente más áspero, cambiando el timbre en vez del volumen, que es
lo contrario de lo que significa una reducción.
**RC-5 se reescribe, y es legítimo**: un contrato de regresión protege
comportamiento, no defectos. Lo que pineaba —«la ganancia se fija ANTES de que
la síntesis reviente»— sólo importaba porque el valor iba a un nodo compartido.
La cobertura no se pierde, se coloca donde vive cada responsabilidad:
`sound-port.test.ts` ya pineaba que el canal resuelve el NIVEL y lo entrega;
`sound.test.ts` pinea ahora que el master **no se mueve**; y el art estrena un
contexto falso que sí construye el grafo, para ver el pico de la envolvente.
**A-4 — las opciones del canal, imposibles de equivocar.**
`SoundChannelOptions` pasa a unión discriminada: `{ engine, preferences?,
logger? }` **o** la forma de construcción (`audioContextFactory` / `fetcher` /
`dom` / `masterGain` / `timers`). Nunca ambas — un motor llega ya construido, así
que sus opciones de construcción no significan nada a su lado, y hasta hoy se
aceptaban y se tiraban en silencio. La defensa primaria es el tipo (doctrina de
la casa), con un guard `@ts-expect-error` que hace fallar `check` el día que la
unión deje de rechazar la mezcla; el aviso por logger es la red para JS.
`engine.ts` pasa de un spread a tres ramas en orden de precedencia.
Y **`fetchFn` → `fetcher`**, para alinearse con `$perm`: un nombre por concepto.
`audioContextFactory` **se queda** — es el patrón `idFactory` que ya usan
`$logger` y `$bus`, y nombra el tipo exacto que fabrica (`context` a secas
colisiona con el contexto GL de `$scene`).
**A-3 — S-1 aceptado, medido: 2,2 KB.**
El art entero son 6.410 bytes minificados / 2.177 gzip. Y mi propia propuesta
para cerrarlo era falsa: quitar el fallback del canal no saca el art de ningún
bundle, porque `createActiveUix` y `defineEngineSound` lo importan
incondicionalmente. Cerrarlo de verdad exige carga diferida, que choca con que
`prime()` deba ser síncrono dentro del gesto, y volver `uix.sound` perezoso —
cambio de superficie pública por 2,2 KB. Se acepta: el art es servicio de
núcleo, como `motion` y `scene`. Queda corregida la doctrina: S-1 era el más
débil de los cuatro síntomas; los que justificaban la extracción eran S-2 y S-4.
**La voz, declarada como diseño.** La quinta a 1.5×, el ADSR recortado a
15 %/40 %, el contour de ±400 cents y el mapeo del AM son decisiones perceptivas
calibradas contra el vocabulario de sema, no maquinaria. Escrito en el README
del art y en la cabecera de `engine-sound.ts`, con la regla: el día que un
segundo consumidor quiera otra voz, ése es el momento de partir el art en dos
—gobierno de contexto / voz—, no antes.
Verificación: art + sema **17 suites / 204 tests** · `contracts.test.ts` 35/38
(los 3 rojos, ajenos) · `check` en la baseline exacta (73, 0 propios) ·
`docs:check` **0 errores** · los guards de A-5 **vistos fallar** al reintroducir
la escritura al master · navegador `/temas/sema`, 4 ciclos de editar→disparar:
**1 contexto, 16 osciladores, master en 1, cero errores de consola**.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2 months ago |
|
|
cf37aee002 |
docs(sound): el aviso de segundo contexto dice lo que hace, no lo que promete
A-2 de la auditoría (`PLAN-sound-engine` §16). El contador de contextos vivos sólo ve **los que crea el art**, así que un `new AudioContext()` en cualquier otro sitio le es invisible: detecta cableado doble de ENGINES, no el antipatrón del contexto crudo que su propio mensaje describe. Ese hueco es exactamente lo que dejó al estudio de sema abrir un segundo contexto en silencio hasta ayer (A-1) — y lo que hizo inútil el plan del handoff anterior, que era «abre la página y mira el warn». Cerrarlo de verdad exigiría enganchar el constructor global, es decir parchear la plataforma. El art no lo va a hacer. Así que se escribe donde prometía de más, en `consts.ts` y en el README, y se apoya en la salida real: los consumidores que necesitaban su propio contexto ahora tienen puertas —`decode` para las muestras, `context` para el grafo— que no les obligan a abrirlo. Sin cambios de comportamiento. Art 13/13 · `check` en la baseline exacta (73). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
2 months ago |
|
|
08ee18a8e1 |
fix(sound): `decode()` — la puerta que faltaba, y el estudio deja de abrir su contexto
A-1 de la auditoría (`PLAN-sound-engine` §16): `analyze.ts` hacía `new Ctor()` propio para decodificar el `.wav` importado. Medido inyectando un WAV real por el `input[type=file]`: **1 → 2 contextos**. Transitorio —se cerraba al acabar el decode— pero es exactamente el antipatrón que el art existe para impedir, en la misma página que usé como prueba de la invariante. Y el aviso de «segundo contexto» no lo vio, porque sólo cuenta los contextos que crea el art (A-2). No era un despiste de esa página: **la superficie del art no ofrecía la operación**. `preload(urls)` decodifica y esconde los `AudioBuffer` en una caché privada, así que quien quiere las MUESTRAS —un waveform leyendo picos, un analizador midiendo un fichero— no tenía puerta y se abría la suya. - **`EngineSound.decode(data): Promise<AudioBuffer | null>`**. Segunda puerta, simétrica de `context`: una para quien quiere un GRAFO, otra para quien quiere las MUESTRAS. Las dos llevan al mismo contexto. - **No pasa por `getOrCreateContext()`**: decodificar funciona sobre un contexto suspendido, y `resume()` fuera de un gesto puede quedarse pendiente para siempre — un `decode()` que se espera desde la UI no puede colgar de eso. Se añade `ensureContext()`, crear sin resumir. - **No cachea** (los bytes crudos no tienen clave; la caché por URL es de `preload`) y **devuelve `null` en vez de lanzar**. - **Desviación declarada** de lo que §16.2 proponía: NO se añade el acceso a los buffers cacheados. Hoy no tiene consumidor —`Waveform` no existe— y añadir superficie sin consumidor es justo lo que §16.1 le reprocha al art. - `analyze.ts` toma el motor por puerto estructural; `AnalyzePanel` lo lee de `getActiveUix()`, que es el idioma de la casa, no prop-drilling. MEDIDO en Chrome: importar un WAV crea ahora **1 contexto** en vez de 2, y el earcon posterior reutiliza ése. Y sigue analizando bien: un tono de 440 Hz a 8 kHz, decodificado sobre el contexto compartido a 44,1 kHz, se mide como **441 Hz** — el resampleo no falsea la medida. Guards nuevos en `engine-sound.test.ts`: decodifica sobre el contexto compartido SIN llamar a `resume()`, un segundo `decode` no crea otro contexto, y devuelve `null` con bytes indecodificables o sin contexto. Verificación: art + sema 17 suites / 201 tests · `check` en la baseline exacta (73 errores, 0 propios). Quedan abiertos A-2 (el aviso es ciego a los contextos crudos), A-3 (S-1 no está cerrado), A-4 (opciones del canal tiradas en silencio) y A-5 (`gainScale` en el master compartido) — los tres últimos cambian comportamiento público y esperan decisión. 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 |