kimiya

Embed · the runtime in your own program

Certain in the host, judged in Kimiya, certified at the boundary one front end · a portable IR · interchangeable runtimes · one certificate

The tutorial runs programs from a terminal. An application — a desktop shell, a phone, a browser tab, a server — wants the same guarantees inside: its own models, its own files, its own clock, its own way of stopping a run. This page is how that works, and what stays the same no matter who hosts it.

§1 · the shape of it

One front end, one document, many runtimes

Kimiya is not reimplemented per language. There is one front end — lexer, parser, the discipline checker (K1–K15), the type checker — and it is the Python one. It emits a checked program as a portable document, kir/1: a JSON tree with every name already resolved, every judged relation's task key fixed, every prompt template hashed, every irreversible act flagged, and a requires block saying what the program needs from a host. A runtime executes that document; it never parses source and never re-checks discipline — it may refuse a document, never reinterpret it.

python3 -m kimiya ir prog.kim          -- prog.kir.json: checked, resolved, hashed
kimiya-rt validate prog.kir.json      -- a runtime's own consumer validation
kimiya-rt run prog.kir.json name=value   -- the same certificate as `kimiya run`
kir/1The document. Frozen with 1.15.0: changes from here are additive or carry a new number. Its contract is docs/ir.md in the download — document shape, node set, static resolution rules, the validation a consumer must perform, and the decisions that pin number rendering, faults and line splitting so two runtimes cannot drift on them.
kabi/1The boundary (§2). What a runtime imports from its host and exports to it, and — the longer half — the behaviour that is the runtime's own and must be identical everywhere: prompt assembly to the byte, verdict parsing, panel composition, the θ ledger, datasheet normalisation, the trace and certificate schemas. docs/host_abi.md.
runtimeExecutes a document behind the boundary and performs no I/O of its own. Two exist: the Python reference (interpreter and compiler) and kimiya-rt in Rust, which is also the WebAssembly module, the C library and the Android library (§3).
hostYour program. It supplies the imports and owns everything the runtime must not: the models and their credentials, the files, the clock, the console, the workspace, and the right to stop a run.

Why not a second compiler

Because the certificate must mean one thing. If two implementations assembled prompts differently, or rounded θ differently, or ordered a panel differently, a certificate would be a statement about an implementation rather than about a run. One front end and a normative list of runtime-owned behaviour keep the semantics in one place; the runtimes are held to it by conformance (§4), not by good intentions.

§2 · the boundary

What a host supplies, what it gets back

Every import is a small set of named operations; a host may omit a whole import (no screen world on a phone) and the runtime refuses, before running, any program whose requires needs it. The imports:

oraclecomplete(agent, request) → reply. The runtime builds the request — prompt, system text, temperature, token cap — and hashes it; the host talks to the model. A request's error is classed transient (the runtime's silence rules apply), refused (the run stops) or cancelled. A reply may carry a structured verdict instead of words: that is how a small local classifier sits on a judge panel next to a chat model, and the certificate keeps the two distinct, seat by seat.
kernelHost functions — the program's pyfn / use python table, or whatever the host binds under the same names: a Rust twin, a worker process, a stub. Trusted like check; the certificate's kernel block says who bound each one.
worldsfile, screen, dom, and the image codec — observe and act, with the arity and effect class of each action fixed by the ABI, not by the host.
store · clock · console · credentialsThe workspace (trace, datasheets, memo, caches, certificate), the time every row is stamped with, where print goes, and how a named secret is resolved. A credential crosses the boundary inward only: into a request the host itself sends, never into a message, a trace or a reply.

The lifetime of a run

prepare(kir_json)             -- load + validate, once per document; refused with the problems named
execute(prepared, params, limits, host)   -- any number of times; each with its own params,
                                       --  limits, cancel token and host state
close(prepared)                -- releases the document and everything a run owned:
                                       --  prompts, replies, θ, memo keys (freed, not zeroed)

Every execution ends in exactly one outcome, a certificate whose status is one of COMMITTED, ENDED, ABSTAINED or CANCELLED. The fourth is the host's: a cancel token tripped from any thread, or a limit on model calls, tokens or host-clock seconds, stops the run at the next statement boundary or before the next model call, and the certificate's reason names what fired — cancelled by the host, limit: 40 model call(s) reached. A run is never stopped between a model call and the recording of its reply. What the program did (abstain) and what was done to it (cancel) are never confused.

in memoryA host that must touch no disk — a phone, a notes app in a privacy mode — gets an in-memory host: files, workspace, console and clock live for the run and are handed back once, or dropped. The outcome carries the certificate, the files the program wrote (never its inputs echoed back) and, only if asked, the trace.
receiptThe versioned minimal record to keep when the trace is not kept: status, θ and its factors, the instruments and their grades, the prompt-template hashes, cost, egress counts, the document's hash — and no claim text, no reason, no value. A retention ladder: trace in memory, receipt persisted, nothing else.
asynchronousA host whose answers arrive later — a coroutine, a network reply, a streaming on-device model, a browser — runs the same execution turned inside out: the runtime hands each host call to the embedder as an event and continues when answered. Natively that is a thread and a channel; in WebAssembly the module is suspended inside its one import and resumed with the reply. The runtime's code, and its certificate, are the same either way.
faultsA fault or abstention message never carries a value — a length, a type, a hash, never the text — so an error path cannot become a channel for sensitive input. Tests plant a sentinel in every input and assert it reaches no certificate, trace, console line, cache or receipt.

