Tasks

The definition of a repeatable job: its goal, its limits, the tools it may use, and what happens next. A task never runs; a run does.

A task is a definition

A task is a repeatable job description: what the job is for, how to do it, what it may touch, and what happens after it. Creating one does no work. Work happens in a run, and a run starts from a person, a schedule, a webhook, or the task before it in a handoff.

Create one on Tasks → Create task, or over the API. Create a task when a capability is missing, not for one piece of work: "triage an issue" is a task, and "fix issue 42" is a run of one.

Anatomy

Most of a task lives in its version, which is fixed once saved:

Part What it is
Goal One sentence of what the task is for. The model reads it on every run, and self-improvement aims at it.
Success metric How you would know it is working, one line per metric. Free text today.
Guardrails Rules the model must not break, one per line: "never email a customer", "escalate if unsure". They are instructions to the model. What actually stops a call is a tool scope or a gate.
Skill The SKILL.md: how to do the job, step by step, in plain language.
Tools Every tool a run may call, and nothing else. A tool can be narrowed to some values of its fields. See Gates and tool scopes.
Inputs The fields a run starts with: each has a key, a label, a type (string or number), and optionally a default and whether it is required.
Gates The tool calls that wait for your approval before they happen.
Spend A budget per run, and which model runs it: an exact model, or a highest model tier. See Spend and models.
Workspace For a task that works in a repository: the branch it works on and which files it may write. See Workspaces.
Successors The tasks that run after it, and on which outcome. See Handoffs.

Some things belong to the task itself rather than to a version, so the version history does not record them:

Part What it is
Name and slug The slug is unique in your enterprise. Successors, webhooks and the API find the task by it, so choose it deliberately.
Team The team the task belongs to.
Who runs it A role. Each run goes to a member who holds that role on the task's team and is free, the one who has waited longest first. A role with no team is enterprise-wide. A task cannot be given to one member. See Roles.
Runs at once Its lanes, if it declares any. See Runs at once.
Status active, or deprecated: a deprecated task starts no new runs. Start, the API and its webhook refuse it, its schedule stops firing, and runs waiting to start are closed. Runs already under way finish.
Schedule Its cadence, if it has one. Changing it publishes no new version. See Schedules and webhooks.

A task's page in the portal also shows its runs, its triggers, and any self-improvement recommendations waiting on it.

What a task can call

A run can call only the tools its task lists, by exact name, and nothing else. They come in two kinds:

  • Built-in tools, which the OS answers itself: os.*, workspace.*, memory.*, web.*, and the actions of a browser. The built-in tools reference is the exact list, with what each takes, whether it writes, and which can wait at a gate.
  • Vendor tools, from the systems your enterprise connects: GitHub, Slack and the rest. The Tools directory lists each system, and how to connect it.

How to narrow a tool to some values, and which calls wait for you, is in Gates and tool scopes.

Runs at once

A task runs one run at a time unless it says how its work splits. Declare the input keys that split it, its lanes, with serializeOn (Tasks API): a task that works one issue of one repository at a time might declare ["repo", "issue"]. Then runs on different issues run at once, and two runs on the same issue never do: the second waits, or is skipped, as it would for a task with one lane.

  • A lane is the values of those inputs, trimmed and in lower case, so Acme/Web and acme/web are the same lane.
  • A member still does one run at a time. Lanes run side by side only when enough members hold the task's role.
  • Keys are yours to choose: a repository, a campaign, a region. The OS never reads meaning into them.

Versions

Every save publishes a new version, numbered from 1. A version is never changed after it is saved.

  • A run keeps the version it started on. Saving a new version while a run is under way changes nothing for that run; the next run uses the new one. A run waiting as pending takes whichever version is current when it starts.
  • Version history on the task shows every version as it was, read-only, and the runs that used it.
  • Going back to an earlier definition means opening that version and saving its content as a new version. There is no one-click restore.

Editing safely

Edit on a task opens its current version; Save as new version publishes your changes as the next one.

If someone (a person, or a self-improvement change you approved) published a newer version while you were editing, your save is refused rather than putting the older definition back over theirs. Copy what you want to keep, then Cancel edit to load the newer version and make your change on top of it. Over the API, the same protection is baseVersionId: send the version you read, and a save made after someone else's is refused with a 409.

Checks when you save

A version that could never run is refused, and one with a likely mistake is saved with a warning:

Code Refused or warned Why
gate_required_for_tool Refused The task can merge a pull request or send a new mail but declares no gate on it, or it can write a plan (a team, role, member, task or spend change) but declares no CEO gate on asking the CEO.
gate_summary_tool_required Refused The task can merge but cannot write the summary the merge gate needs.
deterministic_with_tools Refused A task that runs no model (deterministic) lists tools it could never call.
successor_when_unknown Refused A successor's when is not one the OS knows.
successor_cap_invalid Refused A successor's loop cap is not a whole number of at least 1.
successor_delay_invalid Refused A successor's delay is not more than 0 and at most 1440 minutes.
unconditional_loop Refused Successors on terminal loop back to the task, so it would never stop.
successor_unknown_slug Warned A successor names a task your enterprise does not have.
successor_on_unknown Warned A successor waits on an outcome the OS does not know, usually a typo.

Warnings show on the task, and on Blockers under Task definitions, until they are fixed.

Inputs

A task's inputs are what a run starts with. Start a run on the task's page shows them as a form, filled with their defaults, and will not start while a required one is empty. The same keys are what a schedule, a webhook body, or the task before it provide.

However a run starts, an input it leaves out or blank takes its default, and a required input with no value and no default refuses the start with input_required naming it: a schedule's firing, a webhook, the API and chat alike. The one exception is a run the task before it starts: its input is whatever that run handed on. Keys the task does not declare pass through to the run as sent.

Clone and copy

Community → Catalog lists the tasks you can take into your enterprise, in two ways:

Clone Copy
What you get Your own installation of the original, linked to it A new, independent task
Who owns the definition The original's owner You
Can you edit it No: Edit is disabled, and self-improvement does not run on it Yes
Starts on The original's current version Version 1, with the original's definition
Later versions A newer version of the original is offered on the clone's page; Update takes it, and nothing moves your clone until you do None: it is yours from here
You choose Its team Its name, slug, team and role

A clone keeps the original's role, and a copy keeps it unless you choose another. Either runs only once someone on its team holds that role.

Either way, you can run it, schedule it and delete it. Neither brings a schedule, run history, credentials or memory: you connect your own tools, and a clone may not write memory above its own task. Successors that pointed at the original point at your copy; other successors look for tasks with the same slugs in your enterprise.

Copy also works on your own tasks, from the task's page, to start a variant without touching the original.

The OS's own tasks are part of the product, not of the catalog: the same in every enterprise, and changed only with a release of the OS. They cannot be cloned or copied, and nobody can edit, reschedule or delete one. You can still start them. See Enterprise.

Deleting a task

Delete on a task removes its definition and every version of it. Runs that already happened are kept.

Over the API

With an API token scoped tasks:read (and tasks:write to change them):

Call What it does
POST /v1/tasks Create a task, with its first version.
GET /v1/tasks/{id} The task, its current version and skill, its version list, and its definition warnings.
POST /v1/tasks/{id}/versions Save a new version. Send baseVersionId.
POST /v1/tasks/{id}/copy Copy it, with a new name, slug and team, and optionally a new role.
PUT /v1/tasks/{id}/schedule Set its schedule.
POST /v1/tasks/{id}/runs Start a run.

See Tasks over the API for the full shape of a task.