BoundaryLogEvent actually get serialized.
The five buckets
Field-to-bucket mapping
Every field on the wire formatBoundaryLogEvent is gated by exactly one bucket:
| Field | Bucket | Shown by default |
|---|---|---|
contractName, environment, timestamp | always | yes |
attempt, maxAttempts, ok, durationMs | metadata | yes |
model, rulesCount | metadata | yes |
sdk (name, version, runtime) | always | yes |
category, issues | errors | yes |
repairs | repairs | yes |
input | inputs | no |
output | outputs | no |
metadata is treated as always-on — the base identity and run stats are the minimum useful payload. If you need to disable everything, don’t wire a logger at all.
Why raw input/output defaults to off
- User prompts contain customer data, PII, and internal context.
- Model completions contain proprietary business logic (lead scores, financial calcs, medical reasoning).
- Both can contain credentials echoed back by the model.
- Enable them only in
stagingordevelopment, not in production, until you’ve audited what actually flows through. - Pair with redaction rules that match your data shape.
- Or use
beforeSendto hash / summarize the input before it leaves.
Opt-in recipe: debug staging traffic
Opt-out recipe: no failure details
If your failure strings themselves contain PII (rare — but possible when a rule interpolates record values into the error message), turnerrors off:
ok: false and the attempt count. You just lose the per-rule breakdown on the dashboard.
Order of operations
Capture runs first — anything it strips cannot be resurrected downstream.See also
Redaction
Fields, patterns, custom per-leaf scrubbing
beforeSend
Per-event transform or drop
BoundaryLogEvent
Full wire format