Skip to content
Konjure / spatial intelligence

Design notes

Understand current contracts and the proposals that still need implementation.

Return to the language guide for lessons, or the language reference for implemented rules.

The language separates three kinds of work: describing values, changing an ordered ECS world, and asking a host to present that world. Rust owns language semantics and validation. A browser, native application or editor owns its platform resources and lifecycle.

Current boundaries

LayerCurrent responsibility
Parser and linkerNamed UTF-8 sources, syntax, declarations, imports and trait signatures
Type checkerAll bodies, inferred locals, method calls, fields, returns and typed component selectors
InterpreterChecked values, calls, control flow, execution budgets and transactions
ECSStable entity IDs, typed component joins and sequential lifecycle callbacks
Spatial bridgeValidated geometry and supported rigid-body components
HostDrawing, UI, playback, device permissions and resource access

The built-in Sphere type describes a value type. Sphere { radius: 0.3 } creates a value. spawn(Sphere { radius: 0.3 }) creates an entity with that component. A renderer can then interpret the component as geometry. Keeping those steps explicit makes pure data useful outside a scene and makes scene effects inspectable.

The built-in schemas include geometry, transforms, material, rigid-body state, text, image, video, audio, streams and controls. Consult the generated catalog for each name’s support status. A resource contract is data exchanged with a host; it is not evidence that a camera was opened, media played or a device permission was granted.

Rust hosts register typed native functions through NativeRegistry, pass it to compile_with_registry, then initialize a machine with the same signatures. Compilation checks native calls, and the runtime rechecks host argument and return values. A registered function must be pure and bounded: no I/O, device access, external mutation or panics. The interpreter cannot roll back such effects or preempt an unbounded native function. Keep those operations at an explicit host boundary instead.

Type-system direction

The numeric foundation implements explicit widths, checked arithmetic and exact conversion in the SDK. The language retains literal digits and chooses a dtype during checking. Tensors reuse the same scalar rules over packed storage.

Keep type, trait and system separate. A type defines reusable data and methods, a trait defines a behavior contract, and a system schedules work over matching components. Giving a type an implicit update loop would hide when its behavior runs and whether constructing an ordinary value changes the world.

Every function, method and callback body is statically checked, including unused code. Locals have inferred fixed types and collection elements are homogeneous. There is no permissive Any type in authored programs. Type checking establishes expression and call contracts; runtime checks still handle world membership, numeric bounds, allocation and termination budgets.

User-defined generic functions, access modifiers, and trait-associated types remain proposed extensions. Enums and exhaustive branching are implemented; see Enums and results.

Any expansion needs a precise interaction with nominal type identity, serialized values, module visibility and host bindings. Adding syntax without those contracts would make the editor promise more than the runtime checks.

Implementation choices

konjure-lang currently uses a bounded handwritten lexer and Pratt parser, with Ariadne for terminal diagnostics. Chumsky is a candidate parser library; it is not a dependency or a prerequisite for the public language contract. Rust token spans, symbols and the built-in catalog drive both documentation highlighting and the browser editor. The editor is a textarea with a token overlay and source services, not a full language server.

The interpreter owns a small ordered ECS whose components are runtime-defined type values. This avoids requiring a Rust type for each type in a loaded program. Keep storage and scheduling behind that interface so a different ECS implementation can be evaluated against the same tests when workloads justify it. Rapier supplies the current rigid-body solver; libm supplies shared numeric operations for native and WASM execution.

Systems and events

The scheduler runs explicit init, frame and done callbacks. A query selects one type or trait, or joins several distinct concrete component types. Bindings are typed and successful callbacks write component changes back as one transaction. Lifecycle membership participates in rollback.

Optional and excluded components, trait joins, declared read/write sets, parallel scheduling and explicit dependency constraints remain proposed extensions. Each needs a defined ordering and conflict policy.

A typed event queue is also a possible next boundary: events would need source, delivery order, lifetime and replay semantics. Host calls into named functions do not already constitute that event system. Input, voice and assistant actions must retain their own authorization and completion evidence.

Debugging direction

The runtime exposes source spans, metadata, logs and bounded execution traces. The workbench can advance a tick and inspect state. A full source debugger would additionally need breakpoints, paused stack frames, local-variable inspection and statement-level stepping; these are not implemented by a tick control.

Likewise, deterministic language execution is narrower than a replay guarantee for all host behavior. External model inference, media timing, physical sensors and irreversible effects require separate recording and replay contracts.

Rendering and spatial work

The shared spatial bridge should remain the source for geometry and physics semantics. A new renderer should consume those outputs rather than reimplement language evaluation. Blender and Unity adapters, custom shaders, advanced materials, animation rigs and richer collision shapes remain separate adapter or runtime work where they are not explicitly supported.

A rendered moving object or successful rigid-body test does not establish room anchoring. Camera calibration, tracking, room alignment and device rendering need their own measured integration evidence.

Retained scene compiler

The Rust SDK’s declarative scene and node compiler remains available with its existing examples. Its .konjure document output, unit suffixes and declared actions are documented in the legacy scene format. The programmable language does not silently reinterpret that source, and the two formats should not be mixed within one program.

Data pipeline invariants

PhaseInputOutput and invariant
ParseNamed UTF-8 sourceRaw literal digits, explicit generic selectors and slice syntax; byte spans retained
CheckAST and Rust builtin declarationsFixed scalar or tensor dtype on every checked expression, including unused bodies
EvaluateChecked expressions and budgetsSDK scalar/tensor operations; allocation, shape and arithmetic errors abort the transaction
PresentAccepted stateRust-validated geometry and typed buffer exports; the browser owns drawing and lifecycle

For let t = [1, 2]:i32; print(t[-1]?);, parsing preserves the selector and negative index. Checking assigns i32 to the elements and scalar result. Execution builds eight packed bytes and normalizes -1 against the length. Presentation receives the log 2; no JavaScript evaluates the program.

Validate this path with bash scripts/check-language.sh, cargo test -p konjure-sdk --doc, and npm run test:web after rebuilding WASM. The Rust-owned examples embedded in this site run in both native and WASM tests.