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/audit/components/search-field.md

4.3 KiB

Audit: search-field

audit-version: 1 audited-at: 2026-06-26 scope: method: adversarially-verified workflow (analyze → refute); HIGH/CRITICAL lead-verified. Clean-check pseudo-findings dropped. B4 ground-truth: segmented date/time/color-field register inputId via $effect (SYS-A30-EFFECT, no loop); number-field is the direct-assignment reference. provider: src/uix/soma/components/search-field/search-field-provider.svelte.ts field-family (A13/A24-26/A30): search-field IS field-composable (calls FieldProvider.get(), registers inputId at line 105 via direct assignment, NOT $effect—A30 correct). Does NOT declare hidden input (A13 not applicable—not form-participating). Does not emit segmented contenteditable (A26 not applicable). Does not read readonlySegments (A24/A25 not applicable). Field composition integration is clean: aria-labelledby/aria-descr

Summary

Counts (post-verification): CRITICAL 0 · HIGH 0 · MEDIUM 2 · LOW 0.

Findings

MEDIUM: SYS-1 scope-drift — eidos recipe/CSS dir exists but morfo 'scope' omits 'eidos' — SF-SYS1-scope-drift

  • dimension: A
  • rule: SYS-1 scope-drift — eidos recipe/CSS dir exists but morfo 'scope' omits 'eidos'
  • location: src/uix/morfo/components/search-field.ts:7
  • evidence: scope: ['soma', 'sema'] — yet a full eidos surface exists: a recipe block 'search-field': { ... } at src/uix/eidos/lib/recipes/base.ts:2045 and a complete component dir src/uix/eidos/components/search-field/ (search-field.css, types.ts, search-field.svelte, plus icon/input/clear-trigger/loading-indicator wrappers).
  • 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: fixed (212624e0)

MEDIUM: Test coverage of a high-risk path — debounced onValueChange has no test — SF-F-debounce-untested

  • dimension: F
  • rule: Test coverage of a high-risk path — debounced onValueChange has no test
  • location: src/uix/soma/components/search-field/search-field-provider.svelte.test.ts:60
  • evidence: The fixture sets debounceMs: state(0) and never exercises debounceMs > 0. The debounce branch in commit() (provider lines 176-196: schedules this.soma.uix.timers.schedule(...), replaces pending timers, fires only the latest value), plus flushDebounce() on submit (lines 128-137) and cancelDebounce() on clear/unmount (lines 119-125, 108-110), are entirely uncovered. The test stubs soma as a partial object with no uix.timers, so a debounced path would not even resolve a timer service.
  • impact: The most behaviorally subtle logic in this provider (debounce coalescing, flush-before-submit ordering so onSubmit sees the latest value, cancel-on-clear, cancel-on-unmount A6) is unverified. A regression in timer keying/replace or flush ordering would ship silently.
  • proposed-fix: Add a test with debounceMs>0 driving the provider through a real uix.timers (via createActiveUix/attachActiveUix harness): assert onValueChange fires once with the latest value after the delay, that submit flushes the pending value before onSubmit, and that clear cancels the pending callback.
  • verify: [verifier-added] added by adversarial verify pass
  • fix-status: open

No-findings dimensions

A, B, C, D, E, E-bis, F, G

Theming facts (E-bis)

  • magic z-index: none
  • magic literals: line-height: 1 at search-field.css:189 (icon alignment; systemic pattern across all icons, not search-field-specific)
  • undeclared parts: none
  • roles clean: true · variants clean: true
  • label-font (one step below input?): N/A — search-field composes Field; Field renders the label. No direct label in search-field recipe.

Tests (F)

  • exists: true · env: @vitest-environment jsdom
  • covers: root state attrs projection; focus/blur state tracking; input commit and value change; submit on Enter; clear on Escape and click; debounce behavior; Field composition (OR-merge of flags, labelId integration)
  • untested:

Powered by TurnKey Linux.