You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
svelte-kit-vice/docs/CANON.md

306 lines
15 KiB

---
title: UIX Semantic Canon
type: canon
audience: human + agent
authority: canonical — single source of truth for the semantic vocabulary
status: current
sources:
feat(audit): component re-audit + fixes P0–P5 (P4 complete, P5 in progress) Re-audit of the whole component catalog at pilot depth (91 fichas + the checkpoint verdicts in docs/audit/components/) and the executed fix packages. - P0–P3: doctrine (sema participation, CANON §3 intent, component-guide §5 + API naming, §32 outline), guards (morfo-vocabulary-check S10/S11d, component-audit A-3.1/A-1.4/S9, eidos-lint classHooks), morfo contracts (role=application removed ×4, aria-selected off the Day, drp translationRef, field data-state prune, pin-input commit-set, media-player renames), 13 new sema packs + 12 morfos family-default → pack. - P4 (N1–N10) COMPLETE: selectionMode (select/combobox/toggle-group/calendar); onValueCommit terminal-callback norm (pin-input/search/password/textarea + date/time/color-field add); typed validation reason + onInvalid (tags-input, css-field); index/onIndexChange (carousel); deselectable; openDelay/ groupSkipDelay; allowCustomValue; defaultValue prune. - P5 (in progress): S1 class-hooks codemod (22 hooks → data-attrs across cropper/button/image-picker/toggle/image-adjustments); S5 outline remnant in field.css; depth pass (data-depth=overlay on tooltip/toast/float-panel); touch-rows (--touch-target token, decoupled ::before hit-slop, area-not-visual, 44 AAA). S6 (Field composition) + S8 (calendar-surface) pending. Verification: errors-outside-(alpha|words|palabras|chronos) == 59 (baseline); morfo-vocabulary-check exit 0; eidos-lint class-hooks/invalid 0 on touched components; per-component vitest suites green. Handoff + remaining plan: docs/process/continue-audit-fixes-2026-07.md Excluded (broken by the N1 rename, left broken per user decision, not staged): words/**, palabras/**, chronos, web/routes/alpha/**. Reconciliation pending: the touch-rows ::before for checkbox/switch reverses changelog §37's earlier pseudo-element rejection (WCAG-overlap) that had routed markers to a labeled-row/Field task — flagged for the user in the handoff. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
book: docs/Disenando_lo_que_ocurre_HOMOGENEIZADO.pdf ("Diseñando lo que ocurre", ed. homogeneizada 2026-07 — the earlier v2_3.md no longer exists)
code: src/uix/sema/verbs.ts, src/uix/sema/types.ts, src/uix/intent.ts, src/uix/sema/sema-map.ts, src/uix/morfo/types.ts
---
# UIX Semantic Canon
This is the **single source of truth** for the framework's semantic vocabulary:
the families, intents, verbs, the intent policy, the composition rules, and the
expression channels. It exists so the rest of the corpus **stops re-transcribing
the vocabulary** (which is how it silently drifted: "7 families" survived in
three docs after the canon moved to 8). Every other doc links here.
feat(docs): S1 — generated canonical-vocabulary appendix (STUMBLES #1) An agent building a component from the docs-book alone could not assign archetypes / holds / haptic kinds: the closed sets live only in code consts and the corpus (correctly) forbids copying them into prose, so they were invisible from the docs. STUMBLES #1, the top stumble. Fix: docs/canon/vocabularies.md is GENERATED from the consts by 'npm run docs:vocabularies' — the ONE sanctioned place the lists are spelled out (generated = no drift objection), which every other doc links to. It covers part archetypes (with a one-line role each), sema families with their default hold/persistence + per-intent overrides, verbs by family, intents, the perceptual-duration scale, haptic kinds, the 33 palette scales, sizes, variant archetypes, and the shared common.* strings. - scripts/docs-vocabularies.ts imports the consts (robust — no fragile JSDoc/regex parsing) and formats them; the generation is an exported function so docs-check can compare. - Added ARCHETYPE_DESCRIPTIONS to morfo/types.ts (co-located with ARCHETYPE_VOCABULARY, satisfies Record<MorfoArchetype,string>) as the authoritative one-liners the appendix reads — descriptions become first-class data instead of inline union JSDoc a tool would have to parse. - docs-check gains I7: it regenerates in-memory and fails if the committed file drifts from the consts (negative-tested: corrupt -> error, regen -> green). The appendix's own counts pass I1, so I1 doubles as a second guard. - Linked from README (E2 canon row + two 'I want to' shortcuts), CANON.md (doctrine here, enumerated lists there), architecture/morfo.md (pick a part's archetype), and the component-audit minimum-package list (STUMBLES #8). docs:check 0 errors; npm run check unchanged in my files. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
> **Need the concrete closed sets to build from** (every family's verbs and
> default hold, the intents, haptic kinds, part archetypes, palette scales,
> sizes, variants, shared strings)? They are spelled out — GENERATED from the
> code, so they never drift — in [`canon/vocabularies.md`](./canon/vocabularies.md).
> This file is the *doctrine*; that one is the *enumerated lists*.
Two anchors hold this canon honest:
feat(audit): component re-audit + fixes P0–P5 (P4 complete, P5 in progress) Re-audit of the whole component catalog at pilot depth (91 fichas + the checkpoint verdicts in docs/audit/components/) and the executed fix packages. - P0–P3: doctrine (sema participation, CANON §3 intent, component-guide §5 + API naming, §32 outline), guards (morfo-vocabulary-check S10/S11d, component-audit A-3.1/A-1.4/S9, eidos-lint classHooks), morfo contracts (role=application removed ×4, aria-selected off the Day, drp translationRef, field data-state prune, pin-input commit-set, media-player renames), 13 new sema packs + 12 morfos family-default → pack. - P4 (N1–N10) COMPLETE: selectionMode (select/combobox/toggle-group/calendar); onValueCommit terminal-callback norm (pin-input/search/password/textarea + date/time/color-field add); typed validation reason + onInvalid (tags-input, css-field); index/onIndexChange (carousel); deselectable; openDelay/ groupSkipDelay; allowCustomValue; defaultValue prune. - P5 (in progress): S1 class-hooks codemod (22 hooks → data-attrs across cropper/button/image-picker/toggle/image-adjustments); S5 outline remnant in field.css; depth pass (data-depth=overlay on tooltip/toast/float-panel); touch-rows (--touch-target token, decoupled ::before hit-slop, area-not-visual, 44 AAA). S6 (Field composition) + S8 (calendar-surface) pending. Verification: errors-outside-(alpha|words|palabras|chronos) == 59 (baseline); morfo-vocabulary-check exit 0; eidos-lint class-hooks/invalid 0 on touched components; per-component vitest suites green. Handoff + remaining plan: docs/process/continue-audit-fixes-2026-07.md Excluded (broken by the N1 rename, left broken per user decision, not staged): words/**, palabras/**, chronos, web/routes/alpha/**. Reconciliation pending: the touch-rows ::before for checkbox/switch reverses changelog §37's earlier pseudo-element rejection (WCAG-overlap) that had routed markers to a labeled-row/Field task — flagged for the user in the handoff. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
- **The book** — `docs/Disenando_lo_que_ocurre_HOMOGENEIZADO.pdf` ("Diseñando
lo que ocurre", edición homogeneizada). The editorial source. Each entry
cites its chapter.
- **The code** — the runtime is the executable form. Concrete *values* (per-family
holds, channel signatures, the full verb lists with author extensions) live in
code and are **linked, not copied here**, on purpose. This doc fixes the
*doctrine*; the code fixes the *numbers*.
> Rule: if you need to state a family, an intent, a verb, or a composition rule
> in any other doc, **link this file** — do not paste a copy. A second copy is a
> future drift.
---
## 1. The canonical chain
Every perceptible event resolves through one chain (book ch. 11, §0; ch. 30):
```
event → family → verb / phase → evaluation (if any) → intent → expression channels → unified reading
```
The framework encodes this chain literally: **morfo declares** it, **soma
executes** it (`runtime.trigger`), **sema** carries the perceptual vocabulary and
dispatches channels, **eidos** materializes the visual channels. See
[architecture/active-architecture.md](./architecture/active-architecture.md) for the layer wiring;
this file is only the *vocabulary* that flows through it.
---
## 2. The 8 families
A family is **not** a component or an effect. It is *a recurring class of event
that answers one perceptual question* (book ch. 8, ch. 21). The eight are the
reduction of a wider exploratory set down to a minimal-yet-sufficient grammar
(book ch. 8 §1–3).
Canonical list: `SemaFamily` in [`src/uix/sema/types.ts`](../src/uix/sema/types.ts)
(`SemaValencedFamily | SemaTransitionalFamily`). Per-family base signature,
active channels and hold: `SEMA_MAP.families` in
[`src/uix/sema/sema-map.ts`](../src/uix/sema/sema-map.ts).
| Family | Perceptual question | Accepts intent | Book |
| --- | --- | --- | --- |
| `contact` | ¿el sistema ha sentido mi acción? | leve / anticipatory | ch. 22 |
| `commit` | ¿qué quedó fijado o tuvo consecuencia? | **fully** | ch. 23 |
| `signal` | ¿algo reclama mi atención? | **fully** | ch. 24 |
| `handle` | ¿estoy manipulando directamente este objeto? | only on `drop` | ch. 25 |
| `emerge` | ¿algo entró o salió del campo perceptivo? | normally no | ch. 26 |
| `shift` | ¿cambió el contexto / régimen? | normally no | ch. 27 |
| `sustain` | ¿esto sigue ocurriendo? | normally no | ch. 28 |
| `delegate` | ¿quién actúa ahora? | no by default | ch. 29 |
`contact`/`commit`/`signal`/`handle` are the **valenced** families;
`emerge`/`shift`/`sustain`/`delegate` are the **transitional** ones (book ch. 9).
That split is a *classification*; it no longer dictates the intent rule — the
policy (§4) does.
---
## 3. The 6 intents
An intent is the **evaluative modulation** of an evaluable event — a region of
the valence/activation space (Russell), **not** a color (book ch. 9 §6, ch. 10).
Canonical list: `INTENTS` in [`src/uix/intent.ts`](../src/uix/intent.ts) — owned
by UIX itself, not by a layer. Per-intent perceptual deltas: `SEMA_MAP.intents`
in [`sema-map.ts`](../src/uix/sema/sema-map.ts).
| Intent | Valence / activation | Reading | Book |
| --- | --- | --- | --- |
| `neutral` | low activation, no strong valence | notar sin tono | ch. 10 |
| `affirm` | positive, low activation | "todo va bien" (confirmación suave) | ch. 10 |
| `fulfill` | positive, mid-high activation | "objetivo cumplido" (resuelve tensión) | ch. 10 |
| `risk` | negative, moderate activation | "revisa esto" (corregible) | ch. 10 |
| `threat` | negative, high activation | "atiende ahora" (aún evitable) | ch. 10 |
| `loss` | negative, lower activation, posterior | "ya ocurrió" (consecuencia consumada) | ch. 10 |
Three distinctions the inherited semaphore (`success`/`warning`/`danger`/`info`)
collapses, and that this canon keeps apart (book ch. 10 §4):
- **`threat` ≠ `loss`** — threat convokes action *before* the consequence; loss
registers it *after*. They must not look/sound the same.
- **`affirm` ≠ `fulfill`** — soft confirmation vs resolution of a tension.
- **`info` is not an intent** — it is attentional salience → `signal.* + neutral`.
feat(audit): component re-audit + fixes P0–P5 (P4 complete, P5 in progress) Re-audit of the whole component catalog at pilot depth (91 fichas + the checkpoint verdicts in docs/audit/components/) and the executed fix packages. - P0–P3: doctrine (sema participation, CANON §3 intent, component-guide §5 + API naming, §32 outline), guards (morfo-vocabulary-check S10/S11d, component-audit A-3.1/A-1.4/S9, eidos-lint classHooks), morfo contracts (role=application removed ×4, aria-selected off the Day, drp translationRef, field data-state prune, pin-input commit-set, media-player renames), 13 new sema packs + 12 morfos family-default → pack. - P4 (N1–N10) COMPLETE: selectionMode (select/combobox/toggle-group/calendar); onValueCommit terminal-callback norm (pin-input/search/password/textarea + date/time/color-field add); typed validation reason + onInvalid (tags-input, css-field); index/onIndexChange (carousel); deselectable; openDelay/ groupSkipDelay; allowCustomValue; defaultValue prune. - P5 (in progress): S1 class-hooks codemod (22 hooks → data-attrs across cropper/button/image-picker/toggle/image-adjustments); S5 outline remnant in field.css; depth pass (data-depth=overlay on tooltip/toast/float-panel); touch-rows (--touch-target token, decoupled ::before hit-slop, area-not-visual, 44 AAA). S6 (Field composition) + S8 (calendar-surface) pending. Verification: errors-outside-(alpha|words|palabras|chronos) == 59 (baseline); morfo-vocabulary-check exit 0; eidos-lint class-hooks/invalid 0 on touched components; per-component vitest suites green. Handoff + remaining plan: docs/process/continue-audit-fixes-2026-07.md Excluded (broken by the N1 rename, left broken per user decision, not staged): words/**, palabras/**, chronos, web/routes/alpha/**. Reconciliation pending: the touch-rows ::before for checkbox/switch reverses changelog §37's earlier pseudo-element rejection (WCAG-overlap) that had routed markers to a labeled-row/Field task — flagged for the user in the handoff. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
### Intent assignment — undo matrix and binary toggles (framework materialization, 2026-07-07)
fix(cleanroom): F2+F3+F4-C+SEM-4s1 — lote mecánico, censos con guard, corpus documental y el close polimórfico de los pickers VIVO F2 — lote mecánico (13 ítems): - DEP-2 ogl eliminado (0 imports) · DEP-1 clsx inlineado como toClassString propio + suite de contrato (props.test.ts; soma.md §12 cerrado). - THM-7: los 5 selectores manuales de sema.md reescritos con semaSelector (los ejemplos [data-toast-root] apuntaban a un part INEXISTENTE — la deriva que el builder previene, demostrada en el propio doc). - MOR-1 escape isomorfo + validación de attr-names en semaSelector + 9 tests (selectors.test.ts, matches() real con comillas/corchetes) · MOR-2 partMarkerAttr = única fuente compilador↔builder + test de paridad · MOR-3 _resetCompileCache borrado (0 usos). - SOM-2 keydown continue en match sin handler + keyboardFixtureMorfo · SOM-1 no-await de handlers (censo async = 0; contrato V1 cumplido) + pin. - SEM-2 trigger pre-attacha catch con logger (void trigger sin unhandled rejection; throw intacto para awaiters) + pin · SEM-3 fallback muerto de applyDominance → skip defensivo + timer tope de awaitExpression cancelado · SEC-1 adjudicado YA implementado (assertCssVariableValue desde 2026-05-11) + pin del path de VALOR. - accordion → outline (§32; su outline:none dejaba CERO anillo en HCM) — verificado en vivo · THM-6 radius-full 9999px · EID-4 recuentos 33. F3 — censos con guard: - SOM-3 cerrado: announcer + image-provider migrados a scheduler-preferred (consumidores cableados: date/time-field vía soma.uix.timers; avatar/image vía eidos.timers — verificado en vivo); guard de timers ENSANCHADO de soma/components a TODO soma y pasado a EVIDENCIA (setTimeout exige .schedule( en el fichero — layers/ y datetime/ escapaban del ámbito viejo). - THM-5: R-4.7 nueva (válvula same-line /* important: <razón> */, escaneo comment-blanked) + las 15 declaraciones anotadas con su razón + canon recipe-contract §3/§4. - SOM-4 adjudicado: el censo/guard YA existían (49 pins); knob/mask-field/ timeline pinneados (overrides documentados en call-site); media-player Batch-4 (35 hits, cero renderProps) = único batch restante, registrado. - THM-4 doctrinado en eidos.md §unused (comportamiento/composición = legítimo; deuda = eje visual sin consumidor; hotspots por lotes). F4-C — corpus documental (decisiones de usuario aplicadas): - DOC-3: los 15 enlaces muertos resueltos (repoint a la edición FINAL trackeada / des-link históricos) · docs:check I6-links WARN→ERROR. - DOC-1: tabla «Build contract» MIGRADA a component-guide con estados modernizados (A3–A5 → LIVE + guards de hoy); banners reapuntados; citas de CANON/sema.md historificadas; lápida-redirect en el §13 del fósil. - DOC-4: hold chain → holds.ts · FAQ event:* SUPERSEDED por signatures · gradient añadido a los DOS capstones (sextet real) · nota de paleta de demo-authoring corregida (universalPaletteDecls + decisión THM-2 = mecanismo universal como sucesor del tracker borrado). - DOC-5/6: recuentos anti-frágiles datados · §4.11 dup → §4.12 · Known gaps historificado · N-6/N-7 recuperadas de git (d68d2c45^) y canonizadas en eidos.md §pickers · authoring E2 → canon/tsc.md · air-old des-linkado · EID-3 (placement) en la fila RTL · AUX-2 disabledDom documentado. SEM-4 sesión 1 — el close polimórfico de los pickers, VIVO (D.11): - Reconciliación: los morfos ya no declaran close (delegated al Popover, de-dialoged 06-27); el agujero real era el cierre programático bypaseando dismissWith → save/cancel/select eran perceptualmente SILENCIOSOS. - Fix: PickerShellHandle.setPopoverDismiss + closeWith(cause) en los 5 providers (14 sitios; select/commit → 'save' = commit.save+fulfill, cancel → 'cancel' = emerge; fallback raw para headless) + UN inyector en el eidos PickerShell root (norma N-8). Picker genérico fuera a propósito (ya suena commit-set/cancel por diseño S9). - Verificado en vivo (date-picker): Done → close·commit·fulfill·active · Cancel → close·emerge · cierre real. Gates: matriz 141/141 (los 6 morfos nuevos de la pista de texto paralela también PASS) · contracts 38/38 · eidos 314 · sema 178 · morfo 94 · docs:check 0/0 con I6 en error · baseline propio 57. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
Two assignment rules the catalog already practiced consistently. THIS section
is the canonical registry; they were canonized at the component-audit
checkpoint (verdicts C1/C3 — historical record in
feat(audit): component re-audit + fixes P0–P5 (P4 complete, P5 in progress) Re-audit of the whole component catalog at pilot depth (91 fichas + the checkpoint verdicts in docs/audit/components/) and the executed fix packages. - P0–P3: doctrine (sema participation, CANON §3 intent, component-guide §5 + API naming, §32 outline), guards (morfo-vocabulary-check S10/S11d, component-audit A-3.1/A-1.4/S9, eidos-lint classHooks), morfo contracts (role=application removed ×4, aria-selected off the Day, drp translationRef, field data-state prune, pin-input commit-set, media-player renames), 13 new sema packs + 12 morfos family-default → pack. - P4 (N1–N10) COMPLETE: selectionMode (select/combobox/toggle-group/calendar); onValueCommit terminal-callback norm (pin-input/search/password/textarea + date/time/color-field add); typed validation reason + onInvalid (tags-input, css-field); index/onIndexChange (carousel); deselectable; openDelay/ groupSkipDelay; allowCustomValue; defaultValue prune. - P5 (in progress): S1 class-hooks codemod (22 hooks → data-attrs across cropper/button/image-picker/toggle/image-adjustments); S5 outline remnant in field.css; depth pass (data-depth=overlay on tooltip/toast/float-panel); touch-rows (--touch-target token, decoupled ::before hit-slop, area-not-visual, 44 AAA). S6 (Field composition) + S8 (calendar-surface) pending. Verification: errors-outside-(alpha|words|palabras|chronos) == 59 (baseline); morfo-vocabulary-check exit 0; eidos-lint class-hooks/invalid 0 on touched components; per-component vitest suites green. Handoff + remaining plan: docs/process/continue-audit-fixes-2026-07.md Excluded (broken by the N1 rename, left broken per user decision, not staged): words/**, palabras/**, chronos, web/routes/alpha/**. Reconciliation pending: the touch-rows ::before for checkbox/switch reverses changelog §37's earlier pseudo-element rejection (WCAG-overlap) that had routed markers to a labeled-row/Field task — flagged for the user in the handoff. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
[`audit/components/_veredictos.md`](./audit/components/_veredictos.md)):
- **The undo matrix.** Removing an item from a collection
(`commit.unselect`) = **`affirm`** — an active choice, as affirmative as
selecting it (calendar, select, combobox, grid-list, listbox). Un-marking a
binary (the uncheck direction of `commit.toggle`) = **`neutral`**.
Abandoning or clearing (`commit.reset`, `commit.cancel`) = **`neutral`**.
- **Binary toggles — two sanctioned models.** *Mark-done* semantics, where
the direction itself carries the evaluative load, use two static
directional events (checkbox: `commit-toggle-check` affirm /
`commit-toggle-uncheck` neutral). *Mode-switch* semantics, where the weight
depends on WHAT is being switched, use one event with
`intent: { fromProp: 'intent', default: 'neutral' }` so the consumer grades
it (switch, toggle, toggle-group). Choose by the question: does the ON
direction intrinsically mean progress/agreement? → static directional.
Does context decide? → `fromProp`.
---
## 4. Intent policy — `SEMA_FAMILY_POLICY`
Whether intent is *required* is set **per family by policy**, not by the
valenced/transitional split (book ch. 8 §6, ch. 9). Two independent axes, in
[`src/uix/sema/types.ts`](../src/uix/sema/types.ts) (`SEMA_FAMILY_POLICY`):
- **`intentRequirement`** (`'required' | 'optional' | 'forbidden'`) — the
compile-time gate. `'required'` (only `commit` and `signal`) → `intent` is
mandatory in `MorfoEventSemantic`. `'forbidden'` is reserved (no family uses
it today). Drives the `SemaEvent` / `MorfoEventSemantic` discriminated unions.
- **`intentGuidance`** (`'expected' | 'contextual' | 'discouraged'`) — doctrinal
hint, no type effect. `commit`/`signal` = `expected`; `contact` = `discouraged`
(book ch. 22 §11: *"el intent fuerte no debería vivir en el contacto"*); the
rest = `contextual`.
Runtime: `validateSemaEvent` throws when a `required` family is built without
intent.
---
## 5. The evaluable-vs-structural rule
> **The intent lives in the evaluable event (the message), not in the structural
> container (the frame).** (book ch. 9 — *"Qué eventos son mensaje y qué eventos
> son marco"*; restated in Appendix A.)
A modal that opens is `shift.enter-mode` (frame); the warning inside it is
`signal.warn + threat` (message). A spinner is `sustain.progress` (frame); the
failure after it is `commit.fail + risk` (message). Cargar el intent en el marco
es el antipatrón capital (book ch. 34 §5 "Modal rojo", §4 "todo lo que aparece es
alerta").
In the framework this is enforced declaratively: the event that *carries* the
intent declares it in its morfo `events[].semantic.intent`; the frame event does
not. The runtime never infers intent (book **Appendix A**: *"El intent no se
hereda implícitamente… El runtime no debe adivinar. La semántica debe estar
declarada."*). This is exactly the morfo → soma → sema → eidos contract.
---
## 6. Canonical verbs — `SEMA_VERBS`
Verbs concrete the action within a family (book ch. 8 §"niveles", ch. 22–29).
`morfo.events[].semantic.verb` MUST be in its family's set; `events[].name`
should follow `{family}-{verb}[-{variant}]` or `{verb}-{variant}` so sema / sound
/ haptic / eidos can subscribe transversally.
**Executable source of truth:** `SEMA_VERBS` in
[`src/uix/sema/verbs.ts`](../src/uix/sema/verbs.ts) — including the documented
author extensions (e.g. `commit.unselect`, `handle.zoom`, `signal.inform`),
tracked in [decisions/book-deviations.md](./decisions/book-deviations.md).
The book's base verbs, by family:
- `contact` (ch. 22): press · tap · activate · focus · trigger · release
- `commit` (ch. 23): select · toggle · save · submit · confirm · complete · fail · cancel · reset · discard · delete · restore · expire · acknowledge
- `signal` (ch. 24): announce · notify · warn · alert · emphasize · remind
- `handle` (ch. 25): pick · carry · drop · drag · resize · reorder · rotate · scroll
- `emerge` (ch. 26): present · dismiss · open · close · expand · collapse · reveal · hide
- `shift` (ch. 27): enter-mode · exit-mode · navigate · route · step · return · context
- `sustain` (ch. 28): start · progress · loading · waiting · syncing · processing · streaming · pending · retrying · end
- `delegate` (ch. 29): offer · plan · authorize · act · review · escalate · return
Verbs that look like one family but belong to another (book canon): `select` /
`toggle` / `acknowledge` are `commit` (they fix state); `edit` is expressed as
`shift.enter-mode` (régimen change), not a `handle` verb.
---
## 7. Expression channels + the owner split
The book defines **8 expression channels** (book ch. 11–20): tiempo · motion ·
presencia · profundidad · forma · color · sonido · háptica. *"El color expresa el
intent, no lo define"* (ch. 16); *"ningún canal agota la semántica"* — robustness
= a reading that survives the loss of a channel (ch. 19, ch. 33).
The framework **splits these channels by owner** (decision recorded in
[decisions/book-deviations.md](./decisions/book-deviations.md) D.8):
- **sema runtime channels** = `sound` + `haptic` only (the two in
`SemaChannelSignatures`), plus the projected `visual` meta-channel that stamps
`data-event-*` during the hold. `motion`/`color`/`presence`/`depth`/`shape`
were removed from sema.
- **eidos** materializes the visual channels (motion / presence / depth / shape /
color) by reacting in CSS to `data-event-*` + the morfo's state attrs.
So the book's 8 channels are conceptual; at runtime they are owned by different
feat(audit): component re-audit + fixes P0–P5 (P4 complete, P5 in progress) Re-audit of the whole component catalog at pilot depth (91 fichas + the checkpoint verdicts in docs/audit/components/) and the executed fix packages. - P0–P3: doctrine (sema participation, CANON §3 intent, component-guide §5 + API naming, §32 outline), guards (morfo-vocabulary-check S10/S11d, component-audit A-3.1/A-1.4/S9, eidos-lint classHooks), morfo contracts (role=application removed ×4, aria-selected off the Day, drp translationRef, field data-state prune, pin-input commit-set, media-player renames), 13 new sema packs + 12 morfos family-default → pack. - P4 (N1–N10) COMPLETE: selectionMode (select/combobox/toggle-group/calendar); onValueCommit terminal-callback norm (pin-input/search/password/textarea + date/time/color-field add); typed validation reason + onInvalid (tags-input, css-field); index/onIndexChange (carousel); deselectable; openDelay/ groupSkipDelay; allowCustomValue; defaultValue prune. - P5 (in progress): S1 class-hooks codemod (22 hooks → data-attrs across cropper/button/image-picker/toggle/image-adjustments); S5 outline remnant in field.css; depth pass (data-depth=overlay on tooltip/toast/float-panel); touch-rows (--touch-target token, decoupled ::before hit-slop, area-not-visual, 44 AAA). S6 (Field composition) + S8 (calendar-surface) pending. Verification: errors-outside-(alpha|words|palabras|chronos) == 59 (baseline); morfo-vocabulary-check exit 0; eidos-lint class-hooks/invalid 0 on touched components; per-component vitest suites green. Handoff + remaining plan: docs/process/continue-audit-fixes-2026-07.md Excluded (broken by the N1 rename, left broken per user decision, not staged): words/**, palabras/**, chronos, web/routes/alpha/**. Reconciliation pending: the touch-rows ::before for checkbox/switch reverses changelog §37's earlier pseudo-element rejection (WCAG-overlap) that had routed markers to a labeled-row/Field task — flagged for the user in the handoff. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
layers. `hold` (the registration FLOOR — a minimum, never a ceiling: the
expression completes before unstamping, capped only by the channel's
engineering guard) resolves per family + intent from `SEMA_HOLDS_BY_INTENT`
([`holds.ts`](../src/uix/sema/holds.ts) — the single hold source since
2026-07-06; the duplicated per-family `SEMA_MAP` hold was removed) over the
`SEMA_DURATIONS` scale (glimpse / brief / settled / noticed / …). The ms are
the framework's MATERIALIZATION of the book's qualitative regions (cap. 32,
TABLA 32.1/32.2 — the book deliberately gives no numbers); see
[decisions/book-deviations.md](./decisions/book-deviations.md) D.12.
Persistence (lifecycle) is separate — `SignalPersistence` in
[`types.ts`](../src/uix/sema/types.ts) (book ch. 12 §6, ch. 4 §13: la huella
se declara).
---
## 8. Composition rules
Real interaction is a temporal composition of events, not one family (book ch. 30,
ch. 6 §13). The rules are derived from perceptual need, not decree (ch. 30 §3):
1. **contact precedes the result** when there is direct action (agency).
2. **sustain precedes commit** when there is a wait (continuity).
3. **threat precedes loss** — never `commit.delete + threat` (before/after the
consequence).
4. **emerge does not absorb the content's intent** — `emerge.open → signal.warn +
risk`, not `emerge.open + risk` (frame ≠ message).
5. **shift must orient** the context change (focus + title + landmark).
6. **handle concentrates evaluation on the drop**, not the carry.
7. **every open process needs an exit** (commit / cancel / fail / persisted-warn).
On simultaneity, attentional dominance (ch. 30 §7): the evaluable event dominates
the structural; higher activation dominates lower; on a tie, the most recent.
---
## 9. Naming + the declarative layer
Name **events, not effects** (book ch. 36): `contact.press`, `commit.save +
affirm`, `signal.warn + risk` — never `redAlert`, `successToast`, `shakeError`.
The grammar is implemented as a **declarative layer above components, tokens and
patterns** (book Appendix A) — in UIX, the **morfo** map:
```
morfo declares → soma executes (runtime.trigger) → sema vocabulary + channels → eidos materializes (reads DOM)
```
Cross-layer vocabularies that anchor this:
- **Archetypes** — cross-component part classification, `ARCHETYPE_VOCABULARY` in
[`src/uix/morfo/types.ts`](../src/uix/morfo/types.ts), emitted as
`data-archetype`.
- **The `data-event-*` tokens** — the contact surface sema stamps and eidos reads
(see [architecture/sema](./architecture/sema.md)).
---
## 10. Visual canon (sibling)
This file is the **semantic** canon. The **visual** canon — the Token Scope
Contract (`--{component}-*` public / `--_{component}-*` internal; never
`--eidos-*`/`--air-*`/`--terra-*`/`--soma-*`), the 9 color roles, the size scale,
and the variant vocabulary (`EIDOS_VARIANTS`) — lives in
[eidos/THEMING.md](./theming/reference.md) §4–7 and
[eidos/lib/types.ts](../src/uix/eidos/lib/types.ts). Variants are eidos canon, not
theme (THEMING §19): a theme re-tints what is perceptually fixed; it does not
invent families, intents or variants.
---
## Sources
fix(cleanroom): F2+F3+F4-C+SEM-4s1 — lote mecánico, censos con guard, corpus documental y el close polimórfico de los pickers VIVO F2 — lote mecánico (13 ítems): - DEP-2 ogl eliminado (0 imports) · DEP-1 clsx inlineado como toClassString propio + suite de contrato (props.test.ts; soma.md §12 cerrado). - THM-7: los 5 selectores manuales de sema.md reescritos con semaSelector (los ejemplos [data-toast-root] apuntaban a un part INEXISTENTE — la deriva que el builder previene, demostrada en el propio doc). - MOR-1 escape isomorfo + validación de attr-names en semaSelector + 9 tests (selectors.test.ts, matches() real con comillas/corchetes) · MOR-2 partMarkerAttr = única fuente compilador↔builder + test de paridad · MOR-3 _resetCompileCache borrado (0 usos). - SOM-2 keydown continue en match sin handler + keyboardFixtureMorfo · SOM-1 no-await de handlers (censo async = 0; contrato V1 cumplido) + pin. - SEM-2 trigger pre-attacha catch con logger (void trigger sin unhandled rejection; throw intacto para awaiters) + pin · SEM-3 fallback muerto de applyDominance → skip defensivo + timer tope de awaitExpression cancelado · SEC-1 adjudicado YA implementado (assertCssVariableValue desde 2026-05-11) + pin del path de VALOR. - accordion → outline (§32; su outline:none dejaba CERO anillo en HCM) — verificado en vivo · THM-6 radius-full 9999px · EID-4 recuentos 33. F3 — censos con guard: - SOM-3 cerrado: announcer + image-provider migrados a scheduler-preferred (consumidores cableados: date/time-field vía soma.uix.timers; avatar/image vía eidos.timers — verificado en vivo); guard de timers ENSANCHADO de soma/components a TODO soma y pasado a EVIDENCIA (setTimeout exige .schedule( en el fichero — layers/ y datetime/ escapaban del ámbito viejo). - THM-5: R-4.7 nueva (válvula same-line /* important: <razón> */, escaneo comment-blanked) + las 15 declaraciones anotadas con su razón + canon recipe-contract §3/§4. - SOM-4 adjudicado: el censo/guard YA existían (49 pins); knob/mask-field/ timeline pinneados (overrides documentados en call-site); media-player Batch-4 (35 hits, cero renderProps) = único batch restante, registrado. - THM-4 doctrinado en eidos.md §unused (comportamiento/composición = legítimo; deuda = eje visual sin consumidor; hotspots por lotes). F4-C — corpus documental (decisiones de usuario aplicadas): - DOC-3: los 15 enlaces muertos resueltos (repoint a la edición FINAL trackeada / des-link históricos) · docs:check I6-links WARN→ERROR. - DOC-1: tabla «Build contract» MIGRADA a component-guide con estados modernizados (A3–A5 → LIVE + guards de hoy); banners reapuntados; citas de CANON/sema.md historificadas; lápida-redirect en el §13 del fósil. - DOC-4: hold chain → holds.ts · FAQ event:* SUPERSEDED por signatures · gradient añadido a los DOS capstones (sextet real) · nota de paleta de demo-authoring corregida (universalPaletteDecls + decisión THM-2 = mecanismo universal como sucesor del tracker borrado). - DOC-5/6: recuentos anti-frágiles datados · §4.11 dup → §4.12 · Known gaps historificado · N-6/N-7 recuperadas de git (d68d2c45^) y canonizadas en eidos.md §pickers · authoring E2 → canon/tsc.md · air-old des-linkado · EID-3 (placement) en la fila RTL · AUX-2 disabledDom documentado. SEM-4 sesión 1 — el close polimórfico de los pickers, VIVO (D.11): - Reconciliación: los morfos ya no declaran close (delegated al Popover, de-dialoged 06-27); el agujero real era el cierre programático bypaseando dismissWith → save/cancel/select eran perceptualmente SILENCIOSOS. - Fix: PickerShellHandle.setPopoverDismiss + closeWith(cause) en los 5 providers (14 sitios; select/commit → 'save' = commit.save+fulfill, cancel → 'cancel' = emerge; fallback raw para headless) + UN inyector en el eidos PickerShell root (norma N-8). Picker genérico fuera a propósito (ya suena commit-set/cancel por diseño S9). - Verificado en vivo (date-picker): Done → close·commit·fulfill·active · Cancel → close·emerge · cierre real. Gates: matriz 141/141 (los 6 morfos nuevos de la pista de texto paralela también PASS) · contracts 38/38 · eidos 314 · sema 178 · morfo 94 · docs:check 0/0 con I6 en error · baseline propio 57. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
- **Book** — [`docs/Disenando_lo_que_ocurre_FINAL.pdf`](./Disenando_lo_que_ocurre_FINAL.pdf)
(FINAL edition, 426 pp. — the canonical anchor, tracked in-repo; chapter map
in [`book-map.md`](./book-map.md)): families ch. 8 + 21–29 · intents
ch. 9–10 · channels ch. 11–20 · composition ch. 30 · matrices ch. 31 ·
ranges ch. 32 · accessibility ch. 19 + 33 · validation ch. 35 ·
theory→system ch. 36 · declarative layer Appendix A.
- **Code** — `verbs.ts` (`SEMA_VERBS`) · `types.ts` (`SemaFamily`,
`SEMA_FAMILY_POLICY`, `SignalPersistence`) · `intent.ts` (`INTENTS`) ·
`sema-map.ts` (`SEMA_MAP`) · `morfo/types.ts` (`ARCHETYPE_VOCABULARY`).
- **Deviations from the book** — [`decisions/book-deviations.md`](./decisions/book-deviations.md).

Powered by TurnKey Linux.