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 for v1 are claude_code and codex. (A test_double adapter exists for internal testing and is not user-visible.)
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.

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 two supported harnesses do not see the same calls — a rule written against write + outside: work_folder behaves differently on claude_code than on codex, and a policy is a guardrail against mistakes, not a sandbox. 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.

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