Skip to main content
After this guide, a workflow runs on a cron cadence with a fixed input, a goal runs it repeatedly until a judge says the objective is met, and you know what the agent may do with workflows from chat. A schedule is the workflow’s own cadence job and every fire is a recorded run; for a background function with no run record, use a job. The 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), with concurrencyPolicy: '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.
The reply is ✅ 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, --max-runs is used up, or you close it.
The reply is ✅ 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. 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 with consent_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:
Only assigned steps are listed and they are numbered among themselves, so a tool step and a step left on the agent’s model do not appear. Under the threshold the block is headed 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 a seat_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

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.
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.
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.