Skip to content

[code-quality] Add FIXME(pointer-capture-race) comment + small cleanups in migrated files #97

@fedorovvvv

Description

@fedorovvvv

Source: PRD-018 SC-2 audit — minor warnings consolidated.

A handful of small, low-risk cleanups across the migrated files. Bundling them into one issue.

1. Silent try/catch needs FIXME (rule 10)

template/src/widgets/timeline/ui/Timeline.svelte:97-105

releasePointerCapture is wrapped in try { … } catch {} without a comment. Per .claude/rules/10-comments-policy.md, suppressed errors require // FIXME(reason): …. Add:

// FIXME(pointer-capture-race): release may throw if onPointerDown was preempted by capture transfer

2. Inline <span class="kind"> re-implements Badge (Arch [W13])

template/src/widgets/insights-rail/ui/InsightsRail.svelte:647-655

The widget uses <Badge variant="ghost" size="sm" class="kind"> correctly elsewhere (e.g. ArtifactPanel.svelte:188). Replace the inline <span class="kind"> with the same <Badge> (after Badge tone="mono" lands — see rule-24 cleanup tracker).

3. InsightsRail double-call of t.badge() (Logic [W3], Frontend [W10])

template/src/widgets/insights-rail/ui/InsightsRail.svelte:97

{#if t.badge() !== null && t.badge() !== 0}
  <Badge ...>{t.badge()}</Badge>
{/if}

Three calls per tab per render. Use {@const}:

{#each TABS as t (t.key)}
  {@const n = t.badge()}
  ...
  {#if n !== null && n !== 0}<Badge ...>{n}</Badge>{/if}
{/each}

Also: n !== 0 check is dead (badge: () => x.length || null already collapses 0 → null). Drop one.

4. Missing key on InsightsRail {#each TABS} (Frontend [W7])

Same file, line 89. Stable identity, no real bug, but every other widget uses keyed each. Add (t.key) for consistency.

5. PaneFrame drag-guard depends on Select internals (Logic [W6])

template/src/widgets/mosaic/ui/PaneFrame.svelte:36-49

closest("[data-select-trigger], …") relies on shared/ui/Select emitting that attribute on its trigger. Verify it does; if not, the drag-guard silently no-ops on the Select's trigger zone. Add a // TODO(select-trigger-marker): confirm shared/ui/Select forwards data-select-trigger if the verification is deferred.

6. Timeline fetch lacks AbortController (Security [W3])

template/src/widgets/timeline/ui/Timeline.svelte:43-66

Slow /api/timeline-events will leave loadingEvents=true for the lifetime of the request. Add AbortController with a timeout (matches the server's 10s GIT_TIMEOUT_MS).

7. Clipboard fallback DOM leak edge case (Security [W2])

template/src/widgets/artifact-panel/ui/ArtifactPanel.svelte:91-108

document.body.removeChild(ta) runs in finally only after ta.select() — if ta.select() throws (rare; iOS Safari), the textarea is leaked. Wrap from ta.select() inside the try. Already has TODO(clipboard-fallback).

Acceptance

Each item resolved or marked as a TODO with a tracking issue. Single PR is fine.

Audit traceability

  • Reviewers: Logic, Frontend, Security

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentation

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions