Blaze
Sound hot reload · JIT-native · Apache-2.0

The live logic runtime.

Swap a function in a running production process — in ~500 microseconds.

Provably safe. Canaried against live traffic. Instantly reversible. An embeddable JIT scripting runtime — for humans, and for AI agents.

“LaunchDarkly flips booleans. Blaze swaps functions — in 500 microseconds, with a proof, a canary, and an undo button. And it is how you let an AI touch production logic without fear.”
$ git clone https://github.com/grloper/Blaze && cd Blaze && cargo run -p blaze-jit --release --example living_service -- --script
Read the proofs →
496µs
body-edit hot-swap under live HTTP load
51,815
requests across 6 live edits · 0 dropped
51×
faster than an embedded interpreter, same rule
110
tests, each attacking a claim from a 2nd thread

See it run

A living service under fire.

An HTTP risk-scoring service whose logic is a .blaze program, hot-swapped while thousands of requests per second pour through it. Six live edits — every beat asserted, over real HTTP, under load.

Recorded deterministically from docs/living_service.tape. Hammered from four threads by tests/living_service.rs.

How it can be safe

The firewall: callers read the signature, not the body.

Blaze is an incremental compiler first. Source is a fine-grained salsa query graph in which a function’s lowered IR depends on its own text and its callees’ signatures — never their bodies. That asymmetry makes every edit’s blast radius a computed fact, not a guess.

reads the SIGNATURE — never the body raw source (input) function_text(f) ← firewall node function_signature(f) lowered_dev_ir(f) compiled_machine_code(f)

An edit to a function’s body re-lowers only that function — every caller is a byte-for-byte memo hit. An edit to its signature forces exactly the callers that read it into the radius. The graph computes the blast radius as a byproduct of recompiling the edit.

Rejected

A defect is proven — nothing goes live

Syntax error, undefined callee, arity or type mismatch, undefined variable. Nothing is compiled or patched; the previous known-good generation keeps serving every call untouched.

NoEffect

The edit changed nothing that matters

No function’s IR changed — a comment, whitespace. Zero codegen, zero generations, and it costs nothing at all.

SafeSwap

A body changed, signatures held

One lock-free atomic pointer store — valid under concurrent execution, because the firewall guarantees no caller’s code mentions anything about the callee but its slot.

The category

Everything else guesses, flips, or restarts.

Live behavior change isn’t new — but every existing approach trades away granularity, proof, or speed. Blaze keeps all three.

Approach Unit of change Where it runs Reload speed Proven radius Per-rule canary Rollback
LaunchDarkly Boolean / config flags SaaS eval ($20k+/yr) flag flip n/a (no code) flag off
OPA / Rego Whole policy bundle In-process whole-bundle reload redeploy bundle
Sandbox / microVM Whole script / process Out-of-process seconds (spin-up) restart
dlopen / hot-patch Native library In-process ms, guessed diff ✗ guessed reload library
Blaze Individual functions In-process JIT ~500µs, proven ✓ per edit ✓ live traffic ✓ one call

For AI agents

Let an AI touch production logic — without fear.

The same pipeline that protects a human protects an autonomous editor. Every proposed edit runs a gauntlet before it can reach a real request.

01
Propose
The agent writes a candidate function.
02
Gate
Diagnostics prove it well-formed, or Reject it.
03
Offline eval
Scored against a reference test set.
04
Canary
Shadow-run on sampled live traffic.
05
Promote / Abort
Clean → classified swap. Bad → auto-abort.
06
Metrics
Lock-free counters confirm the outcome.

The killer scenario: an edit that passes every offline test.

A candidate clears the whole offline eval set — then loops forever on an input shape the eval set never covered. The canary shadow-executes it on a sampled slice of live traffic, under the primary’s own fuel budget, and traps FuelExhausted. It auto-aborts and is never promoted. The caller only ever saw the live answer.

→ asserted in agent_loop.rs::the_agent_pipeline_keeps_every_bad_edit_out_of_production

“The blast radius of a bad idea is a shadow execution, not an outage.”

Benchmarks

Real numbers, honestly labeled.

Every number below is single-run, release mode, measured on this repo’s dev container — a modest, shared cloud box. They vary run to run; the ratios and orders of magnitude are the point, and the structural claims survive any hardware. Each table ships a cargo run you can reproduce.

Reload latency, per edit class

bench_reload — a 40-function call chain where every function transitively depends on the edited leaf; median of repeated edits.

