You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Continuation of the WASI hardening cycle that began with #583 (closed after waves 7-11). The Preview 3 surface is at 40/40 conformance + 99.1 % (338/341) WIT-method coverage; the remaining work falls into five buckets:
Bucket
Description
A
Direct follow-ups from waves 7-11 PRs (small, well-scoped)
Future scope (await upstream — track but don't start yet)
Each item below carries enough context that a future wave-N agent can pick it up directly without re-deriving the scope.
A. Direct follow-ups from waves 7-11
A1 — Honour outbound HTTP request-options timeouts. PR feat(wasi:http/types@0.2): 7 missing P2 audit arms (#583) #612 wired the 6 P2 timeout getters/setters into the WIT surface but the worker (httpClientLowLevelFetch, PR feat(wasi:http): surface outbound response headers (#583 A4) #594) doesn't consume them. Pass connect-timeout / first-byte-timeout / between-bytes-timeout through to std.http.Client.Request (its timeout_options field), and gate against the new fields when set. Add a fixture-style test: configure timeout=10 ms, target a slow server, expect connection-timeout. Symmetric work for P3 if 0.3 ships the same surface.
A2 — Kernel splice(2) for output-stream.splice. PR feat(wasi:io, wasi:sockets): 8 missing P2 audit arms (#583) #615 shipped a buffer-through MVP. The Linux fast-path is splice(in_fd, NULL, out_fd, NULL, len, 0). Detect when both src/dst are real fds (vs in-memory streams) and use the syscall; preserve the buffer-through path as fallback. Out of scope: macOS/Windows (no equivalent — keep buffer-through there).
A4 — W7-5 wrapper "circular-import" investigation. Multiple agents (W8-1, W10-4, W11-6) reported transient Python "circular-import" failures running wasi-p3-testsuite via tests/wasi-testsuite-runner-patch/wasi_test_runner.py. The host (me) couldn't reproduce when checking directly. Likely a cache / stale __pycache__ issue. Action items:
Add find . -name __pycache__ -exec rm -rf {} + to the wrapper bootstrap.
If it persists, switch the wrapper from import wasi_testsuite (or whatever does the circular-import-prone thing) to importlib-based lazy loading.
Verify on a fresh worktree.
A5 — Tighten wasi-microbench budgets + flip continue-on-error: false. PR perf(wasi): CoreMark-aware WASI micro-bench infrastructure (#583) #611 shipped with 1.5× initial median budgets and continue-on-error: true. After a week or two of CI data, recalibrate budgets to actual measured medians + 2σ noise margin, and flip the gate to required. Expected initial pass-rate ≥ 95 % on the recalibrated budgets.
A6 — Disk-backed wasi:keyvalue (atomic-rename write-through). PR feat(wasi:keyvalue@0.2.x): real CAS + optional file-backed persistence (#583 B4 follow-up) #608 shipped synchronous JSON-file rewrite on every mutation; document explicitly notes "atomic-rename future hardening." Implement tmp-file + rename(2) for crash-safety. Optionally add fsync between write and rename for durability (off by default — most testsuite uses don't need fsync overhead).
A7 — Finer outbound HTTP cancel via per-TLS-record polling. PR feat(wasi:http): finer-grained outbound cancel via Request-phase polling (#583 follow-up) #602 polls cancel between connect / send-head / receive-head / read-body / per-64-KiB-body-chunk phases. The bottleneck is TLS record processing — a single Request.receiveHead may pump multiple TLS records over many ms. Wrap the underlying Reader with a cancel-aware adapter that polls between TLS records. May require coordinating with W7-3's error-mapping table.
A8 — HTTP/1.1 response-body cancel. Symmetric to A7 — when the host is writing a large response back to a guest, observe task.cancel on the guest side and short-circuit the writer.
B. wasi:threads (legacy Preview 1 surface) — multi-PR sub-wave
Per docs/design/wasi-threads.md (PR #603, recommendation Option B: one Interpreter/std.Thread per WASI thread + shared linmem + atomics). Execute in order — each wave gates the next.
B1.1 — Wave 1: Thread-safe resource tables. Wrap every *_table access in WasiCliAdapter and ComponentInstance with a mutex; gate behind comptime so the single-threaded build keeps zero-overhead. Required deliverable: measured single-threaded coremark perf delta < 2 %. If the delta exceeds 2 %, use per-cache-line padded RW-locks or rethink the locking granularity.
B1.2 — Wave 2: std.Thread spawning wrapper. Productionise the existing thread_manager.zig prototype mentioned in the design doc. Each spawned thread gets its own Interpreter instance pointing at the shared Memory. Add a smoke fixture: spawn 2 threads, each increments a guest counter, both join, expect 2.
B1.3 — Wave 3: Wasm threads proposal opcode support. Replace the currently non-atomic atomic_prefix opcodes (search 0xFE in src/runtime/interpreter/) with @atomicLoad / @atomicStore / @atomicRmw / @cmpxchgStrong. Implement i32.atomic.wait / i64.atomic.wait / i32.atomic.notify against a host-side wait-queue keyed by (memory_base, addr). Fix the atomic.fence no-op.
B1.5 — Wave 5: Cancellation across threads. Split the existing trap_flag into trap_flag + cancel_flag on ThreadManager. task.cancel from one thread propagates to siblings.
B1.6 — Wave 6: Per-thread wasi_ctx slot + TLS. Per-thread WASI context fields (current-task-manager, current-cancel-token) move from ComponentInstance → ExecEnv. Thread-local storage via the wasm threads proposal's thread.local globals.
B1.7 — Wave 7+: shared-everything-threads canon built-ins when upstream stabilises them (current target: Component Model post-Preview-3 epoch). Treat as a future-compat checkpoint until then.
C. Maintenance cadence
C1 — Quarterly WIT-vs-impl audit refresh. Re-run the methodology from PR docs(wasi): WIT-vs-impl audit document (#583 D) #604 / docs/wasi-impl-audit.md. Use the existing reproducible-grep section as the recipe. Flag any new ❌ / ⚠️ rows for follow-up. Target cadence: every 3 months (next: mid-August 2026).
C2 — Quarterly parity skip-list poll. Re-run the W11-4 / PR ci(wasi-p3-parity): poll upstream fixes + refresh skip-list #610 methodology: poll the 4 upstream issues (wasmtime#13396/97/98 + wasi-testsuite#228) and any new entries. Remove fixed entries. Update _last_polled in tests/wasi-p3-parity-skip.json. Target cadence: every 3 months (next: mid-August 2026).
C3 — Quarterly Wasmtime version bump. Currently pinned at 44.0.1 in .github/workflows/wasi-p3-parity.yml. Bump to latest stable; verify the parity baseline doesn't regress. If newer Wasmtime fixes one of the 4 documented bugs, the upstream issue auto-resolves under C2.
C4 — wasi-testsuite submodule bump. Currently pinned at 40c1f7d3 (vendored in tests/wasi-testsuite/). Upstream evolves; bump and re-run both gates. If the bump introduces new fixtures, either pass them or add to skip-list with rationale.
D. Investigations
D1 — macos-arm64 coldstart noise. PR perf(wasi:streams): zero-copy stream.write for TCP send + FS write-via-stream (#583 B2 follow-up) #606 hit a 13 %-over-budget median on macos-arm64 (noop.cwasm 451 µs vs 400 µs budget, samples=25). CI re-run passed. Investigate whether the sample-size / outlier-rejection in tests/coldstart/noop_*.zig is too tight. Options: increase samples to 100, use p95 instead of median, or trim 10 % outliers.
D2 — /work disk-hygiene.bench-coremark-* worktrees accumulate (~500 MB each, dozens present). Add a git worktree prune + age-based deletion (>14 days, unused) to the bench scripts.
Continuation of the WASI hardening cycle that began with #583 (closed after waves 7-11). The Preview 3 surface is at 40/40 conformance + 99.1 % (338/341) WIT-method coverage; the remaining work falls into five buckets:
wasi:threads(legacy P1 surface) — multi-PR sub-wave perdocs/design/wasi-threads.md(PR #603)Each item below carries enough context that a future wave-N agent can pick it up directly without re-deriving the scope.
A. Direct follow-ups from waves 7-11
A1 — Honour outbound HTTP
request-optionstimeouts. PR feat(wasi:http/types@0.2): 7 missing P2 audit arms (#583) #612 wired the 6 P2 timeout getters/setters into the WIT surface but the worker (httpClientLowLevelFetch, PR feat(wasi:http): surface outbound response headers (#583 A4) #594) doesn't consume them. Passconnect-timeout/first-byte-timeout/between-bytes-timeoutthrough tostd.http.Client.Request(itstimeout_optionsfield), and gate against the new fields when set. Add a fixture-style test: configure timeout=10 ms, target a slow server, expectconnection-timeout. Symmetric work for P3 if 0.3 ships the same surface.A2 — Kernel
splice(2)foroutput-stream.splice. PR feat(wasi:io, wasi:sockets): 8 missing P2 audit arms (#583) #615 shipped a buffer-through MVP. The Linux fast-path issplice(in_fd, NULL, out_fd, NULL, len, 0). Detect when both src/dst are real fds (vs in-memory streams) and use the syscall; preserve the buffer-through path as fallback. Out of scope: macOS/Windows (no equivalent — keep buffer-through there).A3 — HTTPS handshake when std lands
std.crypto.tls.Server. Tracked under wasi:http@0.3 incoming-handler: HTTPS termination blocked on upstream Zig 0.16 std (#583) #609. The scaffolding from PR feat(wasi:http@0.3): HTTPS incoming-handler TLS plumbing (#583 / #609) #614 (cert/key load, CLI flags,ServeHttpOptions.tls_config) is ready — the actual handshake just plugs into the placeholderHttpsTlsConfig.handshake(fd). Monitor upstream Zig releases; when the server-side API ships, flip this PR.A4 — W7-5 wrapper "circular-import" investigation. Multiple agents (W8-1, W10-4, W11-6) reported transient Python "circular-import" failures running
wasi-p3-testsuiteviatests/wasi-testsuite-runner-patch/wasi_test_runner.py. The host (me) couldn't reproduce when checking directly. Likely a cache / stale__pycache__issue. Action items:find . -name __pycache__ -exec rm -rf {} +to the wrapper bootstrap.import wasi_testsuite(or whatever does the circular-import-prone thing) toimportlib-based lazy loading.A5 — Tighten
wasi-microbenchbudgets + flipcontinue-on-error: false. PR perf(wasi): CoreMark-aware WASI micro-bench infrastructure (#583) #611 shipped with 1.5× initial median budgets andcontinue-on-error: true. After a week or two of CI data, recalibrate budgets to actual measured medians + 2σ noise margin, and flip the gate to required. Expected initial pass-rate ≥ 95 % on the recalibrated budgets.A6 — Disk-backed
wasi:keyvalue(atomic-rename write-through). PR feat(wasi:keyvalue@0.2.x): real CAS + optional file-backed persistence (#583 B4 follow-up) #608 shipped synchronous JSON-file rewrite on every mutation; document explicitly notes "atomic-rename future hardening." Implementtmp-file + rename(2)for crash-safety. Optionally add fsync between write and rename for durability (off by default — most testsuite uses don't need fsync overhead).A7 — Finer outbound HTTP cancel via per-TLS-record polling. PR feat(wasi:http): finer-grained outbound cancel via Request-phase polling (#583 follow-up) #602 polls cancel between connect / send-head / receive-head / read-body / per-64-KiB-body-chunk phases. The bottleneck is TLS record processing — a single
Request.receiveHeadmay pump multiple TLS records over many ms. Wrap the underlyingReaderwith a cancel-aware adapter that polls between TLS records. May require coordinating with W7-3's error-mapping table.A8 — HTTP/1.1 response-body cancel. Symmetric to A7 — when the host is writing a large response back to a guest, observe
task.cancelon the guest side and short-circuit the writer.B.
wasi:threads(legacy Preview 1 surface) — multi-PR sub-wavePer
docs/design/wasi-threads.md(PR #603, recommendation Option B: oneInterpreter/std.Threadper WASI thread + shared linmem + atomics). Execute in order — each wave gates the next.B1.1 — Wave 1: Thread-safe resource tables. Wrap every
*_tableaccess inWasiCliAdapterandComponentInstancewith a mutex; gate behindcomptimeso the single-threaded build keeps zero-overhead. Required deliverable: measured single-threadedcoremarkperf delta < 2 %. If the delta exceeds 2 %, use per-cache-line padded RW-locks or rethink the locking granularity.B1.2 — Wave 2:
std.Threadspawning wrapper. Productionise the existingthread_manager.zigprototype mentioned in the design doc. Each spawned thread gets its ownInterpreterinstance pointing at the sharedMemory. Add a smoke fixture: spawn 2 threads, each increments a guest counter, both join, expect 2.B1.3 — Wave 3: Wasm
threadsproposal opcode support. Replace the currently non-atomicatomic_prefixopcodes (search0xFEinsrc/runtime/interpreter/) with@atomicLoad/@atomicStore/@atomicRmw/@cmpxchgStrong. Implementi32.atomic.wait/i64.atomic.wait/i32.atomic.notifyagainst a host-side wait-queue keyed by(memory_base, addr). Fix theatomic.fenceno-op.B1.4 — Wave 4:
wasi.thread-spawnhost import binding. Bind the Preview 1wasi:thread-spawncore-module import. Add a pthread end-to-end fixture (tests/wasi-threads/).B1.5 — Wave 5: Cancellation across threads. Split the existing
trap_flagintotrap_flag+cancel_flagonThreadManager.task.cancelfrom one thread propagates to siblings.B1.6 — Wave 6: Per-thread
wasi_ctxslot + TLS. Per-thread WASI context fields (current-task-manager, current-cancel-token) move fromComponentInstance→ExecEnv. Thread-local storage via the wasm threads proposal'sthread.localglobals.B1.7 — Wave 7+:
shared-everything-threadscanon built-ins when upstream stabilises them (current target: Component Model post-Preview-3 epoch). Treat as a future-compat checkpoint until then.C. Maintenance cadence
C1 — Quarterly WIT-vs-impl audit refresh. Re-run the methodology from PR docs(wasi): WIT-vs-impl audit document (#583 D) #604 /⚠️ rows for follow-up. Target cadence: every 3 months (next: mid-August 2026).
docs/wasi-impl-audit.md. Use the existing reproducible-grep section as the recipe. Flag any new ❌ /C2 — Quarterly parity skip-list poll. Re-run the W11-4 / PR ci(wasi-p3-parity): poll upstream fixes + refresh skip-list #610 methodology: poll the 4 upstream issues (wasmtime#13396/97/98 + wasi-testsuite#228) and any new entries. Remove fixed entries. Update
_last_polledintests/wasi-p3-parity-skip.json. Target cadence: every 3 months (next: mid-August 2026).C3 — Quarterly Wasmtime version bump. Currently pinned at
44.0.1in.github/workflows/wasi-p3-parity.yml. Bump to latest stable; verify the parity baseline doesn't regress. If newer Wasmtime fixes one of the 4 documented bugs, the upstream issue auto-resolves under C2.C4 — wasi-testsuite submodule bump. Currently pinned at
40c1f7d3(vendored intests/wasi-testsuite/). Upstream evolves; bump and re-run both gates. If the bump introduces new fixtures, either pass them or add to skip-list with rationale.D. Investigations
D1 — macos-arm64 coldstart noise. PR perf(wasi:streams): zero-copy stream.write for TCP send + FS write-via-stream (#583 B2 follow-up) #606 hit a 13 %-over-budget median on macos-arm64 (
noop.cwasm451 µs vs 400 µs budget, samples=25). CI re-run passed. Investigate whether the sample-size / outlier-rejection intests/coldstart/noop_*.zigis too tight. Options: increase samples to 100, use p95 instead of median, or trim 10 % outliers.D2 —
/workdisk-hygiene.bench-coremark-*worktrees accumulate (~500 MB each, dozens present). Add agit worktree prune+ age-based deletion (>14 days, unused) to the bench scripts.D3 — macos-arm64
wasi-p3-testsuiteperformance. This Azure dev VM takes ~11 s forhttp-fields(mitigated via chore(wasi): configurable wasi-testsuite timeout + README refresh (#583 A7+D1) #585'sWAMR_TESTSUITE_TIMEOUTknob). Profile what's slow on the same fixture under macos-arm64 CI runners.E. Future scope (track but don't start)
E1 — HTTP/2 incoming-handler. HTTP/1.1 robustness is done (PR feat(wasi:http@0.3): incoming-handler HTTP/1.1 robustness — keep-alive + chunked + trailers + limits (#583 A5) #595). HTTP/2 requires HPACK + multiplexing + flow-control — significant work. Wait until there's a guest-side use case.
E2 —
wasi:blobstorehost adapter. Deferred per PR docs(wasi:blobstore): document deferral with concrete blockers (#583) #605 with 6 documented blockers. Re-poll when upstream WIT pins a non-draft version + wasmtime ships a baseline + wasi-testsuite ships fixtures.E3 —
shared-everything-threadscanon built-ins. Component-model post-Preview-3 threads proposal. Successor to legacywasi:threads. See B1.7.E4 — Real disk-backed
wasi:keyvalue. Beyond A6's atomic-rename JSON file: sqlite or LMDB for production use. Only if a real guest workload demands it.E5 —
wasi:loggingstructured context. PR feat(wasi:logging@0.1.x): host adapter via std.log + stderr (#583 B5) #598 routes log calls tostd.logwith[context] messageformatting. Upstream may evolve toward structured k-v attributes; track and adopt when WIT changes.Wave-12 starter pack (recommended next steps)
If picking up cold, the lowest-risk, highest-yield wave-12 set is:
splice(2)Defer A3 (HTTPS handshake — upstream Zig blocked), A4 (investigation — needs interactive debugging), B1.2+ (depend on B1.1), C2-C4 (cadence — wait the quarter).
References
docs/wasi.md— feature matrix.docs/wasi-impl-audit.md— current 99.1 % audit (PR docs(wasi): WIT-vs-impl audit document (#583 D) #604 + feat(wasi:http/types@0.2): 7 missing P2 audit arms (#583) #612 + feat(wasi:io, wasi:sockets): 8 missing P2 audit arms (#583) #615).docs/design/wasi-threads.md— B1 design (PR docs(wasi:threads): design doc for B3 multi-threaded interpreter (#583 B3) #603).files/wave-{7..11}-summary.mdin the session workspace (local to the dev VM).