inputs, outputs, and repairs. Everything else on a BoundaryLogEvent is structural and always sent, because Boundary can’t show you a run at all without it.
The three buckets
Always-on fields
These are sent on every event regardless of capture config. They’re the minimum Boundary needs to plot a run:| Group | Fields | Why always on |
|---|---|---|
| Identity | contractName, environment, timestamp, runId | Required to coalesce per-attempt + terminal events into one run row. |
| Run metadata | attempt, maxAttempts, durationMs, ok, final | The shape of “what happened in this run.” |
| Contract metadata | model, rulesCount, schema, rules | Stamped so the dashboard can attribute failures to the right contract version. |
Failure attribution (only on ok: false) | category, issues, ruleFailures | Without these, a failure event is just a flag — useless for triage. |
| SDK attribution | sdk.name, sdk.version, sdk.runtime | Used to debug version-specific behavior. |
Field-to-bucket mapping
| Field | Gate | Default |
|---|---|---|
input | capture.inputs | off |
output | capture.outputs | off |
repairs | capture.repairs | on |
| Everything else | always sent | on |
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 in
stagingordevelopmentfirst and audit what actually flows through before flipping production. - Pair with redaction rules that match your data shape.
- Or use
beforeSendto hash or summarize the input before it leaves the process.
Opt-in recipe: debug staging traffic
When you can’t capture failure context
Failure attribution (category, issues, ruleFailures) is always sent on a failed event — there is no flag to drop it. If a specific failure message would leak data because a rule interpolates record values into it, fix it at the source: rewrite the rule to return a generic message string, or use beforeSend to scrub issues[] before the event leaves the process.
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