EventLatency
Full cold compile (≈ a restart’s compile cost)8.5 ms
Body edit → SafeSwap (radius 1 of 40)0.74 ms
Comment → NoEffect (radius 0)0.54 ms
ABI edit → Relink (radius 2)1.9 ms
$ cargo run -p blaze-jit --release --example bench_reload

Call throughput

bench_calls / bench_vs_interpreter — a trivial leaf (dispatch cost), and the same branchy risk rule vs. an embedded interpreter (rhai), cross-checked to agree on every input.

PathThroughput
call(name) — lock + string lookup per call~19 M calls/s/thread
call_handle — resolve once, then lock-free~50 M calls/s/thread
call_handle, 4 threads (~94% linear)~188 M calls/s
rhai call_fn — AST interpreter, same rule~0.96 M calls/s/thread

~51× the interpreter on identical logic — and still hot-swappable, which a compiled dylib is not. That is the “swap functions, don’t flip booleans” number.

$ cargo run -p blaze-jit --release --example bench_vs_interpreter

Canary overhead on the live path

bench_canary — what call_canary costs the live path, on a ~46 ns leaf so the deltas are visible. The caller always gets the live answer.

ModeOverhead
Idle (no candidate — one atomic load)+~4 ns/call
Shadowing 1% of calls (lock-free sampler)+~4 ns/call
Shadowing 100% of calls (a full shadow every call)+~220 ns/call
$ cargo run -p blaze-jit --release --example bench_canary

Claims → proofs

Every claim is a theorem with a test.

Every “instant”, “safe”, and “proven” on this page traces to a named test that attacks the guarantee from a second thread while it holds. Here are the strongest — each links to its function on GitHub.

A body edit swaps live under concurrent calls — zero missed calls, zero torn values. live.rs::body_edit_swaps_under_concurrent_execution
An ABI edit is classified Relink and transitions atomically — observed values are only ever fully-old or fully-new. live.rs::signature_edit_relinks_atomically_under_fire
A syntax error is Rejected; last-good keeps answering every concurrent call. live.rs::syntax_error_holds_last_good_under_concurrent_execution
Unbounded recursion aborts the call with a typed error — it never faults the host. live.rs::unbounded_recursion_aborts_with_error_not_a_crash
An infinite loop aborts with FuelExhausted, never hangs — the runtime is healthy afterward. live.rs::infinite_loop_aborts_with_fuel_exhausted
The fast FuncHandle path is torn-free under concurrent hot-swaps. live.rs::handle_calls_are_correct_under_concurrent_body_swap
A canary’s candidate answer never reaches a caller — even under a storm of mirrored calls. canary.rs::the_caller_never_sees_the_candidate
A diverging candidate auto-aborts and cannot be promoted. canary.rs::a_diverging_candidate_auto_aborts
rollback(gen) reverts through the same swap protocol, torn-free under a second thread. journal.rs::rollback_is_sound_under_concurrent_execution
A live-edited x / 0 cannot fault the host — division is guarded in codegen. jit.rs::division_is_guarded_and_cannot_fault_the_process
Per-function metrics are exact under concurrent callers, lock-free. metrics.rs::counts_are_exact_under_concurrent_callers
The whole living-service story — six live edits under sustained load, each classified as claimed, zero dropped calls. living_service.rs::the_living_service_story_holds_under_load
An autonomous agent’s gate + eval + canary pipeline keeps every bad edit out of production. agent_loop.rs::the_agent_pipeline_keeps_every_bad_edit_out_of_production

Honest limits

A focused core, not a general language.

What Blaze deliberately does not do yet — so you know before you build on it. None of these change the reload and safety guarantees.

One file, one flat namespace

A program is a single .blaze source of top-level functions. No modules, no imports.

Two scalar types only

int (i64) and float (f64). No strings, arrays, structs, or pointers — which is also why a script can’t corrupt the host: there are no memory operations to abuse.

State lives in the host

Blaze functions are pure over their scalar arguments; all persistent state is the embedder’s. That is exactly what makes state survive every reload.

Retired code is retained, not freed

A concurrent caller may still be inside an old generation mid-swap, so old code pages stay mapped. The cost grows with edit count × edited-function size.

A canary re-executes each sampled call

Mirror only logic free of observable host side effects (the norm for scoring functions). A canary is an evaluation mode, not steady state.

StateMigration is reserved

A reserved EditClass for when script-owned persistent state lands with layout versioning. Today it cannot occur.