Severity: medium — missing trap escalates to an internal assert (jspi mode).
SITE 5 (intrinsics/async_builtins.ts:474-486) parks a sync subtask.cancel
via blockCurrentActivation({readyFunc: () => st.resolved(), ...}) and
never sets hasSyncWaiter. The reference's wait_for_pending_event sets
has_sync_waiter for the duration (definitions.py:786-790, reached from
canon_subtask_cancel :2491), which is what makes a concurrent
waitable.join trap (canon_waitable_join, definitions.py:2463). The
repo's own join-time trap exists (async_builtins.ts:362-365) but can never
fire on this path. The stream twin does this correctly — SITE 4,
stream_builtins.ts:305-323.
Escalation: with the illegal join admitted, another task's
waitable-set.wait can steal the SUBTASK event between resolution and the
cancel's resume; finishSubtaskCancel (:403-419) then calls
getPendingEvent() with no pending event and dies in assert_
(task/waitable.ts:70) — an internal AssertionError where the reference
makes the misuse a trap at the join.
Fix: mirror SITE 4 — set hasSyncWaiter before the park, clear it in
produce, and use hasPendingEvent() (not resolved()) as the ready
condition, matching the reference's wait target.
Found in the 2026-08-10 adversarial conformance review (runtime + translator vs component-model @ 73b7ad5 definitions.py; wasmtime-environ 47.0.3 treated as trusted).
Severity: medium — missing trap escalates to an internal assert (jspi mode).
SITE 5 (intrinsics/async_builtins.ts:474-486) parks a sync
subtask.cancelvia
blockCurrentActivation({readyFunc: () => st.resolved(), ...})andnever sets
hasSyncWaiter. The reference'swait_for_pending_eventsetshas_sync_waiterfor the duration (definitions.py:786-790, reached fromcanon_subtask_cancel :2491), which is what makes a concurrent
waitable.jointrap (canon_waitable_join, definitions.py:2463). Therepo's own join-time trap exists (async_builtins.ts:362-365) but can never
fire on this path. The stream twin does this correctly — SITE 4,
stream_builtins.ts:305-323.
Escalation: with the illegal join admitted, another task's
waitable-set.waitcan steal the SUBTASK event between resolution and thecancel's resume;
finishSubtaskCancel(:403-419) then callsgetPendingEvent()with no pending event and dies inassert_(task/waitable.ts:70) — an internal AssertionError where the reference
makes the misuse a trap at the join.
Fix: mirror SITE 4 — set
hasSyncWaiterbefore the park, clear it inproduce, and usehasPendingEvent()(notresolved()) as the readycondition, matching the reference's wait target.
Found in the 2026-08-10 adversarial conformance review (runtime + translator vs component-model @ 73b7ad5 definitions.py; wasmtime-environ 47.0.3 treated as trusted).