> ## Documentation Index
> Fetch the complete documentation index at: https://xerg.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Hermes trace collection

> Collect certified, sanitized Hermes traces locally and reconcile them to state.db.

Xerg supports optional local trace enrichment from the exact certified
`briancaffey/hermes-otel` commit
`0180c5e63b9d035ee0754d9a0d75c3499a8def26`. This is not required for Hermes
analysis parity: the first-party Xerg observer is the primary request and
mechanical source.

Hermes traces are never an independent monetary audit. A matching, auditable
`state.db` is always required.

## Start the collector

```bash theme={null}
npx @xerg/cli@latest collect hermes \
  --state-db ~/.hermes/state.db
```

Xerg binds only to `127.0.0.1`, accepts OTLP/HTTP protobuf traces at
`/v1/traces`, prints the required plugin configuration, and waits for
`Ctrl-C`. It never installs, enables, or edits the third-party plugin and never
pushes automatically.

Required plugin configuration:

```yaml theme={null}
capture_previews: false
capture_conversation_history: false
capture_logs: false
sample_rate: 1.0

backends:
  - type: otlp
    name: xerg-local
    endpoint: http://127.0.0.1:4318/v1/traces
    traces: true
    metrics: false
    logs: false
```

Set `HERMES_OTEL_DEBUG=false`.

The pinned plugin resolves YAML from
`~/.hermes/plugins/hermes_otel/config.yaml`, even when Hermes itself uses a
non-default `HERMES_HOME`. For a non-default profile, use the equivalent
environment configuration that `xerg collect hermes` prints
(`OTEL_JAEGER_ENDPOINT` plus the `HERMES_OTEL_*` privacy and sampling
variables). Environment values override plugin defaults. Xerg still does not
edit either location.

## Audit an existing capture

```bash theme={null}
npx @xerg/cli@latest audit \
  --runtime hermes \
  --state-db ~/.hermes/state.db \
  --otlp-file ./hermes.capture.jsonl
```

You may also add `--hermes-events-dir`. The observer remains primary. If
observer and trace request totals disagree, Xerg retains the original
`state.db` aggregate and reports the conflict. It never creates duplicate
economic calls.

The certified plugin reports its prompt-token bucket inclusive of cache reads
and writes. Xerg converts that value to the uncached input bucket before exact
reconciliation, preserving the separate cache buckets used by `state.db` and
the first-party observer. Adding or removing optional trace enrichment does
not change the authoritative audit ID or comparison key.

## Correlation and privacy

Xerg creates one owner-only 32-byte correlation key per installation. Native
session, trace, span, turn, and tool-call identifiers are HMACed before capture
persistence. Only the key ID is stored in a capture. A moved capture without
the matching local key remains readable for descriptive diagnostics but cannot
split state economics.

The sanitizer persists only bounded provider/model/tool/role/skill names,
statuses, durations, token buckets, counts, hashed ancestry, and the certified
plugin commit target. It drops prompt/response values, conversation content,
invocation parameters, tool arguments/results, commands, paths/targets, goals,
summaries, approval text, skill paths, user IDs, and arbitrary attributes even
when plugin privacy settings are wrong.

Limits match the OpenClaw collector: 16 MiB per request, 256 MiB per sanitized
capture, and 100,000 decoded spans. Files are owner-only and no-overwrite;
metrics, logs, JSON, gRPC, remote binding, and remote collection are rejected.
