Fix broken Pages deploy: self-host Surfer artifact, refresh MOX wasm#7
Merged
Conversation
Two bugs in the recently-added worker_threads orchestration caused nearly every SV/SVA compile to fail with "cannot open output file": 1. main() called fs.mkdtempSync at the top and fs.rmSync in a finally block. workerLoop's outer async function returned immediately after registering the message handler, so the finally ran and deleted the work directory before any task was processed. All subsequent compiles failed with ENOENT. Fix: in worker threads, await workerLoop and then await a never- resolving promise so the work dir survives for the worker's lifetime. The worker is reaped by the parent's w.terminate() at the end of orchestrate. 2. The timeout monitor and worker-error handler both called spawnWorker(slot) followed by assignNext(slot). spawnWorker is synchronous; the new worker hasn't sent 'ready' yet. assignNext posted a task and set taskStart=Date.now(). After 3s (the cold-load was ~30s), the monitor re-timed-out the same not-yet-running task, creating a livelock that prevented the run from finishing. The 'ready' handler in spawnWorker already calls assignNext when the replacement worker is actually ready, so the explicit call after spawnWorker is redundant and harmful. Also includes the in-progress circt → mox rebrand renames across this script (CIRCT_DIR → MOX_DIR, circt-* tool names → mox-*). Suite now produces a summary instead of hanging: 91 passed, 28 failed, 4 skipped — the failed lessons are real UVM timeouts and known sva-bmc bugs, not the prior across-the-board "compile error".
Two bugs in the recently-added worker_threads orchestration caused nearly every SV/SVA compile to fail with "cannot open output file": 1. main() called fs.mkdtempSync at the top and fs.rmSync in a finally block. workerLoop's outer async function returned immediately after registering the message handler, so the finally ran and deleted the work directory before any task was processed. All subsequent compiles failed with ENOENT. Fix: in worker threads, await workerLoop and then await a never- resolving promise so the work dir survives for the worker lifetime. 2. The timeout monitor and worker-error handler both called spawnWorker(slot) followed by assignNext(slot). spawnWorker is synchronous; the new worker has not sent ready yet. assignNext posted a task and set taskStart=Date.now(). After 3s the monitor re-timed-out the same not-yet-running task, creating a livelock that prevented the run from finishing. The ready handler in spawnWorker already calls assignNext when the replacement worker is actually ready, so the explicit call after spawnWorker is redundant and harmful. Also includes the in-progress circt to mox rebrand renames across this script (CIRCT_DIR to MOX_DIR, circt-* tool names to mox-*). Suite now produces a summary instead of hanging: 91 passed, 28 failed, 4 skipped - the failed lessons are real UVM timeouts and known sva-bmc bugs, not the prior across-the-board "compile error".
Rename the local CIRCT-flavored toolchain references to the new MOX naming everywhere they appear outside the runtime contract: - scripts/: setup-circt.sh -> setup-mox.sh, build-circt-wasm.sh -> build-mox-wasm.sh, sync-circt-wasm.sh -> sync-mox-wasm.sh, check-circt-issues.sh -> check-mox-issues.sh; package.json scripts use the new names; bootstrap-repro.sh and other shell helpers updated accordingly. - src/runtime/: circt-adapter.js -> mox-adapter.js, circt-config.js -> mox-config.js, plus the matching *.test.js files. Vite env-var lookups and runtime config keys use MOX_* names. - e2e/, workflows, docs, .env.example, README, CLAUDE.md, AGENT.md, CURRICULUM.md, +layout.svelte, lesson page: comments and labels point to mox-*. - scripts/toolchain.lock.sh: bump MOX_REF_LOCKED to e5e0f6b2898a4b3f1763916077504a7d15e730b1 (current normal-computing/mox main + local LSP rename rebase). - scripts/build-mox-wasm.sh: set CCACHE_SLOPPINESS and CCACHE_BASEDIR before the cmake invocation. Without this, 91% of the LLVM/MOX cxx work is uncacheable because it uses precompiled headers and default ccache sloppiness rejects PCH compiles. With the new defaults a second cold build hits cache for the unchanged TUs instead of recompiling everything.
- toolchain.lock.sh: point Surfer at a self-hosted GitHub release asset (surfer-web) instead of GitLab's moving "latest main" URL, which broke the pinned SHA and aborted every deploy since 2026-03-09. Bump MOX_REF to 805b42d2 (matches the freshly published mox-wasm release). - sync-mox-wasm.sh: fix mktemp template so the UVM bundle is named uvm-core.tar.gz (mktemp only substitutes trailing Xs). - deploy.yml: unpack uvm-core*.tar.gz so the current mis-named asset works. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
The live site (https://thomasnormal.github.io/sv-tutorial/) was serving a stale build from 2026-03-09 — every deploy since then failed at the "Download Surfer assets" step.
Root cause:
setup-surfer.shdownloaded Surfer's?job=pages_build&ref=mainartifact — a moving "latest main" target — but verified it against a pinned SHA256. As soon as the Surfer project pushed new commits tomain, the artifact content changed, the SHA check failed, andset -euo pipefailaborted the deploy before building.Changes
scripts/toolchain.lock.sh— Surfer now downloads from a self-hosted GitHub release asset (surfer-web→surfer-pages_build.zip) with a matching pinned SHA. Stable URL + frozen content + integrity preserved. Refresh instructions live in the lock comment. Also bumpsMOX_REF_LOCKED→805b42d2to match the freshly publishedmox-wasmrelease.scripts/sync-mox-wasm.sh— fix the UVM bundlemktemptemplate.mktemponly substitutes trailingXs, souvm-core.XXXXXX.tar.gzproduced a literal-XXXXXXfilename. The bundle is now built asuvm-core.tar.gzinside amktemp -ddirectory..github/workflows/deploy.yml—unpack_uvm_bundle_if_present()now matchesuvm-core*.tar.gz(newest first), so the currently-uploaded mis-named asset works without a re-upload, and future correctly-named bundles also work.Companion release work (already done)
surfer-webrelease mirroring Surfer pages_build (GitLab pipeline 2625476633 / commit 98287107b9).mox-wasmrelease with freshly built wasm tools (mox-verilog / sim / sim-vpi / bmc / lec) plus the Apache-2.0 UVM core source bundle, built fromnormal-computing/mox @ 805b42d2.Verification
scripts/setup-surfer.shdownloads, SHA-verifies, extracts, and applies the integration patch from the new release URL.VITE_BASE=/sv-tutorial/ npm run buildis clean;build/contains all 5 mox wasm tools, the UVM manifest + 170 source files, and Surfer.🤖 Generated with Claude Code