> ## Documentation Index
> Fetch the complete documentation index at: https://docs.blobhub.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Configuration

> The complete ~/.blobhub-worker/config.yaml reference

The worker reads its declarative configuration from `~/.blobhub-worker/config.yaml`. This page is the
complete reference for that file: the `polling`, `concurrency`, and `agents` blocks that tune the
worker globally, and the `sections` list that declares the work it runs. Edits take effect on the
next `blobhub-worker start` — there is no hot reload in v1.

The BlobHub API base URL lives in `~/.blobhub-worker/credentials.yaml` (written by
[`blobhub-worker login`](/worker/cli/login)) and is **not** configurable from `config.yaml`. To point
the worker at a different endpoint (staging, on-prem), re-run `login` and supply the new URL when
prompted, or hand-edit `credentials.yaml`'s `api.url`.

## Top-level shape

```yaml theme={null}
polling:
  interval_idle_ms: 1500
  interval_active_ms: 3000
  backoff_max_ms: 30000

concurrency:
  max_agents: 4

agents:
  claude_code:
    executable: claude            # default: "claude" for claude_code, "codex" for codex
    model: claude-sonnet-4-6       # harness-specific string; default unset
    effort: high                  # low|medium|high (portable) or a passthrough value; default unset
    permissions: approval         # autonomous|approval; default approval

sections:
  - name: backend-feature         # optional label
    job_type: session_agent_harness
    session:
      org_id: org_01J...
      blob_id: blb_01J...
      revision_id: rev_01J...
      session_id: ses_01J...
```

Every top-level block is optional except `sections`. Defaults are shown above.

## `polling`

Adaptive cadence for any per-section poll loop that needs one.

| Key                  | Type | Default | Description                                          |
| -------------------- | ---- | ------- | ---------------------------------------------------- |
| `interval_idle_ms`   | int  | 1500    | Sleep between polls when the section is idle.        |
| `interval_active_ms` | int  | 3000    | Sleep between polls while the section is doing work. |
| `backoff_max_ms`     | int  | 30000   | Upper bound on exponential backoff after API errors. |

## `concurrency`

| Key          | Type | Default | Description                                                                                                                          |
| ------------ | ---- | ------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `max_agents` | int  | 4       | Maximum number of agent processes the worker runs simultaneously across all sections. Job types that don't spawn agents ignore this. |

## `agents`

A map of `agent_type` → per-agent settings. Job types that spawn coding agents (currently
[`session_agent_harness`](/worker/session-agent-harness/overview)) read this block to decide how to
launch the agent inside each thread's `work_folder`. Supported `agent_type` values for v1 are
`claude_code` and `codex`. (A `test_double` adapter exists for internal testing and is not
user-visible.)

```yaml theme={null}
agents:
  claude_code:
    executable: claude
    model: claude-sonnet-4-6
    effort: high
    permissions: approval
  codex:
    executable: codex
```

| Key           | Type   | Default                                             | Description                                                                                                                                                                                   |
| ------------- | ------ | --------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `executable`  | string | `claude` (for `claude_code`); `codex` (for `codex`) | Command name to resolve on `PATH`.                                                                                                                                                            |
| `model`       | string | unset                                               | Harness-specific model identifier passed to the agent. Leave unset to use the agent's own default.                                                                                            |
| `effort`      | string | unset                                               | Reasoning effort. Portable values `low`, `medium`, `high`, or any harness-specific passthrough string. Unset = agent default.                                                                 |
| `permissions` | string | `approval`                                          | `autonomous` runs without an approval gate; `approval` routes sensitive actions to the interactive prompt bridge (a human replies from the web UI), and denies them if no human is reachable. |

These settings are the **middle tier** of a three-tier, per-field resolution: a thread's own
`agent.*` block (set on the thread session object) overrides the matching `agents.<type>` key here,
which in turn overrides the codebase default. Only `permissions` has a non-empty codebase default
(`approval`); `executable` falls back to `claude`/`codex` by agent type. For the full precedence
rules and the per-thread overrides, see
[Job Session Object](/worker/session-agent-harness/thread-object).

