feat(sema/morfo): add commit.unselect to canon + apply to 6 morfos

User doctrinal decision (2026-05-25): add `unselect` as canonical verb of
the commit family. The pair `select` / `unselect` covers results applied
on the selection state of an item — distinct from `toggle` (binary
control flip) and `remove` (retirement from a collection).

Quoting the author:
  "Seleccionar y deseleccionar son resultados aplicados sobre el estado
   de selección de un elemento. Eso es commit, porque el resultado queda
   aplicado.
   - No es remove: no estás eliminando el item ni sacándolo de una
     colección funcional; solo estás cambiando su estado de selección.
   - No es necesariamente toggle: toggle describe mejor el mecanismo
     binario o el control, pero no expresa tan bien el resultado
     semántico concreto."

Changes:
- src/uix/sema/verbs.ts: add `unselect` to SEMA_VERBS.commit after
  `select` (natural pair). Header comment documents the doctrinal
  distinction with toggle and remove.
- 6 morfos updated: calendar, combobox, grid-list, listbox, select,
  tag-group. Each changes `commit-unselect` from
  `verb: 'remove' + intent: 'neutral'` to
  `verb: 'unselect' + intent: 'affirm'`. Names preserved (already
  canonical now). Intent `affirm` because "the action applied
  correctly" (sobrio, not celebratory).
- src/docs/LIBRO_VARIACIONES_Y_EXTENSIONES.md: C.2 marked RESUELTO with
  the full doctrinal reasoning verbatim. A.3 (remove vs delete) updated
  to reflect the three-way distinction now formalized
  (unselect/remove/delete). New A.7 entry for `unselect` itself with
  "para el libro" note (add to Cap 23 §5).

Verification:
- morfo:vocabulary: warns 25 → 19 (-6 unselect cluster), EXIT 0
- vitest src/uix/sema src/uix/morfo: 195/195 pass

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
active-uix
dev 5 months ago
parent 1582572e9b
commit f3641347de

