ReviewOS

zig-utils/zig-js

Threads: promote remaining WebKit PR-249 reference cases

#11
Closed chris opened this 9 days ago ·
9 days ago

Parent: #1

Goal

Promote reference-only WebKit PR-249 files only when zig-js implements the underlying behavior, while keeping blockers machine-auditable.

Current baseline

The allowlist has 236 promoted files out of 259 executable files: 234 in the default corpus plus 2 no-GIL-only witnesses. zig build threads-reference-audit rejects uncategorized executable cases, and maintained negative probes verify the nearest blockers. The audit currently classifies 23 executable reference-only files plus 5 helper/preload files.

Remaining categories

  • WebAssembly-dependent witnesses.
  • JIT/compiler hooks, code-artifact hooks, and shell controls not exposed by zig-js.
  • JSC heap snapshot / preventCollection / shared-GC mark-list hooks.
  • JSC-specific butterfly verification assumptions that are not portable to zig-js.
  • Detached-source fresh-view construction assumptions that zig-js deliberately rejects after ArrayBuffer transfer.
  • Remaining semantic cases whose current failure evidence is listed by the audit tool.

Recently resolved from this tracker

  • semantics/oom-one-thread.js is promoted after the heap-cap collect/retry work.
  • The portable part of cve/mc-df-arraycopy-relabel.js is now covered by zig-js-owned TypedArray source-length snapshot witnesses; the reference file remains out for its JSC butterfly-verification shape.
  • The portable creator-owned buffer lifetime subset behind cve/mc-life-creator-thread-dies.js is covered by unit/threadfuzz witnesses; the reference file remains out for detached-source fresh-view construction.
  • Four additional PR-249 references were promoted in d74fa86c: cve/mc-init-butterfly-grow-slack.js, cve/mc-jit-delete-reuse-stale-offset.js, cve/mc-jit-double-relabel-stale-shape.js, and cve/mc-jit-ta-resize-hoisted-base.js.
  • b0f5193e promoted cve/mc-init-direct-arguments-override.js after bounding its no-GIL stress arm and fast-pathing mapped-arguments indexed get/set through exact local helpers; focused default and no-GIL runs pass, #35 is closed, and the audit now reports 236/259 promoted executable files with 23 executable reference-only files remaining.

Rules

  • Do not rewrite a reference test merely to make it pass.
  • Promote only with a focused engine test and the full allowlist gate.
  • Keep helper/preload files classified separately from executable cases.
  • Update expected blocker evidence when behavior changes.

Acceptance criteria

  • No missing or uncategorized executable files.
  • Promotion probes fail for documented reasons until the feature lands.
  • Every promoted case is green in normal and applicable no-GIL/TSan corpus legs.
9 days ago

Promoted congc-t1-window-split.js in 163638b9 after confirming its $vm-guarded compatibility path completes cleanly in zig-js.

Validation:

  • zig build threads-test -Dthreads-case=congc-t1-window-split.js — 1/1 passed
  • zig build threads-reference-audit — 230/259 executable files promoted; 29 executable reference-only cases and 5 helpers remain, all classified

The corpus timeout/drain adjustments in the same commit reflect isolated-process behavior observed while re-validating this promotion. The remaining categories in this issue are unchanged.

9 days ago

Advanced the blocker-audit side of #11 in a660f03 (tools(threads): sharpen reference blocker categories).

The audit still reports 230/259 executable PR-249 files promoted and no uncategorized executable files, but the closest promotion probes now use explicit blocker categories instead of the previous coarse unsupported shell option bucket:

  • cve/mc-df-arraycopy-relabel.js: JSC butterfly verification shell option, typed-array set length race semantics
  • cve/mc-life-creator-thread-dies.js: ArrayBuffer detach/resize survivor semantics
  • dw2-marklistset-storm.js: JSC shared-GC mark-list hooks
  • w16-c1-prevent-collection.js: JSC heap snapshot/preventCollection hooks
  • semantics/oom-one-thread.js: heap cap / per-thread OOM

Validation:

  • zig build threads-reference-audit
  • python3 tools/threads-reference-audit.py --format json
  • bun run docs:build
  • git diff --check

This does not promote any file; it keeps the reference-only tail more machine-auditable so future behavior changes point to a concrete missing feature or promotion decision instead of a generic option label.

9 days ago

