Luigit
repositories / smith

smith

There are many coding harnesses - but this one is fast

owned by admin

smith-core/src/content_codec.rs

Raw
//! SMH-SPEC-SPEC0001: Sessions, typed entry content.
//!
//! Version 1 typed entry content. All integers are little endian, strings and
//! JSON spans have u32 byte lengths; JSON alone uses CBOR. No Rust layout is persisted.
use crate::cbor::{Encoder, Header, Write};
use crate::session::{COMPACTION_KIND, EntryContent, EntryContentRef, EntryKind};
use serde::ser::{SerializeSeq, SerializeStruct};
use serde::{Serialize, Serializer};
use smith::error::{Result, SmithError};
use smith::id::{MessageId, ToolCallId};
use smith::message::{ContentBlock, Message, Role};
use smith::structured::{AccessError, Kind, StructuredData, StructuredValue, ToolArguments};

fn invalid(reason: &str) -> SmithError {
    SmithError::Session {
        code: smith::error::SessionCode::EntryDecode,
        message: reason.into(),
    }
}

struct Cursor<'a> {
    bytes: &'a [u8],
}
impl<'a> Cursor<'a> {
    fn take(&mut self, count: usize) -> Result<&'a [u8]> {
        let (head, rest) = self
            .bytes
            .split_at_checked(count)
            .ok_or_else(|| invalid("truncated content span"))?;
        self.bytes = rest;
        Ok(head)
    }
    fn byte(&mut self) -> Result<u8> {
        Ok(self.take(1)?[0])
    }
    fn u32(&mut self) -> Result<u32> {
        Ok(u32::from_le_bytes(
            self.take(4)?
                .try_into()
                .map_err(|_| invalid("truncated u32"))?,
        ))
    }
    fn i64(&mut self) -> Result<i64> {
        Ok(i64::from_le_bytes(
            self.take(8)?
                .try_into()
                .map_err(|_| invalid("truncated i64"))?,
        ))
    }
    fn id(&mut self) -> Result<u128> {
        Ok(u128::from_le_bytes(
            self.take(16)?
                .try_into()
                .map_err(|_| invalid("truncated ID"))?,
        ))
    }
    fn span(&mut self) -> Result<&'a [u8]> {
        let n = self.u32()? as usize;
        self.take(n)
    }
    fn text(&mut self) -> Result<&'a str> {
        std::str::from_utf8(self.span()?).map_err(|_| invalid("invalid UTF-8"))
    }
    fn boolean(&mut self) -> Result<bool> {
        match self.byte()? {
            0 => Ok(false),
            1 => Ok(true),
            _ => Err(invalid("invalid boolean")),
        }
    }
    fn json(&mut self) -> Result<JsonView<'a>> {
        let bytes = self.span()?;
        crate::json_scan::scan(bytes, None)?;
        Ok(JsonView(bytes))
    }
    fn end(&self) -> Result<()> {
        if self.bytes.is_empty() {
            Ok(())
        } else {
            Err(invalid("trailing content bytes"))
        }
    }
}

fn put_span(out: &mut Vec<u8>, bytes: &[u8]) -> Result<()> {
    let len = u32::try_from(bytes.len()).map_err(|_| invalid("content span exceeds u32"))?;
    out.extend_from_slice(&len.to_le_bytes());
    out.extend_from_slice(bytes);
    Ok(())
}
#[derive(Clone, Copy, Debug)]
struct SpanLimit;

/// CBOR sink limited to one length-prefixed JSON span.
struct BoundedOutput<'a> {
    out: &'a mut Vec<u8>,
    start: usize,
    max: usize,
}
impl<'a> BoundedOutput<'a> {
    fn new(out: &'a mut Vec<u8>, max: usize) -> Self {
        Self {
            start: out.len(),
            out,
            max: max.min(u32::MAX as usize),
        }
    }
    const fn len(&self) -> usize {
        self.out.len() - self.start
    }
}
impl Write for BoundedOutput<'_> {
    type Error = SpanLimit;

    fn write_all(&mut self, bytes: &[u8]) -> std::result::Result<(), Self::Error> {
        let Some(len) = self.len().checked_add(bytes.len()) else {
            return Err(SpanLimit);
        };
        if len > self.max {
            return Err(SpanLimit);
        }
        self.out.extend_from_slice(bytes);
        Ok(())
    }

    fn flush(&mut self) -> std::result::Result<(), Self::Error> {
        Ok(())
    }
}

fn put_json<'a, Value: StructuredValue<'a>>(out: &mut Vec<u8>, value: Value) -> Result<()> {
    put_json_bounded(out, value, u32::MAX as usize)
}

