toryo docs
Documentation navigation

Sequence

Multi-step work as one observable run. A sequence is a predefined pipeline of steps with typed inputs and outputs, where each step's output feeds the next. A run can move forward, loop back to an earlier step, and pause for you.

Sequence sits above dispatch the way a conductor sits above the orchestra: it coordinates execution. Steps that need an agent fan out into dispatch as ordinary jobs, and so does slow acceptance work.

This is what a /toryo-code invocation actually starts.

The six kinds of step#

KindWhat happens
workeran agent session runs, through dispatch
completionone model call that must return JSON matching a shape you declared
transforma pure function reshapes the previous step's output
setupin-process work with side effects, such as minting a git worktree, copying files into place, or running a command
humanthe run pauses and waits for you
acceptancethe plan's acceptance commands run on the host as a dispatch job with no model, and their exit codes become evidence

A worker step is the expensive one: a whole agent session, with tools and a repository. A completion step is the cheap one for the times you only need the model to decide something ("grade this", "rank these") and hand back structured data a later step can branch on. Completion is an authoring convenience compiled into a worker step.

A human step is the gate. The run parks, board raises an OS notification, and nothing proceeds until you acknowledge it, whether by approving, rejecting, or sending the work back with written feedback. A gate can also present the agent's own questions as pickable options, so the planner can ask you which of two approaches to take and get a real answer rather than guessing.

A worker can also ask a bounded question while it is live. That is distinct from a human step designed into the YAML: the current session pauses for the operator's answer, then continues in place. Unanswered questions use the declared fallback or park the step, depending on how the worker asked. A sandbox or policy denial sends the worker looking for an allowed route first. If none works, it records the denial as evidence and continues independent work. It asks you only for what you can grant: a credential, account or service access, host setup, or an indispensable decision it cannot make.

The shipped sequences#

Three, and they are how we work rather than how you have to:

  • code-task, the full engineering lifecycle, and the one you will use most. Idea-backed runs first verify that the complete premise still exists on the current base. Survivors continue through plan → you approve the plan → install an isolated worktree with the project's own install command → implement and open a regular pull request (never a draft) → local verification → self-review → review gates → formal review → readiness → you approve the merge → verify the merge → record what was learned. The plan gate lists the acceptance commands and says when no install command is available. The run reads its per-project settings at creation. Any worker role you leave out of providers runs on claude. It is a file rather than something compiled into toryo: toryo setup offers to install it, toryo sequence install-shipped adds it later, and you can read, edit or fork it like any sequence you wrote yourself. Declining the offer is fine, you get an empty catalog and everything else still works.

  • review-task, which grades a whole codebase and produces a report, optionally published into the library. A file too, installed by the same offer as code-task, and yours to read, edit or fork once it is there.

  • research-task, which researches a topic or URL into a library finding, behind an approval gate. A file too, installed by the same offer as code-task, and yours to read, edit or fork once it is there.

A fourth, ideas-verify, ships as well but belongs to the system rather than to you: it re-checks filed ideas against the code as it stands now so the ones already solved get closed instead of read again. toryo sequence list leaves it out unless you pass --include-system, and it is described on Ideas as the behavior it is.

How code is judged#

code-task gives self-review and formal review different jobs, but both judge against the same review-criteria library document. Each review chain fetches that rubric explicitly and stops closed if it is missing or blank, rather than silently grading without the shared standard. Self-review examines the implementation before handoff. Formal review independently grades the result and decides whether blocking findings send it back through implementation.

Self-review never edits the branch. Blocking findings go back to implementation; notes carry on to formal review, even when the letter grade is B. After three retries leave blocking findings open, the run parks at Self-review left blocking findings open. You can choose Re-run implementation, Send to formal review, or Keep paused. These retries do not spend the formal-review attempt budget.

The rubric is only one input. The worker's role orientation defines reviewer behavior, while the resolved directive stack adds layered rules, from the shared library through your own standing rules to the repository's and nested directories' rules. Those directives can specialize or tighten the work expected in this repository, but they do not silently replace the rubric fetched into the review prompt. See How directives affect review for precedence and provider delivery.

Local acceptance#

