SYS-001 (SUMMARY) resolved + 46 per-component scope-drift findings set to
fixed. The other drifted components annotate the drift in their report header
(not a fix-status finding) or capture it only via the systemic SYS-001, so they
have no per-component line to flip. scroll-area's data-overflow finding is a
distinct undeclared-attr issue (not scope) and stays open.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- impact: The eidos directory at src/uix/eidos/components/calendar/ exists (with calendar.css, components, types.ts), but morfo declares scope as ['soma', 'sema'] without 'eidos'. Per known systemic SYS-1, this is acceptable if the eidos layer is optional or only consumed via composition.
- proposed-fix: Verify with team: is eidos-layer consumption optional? If mandatory, update scope to ['soma', 'sema', 'eidos'].
- verify: [confirmed] Confirmed at calendar.ts:7 `scope: ['soma', 'sema'],` omits 'eidos', yet a full eidos layer exists: recipe block `calendar:` at base.ts:1626 (60+ tokens) AND src/uix/eidos/components/calendar/ contains calendar.css + ~25 .svelte wrappers + recipe consumption. This is exactly the known systemic SYS-1 scope-drift (MEDIUM). The candidate's framing as 'acceptable if optional' is the SYS-1 baseline narrative; the drift itself is real and matches the documented systemic pattern.
- fix-status: open
- fix-status: fixed (212624e0)
### MEDIUM: Magic literal in recipe token: '0.62' opacity not from canonical scale — calendar-004 <!-- id: calendar-004 -->
- verify: [confirmed] Confirmed at src/uix/morfo/components/carousel.ts:7 — `scope: ['soma', 'sema'],` with NO 'eidos', while a full eidos implementation exists: src/uix/eidos/components/carousel/carousel.css is 10912 bytes plus types.ts, context, and 8 visual .svelte wrappers (carousel-item.svelte, carousel-viewport.svelte, etc.). This is exactly the SYS-1 scope-drift pattern: eidos materializes visual/size/variant attrs the morfo scope doesn't declare. Severity MEDIUM is correct (matches baseline). Note this is broadly systemic on this branch — calendar.ts:7, color-picker.ts:7, combobox.ts:7, command.ts:7, dialog.ts:18 and others all declare ['soma','sema'] yet ship eidos dirs — so the fix should likely be a sweep, but the carousel finding stands on its own evidence.
- fix-status: open
- fix-status: fixed (212624e0)
### MEDIUM: SYS-3 (jsdom-only test of interaction-heavy path) — carousel-102 <!-- id: carousel-102 -->
@ -17,7 +17,7 @@ Counts (post-verification): CRITICAL 0 · HIGH 0 · MEDIUM 1 · LOW 2.
- impact: The morfo's declared scope no longer reflects reality: an eidos consumer exists but the contract says only soma+sema. Scope is the declared surface; drift means tooling/audits that read `scope` will under-count the eidos layer.
- proposed-fix: Add 'eidos' to the scope array: `scope: ['soma', 'sema', 'eidos']` (cf. button.ts:47 which declares it). Or — if the project decides hand-authored thin consumer wrappers do NOT count as an eidos recipe — codify that rule, since toggle/switch/collapsible omit it too. This is the confirmed-systemic SYS-1; clipboard matches the majority that omit it.
- verify: [verifier-added] added by adversarial verify pass
- fix-status: open
- fix-status: fixed (212624e0)
### LOW: Recipe spacing MUST reference --space-* tokens; raw rem literals are drift — CLIP-2 <!-- id: CLIP-2 -->
@ -18,7 +18,7 @@ Counts (post-verification): CRITICAL 0 · HIGH 1 · MEDIUM 1 · LOW 0.
- impact: Scope declaration diverges from actual architecture; contract validators may not catch eidos-layer changes. Documentation of morfo scope is stale.
- proposed-fix: Update collapsibleMorfo scope to ['soma', 'sema', 'eidos'] to match accordion pattern and actual directory structure
- verify: [confirmed] CONFIRMED. morfo declares `scope: ['soma', 'sema']` at src/uix/morfo/components/collapsible.ts:22, but src/uix/eidos/components/collapsible/ exists with a full implementation (collapsible.svelte, collapsible.css, collapsible-trigger.svelte, collapsible-content.svelte, types.ts, index.ts, README.md — verified via glob). The sibling disclosure pattern accordion correctly declares `scope: ['soma', 'sema', 'eidos']` at src/uix/morfo/components/accordion.ts:7. This is SYS-1 scope-drift, MEDIUM. Severity unchanged.
- fix-status: open
- fix-status: fixed (212624e0)
### HIGH: SEQUENCE-LAG — `collapse` is `sequence:'pre'` but sets state in the handler (the Checkbox-244ms-lag mechanism) — collapsible-NEW-001 <!-- id: collapsible-NEW-001 -->
- verify: [confirmed] Confirmed SYS-1 scope-drift. morfo/components/color-field.ts:7 `scope: ['soma', 'sema'],` omits 'eidos'; eidos dir src/uix/eidos/components/color-field/ exists with real color-field.css (10039 bytes) + recipe. MEDIUM correct. Systemic across field family (css/date/number/password/search/time-field all do the same).
- impact: Morfo scope contract is incomplete. Downstream tooling expecting strict scope adherence will find undeclared layer.
- proposed-fix: Update morfo scope to ['soma', 'sema', 'eidos']
- verify: [confirmed] Confirmed SYS-1 scope-drift. color-picker.ts:7 reads `scope: ['soma', 'sema'],` yet a full eidos implementation exists at src/uix/eidos/components/color-picker/ (color-picker.css recipe + 25+ .svelte wrappers per Glob). `'eidos'` IS a valid Layer (src/uix/types.ts:17 `export type Layer = 'soma' | 'sema' | 'eidos';`), and morfo `scope: readonly Layer[]` (types.ts:799). date-picker.ts:13 has the identical `scope: ['soma', 'sema']`, so this is the documented systemic SYS-1 across the picker family. MEDIUM is correct.
- impact: Component has eidos visuals and recipes but scope doesn't declare it; scope drift breaks the four-layer contract and may cause issues with validation or tooling that expect declared scopes
- proposed-fix: Add 'eidos' to the scope array: scope: ['soma', 'sema', 'eidos']
- verify: [downgraded] morfo line 7 reads `scope: ['soma', 'sema'],` and an eidos/components/command/ dir with CSS exists. But this is NOT command-specific drift: I counted 63 stateful morfos (combobox, calendar, date-picker, color-picker, dialog, select, popover, listbox, etc.) that ALL omit 'eidos' from scope while shipping an eidos recipe dir. The `scope` field semantics in src/uix/morfo/types.ts:770-839 govern SEMA/event coherence ('If a morfo declares events[] AND scope:['sema']...'), not eidos-recipe presence — the visual layer is not gated by the scope array. No contract test asserts scope must include 'eidos' when CSS exists. Treating this as a HIGH per-component contract violation contradicts the framework's own baseline (63/64 components do it). At most a systemic LOW doc/convention observation; the stated HIGH severity and 'breaks the four-layer contract' impact are not supportable.
- fix-status: open
- fix-status: fixed (212624e0)
### LOW: Magic literal — em font sizes — command-003 <!-- id: command-003 -->
@ -18,7 +18,7 @@ Counts (post-verification): CRITICAL 0 · HIGH 0 · MEDIUM 2 · LOW 1.
- impact: Scope mismatch signals incomplete contract declaration; framework tooling may not validate eidos layer against morfo
- proposed-fix: Update morfo scope to ['soma', 'sema', 'eidos']
- verify: [confirmed] Confirmed SYS-1 scope-drift. morfo cropper.ts:20 `scope: ['soma', 'sema']` omits 'eidos', yet the eidos layer exists: dir src/uix/eidos/components/cropper/ (cropper.css, cropper.svelte, types.ts) AND a recipe `cropper:` at src/uix/eidos/lib/recipes/base.ts:1152. Matches the established systemic baseline (sibling image-picker.ts:20 and image-adjustments.ts:18 carry the same omission). MEDIUM stands.
- fix-status: open
- fix-status: fixed (212624e0)
### MEDIUM: SYS-3: Missing test coverage for high-risk paths (gesture, async, timers) — cropper-003 <!-- id: cropper-003 -->
@ -17,7 +17,7 @@ Counts (post-verification): CRITICAL 0 · HIGH 0 · MEDIUM 1 · LOW 0.
- impact: Contract validator cannot check that eidos wrappers only import from morfo PARTS, risking cross-layer coupling over time as the component evolves
- verify: [confirmed] Confirmed as a SYS-1 scope-drift instance. `css-field.ts:7` = `scope: ['soma', 'sema']` while an eidos dir exists with a wrapper + css (`eidos/components/css-field/css-field.svelte` imports `./css-field.css`, plus `types.ts`/`index.ts`). MEDIUM is correct per the SYS-1 catalog. Caveat for the orchestrator: this is SYSTEMIC across the whole field family, not a css-field anomaly — the project's REFERENCE baseline NumberField is identical (`number-field.ts:7` = `scope: ['soma', 'sema']` with its own eidos dir), as are time-field/color-field/date-field (all `scope: ['soma', 'sema']`). Note also css-field has no dedicated recipe: its eidos css (`css-field.css`) declares 'CssField has no visual of its own: it IS a spin-field' and styling comes from the shared `spin-field` recipe (`base.ts:1016`) via structural identity. The scope-validator gap still stands regardless.
@ -18,7 +18,7 @@ Counts (post-verification): CRITICAL 0 · HIGH 0 · MEDIUM 2 · LOW 0.
- impact: Contract validator may not catch visual-layer rules as part of the component's declared surface area.
- proposed-fix: Update morfo scope from ['soma', 'sema'] to ['soma', 'sema', 'eidos']
- verify: [confirmed] CONFIRMED at MEDIUM. morfo `src/uix/morfo/components/date-field.ts:7` declares `scope: ['soma', 'sema']` (grep verified), while the eidos layer exists: recipe block `'date-field':` at `src/uix/eidos/lib/recipes/base.ts:1172` and CSS `src/uix/eidos/components/date-field/date-field.css` (read in full, 228 lines). This matches the documented systemic SYS-1 scope-drift (MEDIUM). NOTE: the project's stated REFERENCE component NumberField has the IDENTICAL condition — number-field.ts:7 also declares `scope: ['soma', 'sema']` yet `src/uix/eidos/components/number-field/` exists — so this is a true systemic pattern for the field family, not a date-field-specific defect. Severity stays MEDIUM per SYS-1; confidence high that the condition holds, with the caveat that whether 'eidos' is REQUIRED in scope for these components is a project-wide convention question.
- fix-status: open
- fix-status: fixed (212624e0)
### MEDIUM: Test coverage gap (field-family paths) — date-field-003 <!-- id: date-field-003 -->
- impact: Morfo contract mismatches the actual layer composition. Eidos recipes exist but scope doesn't declare them, risking validator confusion and runtime assumptions about which layers are active.
- proposed-fix: Change morfo scope to ['soma', 'sema', 'eidos'] to match the actual directory structure and eidos recipe presence.
- verify: [confirmed] Confirmed as SYS-1 scope-drift. date-picker.ts:13 reads `scope: ['soma', 'sema'],` yet `src/uix/eidos/components/date-picker/` exists with date-picker.css (6115 bytes), date-picker.svelte, types.ts, and several *.svelte wrappers. This is systemic across the whole picker family: color-picker, date-range-picker, time-picker, time-range-picker, calendar all read `scope: ['soma', 'sema']` while their eidos dirs exist; only range-calendar declares eidos. MEDIUM is the correct severity per the SYS-1 baseline — it is a contract/metadata mismatch, not a runtime defect (createAttrs/morfo are unaffected since the morfo is `as const satisfies Morfo` at line 230).
- fix-status: open
- fix-status: fixed (212624e0)
### MEDIUM: INERT EVENTS: morfo declares 'open' event but provider never fires it via runtime.trigger( — date-picker-002 <!-- id: date-picker-002 -->
@ -19,7 +19,7 @@ composition (A27): Composes via A27: PopoverProvider and DateRangeFieldProvider
- impact: Eidos CSS file (date-range-picker.css) exists and is imported in eidos component (line 8) but no canonical recipe tokens/config define size/color/variant scales for this component; recipes are the contract bridge for eidos.
- proposed-fix: Add 'eidos' to morfo scope declaration: `scope: ['soma', 'sema', 'eidos']` and create the date-range-picker recipe block in src/uix/eidos/lib/recipes/base.ts with token definitions for size (xs/sm/md/lg), color (primary/secondary/neutral/affirm/fulfill/risk/threat/loss), and variant (surface/outline/ghost).
- verify: [confirmed] CONFIRMED as SYS-1 scope-drift (MEDIUM). morfo line 13 `scope: ['soma', 'sema']` omits 'eidos', yet src/uix/eidos/components/date-range-picker/ has 25 files incl. date-range-picker.css imported by the eidos component. Grep for 'date-range-picker' in lib/recipes/base.ts = 0 matches (confirmed). HOWEVER the candidate's proposedFix is partly WRONG and I downgrade its remedy claim: the eidos CSS does NOT need its own recipe block. I read date-range-picker.css (690 lines) — it owns NO `--date-range-picker-*` recipe tokens; it COMPOSES tokens from sibling recipes (`--date-field-height-md`, `--calendar-padding-md`, `--calendar-accent-solid`, lines 2-28) plus global scales (`--color-primary-*`, `--space-*` L391/419, `--radius-md` L589, `--font-size-md/sm` L595/621). This is the A27 picker-composition pattern: the picker composes Field+Calendar+Popover and legitimately has no recipe entry. Verified systemic across the family: date-picker.ts also has `scope: ['soma','sema']` and 0 recipe matches; time-range-picker same. So the ONLY real defect is the missing 'eidos' token in the scope array — not a missing recipe block. Severity MEDIUM (SYS-1) is correct; the fix is to add 'eidos' to scope, NOT to author recipe tokens.
- fix-status: open
- fix-status: fixed (212624e0)
### MEDIUM: INERT EVENTS: morfo declares 'commit-reset' event but provider NEVER fires it via runtime. — date-range-picker-002 <!-- id: date-range-picker-002 -->
@ -22,7 +22,7 @@ Counts (post-verification): CRITICAL 0 · HIGH 0 · MEDIUM 3 · LOW 0.
- impact: Framework scope validation may flag this as inconsistent; eidos layer is present but not declared in morfo scope.
- proposed-fix: Update morfo scope declaration to scope: ['soma', 'sema', 'eidos'] to match the actual component hierarchy.
- verify: [confirmed] CONFIRMED. morfo declares scope: ['soma', 'sema'] (drag-drop.ts:7) yet a full eidos implementation exists: recipe entry 'drag-drop': { 'preview-z': '99' } (recipes/base.ts:4259-4261), drag-drop.css, and 3 svelte wrappers (draggable/droppable/preview). The Morfo.scope doctrine (morfo/types.ts:798) reads 'Layers that implement this component' and 'eidos' is a valid Layer (schema.ts:49: union(literal('soma'), literal('sema'), literal('eidos'))). Omitting 'eidos' is genuine scope-drift = SYS-1 baseline MEDIUM. Note: many siblings (calendar/carousel/color-field/combobox/command) share the same drift, consistent with SYS-1 being systemic.
@ -18,7 +18,7 @@ Counts (post-verification): CRITICAL 0 · HIGH 0 · MEDIUM 1 · LOW 0.
- impact: The morfo scope should include 'eidos' to signal that the component has visual styling rules. Missing 'eidos' in scope creates confusion about the component's boundaries.
- proposed-fix: Change morfo line 7 from scope: ['soma', 'sema'] to scope: ['soma', 'sema', 'eidos']
- verify: [confirmed] Confirmed. editable.ts:7 declares `scope: ['soma', 'sema']` — verified by reading the file. The eidos layer materially implements this component: 13 files under src/uix/eidos/components/editable/ (incl. editable.css) plus a recipe block at src/uix/eidos/lib/recipes/base.ts:2724 (`editable: {`). The Layer field is documented in types.ts:799 as 'Layers that implement this component', so omitting 'eidos' while shipping a full eidos implementation is genuine contract drift — matches the SYS-1 scope-drift baseline (MEDIUM). Severity MEDIUM is correct: this is a contract/documentation inconsistency, not a behavior bug (the eidos CSS still loads and works regardless of the morfo scope array). Confirmed systemic, not editable-specific: combobox, color-picker, date-field, calendar all have eidos CSS files yet their morfo scope is `['soma', 'sema']` too (e.g. calendar.ts:7, combobox.ts:7, color-picker.ts:7). Proposed fix (add 'eidos' to the array) is correct.
@ -21,7 +21,7 @@ Counts (post-verification): CRITICAL 0 · HIGH 0 · MEDIUM 2 · LOW 0.
- impact: MEDIUM (expected pattern per audit notes: 'No eidos scope-drift expected? (it has an eidos dir)'). Eidos wrapper components import soma correctly (all 11 .svelte files in eidos/field show 'import * as Field from $soma/components/field'), so the directory exists but is subordinate to soma — this is the normal composition pattern (eidos wraps soma visually, doesn't add a new layer to scope). No contract or behavior violation.
- proposed-fix: This is systemic (SYS-1). Document as expected: field is a soma component with an eidos visual wrapper layer; scope correctly declares soma as the source of truth.
- verify: [downgraded] Confirmed shape: fieldMorfo.scope = ['soma'] (field.ts:7) and a full eidos/components/field/ recipe dir exists. But SYS-1 scope-drift is the pattern where a soma component has an eidos visual layer not reflected in 'scope'; here every eidos wrapper composes soma (grep for 'import.*eidos' in field-provider returned NO matches — frontier clean). This is the normal eidos-wraps-soma composition, not a contract or behavior violation. Candidate's own impact text says 'expected pattern' / 'no contract or behavior violation'. Downgrade MEDIUM->LOW; record as systemic-expected, not a Field-specific defect.
@ -21,7 +21,7 @@ Counts (post-verification): CRITICAL 0 · HIGH 0 · MEDIUM 1 · LOW 0.
- repro: grep -n 'scope:' src/uix/morfo/components/file-upload.ts; ls -d src/uix/eidos/components/file-upload
- proposed-fix: Update line 7 from scope: ['soma', 'sema'] to scope: ['soma', 'sema', 'eidos']
- verify: [confirmed] CONFIRMED. morfo src/uix/morfo/components/file-upload.ts:7 declares `scope: ['soma', 'sema']`. The eidos layer is fully implemented: src/uix/eidos/components/file-upload/ holds 13 .svelte wrappers + file-upload.css (foundation reading `--file-upload-*` recipe tokens, e.g. `--_file-upload-gap: var(--file-upload-gap-md)`) + types.ts + README.md, AND a recipe exists at src/uix/eidos/lib/recipes/base.ts:2369 ('file-upload': {...} with per-color solid/track tokens). Eidos is present but omitted from morfo scope → SYS-1 scope-drift. MEDIUM is correct per baseline. Note: the candidate's repro `grep -n 'scope:'` is fine, but a `grep 'file-upload:'` on base.ts misses the recipe because the key is tab-indented — the recipe DOES exist.
- fix-status: open
- fix-status: fixed (212624e0)
## No-findings dimensions
Behavior (A35/A36 loops: no per-item $effect reading opts.ref.current AND writing provider state; no microtask-mediated async without untrack), Behavior (A6 cleanup: all listeners via soma.dom.listen() return disposers; URL.createObjectURL/revokeObjectURL pair in $effect return), Behavior (A33: no $state(new Map/Set); A31: no O(N²) includes checks), Behavior (A30: hiddenInputId set directly in constructor line 444, not in $effect; hiddenInputRef via onRefChange callback line 440-442), Behavior (A15 GESTURE: no drag-drop/cropper gesture logic; dropzone uses native drag events with proper preventDefault), Behavior (LIVE REGIONS: signal-warn-reject dispatches with message; untilFix persistence documented line 191-194), Contract (2-of-3 rule: morfo + soma + eidos all present; all 13 morfo parts registered via runtime.part()), Contract (data naming: all data-* attributes are kebab-cased; no data-soma-* violations), Contract (morfo validation: 'as const satisfies Morfo' present; all aria and data attrs declared), Frontier (no soma->eidos imports; eidos correctly imports from soma), Frontier (no syncAttrs double-write; parts use renderProps() correctly), Theming (focus rings use --focus-ring-width and --focus-ring-color CSS vars; no hardcoded hex colors or magic px values; no z-index magic), DOM selectors (no querySelector with interpolated consumer values; no direct document/window; uses soma.dom.getDocument()), Passive roles (ItemProgress role='progressbar' declares no component-level events; correct), Archetype validation (Item archetype:'item' is correct; CSS does not assign cursor:pointer or interactive styling to display items), Tests (provider.svelte.test.ts covers rejection logic, maxFiles caps, dropzone interactions, item metadata, removal, progress, clear state; jsdom environment)
@ -18,7 +18,7 @@ Counts (post-verification): CRITICAL 0 · HIGH 0 · MEDIUM 1 · LOW 0.
- impact: The morfo's declared scope under-reports its real consumers. Any scope-driven tooling (coverage checks, layer-presence assertions) will treat form as having no eidos materialization, masking drift if the eidos selectors fall out of sync with the morfo's emitted attrs.
@ -38,7 +38,7 @@ Counts (post-verification): CRITICAL 0 · HIGH 2 · MEDIUM 1 · LOW 0.
- impact: Inconsistency in declared vs actual scope. Eidos components are real and functional but not flagged in morfo. May confuse consumers about component structure.
- proposed-fix: Either (1) add 'eidos' to morfo.scope: `scope: ['soma', 'sema', 'eidos']`, OR (2) remove the eidos directory if GridList is soma-only. Recommend option 1 since eidos wrapper clearly exists and re-exports soma.
- verify: [confirmed] Confirmed SYS-1 scope-drift. grid-list.ts:7 declares `scope: ['soma', 'sema']` but a full eidos directory exists: grid-list.svelte, grid-list.css, types.ts, index.ts, grid-list-row.svelte, grid-list-cell.svelte, grid-list-selection-checkbox.svelte (verified via glob). The eidos wrapper is real and functional yet 'eidos' is omitted from the morfo scope. This is the documented systemic SYS-1 pattern (siblings command/combobox/date-picker show the same omission). MEDIUM per baseline. No recipe entry in recipes/base.ts (grep `grid-list:`/`gridList` returned no match), so the eidos surface is CSS-only — adding 'eidos' to scope is the correct alignment.
- fix-status: open
- fix-status: fixed (212624e0)
## No-findings dimensions
C - DOM-selector (CSS.escape used correctly on line 184 for consumer value), D - Frontier (no soma→eidos imports; eidos→soma normal), E - TSC/Theming (--control-height-*, --font-size-*, --space-*, --color-* all canonical; no magic hex or z-index), F - Tests (test environment jsdom is acceptable for this DOM-interactive pattern; keyboard nav, selection, typeahead tested), G - Redundancy (no detected duplication in selection/keyboard navigation logic), E-bis - No A33 ($state(new Map/Set)), A30 (id registration is direct field, not $effect), A6 (listeners cleaned in $effect.root), A14 (roving tabindex correctly implements exactly one tabindex=0), A34 DOM-TOPOLOGY (require() pattern not used)
@ -19,7 +19,7 @@ Counts (post-verification): CRITICAL 0 · HIGH 0 · MEDIUM 1 · LOW 0.
- repro: Inspect src/uix/morfo/components/image-adjustments.ts line 18 (scope: ['soma', 'sema']) and verify that src/uix/eidos/components/image-adjustments/ exists with a full component implementation.
- proposed-fix: Update the morfo's scope to: scope: ['soma', 'sema', 'eidos']. This aligns the contract with the actual implementation layers present.
- verify: [confirmed] CONFIRMED. image-adjustments.ts:18 declares `scope: ['soma', 'sema']`, omitting 'eidos'. A full eidos implementation exists at src/uix/eidos/components/image-adjustments/ (image-adjustments.css verified read, README.md verified read, recipe block at base.ts:1112-1132 'image-adjustments': {...}). This is the confirmed-systemic SYS-1 scope-drift pattern. MEDIUM. Fix: scope: ['soma', 'sema', 'eidos'].
@ -18,7 +18,7 @@ Counts (post-verification): CRITICAL 0 · HIGH 0 · MEDIUM 1 · LOW 0.
- impact: Contract drift: the morfo under-declares its implementing layers. Tooling/coverage that keys off `scope` (lint, layer audits, sema coverage) treats the component as having no eidos layer, masking the eidos↔morfo contract. Cosmetic-to-tooling, no runtime user impact — matches the confirmed SYS-1 baseline severity (MEDIUM).
- proposed-fix: Add 'eidos' to the scope array: `scope: ['soma', 'sema', 'eidos']` in src/uix/morfo/components/image-picker.ts:20.
- verify: [verifier-added] added by adversarial verify pass
@ -28,7 +28,7 @@ Counts (post-verification): CRITICAL 0 · HIGH 1 · MEDIUM 1 · LOW 0.
- impact: Morfo contract validator may not check eidos layer compliance; documentation/tooling may omit eidos layer from automated coverage. Scope mismatch creates maintenance liability if eidos changes are made without realizing morfo is unaware.
- verify: [confirmed] CONFIRMED MEDIUM (canonical SYS-1). Morfo line 7: `scope: ['soma', 'sema']` (file ends correctly with `} as const satisfies Morfo;` — contract annotation is fine, not a separate finding). The eidos layer materially exists at src/uix/eidos/components/listbox/: listbox.css (6574 bytes), listbox.svelte, listbox-item.svelte, listbox-group.svelte, listbox-group-label.svelte, listbox-item-indicator.svelte, types.ts, index.ts — a full implementation. Per SYS-1, eidos-recipe-dir-exists + morfo-scope-omits-'eidos' = MEDIUM scope-drift, and that is exactly the case here. Context: this is systemic — only 63/128 morfo components declare 'eidos' in scope despite 130 eidos dirs; major interactive siblings (toggle/dialog/select/combobox/popover) all omit it too. Minor correction to candidate evidence: there is NO `listbox:` recipe key in lib/recipes/base.ts (grep returns nothing) — the CSS is foundation-only, not recipe-driven. But SYS-1 triggers on the eidos DIR existence, which is confirmed, so the finding stands at MEDIUM. Fix: add 'eidos' to the scope array.
- fix-status: open
- fix-status: fixed (212624e0)
## No-findings dimensions
C (DOM-selector - CSS.escape use safe on framework numeric IDs), D (Frontier - no soma→eidos imports, no double-write divergence), E (TSC theming - all CSS vars reference canonical --color-* / --space-* / --radius-* / --opacity-* / --font-size-*), G (Redundancy - keyboard nav index math consistent, no duplication with divergence risk)
- repro: Check src/uix/morfo/components/menubar.ts line 7 against presence of src/uix/eidos/components/menubar/ directory.
- proposed-fix: Add 'eidos' to the scope array: scope: ['soma', 'sema', 'eidos']
- verify: [confirmed] morfo line 7 reads `scope: ['soma', 'sema'],` yet a full eidos recipe dir exists at src/uix/eidos/components/menubar/ (menubar.css, menubar.svelte, menubar-content.svelte, menubar-context.ts, types.ts, index.ts). The morfo's OWN comment contradicts the scope: line 8-10 cites the sema pack, and the eidos wrapper stamps data-size + reuses the dropdown recipe. Sibling components with an eidos dir DO list 'eidos' (accordion.ts:7, dropdown-menu.ts:11 both `['soma','sema','eidos']`). This is exactly SYS-1 scope-drift. HIGH is justified: the compiled scope is the contract the validators key on, and it's wrong.
- fix-status: open
- fix-status: fixed (212624e0)
### MEDIUM: SYS-4 keyboard route duplication + index math duplicated — menubar-004 <!-- id: menubar-004 -->
@ -18,7 +18,7 @@ Counts (post-verification): CRITICAL 0 · HIGH 0 · MEDIUM 1 · LOW 0.
- impact: Contract metadata drift: the morfo scope no longer reflects which layers consume the component. Tooling/lint that keys off `scope` to know an eidos recipe should exist will under-report. Consistency only — runtime behavior unaffected.
- proposed-fix: Add 'eidos' to the meter morfo `scope` array: `scope: ['soma', 'eidos']`, matching the other B7 components that declare the eidos scope.
- verify: [verifier-added] added by adversarial verify pass
@ -20,7 +20,7 @@ composition (A27): N/A (not a picker)
- repro: Observe the eidos directory structure.
- proposed-fix: Update morfo scope to `scope: ['soma', 'sema', 'eidos']`
- verify: [confirmed] Confirmed SYS-1 scope-drift. month-grid.ts:7 declares `scope: ['soma', 'sema']` while a full eidos layer exists: src/uix/eidos/components/month-grid/ contains month-grid.css (recipe-consuming `[data-month-grid]` block at lines 3-7, e.g. `--_month-grid-cell-size: var(--calendar-day-size-md)`), plus 8 .svelte wrappers, types.ts, index.ts and README.md. The morfo omits 'eidos' from scope. This is the known systemic MEDIUM baseline — matches the SYS-1 pattern seen across batch-1/2.
- fix-status: open
- fix-status: fixed (212624e0)
### LOW: DOM-selector: querySelector/querySelectorAll must not interpolate consumer/state-derived v — month-grid-001 <!-- id: month-grid-001 -->
@ -18,7 +18,7 @@ Counts (post-verification): CRITICAL 0 · HIGH 0 · MEDIUM 1 · LOW 0.
- impact: Scope mismatch signals incomplete layer declaration. Eidos layer is real and should be listed in morfo scope.
- proposed-fix: Update morfo scope from ['soma', 'sema'] to ['soma', 'sema', 'eidos'] to match the existing eidos layer.
- verify: [confirmed] Confirmed SYS-1 scope-drift. src/uix/morfo/components/pagination.ts:7 declares `scope: ['soma', 'sema'],` but a complete eidos layer exists: src/uix/eidos/components/pagination/ contains pagination.css (4255 bytes), 7 Svelte wrappers, index.ts, types.ts, and a README, plus a recipe entry at src/uix/eidos/lib/recipes/base.ts:1715 (`pagination: {`). Peer components with an eidos layer include it in scope (accordion.ts:7 `scope: ['soma', 'sema', 'eidos']`, button.ts:47, checkbox.ts:7). The omission is a real layer-declaration drift. MEDIUM is correct.
- fix-status: open
- fix-status: fixed (212624e0)
## No-findings dimensions
Contract parts registration (2-of-3 rule verified: all 7 parts registered), Contract data/aria naming (data-{c}-{part} pattern used, no data-soma-* violations), Contract Morfo as const satisfies, Behavior A31 per-item O(N²) derived reading global state, Behavior A33 $state(new Map/Set) reactivity, Behavior A35/A36 per-item $effect ref-write loops, Behavior A30 id-registration via $effect, Behavior A6 cleanup (no Resource leaks detected), Behavior A18/A10/A14/A12 keyboard navigation (N/A: pagination uses snippet-based rendering, not nav), Behavior A34 require() topology (all triggers/items require parent Provider, DOM descendants), DOM-selector (no querySelector usage), Frontier eidos→soma import (correct), Frontier syncAttrs double-write (Provider and Ellipsis only, no conflicting props), Theming roles/tokens (recipe uses --space-*, --font-size-*, --radius-*, --opacity-*, --color-* role references), Tests environment (jsdom with @vitest-environment directive), Tests coverage (page ranges, clamping, navigation, disabled state all tested)
@ -18,7 +18,7 @@ Counts (post-verification): CRITICAL 0 · HIGH 0 · MEDIUM 1 · LOW 0.
- impact: Component maintainers may miss that eidos layer exists; recipe synchronization risk if scope drift persists across the codebase
- proposed-fix: Change line 31 to scope: ['soma', 'sema', 'eidos']
- verify: [confirmed] CONFIRMED at the cited severity. morfo src/uix/morfo/components/password-field.ts:31 declares `scope: ['soma', 'sema'],` — 'eidos' is omitted. Yet eidos demonstrably implements the component: (a) the recipe entry `'password-field': {` exists at src/uix/eidos/lib/recipes/base.ts:2097 (the candidate's cited line is exact), with control-height/space/font tokens following; (b) the eidos component directory src/uix/eidos/components/password-field/ contains 8 files (password-field.svelte, -input, -visibility-trigger, -strength-meter, -caps-lock-indicator, types.ts, index.ts, password-field.css). The `scope` field is documented in src/uix/morfo/types.ts:799 as 'Layers that implement this component', so the declared array genuinely diverges from the real implementation. This is the established SYS-1 scope-drift pattern (MEDIUM in baseline) — informational/metadata drift, not a behavioral or a11y bug: the component renders and works; the `scope` array does not gate eidos at runtime. MEDIUM is the correct severity (not HIGH — no latent behavioral failure; not LOW — it is a real contract/metadata inconsistency the coverage tooling tracks). Note: this is systemic, not unique to password-field — calendar (calendar.ts:7), color-field (color-field.ts:7), color-picker, combobox, command and other components likewise carry `['soma', 'sema']` while shipping eidos directories, consistent with SYS-1 being a confirmed systemic finding.
- fix-status: open
- fix-status: fixed (212624e0)
## No-findings dimensions
A Contract (Morfo), A Behavior (Soma), C DOM-selector, D Frontier, E TSC, E-bis Theming, F Tests
- repro: Read src/uix/morfo/internal/picker-shell.ts line 32 and compare to ls src/uix/eidos/components/picker-shell/ — 7 files present.
- proposed-fix: Update morfo scope from `scope: ['soma']` to `scope: ['soma', 'eidos']` to match the architecture. Alternatively, if intentionally minimizing the contract surface, document that eidos-layer parts are NOT part of the public morfo (correct per current design) and clarify in the comment.
- verify: [downgraded] Facts confirmed but severity overstated. Read src/uix/morfo/internal/picker-shell.ts:32 `scope: ['soma'],` and the eidos dir DOES exist (ls showed picker-shell.svelte/-header/-body/-footer/-clear/-cancel/-close + picker-shell.css + recipe usage). HOWEVER this is NOT undocumented SYS-1 drift: picker-shell.ts:23-25 explicitly states `Scope is \`soma\` only — no semantic events; the host picker emits commit-*/shift-* on its own provider. No \`expression\` field because there is no morfo-emitted event to express.` The README (lines 15-19) and audit-codex P1 #5 closure (line 51) document picker-shell as an INTERNAL primitive whose morfo is deliberately a single Provider stub. The eidos divs (`data-picker-shell`, `data-picker-footer`) are standalone layout containers, NOT morfo-declared parts — so there is no contract<->visual part mismatch, which is what SYS-1/2-of-3 actually polices. The candidate's own proposedFix concedes 'correct per current design'. Real, intentional, documented => LOW doc/observation, not MEDIUM scope-drift. SYS-1 baseline is for components with an UNINTENDED scope omission, not a documented internal contract-surface minimization.
@ -18,7 +18,7 @@ Counts (post-verification): CRITICAL 0 · HIGH 0 · MEDIUM 1 · LOW 0.
- impact: The morfo contract under-declares the component's real consumer layers; any tooling that walks `scope` to know which layers materialize a component (lint/coverage/codegen) will skip eidos for Progress even though eidos owns its size/shape visual surface. Same drift class as meter.ts (also `['soma']`), so it is a shared B7-family systemic issue, not a one-off.
- proposed-fix: Add 'eidos' to the scope tuple: `scope: ['soma', 'eidos']`. (No 'sema' — Progress declares no events, expression is none/passive, which is correct.)
- verify: [verifier-added] added by adversarial verify pass
@ -19,7 +19,7 @@ Counts (post-verification): CRITICAL 0 · HIGH 0 · MEDIUM 1 · LOW 0.
- repro: Inspect src/uix/morfo/components/rating-group.ts line 7 and confirm eidos directory + recipe tokens exist
- proposed-fix: Update morfo scope from ['soma', 'sema'] to ['soma', 'sema', 'eidos']
- verify: [confirmed] Confirmed SYS-1 scope-drift. src/uix/morfo/components/rating-group.ts:7 declares `scope: ['soma', 'sema'],` while a full eidos layer exists: recipe block at src/uix/eidos/lib/recipes/base.ts:2018 (`'rating-group': { 'gap-xs': ... 'item-color-active': 'var(--color-fulfill-solid)' ... }`) plus eidos wrapper/css/types/README under src/uix/eidos/components/rating-group/ (rating-group.svelte, rating-group.css, types.ts, README.md). Direct peers that ALSO have eidos recipes DO declare it: radio-group.ts:7, checkbox.ts:7, toggle-group.ts:10 all read `scope: ['soma', 'sema', 'eidos']`. So 'eidos' is the project's convention when an eidos recipe is present, and rating-group omits it. MEDIUM per SYS-1 baseline. (Note: a broader population of soma-rooted components — calendar, combobox, command — also omit 'eidos' despite having eidos css; this is a wider systemic pattern, but rating-group's drift is real and matches the SYS-1 rule against its rating-control peers.) Proposed fix: change to `scope: ['soma', 'sema', 'eidos']`.
@ -18,7 +18,7 @@ Counts (post-verification): CRITICAL 0 · HIGH 0 · MEDIUM 2 · LOW 0.
- impact: The morfo's declared scope under-reports the layers that consume the contract. Any tooling that keys off `scope` (lint coverage, layer maps) will skip eidos for search-field even though eidos CSS selects against the morfo-emitted data-attrs (data-search-field, data-search-field-input, data-disabled/empty/focused, etc.).
- proposed-fix: Add 'eidos' to the morfo `scope` array: `scope: ['soma', 'sema', 'eidos']`.
- verify: [verifier-added] added by adversarial verify pass
- fix-status: open
- fix-status: fixed (212624e0)
### MEDIUM: Test coverage of a high-risk path — debounced onValueChange has no test — SF-F-debounce-untested <!-- id: SF-F-debounce-untested -->
@ -18,7 +18,7 @@ Counts (post-verification): CRITICAL 0 · HIGH 0 · MEDIUM 1 · LOW 0.
- impact: The morfo's declared scope is the contract for which layers consume it. Omitting 'eidos' while a recipe + CSS layer actively style the component understates the contract surface: drift checks, lint, and any scope-driven tooling will not treat eidos as a consumer, so a morfo rename of a thumb part/attr won't flag the eidos CSS that depends on it.
- proposed-fix: Add 'eidos' to the slider morfo scope: `scope: ['soma', 'sema', 'eidos']`. Confirm against the convention used by other B6 components that DO declare eidos.
- verify: [verifier-added] added by adversarial verify pass
- fix-status: open
- fix-status: fixed (212624e0)
## No-findings dimensions
B: Behavior (sequence: 'post' verified, state set at call-site before trigger), A: Contract (2-of-3 parts satisfied, kebab markers correct), A12: RTL Transform (verified correct in thumb, range, tick — isRtl checks respected), A13: Hidden Input (verified rendered on thumb when name provided), A14: Roving Tabindex (not applicable — slider uses single focusable thumb with tabindex: 0), A15: Gesture (pointer handlers with deferred setPointerCapture after MOVE_BUFFER; drag cleanup via cancelFrame), A6: Cleanup (dragSignalFrame cancelled in onpointermove/onpointerup/onpointercancel; no memory leaks detected), A31: O(N²) (no provider method calls in loops; candidates.includes() is safe), A30: Child ID Registration (not applicable), A33: SvelteMap (no $state(new Map/Set) detected), CSS: No magic z-index, no unthemed color literals, all size tokens reference --slider-* recipe vars), Scope-Drift: Morfo declares scope=['soma','sema'] and eidos directory exists with valid components, Frontier: No soma->eidos imports detected, Contract Validators: ':Morfo satisfies' present; morfo is 'as const satisfies Morfo'
- verify: [confirmed] CONFIRMED. morfo at src/uix/morfo/components/stepper.ts:7 declares `scope: ['soma', 'sema']`. A full eidos implementation exists: src/uix/eidos/components/stepper/ (stepper.css 6.8KB, types.ts, index.ts, 11 .svelte wrappers) plus a recipe at src/uix/eidos/lib/recipes/base.ts:3152 (`stepper: {`). The Morfo.scope doc (types.ts:798-799) defines scope as 'Layers that implement this component.' Reference morfos with eidos dirs DO declare it: toggle-group/tabs/radio-group/checkbox/accordion all have `scope: ['soma', 'sema', 'eidos']`. Stepper omits 'eidos' despite a complete eidos layer — genuine SYS-1 scope-drift. MEDIUM holds.
- fix-status: open
- fix-status: fixed (212624e0)
### MEDIUM: Morfo.expression missing for events + scope:['sema'] with existing sema pack — stepper-005 <!-- id: stepper-005 -->
@ -18,7 +18,7 @@ Counts (post-verification): CRITICAL 0 · HIGH 0 · MEDIUM 1 · LOW 0.
- impact: Recipe tokens in eidos layer not declared in morfo scope; eidos wrapper (src/uix/eidos/components/switch/switch.svelte:30) adds data-size but recipe scope is undeclared
- verify: [downgraded] REAL inconsistency but downgraded MEDIUM->LOW. Confirmed at src/uix/morfo/components/switch.ts:24 `scope: ['soma', 'sema']` while the eidos recipe exists (src/uix/eidos/lib/recipes/base.ts:3370 `switch: {`) and the dir src/uix/eidos/components/switch/ ships switch.css (line 1 `[data-switch] {`) + switch.svelte. The literal scope doc (types.ts:799 'Layers that implement this component') supports including 'eidos'. BUT three facts cut the severity: (1) the canonical Toggle pilot — closest sibling, with structural identity + recipe + eidos dir — ALSO omits eidos: src/uix/morfo/components/toggle.ts:25 `scope: ['soma', 'sema']`, so this is a Toggle/Switch-family convention, not a Switch-specific drift (checkbox.ts:7 and radio-group.ts:7 DO declare 'eidos' — codebase is split); (2) no validator enforces eidos-in-scope — types.ts:835-839 only errors on `events[] + no scope:['sema']` and warns on missing `expression`, neither of which Switch violates (expression:'pack' present at line 27); (3) it is inert metadata with no runtime effect. SYS-1 baseline lists scope-drift as MEDIUM, but the Toggle parity + zero enforcement make this LOW.
@ -19,7 +19,7 @@ Counts (post-verification): CRITICAL 0 · HIGH 0 · MEDIUM 1 · LOW 0.
- repro: ls -la src/uix/eidos/components/tags-input; grep scope src/uix/morfo/components/tags-input.ts
- proposed-fix: Change line 7 from scope: ['soma', 'sema'] to scope: ['soma', 'sema', 'eidos']
- verify: [confirmed] CONFIRMED at high confidence. src/uix/morfo/components/tags-input.ts:7 declares `scope: ['soma', 'sema']` and the morfo is closed with `as const satisfies Morfo` (verified at file tail), so the literal scope array is load-bearing. The eidos layer materially implements this component: (a) full CSS foundation at src/uix/eidos/components/tags-input/tags-input.css (`[data-tags-input] { --_tags-input-gap: var(--tags-input-gap-md); ... }`), (b) a substantial recipe at src/uix/eidos/lib/recipes/base.ts:2928 (`'tags-input': { ... }`) with 8 per-intent track color tokens (lines 3026-3033), and (c) 8 component .svelte part files (control/input/item/item-text/item-delete-trigger/clear-trigger + index + types). The `scope` field is documented at types.ts:798-799 as 'Layers that implement this component' with the explicit note 'Eidos-only primitives may declare ["eidos"]'; `Layer` (src/uix/types.ts:17) = 'soma' | 'sema' | 'eidos', so 'eidos' is a valid member that is omitted despite a real eidos implementation. This is SYS-1 scope-drift, MEDIUM. The proposed fix (`['soma', 'sema', 'eidos']`) is correct. Note for context: sibling field morfos number-field.ts:7 and css-field.ts:7 also declare `scope: ['soma', 'sema']`, suggesting this is a systemic field-family drift, not a one-off.
- fix-status: open
- fix-status: fixed (212624e0)
## No-findings dimensions
A: Contract (morfo as const satisfies Morfo, parts 2-of-3 clean, events all fired), B: Behavior (keyboard A17 compliant, no effect id-loops, no timers), C: DOM-selector (no unescaped CONSUMER values), D: Frontier (no soma-imports-eidos), E: TSC (tokens use role aliases), F: Tests (3 paths: add/reject, keyboard/paste/blur, navigation)
@ -18,7 +18,7 @@ Counts (post-verification): CRITICAL 0 · HIGH 0 · MEDIUM 2 · LOW 0.
- impact: Scope drift creates maintenance risk: schema generators and validators may not handle eidos layer, causing potential mismatches during component evolution or tooling updates
- proposed-fix: Add 'eidos' to morfo scope declaration on line 18: scope: ['soma', 'sema', 'eidos']
- verify: [confirmed] CONFIRMED at MEDIUM. textarea.ts:18 declares `scope: ['soma', 'sema'],` while a full eidos visual layer exists: Glob of src/uix/eidos/components/textarea/ returns textarea.svelte, textarea-input.svelte, textarea-count.svelte, textarea.css, types.ts, index.ts. The `Morfo.scope` field is documented in types.ts:798-799 as 'Layers that implement this component. Eidos-only primitives may declare [eidos].' — so an implementing eidos layer belongs in scope. This is the systemic SYS-1 pattern, not a one-off: the audit's REFERENCE baseline NumberField shows the IDENTICAL omission — number-field.ts:7 also reads `scope: ['soma', 'sema'],` yet src/uix/eidos/components/number-field/ has a full recipe + 8 svelte files. Severity stays MEDIUM (systemic doctrine drift, no runtime/a11y impact), matching the pre-established SYS-1 classification.
- fix-status: open
- fix-status: fixed (212624e0)
### MEDIUM: SemaExpressionMode coverage (types.ts:835-837 — morfo with events[] + scope sema SHOULD se — textarea-002 <!-- id: textarea-002 -->
@ -35,7 +35,7 @@ Counts (post-verification): CRITICAL 0 · HIGH 0 · MEDIUM 2 · LOW 1.
- impact: Scope declaration is incomplete. The eidos layer provides visual recipes, but morfo declares scope without 'eidos', causing contract validators to miss eidos-layer violations.
- proposed-fix: Update line 7 to: scope: ['soma', 'sema', 'eidos'],
- verify: [confirmed] Confirmed. time-field.ts:7 declares `scope: ['soma', 'sema']` — omits 'eidos'. The eidos layer exists in full: Glob of src/uix/eidos/components/time-field/ returns time-field.css, time-field.svelte, time-field-input.svelte, time-field-hidden-input.svelte, time-field-segment.svelte, time-field-label.svelte, types.ts, index.ts, README.md. Classic SYS-1 scope-drift; contract validators won't reach the eidos layer. Fix: add 'eidos' to the scope array.
- fix-status: open
- fix-status: fixed (212624e0)
### LOW: Morfo declares Label part defaultElement='label' but soma renders <div> — time-field-003 <!-- id: time-field-003 -->
- impact: Scope metadata is incorrect, confusing consumers about which layer(s) implement time-picker. Known systemic issue but should be corrected.
- proposed-fix: Change scope to ['soma', 'sema', 'eidos'] to match actual implementation structure
- verify: [confirmed] CONFIRMED. morfo line 13: `scope: ['soma', 'sema']` — omits 'eidos'. The eidos dir is real: I read src/uix/eidos/components/time-picker/time-picker.css (308 lines of recipe CSS). This is the catalogued systemic SYS-1 scope-drift, MEDIUM. Severity correct.
- fix-status: open
- fix-status: fixed (212624e0)
### MEDIUM: INERT EVENTS: morfo declares 'open' event that provider never fires — time-picker-002 <!-- id: time-picker-002 -->
- dimension: A - Contract (morfo), B - Behavior (soma)
@ -17,7 +17,7 @@ Counts (post-verification): CRITICAL 0 · HIGH 0 · MEDIUM 1 · LOW 0.
- impact: Contract validator will not enforce eidos presence rules; consumers may ignore eidos-layer variants/size/color constraints.
- proposed-fix: Add 'eidos' to morfo scope: `scope: ['soma', 'eidos']`
- verify: [confirmed] CONFIRMED. src/uix/morfo/components/time-range-field.ts:7 reads `scope: ['soma'],` — 'eidos' is absent. The eidos directory src/uix/eidos/components/time-range-field/ genuinely exists with 6 files (time-range-field.svelte, time-range-field.css, types.ts, index.ts, time-range-field-input.svelte, time-range-field-label.svelte) per Glob. This is textbook SYS-1 scope-drift. The omission is real (not intentional): the sibling component using the IDENTICAL overlay trick — date-range-field, explicitly named in this recipe's header comment ('Same trick DateRangeField uses') — declares `scope: ['soma', 'eidos']` (src/uix/morfo/components/date-range-field.ts:10). So time-range-field's `['soma']` diverges from its own established sibling precedent. MEDIUM is correct per the SYS-1 baseline.
- fix-status: open
- fix-status: fixed (212624e0)
## No-findings dimensions
B Behavior, C DOM-selector, D Frontier, E-bis Theming (roles/aliases/spacing/radius/z-index/opacity naming), F Tests, G Redundancy
- verify: [confirmed] CONFIRMED — SYS-1 scope-drift. morfo line 13: `scope: ['soma', 'sema'],` omits 'eidos', yet a full eidos recipe dir exists at src/uix/eidos/components/time-range-picker/ (14 files: time-range-picker.css 392 lines, .svelte parts, index.ts, types.ts, README.md). This is the known systemic SYS-1 pattern (MEDIUM). The eidos layer genuinely materializes this component (CSS targets [data-time-range-picker]*) so the scope array is incomplete. Confidence high, severity MEDIUM as baselined.
- verify: [confirmed] CONFIRMED at src/uix/morfo/components/toast.ts:8 — `scope: ['soma', 'sema']` omits 'eidos' while a full eidos layer exists: recipe `toast: {` at src/uix/eidos/lib/recipes/base.ts:3545, plus src/uix/eidos/components/toast/ with toast.css (11466B), types.ts, and 9 part wrappers. The scope field per types.ts:799 declares 'Layers that implement this component', so omitting 'eidos' is genuine drift. Matches the SYS-1 baseline (MEDIUM). NOTE: confirmed SYSTEMIC — dialog/drawer/popover/toggle all likewise declare `scope: ['soma', 'sema']` while shipping eidos recipes+dirs; this is the documented split where some components (button/checkbox/accordion/context-menu) DO declare 'eidos'. Severity MEDIUM stands; it is a contract-coverage inconsistency, not a behavioral bug.
- fix-status: open
- fix-status: fixed (212624e0)
## No-findings dimensions
B (Behavior: A35/A36 loops clean — untrack present on present/announce trigger; A6 timer cleanup via .cancel() in clearTimer and $effect cleanup; A33 no $state(Map/Set); A31 no O(N²) derived patterns; A30 direct ID registration; A15 gesture properly uses setPointerCapture; A6/A34 hotkey listeners cleaned via this.cleanupHotkey in $effect), C (DOM: no unsafe querySelector interpolation; uses soma.dom.getDocument/getWindow), D (Frontier: soma does not import eidos; syncAttrs: true throughout; no double-write divergence), E (TSC: z-index uses --toast-toaster-z token; opacity literals 0/1 are canonical, no --opacity-* variants exist; focus-ring uses canonical tokens; spacing uses --space-* tokens), E-bis (Theming: only 9 roles used; all 6 intents correctly mapped to palettes; status is 'indicator' archetype, not interactive; no hardcoded :active or focus-ring), F (Tests: hotkey focus, timers with cancel, ARIA projection, promise lifecycle covered in separate test), G (Redundancy: no re-implemented gesture/registry/live-region)
@ -18,7 +18,7 @@ Counts (post-verification): CRITICAL 0 · HIGH 0 · MEDIUM 1 · LOW 0.
- impact: Morfo scope does not accurately reflect the component's actual API surface. Eidos-provided visual attrs (data-variant, data-size, data-block, data-icon-only) consumed by toggle.css are outside the declared contract.
- verify: [confirmed] CONFIRMED SYS-1 scope-drift at MEDIUM. morfo/components/toggle.ts:25 declares `scope: ['soma', 'sema']`, yet a full eidos surface exists: src/uix/eidos/components/toggle/ ships toggle.css + toggle.svelte + types.ts + a recipe entry (lib/recipes/base.ts:3646 `toggle: {`). The eidos wrapper (toggle.svelte:49-52) emits data-variant/data-size/data-block/data-icon-only consumed by toggle.css. Peer twins DO declare eidos: checkbox.ts:7, radio-group.ts:7, tabs.ts:7, and notably toggle-group.ts:10 (which reuses Toggle's recipe via structural identity) all carry `scope: ['soma', 'sema', 'eidos']`. NOTE on severity ceiling: this is purely a contract-accuracy/documentation gap — `scope` is documented (types.ts:799) as 'Layers that implement this component' but NO validator enforces 'eidos' presence (the morfo-coverage check at types.ts:835-839 only errors on events-without-sema-scope and warns on missing `expression`). It is also not toggle-unique: switch.ts:24 (toggle's structural twin) has the identical omission. So MEDIUM is the correct ceiling — real inconsistency vs. direct peers, zero functional/runtime impact. Does not rise to HIGH.
@ -18,7 +18,7 @@ Counts (post-verification): CRITICAL 0 · HIGH 0 · MEDIUM 1 · LOW 0.
- impact: Morfo scope declaration incomplete; validator may not catch eidos-layer issues
- proposed-fix: Update morfo scope to ['soma', 'sema', 'eidos']
- verify: [confirmed] CONFIRMED. src/uix/morfo/components/toolbar.ts:7 reads `scope: ['soma', 'sema'],` yet a full eidos layer exists: src/uix/eidos/components/toolbar/ (toolbar.css, index.ts, types.ts, 5 part svelte files) plus a recipe entry at src/uix/eidos/lib/recipes/base.ts:2312 (`toolbar: {`). This is the documented SYS-1 scope-drift baseline (MEDIUM) — peers toggle/dialog/popover drift identically (scope omits 'eidos' despite eidos dirs), while button.ts:47/accordion.ts:7/checkbox.ts:7 correctly declare ['soma','sema','eidos']. Severity MEDIUM is correct.
@ -18,7 +18,7 @@ Counts (post-verification): CRITICAL 0 · HIGH 0 · MEDIUM 1 · LOW 0.
- impact: Morfo scope does not accurately reflect the component's layer coverage. The eidos visual/theming layer exists as a full implementation but is not declared in scope.
- proposed-fix: Update morfo scope from ['soma', 'sema'] to ['soma', 'sema', 'eidos']
- verify: [confirmed] CONFIRMED SYS-1 scope-drift. morfo src/uix/morfo/components/virtual-grid.ts:7 declares scope: ['soma', 'sema'] (omits 'eidos'), yet a complete eidos implementation exists at src/uix/eidos/components/virtual-grid/: index.ts lines 2-16 export a full compound API (VirtualGridRoot/Viewport/Cell) plus public types, and virtual-grid.css ships a substantive recipe (data-size xs/sm/lg/xl, data-variant surface/outline/ghost, 7 data-color cascades, viewport + cell positioning, focus-visible ring). The eidos visual/theming layer is materially present but undeclared in scope. MEDIUM per baseline.
- fix-status: open
- fix-status: fixed (212624e0)
## No-findings dimensions
A Contract (parts/events/data/aria match), B Behavior (no A31 O(N²), no A33 Map/Set reactivity, no A35 per-item effect loops), C DOM-selector (no interpolated selectors without escape), D Frontier (soma does not import eidos, eidos->soma is normal), E TSC/Theming (all tokens canonical, no raw hex/opacity decimals, correct role aliases), F Tests (jsdom environment, covers 2D window math and scrollToCell), G Redundancy (no cross-component duplication)
@ -18,7 +18,7 @@ Counts (post-verification): CRITICAL 0 · HIGH 0 · MEDIUM 1 · LOW 0.
- impact: Scope contract violation: declared scope does not match actual component architecture. API consumers expect soma-only but eidos layer exists and is used.
- proposed-fix: Update morfo scope declaration to scope: ['soma', 'sema', 'eidos'] to match the actual component implementation at G:/dev/svelte/vicen/src/uix/eidos/components/virtual-list/
- verify: [confirmed] Confirmed SYS-1 scope-drift at MEDIUM. src/uix/morfo/components/virtual-list.ts:7 declares `scope: ['soma', 'sema'],` and the morfo is `as const satisfies Morfo` (line 125), yet a full eidos layer exists at src/uix/eidos/components/virtual-list/ (virtual-list.svelte, virtual-list-viewport.svelte, virtual-list-window-viewport.svelte, virtual-list-item.svelte, virtual-list.css, types.ts, index.ts). virtual-list.css is a genuine recipe with size/variant/color cascades, e.g. `[data-virtual-list-root][data-variant='surface'] { border: var(--border-width) solid var(--color-border-default); ... }` (lines 53-56) and color cascades lines 67-73 — it demonstrably styles the morfo-emitted data-attrs. The scope omits 'eidos' while eidos is implemented and used. One nuance to the candidate's wording: there is NO top-level `virtual-list:` entry in src/uix/eidos/lib/recipes/base.ts (only `s-text-virtual-list` skeleton-text at line 3534); the component uses a standalone foundation-style .css file rather than a base.ts recipe. This does not change the verdict — the eidos layer plainly exists. Sibling virtual-grid carries the same pattern (the morfo comment line 8 says 'Same rationale as virtual-grid').
@ -19,7 +19,7 @@ composition (A27): N/A (year-grid is not a picker; it is a standalone grid compo
- impact: The morfo contract claims eidos is out-of-scope, but the eidos layer clearly exists and is active. This is the documented SYS-1 systemic issue.
- proposed-fix: Update morfo scope to `['soma', 'sema', 'eidos']` to reflect reality.
- verify: [confirmed] Confirmed at MEDIUM (documented systemic SYS-1 scope-drift). Morfo line 7: `scope: ['soma', 'sema'],` — eidos omitted. Yet src/uix/eidos/components/year-grid/year-grid.css exists (284 lines, mtime Jun 23, real recipe selecting [data-year-grid], [data-year-grid-cell], [data-year-grid-grid], variant/color/size cascades) plus a full eidos component dir (year-grid.svelte, year-grid-cell.svelte, year-grid-grid.svelte, index.ts, types.ts, README.md). The eidos layer is active and shipping, so the morfo scope under-declares reality. Matches the known SYS-1 baseline; MEDIUM is appropriate.