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

# Filesystem Layout

> session_agent_harness per-section subtree under ~/.blobhub-worker/jobs/

This page covers the per-section files the `session_agent_harness` job type writes under
`~/.blobhub-worker/jobs/`. For the generic top-level layout (`identity.yaml`, `credentials.yaml`,
`instance.yaml`, `config.yaml`, `logs/{instance_id}/worker.jsonl`) see
[Filesystem Layout](/worker/filesystem).

## Tree

```
~/.blobhub-worker/jobs/
└── session_agent_harness-{session_id}/
    ├── section.yaml             # per-section runtime state (event-poll cursor, attachment)
    ├── logs/
    │   └── section.log
    └── threads/
        └── {thread_alias}/
            ├── thread.yaml      # per-thread state (agent state, agent_session_id, cursors)
            └── logs/
                └── thread.log   # full untruncated agent stdio + tool I/O
```

The agent runs with `cwd = workspace.work_folder`; the worker keeps **no** separate agent-session
directory on disk. Session resume is SDK-managed and keyed by `agent_session_id` (recorded in
`thread.yaml`).

`job_id` is deterministic: `session_agent_harness-{session_id}`. This guarantees stable paths
across restarts, reinstalls, and config edits — and namespaces this job type away from any future
ones.

## File-by-file

### `section.yaml` — per-section runtime state

Persisted by the worker. Recovery on next start re-reads this.

```yaml theme={null}
name: my-project
job_type: session_agent_harness
session:
  org_id: org_01J...
  blob_id: blb_01J...
  revision_id: rev_01J...
  session_id: ses_01J...
attachment:
  status: attached                    # attached | refused
  attached_at: 2026-05-27T12:35:01Z
  error:
    code: null
    message: null
events:
  last_processed_at: 2026-05-27T12:40:00Z
```

### `logs/section.log`

Section-scoped JSON-line log: poll cadence, event dispatch, thread discovery.

### `threads/{alias}/thread.yaml` — per-thread state

The worker's local, authoritative-for-recovery view of a thread, plus the inbound/outbound item
cursors. This **local layout differs from the wire envelope**: it keeps `workspace.agent_type` and
`agent.state`, and the `agent_session_id` resume pointer and `error` block are local-only — they
never appear on the wire. The mapping is documented on
[Job Session Object](/worker/session-agent-harness/thread-object).

```yaml theme={null}
alias: my-feature-x
session: { ... }
workspace:
  agent_type: claude_code         # local layout keeps agent_type here (wire uses agent.type)
  work_folder: /Users/me/projects/foo
agent:
  state: active                   # "" | pending | active | completed | failed
  agent_session_id: ag_sess_...   # local-only resume pointer (never on the wire)
  error:                          # local-only failure detail (surfaces via thread_failed)
    code: null
    message: null
items:
  last_consumed:
    item_id: itm_01J...
    created_at: 2026-05-27T12:50:00Z
  last_posted:
    item_id: itm_01J...
    created_at: 2026-05-27T12:50:05Z
```

### `threads/{alias}/logs/thread.log`

Captures the **full untruncated** agent stdio + tool I/O. When the worker truncates a thread item
to fit the 350 KB budget, the local log retains the full payload — see
[Thread Items](/worker/session-agent-harness/thread-items).

## Why both server-side metadata and `thread.yaml`?

* The **server-side envelope** is authoritative for handoff. Anyone with API access (web UI, SDK,
  another tool) reads it to see the agent state machine.
* **`thread.yaml`** is authoritative for **local recovery**. The worker writes it before any
  externally observable side-effect, so a crash-restart finds a truthful local record.

## See also

* [Filesystem Layout](/worker/filesystem) — generic top-level files.
* [Job Session Object](/worker/session-agent-harness/thread-object) — wire vs local field layout.
* [Configuration](/worker/configuration)
* [Recovery](/worker/session-agent-harness/recovery)
