An AI-native language for declarative systems
A BEAM language designed as a compilation target for AI coding agents — with verified state machines, protocol checking, chaos testing, and compiler-generated telemetry
Named for the Norse goddess who witnesses oaths. Vor programs are oaths about system behavior — declared, witnessed by the compiler, and enforced.
AI agents are writing more and more code. They’ll inevitably build distributed systems. And they’ll produce that code faster than humans can review it.
We need compilers that catch what human review would miss — not as a separate practice, but as part of ordinary compilation.
The BEAM already provides process isolation, supervision, and distributed message passing — eliminating entire classes of bugs. Vor adds the layer the BEAM doesn’t: verification that your state machines are correct, your protocols are compatible, and your system recovers from failures.
One source file declares agents, protocols, invariants, and constraints. Two commands verify it, one stress-tests it:
mix compile → proves safety properties (milliseconds)
mix vor.check → bounded-verifies multi-agent invariants (seconds)
mix vor.simulate → chaos-tests real BEAM processes (minutes)
An AI agent writes one file. Three commands verify it. The compiled binary is a standard OTP process, pre-instrumented with telemetry — no separate spec, no instrumentation code.
agent LockManager(lock_timeout_ms: integer) do
state phase: :free | :held
state holder: atom
state wait_queue: list
state auth_token: binary sensitive
protocol do
accepts {:acquire, client: atom, priority: integer} where priority >= 1 and priority <= 10
accepts {:release, client: atom}
emits {:grant, client: atom}
emits {:queued, position: integer}
emits {:ok}
end
on {:acquire, client: C, priority: P} when phase == :free do
transition phase: :held
transition holder: C
emit {:grant, client: C}
end
on {:acquire, client: C, priority: P} when phase == :held do
transition wait_queue: list_append(wait_queue, C)
qlen = list_length(wait_queue)
emit {:queued, position: qlen}
end
on {:release, client: C} when phase == :held do
if list_empty(wait_queue) == :true do
transition phase: :free
transition holder: :nil
emit {:ok}
else
next_client = list_head(wait_queue)
transition wait_queue: list_tail(wait_queue)
transition holder: next_client
emit {:ok}
end
end
safety "no grant when held" proven do
never(phase == :held and emitted({:grant, _}))
end
liveness "lock released eventually" monitored(within: lock_timeout_ms) do
always(phase == :held implies eventually(phase != :held))
end
resilience do
on_invariant_violation("lock released eventually") ->
transition phase: :free
transition holder: :nil
end
end
The safety invariant is proven at compile time. The where constraint rejects invalid input before handlers run. The sensitive field is redacted in telemetry. The liveness invariant is monitored at runtime with automatic recovery. Every state transition and message generates telemetry. This compiles to a standard OTP gen_statem.
Wire agents together and mix vor.check bounded-verifies distributed invariants by exploring all message interleavings within configured bounds:
system RaftCluster do
agent :n1, RaftNode(node_id: :n1, cluster_size: 3)
agent :n2, RaftNode(node_id: :n2, cluster_size: 3)
agent :n3, RaftNode(node_id: :n3, cluster_size: 3)
connect :n1 -> :n2
connect :n1 -> :n3
connect :n2 -> :n1
connect :n2 -> :n3
connect :n3 -> :n1
connect :n3 -> :n2
safety "at most one leader" proven do
never(count(agents where role == :leader) > 1)
end
end
Tracked fields: current_term, role, vote_count
Abstracted fields: commit_index, log, voted_for
Symmetry: enabled (3 identical agents, 6× reduction)
✓ Bounded-verified (1001 states, depth 10)
Verification proves properties within bounds on a model. Chaos testing complements it by exercising real compiled code under failure — catching implementation bugs, timing issues, and recovery failures the model checker can’t reach.
mix vor.simulate --partition --delay --workload 10
Starts real BEAM processes, injects real failures, checks invariants against live state:
--seed NFor BEAM-native systems, no external chaos infrastructure is needed — the BEAM provides failure injection as function calls.
The compiler knows every state field, message type, and transition. It generates telemetry calls in the compiled bytecode — no instrumentation code in the source file.
| Event | Fires on |
|---|---|
[:vor, :agent, :start] |
Agent initialization |
[:vor, :message, :received] |
Handler invocation |
[:vor, :transition] |
State field change (sensitive fields redacted) |
[:vor, :message, :emitted] |
Reply sent |
[:vor, :constraint, :violated] |
Protocol constraint rejection |
Attach any :telemetry backend and every agent is observable. You still need a metrics backend (Prometheus, Grafana) to view the data — Vor generates the events.
For BEAM-native actor systems, Vor addresses several concerns that typically require separate tools: formal verification replaces a separate specification language, chaos testing uses BEAM-native primitives instead of external infrastructure, protocol composition checking at compile time replaces contract testing, compiler-generated telemetry replaces manual instrumentation, and protocol constraints replace validation libraries.
These simplifications apply to BEAM-native systems. Infrastructure-level concerns — provisioning, external HTTP routing, metrics backends, CI/CD, load testing, secrets management — remain outside the language.
Vor is designed as a two-language stack:
extern gleam blocksAll five examples are fully native Vor. Gleam is there when you need typed library functions for complex data operations.
The spec is the program. No separate specification. No drift.
Guarantee tiers are explicit. proven at compile time, monitored at runtime. The compiler fails closed — it never claims to verify what it can’t.
Observable by default. The compiler generates telemetry from the program’s structure.
Input validated at the protocol level. where constraints reject invalid messages before handler code runs.
Sensitive data declared. Fields marked sensitive are redacted in telemetry.
Failure is first-class. Resilience handlers define recovery. Recovery paths are verified.
The BEAM is the foundation. Thirty years of production-proven concurrency, fault tolerance, and distribution.
394+ tests · 9 property-based test suites · Raft bounded-verified in 1,001 states · MIT License