diff --git a/docs/architecture/sema.md b/docs/architecture/sema.md index 5822d156d..b51a2e7ad 100644 --- a/docs/architecture/sema.md +++ b/docs/architecture/sema.md @@ -649,6 +649,28 @@ announcer (`{ announce }`, e.g. `ActiveUix.announce`, one shared region) or a self-owned pair of live regions built from the injected `dom`. Fire-and-forget, never rejects. Supersedes `book-deviations.md` D.8's deferral. +**Live-region doctrine — who owns what (AUX-1 / SEM-1, 2026-07-11).** The +framework has ONE sink, two emitters, and an app-level component: + +- `uix.announce` (ActiveUix) owns the SHARED pair of live regions — the + low-level sink (its zwsp-toggle re-announce is an implementation detail of + that sink, not a third policy). +- The two framework **emitters** both prefer delegating to it: the soma + runtime's a11y commitments (`a11ySemantic.requiresLiveRegion` → + `sources.announce`) and this channel (inject `{ announce: uix.announce }`; + its self-owned clear-then-set regions are ONLY the no-uix fallback). +- The soma `` component is different in kind: an app-authored, + declarative region for app-level messages — not a vehicle for framework + event announcements. + +Priority is ONE policy everywhere (SEM-1 — the runtime used to add a +`family === 'signal'` conjunct, making a threat-tinted commit announce +polite on one path and assertive on the other): the evaluative INTENT alone +— `threat` / `loss` → `assertive`, else `polite` — implemented identically +in `priorityForIntent` (`chans/announce.ts`) and the runtime's a11y step +(`runtime.svelte.ts`), pinned by tests on both sides +(`announce.test.ts` · `runtime.svelte.test.ts` SEM-1). + ### Per-channel reductions — `engine.preferences` `BK-REDUCTIONS` (ch. 32 §12 / ch. 33 §7): a symmetric reduction story per diff --git a/docs/process/continue-cleanroom-fixes-2026-07.md b/docs/process/continue-cleanroom-fixes-2026-07.md index 54c06d1ec..d43d5b359 100644 --- a/docs/process/continue-cleanroom-fixes-2026-07.md +++ b/docs/process/continue-cleanroom-fixes-2026-07.md @@ -20,6 +20,35 @@ - Badge R-4.3 (única violación R-4.x viva en su §5.3) ✅ cerrada en el censo R-1.x (`ee9786bc`). Su matriz (102/32/0) es previa: hoy **134/0/0**. +## ⏭️ ARRANQUE PRÓXIMA SESIÓN → F2 (lote mecánico) + +Estado al cierre 2026-07-11: **F0 ✅ + F1 ✅** (commiteadas — `4addfd7d` + +el handoff posterior). Gates vigentes que deben MANTENERSE: matriz +**135/0/0** · contracts **38/38** · eidos **309/309** · sema 178 · baseline +**57** · vocab exit 0. Leer los bloques «EJECUTADA» de F0/F1 (abajo) para +el contexto y arrancar F2 directo — es el lote SIN decisiones de usuario. +Orden sugerido (barato → delicado, no-cascada: ítem → gates → siguiente): + +1. **DEP-2** ogl fuera de package.json (+lockfile) · **DEP-1** clsx + inlineado (cerrar el "pending" de soma.md §12). +2. One-liners: **THM-7** (ejemplo sema.md → semaSelector) · **THM-6** + (menu-dial `--radius-full, 1px` → 9999px) · **EID-4** ("31-scale" → 33 ×2). +3. **MOR-1** escape/validación en semaSelector (isomorfo, sin CSS.escape + del DOM) + tests con `"` y `]` · **MOR-2** des-duplicar convención de + marker · **MOR-3** `_resetCompileCache` implementar-o-borrar. +4. **SOM-2** keydown `continue` en match sin handler + test · **SOM-1** + censo de handlers async → si 0, quitar el await (si hay, DECISIÓN #3). +5. **SEM-2** logging por defecto (dev) en canales sin logger + vía + `void trigger` sin unhandled rejection (throw intacto para awaiters) · + **SEM-3** fallback muerto applyDominance + cancelar timer de + awaitExpression · **SEC-1** serializador renderCssVariables rechaza + `;`/`}` embebidos + test. +6. **accordion → outline** (hallazgo F1: `outline:none` + box-shadow = cero + anillo en HCM) — con verificación visual, patrón tabs.css:102. + +Después de F2 → F3 (censos SOM-3◐/SOM-4/THM-5/THM-4). Las iniciativas F4 +(THM-2 paleta · SEM-4 firma dormida · DOC-1/2 · GAP-\*) esperan decisión. + ## Principios de secuencia 1. **La máquina primero.** Los fixes que amplían el enforcement (THM-1, @@ -76,7 +105,38 @@ **Salida de F0**: matriz 135/0/0 · contracts 38/38 · suite eidos 306/306. -## F1 — Coherencia P1: foco y voz (≈1 sesión) +## F1 — Coherencia P1: foco y voz ✅ EJECUTADA 2026-07-11 + +> Resultado: matriz **135/0/0** · contracts 38/38 · eidos **309/309** (+3 +> guards de fundación) · sema 178/178 · soma 1041 verde (2 rojos ajenos: +> chronos = pista rota pre-existente · attr-audit = timeout de contención, +> PASA aislado) · baseline 57. Hallazgos de la ejecución: +> +> - **EID-1**: el `outline: none !important` global que justificaba el +> box-shadow **no existe** — la única mención en TODO el árbol era el +> propio comentario de archetypes.css (fósil de la era Tailwind). Y el +> anillo de fundación pintaba EN PARALELO con los de receta (propiedades +> distintas, mismos tokens → duplicación invisible, verificado en vivo). +> Migrado a outline + `--focus-ring-*` envuelto en `:where()` (la +> fundación pierde ante cualquier receta al compartir ya la propiedad); +> `--focus-ring-bg` era hook muerto (0 consumidores) — retirado. +> Verificación en vivo: Close de dialog = UN anillo (el de Button, box-shadow +> none) · sonda desnuda `data-archetype` = anillo de fundación · light+dark. +> Asientos en reference §32 + changelog §32; bloque forced-colors queda +> como suelo defensivo. +> - **EID-2**: disabled `0.5` → `var(--opacity-disabled)` (=0.4 — las +> recetas YA usaban el token: disabled se veía distinto según la capa) ×3 +> + close hover `0.85` → `var(--opacity-hover)` (=0.9, token por rol). +> Verificado en vivo (0.4 computado). +> - **F1.3**: 3 guards nuevos en recipe-css-contract ("Foundation CSS +> discipline": color/typo/opacity sobre `eidos/*.css` + `lib/*.css`, +> enumeración dinámica) + fallback fantasma `#fff` pagado en +> menu-indicator. picker-shell/spin-field ya entraban por dir. +> - **SEM-1**: runtime alineado al canal — prioridad = INTENT solo +> (threat/loss → assertive); pinneado con `liveRegionFixtureMorfo` +> (commit+threat = el caso divergente) en runtime.svelte.test. **AUX-1**: +> doctrina "who owns what" en sema.md §Announce (1 sink `uix.announce` · +> 2 emisores · `` app-level). | Ítem | Qué | Tamaño | | --- | --- | --- | @@ -251,6 +311,12 @@ Deuda "sin urgencia" desde 2026-05/06 — ponerle fecha (**DECISIÓN #5**): ## Cola lateral (no bloqueante, registrada) +- **accordion: anillo box-shadow + `outline: none` (§32 stray)** — el censo + S5 no lo vio (accordion.css:165 `outline: none` + anillo box-shadow con + tokens propios). Consecuencia real: en forced-colors/HCM su + `outline: none` (0,2,0) gana al suelo defensivo generado (0,1,0) → **cero + anillo en HCM**. Migrar a outline en el lote F2 (mecánico, con + verificación visual). - **Cascada de entrada vs firmas de evento (sistémico, shipped)**: las reglas generadas `[data-stagger][data-state='open'] > [data-animation-style='…']` (0,3,0) siguen reclamando `animation` tras