This table gathers every pyproc capability behind the product entrance a user starts from. It is not a market-readiness or adoption table: it groups the public surface by intrinsic value, contract state, prerequisites, runnable surface, verification, and boundaries.
Canonical sources are split:
- Install, version pinning, import boundaries: contract.md
- The speed-measurement contract: benchmarking.md (measurements live only in ledgers and artifacts. Speed is something you measure yourself with the Speed Lab, not a number posted here for you to trust)
.pymachinetrust and the permission UI: trustPermissions.md- Portable bundle (
PYBUNDLE1) envelope layout: bundleFormat.md - Reopening product resources after a revival: resumeCatalog.md
- Platform requirements and preflight (browser, JSPI, COOP/COEP, engine, resources): platformRequirements.md
Contract states match the README's Capability contract. They describe only what pyproc itself can prove.
| State | Conditions |
|---|---|
| Complete | The declared success, failure, and recovery invariants run in a real browser; the installed package exposes the same path; a deliberate failure proves the guard; types and docs state the boundary. |
| Bounded | The listed behavior is implemented and gated, while a precise intrinsic boundary remains in the row. No fallback or elapsed-time condition changes this state. |
| Probe | A runnable experiment proves a narrow mechanism, but it is not part of the default product entrance. |
| Engine proof | A second engine proves separation of primitives; it is not the default Python Machine. |
A state drops immediately if its own invariant, installed path, negative proof, or declared boundary disappears. Adoption, user count, another repository, release age, and market response are never inputs.
Every Complete row appears here. The structure gate compares the two sets and rejects missing browser, installed-package, negative, or boundary evidence.
| Surface | Invariant | Browser gate | Installed-package gate | Negative proof | Declared boundary |
|---|---|---|---|---|---|
| Python runtime | Real CPython executes, loads packages, and owns file IO in the tab | npm run test:browser |
npm run test:installed |
invalid options and corrupted engine bytes are deliberate RED fixtures | Pinned Pyodide package corpus and browser platform requirements |
| Deployment asset integrity | Engine, worker, and Service Worker bytes are verified before execution | npm run test:browser |
npm run test:installed |
bad script, core, worker, and manifest hashes are deliberate RED fixtures | Same-origin static asset layout |
| Default durable Machine | open() settles a command only after heap, /home/web, and outcome share one durable generation |
npm run test:browser |
npm run test:installed |
commit failure and failover outcome-unknown paths are deliberate RED fixtures | Last completed generation; an unprovable in-flight effect is never replayed |
A runnable surface is an example a person opens, a browser gate, a probe, or a tracked benchmark artifact. Every product claim must be reproducible through one of the runnable surfaces in the table below.
| Capability | Product value | Public surface | Contract state | Prerequisites | Runnable surface | Verification | Boundaries |
|---|---|---|---|---|---|---|---|
| Python runtime | Runs CPython, package loading, stdout/stderr, and file IO in a browser tab | boot -> machine handle (machine.run/machine.fs), checkEnvironment, escape hatch machine.runtime (Runtime, FileSystem, MemoryCapability); PAGE_SIZE is in pyproc/history |
Complete | A supported browser (platformRequirements.md), Pyodide v314.0.2 (CPython 3.14), optional SRI, and use of the public API rather than the internal raw.FS |
basic example, browser gate | npm test, npm run test:browser, npm run test:installed |
Not a guarantee for every Python package. Native C extensions need a Pyodide build or a static build |
| Deployment asset integrity | Copies worker, SharedWorker, and Service Worker assets to your own origin and verifies the bytes | getPyProcAssetManifest, verifyPyProcAssetIntegrity, registerPyProcServiceWorker, PYPROC_ASSET_MANIFEST_VERSION in pyproc/assets |
Complete | Your deployment preserves the manifest's relative path structure, provides the pyproc-assets SRI manifest, and configures Service Worker scope and headers |
asset manifest CLI, installed-package browser gate | npm test, npm run test:package, npm run test:installed |
Opening a worker graph from CDN URLs alone is blocked by the browser's same-origin policy |
| Restore reactivity | Saves state at execution boundaries and offers live-diff restore, time travel, and branching | machine.history (checkpoint/restore/tree/prune); the internal contract is ReactiveController (machine.runtime.enableReactive()) |
Bounded | Declared checkpoint boundaries, the recorded engine/manifest contract, and a restorable heap delta | browser gate, the [hash soundness] and [reactive tree] property and fuzz sections of the structure gate | npm test (the [hash soundness] false-negative fuzz plus the [reactive tree] arbitrary-tree reference-integrity property, both with negative tests confirmed), npm run test:browser (full-heap byte-for-byte round trip and more) |
Does not automatically capture an in-flight Promise, a network request, or an external handle at an arbitrary moment |
| Process OS | Spawns Python workers as processes and offers snapshot-fork, live fork fan-out (forkMany), map, mapArray, sharded matmul, signals, and IPC |
machine.proc() -> PyProc, SIGNAL |
Bounded | crossOriginIsolated, SharedArrayBuffer, JSPI, same-origin worker assets, and handling of the checkEnvironment() result |
process OS example, speed lab, browser gate, installed-package browser gate | npm run test:browser, npm run test:installed, npm run test:examples |
Not full POSIX fork and not native shared-memory threads. It is a browser-worker OS model. The boundary identity that fork and forkMany rest on holds only worker-to-worker: a replay in the main kernel and one in a worker kernel produce different bytes even at the same heap length (loader and context differences), and for the same reason heap addresses differ across browsers and machines (same contents, different layout; measured 2026-07-17 at 178-184 of 480 pages). That is why fork stays between workers and PyProc is the coordinator |
| Browser server URL | Runs a Python ASGI app inside the kernel and fetches it from a real browser URL | machine.runtime.enableAsgiServer() (AsgiServer), VirtualOrigin (SW registration through registerPyProcServiceWorker in pyproc/assets) |
Bounded | pyprocSw.js Service Worker registration, same-origin scope, and a route-prefix design |
server dev example, installed-package browser gate | npm run test:installed, npm run test:examples |
Not a real TCP listener, and three boundaries are now measured and gated rather than assumed: a synthesized response cannot set a browser cookie, a WebSocket upgrade never reaches the kernel (fetch interception only), and a streaming response arrives as one buffered body, so more_body is accepted but SSE does not stream |
| Terminal and borrowed syscalls | Attaches a serverless Python terminal, blocking input, a subprocess worker, and a sync bridge | machine.term() (Terminal), machine.runtime.enableSyscallBridge() (SyscallBridge) |
Bounded | A JSPI-capable browser, terminal UI event wiring, and the child worker asset | terminal example, terminal probe, syscall probe | npm run test:browser, terminal and syscall probes |
A borrowed-syscall layer, not a complete POSIX syscall table |
| Environment lane | Reproduces a repeatable environment from a declaration (packages, lock, wheel cache) | The boot manifest (packages/env/setup/wheelDir, absorbing the former bootEnv/runScript), machine.runtime.enableWheelCache() (WheelCache) |
Bounded | Wheels installable under Pyodide, a consistent lock and manifest, and an OPFS cache | env manager campaign, PEP 723 probe, wheel cache probe | env manager probes, installed-package gate | Native wheels cannot be carried over as they are. Reproducibility breaks if engine, lock, and cache fall out of step |
| Portable machine image | Exports the heap delta and /home/web as a .pymachine and reopens it under a signature and a trusted public key |
boot({ deterministic: true }) (formerly bootSession) plus machine.history.export/save (formerly Session), open (formerly openMachine); the signature chain lives in pyproc/history (formerly createMachineKeyPair/exportMachinePublicKey/fingerprintMachinePublicKey), Init (machine.runtime.enableInit()) |
Bounded | The same engine and manifest, use of /home/web, a trust key or explicit trust, and a resume.py hook design |
machine example, installed-package browser gate, golden workflow | npm test (the [envelope and image boundary] section: bundle index-forgery rejected at the prefix, machineImage adversarial-input boundaries, negative tests confirmed), npm run test:installed, npm run test:golden |
A signature is provenance trust, not permission. File descriptors, sockets, and DB connections must be reopened by resume.py |
| Machine journal | Uses idle commits and a WAL to revive a crashed tab from the heap and /home/web of the last commit |
machine.history.commit/recover/watch/pack (MachineJournal) |
Bounded | OPFS, an idle-commit policy, pack/prune operations, and the same engine and manifest | journal probe, large heap journal probe, installed-package browser gate | journal probes, npm run test:installed |
A long-lived blob store grows without pack and prune. It is subject to browser storage quota. Changes after a commit are lost |
| Permission jail | Restricts Python code's net, clipboard, home, and worker permissions through a permission manifest and CSP | enableJail(permissions) on machine.runtime, returning { jail, permissions, connectSrc } |
Probe | A permission manifest, the jail context's CSP, a host allowlist, and a permission UI | jail probe, installed-package browser gate, trust and permissions | npm run test:installed, npm run test:browser (the enableJail evidence checks), jail probes |
Not a sandbox that removes every side channel available to code in the same parent window. Strong isolation requires an opaque-origin design |
| Outbound sockets | Lets Python socket, urllib, and http.client reach an external host:port |
SocketBridge (pyproc/socket) |
Probe | A WS-to-TCP relay, JSPI blocking recv, and product operation of that relay | socket campaign, Python socket probe | socket bridge probes | Inbound sockets are a browser security wall. For HTTPS the relay handles TLS |
| Device filesystem | Exposes browser features as Python file paths | machine.runtime.enableDeviceFs() (DeviceFs) |
Bounded | Explicit device injection, browser permissions, and a clear file-path policy | installed-package browser gate, device FS probe, machine campaign | npm run test:installed, device FS probes |
Only explicitly configured devices allowed by browser policy exist |
| GPU compute | Uploads f32 arrays to WebGPU and runs a GPU-resident linear algebra pipeline | GpuCompute, GpuArray, GpuBridge (pyproc/gpu) |
Probe | WebGPU, a windowed browser, a real GPU, and an f32 data path | GPU campaign, GPU tiled probe, GPU Python probe | GPU probes on real hardware | WGSL has no f64. Headless CI numbers are not evidence of product performance |
| Default durable Machine | Opens one named Python Machine across tabs and cold-reopens it after every tab closes | open() / open({ name }) -> KernelElection; run auto-commits heap, /home/web, and forwarded outcome before settling |
Complete | Web Locks, BroadcastChannel, OPFS, the verified same-origin engine distribution, and the same origin. SAB-based OS capabilities also need crossOriginIsolated and JSPI |
immortal demo, kernel election probe, installed-package browser gate, golden workflow | npm test (serialized run/commit, commit-failure outcome-unknown, election fencing and outcome records), npm run test:installed (argument-free open plus cold reopen without manual commit), npm run test:golden |
Not a multi-user server. Recovery is to the last completed command generation. A normal follower cut off mid-command still cannot prove leader-heap portability, so the durable RPC state table closes it as non-retryable outcome-unknown |
| Machine container and jobs | Starts a separate machine kernel inside a browser worker and offers job control | machine.containers() -> MachineContainer, machine.jobs() -> JobControl (a process-OS lane: it assumes the same replay pool as machine.proc) |
Bounded | crossOriginIsolated, the worker graph, and an explicit process-lifecycle policy |
browser gate (the machine.jobs and machine.containers evidence checks), installed-package browser gate, machine container probe, job control probe, pipe and shm probe | npm run test:browser, the MachineContainer and JobControl rows of npm run test:installed, process OS probes |
Not a Linux container and not an OS scheduler. It is pyproc's browser-kernel isolation model |
| Guests on one wire | Two guests on one computer exchange real Ethernet frames instead of merely coexisting | The built-in network device of createWebComputer (a MemoryEthernetSwitch), the pyprocNet module inside the Python guest, and the frame law exported from pyproc/machine |
Bounded | createWebComputer with network left on, and a guest that speaks frames |
guest network probe, packet network probe | npm run test:web-machine (the guest network probe runs in CI; the Linux crossing is in the local --v86 lane) |
Only ARP and ICMP echo are answered automatically; TCP, UDP, and DNS are the guest's own business. There is no uplink, so guests reach each other and nothing else. Both guests currently share one JS thread, so a frame arrives between run() calls rather than during one |
| Non-Pyodide engine seam | Proves the session and time-travel primitives work on non-Pyodide CPython 3.14 WASI | bootWasi, WasiSession (pyproc/wasi) |
Engine proof | A caller-provided wasmURL, the WASI worker asset, and the JSON value bridge |
WASI browser gate, engine port campaign, WASI REPL probe | WASI gate, dual engine probe in npm run test:web-machine:wasi |
Not the production default engine. The value bridge is JSON-centric and C extensions need a static build |
- The README's Product entrances table is the API map. This document groups those paths into capability contracts backed by runnable evidence.
- Run
checkEnvironment()and the deployment preflight before entering a capability whose prerequisites require them. - Keep Probe rows outside the default product path until their own acceptance conditions become automated.
- Where the browser physically blocks something - inbound sockets and arbitrary native binaries above all - pyproc alone promises nothing. Those need a relay, an agent, a static build, or a change in the platform.