Skip to main content
The worker reads its declarative configuration from config.yaml inside the profile’s own state tree — ~/.blobhub-worker/profiles/{profile}/config.yaml, so each profile watches its own sessions. blobhub-worker whoami prints the tree a given invocation resolves to; for what is running on this machine and what it is doing, see instance ls/show instead. 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 belongs to the profile, not to config.yaml. It is stored alongside the key in ~/.blobhub/credentials.yaml (written by blobhub-worker login) and can be overridden per run with --api-url or BLOBHUB_API_URL. To point a worker at a different endpoint, log in under a second profile name and run start --profile <name> — that gives the other endpoint its own configuration and cursors rather than reusing this one’s.

Top-level shape

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

polling

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

concurrency

agents

A map of agent_type → per-agent settings. Job types that spawn coding agents (currently session_agent_harness) read this block to decide how to launch the agent inside each thread’s work_folder. Supported agent_type values are claude_code, codex, and antigravity (Google’s Antigravity CLI, agy). (A test_double adapter exists for internal testing and is not user-visible.) None of the three agent CLIs ships with the worker — see Install for what each one needs on the host before a thread can be handed to it.
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/agy by agent type. For the full precedence rules and the per-thread overrides, see Job Session Object.

policy

The operator’s rule set and ceiling for any thread running with permissions: guarded (see the agents table above). This block is optional; omitting it is equivalent to allow_autonomous: true with no rules — today’s behavior for every existing deployment.

Rule shape

Each entry in rules — both here and in a thread’s own policy block — has the same shape: Rules are evaluated first match wins, in this order: this section’s rules, then the thread’s own policy.rules, falling through to the thread policy’s default (allow | ask | deny) when nothing matches. The worker config carries rules only — default belongs to the thread’s own policy, because a machine-wide default would be a ceiling on nothing in particular. effect is a portable vocabulary, but the three supported harnesses do not see the same calls, so the same rule does different work on each. claude_code and antigravity route every tool call to the gate, which is also the only gate they have; codex runs inside an OS sandbox and asks only when a call escalates beyond it, so a rule written against write + outside: work_folder matches something different there. A policy is a guardrail against mistakes, not a sandbox, on any of the three. Before writing rules for a sensitive workspace, read Job Session Object → Policy and guarded permissions for the full evaluation model, the per-harness capability table, and what a policy cannot enforce.

attachments

The worker’s own default inbox location — the middle tier of a three-tier, whole-value resolution: a thread’s own attachments.inbox (set on the thread session object) overrides this block’s inbox, which in turn overrides the codebase default. This block is optional; omitting it is equivalent to inbox: .blobhub/inbox — today’s behavior for every existing deployment.
Unlike policy, there’s no on/off switch behind this: every tier resolves to some directory, and the worker always creates and uses one. For the full resolution order, the containment rule, and what happens when the resolved path escapes work_folder, see Job Session Object → Attachments.

sections

A list. Each entry is a unit of work the worker runs. Every section has these generic fields: 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.

session

job_id — the on-disk state directory under the profile’s own jobs/ — is always derived from the resolved session id, never from the configured spelling: a session re-created under the same alias is a different session, and its threads must not inherit the old session’s local state. See Filesystem Layout. Two sections may not name the exact same (org_id, blob_id, revision_id, session_id, session_prefix) tuple (DUPLICATE_SECTION_TARGET at load; see Validation below) — but because session_id can be spelled as either an id or an alias, one section naming a session by id and another naming the same session by alias will not be caught by that static check. The worker repeats the check after resolution: whichever section’s reference resolves second refuses to attach with the same DUPLICATE_SECTION_TARGET code, while the worker keeps serving every other section. See Session Agent Harness → Reference for that section-level form.

Full working example

A complete config.yaml with the global blocks set, a policy ceiling, and one session_agent_harness section watching a slice of a session named by alias.
A minimal single-section example — the same shape with a uuid session_id, no session_prefix, and permissions: approval — needs nothing beyond the Top-level shape block above. Save this file at ~/.blobhub-worker/profiles/default/config.yaml (or wherever blobhub-worker whoami reports), then run:
Once running, prepare a thread session object inside that session and set instance.state = "pending" to hand it off to the worker — see Handoff.

Validation

The configuration is validated on every start, before any section is dispatched. session_prefix, when set, must match ([A-Za-z0-9._@-]+/)+ — one or more path segments each ending in /, with no . or .. segment. The top-level policy.rules are checked against the same effect / action vocabulary documented under policy above; an unknown value fails with INVALID_CONFIG naming the offending rule. Process-level codes (INVALID_CONFIG, UNKNOWN_JOB_TYPE, MISSING_SESSION_KEYS, DUPLICATE_SECTION_TARGET) and their remediation are catalogued on Reference. Section- and thread-level codes for session_agent_harness — including POLICY_MISSING, POLICY_INVALID, POLICY_AUTONOMOUS_FORBIDDEN, and the section-level, post-resolution form of DUPLICATE_SECTION_TARGET — are on the Session Agent Harness reference.

See also