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

37 lines
5.1 KiB

# Audit: metrics
audit-version: 1
audited-at: 2026-06-26
scope:
method: adversarially-verified workflow; HIGH lead-verified. B7 ground-truth: Toolbar A35 + Form A36 incidents STAYED FIXED (untrack present); toast/clipboard/drag-drop use uix.timers (no A6 leak); button is clean (its archetype finding was inert — Spinner not runtime-registered); data-size/data-shape are eidos visual attrs (not contract violations).
provider: G:/dev/svelte/vicen/src/uix/soma/components/metrics/metrics.svelte.ts (runtime-only, no traditional provider)
cleanup-audit (A6/A35/A36): No timers, setInterval, ResizeObserver, IntersectionObserver, MutationObserver, addEventListener, or pointer listeners declared in eidos or soma directories. A35 loop check: metrics-delta's $effect writes to context.setIntent (line 46-48), which updates root's currentIntent state, but no component r
## Summary
Counts (post-verification): CRITICAL 0 · HIGH 0 · MEDIUM 1 · LOW 0.
## Findings
### MEDIUM: F (Tests): a component with a non-trivial soma runtime path (live-region dispatch + value- — metrics-no-runtime-test <!-- id: metrics-no-runtime-test -->
- dimension: F
- rule: F (Tests): a component with a non-trivial soma runtime path (live-region dispatch + value-change effect + intent-publish effect) should have a provider/runtime test mapping the RISK paths. None exists.
- location: src/uix/soma/components/metrics/ (no *.test.ts) — verified via find/grep: zero files reference metricsMorfo/createMetricsRuntime/notifyUpdate in any *.test.ts/*.spec.ts
- evidence: `createMetricsRuntime` (metrics.svelte.ts:17) is exercised through three reactive code paths with no coverage: (1) the live-signal dispatch — metrics.svelte:57-63 `notifyUpdate` → `runtime.trigger('signal-notify-update', { fallbackTarget: el, message: text })`, which routes through `uix.announce` via the morfo's `a11ySemantic.requiresLiveRegion` (metrics.ts:64); (2) the value-change detector — metrics-value.svelte:21-32 (`prev`/`firstRun` memo, the `live`-off no-op path, and the first-run-suppressed path); (3) the intent-publish effect — metrics-delta.svelte:46-48. These are exactly the live-region/effect paths the audit flags as high-risk, yet there is no test asserting the trigger fires only on a real change, stays inert when `live` is off, suppresses the first run, and announces `message`.
- impact: Regressions in the live-update signal (e.g. re-introducing a first-run announce, or firing when value is unchanged, or breaking the `live`-off no-op gate) would ship silently. The change-detection memo logic (metrics-value.svelte:18-32) is subtle and untested.
- repro: find/grep over src for metric*test / metricsMorfo|createMetricsRuntime|notifyUpdate in *.test.ts returns nothing.
- proposed-fix: Add src/uix/soma/components/metrics/metrics.svelte.test.ts (or a runtime test) using a real ActiveUix via createActiveUix/attachActiveUix (never a fake announce per project rule): assert `notifyUpdate` triggers `signal-notify-update` only on a value change when `live` is on, is a no-op when `live` is off, suppresses the first run, and forwards `message` to the live region.
- verify: [verifier-added] added by adversarial verify pass
- fix-status: open
## No-findings dimensions
A: Contract (morfo scope satisfies, parts declared and present, 2-of-3 rule, part data-* naming correct, aria declarations present), B: Behavior (A35: no per-item effect reading opts.ref.current + writing provider state; A36: no async-microtask-mediated freeze; A33: no $state(Map/Set) non-reactive; A31: no O(N²) derived with global provider reads; A6: no timers/observers/listeners declared; A30: no child->parent id registration in $effect; A15: no gesture; LIVE REGIONS: signal-notify-update correctly dispatched via runtime.trigger with message + announce; A34: announce provider reachable), C: DOM-selector (no interpolated consumer values; global document/window not used), D: Frontier (no soma imports from eidos; no eidos imports from soma except in root to call createMetricsRuntime; data-size/color/variant are visual attrs; Progress/Gauge use framework Meter composition), E: TSC tokens (all spacing via --space-* tokens; all icon-size via --icon-size-*; all color via CSS custom properties; no hardcoded focus-ring or :active), E-bis Theming (Delta composes Badge which uses canonical color roles; featured icon colors use 9 canonical roles; no hardcoded hex; recipe tokens via --metrics-* private scale), F: Tests (no test file present - gap noted but not violation per baseline), G: Redundancy (standard context pattern for live-signal bridge; no gesture re-implementation)
## Theming facts (E-bis)
- magic z-index: none
- magic literals: none
- undeclared parts: none
- roles clean: true · variants clean: true
## Tests (F)
- exists: false · env: N/A
- covers:
- untested: signal-notify-update dispatch when live=true and value changes; intent derivation (trend vs goodTrend); size cascading to sub-parts (Badge, Meter, icon size); aria-label generation on Delta; part composition (Badge, Meter, Sparkline) integration; reduced-motion behavior (if applicable); announce() called with correct priority (polite/assertive)

Powered by TurnKey Linux.