Axis / Build System / Recipe / Lua declaration adapter
Lua declaration adapter
This adapter loads authored Lua modules, records declarations and invokes captured handlers with explicit capabilities. It converts between Lua values and the native structures supplied by its caller. It does not choose which declarations should execute.
Source entry point and API: load.go.
Files and module lifetime
Load receives a root directory, optional supplied filesystem, module prefixes and explicit entry modules. It evaluates those entries in supplied order. It performs no filesystem discovery; callers may obtain entries by walking their own collections. The filename axis.lua has no special meaning to this adapter.
include(path) evaluates a declaration module once. load(path) evaluates a library module once and returns its value. A module supplied as an entry and reached through an import is still evaluated once. Paths are relative to the importing module. Recursive imports fail. Module availability does not select its declarations for execution.
The interpreter uses Lua 5.1 syntax and deterministic portions of the base, string, table and math libraries. Standard filesystem, process, clock, randomness, environment, debug and dynamic loading capabilities are unavailable. The registration functions named os and package do not expose the Lua libraries with those names.
Captured handlers execute in fresh loaded interpreter state with cancellation. Independent invocations may run concurrently over the immutable captured catalog, each with its own capabilities. Shared mutable state must not carry information across handler invocations. Authored code is trusted; isolation is not a security boundary against malicious code.
Registration vocabulary
A declaration is a table registered under a kind and a name. These functions describe the supported syntax, not an invitation to infer additional fields.
| Function | Role | Accepted fields |
|---|---|---|
package |
Named software construction and installation behavior | name version source builder requires tools environment toolchains inputs options configure build install |
os |
Named userspace composition request | name requires targets options configure |
target |
Named destination context | name machine environment toolchains requires options configure run |
builder |
Reusable source convention | name detect toolchains configure build install |
environment |
Prepared execution image declaration | name image prepare bootstrap |
Unknown fields, duplicate identities and invalid names fail. require creates a named dependency reference with an optional software-version constraint; it does not import a Lua module. bootstrap(name) creates an explicit reference to a prepared tool descriptor. Registration and module inclusion are prohibited during handlers.
Values and handler capabilities
Data contains booleans, strings, finite numbers, string-keyed tables and dense lists. Cycles, functions in data, mixed-key tables and sparse lists fail. Empty untyped tables mean dictionaries; schema-defined list fields accept an empty list. nil means omission. Integers must be exactly representable.
Handler context fields and arguments are read-only. Configuration handlers may call ctx:add_config and must return normalized options. Detection may inspect permitted source paths and must return a boolean. Execution and preparation handlers use granted filesystem and command capabilities and return no value. A mutated argument, invalid return value or unsupported capability fails with declaration and phase context.
Execution methods include literal-argument ctx:exec, reads and writes within owned paths, output declaration, allocated tool lookup, copying, directory creation and links. ctx:progress(current,total) accepts nonnegative integer units, requires current not to exceed a positive total and uses zero total for unknown progress. These methods delegate to caller-supplied capabilities; the interpreter does not fabricate a filesystem or infer host tools.
Launch-command handler
target.run(ctx) returns { args = { executable, ... }, env = { NAME = "value" } }. args is a nonempty string list; env is an optional string dictionary. Other fields are rejected. The adapter converts this value to a native executor.Command; it never executes the returned command.
The context exposes immutable name, machine, configured options and work. ctx:input("os") accesses the explicitly bound product image. ctx:artifact(dependency, output) accesses a named regular-file result in the declared support closure. Unknown bindings, unavailable results and tree outputs fail. ctx:path(ctx.work, relative) can describe a scratch path. There is no ctx:exec, configuration, source inspection, output declaration or filesystem mutation capability in this handler.
The caller controls input preparation, process execution, terminal streams and directory lifetime. The first argument names an already available executable; it is not a software dependency or an installation request. Launch behavior is optional and is not evaluated by listing, planning or image-only construction.
Current limits and examples
Only the registrations listed above are implemented. Source-built toolchain registration, discovery callbacks, remote module collections, general input-slot execution and packing are not implemented simply because a future example describes them. Accepted fields can carry data for a later stage without implementing all proposed behavior.
Worked examples preserve design examples and state their assumptions. They are informative; the accepted-field table and actual capability checks determine current support.