- A project that compiles (
lua compile --ciexits 0) and passes Test an agent before you release. - A credential for the agent, and its ID in
lua.skill.yaml.
1
Lock down credentials
- CI authenticates with a scoped API key stored as a CI secret and read from
LUA_API_KEY; nobody’s personal user session runs the release. - No key or secret appears in code: tools read
env('KEY'), and each value is stored withlua env production -k <KEY> -v <value>(Call your API). .envis listed in.gitignore(the scaffold’s.gitignoreholds onlydist-v2/; copy.npmignoreover it) and holds values for locallua testruns only.
2
Pin the agent configuration
src/index.tsnames amodel(or a model resolver). Pushing aLuaAgentwith neither clears the server’s model, including one chosen in the admin dashboard; pick a code fromlua models list --json --ci(About models).- The persona has been reviewed in the sandbox with
lua persona sandbox view.
3
Lock down controls
- Governance is pushed:
src/governance.tsnames the tools that never run (rules.blockTools), the ones a person confirms (rules.requireToolApproval), and aninjectionthreshold;lua push agentapplies it at once. lua sync --checkexits 0: no drift in name, persona, model, or governance between your checkout and the server.lua auth sessionslists only devices you recognize;lua auth sessions revoke <id>signs out any other.- The CI key holds
agents:read,agents:write,automations:read, andautomations:write, plusworkflows:readandworkflows:writeonly when it pushes workflows, and noknowledge:*oragents:manage(Automate releases in CI). - Telemetry is decided:
lua telemetry offon any machine that must send nothing.
4
Check knowledge, features, and channels
- Knowledge documents are uploaded and
lua resources listshows them; Knowledge Search is on withlua features enable --feature-name rag(Add knowledge). lua features listshows only the features you want; Web Search is on by default for agents created in the admin dashboard.lua channels listshows every channel end users will use, and you have sent one message on each (quick testing tries a channel before you connect your own number or page).- Outbound sends outside WhatsApp’s 24-hour window use an approved WhatsApp message template (Send proactive messages).
5
Verify webhooks, jobs, workflows, and MCP servers
- Every webhook sets
secretas a string literal, so calls without a validx-lua-signature: sha256=<hex>are refused; vendors with their own signature scheme are verified insideexecute. Test againsthttps://webhook.heylua.ai/<agent-id>/<webhook-name>(Handle a webhook). - Every job sets
timeout(1 to 600 seconds, default 300) andretry: { maxAttempts, backoffSeconds }, andlua test job --name <name>ran clean (Schedule a job). - Every workflow was pushed on its own, because
lua push allskips workflows, andlua test workflow --name <name>covered both sides of each predicate and each approval (Test a workflow offline). lua mcp listshows each MCP server you rely on as active.
6
Rehearse the release and the rollback
- The numbers on Limits hold for your traffic, and
lua logs --type agent_error --limit 5 --jsonreturns an emptylogsarray in the sandbox (Read logs and debug an agent). lua status --json --cishows no primitive asbehindand no orphan withcritical: true.- The candidate is a staged agent version, diffed against the active one and previewed in production.
- The rollback is
lua version promote <previous>, the same command as the release and immediate; it restores every code primitive version and the model and touches nothing else: not the persona (lua deploy persona --set-version <n> --force), environment variables, knowledge, features, channels, MCP activation, governance and model settings, devices, data the bad version wrote, or runs in flight (what a version snapshots). - If you release through the Claude Code plugin, it blocks production commands until you confirm once;
--auto-deployis never used (Claude Code plugin).
7
Verify
Confirm the active marker moved, send one production message on a fresh thread, and check for agent errors.The
Output
* marks the active version. An empty logs array is the pass condition; otherwise roll back with lua version promote <previous> and read the entries.If it isn’t working
Model configuration cleared appears in the push output
Model configuration cleared appears in the push output
src/index.ts has no model and no resolver, so the push sent null and the agent fell back to the platform default. Add model: '<code>', push again, and create a new version.A webhook answers 401 Invalid webhook signature to the vendor
A webhook answers 401 Invalid webhook signature to the vendor
The vendor doesn’t send
x-lua-signature; it signs with its own header. Remove secret from that webhook, verify the vendor’s header inside execute, then push and deploy the webhook.lua status --json shows a primitive as behind
lua status --json shows a primitive as behind
The server has a newer version than your checkout. Run
lua sync --pull, review the changes, and restart the checklist from the push.Next steps
Release an agent to production
Push, snapshot, promote, verify, and roll back.
Automate releases in CI
The same commands behind a GitHub approval gate.
Limits
Timeouts, sizes, and quotas in one place.
About releases and versions
What a version snapshots and what it doesn’t.