@ -38,15 +38,15 @@ Estos verbos están en `src/uix/sema/verbs.ts:SEMA_VERBS` pero NO aparecen en la
### A.3 `commit.remove` vs `commit.delete` ### A.3 `commit.remove` vs `commit.delete`
- **Status**: `remove` heredado del canon pre-libro. Usado en muchos morfos (calendar, combobox, listbox, select, tag-group, range-calendar...). - **Status**: `remove` heredado del canon pre-libro. Tras la resolución de C.2 (unselect = `commit.unselect`, no `remove`), el verbo `remove` queda **mucho menos usado** — su nicho ahora es solamente "quitar de una colección sin destruir" (ej. removing un item de una lista de favoritos sin eliminarlo del catálogo).
- **Libro Cap 23 §5** lista `delete` (destrucción consumada). **`remove` no aparece.** Cap 23 §6.3: "commit.delete = consecuencia irreversible o crítica". - **Libro Cap 23 §5** lista `delete` (destrucción consumada). **`remove` no aparece.**
- **Decisión**: distinción introducida en el canon: - **Decisión doctrinal del autor (2026-05-25)** — al resolver C.2:
- `remove` = quitar de una colección sin destruir el elemento (deseleccionar opción, quitar tag, retirar de set) - `remove` queda para retirada, eliminación o salida de colección — DISTINTO de unselect (cambio de estado de selección).
- `delete` = destrucción persistente (borrar archivo, eliminar registro) - `delete` queda para destrucción persistente.
- **Argumento**: el libro Cap 23 §6 separa "fijación de estado" (select/toggle) de "consecuencia irreversible" (delete). Quitar de una multi-selección NO es destrucción del item (sigue existiendo en el catálogo), es cambio de estado de pertenencia a un set. - `unselect` queda para estado de selección.
- Los tres verbos son distintos doctrinalmente.
- **Decisión pendiente para el libro**: - **Decisión pendiente para el libro**:
- (a) Formalizar `remove` como verbo distinto de `delete`, con su propia firma perceptiva (sin loss intent, neutral/affirm según contexto). - Formalizar `remove` como verbo distinto de `delete` y de `unselect`, con su propia firma perceptiva (retirada de colección, sin loss intent).
- (b) Unificar bajo `delete` (acepta el matiz "del set") y eliminar `remove` del canon.
### A.4 `commit.confirm` ### A.4 `commit.confirm`
@ -68,6 +68,22 @@ Estos verbos están en `src/uix/sema/verbs.ts:SEMA_VERBS` pero NO aparecen en la
- (a) Formalizar `set` en Cap 23 §5 como verbo canónico (su nicho: aplicar un valor sin que sea persistencia/submit/completion). - (a) Formalizar `set` en Cap 23 §5 como verbo canónico (su nicho: aplicar un valor sin que sea persistencia/submit/completion).
- (b) Mapear set a `apply` (también en uso para delegate.act). - (b) Mapear set a `apply` (también en uso para delegate.act).
### A.7 `commit.unselect` (decisión doctrinal del autor, 2026-05-25)
- **Status**: Añadido al canon como verbo de `commit`. Resuelve C.2 (cluster unselect, 6 componentes).
- **Libro Cap 23 §5** lista `select` pero no `unselect`.
- **Decisión doctrinal del autor** (transcrita literal en C.2):
> Seleccionar y deseleccionar son resultados aplicados sobre el estado de selección de un elemento. Cuando el usuario selecciona, **este item queda seleccionado**. Cuando deselecciona, **este item deja de estar seleccionado**. Eso es `commit`, porque el resultado queda aplicado.
>
> Diferenciación con verbos cercanos:
> - No es `remove` (no se elimina ni se saca de colección, solo cambia estado de selección).
> - No es `toggle` (toggle describe el mecanismo binario; unselect el resultado semántico concreto).
>
> El par natural sobre items seleccionables es `commit.select` / `commit.unselect`. Independiente de modo single/multi.
- **Para el libro**: añadir `unselect` a Cap 23 §5 como verbo canónico. El par `select`/`unselect` cierra la simetría sobre estado de selección de items, distinto de `toggle` (control binario) y `remove` (colección).
### A.6 `commit.apply / partial / block / move / upload` ### A.6 `commit.apply / partial / block / move / upload`
- **Status**: añadidos en Plan B commit 1 desde el libro mismo. - **Status**: añadidos en Plan B commit 1 desde el libro mismo.
@ -163,16 +179,29 @@ Hoy ~35 events siguen como warns en `morfo:vocabulary` porque el verbo declarado
- **Decisión tomada**: `commit.reset` con name canónico `commit-reset` (sin variant — no hay ambigüedad de múltiples resets en ningún componente del cluster). Verbo `'remove'` mal-declarado en range-calendar también corregido a `'reset'`. - **Decisión tomada**: `commit.reset` con name canónico `commit-reset` (sin variant — no hay ambigüedad de múltiples resets en ningún componente del cluster). Verbo `'remove'` mal-declarado en range-calendar también corregido a `'reset'`.
- **Decisión pendiente para el libro**: ninguna. La doctrina del libro literal cubre exactamente el caso. Se podría añadir mención explícita de "clear de un campo" como ejemplo de `commit.reset` en una próxima edición. - **Decisión pendiente para el libro**: ninguna. La doctrina del libro literal cubre exactamente el caso. Se podría añadir mención explícita de "clear de un campo" como ejemplo de `commit.reset` en una próxima edición.
### C.2 "Unselect" como concepto ### C.2 "Unselect" como concepto — RESUELTO añadiendo `unselect` al canon
- **Status**: Resuelto por el autor el 2026-05-25. `unselect` añadido a `SEMA_VERBS.commit` como verbo canónico. Los 6 morfos ahora declaran `verb: 'unselect'`, `intent: 'affirm'`.
- **6 componentes** afectados: calendar, combobox, grid-list, listbox, select, tag-group.
- **Decisión doctrinal del autor** (transcrita literal):
> `select` y `unselect` son resultados aplicados sobre el estado de selección de un elemento. Cuando el usuario selecciona, **este item queda seleccionado**. Cuando deselecciona, **este item deja de estar seleccionado**. Eso es `commit`, porque el resultado queda aplicado.
>
> - No es `contact`, porque no solo se ha recibido el gesto.
> - No es `handle`, porque no hay manipulación continua.
> - No es `remove`, porque no estás eliminando el item ni sacándolo de una colección funcional; solo estás cambiando su estado de selección.
> - No es necesariamente `toggle`, porque `toggle` describe mejor el mecanismo binario o el control, pero no expresa tan bien el resultado semántico concreto.
>
> Regla final:
> - `select` / `unselect` → resultados sobre estado de selección
> - `toggle` → inversión binaria genérica (switch, checkbox como control)
> - `remove` → retirada, eliminación o salida de colección
>
> Independiente de si la lista es single-select o multi-select. En ambos casos, la lectura del usuario es que el item deja de estar seleccionado.
- **6 componentes** usan `commit-unselect`: calendar, combobox, grid-list, listbox, select, tag-group. - **Intent**: `affirm` (la acción se aplicó correctamente, sin celebración).
- **Libro** tiene: `select` (Cap 23, fija una opción), `toggle` (flip binario), `remove` (en canon UIX, no en libro literal). - **Name**: `commit-unselect` se mantiene (el name ya parsea canónico ahora que `unselect` está en `SEMA_VERBS.commit`).
- **Posibles mapeos**: - **Para el libro**: añadir `unselect` a la lista de verbos canónicos de `commit` en Cap 23 §5. El par `select`/`unselect` es el natural sobre estado de selección de items.
- Single-select donde el mismo click deselecciona: `commit.toggle` (estado on/off del item)
- Multi-select donde el click quita uno: `commit.remove` (quitar de la lista de seleccionados)
- **Pregunta para el libro**:
- (a) ¿`unselect` es siempre composición `commit.toggle` o `commit.remove`?
- (b) ¿El libro debe dar guía sobre cuándo es uno u otro?
### C.3 Otros nombres no canónicos (~19 events individuales) ### C.3 Otros nombres no canónicos (~19 events individuales)

