Skip to main content
dotbot runs each task as one focused provider session. The session explores the codebase, resolves ambiguity, writes code, runs tests, and commits — all within a single attempt. Folding discovery and implementation into one session keeps the agent’s context intact from the first file it reads to the commit it makes, and it lets dotbot pause for human input or park a finished task for review without splitting the work across separate runs.

A task runs as one session

When dotbot picks up a task, it claims the task directly for execution and moves it straight to in-progress. There is no separate analysis state. Discovery is the opening part of the same session, not a distinct phase the task transitions through.
Inside that single session the agent:
  1. Explores the codebase and identifies the files the task will affect
  2. Writes code in the task’s isolated git worktree
  3. Runs the project’s test suite and verify hooks
  4. Commits changes with a tag in the format [task:XXXXXXXX]
Tasks of type script, mcp, task_gen, and barrier never start a provider session. The runtime dispatches them deterministically, runs them in the task’s worktree, and skips verification hooks. They move straight from todo to in-progress to done.
Every commit message dotbot produces includes the short task ID tag, so you can trace any change back to the task that produced it:

The HTTP runtime

Task execution sits on top of a per-project HTTP runtime. The runtime owns the task queue, the state transition table, and the activity log. The CLI talks to it over HTTP rather than mutating files directly, which is what keeps concurrent task runners consistent. You can drive the runtime directly: dotbot serve is useful for diagnostics and tests that want the HTTP surface without a UI. It runs until you press Ctrl+C, then removes .bot/.control/runtime.json so the next start gets a fresh token. dotbot runtime-status exits 0 when the runtime is alive and reachable, 1 when it is not running, and 2 when the PID is alive but the HTTP endpoint is unreachable.

Multi-slot concurrent execution

dotbot can run multiple tasks from the same workflow in parallel. Each task runs in its own task-runner process and its own git worktree (see Per-task git worktree isolation), so there are no file conflicts between concurrent tasks. You control the concurrency limit with the execution.max_concurrent setting in settings.default.json or from the Settings tab in the dashboard. It defaults to 1.
Use a cheaper model tier for simple tasks and reserve the most capable tier for complex ones. Per-task model selection reduces token spend without sacrificing quality where it matters.

Per-task model selection

Models are configured as tiers — fast, balanced, and best — and each provider maps the tiers to its own concrete models. The default tier is best. A task can set a model field to override the default for that task:
Model resolution order: task-level model override, then execution.model from settings, then the active provider’s default model. An unknown tier falls back to the provider default.

Process types

dotbot runs a unified task-runner process per execution slot. Each task-runner claims a task, runs it to completion, and then picks up the next available task. The legacy split between separate analysis and execution processes is gone. You can see active processes in real time on the Processes tab in the dashboard. For each running process it shows the type, the active model, the current task, and elapsed time.

Flow diagram

When the agent cannot resolve a question from the codebase, it moves the task to needs-input and routes the question to a stakeholder via Teams, Email, or Jira. Once an answer arrives, the task returns to todo and is picked up again with the answer in context. When a task requires human sign-off before it merges, it moves to needs-review instead of done. See Task lifecycle states and transitions for the full state machine.