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
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 inrules — 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 completeconfig.yaml with the global blocks set, a policy ceiling, and one
session_agent_harness section watching a slice of a session named by alias.
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:
instance.state = "pending" to hand it off to the worker — see
Handoff.
Validation
The configuration is validated on everystart, 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.

