---
url: >-
  https://adk.nht.io/api/batteries/orchestration/cells/lua/functions/createLuaCell.md
---

# Function: createLuaCell()

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

Defined in: [src/batteries/orchestration/cells/lua/index.ts:680](https://github.com/NHTIO/ADK/blob/v1.20260906.0/src/src/batteries/orchestration/cells/lua/index.ts#L680)

Construct a Lua predicate evaluator cell.

## Parameters

| Parameter  | Type                                                            | Description                                                               |
| ---------- | --------------------------------------------------------------- | ------------------------------------------------------------------------- |
| `options?` | [`CreateLuaCellOptions`](../interfaces/CreateLuaCellOptions.md) | Optional enforcement tuning: instruction budget, memory ceiling, timeout. |

## Returns

[`LuaCell`](../interfaces/LuaCell.md)

A [LuaCell](../interfaces/LuaCell.md) 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](../interfaces/LuaCell.md#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.
