Skip to content

Spec overview

The formal q64 language specification, the public contracts every toolchain component agrees on, and (eventually) the conformance test suite.

Status: draft (v0). The contracts that unblock parallel development are already written; the formal language semantics follow.

Current contracts

FileCovers
qube.json5.md + .schema.jsonManifest file every qube ships at its root
diagnostics.md + .schema.jsonJSON envelope every toolchain binary emits on stderr
q64-cli.mdThe q64 binary’s CLI surface and subprocess contract
qube-cli.mdThe qube binary’s CLI surface and how it invokes q64
continuum-api.mdHTTP API between qube and the registry
modules.mdModule organization, imports, visibility, re-exports
faces.mdPolymorphism: faces (interfaces) and fits (implementations)
errors.mdResult<T, E>, try, panic / trap, Option<T>, Error face
effects.mdEffect markers, implication graph, propagation, capability disclosure
generics.mdType / const / region / effect parameters, bounds, where, defaults, inference
types.mdNumeric tower, bool, arb-width ints, parameter modes, optional narrowing
units.mdUnit lattice: blessed unit types, prefixes, dimensional algebra, logarithmic units, @unit
annotations.md@-form catalog: four categories, casing rule, position table, ANN diagnostic band
test-framework.md@test, assertions, capability mocking, property tests, Arbitrary face, TST diagnostic band
memory.mdRegions, dual heap, transfers, multi-memory layout, shared / managed annotations
concurrency.mdScopes, tasks, channels, select, actors, cancellation, panics, host translation
streams.mdSignal / Event / Stream, @stage, graph,
env.mdCapability model, Env structure, main signature, with_capabilities, disclosure
grammar.mdLexical structure and the consolidated syntactic grammar
rpc.mdQube-to-qube RPC over the synthesized WIT world: wRPC + component-value wire, the @wire effect, transports, addressing
tests/Conformance test corpus — .q source files paired with expected diagnostic envelopes. See tests/README.md for conventions and tests/INDEX.md for code coverage.

Wasm 3.0 is the platform; the Component Model is an optional wrapper

Core Wasm 3.0 (the feature set committed in memory.md §“The platform” — multiple memories, WasmGC, threads + atomics, stack-switching, SIMD, plus a per-build address space of either wasm32 or wasm64) is q64’s compilation target and primary artifact. qube build produces a core module; the address space is chosen explicitly per build — there is no default (wasm32 is the WebKit/iPad-compatible baseline; wasm64 adds Memory64 for capable hosts).

WIT and the WebAssembly Component Model are not part of core Wasm 3.0 — they are a layered spec for host integration. q64 treats them as an opt-in wrapping layer: a component embeds the unmodified core module and adapts it to the canonical ABI, for hosts that speak components (wasmtime serve, jco / componentize-js, wasmCloud). Emitting a component does not change the language.

The component’s import/export surface is synthesized, not authored: its exports are the qube’s public functions, and its imports are the qube’s compiler-derived capability set (per env.md and effects.md). The same synthesized world is the contract for qube-to-qube RPC (see rpc.md) — the canonical-ABI value encoding doubles as the wire format.

q64 targets WASIp3 (WASI 0.3) as its Component Model baseline. WASIp3 adds native stream<T> / future<T> to the canonical ABI, so the Signal / Event / Stream family does bridge to WIT — a Stream<T, R> lowers to WIT stream<T> and a Future<T> to WIT future<T> at the component boundary (see streams.md and env.md §“Env and the Component Model (WASI Preview 3)”). WASIp3 is at release-candidate status upstream; q64 tracks it, pinned to the snapshot the active runtime implements and re-pinned on each upstream RC release (see env.md).

One abstraction is still deliberately not bridged to WIT: faces / fits (a type-class system, not WIT resources — see faces.md). Sending WIT resources over the wire is also deferred, pending the separate upstream resource-transfer story (not part of WASIp3 async).

