|
|
---
|
|
|
title: UIX Semantic Canon
|
|
|
type: canon
|
|
|
audience: human + agent
|
|
|
authority: canonical — single source of truth for the semantic vocabulary
|
|
|
status: current
|
|
|
sources:
|
|
|
book: docs/Disenando_lo_que_ocurre_v2_3.md ("Diseñando lo que ocurre", v2.3)
|
|
|
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.
|
|
|
|
|
|
Two anchors hold this canon honest:
|
|
|
|
|
|
- **The book** — `docs/Disenando_lo_que_ocurre_v2_3.md` ("Diseñando lo que
|
|
|
ocurre", v2.3). 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`.
|
|
|
|
|
|
---
|
|
|
|
|
|
## 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 [LIBRO_VARIACIONES_Y_EXTENSIONES.md](../src/docs/LIBRO_VARIACIONES_Y_EXTENSIONES.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
|
|
|
[LIBRO_VARIACIONES](../src/docs/LIBRO_VARIACIONES_Y_EXTENSIONES.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
|
|
|
layers. `hold` (minimum perceptible duration) is per-family in
|
|
|
`SEMA_MAP.families[*].hold` over the `SEMA_DURATIONS` scale (glimpse / brief /
|
|
|
noticed / …). Persistence (lifecycle) is separate — `SignalPersistence` in
|
|
|
[`types.ts`](../src/uix/sema/types.ts) (book ch. 12 §6).
|
|
|
|
|
|
---
|
|
|
|
|
|
## 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
|
|
|
|
|
|
- **Book** — [`docs/Disenando_lo_que_ocurre_v2_3.md`](./Disenando_lo_que_ocurre_v2_3.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** — [`src/docs/LIBRO_VARIACIONES_Y_EXTENSIONES.md`](../src/docs/LIBRO_VARIACIONES_Y_EXTENSIONES.md).
|