Session recording
What is recorded of every agent run, where it is kept, and what is not recorded.
Every agent run leaves a record of what it did. Recording is on by default; a single run can opt
out with saphan run --no-recording, and an installation with guardrail.record = false. Neither
turns off a run the guardrail judges: that run is still recorded.
A run that was not recorded says so on its run record, with the reason.
The records
A run produces up to five records, kept in different places for different readers.
| record | what it holds | where it lives |
|---|---|---|
| the run record | who, what and where: run id, stream, role, seat, machine, backend, model, times, status, the vendor's session key, and at the end the SHA-256 and size of the raw transcript. No conversation text | the installation's database |
| the live journal | the run's output as it happens — the agent's text, its thinking, its tool calls and their output — redacted, in small chunks, ending with the run's exit status and the digest of the raw transcript | the run's directory on the dispatching machine |
| the model transcript | every request and response that passes through the recorder, each as an event with the original's digest and a redacted copy of its body, chained by hash; blocked exchanges are recorded as withheld, not left out | the run's working directory, on the machine where the agent ran |
| the guardrail audit file | one line per guardrail decision — stage, decision, rule and reason, and each item's digest and size, never its content | .saphan-guardrail/audit.jsonl in the run's working directory |
| the raw transcript | the agent's unmodified output, not redacted | the run's directory on the dispatching machine |
⚠ The raw transcript is the agent's output exactly as written, secrets included. It exists so that the live journal can be checked against it by digest. Do not give viewers access to it. The Sessions screen never shows it — but one console route, a finished run's output stream, replays the raw transcript unredacted when the run has no journal. Restrict console access accordingly.
⚠ The agent is given the recorder's address; it is not confined to it, except where model egress is sealed. An empty model transcript on a run that produced output most likely means its traffic went around the recorder.
The model transcript is written by the guardrail proxy, which is why recording follows the guardrail's coverage: an agent or lane the guardrail does not cover has a run record, a live journal and a raw transcript, but no model transcript.
Live output
For claude-code, the live journal fills as the run progresses only when the installation streams
transcripts:
Otherwise the text arrives when the run ends. The setting applies to runs started with saphan run;
any value other than stream-json means off.
In this section
| page | for |
|---|---|
| Watching and reading | following a run live, and reading it afterwards |
| Integrity and redaction | how a record can be checked, what is redacted and what is not |
| Limits | what is not recorded, and what cannot be read back yet |