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/src/uix/sema/validation.ts

53 lines
1.7 KiB

import { isSemaEvent, isSemaEventLabel, isIntent, isIntentBinding } from './event'
import { SemaInvariantError } from './errors'
import { SEMA_FAMILY_POLICY, type SemaActionEvent, type IntentBinding } from './types'
export { SemaInvariantError } from './errors'
export function validateIntentBinding(binding: IntentBinding, ctx = 'sema.intent'): void {
if (!isIntentBinding(binding)) {
throw new SemaInvariantError(`${ctx} is not a valid IntentBinding`)
}
const supported = binding.supported ?? []
if (supported.length === 0) return
for (const intent of supported) {
if (!isIntent(intent)) {
throw new SemaInvariantError(`${ctx}: intent "${String(intent)}" is not a valid Intent`)
}
}
if (!supported.includes(binding.default)) {
throw new SemaInvariantError(
`${ctx}: default intent "${binding.default}" must be included in supported intents`
)
}
}
export function validateSemaEvent(event: SemaActionEvent, ctx = 'sema.event'): void {
if (isSemaEventLabel(event)) return
if (!isSemaEvent(event)) {
throw new SemaInvariantError(`${ctx} is not a valid canonical semantic event`)
}
sema/morfo/eidos: typed selector builder + dialog wrapper + emerge color sema architecture - sema-map: 5-channel registry (motion / sound / color / presence / haptic) via SemaChannelSignatures declaration merging; engine stamps data-event-* tokens; flat CSS-style cascade replaces the eventLabel-overrides middle layer. - sema-map: emerge family gains base.color so intent deltas can shift hue / saturation / intensity. Without a base, the resolver was skipping the channel and Dialog open with intent='threat' rendered as neutral blue in the Sema tab visualisation. - types: SEMA_FAMILY_POLICY const drives compile-time + runtime intent requirements per family. Object shape so future per-family policy fields fit alongside. Emerge events MAY now declare intent (canon update — a Dialog confirming threat carries it in its very appearance). - chans: rename vibra→haptic, add HapticChannel V1 (Vibration API); SoundChannel eager-init on first user gesture (autoplay race fix). morfo selector discipline - morfo/selectors.ts (new): semaSelector(morfo, partKebab, matchers?) — type-checked against morfo.parts and morfo.events. Sema cascade rules MUST use it; hand-written strings are an architecture violation that breaks silently when morfo renames a part. - dialog morfo: open carries intent via fromProp; close-cancel / close-dismiss / close-dismiss-outside drop intent (cancellation has no evaluative load); close-save stays hardcoded fulfill (commit fulfils the user's decision regardless of dialog context). eidos dialog migration (4th pilot) - eidos/components/dialog/: full subdirectory wrapper — flat <Dialog> + compound Provider/Trigger/Overlay/Content/Title/Description/Close/Header/ Footer; size + position responsive props; sheet auto-form on narrow viewports; closePosition for the auto-X. - sema/components/dialog.ts: cascade rules use semaSelector(dialogMorfo, 'content', matchers?). Intent block adds character (haptic kind / pattern) but never overrides pitch / gain / contour — those are intent.deltas signature ownership and overriding flattens per-intent perceptual difference. demo controls + dialog page - src/lib/_demo (DemoSwitch / DemoEnum / DemoText / DemoRange) — unified controls reused across all component demos. - web/routes/dialog: live preview always rendered above tabs; per-event Sema tab with independent intent probe; signature visualisation + Play buttons with fallback target chain. documentation - CLAUDE.md: intent.deltas signature ownership rule; eidos drift defense doctrine (types over lint); 2026-05-09 hand-off entry. - morfo/README: Typed selector builder section. - eidos/README: linter section reframed as opt-in safety net for plain CSS recipes; the architectural mechanism is compile-time typing. - sema/README: open channel registry + flat cascade docs + override semantics + intent policy const + selector builder discipline. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
const intent = 'intent' in event ? event.intent : undefined
refactor(sema/docs): apply author's evaluation — status classification + intentRequirement/intentGuidance split Two changes in one commit: 1. **Doctrina del autor sobre el documento de variaciones** The author evaluated LIBRO_VARIACIONES_Y_EXTENSIONES.md and gave per- entry verdicts. The doc is now rebranded, restructured, and classified: - Renamed: "Registro de desviaciones entre implementación y canon editorial". Disclaimer at top: not the book, internal registry only. - Formal status classification (BOOK_CANON / PROJECT_CANON / CANDIDATE / LOCAL_EXTENSION / DEPRECATED / ALIAS / IMPLEMENTATION_CONTRACT). - Per-entry verdicts assigned per author's evaluation. Author's doctrinal texts included verbatim where given. - A.6 split per verb (was a single bullet for apply/partial/block/ move/upload; now each has its own status: apply=BOOK_CANON, move=BOOK_CANON, upload/partial/block=CANDIDATE). - A.6/A.7 ordering fixed (commit.unselect now A.11 — terminal). - C.3 split into C.3.a (renames mecánicos) y C.3.b (correcciones doctrinales — command intent shift). - E (resumen ejecutivo) actualizado: clear/unselect movidos a resueltos (estaban contradiciéndose). Pendientes reales listados. - F + new section G ("Anti-mezclas") con disciplina sobre el doc. 2. **Family policy: split `intentPolicy` en `intentRequirement` + `intentGuidance`** (D.3 del doc). La policy actual `'allowed' | 'expected' | 'optional'` mezclaba dos ejes que el autor pidió separar: - `intentRequirement: 'required' | 'optional' | 'forbidden'` — compile-time type constraint. - `intentGuidance: 'expected' | 'contextual' | 'discouraged'` — guía doctrinal sin efecto en tipos. Policy nueva: | family | requirement | guidance | |----------|-------------|--------------| | contact | optional | discouraged | (Cap 22 §11) | commit | required | expected | | signal | required | expected | | handle | optional | contextual | | emerge | optional | contextual | | shift | optional | contextual | | sustain | optional | contextual | | delegate | optional | contextual | (Cap 29 §4) `IntentExpectedFamily` deprecated → `IntentRequiredFamily` (alias mantenido). `IntentPolicy` type también deprecated. Consumers actualizados: event.ts (isSemaEvent usa requirement), validation.ts (validateSemaEvent usa requirement), event.test.ts (tests usan ambos campos), dialog.ts (comment doc update). 3. **Bug menor encontrado en `SEMA_TRANSITIONAL_FAMILIES`**: faltaba `delegate`. Añadido. (Era inconsistente con SemaTransitionalFamily type que sí lo incluye.) Verification: - vitest src/uix/sema src/uix/morfo: 195/195 pass - morfo:vocabulary: 7 warns (todos words/*, separate dev track) - EXIT 0 Pendiente futuro (no en este commit): - Añadir flag `emission` a MorfoEvent type per D.2 (eventos declarados pero no emitidos) - Re-evaluar verbos CANDIDATE (acknowledge/confirm/upload/partial/ block) cuando aparezcan más casos de uso Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
// Policy enforcement: families marked `intentRequirement: 'required'` MUST
sema/morfo/eidos: typed selector builder + dialog wrapper + emerge color sema architecture - sema-map: 5-channel registry (motion / sound / color / presence / haptic) via SemaChannelSignatures declaration merging; engine stamps data-event-* tokens; flat CSS-style cascade replaces the eventLabel-overrides middle layer. - sema-map: emerge family gains base.color so intent deltas can shift hue / saturation / intensity. Without a base, the resolver was skipping the channel and Dialog open with intent='threat' rendered as neutral blue in the Sema tab visualisation. - types: SEMA_FAMILY_POLICY const drives compile-time + runtime intent requirements per family. Object shape so future per-family policy fields fit alongside. Emerge events MAY now declare intent (canon update — a Dialog confirming threat carries it in its very appearance). - chans: rename vibra→haptic, add HapticChannel V1 (Vibration API); SoundChannel eager-init on first user gesture (autoplay race fix). morfo selector discipline - morfo/selectors.ts (new): semaSelector(morfo, partKebab, matchers?) — type-checked against morfo.parts and morfo.events. Sema cascade rules MUST use it; hand-written strings are an architecture violation that breaks silently when morfo renames a part. - dialog morfo: open carries intent via fromProp; close-cancel / close-dismiss / close-dismiss-outside drop intent (cancellation has no evaluative load); close-save stays hardcoded fulfill (commit fulfils the user's decision regardless of dialog context). eidos dialog migration (4th pilot) - eidos/components/dialog/: full subdirectory wrapper — flat <Dialog> + compound Provider/Trigger/Overlay/Content/Title/Description/Close/Header/ Footer; size + position responsive props; sheet auto-form on narrow viewports; closePosition for the auto-X. - sema/components/dialog.ts: cascade rules use semaSelector(dialogMorfo, 'content', matchers?). Intent block adds character (haptic kind / pattern) but never overrides pitch / gain / contour — those are intent.deltas signature ownership and overriding flattens per-intent perceptual difference. demo controls + dialog page - src/lib/_demo (DemoSwitch / DemoEnum / DemoText / DemoRange) — unified controls reused across all component demos. - web/routes/dialog: live preview always rendered above tabs; per-event Sema tab with independent intent probe; signature visualisation + Play buttons with fallback target chain. documentation - CLAUDE.md: intent.deltas signature ownership rule; eidos drift defense doctrine (types over lint); 2026-05-09 hand-off entry. - morfo/README: Typed selector builder section. - eidos/README: linter section reframed as opt-in safety net for plain CSS recipes; the architectural mechanism is compile-time typing. - sema/README: open channel registry + flat cascade docs + override semantics + intent policy const + selector builder discipline. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
// declare intent.
if (
intent === undefined &&
refactor(sema/docs): apply author's evaluation — status classification + intentRequirement/intentGuidance split Two changes in one commit: 1. **Doctrina del autor sobre el documento de variaciones** The author evaluated LIBRO_VARIACIONES_Y_EXTENSIONES.md and gave per- entry verdicts. The doc is now rebranded, restructured, and classified: - Renamed: "Registro de desviaciones entre implementación y canon editorial". Disclaimer at top: not the book, internal registry only. - Formal status classification (BOOK_CANON / PROJECT_CANON / CANDIDATE / LOCAL_EXTENSION / DEPRECATED / ALIAS / IMPLEMENTATION_CONTRACT). - Per-entry verdicts assigned per author's evaluation. Author's doctrinal texts included verbatim where given. - A.6 split per verb (was a single bullet for apply/partial/block/ move/upload; now each has its own status: apply=BOOK_CANON, move=BOOK_CANON, upload/partial/block=CANDIDATE). - A.6/A.7 ordering fixed (commit.unselect now A.11 — terminal). - C.3 split into C.3.a (renames mecánicos) y C.3.b (correcciones doctrinales — command intent shift). - E (resumen ejecutivo) actualizado: clear/unselect movidos a resueltos (estaban contradiciéndose). Pendientes reales listados. - F + new section G ("Anti-mezclas") con disciplina sobre el doc. 2. **Family policy: split `intentPolicy` en `intentRequirement` + `intentGuidance`** (D.3 del doc). La policy actual `'allowed' | 'expected' | 'optional'` mezclaba dos ejes que el autor pidió separar: - `intentRequirement: 'required' | 'optional' | 'forbidden'` — compile-time type constraint. - `intentGuidance: 'expected' | 'contextual' | 'discouraged'` — guía doctrinal sin efecto en tipos. Policy nueva: | family | requirement | guidance | |----------|-------------|--------------| | contact | optional | discouraged | (Cap 22 §11) | commit | required | expected | | signal | required | expected | | handle | optional | contextual | | emerge | optional | contextual | | shift | optional | contextual | | sustain | optional | contextual | | delegate | optional | contextual | (Cap 29 §4) `IntentExpectedFamily` deprecated → `IntentRequiredFamily` (alias mantenido). `IntentPolicy` type también deprecated. Consumers actualizados: event.ts (isSemaEvent usa requirement), validation.ts (validateSemaEvent usa requirement), event.test.ts (tests usan ambos campos), dialog.ts (comment doc update). 3. **Bug menor encontrado en `SEMA_TRANSITIONAL_FAMILIES`**: faltaba `delegate`. Añadido. (Era inconsistente con SemaTransitionalFamily type que sí lo incluye.) Verification: - vitest src/uix/sema src/uix/morfo: 195/195 pass - morfo:vocabulary: 7 warns (todos words/*, separate dev track) - EXIT 0 Pendiente futuro (no en este commit): - Añadir flag `emission` a MorfoEvent type per D.2 (eventos declarados pero no emitidos) - Re-evaluar verbos CANDIDATE (acknowledge/confirm/upload/partial/ block) cuando aparezcan más casos de uso Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
SEMA_FAMILY_POLICY[event.family].intentRequirement === 'required'
sema/morfo/eidos: typed selector builder + dialog wrapper + emerge color sema architecture - sema-map: 5-channel registry (motion / sound / color / presence / haptic) via SemaChannelSignatures declaration merging; engine stamps data-event-* tokens; flat CSS-style cascade replaces the eventLabel-overrides middle layer. - sema-map: emerge family gains base.color so intent deltas can shift hue / saturation / intensity. Without a base, the resolver was skipping the channel and Dialog open with intent='threat' rendered as neutral blue in the Sema tab visualisation. - types: SEMA_FAMILY_POLICY const drives compile-time + runtime intent requirements per family. Object shape so future per-family policy fields fit alongside. Emerge events MAY now declare intent (canon update — a Dialog confirming threat carries it in its very appearance). - chans: rename vibra→haptic, add HapticChannel V1 (Vibration API); SoundChannel eager-init on first user gesture (autoplay race fix). morfo selector discipline - morfo/selectors.ts (new): semaSelector(morfo, partKebab, matchers?) — type-checked against morfo.parts and morfo.events. Sema cascade rules MUST use it; hand-written strings are an architecture violation that breaks silently when morfo renames a part. - dialog morfo: open carries intent via fromProp; close-cancel / close-dismiss / close-dismiss-outside drop intent (cancellation has no evaluative load); close-save stays hardcoded fulfill (commit fulfils the user's decision regardless of dialog context). eidos dialog migration (4th pilot) - eidos/components/dialog/: full subdirectory wrapper — flat <Dialog> + compound Provider/Trigger/Overlay/Content/Title/Description/Close/Header/ Footer; size + position responsive props; sheet auto-form on narrow viewports; closePosition for the auto-X. - sema/components/dialog.ts: cascade rules use semaSelector(dialogMorfo, 'content', matchers?). Intent block adds character (haptic kind / pattern) but never overrides pitch / gain / contour — those are intent.deltas signature ownership and overriding flattens per-intent perceptual difference. demo controls + dialog page - src/lib/_demo (DemoSwitch / DemoEnum / DemoText / DemoRange) — unified controls reused across all component demos. - web/routes/dialog: live preview always rendered above tabs; per-event Sema tab with independent intent probe; signature visualisation + Play buttons with fallback target chain. documentation - CLAUDE.md: intent.deltas signature ownership rule; eidos drift defense doctrine (types over lint); 2026-05-09 hand-off entry. - morfo/README: Typed selector builder section. - eidos/README: linter section reframed as opt-in safety net for plain CSS recipes; the architectural mechanism is compile-time typing. - sema/README: open channel registry + flat cascade docs + override semantics + intent policy const + selector builder discipline. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
) {
throw new SemaInvariantError(
refactor(sema/docs): apply author's evaluation — status classification + intentRequirement/intentGuidance split Two changes in one commit: 1. **Doctrina del autor sobre el documento de variaciones** The author evaluated LIBRO_VARIACIONES_Y_EXTENSIONES.md and gave per- entry verdicts. The doc is now rebranded, restructured, and classified: - Renamed: "Registro de desviaciones entre implementación y canon editorial". Disclaimer at top: not the book, internal registry only. - Formal status classification (BOOK_CANON / PROJECT_CANON / CANDIDATE / LOCAL_EXTENSION / DEPRECATED / ALIAS / IMPLEMENTATION_CONTRACT). - Per-entry verdicts assigned per author's evaluation. Author's doctrinal texts included verbatim where given. - A.6 split per verb (was a single bullet for apply/partial/block/ move/upload; now each has its own status: apply=BOOK_CANON, move=BOOK_CANON, upload/partial/block=CANDIDATE). - A.6/A.7 ordering fixed (commit.unselect now A.11 — terminal). - C.3 split into C.3.a (renames mecánicos) y C.3.b (correcciones doctrinales — command intent shift). - E (resumen ejecutivo) actualizado: clear/unselect movidos a resueltos (estaban contradiciéndose). Pendientes reales listados. - F + new section G ("Anti-mezclas") con disciplina sobre el doc. 2. **Family policy: split `intentPolicy` en `intentRequirement` + `intentGuidance`** (D.3 del doc). La policy actual `'allowed' | 'expected' | 'optional'` mezclaba dos ejes que el autor pidió separar: - `intentRequirement: 'required' | 'optional' | 'forbidden'` — compile-time type constraint. - `intentGuidance: 'expected' | 'contextual' | 'discouraged'` — guía doctrinal sin efecto en tipos. Policy nueva: | family | requirement | guidance | |----------|-------------|--------------| | contact | optional | discouraged | (Cap 22 §11) | commit | required | expected | | signal | required | expected | | handle | optional | contextual | | emerge | optional | contextual | | shift | optional | contextual | | sustain | optional | contextual | | delegate | optional | contextual | (Cap 29 §4) `IntentExpectedFamily` deprecated → `IntentRequiredFamily` (alias mantenido). `IntentPolicy` type también deprecated. Consumers actualizados: event.ts (isSemaEvent usa requirement), validation.ts (validateSemaEvent usa requirement), event.test.ts (tests usan ambos campos), dialog.ts (comment doc update). 3. **Bug menor encontrado en `SEMA_TRANSITIONAL_FAMILIES`**: faltaba `delegate`. Añadido. (Era inconsistente con SemaTransitionalFamily type que sí lo incluye.) Verification: - vitest src/uix/sema src/uix/morfo: 195/195 pass - morfo:vocabulary: 7 warns (todos words/*, separate dev track) - EXIT 0 Pendiente futuro (no en este commit): - Añadir flag `emission` a MorfoEvent type per D.2 (eventos declarados pero no emitidos) - Re-evaluar verbos CANDIDATE (acknowledge/confirm/upload/partial/ block) cuando aparezcan más casos de uso Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
`${ctx}: family "${event.family}" requires intent (intentRequirement: 'required')`
sema/morfo/eidos: typed selector builder + dialog wrapper + emerge color sema architecture - sema-map: 5-channel registry (motion / sound / color / presence / haptic) via SemaChannelSignatures declaration merging; engine stamps data-event-* tokens; flat CSS-style cascade replaces the eventLabel-overrides middle layer. - sema-map: emerge family gains base.color so intent deltas can shift hue / saturation / intensity. Without a base, the resolver was skipping the channel and Dialog open with intent='threat' rendered as neutral blue in the Sema tab visualisation. - types: SEMA_FAMILY_POLICY const drives compile-time + runtime intent requirements per family. Object shape so future per-family policy fields fit alongside. Emerge events MAY now declare intent (canon update — a Dialog confirming threat carries it in its very appearance). - chans: rename vibra→haptic, add HapticChannel V1 (Vibration API); SoundChannel eager-init on first user gesture (autoplay race fix). morfo selector discipline - morfo/selectors.ts (new): semaSelector(morfo, partKebab, matchers?) — type-checked against morfo.parts and morfo.events. Sema cascade rules MUST use it; hand-written strings are an architecture violation that breaks silently when morfo renames a part. - dialog morfo: open carries intent via fromProp; close-cancel / close-dismiss / close-dismiss-outside drop intent (cancellation has no evaluative load); close-save stays hardcoded fulfill (commit fulfils the user's decision regardless of dialog context). eidos dialog migration (4th pilot) - eidos/components/dialog/: full subdirectory wrapper — flat <Dialog> + compound Provider/Trigger/Overlay/Content/Title/Description/Close/Header/ Footer; size + position responsive props; sheet auto-form on narrow viewports; closePosition for the auto-X. - sema/components/dialog.ts: cascade rules use semaSelector(dialogMorfo, 'content', matchers?). Intent block adds character (haptic kind / pattern) but never overrides pitch / gain / contour — those are intent.deltas signature ownership and overriding flattens per-intent perceptual difference. demo controls + dialog page - src/lib/_demo (DemoSwitch / DemoEnum / DemoText / DemoRange) — unified controls reused across all component demos. - web/routes/dialog: live preview always rendered above tabs; per-event Sema tab with independent intent probe; signature visualisation + Play buttons with fallback target chain. documentation - CLAUDE.md: intent.deltas signature ownership rule; eidos drift defense doctrine (types over lint); 2026-05-09 hand-off entry. - morfo/README: Typed selector builder section. - eidos/README: linter section reframed as opt-in safety net for plain CSS recipes; the architectural mechanism is compile-time typing. - sema/README: open channel registry + flat cascade docs + override semantics + intent policy const + selector builder discipline. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
)
}
// Bindings need structural validation; literals + absence are fine.
if (intent === undefined || typeof intent === 'string') return
validateIntentBinding(intent, `${ctx}.intent`)
}

Powered by TurnKey Linux.