master
Drew Owens Share frozen native Rust mechanical development checkpoint and qualification scope b2d7cdb 26d ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764
//! Bounded, process-local observations around durable journal claims.
//!
//! Use one wrapper for the lifetime of a registered Journal. Only a returned
//! ExecutionPermit authorizes a first effect; status and observations never do.
//! Native code runs between start and finish, with no retention lock held.

use crate::{error, AdmissionClaim, DispatchClaim, Error, Journal, Result};
use fusion_mechanical_core::PreparedRequest;
use serde::Serialize;
use serde_json::Value;
use std::collections::BTreeMap;
use std::io::{self, Write};
use std::sync::{Arc, Mutex, OnceLock, Weak};

const MAX_ENTRIES: usize = 256;
const MAX_RESULT_BYTES: usize = 1024 * 1024;
const MAX_RESERVED_BYTES: usize = 16 * 1024 * 1024;
const MAX_REGISTRATIONS: usize = 256;
const MAX_ERROR_BYTES: usize = 1024;

#[derive(Debug, Clone, Copy)]
pub struct RetentionLimits {
    pub max_entries: usize,
    pub max_result_bytes: usize,
    pub max_reserved_bytes: usize,
}
impl Default for RetentionLimits {
    fn default() -> Self {
        Self {
            max_entries: 64,
            max_result_bytes: 256 * 1024,
            max_reserved_bytes: MAX_RESERVED_BYTES,
        }
    }
}
impl RetentionLimits {
    fn validate(self) -> Result<Self> {
        if !(1..=MAX_ENTRIES).contains(&self.max_entries)
            || !(1..=MAX_RESULT_BYTES).contains(&self.max_result_bytes)
            || !(self.max_result_bytes..=MAX_RESERVED_BYTES).contains(&self.max_reserved_bytes)
        {
            return Err(error(
                "operation_retention_invalid",
                "Retention limits exceed hard bounds or cannot reserve one result.",
            ));
        }
        Ok(self)
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum Authority {
    DurableTerminal,
    ObservedNondurable,
    Pending,
    Unknown,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum ObservedOutcome {
    Succeeded,
    Failed,
    NotExecuted,
    Unknown,
}

#[derive(Debug, Clone, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Observation {
    pub session_id: String,
    pub operation_id: String,
    pub request_digest: String,
    pub dispatch_id: String,
    pub outcome: ObservedOutcome,
    /// Exact observed JSON, or None when the payload exceeded the bound.
    pub result: Option<Value>,
    pub payload_omitted: bool,
}

/// Errors retain bounded diagnostics for trusted callers. HTTP adapters must
/// project error codes only: journal messages can contain storage paths.
#[derive(Debug, Clone)]
pub struct Status {
    pub durable: Option<crate::Status>,
    pub observed: Option<Observation>,
    pub storage_error: Option<Error>,
    pub retention_error: Option<Error>,
    pub authority: Authority,
    pub historical: bool,
    pub reconciliation_required: bool,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum Persistence {
    Committed,
    Unconfirmed,
}

#[derive(Debug, Clone)]
pub struct Completion {
    pub observation: Observation,
    pub persistence: Persistence,
    pub persistence_error: Option<Error>,
}

#[derive(Debug)]
pub enum Admission {
    Created(AdmissionToken),
    /// Evidence only. This variant never authorizes another dispatch/effect.
    Existing(Status),
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum Stage {
    Admitting,
    Admitted,
    Dispatching,
    Dispatched,
    Starting,
    Executing,
    Observed,
    Existing,
    Unknown,
}

#[derive(Clone)]
struct StoredObservation {
    dispatch_id: String,
    outcome: ObservedOutcome,
    // Exact JSON bytes, not a potentially disproportionate heap Value graph.
    bytes: Option<Arc<Vec<u8>>>,
}
#[derive(Clone)]
struct Entry {
    digest: String,
    stage: Stage,
    dispatch_id: Option<String>,
    observed: Option<StoredObservation>,
    failure: Option<Error>,
}
struct State {
    entries: BTreeMap<String, Entry>,
    reserved_bytes: usize,
}
struct Inner {
    journal: Journal,
    limits: RetentionLimits,
    state: Mutex<State>,
}

#[derive(Clone)]
pub struct RetainedJournal {
    inner: Arc<Inner>,
}

/// Non-cloneable ownership of a reserved operation's next lifecycle step.
struct Lease<C> {
    owner: Weak<Inner>,
    operation: String,
    digest: String,
    claim: Option<C>,
}
impl<C> std::fmt::Debug for Lease<C> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.debug_struct("RetainedClaim")
            .field("operation", &self.operation)
            .finish_non_exhaustive()
    }
}
impl<C> Drop for Lease<C> {
    fn drop(&mut self) {
        if self.claim.is_some() {
            if let Some(owner) = self.owner.upgrade() {
                if let Ok(mut state) = owner.state.lock() {
                    if let Some(entry) = state.entries.get_mut(&self.operation) {
                        // A dropped permit cannot prove whether a native effect
                        // happened. Keep the reservation and refuse replay.
                        if entry.observed.is_none() {
                            entry.stage = Stage::Unknown;
                        }
                    }
                }
            }
        }
    }
}
#[derive(Debug)]
pub struct AdmissionToken(Lease<AdmissionClaim>);
#[derive(Debug)]
pub struct DispatchToken(Lease<DispatchClaim>);
#[derive(Debug)]
pub struct ExecutionPermit(Lease<DispatchClaim>);

// Tracking uses Weak references, does not prolong Journal lifetimes, and has a
// separate finite bound. Even dropping a wrapper cannot reset its domain while
// an underlying Journal clone remains live. Only Clone shares a registration.
static REGISTRATIONS: OnceLock<Mutex<Vec<Weak<crate::Inner>>>> = OnceLock::new();

fn lock_error() -> Error {
    error(
        "operation_retention_unavailable",
        "Retention state lock was poisoned; no claims are available.",
    )
}
fn uncertain(mut failure: Error) -> Error {
    failure.reconciliation_required = true;
    if failure.message.len() > MAX_ERROR_BYTES {
        let mut end = MAX_ERROR_BYTES;
        while !failure.message.is_char_boundary(end) {
            end -= 1;
        }
        failure.message = failure.message[..end].to_owned();
    }
    failure
}
fn conflict() -> Error {
    error(
        "operation_conflict",
        "Operation identity, owner, or lifecycle token does not match its reserved slot.",
    )
}

impl RetainedJournal {
    pub fn new(journal: Journal, limits: RetentionLimits) -> Result<Self> {
        let limits = limits.validate()?;
        let mut registrations = REGISTRATIONS
            .get_or_init(|| Mutex::new(Vec::new()))
            .lock()
            .map_err(|_| lock_error())?;
        registrations.retain(|weak| weak.strong_count() != 0);
        let identity = Arc::downgrade(&journal.inner);
        if registrations.iter().any(|weak| weak.ptr_eq(&identity)) {
            return Err(error("operation_retention_registered", "This Journal registration already has a retention owner; clone that owner instead."));
        }
        if registrations.len() >= MAX_REGISTRATIONS {
            return Err(error(
                "operation_retention_capacity",
                "The bounded live retention registration table is full.",
            ));
        }
        registrations.push(identity);
        Ok(Self {
            inner: Arc::new(Inner {
                journal,
                limits,
                state: Mutex::new(State {
                    entries: BTreeMap::new(),
                    reserved_bytes: 0,
                }),
            }),
        })
    }

    pub fn session_id(&self) -> &str {
        self.inner.journal.session_id()
    }

    pub fn admit(&self, request: &PreparedRequest, at_ms: u64) -> Result<Admission> {
        if !request.is_write() {
            return Err(error(
                "operation_record_invalid",
                "Read-only requests cannot reserve effect claims.",
            ));
        }
        let session = request.arguments()["sessionId"]
            .as_str()
            .ok_or_else(conflict)?;
        if session != self.session_id() {
            return Err(error(
                "session_mismatch",
                "Historical sessions cannot reserve new effects.",
            ));
        }
        let operation = request.arguments()["operationId"]
            .as_str()
            .ok_or_else(conflict)?;
        crate::bounded_id(operation)?;
        let digest = crate::request_digest(request.canonical_bytes());
        let existing = {
            let mut state = self.inner.state.lock().map_err(|_| lock_error())?;
            if let Some(entry) = state.entries.get(operation) {
                if entry.digest != digest {
                    return Err(conflict());
                }
                true
            } else {
                let total = state
                    .reserved_bytes
                    .checked_add(self.inner.limits.max_result_bytes)
                    .ok_or_else(conflict)?;
                if state.entries.len() >= self.inner.limits.max_entries
                    || total > self.inner.limits.max_reserved_bytes
                {
                    return Err(error("operation_retention_capacity", "Observed-result slots or reserved bytes are full; no admission or native effect is allowed."));
                }
                state.entries.insert(
                    operation.into(),
                    Entry {
                        digest: digest.clone(),
                        stage: Stage::Admitting,
                        dispatch_id: None,
                        observed: None,
                        failure: None,
                    },
                );
                state.reserved_bytes = total;
                false
            }
        };
        if existing {
            return self.status(session, operation).map(Admission::Existing);
        }
        match self.inner.journal.admit(request, at_ms) {
            Ok(crate::Admission::Created(claim)) => {
                self.update(operation, Stage::Admitted, None)?;
                Ok(Admission::Created(AdmissionToken(
                    self.lease(operation, &digest, claim),
                )))
            }
            Ok(crate::Admission::Existing(_)) => {
                self.update(operation, Stage::Existing, None)?;
                self.status(session, operation).map(Admission::Existing)
            }
            Err(failure) => {
                self.update(operation, Stage::Unknown, Some(failure.clone()))?;
                Err(failure)
            }
        }
    }

    pub fn dispatch(
        &self,
        mut token: AdmissionToken,
        dispatch_id: &str,
        at_ms: u64,
    ) -> Result<DispatchToken> {
        crate::bounded_id(dispatch_id)?;
        let claim = self.take(&mut token.0, Stage::Admitted, Stage::Dispatching)?;
        match self.inner.journal.dispatch(&claim, dispatch_id, at_ms) {
            Ok(crate::DispatchOutcome::Claimed(claim)) => {
                let mut state = self.inner.state.lock().map_err(|_| lock_error())?;
                let entry = state
                    .entries
                    .get_mut(&token.0.operation)
                    .ok_or_else(conflict)?;
                entry.stage = Stage::Dispatched;
                entry.dispatch_id = Some(dispatch_id.into());
                Ok(DispatchToken(self.lease(
                    &token.0.operation,
                    &token.0.digest,
                    claim,
                )))
            }
            Ok(crate::DispatchOutcome::Existing(_)) => {
                self.update(&token.0.operation, Stage::Unknown, None)?;
                Err(conflict())
            }
            Err(failure) => {
                self.update(&token.0.operation, Stage::Unknown, Some(failure.clone()))?;
                Err(failure)
            }
        }
    }

    /// The returned permit is the only positive execution authorization from
    /// this layer. Consume it with finish after the one native invocation.
    pub fn start(
        &self,
        mut token: DispatchToken,
        document: Value,
        at_ms: u64,
    ) -> Result<ExecutionPermit> {
        let claim = self.take(&mut token.0, Stage::Dispatched, Stage::Starting)?;
        match self.inner.journal.start(&claim, document, at_ms) {
            Ok(transition) if transition.claimed => {
                self.update(&token.0.operation, Stage::Executing, None)?;
                Ok(ExecutionPermit(self.lease(
                    &token.0.operation,
                    &token.0.digest,
                    claim,
                )))
            }
            Ok(_) => {
                self.update(&token.0.operation, Stage::Unknown, None)?;
                Err(conflict())
            }
            Err(failure) => {
                self.update(&token.0.operation, Stage::Unknown, Some(failure.clone()))?;
                Err(failure)
            }
        }
    }

    /// Pass `now_ms()` directly, without `?`, so clock failure cannot discard
    /// the result. A persistence failure returns Ok with Unconfirmed and keeps
    /// the exact bounded observation; it never returns another execution token.
    pub fn finish(
        &self,
        mut token: ExecutionPermit,
        result: Value,
        time: Result<u64>,
    ) -> Result<Completion> {
        self.complete(&mut token.0, Stage::Executing, result, time, false, false)
    }

    /// Preserve an ambiguous native result without committing a terminal state.
    /// HTTP success:false alone does not prove an effect failed or did not run.
    pub fn finish_unknown(&self, mut token: ExecutionPermit, result: Value) -> Result<Completion> {
        self.complete(&mut token.0, Stage::Executing, result, Ok(0), false, true)
    }

    pub fn not_executed(
        &self,
        mut token: DispatchToken,
        result: Value,
        time: Result<u64>,
    ) -> Result<Completion> {
        self.complete(&mut token.0, Stage::Dispatched, result, time, true, false)
    }

    pub fn status(&self, session: &str, operation: &str) -> Result<Status> {
        crate::bounded_id(session)?;
        crate::bounded_id(operation)?;
        // Never block retention insertion on disk access. After the journal
        // read, snapshot the latest in-memory observation with a short lock.
        let (durable, storage_error) = match self.inner.journal.status(session, operation) {
            Ok(status) => (Some(status), None),
            Err(failure) => (None, Some(uncertain(failure))),
        };
        let historical = session != self.session_id();
        let entry = if historical {
            None
        } else {
            self.inner
                .state
                .lock()
                .map_err(|_| lock_error())?
                .entries
                .get(operation)
                .cloned()
        };
        if let (Some(entry), Some(record)) = (
            &entry,
            durable.as_ref().and_then(|status| status.record.as_ref()),
        ) {
            if record.request_digest != entry.digest
                || entry.dispatch_id.as_ref().is_some_and(|id| {
                    record
                        .dispatch_id
                        .as_ref()
                        .is_some_and(|actual| actual != id)
                })
            {
                return Err(conflict());
            }
        }
        let observed = entry
            .as_ref()
            .and_then(|entry| {
                entry
                    .observed
                    .as_ref()
                    .map(|observation| self.observation(operation, &entry.digest, observation))
            })
            .transpose()?;
        let terminal = durable
            .as_ref()
            .and_then(|status| status.record.as_ref())
            .is_some_and(|record| record.phase.is_terminal());
        let authority = if terminal {
            Authority::DurableTerminal
        } else if observed.is_some() {
            Authority::ObservedNondurable
        } else if entry.as_ref().is_some_and(|entry| {
            matches!(
                entry.stage,
                Stage::Admitting | Stage::Unknown | Stage::Existing
            )
        }) {
            Authority::Unknown
        } else if durable.as_ref().is_some_and(|status| {
            status.outcome == crate::Outcome::Pending && !status.reconciliation_required
        }) {
            Authority::Pending
        } else {
            Authority::Unknown
        };
        Ok(Status {
            durable,
            observed,
            storage_error,
            retention_error: entry.and_then(|entry| entry.failure),
            authority,
            historical,
            reconciliation_required: matches!(
                authority,
                Authority::ObservedNondurable | Authority::Unknown
            ),
        })
    }

    fn complete(
        &self,
        token: &mut Lease<DispatchClaim>,
        expected: Stage,
        result: Value,
        time: Result<u64>,
        not_executed: bool,
        force_unknown: bool,
    ) -> Result<Completion> {
        let outcome = if force_unknown {
            ObservedOutcome::Unknown
        } else {
            match result.get("success").and_then(Value::as_bool) {
                Some(false)
                    if not_executed
                        && result.get("nativeExecutionStarted") == Some(&Value::Bool(false)) =>
                {
                    ObservedOutcome::NotExecuted
                }
                Some(true) if !not_executed => ObservedOutcome::Succeeded,
                Some(false) if !not_executed => ObservedOutcome::Failed,
                _ => ObservedOutcome::Unknown,
            }
        };
        // Encoding is capped while writing; a large Value cannot cause a second
        // unbounded allocation. Its caller-owned allocation is outside cache.
        let (bytes, encoding_error) = match encode(&result, self.inner.limits.max_result_bytes) {
            Ok(bytes) => (Some(bytes), None),
            Err(failure) => (None, Some(failure)),
        };
        let invalid = if encoding_error.is_some() {
            encoding_error
        } else if force_unknown {
            Some(error(
                "operation_outcome_unknown",
                "Native effect outcome is uncertain; terminal persistence is forbidden.",
            ))
        } else if outcome == ObservedOutcome::Unknown {
            Some(error(
                "operation_record_invalid",
                "Observed terminal result has invalid success/execution fields.",
            ))
        } else {
            None
        };
        let claim = {
            let mut state = self.inner.state.lock().map_err(|_| lock_error())?;
            self.check_owner(token)?;
            let entry = state
                .entries
                .get_mut(&token.operation)
                .ok_or_else(conflict)?;
            if entry.digest != token.digest || entry.stage != expected || entry.observed.is_some() {
                return Err(conflict());
            }
            let claim = token.claim.take().ok_or_else(conflict)?;
            if entry.dispatch_id.as_deref() != Some(claim.dispatch_id()) {
                return Err(conflict());
            }
            entry.observed = Some(StoredObservation {
                dispatch_id: claim.dispatch_id().into(),
                outcome,
                bytes,
            });
            entry.stage = Stage::Observed;
            claim
        };
        // From this point, every ordinary clock/validation/storage error leaves
        // the observation available. No cache lock spans Journal or filesystem.
        let persistence = if let Some(failure) = invalid {
            Err(failure)
        } else {
            time.and_then(|at_ms| {
                if not_executed {
                    self.inner.journal.not_executed(&claim, result, at_ms)
                } else {
                    self.inner.journal.finish(&claim, result, at_ms)
                }
            })
            .and_then(|transition| {
                if transition.claimed {
                    Ok(())
                } else {
                    Err(error(
                        "operation_conflict",
                        "A terminal observation cannot replace an existing durable state.",
                    ))
                }
            })
        };
        let failure = persistence.err().map(uncertain);
        self.update(&token.operation, Stage::Observed, failure.clone())?;
        let entry = self
            .inner
            .state
            .lock()
            .map_err(|_| lock_error())?
            .entries
            .get(&token.operation)
            .cloned()
            .ok_or_else(conflict)?;
        let observation = self.observation(
            &token.operation,
            &token.digest,
            entry.observed.as_ref().ok_or_else(conflict)?,
        )?;
        Ok(Completion {
            observation,
            persistence: if failure.is_none() {
                Persistence::Committed
            } else {
                Persistence::Unconfirmed
            },
            persistence_error: failure,
        })
    }

    fn observation(
        &self,
        operation: &str,
        digest: &str,
        stored: &StoredObservation,
    ) -> Result<Observation> {
        let result = stored
            .bytes
            .as_ref()
            .map(|bytes| {
                serde_json::from_slice(bytes.as_slice()).map_err(|_| {
                    error(
                        "operation_retention_invalid",
                        "Retained observation encoding is invalid.",
                    )
                })
            })
            .transpose()?;
        Ok(Observation {
            session_id: self.session_id().into(),
            operation_id: operation.into(),
            request_digest: digest.into(),
            dispatch_id: stored.dispatch_id.clone(),
            outcome: stored.outcome,
            result,
            payload_omitted: stored.bytes.is_none(),
        })
    }
    fn lease<C>(&self, operation: &str, digest: &str, claim: C) -> Lease<C> {
        Lease {
            owner: Arc::downgrade(&self.inner),
            operation: operation.into(),
            digest: digest.into(),
            claim: Some(claim),
        }
    }
    fn check_owner<C>(&self, lease: &Lease<C>) -> Result<()> {
        if !lease.owner.ptr_eq(&Arc::downgrade(&self.inner)) {
            return Err(conflict());
        }
        Ok(())
    }
    fn take<C>(&self, lease: &mut Lease<C>, expected: Stage, next: Stage) -> Result<C> {
        self.check_owner(lease)?;
        let mut state = self.inner.state.lock().map_err(|_| lock_error())?;
        let entry = state
            .entries
            .get_mut(&lease.operation)
            .ok_or_else(conflict)?;
        if entry.digest != lease.digest || entry.stage != expected {
            return Err(conflict());
        }
        let claim = lease.claim.take().ok_or_else(conflict)?;
        entry.stage = next;
        Ok(claim)
    }
    fn update(&self, operation: &str, stage: Stage, failure: Option<Error>) -> Result<()> {
        let mut state = self.inner.state.lock().map_err(|_| lock_error())?;
        let entry = state.entries.get_mut(operation).ok_or_else(conflict)?;
        entry.stage = stage;
        entry.failure = failure.map(uncertain);
        Ok(())
    }
}

fn encode(value: &Value, limit: usize) -> Result<Arc<Vec<u8>>> {
    // Keep iteration storage proportional to depth, never to array length.
    // The stricter depth bound ensures the retained bytes can be parsed by
    // serde_json's default recursion limit when status is projected later.
    enum Children<'a> {
        Array(std::slice::Iter<'a, Value>),
        Object(serde_json::map::Values<'a>),
    }
    impl<'a> Children<'a> {
        fn next(&mut self) -> Option<&'a Value> {
            match self {
                Self::Array(iter) => iter.next(),
                Self::Object(iter) => iter.next(),
            }
        }
    }
    let oversize = || {
        error("operation_observation_oversize", "Observed result exceeded its reserved byte bound; outcome metadata retained, payload omitted.")
    };
    let mut stack = Vec::new();
    let mut current = Some(value);
    let mut nodes = 0usize;
    while let Some(node) = current {
        nodes += 1;
        if nodes > limit {
            return Err(oversize());
        }
        let children = match node {
            Value::Array(values) => Some(Children::Array(values.iter())),
            Value::Object(values) => Some(Children::Object(values.values())),
            _ => None,
        };
        if let Some(children) = children {
            if stack.len() >= 64 {
                return Err(error("operation_observation_depth", "Observed result exceeds the retained payload nesting bound; outcome metadata retained, payload omitted."));
            }
            stack.push(children);
        }
        current = loop {
            match stack.last_mut() {
                Some(children) => match children.next() {
                    Some(value) => break Some(value),
                    None => {
                        stack.pop();
                    }
                },
                None => break None,
            }
        };
    }
    struct Bounded {
        bytes: Vec<u8>,
        limit: usize,
    }
    impl Write for Bounded {
        fn write(&mut self, buffer: &[u8]) -> io::Result<usize> {
            if buffer.len() > self.limit.saturating_sub(self.bytes.len()) {
                return Err(io::Error::other("result exceeds reserved bytes"));
            }
            self.bytes.extend_from_slice(buffer);
            Ok(buffer.len())
        }
        fn flush(&mut self) -> io::Result<()> {
            Ok(())
        }
    }
    // Fixed capacity matches reservation accounting and prevents geometric
    // Vec growth from retaining more bytes than the reservation permits.
    let mut writer = Bounded {
        bytes: Vec::with_capacity(limit),
        limit,
    };
    serde_json::to_writer(&mut writer, value).map_err(|_| oversize())?;
    Ok(Arc::new(writer.bytes))
}

#[cfg(test)]
mod tests;