Dependency: zig-utils/zig-gc#29 Related: #96
Evidence
Fresh main run 29464204902 failed tsan-threadfuzz-midgc with three races from the same allocation-publication gap:
- zig-gc
headerForInteriorAddressread header magic while a mutator's allocator zeroed a fresh cell slab; - the same classifier read header size during initialization;
claimMarktouched the mark bit while the slot was still being initialized.
The binding's owned-slab classifier currently treats every issued slot as classifiable. Slot reservation happens under the size-class lock before zig-gc initializes the header after allocation returns, so a conservative stack scan can observe private construction memory. This is distinct from #96's correctly diagnosed convergence-witness failure.
Evidence: https://github.com/zig-utils/zig-js/actions/runs/29464204902/job/87513830801
Acceptance
- Track header-published slots separately from issued/free backing slots under the existing size-class lock.
- Make exact payload and conservative-interior classifiers return only published slots.
- Publish only after zig-gc initializes the complete header; unpublish before magic clear/reuse.
- Preserve batch allocation, reuse accounting, bulk teardown, owned header validation, and collector performance.
- Add focused fresh/reused/batch/parallel transition coverage.
- Pass focused normal and TSan mid-GC checks, then one fresh full-main gate.