Developer docs Guides
Tasks & scheduling
The task lifecycle: execution modes, phases and progress, approval gates, dependencies, retries, and cron-scheduled runs.
Lifecycle
Every run is a task instance moving through a fixed set of statuses. While it runs, phases and progress stream live to the project board:
| Status | Meaning |
|---|---|
| pending | Created, waiting for dispatch — dependencies may still be running |
| running | Dispatched to the project sandbox; phases and progress stream live |
| pending_approval | Parked at an approval gate until a human answers |
| success | Finished; the returned result is stored with the execution log |
| failed | Errored out; error_message carries the failure reason |
Execution modes
A meta-task defines how its runs execute. script mode runs your entry point with a 300-second budget. agent mode hands the run to a bound agent, which works inside the project workspace sandbox and reports through the same phase and progress channel:
| Mode | Runs as | Typical for |
|---|---|---|
| script | Your Python or TypeScript run() in the sandbox | Deterministic work: reports, syncs, orchestration |
| agent | The bound agent in a workspace conversation | Open-ended work: triage, reviews, refactors |
Approval gates
A run parks in pending_approval whenever it needs a human decision. Agent tasks get there through the agent’s own ask_user_question — the question lands in the task conversation, and your reply becomes the agent’s next turn. Script tasks get there through sub-tasks: when a created task gates, answer it with feedback():
def on_feedback(task):
feedback(task["id"], "Looks good — deploy to staging instead.")
result = wait_task(tid, on_feedback=on_feedback)Dependencies
A task can declare dependencies on other tasks in the same project. Dependents stay pending until every upstream succeeds, then dispatch automatically. A failed upstream keeps dependents parked — retry the upstream, or remove the dependency edge.
Retries and failure
- Dispatch hiccups are retried automatically (up to 5 attempts) before a run is marked failed
- A failed run keeps its
error_message; retry it from the board and progress restarts clean - Quota and configuration problems fail fast, with the reason on the task record
Scheduled runs
Crons run a meta-task on a schedule. A cron binds a meta-task, a cron expression, and fixed params; the scheduler polls due jobs every few seconds and dispatches each run as a normal task instance on the board:
| Field | Purpose |
|---|---|
| Task type | The meta-task to run |
| Cron expression | Standard five-field cron syntax |
| Params | Fixed params merged into every run |
| Enabled | Pause the schedule without deleting it |
Git-integrated runs
When the task’s workspace is bound to a GitLab repository, each run is isolated on its own branch (task-{id}): the platform checks out a worktree, the task does its work, and on success the branch is pushed and a merge request is opened — the MR URL lands on the task record.