# Haiku riscv64 + WebPositive release bundle, built 2026-09-22 (baseline JIT)

`haiku-nightly-hrev60105-riscv64-webpositive-2026-09-22.image` is a Haiku `@nightly-mmc`
image for `qemu-system-riscv64 -M virt`, built from Haiku master hrev60105 plus the ten
patches in `patches/haiku/` (branch `brainos/riscv64-fixes`) and, new versus the 2026-09-20
nightly, **WebPositive** with **HaikuWebKit 1.9.30** cross-built for Haiku riscv64 from
tag `HaikuWebKit-1.9.30` plus the thirteen patches in `patches/webkit/` (branch `brainos/riscv64`),
now with **JavaScriptCore's baseline JIT enabled** (11x faster JavaScript loops than the
2026-09-21 interpreter build - see "What changed vs 2026-09-21 20:32").

Raw MMC image, 715130880 bytes: EFI system partition with U-Boot's payload
(`haiku_loader.efi`) + BFS system volume.
sha256 `bea856e05715a538d637f11628100c08b307e42de91ef2d56f8669da625da6e2` (built
2026-09-22 07:55 UTC, recorded in the workspace `evidence/build/IMAGE.txt`) - verify with
`sha256sum -c SHA256SUMS`. This is the 2026-09-21 20:32 image (virtio bus-manager fix) with
the JIT-enabled `haikuwebkit-1.9.30-3` packages; see "What changed vs 2026-09-21 20:32" below.

## What changed vs the 2026-09-20 release

- **WebPositive works.** `webpositive-r1~beta6_hrev60105` ships in the image together with
  `haikuwebkit-1.9.30-1` (JavaScriptCore) and its runtime deps (brotli, icu via libicu*,
  libxml2/libxslt, sqlite, woff2, libidn2/libpsl/libunistring, execinfo). The browser
  fetches pages over HTTP and **executes JavaScript**: the proof page's own script computes
  `js-ok 2,4,6` (see `capstone/webpositive-jsok-proof-2026-09-21.txt` + screenshot in
  `screenshots/`).
- **JavaScriptCore runs its baseline JIT** (this bundle; the 2026-09-21 bundles were C-loop
  interpreter only). DFG/FTL/B3 stay off - upstream enables the DFG on x86_64 only - so
  expect baseline-JIT speed: ~11x the interpreter on tight loops, no change on runtime-bound
  work such as `Array.prototype.sort` (`capstone/jit-benchmark-2026-09-22.txt`).
- **Known rendering/feature gaps** of this build: no WebGL or ANGLE/mesa (no GPU-accelerated
  canvas), `USE_AVIF`/`USE_JPEGXL` disabled (those libraries are not in the Haiku riscv64
  base; PNG/JPEG/GIF/WebP/BMP work), WebAssembly off, OpenGLES2 requirement relaxed. Plain
  HTML/CSS/text + images + basic scripts render fine; complex pages should be assumed to
  degrade rather than fail.
- Same as the nightly: SMP up to `-smp 4`, virtio-sound, Goldfish RTC clock (TLS-ready),
  au_reader media plugin, first-boot package activation.

## What changed vs 2026-09-21 20:32 (sha 9d9b5c2a)

- **Baseline JIT shipped.** `haikuwebkit-1.9.30-3` / `haikuwebkit_devel-1.9.30-3` carry
  `libJavaScriptCore.so.18.7.4`, `libWebKitLegacy.so.1.9.30` and `bin/jsc` from a build with
  `-DENABLE_JIT=ON -DENABLE_C_LOOP=OFF -DENABLE_DFG_JIT=OFF -DENABLE_FTL_JIT=OFF`; WebPositive
  was relinked against them. Measured in the guest on one boot (`jit-benchmark-2026-09-22.txt`):
  property/arithmetic loop 3268.9 ns/iter (interpreter) -> 291.9 ns/iter (JIT), same binary
  with `--useJIT=false` back at 3426.7; identical checksums on constant-size workloads across
  all three; `propLoop`/`makeArray`/`now` reported compiled by the baseline JIT.