fn put_json_bounded<'a, Value: StructuredValue<'a>>(
    out: &mut Vec<u8>,
    value: Value,
    max: usize,
) -> Result<()> {
    let start = out.len();
    out.extend_from_slice(&[0; 4]);
    let result = {
        let sink = BoundedOutput::new(out, max);
        let mut encoder = Encoder::from(sink);
        encode_json(value, &mut encoder)
    };
    if result.is_err() {
        out.truncate(start);
        return Err(invalid("content span exceeds u32"));
    }
    let len = out.len() - start - 4;
    assert!(
        len <= max,
        "bounded encoder wrote beyond its declared limit"
    );
    let Ok(len) = u32::try_from(len) else {
        out.truncate(start);
        return Err(invalid("content span exceeds u32"));
    };
    out[start..start + 4].copy_from_slice(&len.to_le_bytes());
    Ok(())
}

fn encode_json<'a, Value: StructuredValue<'a>>(
    value: Value,
    encoder: &mut Encoder<BoundedOutput<'_>>,
) -> std::result::Result<(), SpanLimit> {
    match value.kind().map_err(|_| SpanLimit)? {
        Kind::Null => encoder.push(Header::Simple(22)),
        Kind::Bool(value) => encoder.push(Header::Simple(if value { 21 } else { 20 })),
        Kind::Signed(value) if value < 0 => {
            encoder.push(Header::Negative((-1 - value).cast_unsigned()))
        }
        Kind::Signed(value) => encoder.push(Header::Positive(value.cast_unsigned())),
        Kind::Unsigned(value) => encoder.push(Header::Positive(value)),
        Kind::Float(value) => encoder.push(Header::Float(value)),
        Kind::String(value) => encoder.text(value, None),
        Kind::Array => {
            let elements = value.elements().map_err(|_| SpanLimit)?.ok_or(SpanLimit)?;
            encoder.push(Header::Array(Some(elements.len())))?;
            for element in elements {
                encode_json(element.map_err(|_| SpanLimit)?, encoder)?;
            }
            Ok(())
        }
        Kind::Object => {
            let fields = value.fields().map_err(|_| SpanLimit)?.ok_or(SpanLimit)?;
            encoder.push(Header::Map(Some(fields.len())))?;
            for field in fields {
                let (key, value) = field.map_err(|_| SpanLimit)?;
                encoder.text(key, None)?;
                encode_json(value, encoder)?;
            }
            Ok(())
        }
    }
}

pub(crate) fn encode(content: &EntryContentRef<'_>, out: &mut Vec<u8>) -> Result<()> {
    match *content {
        EntryContentRef::Message(message) => {
            out.push(0);
            out.extend_from_slice(&message.id.as_u128().to_le_bytes());
            out.push(match message.role {
                Role::User => 0,
                Role::Assistant => 1,
                Role::System => 2,
                Role::Tool => 3,
            });
            out.extend_from_slice(&message.timestamp_ms.to_le_bytes());
            out.extend_from_slice(
                &u32::try_from(message.blocks.len())
                    .map_err(|_| invalid("too many blocks"))?
                    .to_le_bytes(),
            );
            for block in &message.blocks {
                match block {
                    ContentBlock::Text(text) => {
                        out.push(0);
                        put_span(out, text.as_bytes())?;
                    }
                    ContentBlock::Thinking(text) => {
                        out.push(1);
                        put_span(out, text.as_bytes())?;
                    }
                    ContentBlock::ToolUse {
                        name,
                        input,
                        call_id,
                    } => {
                        out.push(2);
                        put_span(out, name.as_bytes())?;
                        put_json(out, input.view())?;
                        out.extend_from_slice(&call_id.as_u128().to_le_bytes());
                    }
                    ContentBlock::ToolResult {
                        call_id,
                        ok,
                        output,
                    } => {
                        out.push(3);
                        out.extend_from_slice(&call_id.as_u128().to_le_bytes());
                        out.push(u8::from(*ok));
                        put_span(out, output.as_bytes())?;
                    }
                }
            }
        }
        EntryContentRef::ToolCall {
            name,
            input,
            call_id,
        } => {
            out.push(1);
            put_span(out, name.as_bytes())?;
            put_json(out, input.view())?;
            out.extend_from_slice(&call_id.as_u128().to_le_bytes());
        }
        EntryContentRef::ToolResult {
            ok,
            output,
            call_id,
        } => {
            out.push(2);
            out.push(u8::from(ok));
            put_span(out, output.as_bytes())?;
            out.extend_from_slice(&call_id.as_u128().to_le_bytes());
        }
        EntryContentRef::Meta { kind, detail } => {
            crate::metadata::validate(kind, detail.view())
                .map_err(|_| invalid("invalid metadata"))?;
            out.push(3);
            put_span(out, kind.as_bytes())?;
            put_json(out, detail.view())?;
        }
    }
    Ok(())
}