Current audit snapshot:

  • python3 tools/threads-reference-audit.py --format json reports uncategorized = 0 and missing_allowlist_entries = 0.
  • Remaining reference-only categories are still concrete blockers: JSC shell/JIT/heap hooks, WebAssembly construction/grow/relocation, heap-cap/per-thread OOM, ArrayBuffer detach/resize survivor semantics, typed-array set length race shape, and helper/preload files.
  • Current promotion probes remain the same closest candidates (cve/mc-df-arraycopy-relabel.js, cve/mc-life-creator-thread-dies.js, dw2-marklistset-storm.js, w16-c1-prevent-collection.js, semantics/oom-one-thread.js) and still require feature work rather than allowlist paperwork.

No promotion made from this audit pass; the tail remains machine-auditable.

9 days ago

Added a cheap blocker-evidence gate in 78e85ff (tools(threads): add quick reference blocker probes).

What changed:

  • tools/threads-reference-audit.py --run-probes now supports --skip-timeout-probes, so expected timeout blockers can stay documented without making the quick promotion probe gate expensive.
  • New build step: zig build threads-reference-probes runs the audit with --run-probes --expect-current-blockers --skip-timeout-probes --probe-timeout 20.

Validation:

  • python3 -m py_compile tools/threads-reference-audit.py
  • zig build threads-reference-audit
  • zig build threads-reference-probes
  • git diff --check

Current probe evidence from the new gate:

  • cve/mc-df-arraycopy-relabel.js still fails with RangeError: offset is out of bounds.
  • cve/mc-life-creator-thread-dies.js still fails with TypeError: Cannot construct a TypedArray on a detached buffer.
  • semantics/oom-one-thread.js still fails with the expected heap-cap/per-thread-OOM evidence (heap cap fired on at least one thread, zero OOMs).
  • dw2-marklistset-storm.js and w16-c1-prevent-collection.js are skipped by this quick gate because their documented current blocker is timeout behavior.

No files promoted in this slice; the remaining tail is now easier to re-check before deciding whether a behavior change justifies promotion.

9 days ago

Current #11 audit/probe pass after the recent runtime/API chunks:

  • zig build threads-reference-audit still reports 230/259 executable PR-249 files promoted.
  • python3 tools/threads-reference-audit.py --format json reports uncategorized = [] and missing_allowlist_entries = [].
  • zig build threads-reference-probes confirms the current nearest blockers are still the documented blockers:
    • cve/mc-df-arraycopy-relabel.js: still fails with RangeError: offset is out of bounds for the typed-array/butterfly-style blocker.
    • cve/mc-life-creator-thread-dies.js: still fails with TypeError: Cannot construct a TypedArray on a detached buffer for detach/resize survivor semantics.
    • semantics/oom-one-thread.js: still fails with the expected heap-cap/per-thread-OOM evidence (heap cap fired on at least one thread, zero OOMs).
    • dw2-marklistset-storm.js and w16-c1-prevent-collection.js remain skipped in the quick probe gate because their current blockers are timeout/hook-oriented.

No promotion from this pass: the tail remains machine-auditable, and the failures still require feature work rather than allowlist paperwork.

9 days ago

Landed 4ca7f70 (tools(threads): expose reference audit counts).

What changed:

  • tools/threads-reference-audit.py --format json now includes direct top-level coverage fields: promoted_executable, executable_total, reference_only_executable, and helper_preload.
  • The fields mirror the nested allowlist / reference_only sections, so dashboards or issue-update scripts can read the current PR-249 status without understanding the full category schema.
  • No promotion semantics changed; the audit still reports 230/259 promoted executable files, 29 reference-only executable files, 5 helper/preload files, and no uncategorized or missing allowlist entries.

Validation:

  • python3 -m py_compile tools/threads-reference-audit.py
  • JSON consistency assertions for the new top-level fields
  • zig build threads-reference-audit
  • bun run docs:build
  • git diff --check
9 days ago

Current #11 audit after today's chunks remains unchanged but now has child trackers for the two implementable runtime blockers:

  • #24 — heap cap / per-thread OOM contract (semantics/oom-one-thread.js).
  • #25 — ArrayBuffer detach/resize survivor and typed-array race semantics (cve/mc-life-creator-thread-dies.js, cve/mc-df-arraycopy-relabel.js).

Audit evidence from python3 tools/threads-reference-audit.py --format json:

  • promoted_executable = 230 / executable_total = 259
  • reference_only_executable = 29
  • helper_preload = 5
  • uncategorized = []
  • missing_allowlist_entries = []

No files promoted in this pass: the nearest blockers still require runtime feature work or remain intentionally JSC/JIT/WASM/shell-hook-specific. Splitting #24/#25 should keep #11 focused on promotion state while giving the implementable blockers their own acceptance criteria.

