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

329 lines
16 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

---
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_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.
> **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:
- **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`.
### Intent assignment — undo matrix and binary toggles (framework materialization, 2026-07-07)
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
[`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.
**How each channel is AUTHORED** — the owner split says who materializes a
channel; this says what a component actually WRITES, which is the part authors
get wrong:
| Channel | The component writes | Where the values live |
| --- | --- | --- |
| visual (motion / color / presence / depth / shape) | nothing — it declares the EVENT; eidos reacts in CSS to `data-event-*` | eidos recipes + the token engines |
| `sound` | **one NAME**: `sound: 'soft'` — a key of `SOUNDS`, or `SILENT` | [`sound-names.ts`](../src/uix/sema/sound-names.ts), the single catalogue |
| `haptic` | a categorical `kind` (`tick` / `tap` / `pulse` / `success` / …) | `HapticChannel` maps kinds to patterns |
The rule is the same in all three rows and it is the point: **a component says
WHAT occurs, never how loud, how bright or how long.** The sound row was the
exception until 2026-08-06 — packs carried an open bag of eight continuous
axes, 43 % of the rules said nothing but a volume, and 69 of them erased the
contour the intent had just set. It is now a word, enforced by the type.
Adding a sound means **adding a NAME to the catalogue**, never widening a rule:
made once, in one file, where the next component reuses it. Detail and the
resolution order in [architecture/sema.md](./architecture/sema.md); what a
`.wav` can and cannot carry (the intent only moves its LEVEL — physics, not
policy) in [decisions/book-deviations.md](./decisions/book-deviations.md) D.7,
retired but kept for that measurement.
So the book's 8 channels are conceptual; at runtime they are owned by different
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
- **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.