READING EDITION / RESEARCH PREVIEW

This is a static guide, not a live service status. Public remote writes and execution remain disabled. No JavaScript is needed to read this page.

SQLite Body and Lua Programs

This guide describes the first portable body slice. Status words are contractual: SHIPPED means code and tests are in this repository, EXPERIMENTAL means a runnable or inspectable fixture exists but is not a compatibility promise, and PLANNED means design only.

Lua source artifact
  → restricted parser/compiler
  → cursor continuation graph
  → placement + capability check
  → SQLite transactional body
  → Linda assertions/interests with leases
  → Cap'n Web / MessagePort live pipeline
  → bounded semantic sync envelope
  → independent DO SQLite / swarm bodies

The boundaries matter: source is not executable authority, a tuple match is not effect authority, an RPC session is not durable history, and a SQLite changeset is not the Cursors protocol.

SHIPPED: the body contract

src/sqlite-body.mjs supplies a native-compatible schema and allowlisted operation compiler for stored sources, compiled programs, mailbox envelopes, tuple assertions, interests, transactional effects, receipts, fetched-resource metadata, and semantic-sync envelopes. The tables are ordinary SQLite tables, placed deliberately:

Local file Owned tables
self.db stored sources and compiled programs
mailbox.db mailbox envelopes, receipts, semantic-sync envelopes, and the mailbox outbox
world.db tuple assertions, interests, and the world outbox
cache.db verified fetched-resource metadata
outbox.db effects with no co-located semantic intent

An effect is inserted in the same attached database transaction as its local semantic intent; only after commit does a scheduler observe pending rows. The shipped persistent backends do not claim crash atomicity across attached files, so an operation batch may target only one database. SELECT never sends mail or performs an irreversible network effect.

Four connection profiles describe the authorizer boundary:

Profile Intended authority
admin migrations and local ATTACH
internal body-owned operational reads/writes
readOnly inspectors and analytics projections
appScoped named allowlisted application tables

The JavaScript model enforces these profiles now. The browser query capability prepares exactly one statement, asks SQLite's own sqlite3_stmt_readonly() whether it can write, and installs sqlite3_set_authorizer() while it runs. SQL text prefixes are not a security boundary. Row count, SQL bytes, parameters, result bytes, VM execution time, message bytes, and request rate are bounded.

Pure deterministic helpers cover lease validity, canonical-byte recognition, and predicates over already-verified capability material. Hash and mailbox helpers remain asynchronous Web Crypto operations at the API boundary because SQLite scalar callbacks are synchronous in the official WASM OO1 API. Effectful operations go through cursor_outbox.

SHIPPED: official SQLite WASM Worker

browser/sqlite-body-worker.mjs imports @sqlite.org/sqlite-wasm and owns the writable databases in a dedicated Worker. It exposes backend diagnostics plus open, close, restart, bounded read-only query, allowlisted apply, and restricted Lua compilation. apply accepts only mailbox.enqueue, mailbox.receipt, and world.assert; schema, ATTACH, and raw write SQL remain internal.

The present ownership is one writable Worker per page. This PR does not claim cross-tab singleton ownership. A later SharedWorker, Web Lock leader, or explicit handoff may provide that without changing the body API.

The Worker selects among backends that its loaded build and browser context actually expose:

Backend Reality
upstream opfs preferred persistent baseline when cross-origin isolation and OPFS are present; browser-tested
upstream opfs-sahpool selectable persistent backend using a private SyncAccessHandle pool; browser-tested
memory shipped fallback; explicitly transient
upstream opfs-wl exposed by the package but not registered here until its operational contract is measured
wa-sqlite IDBBatchAtomic/custom VFS studied alternative and future adapter; not installed, so no performance claim
sql.js-httpvfs / sqlite-wasm-http read-only fetched-snapshot contenders, not writable body backends

Roy Hashimoto's wa-sqlite work is the model for keeping VFS choice pluggable: IndexedDB batch-atomic and custom VFS designs can win under different browser constraints. They should join the same harness before selection, rather than being declared universally faster.