/// Validated CBOR JSON span, decoded only at the consumer boundary.
#[derive(Clone, Copy, Debug)]
pub struct JsonView<'a>(pub(crate) &'a [u8]);
impl JsonView<'_> {
    fn owned(self) -> Result<StructuredData> {
        StructuredData::from_serializable(&self).map_err(|error| invalid(&error.to_string()))
    }
    /// Whether any JSON string value contains `pattern`.
    ///
    /// # Panics
    /// Only if the private validated-span invariant is broken.
    #[must_use]
    pub fn contains(self, pattern: &str) -> bool {
        let found = crate::json_scan::scan(self.0, Some(pattern));
        assert!(
            found.is_ok(),
            "validated JSON span remains canonical during string search"
        );
        found.is_ok_and(|found| found)
    }
}
impl<'a> StructuredValue<'a> for JsonView<'a> {
    type Elements = crate::json_scan::Elements<'a>;
    type Fields = crate::json_scan::Fields<'a>;

    fn kind(self) -> std::result::Result<Kind<'a>, AccessError> {
        crate::json_scan::kind(self.0).map_err(|_| AccessError::Malformed)
    }

    fn elements(self) -> std::result::Result<Option<Self::Elements>, AccessError> {
        crate::json_scan::elements(self.0).map_err(|_| AccessError::Malformed)
    }

    fn fields(self) -> std::result::Result<Option<Self::Fields>, AccessError> {
        crate::json_scan::fields(self.0).map_err(|_| AccessError::Malformed)
    }
}
impl Serialize for JsonView<'_> {
    fn serialize<S: Serializer>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error> {
        crate::json_scan::serialize(self.0, serializer)
    }
}

/// A validated block borrowing text directly from an entry content span.
#[derive(Clone, Copy, Debug)]
pub enum BlockView<'a> {
    /// Plain text.
    Text(&'a str),
    /// Internal reasoning.
    Thinking(&'a str),
    /// Structured tool request.
    ToolUse {
        /// Tool name.
        name: &'a str,
        /// Structured input.
        input: JsonView<'a>,
        /// Pairing ID.
        call_id: ToolCallId,
    },
    /// Tool output.
    ToolResult {
        /// Pairing ID.
        call_id: ToolCallId,
        /// Success flag.
        ok: bool,
        /// Recorded output.
        output: &'a str,
    },
}
impl Serialize for BlockView<'_> {
    fn serialize<S: Serializer>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error> {
        #[derive(Serialize)]
        struct Use<'a> {
            name: &'a str,
            input: JsonView<'a>,
            call_id: ToolCallId,
        }
        #[derive(Serialize)]
        struct Result<'a> {
            call_id: ToolCallId,
            ok: bool,
            output: &'a str,
        }
        let mut outer = serializer.serialize_struct("ContentBlock", 2)?;
        match *self {
            Self::Text(t) => {
                outer.serialize_field("type", "Text")?;
                outer.serialize_field("data", t)?;
            }
            Self::Thinking(t) => {
                outer.serialize_field("type", "Thinking")?;
                outer.serialize_field("data", t)?;
            }
            Self::ToolUse {
                name,
                input,
                call_id,
            } => {
                outer.serialize_field("type", "ToolUse")?;
                outer.serialize_field(
                    "data",
                    &Use {
                        name,
                        input,
                        call_id,
                    },
                )?;
            }
            Self::ToolResult {
                call_id,
                ok,
                output,
            } => {
                outer.serialize_field("type", "ToolResult")?;
                outer.serialize_field(
                    "data",
                    &Result {
                        call_id,
                        ok,
                        output,
                    },
                )?;
            }
        }
        outer.end()
    }
}

fn block<'a>(cursor: &mut Cursor<'a>) -> Result<BlockView<'a>> {
    Ok(match cursor.byte()? {
        0 => BlockView::Text(cursor.text()?),
        1 => BlockView::Thinking(cursor.text()?),
        2 => BlockView::ToolUse {
            name: cursor.text()?,
            input: cursor.json()?,
            call_id: ToolCallId::from_u128(cursor.id()?),
        },
        3 => BlockView::ToolResult {
            call_id: ToolCallId::from_u128(cursor.id()?),
            ok: cursor.boolean()?,
            output: cursor.text()?,
        },
        _ => return Err(invalid("invalid block tag")),
    })
}

