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.
50 lines
5.9 KiB
50 lines
5.9 KiB
# Audit: image-adjustments
|
|
audit-version: 1
|
|
audited-at: 2026-06-26
|
|
scope: (SCOPE-DRIFT → SYS-1)
|
|
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: src/uix/soma/components/image-adjustments/image-adjustments-provider.svelte.ts
|
|
cleanup-audit (A6/A35/A36): No $effect in ImageAdjustmentsProvider or sub-providers that manage timers, listeners, or observers. No setTimeout, setInterval, addEventListener, ResizeObserver, IntersectionObserver, MutationObserver, or pointer capture in the ImageAdjustments layer (all delegated to composed <Slider>). The test f
|
|
|
|
## Summary
|
|
Counts (post-verification): CRITICAL 0 · HIGH 0 · MEDIUM 1 · LOW 0.
|
|
|
|
## Findings
|
|
### MEDIUM: SYS-1 — Scope-Drift: eidos directory exists but morfo scope does not include 'eidos' — image-adjustments-003 <!-- id: image-adjustments-003 -->
|
|
- dimension: D
|
|
- rule: SYS-1 — Scope-Drift: eidos directory exists but morfo scope does not include 'eidos'
|
|
- location: src/uix/morfo/components/image-adjustments.ts:18 vs src/uix/eidos/components/image-adjustments/
|
|
- evidence: The morfo declares scope: ['soma', 'sema'] (line 18), but a full eidos implementation exists at src/uix/eidos/components/image-adjustments/ containing image-adjustments.svelte, image-adjustments.css, types.ts, README.md, and index.ts. Per the baseline, this is a confirmed systemic issue (SYS-1) affecting several B7 components.
|
|
- impact: Scope mismatch: the morfo's declared scope does not reflect reality. Tooling relying on scope declarations may fail to validate or organize the eidos layer. No functional impact on the component itself, but the contract is misleading.
|
|
- 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'].
|
|
- fix-status: fixed (212624e0)
|
|
|
|
## No-findings dimensions
|
|
B, C, F, G
|
|
|
|
## Theming facts (E-bis)
|
|
- magic z-index: none
|
|
- magic literals: none
|
|
- undeclared parts: none
|
|
- roles clean: true · variants clean: true
|
|
|
|
## Tests (F)
|
|
- exists: true · env: jsdom
|
|
- covers: computeImageFilter: neutral (none), tone functions (brightness/contrast/saturation/hue), 0-based (blur/grayscale/sepia), temperature approximation (warm/cool), multi-adjustment composition; ImageAdjustmentsProvider: live filter derivation, isModified tracking, setAdjustment mutation + callbacks, reset() via runtime trigger, custom adjustments subset, disabled state blocks mutations, catalog + defaults exposed; ImageAdjustmentsItemProvider: derived value/label/formattedValue per adjustment, setValue callback; Snippet props exposure and live callback routing
|
|
- untested: A15 gesture: pointer interaction is delegated to the composed <Slider>, not handled directly by ImageAdjustments. Pointer cleanup verified in Slider tests, not here.; A6 timers/listeners: no direct setTimeout/setInterval/addEventListener/ResizeObserver/etc. in ImageAdjustments provider or components. Interaction heavy lifting delegated to Slider.; A35 effect loop: no per-item $effect reading opts.ref.current and writing provider state. No reactive loop risk.; A36 microtask loop: no async (.then/microtask/setTimeout) writing reactive vars without untrack. Callbacks (onValueChange/onFilterChange) are consumer-driven, not effect-mediated.; Live region: the component does not emit a live region for adjustment changes (per README: 'ItemValue is a plain <span>, not a live region. The Slider thumb already announces aria-valuenow'). Announcement delegated to composed Slider.; A30 id registration: no child->parent id registration loop. Each part registered directly via runtime.part() in the constructor.
|
|
|
|
## Style observations (non-blocking)
|
|
- CSS correctly uses data attribute selectors matching the morfo kebabs: [data-image-adjustments], [data-image-adjustments-item], [data-image-adjustments-item-label], [data-image-adjustments-item-value], [data-image-adjustments-reset].
|
|
- Reset button uses :focus-visible for keyboard navigation cue (line 70-74), not hardcoded :focus. Correct.
|
|
- Reset button uses var(--focus-ring-width) and var(--focus-ring-color), consuming the canonical two-ring focus model from the theme. Correct.
|
|
- Disabled state uses var(--opacity-disabled) (line 19, 77). Correct token usage.
|
|
- Reset hover state applies var(--color-content-primary), correct semantic color. Line 67.
|
|
- Hue row track override correctly uses var(--image-adjustments-hue-track), exiling the literal rainbow to the recipe layer (line 86). Correct raw-color contract.
|
|
- No hardcoded :active, no magic z-index, no raw hex. All CSS tokens correctly namespaced to component.
|
|
- Row typography uses var(--font-size-sm/xs), var(--font-weight-medium), var(--font-mono) — all reference the base tokens, not px/rem literals. Correct.
|
|
- Spacing uses var(--space-*) and var(--image-adjustments-*) recipe tokens. No hardcoded gap/margin px values. Correct.
|
|
- Reset focus-visible outline uses canonical --focus-ring-width + --focus-ring-color, not hardcoded values. Correct.
|
|
- Tabular numerals (font-variant-numeric: tabular-nums) on ItemValue to prevent reflow during drag — good UX consideration (line 48).
|