Pure Lua DSL + interpreter for flow.ir — the Schema-as-Data IR used by
algocline and mlua-swarm-engine to author execution flows
(Node + Expr trees) as a single Lua table.
flow.ir is the canonical Pure Lua source of the IR. It carries:
flow.ir— public API (Node/Expr/compile/default_dispatch/wrap_step/try/fanout/let/concat/assert/format/ etc)flow.ir.schema—Node/Exprdiscriminated schema vialshape.tflow.ir.compile— two-pass validator (shallowlshapecheck + per-kind validator)flow.ir.interpreter— sync interpreter (canonical SoT for evaluation semantics)flow.ir.walk— tree traversalflow.ir.path—$.a.bread/write primitiveflow.{state,token,util}— sibling primitives (state KV / request token / misc util)
This repo lives outside any single consumer:
algoclineconsumes it via re-export throughalc_shapes(= alc-context wrap layer on top oflshape).mlua-swarm-engineconsumes it through themlua-flow-irRust binding (= async runtime + mlua glue on top offlow-ir-core, the Pure Rust sync reflection).
So: same IR, three reflections (Pure Lua / Pure Rust / mlua-glued Rust).
┌──────────────────────────────────────────────────────────────────────┐
│ flow-ir-lua (this repo) │
│ Pure Lua DSL / schema / interpreter / walk / path / compile │
│ alc dependency: zero. lshape vendored under `lshape/`. │
└──────────────────────────────────────────────────────────────────────┘
▲
│ Lua require
│
┌──────────────────────────────────────────────────────────────────────┐
│ flow-ir-core (Rust crate) │
│ Pure Rust schema + sync `eval` + `Dispatcher` trait │
│ no mlua, no async │
└──────────────────────────────────────────────────────────────────────┘
▲
│ re-export
│
┌──────────────────────────────────────────────────────────────────────┐
│ mlua-flow-ir (Rust crate) │
│ flow-ir-core re-export + mlua binding + async runtime │
│ (`eval_async` / `AsyncDispatcher` / Lua `module()` / fanout) │
└──────────────────────────────────────────────────────────────────────┘
▲
│
┌──────────────────────────────────────────────────────────────────────┐
│ mlua-swarm-engine (Rust crate) │
│ host concerns: Spawner / Worker / Loop / AuthzPolicy / cp_state │
└──────────────────────────────────────────────────────────────────────┘
- lshape (vendored under
lshape/) — Schema-as-Data primitive (kind-tagged Lua tables + combinators). Source: github.com/ynishi/lshape. Vendored because lshape does not (yet) ship a luarocks rockspec.
No runtime dependency on algocline, agent-block, or any host framework.
package.path = "./?.lua;./?/init.lua;;"
local ir = require("flow.ir")
local T = require("lshape.t")
local bp = ir.concat({
ir.wrap_step("uppercase", "$.input", "$.output"),
})
local compiled = ir.compile(bp)
local result = ir.default_dispatch(compiled, { input = "hello" }, {
dispatch = function(ref, input)
if ref == "uppercase" then
return string.upper(input)
end
end,
})
assert(result.output == "HELLO")flow-ir-lua/
├── flow/
│ ├── ir/
│ │ ├── init.lua public API
│ │ ├── schema.lua Node / Expr schema (lshape discriminated)
│ │ ├── compile.lua two-pass validator
│ │ ├── interpreter.lua sync interpreter (canonical SoT)
│ │ ├── walk.lua tree traversal
│ │ └── path.lua $.a.b read/write
│ ├── state.lua state KV primitive
│ ├── token.lua request token primitive
│ └── util.lua misc util
└── lshape/ vendored Schema-as-Data lib
├── init.lua / t.lua / check.lua / reflect.lua / luacats.lua
MIT OR Apache-2.0 (same as lshape upstream — dual license preserved).
Carved out of algocline-bundled-packages/flow/{ir,state,token,util}.lua
(2026-06-24) per mlua-swarm-engine v0.0.9 design v3 §7.3
(4-layer flow.ir stack separation). algocline retains the alc-context
wrapper (alc_shapes) which re-exports lshape for its bundled
packages; this repo is the ecosystem-neutral source.