lua workflows policy autonomy verbs on this page require lua-cli 3.36.0 or later.
Before you begin
- A workflow pushed and deployed (
lua workflows deploy <name> -v latest), withconcurrencyPolicy: 'forbid'if two fires must never overlap. - A user session (
lua auth configure).
1
Create a schedule from the CLI
schedules create attaches a cadence to the workflow, or replaces the one it has. Each fire starts a run with the --input you give.✅ schedule <jobId> on "lead-outreach" · cron 0 9 * * 1-5 (Europe/London) · next <time>. --cadence repeats up to 5 times; --every 15m is the interval form (whole minutes). --notify emailApp|email|app|off chooses where each fire notifies, -v pins the version each fire runs, and --backfill-on-enable <n> replays up to n missed fires on re-enable. schedules pause <jobId>, resume <jobId> [--backfill-now], patch <jobId> --paused true|false, and delete <jobId> --yes manage it.2
Declare the schedule in code
A schedule in the definition deploys with the workflow and is activated with
lua workflows activate <name>.src/workflows/weekly-digest.ts
schedule takes the same shape as a LuaJob schedule; scheduleInput must satisfy inputSchema, or lua compile warns schedule-input-required or schedule-input-invalid. deactivate pauses the schedule without touching the live version.3
Create a goal
A goal runs the workflow on a cadence until a judge says the objective is met, The reply is
--max-runs is used up, or you close it.✅ goal <goalId> created on "lead-outreach" · active · runs 0/10 · cron 0 9 * * 1-5 (Europe/London) · schedule <jobId>. A predicate judge is deterministic: '<path> <op> [value]', with path under output., state., or steps.<stepId>., or one of iteration and runStatus, and op one of eq, neq, gt, gte, lt, lte, exists, truthy. An agent judge is --judge-agent <agentId|'$self'> with --schema @schema.json, a JSON Schema whose root declares a boolean done; a '$self' judge also needs --judge-role @role.json ({ name, instructions, tools }). --max-runs is 1 to 100, --max-total-credits caps credits across every run of the goal, and without --cadence the judge runs right after each run. From code, Workflows.setGoal takes the same fields; the Workflows reference says what the deployed runtime accepts.An agent judge’s turn is a judge task, which the class map sends to balanced unless your organization maps it elsewhere or caps the class lower, for goals created after model assignment reached the platform (a fixed date per environment), and only while assignment is on for your organization. A goal created before that keeps the judging agent’s own model for the life of the goal, so turning assignment on never re-prices a goal already running.4
Steer a goal
Read and change a goal by id; never delete its schedule.A goal is
active, paused, done, or closed; a paused goal carries a pauseReason of user, budget, max_runs, or strikes (three consecutive failed iterations). pause skips fires, resume does not replay missed ones, raise lifts --max-runs or --max-credits and re-arms a goal parked at its cap, and close is final. A goal’s cadence is a schedule tagged with the goal id; schedules pause, resume, patch, and delete refuse it with goal_schedule, because the schedule follows the goal.5
Verify
view lists a workflow’s schedules and goals beside its versions.Output
schedules list -i lead-outreach and goals list lead-outreach print the full tables, and every fire appears in lua workflows runs --workflow lead-outreach with Trigger schedule.Options you may need
What the agent can do from chat
An agent that has workflows turned on gets tools for them in conversation: it starts, inspects, resumes, signals, repairs, and cancels runs (startWorkflowRun, getWorkflowRun, and their siblings; cancelWorkflowRun unless the organization turns it off), edits a workflow’s one schedule in place (scheduleWorkflow, unscheduleWorkflow), runs goals (setWorkflowGoal and the goal lifecycle verbs), and, unless composition is turned off, composes new workflows with composeWorkflow. A request that needs steps to run unattended, wait for a person, or recur becomes a composed workflow the agent starts only after presenting the plan and estimate, always with an idempotency key.
Consent and caps
A composed workflow whose estimate crosses your organization’s consent thresholds — by default 15 steps, 20 credits, or 3,600 seconds — asks the end user for consent before anything runs, or is refused withconsent_refused where the organization forbids asking. A goal created from chat defaults to 3 runs. A workflow the agent composed is dynamic: lua workflows list --all shows it, deploy refuses it with WORKFLOW_DYNAMIC, and export <name> brings it into source.
An organization that would rather answer once than answer every time pre-consents a bounded envelope instead. A start whose estimate fits inside the envelope is queued immediately with no card; a start that does not fit asks exactly as it does without one. The envelope lives on the organization’s workflow policy under autonomy, and lua workflows policy autonomy get prints the values in force.
Autonomy is opt-in: with
enabled absent or false, every start behaves as it would with no envelope at all. The envelope is set per organization. Where an agent carries a narrowing of its own, the platform applies it — the lower of the two on every number, only the forms both list, and enabled: false on the agent wins — so an agent never gets more room than the organization opened. There is no public way to set a per-agent narrowing yet.
The envelope applies to composed starts the agent makes from its chat tools — a draft it just composed, or a saved workflow it starts by name. A goal’s first iteration and batch starts ask exactly as they do without one in this release.
Inside the envelope, a composed start whose form is listed and whose estimate is within every bound starts on its own. Outside it, anything over a single bound still asks, a script-form start asks unless script is in forms, and the start after the hourly count is reached asks rather than being refused — the count is kept per organization and agent. Three things the envelope never touches: an approval step still waits for the person it names, a run that crosses its budget or billing ceiling mid-flight still parks, and consent_refused stays a refusal — an envelope never overrides an organization that has turned asking off.
The card you see before a composed run starts
When the agent composes a workflow, it shows the plan before anything runs. The plan names each step the composer assigned a model to, the model class it asks for, the model that class resolves to today, the effort, and the one-line reason. When the estimate crosses your organization’s threshold the same block arrives as a consent card, and the run waits for an explicit yes:Model plan instead, carries the same one cost line, and asks for nothing.
Two things about that cost line are worth reading twice. It is a lower bound: what a call actually costs depends on how much context it carries and how many tools it fires, neither of which is known before the run starts. And the multiple is against this agent’s own model rather than a platform baseline, so a figure below 1× means the assignment made the run cheaper than running every step on the agent’s model, and above 1× dearer.
What the budget counts
The run budget is not your organization’s account credits, the balance aseat_required or an out-of-credits refusal talks about. It caps one run, and budget.maxCredits, --budget-credits and raise-budget --credits keep the word credits whatever unit that run counts, because the cap is one number either way. Operate runs says which unit each run counts and what the unit buys.
The card’s figure is always in actions, whichever unit you are billed in. An organization billed in credits gets one more sentence saying so and pointing at lua workflows status and the budget settings for the credits number: the estimate sums the chosen models’ cost multiples and a credit is one per agent step, so the two are different reads and are never shown as one figure.
If it isn’t working
goal_schedule
goal_schedule
The job you tried to change is a goal’s cadence. Use
lua workflows goals pause <goalId> or goals close <goalId>; a done or closed goal’s leftover schedule can then be deleted.GOAL_NOT_ACTIVE
GOAL_NOT_ACTIVE
Only an active goal pauses and only a paused one resumes; a done or closed goal stays closed. A goal paused at its cap re-arms with
goals raise.SCHEDULE_CAP
SCHEDULE_CAP
A schedule takes at most 5 cadence entries. Pass fewer
--cadence flags or combine them into one cron expression.Next steps
lua workflows reference
Every
schedules and goals flag and refusal.Operate runs
Follow, answer, and cancel the runs a schedule or goal starts.
Models
What a model class is and what the card’s class column means.
Workflows runtime API
setGoal and goals.* from code, and what the deployed runtime accepts.Watch schedule health
Get told when a schedule goes silent, keeps failing or is turned off.

