4.9 KiB
Audit: timeline
audit-version: 1 audited-at: 2026-06-26 scope: soma, sema, eidos (per morfo line 39: scope: ['soma', 'sema', 'eidos']) 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/timeline/timeline-provider.svelte.ts cleanup-audit (A6/A35/A36): CLEAN: Timeline provider and item provider have no timers (setTimeout/setInterval), no listeners (addEventListener, ResizeObserver, IntersectionObserver, MutationObserver, Gesture/pointer capture) to dispose. The emerge-reveal announce in TimelineItemProvider uses untrack() to avoid reactive depende
Summary
Counts (post-verification): CRITICAL 0 · HIGH 0 · MEDIUM 1 · LOW 0.
Findings
MEDIUM: High-risk paths must be tested (A35/A36 loops, live-region dispatch, gesture, timers, vali — timeline-001
- dimension: F: Tests
- rule: High-risk paths must be tested (A35/A36 loops, live-region dispatch, gesture, timers, validation, passive role values)
- location: src/uix/soma/components/timeline/timeline-provider.svelte.test.ts
- evidence: Tests cover status derivation, explicit status override, auto-indexing, and undefined status cases. Missing test for the
emerge-revealevent (live feed / post-sequence announcement). The event is critical to the component's feed mode. - impact: The emerge-reveal event and live feed behavior are not validated by automated tests. Integration/e2e tests may cover this, but unit test for the post-render one-shot announcement when shouldEmerge=true is absent.
- proposed-fix: Add a test case that verifies: (1) items in the initial render do NOT fire emerge-reveal (shouldEmerge=false), (2) items appended after the provider's $effect runs (ready=true) DO fire emerge-reveal one-shot, (3) the event resolves the item's intent prop correctly.
- verify: [confirmed] CONFIRMED. timeline-provider.svelte.test.ts has 4 tests (lines 70, 114, 143, 165): status-from-active, explicit-status-override+intent, auto-index, and undefined-status. ALL construct the provider with live=false: timelineOpts default is
live = false(line 44) and every call site passes false or omits it —timelineOpts(1, false, root)(79,121,148) andtimelineOpts(null)(168). Theemerge-revealone-shot is gated byshouldEmerge = this.provider.live && this.provider.ready(provider line 142) and fired in the item$effect(lines 162-168):if (fired || !shouldEmerge) return; const el = opts.ref.current; if (!el) return; fired = true; untrack(() => void this.runtime.trigger('emerge-reveal', { fallbackTarget: el })). Because no test sets live=true, this entire branch — the component's ONLY semantic event and its central feed-mode behavior (morfo line 44-61, expression:'pack') — is never exercised. Maps to dimension F RISK list (live-region/feed dispatch). MEDIUM (missing test on a high-risk path), high confidence. Note on proposed fix: theuntrack(trigger)correctly prevents an A35/A36 loop (refuted as a concern) andfiredis a plainletnot reactive state, so the test only needs to assert the trigger fires once for an appended item and stays silent for the initial batch / when live=false; intent resolution itself happens downstream in the sema cascade via the per-item runtimeprops.intentsource (provider line 149), so assert the trigger/target rather than intent value directly. - fix-status: open
No-findings dimensions
A: Contract (morfo), B: Behavior (soma), C: DOM-selector, D: Frontier, E: TSC/theming, G: Redundancy
Theming facts (E-bis)
- magic z-index: none
- magic literals: 1em (font-size on Title/Description — inheriting from parent, acceptable pattern) | 50% / -50% (horizontal align=alternate centering — layout-specific, acceptable)
- undeclared parts: none
- roles clean: true · variants clean: true
Tests (F)
- exists: true · env: jsdom / vitest
- covers: status derivation from active index; explicit status override; auto-indexing by registration order; undefined status when active=null; intent prop projection; data-timeline and data-timeline-item marker emission; aria-current conditional on current status
- untested: emerge-reveal event firing in live feed mode; one-shot behavior (should not re-fire); post-sequence timing (item attached before event); shouldEmerge=false in initial render; shouldEmerge=true on append after provider ready
Style observations (non-blocking)
- The z-index:1 on [data-timeline-marker] is a local stacking context to layer the marker above the connector line — acceptable and well-commented.
- The 50% / -50% transform centering in horizontal align=alternate is layout-specific and acceptable (not a magic value for spacing/sizing).