Skip to main content

REASONING_METADATA_KEYS

Constant REASONING_METADATA_KEYS 

Source
pub const REASONING_METADATA_KEYS: &[&str];
Expand description

ChatMessage::metadata keys that carry a source model’s private reasoning/thinking payload — populated today by Session’s foreign- format importers:

  • Claude Code / Codex legacy singular fields (session.rs’s push_claude_assistant/Codex reasoning response_item handling): "thinking"/"thinking_signature"/"redacted_thinking"/ "reasoning"/"reasoning_content"/"reasoning_encrypted".
  • "thinking_blocks" — the Claude Code importer’s exact per-block replay list (session.rs:3475-3480, push_claude_assistant): every thinking/redacted_thinking content block preserved SEPARATELY, in order, each with its own signature/data, as a serialized JSON array. REVIEW FINDING (P4c dep 8, MEDIUM, proven): the Claude Code EXPORTER (session.rs’s to_claude_code_jsonl, ~5654-5676) PREFERS this key over the legacy singular fields whenever present — so leaving it out of this list let a full signed chain-of-thought survive switch_model untouched and get re-emitted, re-attributed to model-B, on the very next Claude Code export. Added here to close that hole.
  • "pi_thought_signature" — pi’s per-toolCall-block thoughtSignature (Google-provider reasoning-continuity token, session.rs:4248-4249 import / session.rs:7418-7419 export as pi_assistant_content_value re-emits it onto every toolCall block, independent of whether any thinking/thinking_blocks key is even present on the message). Audited in alongside the fix above: like redacted_thinking, its payload is opaque/encrypted rather than literal text, but this crate already treats “opaque encrypted reasoning artifact” as reasoning- bearing for redacted_thinkingpi_thought_signature is the same class of thing (Google’s opaque encoded reasoning trace tied to a tool call), just pi-namespaced (docs/interop/research/pi-fields.md:161 groups it under “provider replay signatures” alongside thinking_signature). Deliberately NOT added: pi_text_signature (session.rs:4219-4224/4271-4272, OpenAI Responses replay-continuity id for a text block whose content is already fully exposed via msg.content — pi-fields.md’s own per-field note calls it “replay- continuity residue”, not a reasoning payload) and pi_thinking_redacted (session.rs:4267-4269, a bare boolean flag with no payload of its own — and inert regardless, since pi_assistant_content_value only ever reads it from inside the if let Some(thinking) = ... arm gated on the now-stripped "thinking" key, so it can never reach an export on its own). Stripping either would be over-stripping non-reasoning metadata for no leak-closing benefit.

metadata itself is never serialized onto the wire (ChatMessage’s custom Serialize impl omits it — see message.rs), so this list is a DEFENSE-IN-DEPTH filter, not the primary leak-prevention mechanism: the primary one is that metadata never reaches a provider request at all, regardless of this function. What this filter actually guarantees is the OBSERVABLE contract dep 8 asks for — a post-switch inspection of history (the in-memory session state, sidecar exports, /export, a future translator emitting this session under another harness’s format) never shows model-A’s reasoning attributed to a conversation now being driven by model-B.