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

7.1 KiB

Audit: announce

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: src/uix/soma/components/announce/announce-provider.svelte.ts cleanup-audit (A6/A35/A36): Line 75-77: Single $effect with cleanup return (clearTimers()). Disposes: politeTimer and assertiveTimer via cancel() if present (lines 149-161). Timers are scheduled via soma.uix.timers.schedule() (A6 compliant). Global createAnnouncer (global.svelte.ts): timers stored in RegionPair.timer and cance

Summary

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

Findings

MEDIUM: eidos CSS selectors must match morfo-declared or runtime-auto-generated attributes. A decl — announce-001

  • dimension: E-bis: Theming / Selector drift
  • rule: eidos CSS selectors must match morfo-declared or runtime-auto-generated attributes. A declared prop like visuallyHidden must have a corresponding data attribute or inline style to drive styling.
  • location: src/uix/eidos/components/announce/announce.css:23
  • evidence: Line 23 uses selector [data-announce-region]:not([data-visually-hidden]) to style visible regions. However, data-visually-hidden attribute is never written by soma. The provider (announce-provider.svelte.ts:246) writes inline style when hidden, but never writes a data-* attribute to signal visibility state to eidos.
  • impact: The CSS selector :not([data-visually-hidden]) always matches because the attribute is never present. This means card styling (display, padding, border, etc.) is incorrectly applied to ALL regions, including those where visuallyHidden=true (which should be sr-only with no card chrome).
  • repro: Mount an Announce.Region with visuallyHidden={false}. The region will receive card styling (padding, border, etc.). Mount another with visuallyHidden={true} (default). It will ALSO receive card styling, breaking the sr-only case.
  • proposed-fix: Option A: Modify AnnounceRegionProvider.props (line 242-248) to write data-visually-hidden: hidden ? '' : undefined so the CSS :not([data-visually-hidden]) selector works correctly. Option B: Change the CSS selector to check for inline style presence (not reliable) or add a separate data-visible attribute when visuallyHidden is false. Recommend Option A with a morfo data declaration for the attribute.
  • verify: [downgraded] MECHANISM CONFIRMED, IMPACT REFUTED. Confirmed: data-visually-hidden is NEVER written anywhere. Morfo (announce.ts:88-99) declares only data-role+data-live on the region part; the provider (announce-provider.svelte.ts:243-247) drives visuallyHidden ONLY via inline style: hidden ? VISUALLY_HIDDEN_STYLE : undefined; grep across soma+eidos finds no writer of the attr (announce.css:23 is the sole reference). So [data-announce-region]:not([data-visually-hidden]) (announce.css:23) ALWAYS matches — the negation is dead/non-functional CSS; the 'visible regions only' guard the author intended never excludes the sr-only case. THAT part is a real selector-drift defect (E-bis), MEDIUM stands. BUT the candidate's IMPACT ('incorrectly applied to ALL regions ... breaking the sr-only case') is REFUTED: when visuallyHidden=true, soma sets the inline sr-only style (position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0)) which has higher specificity than the stylesheet rule and overrides padding:0/border:0 inline (lines 12-22). The leftover display:block/background/border-radius/font-size/line-height from the CSS block are visually inert on a 1x1px clipped box — the region stays hidden. So the sr-only case is NOT broken; the defect is dead CSS / a non-functional visible-vs-hidden distinction, not an a11y/visual regression. Keeping MEDIUM but correcting the rationale/impact.
  • fix-status: open

MEDIUM: eidos CSS selectors must key off attributes the morfo declares or soma actually writes; a — announce-101

  • dimension: E-bis: Theming / selector drift, SYS-1-adjacent
  • rule: eidos CSS selectors must key off attributes the morfo declares or soma actually writes; a :not([attr]) guard against an attribute that is never emitted is dead CSS that silently never differentiates state.
  • location: src/uix/eidos/components/announce/announce.css:23
  • evidence: [data-announce-region]:not([data-visually-hidden]) { display:block; padding:...; border:...; background:...; } — but data-visually-hidden is never written: announce.ts:88-99 declares only data-role and data-live on the region part, and announce-provider.svelte.ts:243-247 drives visuallyHidden exclusively via inline style (hidden ? VISUALLY_HIDDEN_STYLE : undefined), never a data attribute. Grep across soma+eidos confirms no writer.
  • impact: The intended 'visible regions only' branch is non-functional: the :not() negation always passes, so the visible-card rule applies to every region. It is masked in the default (visuallyHidden=true) case because the higher-specificity inline sr-only style clips the box, so there is no user-visible regression today — but the CSS no longer expresses the visible-vs-hidden intent and will silently mis-style if the inline style ever changes. Dead-code distinction.
  • repro: Mount <Announce.Region visuallyHidden={false}> and <Announce.Region visuallyHidden={true}>; inspect computed styles — the visible-card rule (display:block/background/font-size) resolves on BOTH because :not([data-visually-hidden]) matches both; only the inline sr-only clip differentiates them, not the CSS branch as intended.
  • proposed-fix: Either (a) project the state as a real attribute the CSS can key on — e.g. declare data-visually-hidden in the region part's morfo data and have soma write it from opts.visuallyHidden, then keep :not([data-visually-hidden]); or (b) gate the visible-card chrome on an opt-in attribute the consumer sets (e.g. data-variant='visible') rather than a negation of a never-present attr. Option (a) keeps the existing selector working.
  • verify: [verifier-added] added by adversarial verify pass
  • fix-status: open

No-findings dimensions

A: Contract (morfo), B: Behavior (A35/A36/A6/A15/live-regions/A30/A33/A31), C: DOM-selector, D: Frontier, E: TSC, F: Tests, G: Redundancy

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 via vitest
  • covers: timer scheduling and cancellation via soma.uix.timers; A/B toggle for repeated announcements; role/aria-live derivation; declarative region attrs sync; standalone region without provider; provider context context injection
  • untested: visible region CSS application (visuallyHidden=false styling); async timer edge cases under network throttle; cross-document announcer (createAnnouncer in iframe/shadow DOM)

Powered by TurnKey Linux.