/// Iterator over blocks in a previously validated message span.
#[derive(Clone, Debug)]
pub struct Blocks<'a> {
    cursor: &'a [u8],
    left: u32,
}
impl<'a> Iterator for Blocks<'a> {
    type Item = BlockView<'a>;
    #[expect(
        clippy::expect_used,
        reason = "Blocks only holds spans fully traversed by decode"
    )]
    fn next(&mut self) -> Option<Self::Item> {
        if self.left == 0 {
            return None;
        }
        let mut cursor = Cursor { bytes: self.cursor };
        let block = block(&mut cursor).expect("validated block span");
        self.cursor = cursor.bytes;
        self.left -= 1;
        Some(block)
    }
    fn size_hint(&self) -> (usize, Option<usize>) {
        (self.left as usize, Some(self.left as usize))
    }
}
impl ExactSizeIterator for Blocks<'_> {}

/// Validated message metadata with zero-copy block iteration.
#[derive(Clone, Debug)]
pub struct MessageView<'a> {
    /// Stable message identifier.
    pub id: MessageId,
    /// Sender role.
    pub role: Role,
    /// Timestamp in Unix milliseconds.
    pub timestamp_ms: i64,
    blocks: Blocks<'a>,
}
impl<'a> MessageView<'a> {
    /// Iterate message blocks without allocating.
    pub fn blocks(&self) -> Blocks<'a> {
        self.blocks.clone()
    }
}
impl Serialize for MessageView<'_> {
    fn serialize<S: Serializer>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error> {
        struct Sequence<'a>(Blocks<'a>);
        impl Serialize for Sequence<'_> {
            fn serialize<S: Serializer>(
                &self,
                serializer: S,
            ) -> std::result::Result<S::Ok, S::Error> {
                let mut seq = serializer.serialize_seq(Some(self.0.len()))?;
                for block in self.0.clone() {
                    seq.serialize_element(&block)?;
                }
                seq.end()
            }
        }
        let mut out = serializer.serialize_struct("Message", 4)?;
        out.serialize_field("id", &self.id)?;
        out.serialize_field("role", &self.role)?;
        out.serialize_field("blocks", &Sequence(self.blocks()))?;
        out.serialize_field("timestamp_ms", &self.timestamp_ms)?;
        out.end()
    }
}

/// Content decoded from bytes, distinct from the recording-time borrowed Rust view.
#[derive(Clone, Debug)]
pub enum EntryContentView<'a> {
    /// Message with block spans.
    Message(MessageView<'a>),
    /// Tool invocation.
    ToolCall {
        /// Tool name.
        name: &'a str,
        /// Structured input.
        input: JsonView<'a>,
        /// Pairing ID.
        call_id: ToolCallId,
    },
    /// Tool completion.
    ToolResult {
        /// Success flag.
        ok: bool,
        /// Recorded output.
        output: &'a str,
        /// Pairing ID.
        call_id: ToolCallId,
    },
    /// Metadata event.
    Meta {
        /// Metadata kind.
        kind: &'a str,
        /// Structured detail.
        detail: JsonView<'a>,
    },
}
impl<'a> EntryContentView<'a> {
    /// Validate every tag, length, nested value and trailing byte before returning a view.
    ///
    /// # Errors
    /// Returns `ENTRY_DECODE` for malformed content.
    pub fn decode(bytes: &'a [u8]) -> Result<Self> {
        let mut cursor = Cursor { bytes };
        let value = match cursor.byte()? {
            0 => {
                let id = MessageId::from_u128(cursor.id()?);
                let role = match cursor.byte()? {
                    0 => Role::User,
                    1 => Role::Assistant,
                    2 => Role::System,
                    3 => Role::Tool,
                    _ => return Err(invalid("invalid message role")),
                };
                let timestamp_ms = cursor.i64()?;
                let count = cursor.u32()?;
                let blocks = Blocks {
                    cursor: cursor.bytes,
                    left: count,
                };
                for _ in 0..count {
                    block(&mut cursor)?;
                }
                Self::Message(MessageView {
                    id,
                    role,
                    timestamp_ms,
                    blocks,
                })
            }
            1 => Self::ToolCall {
                name: cursor.text()?,
                input: cursor.json()?,
                call_id: ToolCallId::from_u128(cursor.id()?),
            },
            2 => Self::ToolResult {
                ok: cursor.boolean()?,
                output: cursor.text()?,
                call_id: ToolCallId::from_u128(cursor.id()?),
            },
            3 => {
                let kind = cursor.text()?;
                let detail = cursor.json()?;
                crate::metadata::validate(kind, detail).map_err(|_| invalid("invalid metadata"))?;
                Self::Meta { kind, detail }
            }
            _ => return Err(invalid("invalid content tag")),
        };
        cursor.end()?;
        Ok(value)
    }

