pub enum Record {
Meta(SessionMeta),
Message(Message),
Summary {
usage: Usage,
turns: u32,
},
Config(RunConfig),
Taint(Taint),
Rewrite {
messages: Vec<Message>,
},
}Variants§
Meta(SessionMeta)
Message(Message)
Summary
Written when a run finishes, so sessions show can report cost without
replaying the whole transcript.
Config(RunConfig)
Everything that shaped the request, written each time a process attaches to the session — on creation and again on every resume.
Not folded into the header, because a session resumed under different flags would make a header written at creation a lie about every turn after the first. Within one process the configuration cannot change, so one record per attach is exactly the granularity that can differ.
Taint(Taint)
What had entered the conversation by this point.
Recorded because it cannot be recovered by reading the transcript back: taint keys off provenance — whether a result actually came from outside — and the transcript stores only the content. Without this, resuming a session that had read a hostile page would hand the model that page again with the interlock disarmed.
Rewrite
The conversation’s messages were rewritten in place — compaction
summarised the head, eviction replaced a stale result, thinning
shortened an old one. An append-only file cannot express an in-place
rewrite as more Message records: slicing “what the run added” off
the end of a rewritten list skips the rebuilt head, which is exactly
where the compaction summary lives, and every trace of the rewrite
with it — a 2026-08-07 benchmark transcript recorded 8 assistant turns
of a 28-turn run that way, starting mid-conversation with no sign a
compaction had ever happened. So the record carries the whole current
list, and Session::load replaces what it has accumulated so far.