All mechanics live in the bro CLI. This skill is policy only.
Prereq: bro on PATH or npx -y @broject/bro@0.
What it is
The hooks layer journals every post-tool event per session to
<git-common>/bro/hooks/trace/<session>.jsonl. bro trace export
pushes the unexported tail of those journals to an OTLP endpoint over
OTLP/HTTP JSON (POST <endpoint>/v1/traces) — one trace per session,
one span per journal line, journal fields as bro.* attributes. A
cursor in trace/.export.json makes repeat exports send only the
delta; span ids are content hashes, so resends dedup server-side.
| Command | What it does |
|---|---|
bro trace export |
Push all journals' new lines as spans |
bro trace export --session <id> |
Push one session's journal only |
bro trace export --dry-run |
Print the request payload, POST nothing |
bro trace export --json |
Machine-readable summary (+ last error) |
Policy
- Off until an endpoint resolves. Export does nothing without
telemetry.otlp.endpointin bro.config.* or the standard env namesOTEL_EXPORTER_OTLP_TRACES_ENDPOINT/OTEL_EXPORTER_OTLP_ENDPOINT(env wins).OTEL_EXPORTER_OTLP_HEADERS(k=v,k2=v2) andOTEL_SERVICE_NAMEmerge the same way.BRO_TELEMETRY=0kills it unconditionally — the same switch as the command journal. - The agent never waits on it. With an endpoint set, the post-tool
hook respawns
bro trace exportdetached at most once pertelemetry.otlp.flushMs(default 60s). A dead collector, DNS failure, or 5xx loses that batch only — the cursor'slastErroris the only record, the hook path stays silent by contract. - Failures are cursor state, not exits. A failed POST leaves the
cursor behind — the next flush resends (at-least-once).
bro trace export --jsonsurfaceslastError/lastErrorAt; the manual verb exits nonzero so an operator run is honest. - Attribution is what's journaled. Spans carry
bro.sessionplus whatever fields the line recorded —bead/agentappear when the session ran under bro's spawn pins (loop/convoy workers); a field absent from the journal simply isn't an attribute.