Problem
The tsan-threadfuzz-midgc job in main run https://github.com/zig-utils/zig-js/actions/runs/29380249887/job/87242192302 failed deterministically for seed 1:
worker terminate/ThreadLocal asyncHold waiters did not reject after midgc releasepublishThreadCompletion() sets ThreadRecord.done = true and wakes synchronous joiners before the finishing thread settles the snapshotted pending_joins. Thread.join() waits only for done, so it can return and drain the joiner queue in that gap. The fuzz oracle can then observe joined threads but not the corresponding asyncJoin().then(... rejection ...) callbacks. TSan makes the publication/settlement window large enough to reproduce.
Scope
- distinguish result publication from completion of the pre-existing async-join settlement snapshot
- make
Thread.join()wait for both transitions - wake joiners after the snapshot is fully settled
- add a deterministic regression that forces the publication/settlement ordering
- run focused unit/TSan coverage and rely on the next combined CI run for the expensive full mid-GC fuzz matrix
This is a runtime ordering bug exposed while validating #106, not an infrastructure failure.