- Patches 7-13 in `patches/webkit/` are what the JIT needed on riscv64/Haiku: offline-asm
  label attributes, completed jump-table types and CCallHelpers methods, the RISCV64
  disassembler disabled (GCC 13 template-pack bug), the LOL JIT tier gated behind a new
  `ENABLE(LOL_JIT)` (x86_64/arm64 backends only), the DFG-off `CompileTimePropertyInlineCache`
  variant, an off-by-one in every Haiku riscv64 `MachineContext.h` register accessor (the
  kernel fills `vregs.x[i]` with x(i+1)), and the RISCV64 assembler headers forwarded so
  WebCore compiles against the JIT.
- Kernel, image definition and every other package: unchanged from 2026-09-21 20:32.
- Proof: the full nightly capstone (12 checks, incl. WebPositive executing JavaScript)
  passed **twice in a row** on this image - runs 109 and 110 in `capstone/`.

## What changed vs 2026-09-21 12:04 (sha 89cde69b)

- **Virtio bus-manager lost-completion fix** (commit `16f902b6cc` on `brainos/riscv64-fixes`): re-checks the used ring after re-enabling interrupts and re-runs the callback. The previous build (sha `89cde69b…`, published 2026-09-21 12:04 UTC) lost a virtio completion while the callback ran, causing ~1/3 boots to wedge with a 100 % black screen and a blocked `virtio_gpu_command` semaphore. The fixed image (sha `9d9b5c2a…`, built 20:32 UTC) boots cleanly 12/12 in the capstone suite.
- **WebPositive stack unchanged** versus the 12:04 build: same HaikuWebKit 1.9.30 packages, same QEMU command, same runtime deps.
- **HTTPS via proxy relay proven**: the WebPositive stack already supports HTTPS through the host relay. Run 406 (on the 12:04 image) shows `https PASS` with title "Home | Haiku Project - WebPositive"; the relay connects to `haiku-os.org`. See `evidence/integration/nightly-run-406/report.txt` for the full log.

## What is in the image / packages

Everything from the 2026-09-20 nightly (Haiku system + HaikuPorts riscv64 toolchain: bash,
coreutils, grep/sed/awk, tar/xz/zip, git, curl, wget, openssh, ...) plus the WebKit family:

    webpositive-r1~beta6_hrev60105-1  haikuwebkit-1.9.30-3   (JavaScriptCore, baseline JIT)
    brotli-1.2.0-1                    libicu*                sqlite-3.53.4.0-1
    libxml2-2.15.3-1  libxslt-1.1.45-2  woff2-1.0.2-3        libidn2/libpsl/libunistring
    libexecinfo-1.1-6

The `haikuwebkit*-3-riscv64.hpkg` pair in this directory is what the image ships (JIT); the
`*-1-riscv64.hpkg` pair is the 2026-09-21 interpreter build, kept so the two releases can be
compared and because the devel package pins its runtime revision. Either pair installs the
browser stack onto any compatible Haiku riscv64 system (WebPositive itself comes from the
nightly image or the HaikuPorts repository).

## Proof in this bundle (`capstone/`)

- `capstone-nightly-run-109-report.txt/.json` and `capstone-nightly-run-110-report.txt/.json`:
  **the two consecutive full capstone PASSes on this image** (sha256 `bea856e0…`), 12/12
  checks each, `webpositive: http_get_js_ok: true` on the JIT engine; screenshot
  `screenshots/webpositive-riscv64-jit-2026-09-22.png`.
- `jit-benchmark-2026-09-22.txt`: interpreter vs JIT numbers from one guest boot.
- `capstone-nightly-run-108-report.txt/.json`: first full capstone PASS on the previous 20:32 image (sha256 `9d9b5c2a…`, interpreter build): 12/12 checks green - boot on 4 harts with no faults; 1920x1080 display;
  USB keyboard + tablet input; DHCP and gateway ping; 440 Hz tone through virtio-sound;
  `wget` from the host; typed command in Terminal read back; StyledEdit text saved; ShowImage
  PNG rendered; MediaPlayer playing an `.au`; **webkit_hello** (jsc reads back `hello-riscv64-ok`) and **webpositive** (browser ready, page fetched over HTTP, JavaScript executed: `http_get_js_ok: true`).
