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/picker-shell.md

53 lines
6.7 KiB

# Audit: picker-shell
audit-version: 1
audited-at: 2026-06-26
scope: INTERNAL morfo (morfo/internal/picker-shell.ts) (SCOPE-DRIFT → SYS-1)
method: adversarially-verified workflow (analyze → refute); HIGH/CRITICAL personally re-verified by the lead. Batch-3 ground-truth: each picker fires trigger(close) (close NOT inert), but open/commit-reset ARE inert; calendar/range-calendar are MID-REFACTOR (uncommitted view-switch work).
provider: src/uix/soma/components/picker-shell/components/picker-shell.svelte
## Summary
Counts (post-verification): CRITICAL 0 · HIGH 0 · MEDIUM 1 · LOW 1.
systemic hits: SYS-1 scope-drift (known pattern per audit baseline).
composition (A27): Re-export pattern (A27 verified): Clear/Cancel/Close compose Button (proper wrapper). Footer/Header/Body are pure layout zones. Picker-shell parts are imported and re-exported under DatePicker/ColorPicker/etc namespaces, not re-implemented. Shared-ref wiring: pickerShellContext set by host picker provider (DatePickerProvider.pickerShellHandle), read by Footer/Clear/Cancel/Close via getPickerShellHandle().
## Findings
### MEDIUM: SYS-1 SCOPE-DRIFT — picker-shell-001 <!-- id: picker-shell-001 -->
- dimension: A
- rule: SYS-1 SCOPE-DRIFT
- location: src/uix/morfo/internal/picker-shell.ts:32 (morfo scope declaration)
- evidence: Morfo declares `scope: ['soma']` at line 32, but eidos directory exists at `src/uix/eidos/components/picker-shell/` with 7 visual components: picker-shell.svelte, picker-shell-header.svelte, picker-shell-body.svelte, picker-shell-footer.svelte, picker-shell-clear.svelte, picker-shell-cancel.svelte, picker-shell-close.svelte. Comment at line 23 explicitly states 'Scope is `soma` only' but implementation contradicts.
- impact: Morfo contract mismatch: scope declaration does not reflect actual layer composition. Audit tools scanning morfo/components/ correctly skip this (internal placement), but if ever moved to public, scope would need updating.
- 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.
- fix-status: fixed (212624e0)
### LOW: Unused emitted data attribute — picker-shell-002 <!-- id: picker-shell-002 -->
- dimension: E-bis
- rule: Unused emitted data attribute
- location: src/uix/eidos/components/picker-shell/picker-shell.svelte:19 and picker-shell-footer.svelte:15
- evidence: Both picker-shell.svelte and picker-shell-footer.svelte emit `data-mode={mode}` attribute (`<div data-picker-shell data-mode={mode} ...>` and `<div data-picker-footer data-mode={mode} ...>`) but this attribute is never consumed — not referenced in picker-shell.css, not grepped in any CSS, not used by sema or other components.
- impact: Dead attribute emitted to DOM; adds noise without utility. Low impact cosmetic issue.
- repro: grep -n 'data-mode' src/uix/eidos/components/picker-shell/*.svelte src/uix/eidos/components/picker-shell/*.css — only .svelte files match, no .css usage found.
- proposed-fix: Either remove `data-mode={mode}` from both components if unused, OR add CSS rules consuming it (e.g., `[data-picker-footer][data-mode='modal']`) if modal-specific styling is intended.
- verify: [confirmed] Confirmed. picker-shell.svelte:19 `<div data-picker-shell data-mode={mode} {...rest}>` and picker-shell-footer.svelte:15 `<div data-picker-footer data-mode={mode} {...rest}>` both emit data-mode, where `mode = $derived(shell?.getMode() ?? 'inline')`. grep for 'mode' in picker-shell.css => 'No matches found'; grep 'data-mode' across all of src/uix => only the two emit sites; no sema file references getMode/data-mode. The comment at picker-shell.svelte:10-12 ('reads `mode` off `pickerShellContext` ... so the CSS can react to inline vs modal') states an intent the CSS never fulfills — the attribute is inert/dead today. getMode() is a real interface method (picker-shell-handle.svelte.ts:21), so it does not crash; purely a dead attribute / unfulfilled-comment-intent. LOW cosmetic is correct.
- fix-status: open
## No-findings dimensions
B, C, D, E, F, G
## Theming facts (E-bis)
- magic z-index: none
- magic literals: none
- undeclared parts: Header | Body | Footer | Clear | Cancel | Close
- roles clean: true · variants clean: true
- conformance: Internal morfo with minimal contract (1 part: Provider). Eidos-layer parts (Header/Body/Footer/Clear/Cancel/Close) are NOT declared in morfo but ARE properly exported and composed. This is by design per the INTERNAL status. All tokens follow canonical naming (--space-*, --color-*, --font-*, --border-width). No magic hex/rgb/hsl/z-index. No double-write or syncAttrs issues. A27 composition verified: parts are re-exported by 5 picker families, not re-implemented.
## Tests (F)
- exists: false · env: N/A
- covers:
- untested: Context registration flow; pickerShellHandle contract across inline/modal modes; Clear/Cancel/Close button click handlers; Visual context size propagation; Popover content scoping by picker-size
## Style observations (non-blocking)
- CSS is clean, readable, well-commented. Uses custom properties for spacing/sizing uniformly. Clear separation of layout concerns (gap, alignment, borders) vs component-owned styling (Button recipe owns button chrome). Selector specificity is appropriate for scoped composition (`[data-popover-content][data-picker-size='X']` cascade).

Powered by TurnKey Linux.