Approving the plan is consent: the plan gate lists every acceptance command, and they run in the run's worktree with the operator's permissions. Argv prevents shell interpolation; it does not sandbox branch code. Each acceptance step runs the commands as an ordinary dispatch job with no model, using your login-shell PATH to find your installed tools. The exit codes are graded into evidence the reviewer and the fix loop read. A missing tool or a timeout is evidence too, not a gate, and nothing needs a separate service or approval renewal.

Commands receive an allowlisted environment, not your whole shell environment. PATH, HOME, locale, toolchain-manager variables (asdf, mise, nvm, volta, pyenv, rbenv, nodenv, rustup/cargo, Java, Go, Bun, SDKMAN and virtualenv), proxy variables and SSH_AUTH_SOCK pass through. Credentials such as API keys, GH_TOKEN and toryo's database URL do not, including credential-like names inside those toolchain families. A command that needs another variable needs a change to toryo itself; there is no per-project override.

The planner declares targeted commands only. The run adds the project's full test command according to its full-suite policy:

  • never runs only targeted commands locally.
  • before-review, the default, adds the suite at the review gates before formal review.
  • every-verify adds it at local verification, the review gates, and after a base refresh.
  • ci never runs it locally. Readiness requires the named forge check to have reported and passed for the reviewed head. Without a configured check name, readiness withholds rather than assuming the suite ran.

Set the policy on Projects. ci avoids oversubscribing the host with concurrent runs of the same full suite. The review gates reuse a passing result already recorded in the same run at the same head, with a clean tracked tree and the same command list. The reviewer reads exit codes the sequence produced, rather than the implementer's account of them.

When every failing command reproduces the same failures at the merge-base, the run does not send an implementer to fix the base. It parks at The base branch is red; every failing test here also fails at its merge-base, with Recheck to run again once the base is fixed and the branch updated, or Proceed with the base failure noted. A base-branch-red warning records that the base branch is red.

Readiness and the merge gate#

Readiness requires acceptance evidence at the reviewed head, a clean tracked tree, closed blocking reviews, and a positive answer from GitHub's checks: every reported check passed, or GitHub reports no checks. Under ci, no checks is not enough: the configured full-suite check must have passed.

An unfinished check is waited on for up to an hour. An unreadable check rollup gets ten minutes; a full-suite check not yet registered on a just-pushed head gets five. A spent wait parks and names what never answered. A red check sends the run back to implement with the failing job and step and an excerpt of its log. That spends an implement attempt, just like a reviewer's send-back.

Other readiness problems park at Readiness withheld, which offers the actions that apply to the problem:

  • Recheck asks again without changing the branch.
  • Mark ready and recheck handles a draft somebody else made.
  • Re-run acceptance runs the reviewed commands at the reviewed head without an implement pass. A moved head or tracked edit refuses that re-run.
  • Re-verify at the new head handles a pull request whose head moved.
  • Bring the branch up to date and re-verify handles a moved base.
  • Grant one more implement attempt extends a spent budget.
  • Send back for changes requests another implement pass while attempts remain.
  • Finish by hand and close the run records your manual completion.
  • Cancel the run ends it as cancelled.

At the merge gate, I merged it is checked against GitHub's repository, pull request number, base and head before the run finalizes. A pull request already merged at the reviewed head into the run's base skips that gate and goes straight to merge verification.

An implementer that stops short must say so. Remaining implementation gets up to two repair passes per reviewed diff; an operator-resolvable blocker parks at Operator intervention required before implementation can finish.

How workers run#

Claude workers skip your user-scope Claude Code configuration: ~/.claude/settings.json, ~/.claude/CLAUDE.md, ~/.claude/rules, and user or claude.ai MCP servers. The target repository's .claude/ settings and .mcp.json still apply. A sequence can set reasoning effort per provider; see Sequence authoring.

Each claude session allows at most maxSubagents concurrent subagents, set through toryo-worker settings. The default is 3; 0 means no limit. A job can override the setting. The agents a claude Workflow starts count toward that limit, though a workflow started beside running subagents can exceed it.

Writing your own#

The three are defaults, not doctrine. Plenty of people run them as they are and never write one, which is a fine way to use toryo. When your process differs, write yours down instead.

A sequence is a YAML file, either global in ~/.toryo/sequences/ or scoped to a repository under .toryo/sequences/. There is no plugin to register and nothing compiled into toryo: the engine reads your file and runs it exactly as it runs the shipped ones. A project file wins when it shares a name with a global file.

What you are writing down is your own process. The steps, what each hands the next, which of them run an agent, and where the run should stop and ask a person. The things a team argues about in review, or that a senior engineer does from memory, become something that runs the same way every time.

Because it is a file in your repository, it travels the way the rest of your code does: reviewed in a pull request, versioned, forked by another team, and handed to a new hire as a working definition of how you build rather than a wiki page about it.

There are four ways to make one, and only one of them involves typing YAML. See Writing your own sequences. github.com/ForceBuilders/toryo-pr-example is a complete one to read.

Share sequences with your team#

A team's sequences are files in the team project's repository, under .toryo/sequences/. They are reviewed and versioned like the code. There is no separate catalog on the team's server.

Clone a team project and set it up on your machine, and its sequences are available in it. They appear only in that team's projects. Your own projects and other teams never see them, so a customer's sequence stays with the customer.

Shipped sequences and your personal ones in ~/.toryo/sequences/ work in every project. A run belongs to the project it runs in.

toryo sequence list --all-projects lists one set of projects at a time: your own, or one team's. Run it from inside a checkout of a team project to see that team's. Anywhere else it lists your own. It never mixes the two.

What makes a run recoverable#

Runs are durable. The daemon can restart mid-run and pick up where it left off, and a few behaviors are worth knowing:

  • Work happens in an isolated git worktree, not your checkout, so your working tree stays clean while a task runs. On success it is cleaned up; on failure it is kept so you can inspect it.
  • Cycles are bounded. Self-review sends blocking findings back to implement; a reviewer that requests changes sends the run back to implement, but only when it flags something genuinely blocking, and only a capped number of times.
  • A moved base branch is handled. If another PR merges underneath a run and the branch no longer merges cleanly, the run goes back and merges the new base in rather than failing. Just before implementation starts, dispatch also tries to fast-forward the worktree onto the base. This is best-effort and never rewrites the branch's own commits.
  • API errors retry themselves with backoff before the run is failed.
  • A step failing the same way repeatedly escalates to you. After escalateAfterN identical failures (default 3, in toryo sequence settings), the run parks paused. Release it with retry --force, as in toryo sequence retry <id> --force, or board's Retry (force) panel. resume refuses an escalated run.
  • retry re-arms a stuck run in place, keeping its worktree, PR, plan, and history, which cancelling and starting over would throw away.
  • Cancelling a run also requests cancellation of its remaining dispatch jobs, reporting each result, including any job it could not cancel.

Before a queued or dependency-blocked run starts, update can correct its input, dependencies, working directory, branch, or base without creating a new run. Once execution starts, that graph and input are pinned. If an editable sequence file needs repair, a guarded re-pin compares the run's recorded steps with the new graph. It admits failed, paused and cancelled runs, so cancel, re-pin, retry can recover a run. It asks for --force when the edit changes a step the run already ran, and still refuses incompatible history or successful output. Re-pin does not resume the run; retry or acknowledgement is the separate action that moves it again.

Archive is history management for terminal runs. It hides a handled success, failure, cancellation, or crash from normal run lists without retrying it or deleting its record. Unarchive restores it to those views.

Chaining runs#

A run can declare that it depends on others. It stays blocked, never reaching dispatch and never minting a worktree, until every prerequisite has succeeded. For a coding task, "succeeded" means the PR was merged, so a dependent run picks up its predecessor's changes with no branch plumbing.

Use it when one task must build on what another produces, instead of letting two runs invent the same helper twice.

Where things go wrong#

  • A step sits awaiting-human. It is waiting on you, in board's Sequence screen or the inbox notification.
  • A run sits blocked. A dependency has not succeeded yet.
  • A run sits paused. A gate is waiting on you, or a step escalated after repeated identical failures.
  • A run carries warnings. Board's run detail and toryo sequence run output show when install or verification settings could not be read, sensitive paths could not be read or the sequence does not take them, or the base branch is red.
  • A pull request check turns red. Readiness sends it back to implement automatically, carrying the failed check's output.
  • A run failed but the work looks salvageable. Use retry rather than starting over; the run's accumulated work is worth keeping.
  • The sequence file was fixed after an early failure. Re-pin the failed run, then retry it. Inspect any request for --force; a structurally incompatible graph still needs a new run.
  • A terminal run is only clutter. Archive it. Archive is not recovery; retry is.

Full command surface: CLI & contract reference.