# ESP32 Lua API Guidelines This is a clean contract for repositories under the same owner's control. Choose the best shared API without preserving old names, signatures, or behavior; consumers migrate to the contract. Every firmware implements all declarations under `lua/api/core/`. Optional hardware contracts live under `lua/api/features/`, as one file or one directory per feature; `sys.hasFeature(name)` guarantees the complete matching contract. Every namespace belongs to exactly one feature or to core, so a feature is a provider pointer rather than a claim to validate: a panel is the `screen` feature (`screen` and `tree`, including the saved rotation and theme), registered only when the firmware supplies a `GuiProvider`, and calibration is `touch.setCalibration()`. A global namespace is a provider contract a firmware implements; anything this library provides itself is a module instead, so `require` and globals divide by who supplies the code. Those live in `native/src/bindings/lib/` and register into `package.preload`, which puts them ahead of the SD-card searcher so nothing shadows an implementation. Pure-Lua modules stay in `lua/lib/`, where shadowing is allowed because a module there is self-contained: it belongs in `lua/lib/` only if replacing it can break nothing but itself. Lua-language sources stay under `lua/`; C/C++ and the vendored interpreter stay under `native/`. Apps are fully trusted; keep permissions and sandboxing out of scope. Firmware commits dirty display content and owns panel refresh policy. Binding annotations under `native/src/bindings/` generate matching `lua/api/` files; regenerate instead of editing files marked generated. Callbacks are fields on the table an app returns, so a `@lua-app` block generates a class an app composes (`---@class PaintApp : App, TouchHandlers`) rather than global functions. Each `@lua-module`/`@lua-augment` directive sits immediately above the `luaL_Reg` table it describes, which is how one source declares several namespaces. This repository owns portable `lua/lib/` modules; shared UI owns theme application and persistence. Use `ble` for BLE/GATT and reserve `bt` for a future Classic Bluetooth contract.