docs(process): handoff del hilo de sema — lo cerrado, la cola y como medirlo
`CONTINUE-sema-audit.md`, autosuficiente para arrancar una sesion nueva sin
releer las 24 000 lineas del corpus.
Registra:
- Las seis entregas de esta sesion con su commit, y por que cada una fue
necesaria (el silencio como valor, el tremolo en serie, el saneamiento
documental, contact-press, D.7 sin versos sueltos, y la regla de cascada que
dejaba de alcanzar ancestros).
- Las decisiones FIRMADAS que nadie debe re-litigar: `contact-press` (deroga el
anexo Tabla 1, con la reversion escrita en el test), la enmienda de D.7 por su
motivo —familias sin `base.sound` fuera de la prohibicion— y la reescritura de
D.8 —`activeChannels` es default, no prohibicion—.
- La COLA en orden de dano, con su evidencia: las 17 reglas de 212 que no
disparan o disparan mal (textarea 6x/13x, navigation-menu, gradient-picker,
chronos, tree-view mudo por teclado, 5 inertes, 10 con tuning de familia
ajena) · los silenciosos (`preload` colgado que ademas abre contexto en el
boot, `masterGain` que no hace nada, fallback de sample sin diagnostico, 3 WAV
muertos, la rama de tipos que deja pasar un `gain` string) · el interruptor
Sound de las demos · el `announce` que no compila · la instantanea perceptual
· la recalibracion tras el fix del AM · y los dos ejes (el `contact` ausente en
84 de 91 morfos, `Toolbar.Button` sin componer).
- **S-07 marcado como NO TOCAR** sin reabrirlo: decision explicita del usuario.
- Como se verifica audio en este repo, que es donde mas tiempo se perdio: render
offline replicando el grafo, A/B dentro del MISMO componente, y contar
osciladores solo responde «llego algo al motor», nunca «se oye».
- Las lecciones de metodo que costaron caro, incluida la propia: medir la
envolvente NO es medir la salida, y por eso declare un silencio que a −13.9
dBFS era lo mas fuerte de la interfaz.
Baseline al cierre: check 75 · docs:check 0/617 · sema+morfo+sound 369/369.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2 months ago
|
|
|
|
# CONTINUE — auditoría del sistema semántico y sus arreglos
|
|
|
|
|
|
|
|
|
|
|
|
> **Kickoff para la sesión siguiente**: _«Lee `docs/process/CONTINUE-sema-audit.md`
|
|
|
|
|
|
> y sigue por la cola de §3, empezando por las 17 reglas.»_
|
|
|
|
|
|
> **Fecha**: 2026-08-06 · Rama `alpha-0.1-dir-prefs` (compartida — otra sesión
|
|
|
|
|
|
> trabaja en `blocks`; `git reset -q` + add sólo lo propio, siempre).
|
|
|
|
|
|
> **Fuente de verdad de los hallazgos**: [`AUDIT-sema-2026-08-05.md`](./AUDIT-sema-2026-08-05.md)
|
|
|
|
|
|
> — 44 confirmados tras refutación adversarial, con fichero, línea y evidencia.
|
|
|
|
|
|
> Este documento sólo dice **qué se cerró, qué queda y cómo medirlo**.
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 1. Cómo empezó, para que nadie repita el camino
|
|
|
|
|
|
|
|
|
|
|
|
El usuario oyó que «no se oyen muchos componentes: Switch, Toggle, algunos
|
|
|
|
|
|
botones de la toolbar». El diagnóstico inicial fue **incorrecto por medir a
|
|
|
|
|
|
medias** y la corrección la dio él: _«el silent emitía sonido, ese era el
|
|
|
|
|
|
problema»_. Tenía razón, y de ahí salió todo lo demás.
|
|
|
|
|
|
|
|
|
|
|
|
Lecciones de método que costaron tiempo real y que valen para cualquier hilo
|
|
|
|
|
|
de este repo:
|
|
|
|
|
|
|
|
|
|
|
|
- **Medir la envolvente NO es medir la salida.** Se midió la automatización del
|
|
|
|
|
|
`AudioParam` (0.0001) y se declaró silencio; la salida real de esa misma firma
|
|
|
|
|
|
con intent `risk` era **−13.9 dBFS**, más fuerte que un botón. Para verificar
|
|
|
|
|
|
audio: **render offline replicando el grafo** (`OfflineAudioContext`) y medir
|
|
|
|
|
|
el pico de muestra. Contar osciladores miente.
|
|
|
|
|
|
- **«Lee toda la documentación» es precondición, no consejo.** Se le preguntó al
|
|
|
|
|
|
usuario por D.8 sin haber leído `sema.md` §componentes continuos, que contenía
|
|
|
|
|
|
la respuesta. La lectura completa del corpus de sema + motor son ~24 000 líneas
|
|
|
|
|
|
en 42 ficheros; el núcleo indispensable está en §5.
|
|
|
|
|
|
- **Un guard que no has visto fallar no vale.** Los cuatro guards nuevos de esta
|
|
|
|
|
|
sesión nacieron en rojo. Dos de ellos **corrigieron el arreglo** que estaban
|
|
|
|
|
|
vigilando (ver §2.4).
|
|
|
|
|
|
- **El árbol está compartido.** Clasificar siempre «míos vs ajenos» por
|
|
|
|
|
|
contenido del diff, nunca por confianza.
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 2. Lo cerrado en esta sesión
|
|
|
|
|
|
|
|
|
|
|
|
| # | Qué | Commit |
|
|
|
|
|
|
| --- | ---------------------------------------------------------------------------- | ----------- |
|
|
|
|
|
|
| 2.1 | El silencio deja de ser aritmética: **`SILENT`**, valor canónico | `24d30ee1a` |
|
|
|
|
|
|
| 2.2 | La rugosidad pasa a **trémolo EN SERIE** (era aditivo sobre el `AudioParam`) | `316452263` |
|
|
|
|
|
|
| 2.3 | Saneamiento documental: deriva propia, copias podridas, dos leyes muertas | `432106f1f` |
|
|
|
|
|
|
| 2.4 | **`contact-press`** en los toggles + D.7 canónica + **D.8 reescrita** | `b9d73c19b` |
|
|
|
|
|
|
| 2.5 | D.7 sin versos sueltos (7 infractores) + guard del intent | `4fccf1662` |
|
|
|
|
|
|
| 2.6 | Una regla de cascada casa con SU objetivo, **nunca con un ancestro** (S-01) | `ccfea0f10` |
|
|
|
|
|
|
|
|
|
|
|
|
### 2.1 `SILENT` — el silencio es un VALOR, no una resta
|
|
|
|
|
|
|
|
|
|
|
|
Había tres claves silenciadoras (`commit.silent`, `emerge.silent`,
|
|
|
|
|
|
`contact.silent`), cada una restando el gain base de SU familia. No eran
|
|
|
|
|
|
silencio: eran un número, y las capas posteriores mueven números. Medido: un
|
|
|
|
|
|
toggle «silenciado» con intent `risk` salía a **−13.9 dBFS** y con `threat` a
|
|
|
|
|
|
**−6.7**, frente a **−9.3** de un botón normal — porque los deltas de intent
|
|
|
|
|
|
suman **rugosidad** (`risk` +0.2, `threat` +0.4), eso cruzaba el umbral del AM,
|
|
|
|
|
|
y el modulador estaba conectado al `AudioParam` de la envolvente.
|
|
|
|
|
|
|
|
|
|
|
|
Hoy: `SILENT` (exportado por `$uix/sema`) se declara en el slice del canal y el
|
|
|
|
|
|
**resolver lo honra retirando ese canal**. Absorbente: ningún delta lo resucita.
|
|
|
|
|
|
Se levanta sólo REEMPLAZANDO el slice con una firma completa.
|
|
|
|
|
|
|
|
|
|
|
|
### 2.2 El trémolo, en serie
|
|
|
|
|
|
|
|
|
|
|
|
`modulatorGain.connect(envelope.gain)` — conectar a un `AudioParam` **suma**.
|
|
|
|
|
|
Ahora hay una etapa de ganancia en serie a `1 - depth` con el modulador sobre su
|
|
|
|
|
|
propio `.gain`. Medido viejo→nuevo: el clic de cierre de cada earcon de `signal`
|
|
|
|
|
|
**0.0666 → 0.0002**; la cola de `commit+risk` 0.263 → 0.103; y
|
|
|
|
|
|
`commit.subtle`+`threat` de RMS **0.143 → 0.018** (era 7× su nivel declarado).
|
|
|
|
|
|
**Contrapartida declarada**: los earcons con rugosidad bajan 1.6–2.7 dB.
|
|
|
|
|
|
|
|
|
|
|
|
### 2.4 Decisiones FIRMADAS — no re-litigar
|
|
|
|
|
|
|
|
|
|
|
|
- **`contact-press`** (directiva del autor). Los tres toggles declaran los dos
|
|
|
|
|
|
momentos del libro: el CONTACTO habla (`contact.soft`, gain 0.08 — el «click
|
|
|
|
|
|
breve opcional» del cap. 22) y el COMMIT calla (`SILENT`, cap. 23: «sonido:
|
|
|
|
|
|
cierre opcional»). ⚠️ Deroga el anexo Tabla 1, que decía «un único evento; el
|
|
|
|
|
|
contacto es implícito»; la reversión está escrita en `compile.test.ts`.
|
|
|
|
|
|
- **D.7 canónica, con enmienda por su motivo**: no se canoniza un sample sobre un
|
|
|
|
|
|
evento cuya familia **tenga `base.sound`**. `handle`/`sustain`/`delegate` salen
|
|
|
|
|
|
de la lista — sin base no hay nada que aplastar, y los 14 usos de `sound()`
|
|
|
|
|
|
sobre `handle` son la única fuente sonora del gesto.
|
|
|
|
|
|
- **D.8 reescrita**: `activeChannels` es el DEFAULT de la familia, no una
|
|
|
|
|
|
prohibición. `channels` ajusta en las dos direcciones; **ampliar exige
|
|
|
|
|
|
justificación perceptual escrita**. Lo prohibido es declarar una firma de canal
|
|
|
|
|
|
que la activación no incluye (regla inerte).
|
|
|
|
|
|
|
|
|
|
|
|
### 2.5 El hallazgo que conecta dos capas
|
|
|
|
|
|
|
|
|
|
|
|
Al arreglar D.7 con `soundTuning('commit.soft', …)`, **el guard lo tumbó**: un
|
|
|
|
|
|
afinado de escalera trae su `gain` como **número desnudo**, y eso se aplica en
|
|
|
|
|
|
modo `replace` igual que el sample. **D.7 y S-07 son el mismo defecto en dos
|
|
|
|
|
|
capas.** Las 9 reglas corregidas **componen** (`gain: { op: 'add', value: -0.25 }`).
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 3. LA COLA — por dónde seguir, en orden
|
|
|
|
|
|
|
|
|
|
|
|
El usuario aprobó todo lo de abajo **menos S-07**, que se trata «más
|
|
|
|
|
|
detenidamente» y por tanto NO se toca sin reabrirlo con él.
|
|
|
|
|
|
|
|
|
|
|
|
### 3.1 Las 17 reglas de 212 que no disparan o disparan mal ← EMPEZAR AQUÍ
|
|
|
|
|
|
|
|
|
|
|
|
Todas con evidencia en `AUDIT-sema-2026-08-05.md` (S-08, S-12, S-13, S-14,
|
|
|
|
|
|
S-15, S-30, S-37, S-38, S-39):
|
|
|
|
|
|
|
|
|
|
|
|
| Componente | Defecto | Efecto medido |
|
|
|
|
|
|
| ------------------- | --------------------------------------------------------------------------- | --------------------------------------------------------------------------- |
|
|
|
|
|
|
| **textarea** | Las 2 reglas apuntan al `provider`; el estampado cae en el `input` | `commit-submit` suena **6×** más fuerte; el aviso de desbordamiento **13×** |
|
|
|
|
|
|
| **navigation-menu** | `fallbackTarget` GANA sobre el part del morfo → 2 reglas `emerge` muertas | abrir/cerrar suena con la base de familia (0.2) en vez de 0.08 / 0.05 |
|
|
|
|
|
|
| **gradient-picker** | Regla para `commit-reset`, evento que el proveedor nunca emite | regla muerta + doc que miente |
|
|
|
|
|
|
| **chronos** | 2 reglas para `handle-drag` / `handle-resize`, que nadie emite | ⚠️ chronos es de **escritura excluida** — auditar, no editar |
|
|
|
|
|
|
| **tree-view** | `select(value)` sin elemento no dispara: el teclado no emite NADA | asimetría teclado/ratón; 2 reglas sólo alcanzables con puntero |
|
|
|
|
|
|
| 5 reglas | Escriben en un canal que la familia no activa (las inertes de D.8) | letra muerta — ahora infracción explícita |
|
|
|
|
|
|
| 10 reglas | Aplican un tuning cuya cabeza de familia MIENTE sobre la base que modifican | la ley de nombrado ya escrita las señala |
|
|
|
|
|
|
|
|
|
|
|
|
⚠️ **`fallbackTarget` gana sobre el `target` declarado en el morfo pese a su
|
|
|
|
|
|
nombre** (`runtime.svelte.ts:757`). Es la causa raíz de dos de las filas.
|
|
|
|
|
|
Decidir si se renombra o se documenta.
|
|
|
|
|
|
|
|
|
|
|
|
### 3.2 Los silenciosos
|
|
|
|
|
|
|
|
|
|
|
|
- **`preload()` se cuelga en `resume()`** fuera de un gesto → no precarga nada
|
|
|
|
|
|
Y abre un `AudioContext` en el arranque de la página (`engine-sound.ts:248`).
|
|
|
|
|
|
- **Las opciones de motor se descartan en silencio**: `createActiveUix({ events:
|
|
|
|
|
|
{ sound: { masterGain: 0.5 } } })` compila y **no hace nada** — `EngineSemantic`
|
|
|
|
|
|
filtra las claves antes de construir el canal (`engine.ts:299-319`). El aviso
|
|
|
|
|
|
que existe en `SoundChannel` no llega a dispararse.
|
|
|
|
|
|
- **El fallback de sample es mudo**: 4 salidas de fallo sin un diagnóstico, y el
|
|
|
|
|
|
catálogo `SOUND_DIAGNOSTIC_EVENTS` no tiene evento para ello. Un 404, un CORS o
|
|
|
|
|
|
un códec no soportado quedan enmascarados para siempre.
|
|
|
|
|
|
- **3 de los 5 WAV son código muerto**: `whoosh`, `pop`, `ding` no los referencia
|
|
|
|
|
|
ningún pack.
|
|
|
|
|
|
- **Tipos**: la rama `Record<string, DeltaValue>` de `SemaSignatureOverride`
|
|
|
|
|
|
desactiva toda comprobación de clave y valor — un `gain` de tipo _string_ llega
|
|
|
|
|
|
hasta el audio.
|
|
|
|
|
|
- **`applyMapOverrides` se traga las erratas de ruta** y crea ramas fantasma.
|
|
|
|
|
|
|
|
|
|
|
|
### 3.3 El interruptor Sound del topbar de las demos no silencia nada
|
|
|
|
|
|
|
|
|
|
|
|
`web/routes/uix/+layout@.svelte` no pasa `preferences` al canal, que se queda en
|
|
|
|
|
|
`'full'`. El framework sí lo soporta. Medido y sin tocar (viene del hilo del
|
|
|
|
|
|
audio, `CONTINUE-sound-engine.md`).
|
|
|
|
|
|
|
|
|
|
|
|
### 3.4 El `announce` no compila
|
|
|
|
|
|
|
|
|
|
|
|
`AnnounceFn` toma la prioridad en una bolsa de opciones y `uix.announce` la toma
|
|
|
|
|
|
posicional; y **ninguna raíz cablea el canal**, así que activarlo cae en el
|
|
|
|
|
|
fallback que añade un SEGUNDO par de live regions. `sema.md` ya enseña el
|
|
|
|
|
|
adaptador de una línea; falta la decisión de código.
|
|
|
|
|
|
|
|
|
|
|
|
### 3.5 La instantánea perceptual ← la que impide que todo esto vuelva
|
|
|
|
|
|
|
|
|
|
|
|
Guard propuesto y aprobado: una **tabla commiteada con la firma resuelta de cada
|
|
|
|
|
|
(componente, evento, intent neutral)** — gain, hold, háptico. Cualquier cambio en
|
|
|
|
|
|
algo que el usuario percibe rompe el test hasta que la instantánea se actualice
|
|
|
|
|
|
**en el mismo commit**, así que el cambio aparece en el diff en vez de esconderse
|
|
|
|
|
|
dentro de un pack. Habría cazado de golpe toda la clase 3.1.
|
|
|
|
|
|
|
|
|
|
|
|
### 3.6 Recalibrar los gains tras el fix del AM
|
|
|
|
|
|
|
|
|
|
|
|
Los earcons con rugosidad bajaron 1.6–2.7 dB porque el trémolo ya no suma nivel.
|
|
|
|
|
|
Es corrección, no pérdida, pero cambia el volumen percibido de `signal` y de todo
|
|
|
|
|
|
`risk`/`threat`. Decisión de catálogo.
|
|
|
|
|
|
|
|
|
|
|
|
### 3.7 Ejes, no tareas
|
|
|
|
|
|
|
|
|
|
|
|
- **`contact` está ausente en 84 de los 91 morfos con eventos.** Hoy lo expresan
|
|
|
|
|
|
7 (los tres toggles de esta sesión + button, file-upload, navigation-menu,
|
|
|
|
|
|
palabras). El libro le dedica el capítulo 22 entero y CANON §8 lo pone como
|
|
|
|
|
|
regla 1: «contact precede al resultado cuando hay acción directa». Es el eje que
|
|
|
|
|
|
explica por qué media interfaz no responde al «¿me has sentido?».
|
|
|
|
|
|
- **`Toolbar.Button` reimplementa su `<button>`** en vez de componer el de soma:
|
|
|
|
|
|
por eso nunca ha sonado, y no se arregla bajando un gain.
|
|
|
|
|
|
|
|
|
|
|
|
### 3.8 NO TOCAR sin reabrirlo — S-07
|
|
|
|
|
|
|
|
|
|
|
|
Los 14 afinados del catálogo fijan `gain` como número desnudo, que se aplica en
|
|
|
|
|
|
`replace` y borra el perfil evaluativo del intent (~150 usos). El usuario lo dejó
|
|
|
|
|
|
para tratarlo «más detenidamente». Las 9 reglas de §2.5 ya componen; **el resto
|
|
|
|
|
|
del catálogo sigue igual y es deliberado**.
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 4. Cómo verificar en este hilo
|
|
|
|
|
|
|
|
|
|
|
|
- **Audio**: render offline replicando el grafo de `synthesize` y medir pico /
|
|
|
|
|
|
RMS / amplitud en el corte. El patrón exacto está en los mensajes de
|
|
|
|
|
|
`316452263` y `24d30ee1a`.
|
|
|
|
|
|
- **A/B siempre dentro del MISMO componente.** Comparar un Button de otra página
|
|
|
|
|
|
con el transporte del player produjo una contradicción falsa (registrado en
|
|
|
|
|
|
`CONTINUE-sound-engine.md`).
|
|
|
|
|
|
- **Emisión y estampado**: `MutationObserver` sobre `data-event*` del subárbol.
|
|
|
|
|
|
- **Silencio**: contar osciladores es válido para «¿llegó algo al motor?», NO
|
|
|
|
|
|
para «¿se oye?».
|
|
|
|
|
|
- **Mutear antes de reproducir y parar al terminar** — el Chrome que suena es el
|
|
|
|
|
|
del usuario.
|
|
|
|
|
|
- Guards: `sounds-grammar.test.ts` · `cascade-scope.test.ts` ·
|
|
|
|
|
|
`d7-intent-survives.test.ts` · `chans/sound.test.ts` · `engine-sound.test.ts`.
|
|
|
|
|
|
|
|
|
|
|
|
**Baseline actual**: `check` **75** · `docs:check` **0/616** · sema+morfo+sound
|
|
|
|
|
|
**369/369**.
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 5. El corpus, si hay que releerlo
|
|
|
|
|
|
|
|
|
|
|
|
Núcleo indispensable (leído entero el 2026-08-06): `PLAN-sound-engine.md` ·
|
|
|
|
|
|
`PLAN-sound-redesign.md` · `CONTINUE-sound-engine.md` · `architecture/sema.md` ·
|
|
|
|
|
|
`CANON.md` · `theming/channels.md` · `arts/sound/README.md` ·
|
|
|
|
|
|
`decisions/book-deviations.md` (D.5 · D.7 · D.8 · D.9 · D.12).
|
|
|
|
|
|
|
|
|
|
|
|
El **libro** está en `docs/Disenando_lo_que_ocurre_FINAL.pdf` y el manuscrito en
|
|
|
|
|
|
`src/docs/*.docx`. El PDF no se puede renderizar aquí; el `.docx` es un zip —
|
|
|
|
|
|
extraer `word/document.xml` y quitar etiquetas da el texto completo. Capítulos
|
|
|
|
|
|
que decidieron cosas en esta sesión: **5 §11** y **7 §13** (el silencio es firma
|
|
|
|
|
|
válida), **20** (coordinación multicanal), **22** (contact) y **23** (commit, con
|
|
|
|
|
|
su tabla de canales y el emparejamiento del Toggle).
|