Skip to content

Document browser WebGL2 and WebGPU rendering in Linux VMs and sandboxes - #2175

Merged
JacobStephens2 merged 2 commits into
mainfrom
docs/gpu-webgl-rendering
Nov 14, 2026
Merged

JacobStephens2 merged 2 commits into
mainfrom
docs/gpu-webgl-rendering

Conversation

@JacobStephens2

Copy link
Copy Markdown
Owner

Summary

Adds primary-source research and empirical benchmarks (docs/research/gpu-webgl-rendering.md) for headless browser WebGL2 and WebGPU rendering across Apple Silicon Linux VMs (vz vs. krunkit Venus, plus macOS host Chrome over CDP) and Linux bwrap sandboxes, following up on #1665 and #2173.

 docs/research/
 ├── linux-on-macbook.md     # Apple Silicon Linux VM comparison and Lima vz setup
+└── gpu-webgl-rendering.md  # Browser WebGL2/WebGPU benchmarks, krunkit/CDP root causes, and bwrap GPU binds

Evidence

Execution evidence

  • Before: git cat-file -e origin/main:docs/research/gpu-webgl-rendering.md exited 128 (no research note in docs/research/ covering browser WebGL2/WebGPU rendering in Linux VMs or bwrap GPU device/sysfs binds).
    After: test -f docs/research/gpu-webgl-rendering.md && scripts/affected-tests origin/main && git diff --check origin/main...HEAD exited 0:
    No checks for docs-only 'docs/research/gpu-webgl-rendering.md'.
    
  • Verified all 21 relative repository links in docs/research/gpu-webgl-rendering.md resolve on disk and all 12 upstream primary-source URLs return HTTP 200.
  • Empirical measurements recorded in the note were gathered on this Apple M5 Pro workstation (macOS Tahoe 26.5.2, Lima 2.2.1, krunkit 1.3.2, libkrun 1.19.8, molten-vk 1.4.2, Fedora 44 aarch64 with slp/mesa-libkrun-vulkan 25.3.6-102.fc44, Chromium 156.0.8078.79).

Merge Danger

Door: two-way

Adds one standalone Markdown research note under docs/research/.

Blast Radius: none

@JacobStephens2 JacobStephens2 added the in-progress A Claim: thirdshift has taken this issue label Nov 14, 2026
Mark where the bwrap GPU binds and SwiftShader figures were measured,
report the systemd-run result, correct the list of network-reachable
Command sessions and glossary terms, and mark claims not traced to a
primary source.
@JacobStephens2

Copy link
Copy Markdown
Owner Author

Review run. Pushed fixes to docs/gpu-webgl-rendering at 2dc095a. Spec axis used the pull request body alone; no closing issue was linked.

Review of PR #2175: GPU WebGL/WebGPU rendering research note

I fixed all three Standards findings and three of the four Spec findings in the research note, and committed them as 2dc095a2. The remaining Spec finding is a wrong number in the PR body, which only the author can change. Final validation passed: the full Rust suite ran, with 0 failures.

Spec source: the PR links no closing issue, so the Spec is the pull request body alone. I read issues #1665 and #2173 (title and body only) as context, not as the Spec. The only changed file is docs/research/gpu-webgl-rendering.md.