§3 · the runtimes

One runtime, five ways to hold it

kimiya-rt is a Rust crate that performs no I/O outside the traits of the boundary. Everything below is that one crate, compiled or wrapped differently; the conformance suite (§4) runs the same goldens through each.

RustImplement the traits (Oracle, Kernel, FileWorld, …), build a Host, run. The crate ships an in-memory host, a replay oracle, the live model backends (Ollama, OpenRouter and OpenAI-style over HTTP behind a cargo feature; the claude CLI with none), the live xdotool screen driver, a recorder that writes the conformance recording, and the threaded asynchronous session. A Tauri desktop application embeds it this way.
WebAssemblyThe crate on wasm32-unknown-unknown with every import crossing one imported function, host_call(op, payload), as JSON in linear memory. A second build rewritten by Binaryen's Asyncify lets a host operation return a Promise; the module sleeps inside the import and wakes with the reply. A Node reference host reproduces the goldens byte for byte and offers a live oracle.
Ckimiya_prepare, kimiya_execute, kimiya_close, a cancel token, and the asynchronous session as kimiya_execute_async / _session_next / _session_reply; the host is one callback, call(ctx, op, payload), JSON both ways. Built as a shared and a static library.
AndroidThe C library with a JNI surface, dev.kimiya.rt.Kimiya, built for arm64-v8a and x86_64. Kotlin bindings wrap it as KimiyaProgram with execute and a coroutine executeSuspending whose host is a suspend fun call(op, payload); cancelling the coroutine or the token ends the run CANCELLED even while a model call is outstanding. A Gradle demo app and eleven instrumented tests are in the download.
PythonThe reference, and still a host: Host(store=…, oracle=…, clock=…, kernel=…) replaces one import at a time; the interpreter and the compiler consult nothing else. An embedding in Python needs no other runtime.

Rust, in six lines

// a run with no disk: files in, certificate out
let doc = kimiya_rt::ir::load(&kir_json)?;
let (mut host, artifacts) = kimiya_rt::memory::memory_host(oracle, kernel, files, secrets);
host.oracle = Box::new(oracle::Live::new(credentials, LiveOpts { cancel: Some(token.clone()), ..Default::default() }));
let cert = Runtime::new(doc, host, &params)?.with_limits(limits).with_cancel(token).run();
let receipt = kimiya_rt::receipt::from_certificate(&cert);   // keep this; drop the trace

Node, with the WebAssembly module

node host/js/kimiya-rt.mjs run prog.kir.json --oracle live --max-calls 20
-- the asyncified module when present; a live provider awaited behind one import

Kotlin

KimiyaProgram(kir).use { program ->
    val out = program.executeSuspending(files = mapOf("transcript.txt" to text), host = myHost, cancel = token)
}   // out: {"status":"done","certificate":{…},"receipt":{…}} — no trace unless asked

§4 · the proof it is one language

Conformance: the same certificate, to the byte

Two runtimes agreeing is tested without a model. The reference records every model request — hashed exactly as the runtime assembled it: model, system text, prompt, temperature, token cap, image hashes — and every reply; a runtime under test is handed the recording as its oracle. A request the recording lacks is not a cache miss, it is a conformance failure: the runtime under test assembled a prompt the reference never made. Host-function calls are recorded and replayed the same way, so a program whose kernel exists only in Python still runs everywhere.

What is comparedHow
The traceEvery row, in order — judgments, votes, acts, observations, cache decisions — after dropping host-clock readings and the host's own paths.
The certificateEvery field, after dropping the three that legitimately differ: the runtime's version, the compiler's, and who bound the kernel.
The suiteTwelve goldens — text, image, screen, dom and batched instruments, one under a call cap — on four runtimes: the Python interpreter, the Python compiler, the Rust runtime, the WebAssembly module in Node. Forty-eight runs, byte-identical. A live run recorded on one runtime replays on the others.

Conformance is graded in levels — L0 text, L1 images, L2 screen, L3 dom, L4 the batched instruments — so a host can say precisely which part of the language it carries. The WebAssembly build is the text level by design: no worlds beyond files. The Rust runtime is L4, the whole language, with the screen and dom worlds under recording drivers and a live xdotool driver bound only on request.

Verified outside this repository

A desktop application that moved its contracts onto the Rust runtime recorded four of them live on Python — judge panels across a CLI-backed and an API-backed model, a schema generation, a vision locate with a screenshot judge — and replayed them on its embedded runtime: identical traces, identical certificates, no replay miss. That is what the boundary is for.

where to find it

In the download

Everything on this page ships inside kimiya-lang.zip: docs/ir.md and docs/host_abi.md (the two contracts), kimiya-rt/ (the crate, with its embedding, leak, screen and oracle tests), kimiya-rt-wasm/ and host/js/, kimiya-rt-ffi/ with the Android build script, android/kimiya-demo/, and tests/conformance/ with the goldens and the harness. The Rust crate is tagged on its own (kimiya-rt-v0.3.0 at this release) so an application can pin it.

The language itself

← The reference

Grammar, the discipline rules, the commands, and what every line of a certificate means.