Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
41e36da
feat(pvm): run framebuffer products through Wasm
replghost Aug 26, 2026
f1c9893
feat(pvm): enforce App manifest v2 identity
replghost Aug 26, 2026
d0c9155
fix(pvm): support bounded CoreVM game hostcalls
replghost Aug 26, 2026
7828cff
feat(pvm): support Tri2D and WebGPU Raster
replghost Aug 27, 2026
063e9bb
fix(pvm): await smoldot app manifest resolution
replghost Aug 27, 2026
34d351f
perf(pvm): compile graphics profile guests
replghost Aug 27, 2026
55c0053
fix(pvm): slice long hostcall sequences
replghost Aug 27, 2026
e51c04a
refactor(pvm): consume neutral browser runtime
replghost Aug 28, 2026
b2dc852
chore(pvm): pin neutral runtime source
replghost Aug 28, 2026
7139607
refactor(pvm): share worker runtime core
replghost Aug 28, 2026
7374107
test(pvm): allow app-specific smoke inputs
replghost Aug 28, 2026
c4a1498
fix(pvm): consume Epoca input events
replghost Aug 28, 2026
50cc282
style(pvm): format runtime adapter
replghost Aug 28, 2026
33ff30c
fix(pvm): vendor reviewed host runtime
replghost Aug 28, 2026
416160c
fix(pvm): revendor Epoca input runtime
replghost Aug 28, 2026
8d2084d
test(pvm): verify continuous Duke audio
replghost Aug 28, 2026
715d331
chore(pvm): point runtime source at PR branch
replghost Aug 28, 2026
68581c6
fix(pvm): retain launch contract across reloads
replghost Aug 29, 2026
7a73d23
fix(resolve): revalidate App v2 contenthashes
replghost Aug 29, 2026
36ad293
refactor(pvm): consume host runtime bridge
replghost Aug 29, 2026
f02f358
feat(pvm): add forced interpreter launch mode
replghost Aug 29, 2026
23beb4f
fix(pvm): restore bridge-owned worker bytes
replghost Aug 29, 2026
dbd8f98
fix(cache): store installed executable pairs atomically
replghost Aug 29, 2026
f1ae173
fix(pvm): expose interpreter startup stages
replghost Aug 29, 2026
e6639cd
fix(pwa): recover incompatible host-sandbox builds
replghost Aug 29, 2026
6fffb75
fix(pvm): protect bridge-owned runtime assets
replghost Aug 29, 2026
f785d7b
feat(pvm): vendor runtime v0.1.1
replghost Aug 29, 2026
8b79ac8
fix(pvm): use browser clock for CoreVM guests
replghost Aug 29, 2026
39e2278
fix(pvm): bound pointer-lock warp deltas
replghost Aug 29, 2026
c40fdb7
fix(pvm): reject pointer-lock jumps
replghost Aug 30, 2026
9cfdd51
fix(pvm): coalesce relative pointer backlog
replghost Aug 30, 2026
a60339c
fix(pvm): drop pointer-lock discontinuities
replghost Aug 30, 2026
f5b7606
fix(pvm): discard stale mouse backlog
replghost Aug 30, 2026
b1a80dd
fix(pvm): enable Safari CoreVM JIT
replghost Aug 30, 2026
1f748eb
feat(pvm): route baseline TrUAPI in sandbox
replghost Aug 30, 2026
074b8c4
fix(pvm): negotiate canonical TrUAPI port
replghost Aug 30, 2026
e70e0bd
fix(pvm): restore bridge-owned runtime assets
replghost Aug 30, 2026
d43f0bb
style(pvm): format TrUAPI transport
replghost Aug 30, 2026
85f2e6d
test(pvm): prove canonical TrUAPI roundtrip
replghost Aug 30, 2026
09f06b3
fix(pvm): update runtime to v0.1.4
replghost Aug 30, 2026
16e4a6e
test(pvm): isolate live performance server
replghost Aug 30, 2026
6c3b4a8
fix(pvm): reconnect warm runtime cache
replghost Aug 30, 2026
57158ef
fix(pvm): compact runtime metrics overlay
replghost Aug 30, 2026
6f92aa8
fix(pvm): explain unsupported app features
replghost Aug 31, 2026
27365ec
fix(pvm): recover WebGPU apps across resize
replghost Aug 31, 2026
12c215b
fix(pvm): capture pointer for WebGPU games
replghost Aug 31, 2026
f542cc6
chore(pvm): pin reviewed motion bridge
replghost Aug 31, 2026
b4dcf71
style(pvm): format resize coverage
replghost Aug 31, 2026
e02644c
feat(pvm): integrate MotionSample v1
replghost Aug 31, 2026
5dcee56
chore(pvm): pin merged GPU motion runtime
replghost Aug 31, 2026
09b7b79
feat(pvm): require explicit relative pointer input
replghost Aug 31, 2026
80c612f
test(pvm): separate capture from guest input
replghost Aug 31, 2026
3a2ab28
test(pvm): retain relative pointer control label
replghost Aug 31, 2026
e5e7358
Revert "test(pvm): retain relative pointer control label"
replghost Aug 31, 2026
ccd0d3d
Revert "test(pvm): separate capture from guest input"
replghost Aug 31, 2026
b31cda0
Revert "feat(pvm): require explicit relative pointer input"
replghost Aug 31, 2026
1c897b3
feat(pvm): deliver text IME focus and wheel input
replghost Sep 2, 2026
b6855c3
chore: rebase onto main and harden dependency overrides
replghost Sep 3, 2026
d5dc0cd
chore(pvm): pin merged advanced input runtime
replghost Sep 3, 2026
24ea647
chore(pvm): pin runtime v0.1.7
replghost Sep 3, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ jobs:
- name: Install dependencies
run: bun install --frozen-lockfile