Standards (3 findings)

  1. Some claims cite no source, or only a landing page (breaks .claude/skills/research/SKILL.md, which says to cite each claim's source). This affected:

    • L36: the hv_vm_map 16 KiB alignment claim.
    • L52–55: the MoltenVK extension gaps and Dawn's checks.
    • L57: the Playwright --use-angle=swiftshader-webgl claim.
    • L71: Chrome DevTools rejecting Host headers.
    • L128: the NVIDIA device-node list.
    • L37: the 16 KiB Mesa patch.

    Fixed.

    • L36: now cites the hv_vm_map reference page (URL returns HTTP 200; parentheses percent-encoded so the Markdown link works).
    • L57: I checked Playwright's chromiumSwitches.ts. It adds --enable-unsafe-swiftshader but no --use-angle flag, so the claim was not backed by source. The note now calls the override observed but not traced, and links that file.
    • The rest: marked as inferred, observed, or not traced to a source.
  2. The §2.2 table (L80) and §4 (L116) miss some network-reachable runs (judgement call). They left out Triage runs without --read-machine, and other unsandboxed Commands.

    • Run: sed -n '361,371p' src/triage.rs | grep -n 'Sessions::within(&session_logs' printed a match, so the claim holds: those Triage runs are unsandboxed.
    • Fixed: both places now read "Unsandboxed Command sessions (for example … and Triage runs without --read-machine)", with a link to src/triage.rs L361-371, and say that --read-machine Triage runs are sandboxed but keep the network.
  3. Glossary terms misused at L99 (judgement call). The heading said Spec / Ticket, which are issues; the things that produce output are runs. Fixed: it now says Ticket run / Spec run.

The reviewer found no baseline smells worth acting on. All relative links and cited src/ line ranges checked out.

Spec (4 findings)

  1. The PR body's URL count is wrong. The body says "all 12 upstream primary-source URLs return HTTP 200". The finding's command printed 13 and exited 1, so the claim holds. Not addressed: see below.

  2. The systemd-run --user --scope result is never reported. The Method mentions it, but no section gives the result. The command exited 1, so the claim holds. Fixed: §4 now says that systemd-run --user --scope --property=MemoryMax=2G and unprivileged bwrap worked out of the box in the krunkit guest. That result comes from the body of GPU WebGL/WebGPU rendering options for Linux VMs and bwrap sandboxes #2173. After the fix the command exits 0.

  3. §4 claims more than was tested. The four bwrap configurations were presented as native Linux and NVIDIA results, but they only ran in the krunkit guest. The note also said "Mesa's Vulkan loader", but the drmGetDevices2() call comes from the Mesa driver. The command exited 1, so the claim holds. Fixed:

    • §4 and the TL;DR now say the binds were tested only inside the Fedora 44 krunkit guest, and that no native host was tested.
    • The NVIDIA note is marked untested.
    • "Vulkan loader" now reads "Vulkan driver (here Venus)".

    After the fix the command exits 0.

  4. Two SwiftShader figures don't match what was measured.

    • The TL;DR credited 84.62 ms/frame to a vz VM, but it was measured in the krunkit VM.
    • The note gave 1440×900 screenshots as "~85–150 ms", but that size was never timed.

    The command exited 1, so the claim holds. Fixed with the finding's other option, labelling where each number came from:

    • The TL;DR now says the figure was measured in krunkit, and is expected to carry over to vz, which was not measured.
    • §3.1 now says 1440×900 captures were not timed, and cites the measured 62.0 ms (720p) and 262.7 ms (1080p).

    The command's second half now passes. Its first half (--vm-type=vz must appear) still fails. I didn't make it pass, because no vz VM was run, and adding that flag would make the note claim a test that didn't happen.

Unaddressed findings

  • Spec 1 (PR body says 12 upstream URLs; there are 13): the number is only in the PR body, which this session may not edit. My check confirmed all 13 URLs plus the GPU WebGL/WebGPU rendering options for Linux VMs and bwrap sandboxes #2173 link return HTTP 200. The author should change the body to 13. This is a correction rather than a decision for the Day shift, so I filed no needs-triage issue.

Review coverage

  • Changed files: docs/research/gpu-webgl-rendering.md, read in full by both reviewers.
  • Unread changed files: none.
  • Generated-output exclusions: none.
  • Hand-written site pages: the Standards reviewer searched site/index.html, site/how-it-works/ and site/architecture/ and found nothing that needs updating.

Files read by the Standards reviewer:

  • docs/research/gpu-webgl-rendering.md
  • .claude/skills/research/SKILL.md
  • AGENTS.md
  • docs/agents/domain.md
  • docs/testing.md
  • GLOSSARY.md (bounded ranges)
  • docs/research/linux-on-macbook.md (partial)
  • docs/research/run-isolation.md (head)
  • docs/research/eval-sandboxes.md (head)
  • docs/adr/0003-static-binaries-through-github-releases.md
  • src/sandbox.rs (bounded ranges)
  • src/proxy.rs (bounded ranges)
  • src/sandbox/code_grader.rs (bounded ranges)
  • src/sandbox/triage.rs (bounded ranges)
  • src/triage.rs (bounded ranges)
  • site/index.html, site/how-it-works/, site/architecture/ (rg only)

Files read by the Spec reviewer:

The reports are in .thirdshift-review-tHoU4q/standards.md and spec.md, and summary.json is {"standards":3,"spec":4}.

Validation

Command Result
scripts/affected-tests main Exit 1, not a valid run. Local main (69c8689b) is older than the PR's base, so the diff swept in unrelated src/ and tests/ files. The npm test --prefix site check it chose failed: Cannot find package 'marked'.
scripts/affected-tests origin/main Exit 0. At the time, origin/main was the fixed point 960f0265. The untracked .review-logs/ files made it fall back to the full Rust suite. cargo test passed in 987 s: 4,524 passed, 0 failed, 201 ignored. The research note itself selects no checks (docs-only).
git diff --check origin/main Exit 0
Relative-link check (all links in the note resolve on disk) Pass; no missing targets
curl on every upstream URL in the note All HTTP 200 after the fix

There were no extra commands to run. The PR was still open when I checked it once, during the full suite. The fixes are committed as 2dc095a2, and no background tasks are left running.

Worst issue per axis:

  • Standards: uncited claims, one of which (the Playwright flag) is not backed by source.
  • Spec: §4 presented bwrap GPU binds tested only in the krunkit guest as native Linux and NVIDIA results.

Security

No unaddressed introduced findings.

CI red at 2dc095a

Inherited failures on main at 960f026:

Repair 1

I made no fix and no commit: the console-test failure doesn't come from this branch, and the test passes here.

Why the failure isn't this branch's

  • Compared with origin/main, the branch changes only one file, docs/research/gpu-webgl-rendering.md. Nothing it touches is read by the Console browser tests, and it adds or changes no tests or checks.
  • The failing test was Stop confirms, cancels and streams completion (requeue) at console/tests/stop.test.cjs:98. It failed with TypeError: Cannot read properties of null (reading 'height'): boundingBox() returned null for an element in the Stop panel.
  • The other 204 Console tests passed in that run, and the triage variant of the same test passed too.
  • Main's CI passed at this branch's merge base (960f0265) and on the two later main commits.
  • Because the branch makes no code or test change, a fix here would have meant editing an unrelated test. This looks like an intermittent Console test failure on the CI runner.

Validation (all in this worktree, logs under .review-logs/)

Command Result
cargo build --locked Passed, exit 0
npm ci (in console/) Passed, exit 0
node --test tests/stop.test.cjs (in console/) Passed, 3/3, exit 0
The same file run 5 more times All 5 passed (3/3 each), exit 0
scripts/affected-tests main Failed, exit 1 (explained below)
scripts/affected-tests origin/main Passed, exit 0
  • scripts/affected-tests main: my local main was out of date, so it compared against old history and selected files this PR doesn't change. It then stopped at npm test --prefix site with Cannot find package 'marked', because the site's npm packages aren't installed here. That failure says nothing about this branch.
  • scripts/affected-tests origin/main: this is the PR's real base. It printed No checks for docs-only 'docs/research/gpu-webgl-rendering.md'. The untracked validation logs in .review-logs/ also made it choose the full Rust suite as a cautious superset. That ran as cargo test (nextest isn't installed) and passed in 879.78 s.

No extra commands were requested. No background tasks are still running.

CI passed or absent at 2dc095a

@JacobStephens2 JacobStephens2 removed the in-progress A Claim: thirdshift has taken this issue label Nov 14, 2026
@JacobStephens2
JacobStephens2 merged commit cf24a5c into main Nov 14, 2026
24 of 25 checks passed
@JacobStephens2
JacobStephens2 deleted the docs/gpu-webgl-rendering branch November 14, 2026 13:22
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.

1 participant