Skip to content

Fix broken Pages deploy: self-host Surfer artifact, refresh MOX wasm#7

Merged
thomasnormal merged 4 commits into
mainfrom
fix-pages-deploy
Jun 25, 2026
Merged

Fix broken Pages deploy: self-host Surfer artifact, refresh MOX wasm#7
thomasnormal merged 4 commits into
mainfrom
fix-pages-deploy

Conversation

@thomasnormal

Copy link
Copy Markdown
Owner

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.sh downloaded Surfer's ?job=pages_build&ref=main artifact — a moving "latest main" target — but verified it against a pinned SHA256. As soon as the Surfer project pushed new commits to main, the artifact content changed, the SHA check failed, and set -euo pipefail aborted the deploy before building.

Changes

  • scripts/toolchain.lock.sh — Surfer now downloads from a self-hosted GitHub release asset (surfer-websurfer-pages_build.zip) with a matching pinned SHA. Stable URL + frozen content + integrity preserved. Refresh instructions live in the lock comment. Also bumps MOX_REF_LOCKED805b42d2 to match the freshly published mox-wasm release.
  • scripts/sync-mox-wasm.sh — fix the UVM bundle mktemp template. mktemp only substitutes trailing Xs, so uvm-core.XXXXXX.tar.gz produced a literal-XXXXXX filename. The bundle is now built as uvm-core.tar.gz inside a mktemp -d directory.
  • .github/workflows/deploy.ymlunpack_uvm_bundle_if_present() now matches uvm-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)

  • Created surfer-web release mirroring Surfer pages_build (GitLab pipeline 2625476633 / commit 98287107b9).
  • Created/populated the mox-wasm release with freshly built wasm tools (mox-verilog / sim / sim-vpi / bmc / lec) plus the Apache-2.0 UVM core source bundle, built from normal-computing/mox @ 805b42d2.

Verification

  • scripts/setup-surfer.sh downloads, SHA-verifies, extracts, and applies the integration patch from the new release URL.
  • VITE_BASE=/sv-tutorial/ npm run build is clean; build/ contains all 5 mox wasm tools, the UVM manifest + 170 source files, and Surfer.

🤖 Generated with Claude Code

thomasahle and others added 4 commits May 13, 2026 17:55
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>
@thomasnormal thomasnormal merged commit 03daf02 into main Jun 25, 2026
0 of 2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants