z-lua-core
Installation
SKILL.md
Lua core
Treat every embedded Lua script as untrusted input until proven otherwise — sandbox by allowlist, budget its resources, keep the host API surface small and typed.
Semantics that bite
- 1-based indexing — every host-side index crossing the boundary needs a +1/-1; do that conversion in one place (the binding layer), not scattered across call sites
- Do not use
#tas a count when a table has holes. Track the count explicitly, or usetable.pack'snwhere supported; Lua 5.1 does not providetable.pack. - everything is a table — arrays, objects, and modules all reuse the same structure. Naming and doc comments are the only thing keeping "array-like" and "map-like" tables from getting confused
- metatables are the sanctioned extension point (
__index,__newindex,__call, operator overloads) — don't stack them into a deep fake-inheritance chain; it stops being readable fast
Embedding discipline
- sandbox by allowlist: strip
io,os,debug,package/require,load/loadstringfrom any environment running untrusted or semi-trusted script content — grant back only what's proven needed, not the reverse - Enforce execution and memory budgets with the selected embedding library's supported controls. Hooks do not interrupt blocked host callbacks: propagate cancellation there too. If the runtime cannot enforce the required memory boundary, isolate untrusted work in a limited process.
- host API surface small and typed — expose a curated set of host functions with validated argument types, not the whole host object graph
- At a raw Lua C API boundary, preserve stack balance and return counts. Use mlua's safe typed API where possible; callers do not ordinarily manipulate
lua_State*. Follow gopher-lua's documentedLStatefunction return convention.