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

5.9 KiB

Audit: 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: G:\dev\svelte\vicen\src\uix\soma\components\field\field-provider.svelte.ts field-family (A13/A24-26/A30): { "A13": "Not applicable: field is the generic wrapper, not a form-participating field (number-field, tags-input, pin-input, color-field, css-field are form-fields). No hidden rendered by field itself.", "A24": "Not applicable: field does not hold a value; child inputs (FieldInputProvider) handle value state. A24 'readonly-without-value warning' applies to child-level components.", "

Summary

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

Findings

MEDIUM: SYS-1 scope-drift: morfo 'scope' declares ['soma'] but eidos directory exists at src/uix/e — field-002

  • dimension: A
  • rule: SYS-1 scope-drift: morfo 'scope' declares ['soma'] but eidos directory exists at src/uix/eidos/components/field
  • location: src/uix/morfo/components/field.ts:7 vs src/uix/eidos/components/field/
  • evidence: fieldMorfo.scope = ['soma'], yet a full eidos/ recipe directory exists with field.css, field.svelte, and 10+ component files.
  • 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.
  • fix-status: open

MEDIUM: Tests: {kebab}-provider.svelte.test.ts must exist; coverage high-risk paths: segment commi — field-007

  • dimension: F
  • rule: Tests: {kebab}-provider.svelte.test.ts must exist; coverage high-risk paths: segment commit/keyboard, hidden-input, Field inheritance, readonly-without-value warning, validation.
  • location: src/uix/soma/components/field/field-provider.svelte.test.ts (exists)
  • evidence: Test file exists and covers: (1) wires field parts, ARIA props, runtime attrs (lines 85-183); (2) updates input value unless disabled/readonly (185-219); (3) integrates with Form state and touched registry (221-256). Paths covered: ARIA wiring (aria-labelledby, aria-invalid, aria-describedby, aria-required, role=alert, aria-live), disabled/readonly guards, Form integration.
  • impact: Field-provider tests cover core A30 wiring and Form integration. NO COVERAGE for A24 'readonly-without-value warning' (field is generic, doesn't hold value itself — A24 applies to value-holding fields like number-field). Test count is lean (3 it() blocks) but focused on the unique field responsibilities.
  • proposed-fix: Optional: add a test verifying that child inputs read disabled/readonly/required/invalid from the parent provider context. Current tests verify runtime wiring but not snippet props propagation. Consider: 'reads disabled/readonly/required/invalid from parent' to guard inheritance.
  • verify: [uncertain] Test exists (field-provider.svelte.test.ts, 256 lines, jsdom env, 3 it() blocks). Coverage is genuinely good for the field's unique responsibilities: ARIA wiring incl aria-labelledby/aria-invalid/aria-describedby join (141-179), disabled/readonly input guards (185-219), Form integration + touched registry + unregister-on-cleanup (221-255). The real, narrow gap the candidate names is legitimate: no explicit assertion that descendant inputs READ disabled/readonly/required/invalid from the parent context (snippetProps inheritance is computed but only the FieldInputProvider's own props are asserted, e.g. 'required: true' at 146 comes from the input part). Holds at MEDIUM as a low-risk test-coverage gap, not a confirmed bug. F: provider test PRESENT, env jsdom (SYS-3 noted).
  • fix-status: open

No-findings dimensions

A (contract: morfo scope/naming/parts), C (DOM selector), G (redundancy)

Theming facts (E-bis)

  • magic z-index: none
  • magic literals: none
  • undeclared parts: none
  • roles clean: true · variants clean: true
  • label-font (one step below input?): Clean: label font-size is calc(control-font - 2px) per base.ts recipe. Label renders at ONE step below input per CSS line 154. Scales correctly with size prop (xs/sm/md/lg/xl).

Tests (F)

  • exists: true · env: jsdom
  • covers: ARIA wiring (aria-labelledby, aria-invalid, aria-describedby, aria-required, role, aria-live); input value update with disabled/readonly guards; Form Provider integration (registerField, unregisterField, getFieldState, touched registry)
  • untested: Child inheritance of disabled/readonly/required/invalid from parent context (snippet props verified, but context propagation to child .svelte components not exercised); Cleanup of id registration on unmount (tested via effect cleanup but not via explicit unmount/remount cycle)

Powered by TurnKey Linux.