Skip to main content
Telemetry events are structured records associated with run identity. The store can derive a logical lineage path from that identity; lineage does not imply runtime filesystem fork. Organization and project are assigned from authenticated request context at ingest time.

Core fields

Time

Events use a hybrid logical clock:

Signals

Every event belongs to one signal — the family of thing it records. Two kinds of family land in the same stream:
  • Captured signals record what your workload did: what it ran, printed, and requested. They flow for a command wrapped by hiloop run and for supported boundaries in a sandbox’s managed capture session.
  • Platform signals record what the platform did around the workload: lifecycle, scheduling, network-policy decisions. They carry resource identities and state vocabulary — never command lines, bodies, or output — so they flow for every sandbox regardless of its capture setting.

llm and net — HTTP exchanges

Each HTTP exchange the workload makes becomes a pair of events — http.request then http.response — sharing an http.exchange_id. Model-provider exchanges are the llm signal; every other exchange is net. The shapes are identical: Ordinary bodies are captured up to a size cap, scrubbed of recognized credential patterns by default, and stored out of line under payload_ref — fetch them with hiloop events payload. A local hiloop run --no-redact disables only that generic scan. Exact supported OAuth token exchanges are metadata-only instead. Content type and content encoding are the only header values recorded; no other header — Authorization, Cookie and the rest — is captured. http.target is ordinarily the full request target, while exact OAuth omission also removes its query values. A harness OpenTelemetry span that carries gen_ai.* or llm.* attributes also lands under llm (named by the span); span attributes are stored as sent and are not scrubbed.

log — process output

One event per captured chunk of process output: The harness’s own OpenTelemetry log records land under log too, named by their log event name (the severity text when unnamed), with the body under message. Capture health. Capture is best-effort by design — it can never fail your workload — so it reports its own completeness instead: as a captured run drains, one final capture.drain event states whether everything captured actually landed. capture.complete is the verdict — true only when every uploadable payload blob landed and no exported event was lost. Behind it: capture.blobs.found / capture.blobs.landed / capture.blobs.missing / capture.blobs.missing_bytes, with capture.blobs.oversize counting bodies over the upload cap that stayed local; and capture.events.dropped / capture.events.rejected / capture.events.pending when events were spooled through a gateway outage (pending records late delivery, never loss — the record queues behind its own backlog, so its arrival certifies everything spooled before it landed too). capture.error carries the failure when a drain went wrong. A captured run with no capture.drain event at all ended without draining — treat its capture as incomplete.

exec — command lifecycle

The lifecycle of the commands your workload ran, from two vantage points that share one signal. A command wrapped by hiloop run records its own process boundary: Every event one hiloop run invocation captures — lifecycle, output, HTTP exchanges, and its run-end capture-health record — also carries wrapper.invocation_id, a unique id minted per invocation, so one wrapped process’s events stay correlated even when several wraps share a run. A buffered sandbox execution is observed by the platform from the host side, so the record exists even if the process never starts: Every emitted exec.start gets exactly one exec.end, so a failed execution never reads as still-running. These events carry workload command lines, so they respect the sandbox’s capture setting. The command’s environment (a secret carrier), stdin, and captured output are never attached — output lives in execution artifacts and log events.

span — harness traces

If the wrapped agent emits its own OpenTelemetry spans, each span becomes one event named after the span, with the trace identity under otel.trace_id, otel.span_id, and otel.parent_span_id (promoted to the trace_id/span_id/parent_span_id columns). Spans carrying gen_ai.*/llm.* attributes classify as llm instead.

metric — resource samples

hiloop run --sample-resources can emit best-effort resource.sample events roughly every 15 seconds for a local process tree. Authoritative runtime-owned resource accounting will use the same event shape when it ships. See usage metering for turning samples into utilization and cost answers.

egress — network policy decisions

The schema reserves egress events for future runtime-native destination-policy decisions. The current fixed network floor emits none of the connection-level events below; the retired shared proxy’s SNI audit stream is not a current product surface. When a runtime-native producer ships, these events remain platform metadata and must never carry credential values or request bodies.

runtime — platform lifecycle

What the platform did to a sandbox and when: state transitions and operation lifecycle with queue latency. These are control-plane metadata with no workload content, so they flow for every sandbox regardless of its capture setting. Emission is best-effort and always follows the committed change, so telemetry can never affect an operation’s outcome. Which run they land on. An operation’s events ride the run of the sandbox it targets, and an execution’s ride the run of its owning sandbox. A resource with no run emits nothing. Deliberate exclusions. Periodic reconciliation emits no operation.* events — that would flood every active run with platform noise; what surfaces is the drift a reconcile actually commits (sandbox.state_changed with reason=reconcile, or sandbox.preempted). Background cleanup maps to no run and emits nothing.

annotation — knowledge you write

Annotations are ordinary events: the name is the annotation schema name, and your payload lives in the attributes (promoted fields become typed columns in the schema-named ann_* view). They’re the write path for eval scores, verdicts, and any other structured knowledge you attach to runs.

Correlation keys

Attributes that join events to each other and to resources: The query engine promotes common network and tracing fields into typed columns — for example http_status_code, http_host, trace_id, and span_id. Use promoted columns when you filter or aggregate on them. Everything else an event carries lives in attributes_json (reach in with hiloop_json_get), and model-shaped fields (model, token counts, messages) derive from the captured payload bodies through a data view like otel_genai_calls. See the concept page for the full allowlist.