    /// Traversal metadata derived from validated content.
    #[must_use]
    pub fn kind(&self) -> EntryKind {
        match self {
            Self::Message(m) => EntryKind::Message {
                id: m.id,
                role: m.role,
            },
            Self::ToolCall { call_id, .. } => EntryKind::ToolCall { call_id: *call_id },
            Self::ToolResult { call_id, ok, .. } => EntryKind::ToolResult {
                call_id: *call_id,
                ok: *ok,
            },
            Self::Meta { kind, .. } => EntryKind::Meta {
                compaction: *kind == COMPACTION_KIND,
            },
        }
    }

    /// Match against recorded string values (not keys).
    #[must_use]
    pub fn contains(&self, pattern: &str) -> bool {
        match self {
            Self::Message(m) => m.blocks().any(|b| match b {
                BlockView::Text(s) | BlockView::Thinking(s) => s.contains(pattern),
                BlockView::ToolUse { name, input, .. } => {
                    name.contains(pattern) || input.contains(pattern)
                }
                BlockView::ToolResult { output, .. } => output.contains(pattern),
            }),
            Self::ToolCall { name, input, .. } => name.contains(pattern) || input.contains(pattern),
            Self::ToolResult { output, .. } => output.contains(pattern),
            Self::Meta { kind, detail } => kind.contains(pattern) || detail.contains(pattern),
        }
    }

    /// Materialize content for agent context, replay or API consumers.
    ///
    /// # Errors
    /// Returns `ENTRY_DECODE` if structured data cannot be materialized.
    pub fn to_owned(&self) -> Result<EntryContent> {
        Ok(match self {
            Self::Message(m) => {
                let mut blocks = Vec::with_capacity(m.blocks.len());
                for block in m.blocks() {
                    blocks.push(match block {
                        BlockView::Text(text) => ContentBlock::Text(text.to_owned()),
                        BlockView::Thinking(text) => ContentBlock::Thinking(text.to_owned()),
                        BlockView::ToolUse {
                            name,
                            input,
                            call_id,
                        } => ContentBlock::ToolUse {
                            name: name.to_owned(),
                            input: ToolArguments::from_data(input.owned()?),
                            call_id,
                        },
                        BlockView::ToolResult {
                            call_id,
                            ok,
                            output,
                        } => ContentBlock::ToolResult {
                            call_id,
                            ok,
                            output: output.to_owned(),
                        },
                    });
                }
                EntryContent::Message(Message {
                    id: m.id,
                    role: m.role,
                    timestamp_ms: m.timestamp_ms,
                    blocks,
                })
            }
            Self::ToolCall {
                name,
                input,
                call_id,
            } => EntryContent::ToolCall {
                name: (*name).to_owned(),
                input: ToolArguments::from_data(input.owned()?),
                call_id: *call_id,
            },
            Self::ToolResult {
                ok,
                output,
                call_id,
            } => EntryContent::ToolResult {
                ok: *ok,
                output: (*output).to_owned(),
                call_id: *call_id,
            },
            Self::Meta { kind, detail } => EntryContent::Meta {
                kind: (*kind).to_owned(),
                detail: detail.owned()?,
            },
        })
    }
}
impl Serialize for EntryContentView<'_> {
    fn serialize<S: Serializer>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error> {
        #[derive(Serialize)]
        struct Invocation<'a> {
            name: &'a str,
            input: JsonView<'a>,
            call_id: ToolCallId,
        }
        #[derive(Serialize)]
        struct Result<'a> {
            ok: bool,
            output: &'a str,
            call_id: ToolCallId,
        }
        #[derive(Serialize)]
        struct Meta<'a> {
            kind: &'a str,
            detail: JsonView<'a>,
        }
        let mut out = serializer.serialize_struct("EntryContent", 2)?;
        match self {
            Self::Message(m) => {
                out.serialize_field("kind", "Message")?;
                out.serialize_field("data", m)?;
            }
            Self::ToolCall {
                name,
                input,
                call_id,
            } => {
                out.serialize_field("kind", "ToolCall")?;
                out.serialize_field(
                    "data",
                    &Invocation {
                        name,
                        input: *input,
                        call_id: *call_id,
                    },
                )?;
            }
            Self::ToolResult {
                ok,
                output,
                call_id,
            } => {
                out.serialize_field("kind", "ToolResult")?;
                out.serialize_field(
                    "data",
                    &Result {
                        ok: *ok,
                        output,
                        call_id: *call_id,
                    },
                )?;
            }
            Self::Meta { kind, detail } => {
                out.serialize_field("kind", "Meta")?;
                out.serialize_field(
                    "data",
                    &Meta {
                        kind,
                        detail: *detail,
                    },
                )?;
            }
        }
        out.end()
    }
}