9 days ago

Landed f3cb0cc: https://github.com/zig-utils/zig-js/commit/f3cb0cc01d039502dbf325303e4c0ada86f28f2e

This keeps the PR-249 audit honest for semantics/oom-one-thread.js: the reference probe now exercises zig-js's real Context.Options.heap_limit_bytes cap instead of failing vacuously because the original JSC RAM-cap directive is inert here.

The current blocker is now recorded as allocation-site catchable OOM semantics. Probe evidence:

FAIL semantics/oom-one-thread.js: OutOfMemoryError: Context heap limit exceeded

That means the cap fires, but the OOM escapes as whole-Thread completion instead of being observed by the local JS try/catch around the allocating expression.

Validation:

  • zig fmt conformance/threads_test.zig
  • PATH="/Users/chris/.local/bin:$PATH" python3 tools/threads-reference-audit.py --fail-on-uncategorized --run-probes --expect-current-blockers --skip-timeout-probes --probe-timeout 20
  • /Users/chris/.bun/bin/bun run docs:build
  • git diff --check

Opened #27 for the remaining runtime semantics work.

9 days ago

PR-249 OOM follow-up landed in 75a7e49: https://github.com/zig-utils/zig-js/commit/75a7e4980b5ad435dedeb7f646945950e0a81c31

The runtime now handles one nearer allocation-site OOM case: if a capped allocation fails while a JS handler is active, the tree-walker/VM can publish the prebuilt OutOfMemoryError as error.Throw and let JS catch it. A focused ArrayBuffer pressure regression passes.

The PR-249 witness is still correctly reference-only: semantics/oom-one-thread.js continues to fail with the documented evidence, OutOfMemoryError: Context heap limit exceeded. That keeps #11's audit baseline honest while #27 tracks the remaining catch-binding/small-allocation pressure semantics.

Also opened #28 for a separate strcell.makeCell OOM panic discovered while probing string allocation pressure.

9 days ago

PR-249 promotion update from 78b553a: semantics/oom-one-thread.js is now promoted after the heap-cap collect/retry work. The audit now reports 231/259 executable files promoted, with 28 executable reference-only files plus 5 helper/preload files remaining.

The negative promotion probes now cover the remaining quick blockers only:

  • cve/mc-df-arraycopy-relabel.js: RangeError offset blocker for the JSC butterfly/typed-array set race shape.
  • cve/mc-life-creator-thread-dies.js: detached ArrayBuffer fresh-view construction TypeError.
  • dw2-marklistset-storm.js and w16-c1-prevent-collection.js remain expected timeout/shell-hook blockers.

Validation: zig build threads-test -Dthreads-case=semantics/oom-one-thread.js --summary all; zig build threads-reference-audit --summary all; zig build threads-reference-probes --summary all.

9 days ago

Current #11 audit after the #25 source-snapshot witness remains 231/259 promoted executable PR-249 files, with 28 executable reference-only files plus 5 helper/preload files.

What changed since the last #11 snapshot:

  • cve/mc-df-arraycopy-relabel.js is still reference-only, but its portable typed-array source-length behavior is now covered by zig-js-owned witnesses from f501ce7.
  • The audit category now says typed-array set source-length snapshot covered by zig-js witnesses, leaving the non-portable part as the JSC butterfly verification shell option.
  • cve/mc-life-creator-thread-dies.js remains classified as detached fresh-view construction after transfer; the portable creator-owned storage subset is already covered.

Validation from this pass:

  • zig build test -Dtest-filter=TypedArray set snapshots array-like source length --summary all
  • zig build threads-reference-audit --summary all
  • python3 tools/threads-reference-audit.py --format markdown
  • python3 tools/threads-reference-audit.py --format json

No promotion made: the remaining tail is still either JSC/JIT/WASM/shell-hook-shaped or already covered by first-party zig-js witnesses where the reference file itself is not portable.

9 days ago

Reference-audit housekeeping landed in 81b0872 (docs threads: update oom witness cap note).

The semantics/oom-one-thread.js heap-cap mapping comment now reflects the current promoted status: the cap mapping remains so the normal corpus exercises the real zig-js allocator-pressure contract, not because allocation-site catchability is still a blocker.

Validation was intentionally light because this was comment-only:

  • zig fmt conformance/threads_test.zig
  • git diff --check
9 days ago