Scope (forthcoming)

  • Type system inference algorithm — the full bidirectional inference rules. (Primitive types and parameter modes landed in types.md; effect markers in effects.md; generics in generics.md.)
  • Conformance test corpus expansion — first batch of ~40 tests landed in tests/; remaining coverage tracked in tests/INDEX.md §“Next batches”.

Vocabulary

The spec is consistent about a handful of words that easily blur together. When in doubt, this table is authoritative.

Case carries meaning. Brand names are Capitalized — Q64, Qube, Continuum — and appear in headings, marketing, and running prose. CLI commands are always monospace lowercase — q64, qube — and only appear in code blocks, command examples, and shell output. For the noun qube specifically, case is also semantic: lowercase qube is a library; Capitalized Qube is a deployable artifact (see qube.json5.md’s type field). Lowercase plural qubes is the generic term covering both.

WordMeaning
qubeA library qube — type: "library", exports a surface, no main. Linked into other qubes statically (dynamic linkage later).
QubeA deployment artifact qube — type: "application", requires a main. The runnable unit.
qubes (plural)The generic noun, covering both libraries and deployable artifacts. What you browse in the Continuum.
qube (CLI)The qube CLI tool — package and build operations against the manifest.
Q64The language. Also the brand wordmark for the product family.
q64 (CLI)The language CLI tool (q64 build, q64 fmt, q64 lsp).
ContinuumThe registry — where all qubes exist. UI at continuum.q64.dev; HTTP API at qube.q64.dev. Wire contract: continuum-api.md.
faceA type-class-style polymorphism construct (≈ trait / typeclass / protocol). Not a WIT interface — see the interface row below and faces.md.
fitA binding of a type to a face (≈ impl). See faces.md.
regionAn allocator with a lifetime. The single noun for memory ownership in q64. See memory.md.
region kindA concrete strategy backing a region: Arena, Pool, Stack, FreeList, Managed. The blessed inhabitants of the Region face.
scope arenaThe implicit Arena-kind region bound to a scope { … } block, named scope. Where panic payloads and defaultable allocations land. See memory.md §“Scope’s implicit arena”.
effectA compile-time marker on a function (or stage, or face method) declaring what it touches or refuses. See effects.md.
stageAn @stage-annotated function — a node in a stream graph. See streams.md.
diagnosticAny structured tool output — error, warning, note. The envelope is defined in diagnostics.md.
trapThe bare Wasm “this module is no longer runnable” instruction. Distinct from panic. Used consistently across errors.md, effects.md, and concurrency.md — the word “halt” does not name a distinct concept in q64.
moduleA q64 source namespace — the unit of import / visibility / re-export inside a qube. See modules.md. Never the Wasm artifact; that is a core module.
core moduleThe primary Wasm 3.0 artifact q64 emit produces. The default qube build output. Distinct from a q64 source module and from a component.
componentThe opt-in WebAssembly Component Model wrapper around the core module (Component Model + WIT, not part of core Wasm 3.0). Emitted only when asked; embeds the unmodified core module. See modules.md §“The qube as a component”.
wasm32 / wasm64The build’s address space: 32-bit (i32 pointers, ≤ 4 GiB — the universal/WebKit baseline) or 64-bit (Memory64 + Table64, i64 pointers — not on WebKit). Chosen explicitly per build; there is no default. See memory.md §“The platform”.
worldThe WIT world synthesized from a qube’s public surface — its component exports (public functions) and imports (derived capability set). Authored by no one; generated. Also the RPC contract (see rpc.md).
interfaceThe WIT sense: a named group of functions / types / resources in a world. Reserved for this meaning in the spec. q64’s type-class abstraction is a face, never called an “interface” unqualified.
resourceA WIT handle to host- or instance-local state (e.g. an open file). Adapter-internal: q64 user code never holds one, and resources are not surfaced as faces/fits, nor sent over RPC.

Why a spec at all

q64 has one implementation today and may always have one. The spec is not written because of competing implementations — it is written because the compiler itself needs an answer key. A formal spec catches the cases where the implementation does something not-quite-right but technically consistent within itself.