Redaction runs in-process, before any byte hits disk. The redactor is applied to tool arguments and results and to model input/output during serialization, so payloads are masked in the written capture — and the tool input_hash is derived from the redacted arguments.
## Opt in
Redaction is opt-in: nothing is masked unless you pass a redactor. The SDK ships default_redactor, a conservative masker for common secrets in strings — emails become [REDACTED_EMAIL]; OpenAI sk- keys, AWS AKIA… keys, and Bearer tokens become [REDACTED_KEY]. It walks dicts, lists, and tuples recursively and never mutates its input.
from evalshift import capture, default_redactor # opt in explicitly — nothing redacts unless you pass a redactor @capture.agent(suite="support_agent", redact=default_redactor) def handle_ticket(query: str) -> str: ...
## Custom redactors
A redactor is any (value) -> value callable. Write your own for domain-specific secrets — the default masks are not a substitute when your data has structured PII.
def my_redactor(value):
# a (value) -> value callable; return a redacted copy, don't mutate
if isinstance(value, str):
return value.replace(account_number, "[REDACTED_ACCT]")
return value
@capture.agent(suite="support_agent", redact=my_redactor)
def handle_ticket(query: str) -> str: ...Set one process-wide with configure(redact=...); a per-capture redact= — on the agent decorator, on agent_session / agent_session_async, or on an adapter handler — takes precedence over it.
from evalshift import configure, default_redactor # process-wide default; a per-capture redact= overrides it configure(redact=default_redactor)
## What a written capture may still contain
A redactor masks payloads. It does not remove structure. After redaction a capture file still contains:
- +The shape of the run — which tools fired, in what order, with what parentage.
- +Envelope metadata — suite, capture id, timestamps,
code_version,schema_version. - +The one-way
input_hash(computed from redacted arguments) — it identifies a call but cannot be reversed to the input.
Note that a session’s agent_input is identity only: it is hashed into the envelope’s input_hash as-is and never stored raw, so redaction does not apply to it.
Plan accordingly: choose a redactor that covers your sensitive fields before turning the gate on in any environment that handles real user data.