|
|
# CONTINUE — la cola de auditorías, y el protocolo con el que se trabaja
|
|
|
|
|
|
> **Kickoff para la sesión siguiente**: _«Lee `docs/process/CONTINUE-audit-queue.md`
|
|
|
> y empieza por §1 (S-33, firmado y sin ejecutar).»_
|
|
|
> **Fecha**: 2026-08-13 · Rama `alpha-0.1-dir-prefs`, pusheada en `eda3b977b`.
|
|
|
> ⚠️ **COMPARTIDA**: otra sesión trabaja en `blocks` **y** en un eje de
|
|
|
> dismissal (los `types.ts` de color-picker / time-picker / time-range-picker).
|
|
|
> `git reset -q` + stagear por lista explícita, y clasificar **por contenido del
|
|
|
> diff, nunca por nombre**.
|
|
|
> **Fuentes de los hallazgos**: [`AUDIT-sema-2026-08-05.md`](./AUDIT-sema-2026-08-05.md)
|
|
|
> (44 confirmados con refutación adversarial) ·
|
|
|
> [`CONTINUE-perceptual-surface.md`](./CONTINUE-perceptual-surface.md) §3 (la
|
|
|
> cola larga, con el detalle de cada eje). Este documento dice **cómo se
|
|
|
> trabaja, qué se firmó y por dónde se sigue**.
|
|
|
|
|
|
---
|
|
|
|
|
|
## 0 · EL PROTOCOLO — va primero porque cambió hoy, y no es opcional
|
|
|
|
|
|
**Por CADA modificación o acción, y ANTES de tocar nada**, se responden las
|
|
|
cinco preguntas del autor:
|
|
|
|
|
|
1. ¿Qué es lo que se va a solucionar?
|
|
|
2. ¿Has leído toda la documentación al respecto, o sólo estás presuponiendo?
|
|
|
3. ¿Qué afecta a otros componentes?
|
|
|
4. ¿Afecta a las doctrinas del ecosistema?
|
|
|
5. ¿Qué modificaciones planteas?
|
|
|
|
|
|
**Un item por mensaje, y se PARA a esperar firma.** Hoy propuse una «puerta»
|
|
|
que me dejaba auto-autorizar lo mecánico y presenté cuatro decisiones juntas en
|
|
|
una hoja resumida; el autor lo cortó en seco. No hay puerta: se expone y se
|
|
|
espera.
|
|
|
|
|
|
Y dos precondiciones que hoy costaron **dos rectificaciones completas**:
|
|
|
|
|
|
- **El SPEC del COMPONENTE es doctrina, y se busca ANTES de diagnosticar.** El
|
|
|
item de la «6ª fila fantasma» de chronos llevaba un mes en la cola y llegó a
|
|
|
estar FIRMADO; al ir a ejecutarlo apareció `SPEC.md` del componente diciendo
|
|
|
lo contrario en tres sitios coordinados. Se revocó. Una asimetría con la
|
|
|
familia NO es evidencia de deriva: puede ser la única decisión escrita.
|
|
|
- **Barrer `docs/` ANTES de proponer retirar nada.** Recomendé retirar
|
|
|
`intentRequirement: 'forbidden'` «igual que `collapse` y `lock`». Falso:
|
|
|
aquellos no tenían una línea en `docs/`; éste está en `CANON.md` §4, en
|
|
|
`architecture/sema.md` §, y en la tabla de **D.3**, decisión firmada del autor
|
|
|
en `decisions/book-deviations.md:472`.
|
|
|
|
|
|
Regla que resume las dos: **el código nunca corrige al canon; se le pone al
|
|
|
autor la CONTRADICCIÓN delante y decide él.**
|
|
|
|
|
|
---
|
|
|
|
|
|
## 1 · Mañana lo primero: S-33, FIRMADO el 2026-08-13 y sin ejecutar
|
|
|
|
|
|
**El defecto es `Exclude`, no «falta una rama».** `IntentOptionalFamily =
|
|
|
Exclude<SemaFamily, IntentRequiredFamily>` es una derivación de mundo abierto
|
|
|
—«todo lo que no es required»— así que una familia marcada `'forbidden'` cae en
|
|
|
el cubo OPCIONAL, donde el intent está permitido. Los dos guardianes de runtime
|
|
|
tienen el mismo hueco: `validation.ts:39` sólo comprueba `=== 'required'`, y
|
|
|
`event.ts:104-110` (`isSemaEvent`), si el intent está presente, devuelve
|
|
|
`isIntent(...) || isIntentBinding(...)` sin mirar la política.
|
|
|
|
|
|
**Medido con el `tsc` del proyecto** (probe con los dos estados del const, hoy y
|
|
|
endurecido). Un único error en todo el probe, y es el control de la derivación
|
|
|
actual:
|
|
|
|
|
|
```
|
|
|
intent-probe.ts(87,1): error TS2578: Unused '@ts-expect-error' directive.
|
|
|
```
|
|
|
|
|
|
es decir: con `contact` en `'forbidden'`, `{ family: 'contact', intent: 'threat' }`
|
|
|
**compila**. Lo demás del probe demostró las tres cosas que hacían falta:
|
|
|
|
|
|
| Probe | Resultado |
|
|
|
| --- | --- |
|
|
|
| `{contact,intent}` · `{contact}` · `{commit,intent}` con la tercera rama presente | compilan → **una rama tecleada sobre `never` no cuesta nada hoy** |
|
|
|
| `@ts-expect-error` sobre `{family:'commit'}` | se CONSUME → la puerta de `required` sigue intacta |
|
|
|
| `@ts-expect-error` sobre `{contact,intent}` con derivación POSITIVA y contact forbidden | se CONSUME → **flipar una línea del const cierra la puerta solo** |
|
|
|
| `{family:'contact'}` a secas, misma situación | compila → `'forbidden'` significa «familia usable, intent prohibido», no «familia inutilizable» |
|
|
|
|
|
|
**La receta firmada:**
|
|
|
|
|
|
1. `sema/types.ts` — derivar los tres cubos **positivamente** (`extends 'optional'`
|
|
|
/ `extends 'required'` / `extends 'forbidden'`), matando el `Exclude`, y añadir
|
|
|
la rama `{ family: IntentForbiddenFamily; intent?: never }` a `SemaEvent` y a
|
|
|
`MorfoEventSemantic` (`morfo/types.ts`).
|
|
|
2. `sema/event.ts:104` y `sema/validation.ts:39` — la condición simétrica en los
|
|
|
dos guardianes de runtime.
|
|
|
3. El esquema sium de `morfo/schema.ts` **no necesita nada hoy** (no hay literal
|
|
|
que añadir mientras ninguna familia sea `'forbidden'`), y si alguien flipa el
|
|
|
const **salta el guard de S-34** que se metió hoy y le dice que lo añada. Las
|
|
|
dos mitades cubiertas: los tipos se activan solos, el runtime avisa.
|
|
|
4. El probe se convierte en **test** (`sema/` o `contracts.test.ts`), para que
|
|
|
el día que alguien reintroduzca un `Exclude` el `@ts-expect-error` deje de
|
|
|
consumirse y falle.
|
|
|
|
|
|
Delta de conducta hoy: **cero, medido**. Lo que cambia es que la promesa del
|
|
|
canon («editing the const reshapes the discriminated unions») pasa a ser cierta.
|
|
|
|
|
|
⚠️ Y la razón por la que se descartó la alternativa que yo mismo había
|
|
|
recomendado —un guard que fallara si alguna familia declara `'forbidden'`— es
|
|
|
doctrinal, no de gusto: es **lint donde el tipo puede hablar**, y `CLAUDE.md`
|
|
|
§*Eidos drift defense* dice que cuando una capa PUEDE expresar la restricción en
|
|
|
TypeScript, hacerlo con un test es una violación de arquitectura. La misma
|
|
|
doctrina con la que ayer se cerró F3 borrando `targetOverride`.
|
|
|
|
|
|
---
|
|
|
|
|
|
## 2 · Lo cerrado hoy (6 commits, todos pusheados)
|
|
|
|
|
|
| Commit | Qué |
|
|
|
| --- | --- |
|
|
|
| `b8aa333fd` | **F3 CERRADA** — `targetOverride` BORRADO de `TriggerOptions` + `assertTargetOverride`; el compilador, ya como censo, cazó 9 usos en tests que el grep del scratch nunca escaneó |
|
|
|
| `c00e97b91` | **F5 CERRADA** — los tres sitios de las tres auditorías, medidos DESPUÉS de la campaña |
|
|
|
| `a15745491` | **chronos `fixedWeeks`: decisión REVOCADA** — el SPEC manda; no era un defecto |
|
|
|
| `44af38e6e` | **S-10** — el canal visual honra los servicios de su propia bolsa (`anidado ?? raíz`, como los otros tres) |
|
|
|
| `14a169357` | **guard D9** — mira también la vista de eidos, que en los componentes-vista ES el emisor |
|
|
|
| `eda3b977b` | **S-34** — el validador de runtime queda atado al const de política de intent, con el guard visto fallar |
|
|
|
|
|
|
Con F5 cerrada, **las seis fases del eje perceptual (F1–F6) están completas**.
|
|
|
|
|
|
---
|
|
|
|
|
|
## 3 · Decisiones ABIERTAS — esperan firma, no se tocan
|
|
|
|
|
|
Cada una necesita su exposición de cinco preguntas cuando se abra. Aquí sólo el
|
|
|
titular y la evidencia ya medida, para no re-descubrirla.
|
|
|
|
|
|
### S-35 · la forma etiqueta regala lo que la estructurada exige
|
|
|
`SemaActionEvent = SemaEvent | SemaEventLabel` y la etiqueta incluye la familia
|
|
|
pelada: `'commit'` compila aunque `commit` sea `required`, y
|
|
|
`normalizeSemaEvent('commit')` devuelve `intent: null` — el documento que la
|
|
|
política declara inválido. `validateSemaEvent` remata devolviendo temprano ante
|
|
|
cualquier etiqueta (`validation.ts:29`). **Alcance medido**: `SemaActionEvent` no
|
|
|
tiene consumidores fuera de los tres ficheros del propio sema. Va pegado a S-33:
|
|
|
la misma unión, las mismas líneas.
|
|
|
|
|
|
### ~~S-30/S-38~~ · EJECUTADO 2026-08-13 — las cinco reglas ABREN LA PUERTA
|
|
|
**La decision se INVIRTIO al contrastarla con el mundo real y con el autor.** Mi
|
|
|
recomendacion era borrar los bloques; el autor pregunto que hacen iOS/Android y
|
|
|
quien decide — y la verificacion en las fuentes (Apple HIG: haptic de warning
|
|
|
para alertas; tick de seleccion para cambios de valor; Android: «less is more»
|
|
|
pero con constantes CONFIRM/REJECT) mas un hecho del propio framework (la
|
|
|
intencion estaba ESCRITA y comentada en los packs, y la haptica entera es
|
|
|
opt-in del producto) cambiaron el veredicto: las reglas llevaban la intencion
|
|
|
del disenador y solo habian olvidado la puerta. Arreglo: `channels: ['sound',
|
|
|
'haptic']` en las cinco, con la razon perceptual escrita en cada una; los 5
|
|
|
waivers de `CHANNEL_EXCEPTIONS` fuera (el guard del censo, re-armado, ES el
|
|
|
test que avisa si vuelve a pasar); y un e2e nuevo en `resolver.test.ts` que
|
|
|
prueba resolucion + `vibrate()` con valores FINITOS (la defensa S-31 cubre los
|
|
|
`{kind:'tick'}` parciales — el aviso del waiver ya estaba pagado). Visto en
|
|
|
rojo dos veces: el censo sin waivers listando las 5, y el e2e contra los packs
|
|
|
sin ensanchar.
|
|
|
|
|
|
### S-30/S-38 · (ficha original, cerrada)
|
|
|
Dialog ×2 (alertdialog y sheet), editable, stepper y timeline escriben
|
|
|
`haptic: {…}` sobre eventos de familia `emerge`/`shift`, cuyo `activeChannels`
|
|
|
es `['sound']`. Medido por el verificador con resolver y canal reales: firma
|
|
|
háptica instalada, `vibrate()` **0 veces**. Y el mapa es coherente en su diseño:
|
|
|
las familias que vibran declaran **base háptica Y canal** (contact, commit,
|
|
|
signal, handle); emerge y shift no declaran ninguna de las dos.
|
|
|
**Opciones**: (a) `channels: ['sound','haptic']` en las cinco (patrón canónico en
|
|
|
`slider`, `css-field`, `drag-drop`) · (b) borrar los bloques y escribir que
|
|
|
emerge/shift no vibran. **Mi criterio: (b)** — el mapa ya lo dice en dos sitios
|
|
|
independientes, y (a) reabriría por la puerta de atrás una decisión perceptual
|
|
|
(que un overlay te vibre en la mano) que nadie ha tomado. Con guard que cruce
|
|
|
cada regla contra el `activeChannels` alcanzable.
|
|
|
|
|
|
### ~~S-19~~ · EJECUTADO PARCIAL 2026-08-13 — la firma alineada; encenderlo sigue ABIERTO
|
|
|
**Mi primer analisis estaba mal y el autor lo mando revisar.** Dije que el canal
|
|
|
estaba muerto porque el runtime de soma no mete `message` en la señal; es cierto
|
|
|
que no lo mete, pero **es diseño, no defecto**: son DOS emisores para DOS
|
|
|
publicos (soma cubre sus componentes; el canal cubre a quien usa
|
|
|
`EngineSemantic` SIN soma y escribe su propia señal con el texto). Justo por eso
|
|
|
nada se anuncia dos veces, y mi opcion (b) —fusionarlos— habria roto el diseño.
|
|
|
Retirada.
|
|
|
|
|
|
HECHO: `AnnounceFn` pasa a prioridad POSICIONAL, como el sumidero y como la
|
|
|
fuente de soma, asi que `{ announce: uix.announce }` compila literal y sobra el
|
|
|
adaptador. Visto en rojo antes: un sumidero con la forma de `uix.announce`
|
|
|
recibia `{priority:'assertive'}` en el hueco de la prioridad — y ahi
|
|
|
`liveRegionIds[obj]` es `undefined`, o sea que TODO caia en la region polite y un
|
|
|
`threat` dejaba de interrumpir. 3 aserciones de test migradas de bolsa a
|
|
|
posicional. `sema.md` §announce reescrito: fuera el aviso del adaptador, dentro
|
|
|
la razon de los dos publicos.
|
|
|
|
|
|
QUEDA ABIERTO (decision, no bug): **ninguna raiz enchufa el canal**. Con el
|
|
|
puerto ya alineado es UNA linea en la raiz, pero encenderlo sin inyectar el
|
|
|
anunciador cae en las regiones propias del canal y añade un SEGUNDO par
|
|
|
`role=status`/`role=alert` junto al compartido.
|
|
|
|
|
|
### S-19 · (ficha original)
|
|
|
`AnnounceFn` pide `(message, { priority })` y `uix.announce` es posicional
|
|
|
`(message, priority?, timeout?)`: el cableado canónico de `sema.md:762` es un
|
|
|
error de tipos, no hay adaptador, y **ninguna de las dos raíces** pasa `announce`
|
|
|
al engine. Si alguien fuerza el cast, `priority` llega como objeto,
|
|
|
`liveRegionIds[priority]` es `undefined` y todo cae en la región polite — un
|
|
|
`threat` deja de interrumpir.
|
|
|
**Son DOS decisiones y conviene no mezclarlas**: (i) alinear la firma + corregir
|
|
|
el doc — no cambia conducta, porque hoy nadie lo pasa; (ii) enchufar el canal en
|
|
|
las raíces, que **sí** cambia conducta y arriesga el «dos sumideros» que la
|
|
|
propia doctrina prohíbe, porque soma tiene su propio puerto de anuncio
|
|
|
funcionando (`soma.svelte.ts:99`, el de metrics/menu-dial/onion-menu).
|
|
|
**Mi criterio**: (i) ahora, (ii) como ítem con censo previo de quién anunciaría
|
|
|
por los dos caminos.
|
|
|
|
|
|
---
|
|
|
|
|
|
## 4 · La cola, en orden
|
|
|
|
|
|
1. ~~**S-33**~~ EJECUTADO 2026-08-13 (`1a174d5a6`): los tres cubos derivados en
|
|
|
positivo + rama `intent?: never` + `intentRequirementOf()` (leer el const
|
|
|
directo ESTRECHA y el gate no compila — arista que la ficha no vio).
|
|
|
Desviacion declarada: `validation.ts` NO se toco (su rama de politica es
|
|
|
inalcanzable — hallazgo nuevo, abierto).
|
|
|
2. ~~**S-35**~~ EJECUTADO 2026-08-13 (`6a7554415`): `SemaEventKey` derivado de la
|
|
|
politica (bare solo sin required; pareja sin forbidden), `SEMA_EVENT_LABELS`
|
|
|
56→54, `isSemaEventLabel('commit')` false → `validateSemaEvent` lanza. Dos
|
|
|
hallazgos ABIERTOS de su paso: el vocabulario de etiquetas no tiene NINGUN
|
|
|
consumidor en produccion (¿se gana el sitio?), y la rama `required` de
|
|
|
`validation.ts:39-46` es codigo muerto (inalcanzable tras `isSemaEvent`).
|
|
|
3. ~~**S-30/S-38**~~ EJECUTADO · ~~**S-19**~~ EJECUTADO PARCIAL (firma alineada; encender el canal sigue abierto, ver §3).
|
|
|
4. **§3.5 fable** — ~~`M1 emission`~~ **PARTE (i) EJECUTADA 2026-08-13**: el
|
|
|
flag `emission: 'runtime' | 'host' | 'external' | 'declared-only'` de D.2
|
|
|
existe en `MorfoEvent` + schema (ausente = `'runtime'`, las ~250
|
|
|
declaraciones intactas), el guard D9 exime por declaracion (y si el evento
|
|
|
eximido esta en la deuda, EXIGE limpiarla — visto con sonda temporal sobre
|
|
|
tooltip), el pack-census rechaza reglas sobre eventos `declared-only`
|
|
|
(fixture 2 casos; `host` NO es muerto), y `morfo.md` §Step 5.5 lleva el
|
|
|
apendice tecnico con la nota doctrinal de D.2. La sonda destapo y cerro un
|
|
|
agujero: el flag entre `name` y `semantic` hacia INVISIBLE el evento al
|
|
|
regex del guard — ahora lo tolera. ⚠️ **Parte (ii): 3 de 7 resueltas** — ~~tooltip ×3~~ **CABLEADO 2026-08-13**
|
|
|
(la re-analisis del autor cazo lo que faltaba: la firma global
|
|
|
`present-rise` de base.css:6520 y que la entrada por `data-state` era el
|
|
|
WORKAROUND de la emision ausente, con la semantica focus=sin-entrada
|
|
|
colgando de ella). Receta F4: `present` pre→post SIN su commit (el commit
|
|
|
fijaba 'delayed-open' y pisaria el 'instant-open' del focus — los overlays
|
|
|
binarios si lo conservan), dismiss ×2 + `targetFallback: [trigger]`,
|
|
|
triggers solo en transiciones REALES (un timer cancelado no emite; un
|
|
|
re-hover abierto no re-emite), y la causa escape distinguida. MEDIDO en
|
|
|
navegador los 3 caminos: hover→present en CONTENT con la entrada autorizada
|
|
|
corriendo (scale-in+fade-in, present-rise NO — el preset gana la cascada);
|
|
|
focus→present con `instant-open` y present-rise CORRIENDO = la fuga exacta
|
|
|
→ silencio visual MINIMO en la receta, scoped a
|
|
|
`[data-state='instant-open'][data-event-phase='active']`, re-medido: anims
|
|
|
[]; leave→dismiss en CONTENT via Presence con la salida autorizada
|
|
|
(scale-out+fade-out, dismiss-fade no); Escape→dismiss-escape. El SILENT del
|
|
|
pack por fin CASA y la puerta de temas funciona. Deudas limpiadas: 3 ids
|
|
|
del D9 + 3 excepciones del censo. ~~virtual-list/grid ×3~~ **RESUELTOS
|
|
|
2026-08-13 con `emission: 'host'`** — la resolucion YA estaba escrita en los
|
|
|
dos providers como decision con su porque («apps wire it themselves with
|
|
|
their own throttle policy»; per-pixel + familia handle = trinquete continuo
|
|
|
bajo inercia) y solo le faltaba un sitio DECLARABLE: es el caso de diseño
|
|
|
del valor `host` de D.2. La cita desfasada del comentario
|
|
|
(`activeChannels=['haptic']` — hoy es ['sound','haptic']) corregida al
|
|
|
tocarlo; la promesa del host es viable (`provider.runtime` es publico).
|
|
|
~~gradient-picker commit-reset~~ **RETIRADO
|
|
|
2026-08-13 (S-14 cerrado)** — y la ficha se corrigio con medida: los
|
|
|
hermanos color/date/time-picker SI emiten su reset (cableados 2026-08-11),
|
|
|
pero NO componen el Picker generico — son dueños de su transaccion.
|
|
|
Gradient-picker la DELEGA entera (su docblock lo declara), asi que el Clear
|
|
|
ya suena con el `commit-reset` del picker compuesto, y cablear el gemelo
|
|
|
habria dado DOBLE firma por un gesto (la clase file-upload). Retirados:
|
|
|
evento del morfo (con la razon en su lugar) + regla del pack + filas de los
|
|
|
dos README + la excepcion del censo + el ultimo id de la deuda.
|
|
|
**Con esto la parte (ii) esta COMPLETA y M1 CERRADO ENTERO: las dos listas
|
|
|
de deuda (INERT_EVENT_DEBT y EMISSION_EXCEPTIONS) quedan VACIAS por primera
|
|
|
vez**, cada una con su lapida explicando las 7 resoluciones. La
|
|
|
instancia original de la ficha (5 pickers con close inerte) esta MUERTA
|
|
|
desde la normalizacion de nombres · ~~`M4`~~ **EJECUTADO 2026-08-13, con
|
|
|
el DIAGNOSTICO CORREGIDO dos veces**: la premisa de la ficha era falsa (hay
|
|
|
12 declaraciones con enum de 3+, censadas: aura·checkbox·image·meter·
|
|
|
progress·tooltip) y su arreglo («exigir exactamente 2 valores») las habria
|
|
|
proscrito — son legitimas porque bindean STRINGS y el modo hace passthrough.
|
|
|
El peligro real es booleano↔enum-no-binario, hoy inexistente. Arreglo: la
|
|
|
pareja solo se infiere con enum BINARIO (exacta por construccion), y un
|
|
|
booleano llegando a 3+ LANZA nombrando la salida declarativa (`v.mapRef`,
|
|
|
que YA existia en el vocabulario — ni campo nuevo ni adivinanza), doctrina
|
|
|
S-09. En mi re-analisis cai en dos: el «guard de contratos» de mi primera
|
|
|
propuesta NO existia, y mi censo de bindings verifico 2 de 12 — la suite
|
|
|
entera de navegador (1278✓) es la que probo que ninguno bindea booleano.
|
|
|
Tests nacidos en rojo 2/3 (el tercero paso porque ES la conducta binaria de
|
|
|
hoy) · ~~`M5`~~ **EJECUTADO 2026-08-13, y la ficha era INCOMPLETA**: acertaba en que
|
|
|
se puede tipar ya, pero no vio que 2 de los 5 usos casan attrs que el morfo
|
|
|
NO declara A PROPOSITO (`data-size`/`data-sheet`, eidos-only por docblock) ni
|
|
|
que un solo slot no puede imponer enum Y quedar abierto (la clase S-11). La
|
|
|
solucion es el precedente de DOS EJES del framework: `state` tipado con
|
|
|
`DataPairOf<M>` (attr declarado + valor del enum; el typo no compila) +
|
|
|
`undeclaredState` abierto y auto-documentado para los eidos-only, con el
|
|
|
builder lanzando en runtime si un attr declarado se cuela por la puerta
|
|
|
abierta (y viceversa) — gate en el builder y no en el censo porque lanza al
|
|
|
IMPORTAR el pack. `aria` queda abierto con la razon escrita (su unico uso
|
|
|
casa un role deliberadamente no declarado). Mi primera propuesta era un
|
|
|
guard de censo — el MISMO error de S-33, corregido en re-analisis. Probes
|
|
|
`@ts-expect-error` + 5 tests runtime nacidos en rojo (4/4) ·
|
|
|
~~`M6`~~ **EJECUTADO
|
|
|
2026-08-13**: los alias `IntentExpectedFamily`/`SemaEventLabel` BORRADOS
|
|
|
(no-shims; D.3 los nombra como HISTORIA, no como prescripción), 13 usos
|
|
|
migrados a los canónicos, `semaIntentExpectedFamilySchema` renombrado
|
|
|
`…Required…` CON el guard S-34 actualizado en el mismo commit, los 2
|
|
|
`as never` de `compile.ts` retirados (vestigio pre-`DepSink`), y
|
|
|
`_resetCompileCache` resultó YA borrado — fuera de la cola ·
|
|
|
~~`E2`~~ · ~~`E3`~~ **EJECUTADOS 2026-08-13** — E2: el mode-source de sistema
|
|
|
consulta `dom.getWindow().matchMedia` y se suscribe por `dom.listen`
|
|
|
(ventana CORRECTA en iframe/popup; fallback crudo sin dom); descartado el
|
|
|
tracker en adom por la regla de ≥2 consumidores (los 6 boots reales de web/
|
|
|
pasan todos su `modeSource` — el camino de sistema tiene hoy CERO
|
|
|
consumidores vivos). E3: `#lastSchemeCss` — un re-derive que falla conserva
|
|
|
el ultimo bloque bueno y avisa por `#uix?.logger` en vez de DESVESTIR la
|
|
|
pagina (`apply()` leia '' como «sin esquema» y borraba el `<style>`);
|
|
|
`applyColorScheme` sigue lanzando eager en la cara del llamador. Hallazgo
|
|
|
del rojo: el validador de config es FAIL-CLOSED y rechaza escalas rotas en
|
|
|
la puerta — la inyeccion del test va sobre `buildScheme` mismo, passthrough
|
|
|
real hasta que el flag lo revienta. Ambos tests vistos morder el codigo
|
|
|
viejo via stash.
|
|
|
5. **§3.6 blocks** — **`A-47` SIGUE ABIERTO — el arreglo del 2026-08-13 fue
|
|
|
REVERTIDO el 2026-08-14** (`acda70f1e` deshecho). No llegaba a 5 recetas
|
|
|
(alias congelados en `:root`, la violacion que `canon/tsc.md` nombra y que
|
|
|
no se leyo antes de proponer), no cubria los lienzos solidos de Card ni
|
|
|
Banner, y EMPEORABA el anillo en subarboles que repintan lienzo claro. Lo
|
|
|
que el analisis dejo en claro y sirve para quien lo retome: el anillo
|
|
|
pertenece al CONTEXTO DE TINTA (`[data-on]`), no al variant de un
|
|
|
componente; y el eje evaluativo (`--focus-ring-color-error`) NO puede
|
|
|
aplanarse a la tinta de contraste — el rojo es el mensaje; su problema real
|
|
|
es que es translucido (`color-mix(risk-8 52%, transparent)`) y se lo come
|
|
|
cualquier lienzo saturado. NADA de esto esta verificado por el autor.
|
|
|
[texto anterior, ahora invalido:] ~~ARREGLADO en la CLASE, no en la
|
|
|
instancia**: el anillo global es primario translucido (suave a proposito) y
|
|
|
sobre un `Surface` solido primario media 1,02:1 (peor aun que el 1,43 del
|
|
|
ledger; misma pareja rgb(142,78,198)). Una declaracion en la regla solida de
|
|
|
`surface.css` rescopa `--focus-ring-color` a la tinta del slot
|
|
|
`contrast(on-solid)` (pick APCA + suelo WCAG, rfc-color-engine §8; §32 = un
|
|
|
solo modelo outline, todos los consumidores beben del var). Medido en la
|
|
|
demo real: 1,02 → **5,18:1** en el `outlineColor` del boton enfocado; el
|
|
|
token global fuera del panel INTACTO (2,17, sin cambios). A plena fuerza,
|
|
|
sin mix — aritmetica sobre token garantizado re-pierde la garantia.
|
|
|
Hallazgos anotados sin decidir: `--focus-ring-color-error` sobre solido
|
|
|
(semantica de error, caso aparte) y el 2,17:1 del anillo global contra la
|
|
|
PAGINA (el ledger no lo señalo; el contraste puede satisfacerse contra el
|
|
|
boton adyacente — decision de diseño si se abre). Fila del ledger →
|
|
|
ARREGLADO, SIN commitear (viaja con la otra sesion, protocolo A-85) ·
|
|
|
~~`A-69`~~ **ARREGLADO 2026-08-13 via la disposicion del ledger, tras
|
|
|
re-analisis del autor** (mi primera propuesta sustituia el muelle por un
|
|
|
ease-out — cambio de DISEÑO de tapadillo: la caida exponencial es la
|
|
|
semilla portada; y mi cita de motion.md §drivers estaba fuera de
|
|
|
jurisdiccion — gobierna presets CSS, no numero→formatter). Ejecutado:
|
|
|
λ derivada de (recorrido, umbral, duration) con ζ fija en 2√2 — misma
|
|
|
FORMA, reloj recalibrado; `onEnd` desde la parada REAL del muelle (antes:
|
|
|
timer ciego que disparaba 5,9 s antes); guard de recorrido no-mostrable.
|
|
|
MEDIDO con Playwright (sonda espejo de la del ledger, muestreo directo de
|
|
|
textContent): 12.500/340/48 asientan TODOS en 1977 ms (duration 2000,
|
|
|
±23 ms) con dispersion 0 ms — antes 7867/5083/3567 y 4310 de dispersion.
|
|
|
Fila del ledger → ARREGLADO sin commitear (protocolo A-85). NO tocados:
|
|
|
A-68 (arranques vs entrada — item propio) ni el driver spring de $motion
|
|
|
(sustrato distinto). **§3.6 blocks COMPLETO.**
|
|
|
6. **§3.3 eje B** — 4 continuos sin throttle (gradient-builder, color-picker
|
|
|
área, number-field, css-field) · `sequence: 'coincident'` sin implementar
|
|
|
con 21 eventos declarándolo (**decisión**: implementar o marcar reservado) ·
|
|
|
las 68 demos emitiendo sin `verb` · medir `knob.handle-drop` (`pre` con
|
|
|
handler) y el retraso de 120 ms de `button.contact-activate`.
|
|
|
7. **Firmadas que quedan** — el chip bloqueado vía `DragDrop.Draggable`
|
|
|
(transversal, con su letra pequeña ya medida en
|
|
|
`CONTINUE-perceptual-surface.md` §4) · retirar `mode`/`scope` (+ la hermana
|
|
|
`SemaCause`, que sigue ABIERTA).
|
|
|
8. **§3.2 restitución de persistentes** — eje nuevo del engine; afecta form,
|
|
|
file-upload, textarea, media-player, announce, aura.
|
|
|
9. **C5 rebanadas 3-4 de chronos** — subir a soma el comportamiento del chip
|
|
|
(teclado, captura de puntero, drag-to-create) y sólo después extraer
|
|
|
`MonthView`/`WeekView`/`AgendaView`. Con D14 dentro. El grande.
|
|
|
|
|
|
---
|
|
|
|
|
|
## 4.1 · Hallazgos del 2026-08-13 — RESUELTOS por el autor
|
|
|
|
|
|
Los tres que salieron mientras se cerraban §3.4 y §3.5, decididos el mismo día:
|
|
|
|
|
|
- **La rama `required` de `validation.ts` es código muerto** → **SE QUEDA, y
|
|
|
documentada** en el docblock de `validateSemaEvent`: `isSemaEvent` es
|
|
|
policy-aware, así que una violación sale por el throw genérico y el mensaje
|
|
|
específico nunca dispara (medido). Se conserva porque los dos guards
|
|
|
responden preguntas distintas y sólo su ORDEN hace redundante a uno;
|
|
|
reordenar sería cambiar el mensaje lanzado sin que nadie lo pida.
|
|
|
- **El vocabulario de etiquetas sin consumidor interno** (`SemaActionEvent`,
|
|
|
`normalizeSemaEvent`, `toSemaEventLabel`, `validateSemaEvent`) → **SE GANA
|
|
|
EL SITIO, y documentado** en el docblock de `SemaActionEvent`: no es falta
|
|
|
de consumidor, es AUDIENCIA — la app que conduce `EngineSemantic` sin soma,
|
|
|
la misma que sirve el canal announce (dos emisores, dos públicos). Soma
|
|
|
nunca toma ese camino porque baja la declaración estructurada del morfo.
|
|
|
- ~~**Encender el canal announce en las raíces (S-19 parte ii)**~~ →
|
|
|
**EJECUTADO 2026-08-13, encendido POR DEFECTO en las dos raíces.** El
|
|
|
análisis destapó que era la raíz o nadie: la opción `announce` se pasa al
|
|
|
construir el engine DENTRO de `createActiveUix`, cuando `uix.announce` aún
|
|
|
no existe — el único cableado escribible por un app caía en las regiones
|
|
|
propias del canal (el segundo par que AUX-1 prohíbe). El impl registra el
|
|
|
canal post-construcción con cierre tardío, igual en standalone y attach.
|
|
|
Default ON porque announce es SUSTITUCIÓN, no ornamento (la norma del campo:
|
|
|
Angular CDK LiveAnnouncer, React Aria — el anunciador a11y es ambiente).
|
|
|
Opt-outs: `events: { announce: false }` (el engine gana el flag legible
|
|
|
`announceOptedOut`) y un `announce` explícito del app gana. Cero doble
|
|
|
anuncio: soma no mete `message` en la señal. Visto en rojo vía stash del
|
|
|
impl; probado que el mensaje aterriza en la región COMPARTIDA (ids de uix,
|
|
|
UN solo `[role='alert']` en el documento). `sema.md` §announce actualizado.
|
|
|
|
|
|
## 5 · Base de verificación (mídete contra esto, no contra memoria)
|
|
|
|
|
|
```
|
|
|
npx vitest run src/uix/sema src/uix/morfo src/uix/contracts.test.ts --project=server
|
|
|
npx vitest run src/uix/soma # proyecto navegador
|
|
|
npm run check # 69 errores = base
|
|
|
npm run docs:check # 0 / 623
|
|
|
```
|
|
|
|
|
|
- `contracts.test.ts` tiene **6 fallos AJENOS y preexistentes** (barrel de
|
|
|
waveform · nombres de fichero de provider · MOR-4 · escrituras DOM de menubar ·
|
|
|
data-attrs · namespaces de aura). Hoy llegó a haber 7: el séptimo era **mío y
|
|
|
de otro commit**, y se cerró (`14a169357`).
|
|
|
- soma navegador: **1278 ✓ / 1**, el timeout ajeno preexistente de
|
|
|
`soma-attr-audit`.
|
|
|
- sema+morfo: **532 ✓**.
|
|
|
|
|
|
---
|
|
|
|
|
|
## 6 · Trampas medidas hoy — no re-descubrirlas
|
|
|
|
|
|
- **El guard D9 es laxo A PROPÓSITO.** Compara `includes("'nombre'")` y no
|
|
|
`trigger('nombre')` porque el nombre llega a la llamada por VARIABLE en media
|
|
|
docena de patrones. Censado: endurecerlo convierte **27 emisiones reales** en
|
|
|
violaciones. Su precio —un nombre entrecomillado en un comentario lo
|
|
|
satisface— queda escrito en el propio colector.
|
|
|
- **El panel del navegador oculto**: `rAF` suspendido (los ticks continuos no
|
|
|
estampan nunca) y la línea de tiempo de animaciones congelada, así que el
|
|
|
desestampado cae SIEMPRE en el tope de 1500 ms de la espera de expresión.
|
|
|
`getAnimations()` dice QUÉ corre sobre QUÉ, nunca cuánto dura.
|
|
|
- **Prettier**: hay ficheros sucios en HEAD (`errors.ts`, `test-fixtures.ts`,
|
|
|
`runtime.svelte.ts`, `runtime.svelte.test.ts`, `contracts.test.ts`). Probar
|
|
|
contra HEAD antes de `--write`, y no reformatear lo que ya estaba sucio.
|
|
|
- **`git stash push <ruta>` + `stash pop`** es la forma limpia de comprobar si un
|
|
|
fallo es tuyo o de HEAD. Hoy demostró que el D9 fallaba sin mis cambios.
|