- name: Verify PVM bridge assets
run: bun run check:pvm-runtime

- name: Run tests
run: bunx --bun turbo run test

Expand Down
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ node_modules/
bun.lock
tests/results/
docs/
apps/sandbox/public/pvm-runtime/
22 changes: 21 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ Each product gets its own `<label>.app.paseo.li` origin, so versions of the same
1. **Resolves** `.dot` names via an in-browser [smoldot](https://github.com/paritytech/smoldot) light client connected to Asset Hub Paseo, querying dotNS contracts.
2. **Fetches** content from the [Bulletin Chain](https://github.com/paritytech/polkadot-bulletin-chain) via smoldot `bitswap_v1_get` JSON-RPC or an IPFS gateway.
3. **Renders** the content in a sandboxed iframe with the Rust-backed TrUAPI bridge, so loaded SPAs can request accounts, sign transactions, connect to chains, and use scoped storage.
4. **Runs** verified framebuffer PolkaVM products by translating `app.polkavm` to WebAssembly at load time inside a worker, with a bounded interpreter fallback.

```
host-playground.paseo.li
Expand Down Expand Up @@ -100,12 +101,31 @@ When a CID points to an IPFS directory (not a single file):
4. The iframe loads from `/dotli-app/index.html` — the SW intercepts all requests and serves files from the in-memory archive
5. Relative imports (`<script src="main.js">`, `<link href="styles.css">`) just work

## How PolkaVM apps work

An archive whose `manifest.json` declares `runtime.kind: "polkavm"` never
executes package-owned HTML. The sandbox instead creates a host-owned canvas,
loads the verified `app.polkavm` and immutable package assets, and translates
the program to WebAssembly inside a worker. Keyboard, pointer, framebuffer,
PCM-audio, asset, and save traffic stays on the bounded PolkaVM host ABI.

The initial profile supports Epoca framebuffer ABI version 1, including CoreVM
products such as `doom.paseo`. Tri2D, WebGPU, and TruAPI guest hostcalls fail
closed until their capability boundaries are implemented independently.

Translated Wasm bytes are cached in product-origin IndexedDB by the SHA-256 of
the PVM program and the pinned translator version. Warm launches skip PVM
instruction lowering; WebAssembly compilation remains browser-owned. If
translation or Wasm compilation fails, the same worker retries through the
bounded interpreter.

## Caching and verification

dotli uses a two-layer cache for fast repeat visits:
dotli uses three cache layers for fast repeat visits:

1. **CID cache** (IndexedDB) — maps `.dot` labels to their last-known CID
2. **Archive cache** (Service Worker) — stores fetched file maps keyed by domain; a cache hit additionally requires the stored CID (and content backend) to match
3. **PVM translation cache** (IndexedDB) — stores translated Wasm bytes keyed by translator version and PVM program digest

On repeat visits, content renders instantly from the cache while it is resolved in the background. The topbar shield shows how the current page was loaded:

Expand Down
10 changes: 6 additions & 4 deletions THIRD_PARTY_NOTICES.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ alphabetically. Copyright and permission notices for each package are retained
in its distribution under `node_modules`.

GPL-family components (GPL-3.0 with the Classpath linking exception) are
compatible with this project's AGPL-3.0 outbound license. Build-time-only
tooling under weak-copyleft (MPL-2.0) or source-available (FSL-1.1-MIT) terms is
used to build the application and is not redistributed as part of it.
compatible with this project's AGPL-3.0 outbound license. The vendored Epoca
PolkaVM browser runtime remains under MPL-2.0, with its PolkaVM-derived portions
under Apache-2.0 OR MIT. Its complete notices and source provenance ship beside
the runtime. Build-time-only tooling under source-available FSL-1.1-MIT terms is
not redistributed as part of the application.

> Generated from the resolved dependency tree (595 distinct third-party
> packages). Platform-specific binary packages (for example
Expand Down Expand Up @@ -76,7 +78,7 @@ smoldot, verifiablejs

## MPL-2.0

lightningcss, lightningcss-darwin-arm64
Epoca PolkaVM browser runtime, lightningcss, lightningcss-darwin-arm64

## FSL-1.1-MIT

Expand Down
7 changes: 6 additions & 1 deletion apps/host/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@
"scripts": {
"build": "tsc && bunx --bun vite build",
"build:prod": "tsc && bunx --bun vite build && bun ../../scripts/compress-dist.ts",
"test:functional": "playwright test --config=tests/functional/playwright.config.ts tests/functional/loading.spec.ts tests/functional/resolution.spec.ts tests/functional/navigation.spec.ts",
"test:functional": "playwright test --config=tests/functional/playwright.config.ts tests/functional/loading.spec.ts tests/functional/resolution.spec.ts tests/functional/navigation.spec.ts tests/functional/pvm.spec.ts",
"test:e2e": "playwright test --config=tests/e2e/playwright.config.ts",
"test:e2e:local": "E2E_PRODUCT_URL=${E2E_PRODUCT_URL:-http://localhost:5199} SIGNER_BOT_BASE_URL=${SIGNER_BOT_BASE_URL:-http://localhost:3737/} SIGNER_BOT_SVC_TOKEN=${SIGNER_BOT_SVC_TOKEN:-admin} SIGNER_BOT_NETWORK=${SIGNER_BOT_NETWORK:-paseo-next-v2} playwright test --config=tests/e2e/playwright.config.ts",
"test:perf": "PERF_RUNS=10 PERF_DOMAIN_A=explore PERF_DOMAIN_B=host-playground npx playwright test --config=tests/performance/playwright.config.ts tests/performance/cold-start.spec.ts",
"test:perf:base": "PERF_RUNS=20 PERF_SAVE_BASE=1 PERF_DOMAIN_A=explore PERF_DOMAIN_B=host-playground npx playwright test --config=tests/performance/playwright.config.ts tests/performance/cold-start.spec.ts",
"test:perf:compare": "bun tests/performance/compare.ts",
"test:pvm:doom": "playwright test --config=tests/performance/playwright.config.ts tests/performance/pvm-doom.spec.ts",
"test:perf:compare:md": "bun tests/performance/compare.ts --markdown",
"lint": "bunx eslint src/",
"typecheck": "tsc --noEmit"
Expand All @@ -21,10 +22,14 @@
"@dotli/eslint-config": "workspace:*",
"@dotli/typescript-config": "workspace:*",
"@playwright/test": "^1.59.1",
"@ipld/car": "^5.4.3",
"@ipld/dag-pb": "^4.1.5",
"playwright": "^1.59.1",
"@types/node": "^25.9.3",
"eslint": "^10.5.0",
"jsqr": "^1.4.0",
"ipfs-unixfs": "^13.0.0",
"multiformats": "^14.0.0",
"prettier": "^3.8.3",
"simple-statistics": "^7.9.0",
"typescript": "~6.0.3",
Expand Down
Loading
Loading