@ -24,9 +24,9 @@ export const calendarMorfo = {
name: 'commit-unselect', name: 'commit-unselect',
semantic: { semantic: {
family: 'commit', family: 'commit',
verb: 'remove', verb: 'unselect',
target: v.partRef('day'), target: v.partRef('day'),
intent: 'neutral', intent: 'affirm',
sequence: 'post' sequence: 'post'
} }
}, },

@ -28,9 +28,9 @@ export const comboboxMorfo = {
name: 'commit-unselect', name: 'commit-unselect',
semantic: { semantic: {
family: 'commit', family: 'commit',
verb: 'remove', verb: 'unselect',
target: v.partRef('item'), target: v.partRef('item'),
intent: 'neutral', intent: 'affirm',
sequence: 'post' sequence: 'post'
} }
} }

@ -25,9 +25,9 @@ export const gridListMorfo = {
name: 'commit-unselect', name: 'commit-unselect',
semantic: { semantic: {
family: 'commit', family: 'commit',
verb: 'remove', verb: 'unselect',
target: v.partRef('row'), target: v.partRef('row'),
intent: 'neutral', intent: 'affirm',
sequence: 'post' sequence: 'post'
} }
} }

@ -24,9 +24,9 @@ export const listboxMorfo = {
name: 'commit-unselect', name: 'commit-unselect',
semantic: { semantic: {
family: 'commit', family: 'commit',
verb: 'remove', verb: 'unselect',
target: v.partRef('item'), target: v.partRef('item'),
intent: 'neutral', intent: 'affirm',
sequence: 'post' sequence: 'post'
} }
} }

@ -25,9 +25,9 @@ export const selectMorfo = {
name: 'commit-unselect', name: 'commit-unselect',
semantic: { semantic: {
family: 'commit', family: 'commit',
verb: 'remove', verb: 'unselect',
target: v.partRef('item'), target: v.partRef('item'),
intent: 'neutral', intent: 'affirm',
sequence: 'post' sequence: 'post'
} }
} }

@ -24,9 +24,9 @@ export const tagGroupMorfo = {
name: 'commit-unselect', name: 'commit-unselect',
semantic: { semantic: {
family: 'commit', family: 'commit',
verb: 'remove', verb: 'unselect',
target: v.partRef('item'), target: v.partRef('item'),
intent: 'neutral', intent: 'affirm',
sequence: 'post' sequence: 'post'
} }
}, },

@ -64,9 +64,18 @@ export const SEMA_VERBS = {
contact: ['press', 'tap', 'activate', 'focus', 'trigger', 'release'], contact: ['press', 'tap', 'activate', 'focus', 'trigger', 'release'],
commit: [ commit: [
// Fijación de estado // Fijación de estado de selección — par natural canónico.
// `select` (libro Cap 23) + `unselect` (extensión del autor 2026-05-25):
// resultados aplicados sobre el estado de selección de un elemento.
// "este item queda seleccionado" / "este item deja de estar seleccionado".
// No es `remove` (no se elimina ni se saca de colección, solo cambia
// estado de selección). No es `toggle` (toggle describe inversión
// binaria genérica, no el resultado semántico de selección).
'select', 'select',
'unselect',
// Inversión binaria genérica (switch, checkbox, control on/off).
'toggle', 'toggle',
// Otros fijadores de estado.
'save', 'save',
// Resolución de proceso // Resolución de proceso
'submit', 'submit',

Loading…
Cancel
Save

Powered by TurnKey Linux.