## `sections`

A list. Each entry is a unit of work the worker runs. Every section has these generic fields:

| Key        | Type   | Required | Description                                                                                       |
| ---------- | ------ | -------- | ------------------------------------------------------------------------------------------------- |
| `name`     | string | No       | Human-readable label shown in the dashboard. The default depends on the job type.                 |
| `job_type` | string | Yes      | The [job type](/worker/job-types) that handles this section. Must be one of the supported values. |

Everything else under a section is determined by its `job_type`. v1 ships one job type,
`session_agent_harness`, documented below.

### `session_agent_harness` sections

A `session_agent_harness` section attaches the worker to one BlobHub session and drives a coding
agent for each thread session object handed off inside it.

```yaml theme={null}
- name: my-project                     # optional; defaults to session_id[:8]
  job_type: session_agent_harness
  session:
    org_id: org_01J...
    blob_id: blb_01J...
    revision_id: rev_01J...
    session_id: ses_01J...
```

| Key        | Type   | Required | Description                                                                                                   |
| ---------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------- |
| `name`     | string | No       | Human-readable label shown in the dashboard. Defaults to `session_id[:8]` when omitted.                       |
| `job_type` | string | Yes      | Must be `session_agent_harness`.                                                                              |
| `session`  | object | Yes      | The four ids identifying the BlobHub session: `org_id`, `blob_id`, `revision_id`, `session_id`. All required. |

## Full working example

A complete `~/.blobhub-worker/config.yaml` with the global blocks set and one
`session_agent_harness` section fully populated.

```yaml theme={null}
polling:
  interval_idle_ms: 1500
  interval_active_ms: 3000
  backoff_max_ms: 30000

concurrency:
  max_agents: 2

agents:
  claude_code:
    executable: claude
    model: claude-sonnet-4-6
    effort: high
    permissions: approval

sections:
  - name: backend-feature
    job_type: session_agent_harness
    session:
      org_id: org_01J3X4M5N6P7Q8R9S0T1U2V3W4
      blob_id: blb_01J4P5Q6R7S8T9U0V1W2X3Y4Z5
      revision_id: rev_01J7K8L9M0N1P2Q3R4S5T6U7V8
      session_id: ses_01J9R0S1T2U3V4W5X6Y7Z8A9B0
```

Save this file at `~/.blobhub-worker/config.yaml`, then run:

```bash theme={null}
blobhub-worker login           # one-time
blobhub-worker start --tui
```

Once running, prepare a **thread session object** inside that session and set
`instance.state = "pending"` to hand it off to the worker — see
[Handoff](/worker/session-agent-harness/thread-handoff).

## Validation

The configuration is validated on every `start`, before any section is dispatched.

| Error                      | Cause                                                                               |
| -------------------------- | ----------------------------------------------------------------------------------- |
| `INVALID_CONFIG`           | The file is missing, unreadable, or not valid YAML.                                 |
| `UNKNOWN_JOB_TYPE`         | A section's `job_type` is not one of the supported values.                          |
| `MISSING_SESSION_KEYS`     | A `session_agent_harness` section's `session` block is missing one of the four ids. |
| `DUPLICATE_SECTION_TARGET` | Two sections target the same `(org_id, blob_id, revision_id, session_id)` tuple.    |

Process-level codes (`INVALID_CONFIG`, `UNKNOWN_JOB_TYPE`, `MISSING_SESSION_KEYS`,
`DUPLICATE_SECTION_TARGET`) and their remediation are catalogued on
[Reference](/worker/reference). Section- and thread-level codes for `session_agent_harness` are on
the [Session Agent Harness reference](/worker/session-agent-harness/reference).

## See also

* [`blobhub-worker start`](/worker/cli/start)
* [Reference](/worker/reference)
* [Job Session Object](/worker/session-agent-harness/thread-object)
* [Job types](/worker/job-types)