Backend selection happens on first open. Attempts to switch a live body or make one Worker own a second body are rejected. Each registry entry reports availability, persistence, read/write capability, isolation requirements, locking, multi-database transaction support, and whether durable cross-file atomicity is actually claimed.

self.db attaches mailbox.db, world.db, cache.db, and outbox.db before schema initialization, only as local files. A Cloudflare Durable Object database is never attached.

SHIPPED: Lua as stored source

src/lua-program.mjs stores UTF-8 source bytes and their source ID separately from compiled program bytes and program ID. The record includes language='lua', profile/version, optional metadata, declared capabilities, and compilation status.

The example examples/watch-party-presence.lua uses only four allowlisted calls. Arguments are JSON-compatible literals inside Lua call syntax. It compiles to assert, interest, and checkpoint graph nodes with renewable, bounded Linda leases. It cannot import, call the host, access properties, execute arbitrary Lua, or directly cause effects.

parse/validate
  → restricted intermediate form
  → cursor program graph
  → placement/capability check
  → execution body

This is intentionally not a general Lua AST. A later compiler can recompile the same source record and compare program IDs without rewriting the source artifact.

SHIPPED: cockpit proof flight

The Lua + SQLite Machine Lab runs this slice inside the browser. It opens the dedicated Worker, compiles the watch-party source, displays the content-addressed graph, applies a leased world.assert plus its co-located outbox row, and queries both records back. The standalone /cursor-machine-proof.html entry uses the same component and is useful when separating body behavior from Open MCT shell startup. See the operating guide.

EXPERIMENTAL: Sessions and projections

SQLite Session/changesets are the preferred normal-table capture mechanism when a build enables the Session extension. The envelope schema has optional changeset bytes plus required schema ID, causal horizon, capability reference, signature reference, and semantic rows. The installed official browser package does not expose a stable high-level Session API, so this PR does not fake one. Semantic rows remain the portable contract; changesets are an optimization between compatible, validated bodies.

cursor_tuples is the first real relational projection. Its indexes push lease horizon constraints into SQLite now. A native virtual-table module may later translate xBestIndex constraints for tuple shape, publisher, and horizon into Cursors interests. cursor_mailbox, cursor_history, cursor_resources, and cursor_receipts remain planned narrow read-only modules.

SHIPPED: Cloudflare boundary

worker/semantic-sync.js accepts only bounded allowlisted semantic row families after a caller-supplied Cursors signature/capability verifier succeeds. Durable Object SQLite stores independent operational state. It does not receive pages, WAL, arbitrary SQL, or extension callbacks, and it does not turn its physical schema into identity or authority.

Operational versus analytical formats

Tool/format Job Status
SQLite hot mutable mailbox, lease, outbox, receipt, and local join state SHIPPED slice
Arrow columnar interchange from validated projections PLANNED
Parquet immutable cold checkpoints/history for analytics PLANNED
DuckDB / DuckDB-Wasm analytical queries over exported or attached read-only material PLANNED

DuckDB does not replace SQLite for mutation. Torrent bencoding remains torrent-local. TIP/TLV islands remain experimental.

Benchmarks without invented claims

Run npm run bench:sqlite. The harness reports transaction-heavy inserts, indexed reads, and registered-function query time for official SQLite WASM memory and node:sqlite when available. It lists OPFS and uninstalled fetched-database adapters as unavailable instead of printing fictional numbers.

Run npm run test:browser for real Chromium coverage of cross-origin isolation, OPFS and SAH-pool selection, local ATTACH, restart persistence, unavailable-backend errors, backend lock-in, co-located mailbox/outbox writes, and SQLite-enforced read-only queries. There is still no universal “fastest browser SQLite” claim: the writable mailbox workload and read-only HTTP-range workload are different benchmarks.

Continue with SQLite + Lua Cursor Machine, Machine Lab, Nelua portable core, SQLite and VFS, and Cap'n Web Pipeline.