Work

Everything Optio runs is work: a one-shot PR task, a nightly report, an automation that wakes when someone requests your review on GitHub, a Claude Code terminal on your laptop that you can pick up from your phone, or a long-lived agent that other agents message. They differ only in five attributes, so one form creates any of them and one list shows them all.

The five attributes

When

What starts it?
  • Now
  • A cron schedule
  • A webhook (POST /api/hooks/<path>)
  • A ticket — GitHub Issues, GitLab Issues, Linear, Jira, Notion
  • A GitHub, Slack, or Linear event — in a pod or on your machine
  • A message from a person or another agent (persistent agents)

Where

Where does it run?
  • An Optio pod in your cluster with one of your registered repos checked out
  • An Optio pod with no repo
  • A directory on your own machine, as it is (Optio Local)
  • A new branch in a checkout on your machine that becomes a PR
  • Environment (pod work) — connections, MCP servers, and skills start from the repo's and the workspace's; the work adds or removes them, picks the secrets its pod gets, can add setup commands, and, when it opens a PR, sets its own code review, draft PRs, and auto-resume cap. Work on a machine uses the machine's own CLI config

Who

What does the work?
  • A terminal with no agent — a shell you open, or a command that runs and exits
  • Claude Code, OpenAI Codex, GitHub Copilot, Google Gemini, Cursor, OpenCode, or OpenClaw (Copilot and OpenClaw run in pods only)
  • …with the model and provider options you choose

What

What is it asked to do?
  • A prompt, or a saved prompt template from the Library — or, for a command, the command
  • {{param}} substitution and {{#if param}} blocks filled from the trigger payload (shell-quoted in a command)

Then

What happens after a turn?
  • Exits when done — opens a PR or produces side effects, then stops
  • Works until merged — opens a PR and keeps working on it through CI and review until it merges (or keeps it green until you merge it)
  • Waits for you — an interactive session that halts at the agent's prompt between turns
  • Persistent agent — keeps memory, wakes on messages, addressable by other agents

Plus a name (or "Job N", "Terminal N" for its kind). The New work form at /work/new asks these in order, each answer narrowing the next — following a PR to merge needs an agent and a repo, a pod terminal is opened by hand, a persistent agent lives in a pod — and reads the draft back as a sentence whose gaps double as validation:

Started by Linear events, a Claude Code run on my laptop on a new branch in ~/src/app that opens a PR and exits when done.

Running weekdays at 09:00 UTC, an OpenAI Codex run in an Optio pod that exits when done.

Started by GitHub tickets, a Claude Code run in an Optio pod with acme/web that opens a PR and keeps working on it until it merges.

Woken by messages, a Claude Code agent in an Optio pod that keeps its memory between turns.

Presets

Open a PR, Assign to Optio, Interactive chat, Terminal, Scheduled run, and Persistent agent seed the common shapes. Any combination of the five attributes is reachable from there.

What each combination becomes

The kind of row a piece of work becomes is a pure function of its attributes. Each kind keeps the pipeline it always had; the work model only changes where you create it and where you see it.

AttributesKindWhat runs
Repo, exits or works until mergedTaskWorktree in a repo pod (or a new branch on your machine) → agent → PR → CI → review → merge
Repo, with a triggerScheduled TaskA saved definition; each firing spawns a fresh Task
No repo, exits when doneJobAn agent or a command, on a pooled Job pod or your machine; add a trigger to make it recurring
Your machine, waits for you, with a triggerLocal automationA terminal or agent session opened in your directory on a schedule, webhook, ticket, or event
Your machine, waits for youLocal terminalAn interactive terminal or agent on a paired machine
Pod + repo, waits for youPod sessionAn interactive terminal + agent chat inside a repo pod
Persistent agentAgentLong-lived, named, message-driven, in a pod with a repo or none; inbox, turns, inter-agent API

Tasks follow the task lifecycle with its autonomous feedback loop. Jobs and scheduled Tasks are covered in Standalone Tasks and Scheduled Tasks. Persistent agents and Optio Local are documented in the repository under docs/.

The Work list

/work merges every kind into one list with four views — Active, Recurring (definitions that spawn runs), Agents, and History — plus All, sorted needs-you first, then live, then by recency. Every row carries the same status scale:

StatusMeaning
needs youAn interactive session is waiting for input
runningAn agent is working, or a pod is provisioning
queuedWaiting for capacity
waitingOpen but idle — a PR waiting on CI or review, an agent between turns
scheduledA recurring definition with an enabled trigger
pausedTriggers disabled, or a paused agent
doneCompleted, merged, or exited cleanly
failedFailed, cancelled, closed without merge, or the pod / terminal died

The Overview's board and the Work tab in the iOS and Android apps (with widgets, a Live Activity on iPhone, and an ongoing notification on Android) show the same rows and statuses.

Swarms

Work whose Then is persistent agent keeps its memory between turns and wakes on messages. Agents in a workspace can list, message, and broadcast to each other over an inter-agent HTTP API, which is what turns a set of agents into a swarm: a dispatcher that fans work out to specialists, a reviewer that closes the loop, all with per-agent pod lifecycle (always-on, sticky, on-demand). Their turns land in the same feed, cost ledger, and Overview as everything else.

Under the hood

The kinds map onto existing tables and services (tasks for every Task and Job run, work_definitions for scheduled Tasks, Jobs, and Local automations, local_terminals, interactive_sessions, persistent_agents). The web creates and lists every kind through /api/work; the polymorphic /api/tasks resource and the per-kind endpoints the mobile apps and the CLI use still serve them. See docs/tasks.md in the repository for the mapping and the API surface.