> ## 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.

# blobhub-worker start

> Run the worker

`blobhub-worker start` loads the configuration, runs preflight checks, and runs each configured
section. The per-section behavior — what the worker does once it's attached — is determined by
the section's [`job_type`](/worker/job-types).

## Synopsis

```bash theme={null}
blobhub-worker start [--tui]
```

| Flag    | Default        | Description                                                                |
| ------- | -------------- | -------------------------------------------------------------------------- |
| `--tui` | off (headless) | Render the live Textual dashboard. Press `q` to request graceful shutdown. |

In headless mode (the default) the worker writes structured JSON log lines to **stderr**, which
makes it suitable for running under systemd, a container supervisor, or `tmux`. With `--tui`, those
same JSON lines are redirected to a file at `~/.blobhub-worker/logs/{instance_id}/worker.jsonl`
(append mode, line-buffered) so the dashboard has the terminal to itself; stderr is silenced while
the dashboard runs. Log rotation is not implemented in v1.

## Preflight

Before any section is contacted, `start` runs the following checks in order. A failure here exits
the process with a clear code; nothing on the server is touched.

1. `credentials.yaml` exists and is mode `0600` — else `CREDENTIALS_NOT_FOUND` /
   `INSECURE_CREDENTIALS_PERMISSIONS`.
2. `identity.yaml` exists — else `IDENTITY_NOT_FOUND` (run `login`).
3. Single-instance lock acquired at `~/.blobhub-worker/instance.yaml` (atomic `O_EXCL`; a stale
   file with a dead PID is replaced) — else `WORKER_ALREADY_RUNNING`.
4. Identity check: `GET /v1/users/me` re-validates the API key and confirms the server-side
   `user_id` matches the recorded one — else `AUTH_INVALID` / `USER_IDENTITY_MISMATCH`.
5. `config.yaml` loaded and validated — else `INVALID_CONFIG`. Each section's
   [`job_type`](/worker/job-types) is dispatched to the corresponding job-type validator, which
   may surface additional codes (e.g. `UNKNOWN_JOB_TYPE`, or job-type-specific section errors).

See [Configuration](/worker/configuration) for the full `config.yaml` schema and
[Reference](/worker/reference) for process-level remediation.

## Per-section behavior

For each configured section the worker dispatches to the section's `job_type`. The runtime
behavior — what gets attached, what gets polled, what gets posted — is documented on the
corresponding job-type page:

* `session_agent_harness` → [Overview](/worker/session-agent-harness/overview).

## Shutdown

`SIGINT` (Ctrl-C) and `SIGTERM` trigger a graceful shutdown:

1. Stop accepting new events.
2. Ask each running section to drain — the per-job-type teardown is documented on the
   corresponding job-type page.
3. Remove `instance.yaml` and exit 0.

`SIGKILL` skips the graceful path; the next `start` will replace the stale `instance.yaml` and run
each job type's recovery routine.

In `--tui` mode, pressing `q` triggers the same graceful shutdown.

## Exit codes

`start` exits non-zero on any preflight failure, on any unhandled fatal error, and on user-requested
shutdown after surfacing the cause. Diagnostic detail is emitted to the structured log stream
(stderr by default; the `worker.jsonl` file under `--tui`) as a `worker_exit` JSON record.

Full code catalog: [Reference](/worker/reference).

## See also

* [`blobhub-worker login`](/worker/cli/login)
* [Configuration](/worker/configuration)
* [Job types](/worker/job-types)