#[cfg(test)]
mod tests {
    //! SMH-SPEC-SPEC0001: Sessions, typed content and bounded access.
    use super::*;
    use crate::session::EntryFrame;
    use proptest::prelude::*;
    use serde::Serialize;
    use smith_alloc::{Counting, Scope, measure};
    use std::sync::Mutex;

    #[global_allocator]
    static ALLOC: Counting = Counting;
    static MEASURING: Mutex<()> = Mutex::new(());

    #[test]
    fn materialized_message_reserves_exact_validated_block_count() {
        let mut message = Message::with_text(Role::User, "0");
        for block in 1..7 {
            message.add_block(ContentBlock::Text(block.to_string()));
        }
        let mut bytes = Vec::new();
        encode(&EntryContentRef::Message(&message), &mut bytes).unwrap();
        let EntryContent::Message(owned) = EntryContentView::decode(&bytes)
            .unwrap()
            .to_owned()
            .unwrap()
        else {
            panic!("message kind must survive materialization");
        };
        assert_eq!(owned, message);
        assert_eq!(owned.blocks.len(), 7);
        assert_eq!(owned.blocks.capacity(), 7);
    }

    #[test]
    fn borrowed_arguments_validate_and_traverse_without_allocations() {
        let arguments = ToolArguments::from_json(
            r#"{"path":"notes.txt","limit":18446744073709551615,"items":[null,true,-0.0]}"#,
        )
        .unwrap()
        .canonicalized(64)
        .unwrap();
        let schema = smith::ToolSchema::object(
            &[("path", "string"), ("limit", "integer"), ("items", "array")],
            &["path"],
        );
        let mut bytes = Vec::new();
        encode(
            &EntryContentRef::ToolCall {
                name: "read",
                input: &arguments,
                call_id: ToolCallId::from_u128(1),
            },
            &mut bytes,
        )
        .unwrap();
        let EntryContentView::ToolCall { input, .. } = EntryContentView::decode(&bytes).unwrap()
        else {
            panic!("tool call must retain argument view");
        };
        let _serial = MEASURING
            .lock()
            .unwrap_or_else(std::sync::PoisonError::into_inner);
        let ((), cost) = measure(Scope::Session, || {
            schema.validate(input).unwrap();
            assert_eq!(input.fields().unwrap().unwrap().len(), 3);
            let Kind::String(path) = input.field("path").unwrap().unwrap().kind().unwrap() else {
                panic!("path must remain a string");
            };
            assert_eq!(path, "notes.txt");
            let resident = (bytes.as_ptr() as usize)..(bytes.as_ptr() as usize + bytes.len());
            assert!(resident.contains(&(path.as_ptr() as usize)));
            assert_eq!(
                input.field("limit").unwrap().unwrap().kind().unwrap(),
                Kind::Unsigned(u64::MAX)
            );
            let mut items = input
                .field("items")
                .unwrap()
                .unwrap()
                .elements()
                .unwrap()
                .unwrap();
            assert_eq!(items.len(), 3);
            assert_eq!(items.next().unwrap().unwrap().kind().unwrap(), Kind::Null);
            assert_eq!(items.len(), 2);
            assert_eq!(
                items.next().unwrap().unwrap().kind().unwrap(),
                Kind::Bool(true)
            );
            let Kind::Float(zero) = items.next().unwrap().unwrap().kind().unwrap() else {
                panic!("negative zero must remain a float");
            };
            assert_eq!(zero.to_bits(), (-0.0_f64).to_bits());
            assert_eq!(items.len(), 0);
            assert!(items.next().is_none());
        });
        assert_eq!(cost.allocations, 0);
        assert_eq!(cost.bytes, 0);
        assert_eq!(cost.peak, 0);
        assert_eq!(std::mem::size_of::<JsonView<'_>>(), 16);
        assert_eq!(std::mem::size_of::<crate::json_scan::Elements<'_>>(), 24);
        assert_eq!(std::mem::size_of::<crate::json_scan::Fields<'_>>(), 40);
    }

    #[test]
    fn json_encoding_uses_existing_output_capacity() {
        let value =
            StructuredData::from_serializable(&serde_json::json!({"b": [1, 2, 3], "aa": "value"}))
                .unwrap();
        let mut bytes = Vec::with_capacity(128);
        let _serial = MEASURING
            .lock()
            .unwrap_or_else(std::sync::PoisonError::into_inner);
        let (result, cost) = measure(Scope::Session, || put_json(&mut bytes, value.view()));
        result.unwrap();
        assert_eq!(cost.allocations, 0);
        assert_eq!(cost.bytes, 0);
    }

    #[test]
    fn bounded_output_writes_short_and_exact_spans() {
        let mut bytes = vec![9];
        {
            let mut sink = BoundedOutput::new(&mut bytes, 3);
            sink.write_all(&[1]).unwrap();
            sink.write_all(&[2, 3]).unwrap();
            assert_eq!(sink.len(), 3);
        }
        assert_eq!(bytes, [9, 1, 2, 3]);
    }

    #[test]
    fn bounded_output_rejects_over_limit_without_appending() {
        let mut bytes = vec![9];
        {
            let mut sink = BoundedOutput::new(&mut bytes, 2);
            assert!(sink.write_all(&[1, 2, 3]).is_err());
            assert_eq!(sink.len(), 0);
        }
        assert_eq!(bytes, [9]);
    }

    #[test]
    fn json_encoding_rolls_back_on_span_limit() {
        let mut bytes = vec![9];
        let value = StructuredData::from_json("\"x\"").unwrap();
        assert!(put_json_bounded(&mut bytes, value.view(), 1).is_err());
        assert_eq!(bytes, [9]);
    }

    #[test]
    fn structured_value_wire_bytes_match_v4_golden_contract() {
        let value = StructuredData::from_serializable(&serde_json::json!([
            -1,
            0,
            23,
            24,
            255,
            256,
            65_535,
            65_536,
            i64::MIN,
            u64::MAX,
            -0.0,
            1.5,
            1.1,
            {"b": 1, "aa": 2},
        ]))
        .unwrap();
        let mut bytes = Vec::new();
        put_json(&mut bytes, value.view()).unwrap();
        assert_eq!(
            bytes,
            [
                60, 0, 0, 0, 0x8e, 0x20, 0x00, 0x17, 0x18, 0x18, 0x18, 0xff, 0x19, 0x01, 0x00,
                0x19, 0xff, 0xff, 0x1a, 0x00, 0x01, 0x00, 0x00, 0x3b, 0x7f, 0xff, 0xff, 0xff, 0xff,
                0xff, 0xff, 0xff, 0x1b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0x80,
                0x00, 0xf9, 0x3e, 0x00, 0xfb, 0x3f, 0xf1, 0x99, 0x99, 0x99, 0x99, 0x99, 0x9a, 0xa2,
                0x61, b'b', 0x01, 0x62, b'a', b'a', 0x02,
            ]
        );
    }

    proptest! {
        #[test]
        fn encoded_json_scalars_round_trip_with_numeric_kind(value in prop_oneof![
            any::<bool>().prop_map(serde_json::Value::Bool),
            any::<i64>().prop_map(serde_json::Value::from),
            any::<u64>().prop_map(serde_json::Value::from),
            any::<f64>().prop_filter_map("finite JSON number", serde_json::Number::from_f64)
                .prop_map(serde_json::Value::Number),
            ".{0,64}".prop_map(serde_json::Value::String),
        ]) {
            let mut bytes = Vec::new();
            let expected = value.clone();
            let value = StructuredData::from_serializable(&value).unwrap();
            put_json(&mut bytes, value.view()).unwrap();
            let encoded = &bytes[4..];
            prop_assert!(crate::json_scan::scan(encoded, None).is_ok());
            prop_assert_eq!(
                crate::json_scan::serialize(encoded, serde_json::value::Serializer).unwrap(),
                expected,
            );
        }
    }

    #[test]
    fn rejects_duplicate_json_keys_before_search_or_materialization() {
        let mut bytes = vec![3, 1, 0, 0, 0, b'k', 7, 0, 0, 0];
        bytes.extend_from_slice(&[0xa2, 0x61, b'a', 1, 0x61, b'a', 2]);
        assert_eq!(
            EntryContentView::decode(&bytes).unwrap_err().code(),
            "ENTRY_DECODE"
        );
    }

    #[test]
    fn borrowed_known_metadata_validation_allocates_nothing() {
        let tool = crate::metadata::encode(&crate::metadata::ToolMutationMetadata::new(
            ToolCallId::from_u128(1),
            smith::error::MutationState::Applied,
        ))
        .unwrap();
        let compaction = crate::metadata::encode(&crate::metadata::CompactionMetadata {
            summary: "summary".to_string(),
            complete: Some(true),
        })
        .unwrap();
        let provider = StructuredData::from_json(
            r#"{"phase":"outcome","status":0,"response_bytes":0,"outcome":"completed"}"#,
        )
        .unwrap();
        for (kind, detail) in [
            (COMPACTION_KIND, compaction),
            (crate::session::TOOL_MUTATION_KIND, tool),
            (crate::session::PROVIDER_HTTP_KIND, provider),
        ] {
            let bytes = EntryFrame::new(
                None,
                &EntryContent::Meta {
                    kind: kind.to_string(),
                    detail,
                },
            )
            .unwrap()
            .content;
            let EntryContentView::Meta { kind, detail } = EntryContentView::decode(&bytes).unwrap()
            else {
                panic!("metadata must retain a borrowed view");
            };
            let _serial = MEASURING
                .lock()
                .unwrap_or_else(std::sync::PoisonError::into_inner);
            let (result, cost) =
                measure(Scope::Session, || crate::metadata::validate(kind, detail));
            assert!(result.is_ok());
            assert_eq!(cost.allocations, 0, "{kind} validation allocated");
            assert_eq!(cost.bytes, 0, "{kind} validation allocated bytes");
        }
    }

    #[test]
    fn reserved_metadata_rejects_malformed_owned_and_borrowed_shapes() {
        let malformed = StructuredData::from_json(r#"{"summary":false}"#).unwrap();
        assert!(
            EntryFrame::new(
                None,
                &EntryContent::Meta {
                    kind: COMPACTION_KIND.to_string(),
                    detail: malformed,
                },
            )
            .is_err()
        );

        let bytes = [
            3, 10, 0, 0, 0, b'c', b'o', b'm', b'p', b'a', b'c', b't', b'i', b'o', b'n', 10, 0, 0,
            0, 0xa1, 0x67, b's', b'u', b'm', b'm', b'a', b'r', b'y', 0xf4,
        ];
        assert!(EntryContentView::decode(&bytes).is_err());
    }

    #[test]
    fn json_view_serialization_streams_without_materializing_json() {
        let detail = StructuredData::from_serializable(&serde_json::Value::Array(vec![
            serde_json::Value::from(-1),
            serde_json::Value::from(u64::MAX),
            serde_json::Value::Number(serde_json::Number::from_f64(-0.0).unwrap()),
            serde_json::Value::Number(serde_json::Number::from_f64(1.1).unwrap()),
        ]))
        .unwrap();
        let expected = serde_json::to_value(&detail).unwrap();
        let bytes = EntryFrame::new(
            None,
            &EntryContent::Meta {
                kind: "event".into(),
                detail,
            },
        )
        .unwrap()
        .content;
        let EntryContentView::Meta { detail, .. } = EntryContentView::decode(&bytes).unwrap()
        else {
            unreachable!();
        };
        let mut output = Vec::with_capacity(128);
        let _serial = MEASURING
            .lock()
            .unwrap_or_else(std::sync::PoisonError::into_inner);
        let (result, cost) = measure(Scope::Session, || {
            let mut serializer = serde_json::Serializer::new(&mut output);
            detail.serialize(&mut serializer)
        });
        result.unwrap();
        assert_eq!(
            cost.allocations, 0,
            "streaming JSON allocated {} times",
            cost.allocations
        );
        let values: serde_json::Value = serde_json::from_slice(&output).unwrap();
        let values = values.as_array().unwrap();
        assert_eq!(values[0].as_i64(), Some(-1));
        assert_eq!(values[1].as_u64(), Some(u64::MAX));
        assert!(values[2].as_f64().unwrap().is_sign_negative());
        assert_eq!(values[3].as_f64(), Some(1.1));
        let EntryContent::Meta { detail, .. } = EntryContentView::decode(&bytes)
            .unwrap()
            .to_owned()
            .unwrap()
        else {
            unreachable!();
        };
        let detail = serde_json::to_value(&detail).unwrap();
        assert_eq!(detail[0].as_i64(), Some(-1));
        assert_eq!(detail[1].as_u64(), Some(u64::MAX));
        assert!(detail[2].as_f64().unwrap().is_sign_negative());
        assert_eq!(detail, expected);
    }
}