Skip to content

Audit: multi-instance and concurrent usage of core runtime primitives #337

Description

@smiggleworth

Purpose

This is an audit task, not a bug report — it produces a test matrix and spins off bugs, it doesn't fix anything itself.

Bugs that only appear when a stateful primitive is used more than once concurrently (two components, two effects, nested scopes) are structurally invisible to tests that only ever exercise one instance at a time. askr-monaco's global-theme conflict (filed against a sibling package, but caused by the same class of gap) is the model case for what this category is meant to catch — verify the equivalent doesn't exist in core.

Procedure

For each of the following core primitives, write or locate a test that exercises two or more concurrent/nested instances simultaneously, not sequentially:

  • src/runtime/scheduler.ts — two independent flush cycles / two callers of waitForFlush() overlapping
  • src/runtime/state.ts — two state cells with cross-referencing updaters; a .set() call from within another cell's updater (see Scheduler.waitForFlush() leaks waiter entries on timeout #332's sibling concern from the earlier audit)
  • src/runtime/effect.ts — two effects both scheduled in the same flush, one triggering the other
  • src/runtime/resource-cell.ts — two resources sharing a dependency, racing to resolve
  • src/runtime/component-scope.ts / component-internal.ts — two component instances mounted to sibling DOM nodes, one unmounting while the other re-renders
  • src/control/for.ts — two <For> lists reconciling in the same flush

Definition of Done

  • Each primitive above has a corresponding row in this issue's description: "✅ concurrent-usage test exists at <path>" or "🔗 gap filed: <issue link>" (a missing test that reveals no actual bug still gets a test added, tracked here, not just noted).
  • No row is left unmarked.

Audit results (2026-08-24)

Primitive Concurrent-usage evidence Result
Scheduler tests/jsdom/runtime/hardening-matrix.test.tsx (overlapping waiters); tests/jsdom/runtime/scheduler-invariants.test.tsx (independent tasks and active-flush enqueue)
State tests/jsdom/runtime/hardening-matrix.test.tsx (cross-cell reentrant updater)
Effect tests/jsdom/runtime/effect-invariants.test.ts (two effects on one source; sibling-triggered draining)
Resource tests/jsdom/runtime/hardening-matrix.test.tsx (two resources sharing a changing dependency with stale/new races)
Component ownership tests/jsdom/runtime/hardening-matrix.test.tsx (owner unmount during active global flush); tests/jsdom/app/cleanup-invariants.test.tsx (async work after sibling cleanup)
For tests/jsdom/runtime/hardening-matrix.test.tsx (two independent lists reconcile in one flush)

Implementation: #346. No runtime defect was exposed, so no gap issue was required.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions