Skip to content

How it works

This page follows a single run from the moment an issue is noticed to the moment the issue is updated. Each phase links to the page that documents it in depth.

A run is created in one of three ways:

  • Manually, from New run / Run (the Start a run dialog). You provide a Task title and optionally an Issue key, Issue URL, Description and per-run overrides for the pipeline’s variables. Without a key, the run gets one like TASK-12.
  • By a polling trigger (Linear, Jira, GitHub). Each trigger polls its tracker at its interval (never more often than every 15 seconds). Every matching issue starts one run. Issues are deduplicated per trigger by key: an issue triggers once, or again after it’s updated if Run again when a processed issue is updated is on (and its previous run has finished). See Linear, Jira, GitHub.
  • By a schedule or webhook trigger. A cron schedule creates a synthetic issue from its task title and description; a webhook creates one from the posted JSON. See Schedule and Webhooks.

Before a manual run is created, the pipeline is validated, and so is its workspace (for example, a Git worktree pipeline with no local repository can’t start). The error appears as Can't start: ….

When a trigger starts a run, its Run starts write-back fires (comment 👋 Jimothy started run #N (…) and/or transition). See Write-back.

At creation the run stores a snapshot of the pipeline definition, merged with its project (workspace, variables, env). Editing the pipeline afterwards doesn’t change a run that’s already queued or running. (Retrying a finished run does pick up the current definition; see Retry.)

The run gets a sequential number (#42) and status Queued. The scheduler starts queued runs in order as long as:

  • fewer than Settings → Max concurrent runs (default 3) runs are active across all pipelines, and
  • the pipeline is below its own Max concurrent runs (0 = no per-pipeline limit).

A queued run whose pipeline is at its limit is skipped, and the next eligible run starts instead.

The run moves to Preparing and fires the run.started event. Jimothy prepares the workspace according to the pipeline’s workspace mode:

Mode (UI label) What happens
Existing folder Uses the folder as-is. No git operations, no isolation.
Git worktree git fetch origin <base> in your clone, then git worktree add -b <branch> <dir> origin/<base> (or the local base branch if there’s no remote).
Fresh clone git clone --branch <base> <url> <dir>, then git checkout -b <branch>.
Empty folder Creates an empty directory.

The branch name comes from the Branch name template (default jimothy/{{issue.key | slug}}). The per-run directory is <workspaces folder>/run-<number>-<issue-key-slug>. If preparation fails, the run fails with Workspace setup failed: …. Details in Workspaces.

The run moves to Running. The scheduler repeatedly looks for Pending steps whose dependencies are all finished and starts every one it finds, so independent steps run in parallel. A step’s dependencies are its Runs after list, or the previous step in the list by default. See DAG & parallelism.

For each step that becomes ready:

  1. Upstream check. If a dependency Failed or was Cancelled (and didn’t have Continue on error), or was skipped because of an upstream failure, the step is Skipped with “Skipped because an upstream step failed”.

  2. Condition. If the step has Run only if and the template renders falsy ('', false, 0, no), the step is Skipped. Dependents still run. See Retries, timeouts & conditions.

  3. Render. The prompt, command or approval message is rendered with the template context: the issue, the run, variables, and the current outputs of every step. In shell steps, interpolated values are shell-quoted.

  4. Execute.

    • Agent steps run on their harness in the workspace: a CLI process, an API call, or the Simulator. Logs stream live, including tool calls, thinking and results when the harness emits structured output.
    • Shell steps run the command with the system shell in the workspace. Exit code 0 is success.
    • Approval steps pause the step as Needs approval, fire approval.required, and wait for Approve or Reject.
  5. Verdict. If the process succeeded, the output is checked against the step’s Pass if output matches / Fail if output matches regexes. See Loops & verdicts.

  6. Retry. If the attempt failed (but not because of a verdict), the step is retried up to Retries on failure times with exponential backoff (2s, 4s, 8s, … capped at 30s).

  7. Loop back. If the step still failed and has On failure, loop back to set, and its loop budget (Max loops, default 2) isn’t used up, the target step and everything downstream of it are reset to Pending and run again, with the failing step’s output available to them.

  8. Record. Output (the last 20,000 characters), cost, tokens, and any PR/MR/preview links found in the output are recorded on the step and the run.

While at least one step is waiting for approval and none are running, the run shows Needs approval.

When no step can make progress:

  • If the run was cancelled, it’s Cancelled and unfinished steps become Cancelled.
  • If any step Failed without Continue on error, the run is Failed with an error like Run tests failed: Command exited with code 1.
  • Otherwise the run Succeeded.

Then:

  • The run.succeeded / run.failed / run.cancelled event goes to your notification channels and the in-app inbox.
  • If the run came from a trigger, its Succeeds or Fails write-back runs (a cancelled run counts as failed). The comment summarizes the run. See Write-back.
  • If Settings → Delete a run’s workspace after it succeeds is on, the workspace of a successful run is removed (branches are kept; Existing folder workspaces are never removed).

Cancel on a queued run removes it from the queue. On an active run it aborts every running step and kills each step’s whole process tree (SIGTERM, then SIGKILL after 5 seconds). Pending approvals resolve as cancelled.

On a finished run:

  • Retry re-queues the run and re-runs every step that didn’t succeed, plus everything downstream of those steps. Succeeded steps keep their output.
  • Retry from here (on a step) re-runs that step and everything downstream of it.

A retry uses the pipeline’s current definition, so you can fix a prompt or command and retry without starting over. Steps are matched by id; new steps are added, removed steps disappear. Loop counters reset. The run’s workspace and branch are reused if the folder still exists.

If Jimothy quits while runs are in progress, those runs are marked Failed on the next launch with “Interrupted: the app was closed while this run was in progress. Use Retry to resume.” Runs that were still Queued are queued again.