Promoted four more PR-249 reference-only files in d74fa86: https://github.com/zig-utils/zig-js/commit/d74fa86\n\nNewly promoted cases:\n- cve/mc-init-butterfly-grow-slack.js\n- cve/mc-jit-delete-reuse-stale-offset.js\n- cve/mc-jit-double-relabel-stale-shape.js\n- cve/mc-jit-ta-resize-hoisted-base.js\n\nCurrent audit state:\n- 235/259 executable PR-249 files promoted.\n- 24 executable reference-only files remain, plus 5 helper/preload files.\n- uncategorized = [] and missing_allowlist_entries = [].\n\nThe audit tool also gained --scan-reference-only, an opt-in sweep that runs every remaining executable reference-only file and fails on unexpected passes. It records expected reference-only passes separately for JSC-shell premise skips and default-only/budget cases, so passable-but-nonportable files do not masquerade as promotion evidence.\n\nNew child tracker opened for the concrete leftover discovered in this pass:\n- #35 — cve/mc-init-direct-arguments-override.js passes serialized/default but its no-GIL promotion arm exceeded this chunk's focused budget.\n\nValidation:\n- Focused default + -Dthreads-parallel-js=true runs for all four promoted cases passed.\n- python3 -m py_compile tools/threads-reference-audit.py\n- python3 tools/threads-reference-audit.py --format json count/category assertions\n- mocked scan classification check for expected vs unexpected reference-only passes\n- zig build threads-reference-audit --summary all\n- zig build threads-reference-probes --summary all\n- bun run docs:build\n- git diff --check

9 days ago

Landed 4c3b46db (docs(threads): sync PR-249 audit counts) as a #11 audit/docs hygiene slice.

What changed:

  • Synced docs/threads/index.md, docs/threads/production-readiness.md, and docs/threads/testing.md with the live reference audit.
  • Current machine-audited PR-249 coverage is 236/259 executable files: 234 default allowlist entries plus 2 parallel_js-only witnesses.
  • The remaining tail is 23 executable reference-only files plus 5 helper/preload files, with no uncategorized or missing allowlist entries.

Validation:

  • python3 tools/threads-reference-audit.py --format json count/category assertions
  • /Users/chris/.bun/bin/bun run docs:build
  • git diff --check

This does not promote a new file; it keeps the human docs aligned with the machine-audited #11 state so future promotion work starts from the right baseline.

CI pending: https://github.com/zig-utils/zig-js/actions/runs/29193634788

9 days ago

Follow-up: push CI for e00d5858 completed green after the #11 docs-audit sync landed.

Run: https://github.com/zig-utils/zig-js/actions/runs/29193634788 Result: 31 success, 1 expected skip, 0 failures.

9 days ago

Tracker hygiene update: synced this issue body with the current machine audit. zig build threads-reference-audit reports 236/259 promoted executable PR-249 files, 23 executable reference-only files, and 5 helper/preload files. I also moved #35 / cve/mc-init-direct-arguments-override.js into the resolved section instead of leaving it described as an open no-GIL promotion blocker.

9 days ago

Green gate note for d0092f5e: https://github.com/zig-utils/zig-js/actions/runs/29201642565

The PR-249 allowlist/audit state remains green at 236/259 executable files with the remaining reference-only blockers still explicit. No new promotion was made in this slice because the current blocker evidence still maps to missing/non-portable behavior rather than an unpromoted passing case.

9 days ago

Closing this promotion tracker as completed.\n\nFinal machine-audited state:\n- 236/259 executable PR-249 files promoted.\n- 23 executable reference-only files and 5 helper/preload files, all classified.\n- uncategorized = [] and missing_allowlist_entries = [].\n- The current quick blocker gate passes and confirms the exact expected evidence for the two nearest portable-shaped cases: TypedArray source-length semantics are already covered by zig-js witnesses while the reference still requires a JSC butterfly verifier; creator-owned buffer lifetime is covered while the reference still assumes fresh-view construction on a detached source, which zig-js intentionally rejects.\n- The remainder requires JSC $vm, JIT/code-artifact, shared-GC mark-list, heap snapshot/preventCollection, checktraps/haveBadTime, or WebAssembly construction/grow/relocation premises not exposed by this engine. Those are not unimplemented portable thread semantics and should not be rewritten or allowlisted into false coverage.\n\nFresh focused validation: zig build threads-reference-probes --summary all (2/2 steps, expected blocker evidence confirmed). Full audit/concurrency gate: https://github.com/zig-utils/zig-js/actions/runs/29232877388.\n\nIf zig-js later deliberately adds WebAssembly or a JIT/code-artifact API, that feature should get a dedicated issue and these references can be reconsidered against the new contract.

Sign in to comment on this issue.