Skip to content
2 min read · 424 words

Function: createLuaCell()

ts
function createLuaCell(options?: CreateLuaCellOptions): LuaCell;

Defined in: src/batteries/orchestration/cells/lua/index.ts:680

Construct a Lua predicate evaluator cell.

Parameters

ParameterTypeDescription
options?CreateLuaCellOptionsOptional enforcement tuning: instruction budget, memory ceiling, timeout.

Returns

LuaCell

A LuaCell with id: 'lua', ready to be wired into an orchestration battery's evaluators. The cell's load() lazily imports wasmoon (an optional peer) and maps a missing peer to E_ORCH_CELL_UNAVAILABLE. validate() refuses a non-string predicate and loads the chunk so a syntax error surfaces at freeze. evaluate() builds a fresh sandboxed VM per call, injects the marshalled ctx.outputs as a ctx global, and interprets the result as a branch or select verdict.

The cell probes the count hook and the allocator cap against a canary at construction (the cap probe positively confirms setMemoryMax plus a tiny ceiling actually REFUSES a large allocation) and reports the actual enforcement guarantee via status(). If either probe fails it falls back to watchdog-only enforcement and REPORTS the reduced guarantee rather than claiming it.

Do not run the runaway-script test in-process. A test that confirms the watchdog actually SIGKILLs the process on while true do end must spawn a CHILD process and observe its exit signal; running it inside this process would kill the test runner. That test lives in a separate, opt-in harness and is never invoked by evaluate itself.

Remarks

THE WATCHDOG'S LAST RESORT IS SIGKILL ON THE HOST PROCESS — read this before wiring the cell. wasmoon is WebAssembly, so the Lua VM runs IN-PROCESS on the main thread. The watchdog is a worker thread, but what it kills is process.pid: your process, not an isolated evaluator.

That is deliberate and there is no lighter option. A synchronous WASM loop owns the main thread, so worker.terminate() has nothing to terminate and process.exit() never runs; only the OS killing the process breaks it. A timeout that cannot be enforced is not a timeout, and this cell would rather enforce one violently than advertise one it cannot deliver.

Be clear about the trade: a non-terminating Lua predicate takes the whole process down with it. The instruction-count hook and the allocator cap normally stop a runaway long before the deadline — the watchdog is the last resort, not the first — but if the construction canaries fail those probes, LuaCell.status reports the reduced guarantee and the watchdog is all that remains.

If a process-wide kill is unacceptable in your deployment, do not wire this cell for untrusted predicates. createStructuredCell cannot loop at all.