- `capstone-nightly-run-107-report.txt/.json`: the capstone PASS on the previous 12:04 build (sha `89cde69b…`), kept for comparison.
- `capstone-nightly-run-106-report.txt/.json`: the run before it, kept as diagnostics. Same
  image; every check passed except one audio flake - MediaPlayer's tone capture stopped early
  (no segment >= 1 s), an unrelated re-runnable artifact: WebPositive and webkit_hello both
  passed in that run too. Run 107 above is the green re-run the release claims on; it is also
  what `tests/test_release_webkit.py` pins offline.
- `webpositive-jsok-proof-2026-09-21.txt`: host access-log proof that the browser itself
  issued both `GET /index.html` and the script-generated request.
- **HTTPS via proxy relay proven**: run 406 shows `https PASS` (WebPositive opens https://haiku-os.org through the host relay). See `evidence/integration/nightly-run-406/report.txt`. Plain HTTP to the host at 10.0.2.2 is verified in every capstone run.

## Repeating the proofs

In the goal workspace, `harness/capstone.py --profile nightly --run N` boots a copy of this
image with exactly the QEMU command below (headless: `-display none`, QMP socket, WAV audio
sink), clicks through the FirstBootPrompt over the USB tablet, and runs all checks listed
above on one boot; reports land in `evidence/integration/nightly-run-N/`. The workspace
tests re-derive every verdict offline from those run directories (the release-level
checks for this bundle are `tests/test_release_webkit.py`).

## Running it on a desktop (Ubuntu 24.04 example)

```sh
sudo apt install qemu-system-misc          # qemu-system-riscv64 with OpenSBI bundled
sha256sum -c SHA256SUMS
cp haiku-nightly-hrev60105-riscv64-webpositive-2026-09-22.image mine.image   # boot a copy

qemu-system-riscv64 -M virt -cpu rv64 -m 4G -smp 4 -accel tcg \
  -bios default -kernel u-boot-riscv64-qemu.bin \
  -drive file=mine.image,format=raw,if=none,id=x0 \
  -device virtio-blk-device,drive=x0,bus=virtio-mmio-bus.0 \
  -device virtio-gpu-pci,xres=1920,yres=1080 \
  -device qemu-xhci -device usb-kbd -device usb-tablet \
  -netdev user,id=net0 -device virtio-net-device,netdev=net0 \
  -audiodev pa,id=snd0 -device virtio-sound-pci,audiodev=snd0 \
  -display sdl -serial stdio
```

- `-bios default` = QEMU's bundled OpenSBI; `-kernel u-boot-riscv64-qemu.bin` is U-Boot for
  the virt machine from github.com/haiku/firmware (in this workspace: `upstream/firmware/u-boot/riscv64/qemu/u-boot.bin`).
- The disk **must** be `virtio-blk-device` on `virtio-mmio-bus.0`; PCI virtio-blk never
  reaches userland on this hrev.
- `-display sdl` keeps the 1920x1080 guest mode (GTK pushes its placeholder window size into
  the EDID and forces 640x480 - see the 2026-09-20 README for details).
- Audio needs PulseAudio/PipeWire (`-audiodev pipewire`/`alsa` alternatives; `none` to keep
  the device silent). Networking: user-mode, guest DHCP at 10.0.2.15, host reachable as 10.0.2.2.
- First boot waits at the **FirstBootPrompt** ("Welcome!" dialog) - click **Try it out**;
  that is not a hang and nothing appears on serial while it waits (~60 s OpenSBI-to-dialog under TCG).

## Building WebPositive's engine: how the cross-build was done (repeatable)

From `BUILD_WEBKIT.md` in the workspace, in short:

1. Toolchain: Haiku riscv64 cross gcc/g++ 13.2 from a built Haiku tree
   (`upstream/haiku/generated.riscv64/cross-tools-riscv64/bin/riscv64-unknown-haiku-{gcc,g++}`);
   sysroot `webkit/sysroot` assembled from the built haiku packages + riscv64 devel
   packages. Vendor into it: Khronos EGL/KHR headers (from WebKit's own ANGLE include tree)
   and Haiku's `Accelerant.h`. Host tools ruby/perl/python3/cmake/ninja/bison/flex; gperf
   built from source into `.tools/` (put `.tools/bin` on PATH).
2. Configure + build **on the host** (never inside the guest), incremental - never delete
   the build directory:

   ```sh
   export PATH=$PWD/.tools/bin:$PATH
   cmake -S upstream/haikuwebkit -B webkit/build-riscv64 -G Ninja \
     -DCMAKE_TOOLCHAIN_FILE="$PWD/webkit/toolchain-riscv64.cmake" \
     -DGPERF_EXECUTABLE="$PWD/.tools/bin/gperf" \
     -DPORT=Haiku -DCMAKE_BUILD_TYPE=Release \
     -DENABLE_JIT=ON -DENABLE_C_LOOP=OFF -DENABLE_DFG_JIT=OFF -DENABLE_FTL_JIT=OFF \
     -DENABLE_WEBASSEMBLY=OFF -DUSE_AVIF=OFF -DUSE_JPEGXL=OFF \
     -DENABLE_WEBKIT=OFF -DENABLE_WEBKIT_LEGACY=ON -DENABLE_MINIBROWSER=OFF

   ninja -j44 -C webkit/build-riscv64-jit         # all targets, ~15 min at -j44, incremental
   # (the 2026-09-21 interpreter build: -DENABLE_JIT=OFF -DENABLE_C_LOOP=ON into webkit/build-riscv64)
   ```

3. Image integration: the HaikuPorts riscv64 `haikuwebkit-1.9.30-3` + devel packages (built
   here as hpkgs, see below) make the nightly's jam pick up WebPositive automatically -
   rebuild the image with `jam -q -j48 -sHAIKU_REVISION=hrev60105 @nightly-mmc` in
   `upstream/haiku/generated.riscv64` (~3-4 min incremental).

## Patches (git format-patch, both apply cleanly onto the bases)

`patches/haiku/` = `git -C upstream/haiku format-patch master` on branch
`brainos/riscv64-fixes`:

1. crt0: keep the stack 16-byte aligned in the riscv64 EFI loader (SMP crash fix)
2. device_manager: publish legacy driver directories after boot (`/dev/audio`)
3. virtio_sound: hmulti_audio driver for VirtIO 1.2 sound + media kit in the minimum image
4. package_daemon: fix double free of VolumeState packages on first boot
5. Add `au_reader` to SYSTEM_ADD_ONS_MEDIA_PLUGINS (riscv64 nightly)
6. au_reader: fix -Werror=sign-compare for 64-bit targets
7. riscv64: read/set the wall clock through the Goldfish RTC on QEMU virt (TLS-ready date)
8. HaikuPorts riscv64: add haikuwebkit-1.9.30-1 + devel (WebPositive enablement)
9. WebPositive: use WebKitLegacy headers for the haikuwebkit packages
10. Revert of 8 in-tree (the recipes are shipped as prebuilt hpkgs alongside this image
    instead; kept so the series stays a faithful record of the branch)

`patches/webkit/` = `git -C upstream/haikuwebkit format-patch HaikuWebKit-1.9.30` on
branch `brainos/riscv64`:

1. wtf: use `<bsd/pthread.h>` for `pthread_attr_get_np` on Haiku (StackBounds)
2. cmake: fix Haiku port options for riscv64 C-loop-only builds (OpenGLES2 conditional, no mimalloc)
3. jsc: support Haiku riscv64 `mcontext_t` in MachineContext accessors
4. jsc: do not require glibc `link.h` on Haiku
5. WebKitLegacy: remove `-lGL` from the Haiku link line for riscv64
6. jsc: include CCallHelpers.h directly in InlineCacheCompiler.h
7. jsc: drop the redundant per-label `.attribute arch` in RISC-V64 offline asm
8. Fix JIT build errors for riscv64: incomplete type and missing CCallHelpers methods
9. Fix JIT build errors for riscv64: complete SimpleJumpTable/StringJumpTable types
10. Fix RISCV64Disassembler template parsing (comments in the DisassemblerType list)
11. Disable RISCV64Disassembler to work around a GCC template-pack bug
12. jsc: build the baseline JIT for Haiku riscv64 (LOL tier gated, DFG-off variant, mcontext fix)
13. cmake: forward the RISCV64 assembler headers so WebCore builds with the JIT on

Both series were checked with sequential `git apply` onto fresh exports of their base
commits (`master` / tag `HaikuWebKit-1.9.30`) - see `tests/test_release_webkit.py`, which
re-verifies this and the SHA256SUMS offline.
