Skip to content
boboddy.dev

Running Workers

A worker is a long-running process that polls the Boboddy server for pending step executions, claims them under a time-limited lease, executes them using a local Docker environment, and reports results back.

Terminal window
boboddy work

By default the worker runs continuously, polling your project’s step queue every 5 seconds.

If your current directory contains .boboddy/boboddy.jsonc, the project ID is read automatically. Otherwise pass it explicitly:

Terminal window
boboddy work <projectId>
Flag Alias Default Description
--once false Poll once and wait for any claimed jobs to finish
--concurrency <n> -c 1 Maximum number of concurrently active jobs
--batch-size <n> -b value of --concurrency Maximum step executions to claim per poll cycle
--lease-duration-seconds <n> -l 30 Lease duration before the server reclaims a job
--poll-interval-ms <n> -p 5000 Milliseconds between poll cycles
--worker-id <id> -w auto Worker identifier used while claiming steps
--work-item-id <id> Only process step executions for this work item ID
--preserve-runtime-on-complete -k false Keep runtime containers and workspace after a job finishes (useful for debugging)
  1. Poll — The worker calls the server to claim a batch of pending step executions.
  2. Claim — Each claimed execution is assigned a lease. The worker sends heartbeats to extend the lease while processing.
  3. Environment setup — For workspace steps (the default), the worker clones your repository and launches a single Docker runtime from your .devcontainer/devcontainer.json. Before bringing the container up, it injects mounts for a pinned, Boboddy-managed OpenCode runtime payload and a session-scoped agent home. For no_workspace steps, this is skipped entirely — see Execution mode.
  4. Agent startup — For workspace steps, OpenCode runs inside that same devcontainer (same environment as your workspace), launched by absolute path from the mounted runtime payload — never the project’s Node or a global opencode. There is no separate AI container, cross-container network, or MCP-host bridge. For no_workspace steps, the same Boboddy-managed OpenCode runtime runs directly on the worker host against a temporary empty directory — no Docker, no clone.
  5. Agent execution — The step is handed to the in-container OpenCode agent with the step’s prompt, input payload, and any configured MCP servers. Provider access is resolved through a normalized contract (currently direct mode: an explicit provider base URL + token, with your local OpenCode config as a fallback source).
  6. Signal extraction — The agent’s structured output is parsed; signals are extracted per the step’s signals definition.
  7. Report — The worker marks the execution complete (or failed) and posts output + signals back to the server.
  8. Cleanup — The Docker environment is torn down (unless --preserve-runtime-on-complete is set).

For workspace steps, the worker creates a dedicated git branch for each step execution right after cloning, commits the agent’s changes to it, and pushes it.

Branches are named <prefix>/<stepKey>-<stepExecutionId>. The prefix defaults to boboddy. To use your own prefix, add branchPrefix to the repo’s .boboddy/boboddy.jsonc:

{
"projectId": "your-project-id",
"branchPrefix": "myteam"
}

With the config above, a step keyed build produces a branch like myteam/build-<stepExecutionId>.

Notes:

  • The prefix is sanitized to a valid git ref (whitespace and unsafe characters become -). If it is missing, empty, or sanitizes to nothing, the worker falls back to boboddy.
  • The prefix is read from the cloned repo’s config on disk, so it lives alongside the code it applies to.

The worker always clones the repo’s default branch, then creates the step’s work branch off a base branch:

  • Later steps in a pipeline are always created off the previous step’s work branch.
  • The first step (and standalone steps) is created off a base branch resolved with the following precedence:
    1. Your current local branch. boboddy work resolves the branch you’re on in the directory you ran it from and checks it out immediately after clone — so the devcontainer config and everything the step runs against comes from the branch you’re actually working on, not the repo’s default branch. Before proceeding, the CLI verifies your current branch exists on origin and is in exact sync with it (not just an ancestor/descendant); if it isn’t pushed, has diverged, or doesn’t exist on origin at all, the command fails fast with a message telling you what to do — it never auto-pushes on your behalf. Use --source-branch <branch> to target a different branch instead (e.g. from CI, or a colleague’s branch) — an override only needs to exist on origin, not be checked out locally. --dry-run performs the same resolution and checks.

    2. A configured base branch, when your current branch can’t be resolved (e.g. boboddy work isn’t run from inside a git checkout, or HEAD is detached). Set baseWorkBranch in the repo’s .boboddy/boboddy.jsonc:

      {
      "projectId": "your-project-id",
      "baseWorkBranch": "develop"
      }

      You can override the configured value per worker with the BOBODDY_BASE_WORK_BRANCH env var in .boboddy/.env. The env var takes precedence over the jsonc field.

    3. The repo’s cloned default branch, when neither of the above applies.

If the resolved base branch cannot be fetched/checked out, the step fails.

  • Docker must be running and accessible to the worker process — required for workspace steps. no_workspace steps do not use Docker.
  • AI provider credentials must be available. Boboddy ships and launches its own pinned OpenCode runtime, so you do not need OpenCode installed — but it reads your provider credentials from ~/.config/opencode/ or from env vars such as ANTHROPIC_API_KEY. See opencode.ai/docs for provider setup.
  • Your repo must have a .devcontainer/devcontainer.json by the time a workspace step runs. boboddy init only reports a missing one; the pipeline designer authors it during a design session, and this worker run is what first builds it. See Setting up a Dev Container to write one by hand.
  • Credentials must be present (boboddy auth login).

For debugging or CI use cases, run a specific work item:

Terminal window
boboddy work --work-item-id <id> --once --preserve-runtime-on-complete

This claims the specified item, runs it once, and keeps the container alive so you can inspect the execution environment.

Newer single-container runs no longer create per-session Docker networks. This command remains as a maintenance utility to remove any unused Boboddy runtime networks left over from older runs:

Terminal window
boboddy runtime cleanup-networks
boboddy runtime cleanup-networks --verbose

Workers use credentials stored in ~/.boboddy.json. If running in CI, set the BOBODDY_BASE_URL environment variable and ensure credentials are available (e.g., via a secret injected at ~/.boboddy.json).