Skip to main content

logicaffeine_compile/concurrency/
marshal.rs

1//! Marshalling between the interpreter's `RuntimeValue` and the `Send`-able
2//! [`RtPayload`] that crosses task/thread boundaries through channels.
3//!
4//! [`materialize`] moves a value OUT of a task's `Rc`-based heap into an owned,
5//! self-contained `RtPayload`; [`rebuild`] reconstructs a fresh `Rc`-based value
6//! in the receiving task's heap. The pair mirrors [`RuntimeValue::deep_clone`]
7//! but crosses the `Send` boundary. Values that cannot cross (closures) yield a
8//! [`MarshalError`]; the Send/escape analysis (Phase 4) rejects them statically,
9//! so this is a defensive backstop, not the primary gate.
10
11use std::cell::RefCell;
12use std::rc::Rc;
13
14use logicaffeine_runtime::RtPayload;
15
16// The integer-sequence description-length codec (the Auto column menu) lives in the leaf crate so
17// the wire layer and the proof layer share one implementation of the format. `describe::` is used
18// for the encode/decode entry points; the generator IR and shared helpers are re-imported so their
19// existing call sites (and downstream `marshal::GenExpr` references) resolve unchanged.
20pub use logicaffeine_base::describe::{gen_eval, GenCmp, GenExpr};
21use logicaffeine_base::describe::{
22    self, consider, deserialize_gen, detect_affine, emit_best_int_column, serialize_gen,
23    MAX_GEN_DEPTH, MAX_GEN_NODES,
24};
25
26use crate::interpreter::{ClosureValue, InductiveValue, ListRepr, MapStorage, RuntimeValue, StructValue};
27
28/// Why a value could not be marshalled across a task boundary.
29#[derive(Debug, Clone, PartialEq, Eq)]
30pub enum MarshalError {
31    /// A value type that cannot cross a task boundary (e.g. a closure, whose
32    /// captured environment would alias another task's heap).
33    NotSendable(&'static str),
34}
35
36/// Move a value out of a task's heap into a `Send`-able payload.
37pub fn materialize(value: &RuntimeValue) -> Result<RtPayload, MarshalError> {
38    Ok(match value {
39        RuntimeValue::Int(n) => RtPayload::Int(*n),
40        RuntimeValue::BigInt(b) => {
41            let (negative, magnitude) = b.to_le_bytes();
42            RtPayload::BigInt { negative, magnitude }
43        }
44        RuntimeValue::Rational(r) => {
45            let (num_negative, num_magnitude) = r.numerator().to_le_bytes();
46            let (_den_sign, den_magnitude) = r.denominator().to_le_bytes();
47            RtPayload::Rational { num_negative, num_magnitude, den_magnitude }
48        }
49        RuntimeValue::Decimal(d) => {
50            let (negative, magnitude, scale) = d.to_le_bytes();
51            RtPayload::Decimal { negative, magnitude, scale }
52        }
53        RuntimeValue::Money(m) => {
54            let (negative, magnitude, scale) = m.amount.to_le_bytes();
55            RtPayload::Money { negative, magnitude, scale, currency: m.currency.code.to_string() }
56        }
57        RuntimeValue::Uuid(u) => RtPayload::Uuid(u.to_bytes()),
58        RuntimeValue::Complex(c) => {
59            let (re_negative, re_num) = c.re().numerator().to_le_bytes();
60            let (_, re_den) = c.re().denominator().to_le_bytes();
61            let (im_negative, im_num) = c.im().numerator().to_le_bytes();
62            let (_, im_den) = c.im().denominator().to_le_bytes();
63            RtPayload::Complex { re_negative, re_num, re_den, im_negative, im_num, im_den }
64        }
65        RuntimeValue::Modular(m) => {
66            let (_, value) = m.value().to_le_bytes();
67            let (_, modulus) = m.modulus().to_le_bytes();
68            RtPayload::Modular { value, modulus }
69        }
70        RuntimeValue::Float(f) => RtPayload::Float(*f),
71        RuntimeValue::Bool(b) => RtPayload::Bool(*b),
72        RuntimeValue::Char(c) => RtPayload::Char(*c),
73        RuntimeValue::Text(s) => RtPayload::Text((**s).clone()),
74        RuntimeValue::Nothing => RtPayload::Nothing,
75        RuntimeValue::Duration(n) => RtPayload::Duration(*n),
76        RuntimeValue::Date(n) => RtPayload::Date(*n),
77        RuntimeValue::Moment(n) => RtPayload::Moment(*n),
78        RuntimeValue::Span { months, days } => RtPayload::Span { months: *months, days: *days },
79        RuntimeValue::Time(n) => RtPayload::Time(*n),
80        RuntimeValue::Word(w) => RtPayload::Word { width: w.width(), bits: w.to_u64() },
81        // A SIMD lane vector is a transient compute value (a register), not a wire type — like a
82        // closure, it does not cross a task boundary. (A future increment can serialize its lanes.)
83        RuntimeValue::Lanes(_) => return Err(MarshalError::NotSendable("Lanes8Word32")),
84        RuntimeValue::List(items) => {
85            let vals = items.borrow().to_values();
86            RtPayload::List(vals.iter().map(materialize).collect::<Result<_, _>>()?)
87        }
88        RuntimeValue::Set(items) => {
89            RtPayload::Set(items.borrow().iter().map(materialize).collect::<Result<_, _>>()?)
90        }
91        RuntimeValue::Tuple(items) => {
92            RtPayload::Tuple(items.iter().map(materialize).collect::<Result<_, _>>()?)
93        }
94        RuntimeValue::Map(m) => {
95            let mut pairs = Vec::new();
96            for (k, v) in m.borrow().iter() {
97                pairs.push((materialize(k)?, materialize(v)?));
98            }
99            RtPayload::Map(pairs)
100        }
101        RuntimeValue::Struct(s) => {
102            let mut fields = Vec::new();
103            for (name, v) in s.fields.iter() {
104                fields.push((name.clone(), materialize(v)?));
105            }
106            RtPayload::Struct { type_name: s.type_name.clone(), fields }
107        }
108        RuntimeValue::Inductive(ind) => RtPayload::Inductive {
109            type_name: ind.inductive_type.clone(),
110            constructor: ind.constructor.clone(),
111            args: ind.args.iter().map(materialize).collect::<Result<_, _>>()?,
112        },
113        // A channel/task handle is an opaque `Send` scheduler id, so it CAN cross
114        // a task (and worker-thread) boundary — e.g. passed as a spawn argument.
115        // It resolves against the one shared scheduler on the other side.
116        RuntimeValue::Chan(id) => RtPayload::Chan(*id),
117        RuntimeValue::TaskHandle(id) => RtPayload::TaskHandle(*id),
118        // A peer handle is just its topic string — trivially `Send`.
119        RuntimeValue::Peer(topic) => RtPayload::Peer((**topic).clone()),
120        RuntimeValue::Function(_) => return Err(MarshalError::NotSendable("Function")),
121        // A live CRDT shares convergent state via Merge/Sync (the relay wire), not by
122        // moving its handle across a task heap — that would alias the same replica.
123        RuntimeValue::Crdt(_) => return Err(MarshalError::NotSendable("Crdt")),
124        // A Quantity travels as its exact SI magnitude (a rational), its dimension (the exponent
125        // vector), and the display unit's symbol — reconstructed losslessly on the far side.
126        RuntimeValue::Quantity(qv) => {
127            let (num_negative, num_magnitude) = qv.q.magnitude_si().numerator().to_le_bytes();
128            let (_den_sign, den_magnitude) = qv.q.magnitude_si().denominator().to_le_bytes();
129            let dim = qv.q.dimension();
130            let mut dim_num = Vec::with_capacity(logicaffeine_base::BaseDim::COUNT);
131            let mut dim_den = Vec::with_capacity(logicaffeine_base::BaseDim::COUNT);
132            for d in logicaffeine_base::BaseDim::ALL {
133                let e = dim.exponent(d);
134                dim_num.push(e.numerator());
135                dim_den.push(e.denominator());
136            }
137            RtPayload::Quantity {
138                num_negative,
139                num_magnitude,
140                den_magnitude,
141                dim_num,
142                dim_den,
143                unit_symbol: qv.unit.symbol.to_string(),
144            }
145        }
146    })
147}
148
149/// Reconstruct a fresh `Rc`-based value in the receiving task's heap.
150pub fn rebuild(payload: RtPayload) -> RuntimeValue {
151    match payload {
152        RtPayload::Nothing => RuntimeValue::Nothing,
153        RtPayload::Int(n) => RuntimeValue::Int(n),
154        RtPayload::BigInt { negative, magnitude } => {
155            RuntimeValue::from_bigint(logicaffeine_base::BigInt::from_le_bytes(negative, &magnitude))
156        }
157        RtPayload::Rational { num_negative, num_magnitude, den_magnitude } => {
158            let num = logicaffeine_base::BigInt::from_le_bytes(num_negative, &num_magnitude);
159            let den = logicaffeine_base::BigInt::from_le_bytes(false, &den_magnitude);
160            // A well-formed payload always has a nonzero denominator; fall back to the
161            // numerator (treated as a whole number) if a corrupt one slips through.
162            match logicaffeine_base::Rational::new(num.clone(), den) {
163                Some(r) => RuntimeValue::from_rational(r),
164                None => RuntimeValue::from_bigint(num),
165            }
166        }
167        RtPayload::Decimal { negative, magnitude, scale } => RuntimeValue::Decimal(Rc::new(
168            logicaffeine_base::Decimal::from_le_bytes(negative, &magnitude, scale),
169        )),
170        RtPayload::Money { negative, magnitude, scale, currency } => {
171            let amount = logicaffeine_base::Decimal::from_le_bytes(negative, &magnitude, scale);
172            let currency = logicaffeine_base::money::currency::by_code(&currency)
173                .unwrap_or(logicaffeine_base::Currency { code: "XXX", scale: 0 });
174            RuntimeValue::Money(Rc::new(logicaffeine_base::Money { amount, currency }))
175        }
176        RtPayload::Uuid(bytes) => {
177            RuntimeValue::Uuid(Rc::new(logicaffeine_base::Uuid::from_bytes(bytes)))
178        }
179        RtPayload::Complex { re_negative, re_num, re_den, im_negative, im_num, im_den } => {
180            let mk = |neg: bool, num: &[u8], den: &[u8]| {
181                logicaffeine_base::Rational::new(
182                    logicaffeine_base::BigInt::from_le_bytes(neg, num),
183                    logicaffeine_base::BigInt::from_le_bytes(false, den),
184                )
185                .unwrap_or_else(logicaffeine_base::Rational::zero)
186            };
187            let re = mk(re_negative, &re_num, &re_den);
188            let im = mk(im_negative, &im_num, &im_den);
189            RuntimeValue::Complex(Rc::new(logicaffeine_base::Complex::new(re, im)))
190        }
191        RtPayload::Modular { value, modulus } => {
192            let v = logicaffeine_base::BigInt::from_le_bytes(false, &value);
193            let n = logicaffeine_base::BigInt::from_le_bytes(false, &modulus);
194            match logicaffeine_base::Modular::new(v, n) {
195                Some(m) => RuntimeValue::Modular(Rc::new(m)),
196                None => RuntimeValue::Nothing, // a corrupt (non-positive) modulus degrades gracefully
197            }
198        }
199        RtPayload::Quantity { num_negative, num_magnitude, den_magnitude, dim_num, dim_den, unit_symbol } => {
200            let num = logicaffeine_base::BigInt::from_le_bytes(num_negative, &num_magnitude);
201            let den = logicaffeine_base::BigInt::from_le_bytes(false, &den_magnitude);
202            let magnitude = logicaffeine_base::Rational::new(num, den)
203                .unwrap_or_else(logicaffeine_base::Rational::zero);
204            // Rebuild the dimension from its exponent vector (BaseDim::ALL order).
205            let mut exps = [logicaffeine_base::Exp::ZERO; logicaffeine_base::BaseDim::COUNT];
206            for (i, slot) in exps.iter_mut().enumerate() {
207                let n = dim_num.get(i).copied().unwrap_or(0);
208                let d = dim_den.get(i).copied().unwrap_or(1);
209                *slot = logicaffeine_base::Exp::new(n, if d == 0 { 1 } else { d });
210            }
211            let dim = logicaffeine_base::Dimension::from_exps(exps);
212            // Resolve the display unit by its symbol; a compound or unknown symbol falls back to the
213            // SI/dimension display (a synthetic empty-symbol unit at the SI base).
214            let unit = logicaffeine_base::quantity::units::by_name(&unit_symbol)
215                .filter(|u| u.dimension == dim)
216                .unwrap_or_else(|| {
217                    logicaffeine_base::Unit::linear("", dim, logicaffeine_base::Rational::one())
218                });
219            let q = logicaffeine_base::Quantity::si(magnitude, dim);
220            RuntimeValue::Quantity(Rc::new(crate::interpreter::QuantityValue { q, unit }))
221        }
222        RtPayload::Float(f) => RuntimeValue::Float(f),
223        RtPayload::Bool(b) => RuntimeValue::Bool(b),
224        RtPayload::Char(c) => RuntimeValue::Char(c),
225        RtPayload::Text(s) => RuntimeValue::Text(Rc::new(s)),
226        RtPayload::Duration(n) => RuntimeValue::Duration(n),
227        RtPayload::Date(n) => RuntimeValue::Date(n),
228        RtPayload::Moment(n) => RuntimeValue::Moment(n),
229        RtPayload::Span { months, days } => RuntimeValue::Span { months, days },
230        RtPayload::Time(n) => RuntimeValue::Time(n),
231        RtPayload::Word { width, bits } => match logicaffeine_base::WordVal::from_u64(width, bits) {
232            Some(w) => RuntimeValue::Word(w),
233            // A well-formed payload always carries width 32/64; degrade a corrupt one to its value.
234            None => RuntimeValue::Int(bits as i64),
235        },
236        RtPayload::List(items) => {
237            let vals: Vec<RuntimeValue> = items.into_iter().map(rebuild).collect();
238            RuntimeValue::List(Rc::new(RefCell::new(ListRepr::from_values(vals))))
239        }
240        RtPayload::Set(items) => {
241            RuntimeValue::Set(Rc::new(RefCell::new(items.into_iter().map(rebuild).collect())))
242        }
243        RtPayload::Tuple(items) => {
244            RuntimeValue::Tuple(Rc::new(items.into_iter().map(rebuild).collect()))
245        }
246        RtPayload::Map(pairs) => {
247            let m: MapStorage = pairs.into_iter().map(|(k, v)| (rebuild(k), rebuild(v))).collect();
248            RuntimeValue::Map(Rc::new(RefCell::new(m)))
249        }
250        RtPayload::Struct { type_name, fields } => {
251            let f = fields.into_iter().map(|(k, v)| (k, rebuild(v))).collect();
252            RuntimeValue::Struct(Box::new(StructValue { type_name, fields: f }))
253        }
254        RtPayload::Inductive { type_name, constructor, args } => {
255            RuntimeValue::Inductive(Box::new(InductiveValue {
256                inductive_type: type_name,
257                constructor,
258                args: args.into_iter().map(rebuild).collect(),
259            }))
260        }
261        RtPayload::Chan(id) => RuntimeValue::Chan(id),
262        RtPayload::TaskHandle(id) => RuntimeValue::TaskHandle(id),
263        RtPayload::Peer(topic) => RuntimeValue::Peer(Rc::new(topic)),
264    }
265}
266
267// =============================================================================
268// Wire codec — a message is any language value, sent over the relay
269// =============================================================================
270//
271// A peer message is just a value, and both ends speak the same language, so the
272// wire form IS the value — carrying its type. [`WireValue`] is the network-
273// portable shape of a value, mirroring the `Send`-able [`RtPayload`] minus the
274// pieces that have no meaning off-machine (a `Function` cannot be marshalled at
275// all; a `Chan`/`TaskHandle` is an index into THIS process's scheduler). Its
276// `struct`/`inductive` variants carry the type name (and constructor), so a sent
277// `Point` is reconstructed as a `Point`, not a bare map — the type rides with the
278// value. Encoding is `bincode`: compact binary, no text parsing, and `RtPayload`
279// is already the materialized form, so on the far side `rebuild` is the only cost
280// left. (Runtime is serde-free by charter, so this serde mirror lives here.)
281// Both peers are the same Logos binary, so the non-self-describing encoding is
282// sound; swapping `bincode` for a self-describing codec (CBOR) is a one-liner if
283// cross-version peers ever matter.
284
285/// A value as it travels the wire — the network-portable projection of
286/// [`RtPayload`], type tags and all.
287#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
288enum WireValue {
289    Nothing,
290    Int(i64),
291    BigInt { negative: bool, magnitude: Vec<u8> },
292    Rational { num_negative: bool, num_magnitude: Vec<u8>, den_magnitude: Vec<u8> },
293    Decimal { negative: bool, magnitude: Vec<u8>, scale: u32 },
294    Money { negative: bool, magnitude: Vec<u8>, scale: u32, currency: std::string::String },
295    Uuid([u8; 16]),
296    Complex {
297        re_negative: bool,
298        re_num: Vec<u8>,
299        re_den: Vec<u8>,
300        im_negative: bool,
301        im_num: Vec<u8>,
302        im_den: Vec<u8>,
303    },
304    Modular { value: Vec<u8>, modulus: Vec<u8> },
305    Quantity {
306        num_negative: bool,
307        num_magnitude: Vec<u8>,
308        den_magnitude: Vec<u8>,
309        dim_num: Vec<i32>,
310        dim_den: Vec<i32>,
311        unit_symbol: String,
312    },
313    Float(f64),
314    Bool(bool),
315    Char(char),
316    Text(String),
317    Duration(i64),
318    Date(i32),
319    Moment(i64),
320    Span { months: i32, days: i32 },
321    Time(i64),
322    Word { width: u32, bits: u64 },
323    Peer(String),
324    List(Vec<WireValue>),
325    Tuple(Vec<WireValue>),
326    Set(Vec<WireValue>),
327    Map(Vec<(WireValue, WireValue)>),
328    Struct { type_name: String, fields: Vec<(String, WireValue)> },
329    Inductive { type_name: String, constructor: String, args: Vec<WireValue> },
330}
331
332/// The wire envelope: the sender's inbox topic plus the typed value.
333#[derive(serde::Serialize, serde::Deserialize)]
334struct WireMessage {
335    from: String,
336    msg: WireValue,
337}
338
339/// One `RtPayload` → its portable [`WireValue`]. `None` if it carries a value
340/// with no meaning on another machine — a local channel or task handle.
341fn rt_to_wire(p: &RtPayload) -> Option<WireValue> {
342    Some(match p {
343        RtPayload::Nothing => WireValue::Nothing,
344        RtPayload::Int(n) => WireValue::Int(*n),
345        RtPayload::BigInt { negative, magnitude } => {
346            WireValue::BigInt { negative: *negative, magnitude: magnitude.clone() }
347        }
348        RtPayload::Rational { num_negative, num_magnitude, den_magnitude } => WireValue::Rational {
349            num_negative: *num_negative,
350            num_magnitude: num_magnitude.clone(),
351            den_magnitude: den_magnitude.clone(),
352        },
353        RtPayload::Decimal { negative, magnitude, scale } => {
354            WireValue::Decimal { negative: *negative, magnitude: magnitude.clone(), scale: *scale }
355        }
356        RtPayload::Money { negative, magnitude, scale, currency } => WireValue::Money {
357            negative: *negative,
358            magnitude: magnitude.clone(),
359            scale: *scale,
360            currency: currency.clone(),
361        },
362        RtPayload::Uuid(bytes) => WireValue::Uuid(*bytes),
363        RtPayload::Complex { re_negative, re_num, re_den, im_negative, im_num, im_den } => {
364            WireValue::Complex {
365                re_negative: *re_negative,
366                re_num: re_num.clone(),
367                re_den: re_den.clone(),
368                im_negative: *im_negative,
369                im_num: im_num.clone(),
370                im_den: im_den.clone(),
371            }
372        }
373        RtPayload::Modular { value, modulus } => {
374            WireValue::Modular { value: value.clone(), modulus: modulus.clone() }
375        }
376        RtPayload::Quantity { num_negative, num_magnitude, den_magnitude, dim_num, dim_den, unit_symbol } => {
377            WireValue::Quantity {
378                num_negative: *num_negative,
379                num_magnitude: num_magnitude.clone(),
380                den_magnitude: den_magnitude.clone(),
381                dim_num: dim_num.clone(),
382                dim_den: dim_den.clone(),
383                unit_symbol: unit_symbol.clone(),
384            }
385        }
386        RtPayload::Float(f) => WireValue::Float(*f),
387        RtPayload::Bool(b) => WireValue::Bool(*b),
388        RtPayload::Char(c) => WireValue::Char(*c),
389        RtPayload::Text(s) => WireValue::Text(s.clone()),
390        RtPayload::Duration(n) => WireValue::Duration(*n),
391        RtPayload::Date(n) => WireValue::Date(*n),
392        RtPayload::Moment(n) => WireValue::Moment(*n),
393        RtPayload::Span { months, days } => WireValue::Span { months: *months, days: *days },
394        RtPayload::Time(n) => WireValue::Time(*n),
395        RtPayload::Word { width, bits } => WireValue::Word { width: *width, bits: *bits },
396        RtPayload::Peer(topic) => WireValue::Peer(topic.clone()),
397        RtPayload::List(items) => WireValue::List(rt_seq_to_wire(items)?),
398        RtPayload::Tuple(items) => WireValue::Tuple(rt_seq_to_wire(items)?),
399        RtPayload::Set(items) => WireValue::Set(rt_seq_to_wire(items)?),
400        RtPayload::Map(pairs) => {
401            let mut wire_pairs = pairs
402                .iter()
403                .map(|(k, v)| Some((rt_to_wire(k)?, rt_to_wire(v)?)))
404                .collect::<Option<Vec<_>>>()?;
405            // Canonical order: sort by the encoded key, so the wire is the same
406            // bytes regardless of the source map's (hash) iteration order.
407            wire_pairs.sort_by(|a, b| canon_bytes(&a.0).cmp(&canon_bytes(&b.0)));
408            WireValue::Map(wire_pairs)
409        }
410        RtPayload::Struct { type_name, fields } => {
411            let mut wire_fields = fields
412                .iter()
413                .map(|(n, v)| Some((n.clone(), rt_to_wire(v)?)))
414                .collect::<Option<Vec<_>>>()?;
415            // A struct is a record (unordered fields), so canonicalize by name.
416            wire_fields.sort_by(|a, b| a.0.cmp(&b.0));
417            WireValue::Struct { type_name: type_name.clone(), fields: wire_fields }
418        }
419        RtPayload::Inductive { type_name, constructor, args } => WireValue::Inductive {
420            type_name: type_name.clone(),
421            constructor: constructor.clone(),
422            args: rt_seq_to_wire(args)?,
423        },
424        // A scheduler token indexes THIS process's scheduler — not portable.
425        RtPayload::Chan(_) | RtPayload::TaskHandle(_) => return None,
426    })
427}
428
429fn rt_seq_to_wire(items: &[RtPayload]) -> Option<Vec<WireValue>> {
430    items.iter().map(rt_to_wire).collect()
431}
432
433/// One [`WireValue`] → its `RtPayload`. The inverse of [`rt_to_wire`]; total.
434fn wire_to_rt(w: WireValue) -> RtPayload {
435    match w {
436        WireValue::Nothing => RtPayload::Nothing,
437        WireValue::Int(n) => RtPayload::Int(n),
438        WireValue::BigInt { negative, magnitude } => RtPayload::BigInt { negative, magnitude },
439        WireValue::Rational { num_negative, num_magnitude, den_magnitude } => {
440            RtPayload::Rational { num_negative, num_magnitude, den_magnitude }
441        }
442        WireValue::Decimal { negative, magnitude, scale } => {
443            RtPayload::Decimal { negative, magnitude, scale }
444        }
445        WireValue::Money { negative, magnitude, scale, currency } => {
446            RtPayload::Money { negative, magnitude, scale, currency }
447        }
448        WireValue::Uuid(bytes) => RtPayload::Uuid(bytes),
449        WireValue::Complex { re_negative, re_num, re_den, im_negative, im_num, im_den } => {
450            RtPayload::Complex { re_negative, re_num, re_den, im_negative, im_num, im_den }
451        }
452        WireValue::Modular { value, modulus } => RtPayload::Modular { value, modulus },
453        WireValue::Quantity { num_negative, num_magnitude, den_magnitude, dim_num, dim_den, unit_symbol } => {
454            RtPayload::Quantity { num_negative, num_magnitude, den_magnitude, dim_num, dim_den, unit_symbol }
455        }
456        WireValue::Float(f) => RtPayload::Float(f),
457        WireValue::Bool(b) => RtPayload::Bool(b),
458        WireValue::Char(c) => RtPayload::Char(c),
459        WireValue::Text(s) => RtPayload::Text(s),
460        WireValue::Duration(n) => RtPayload::Duration(n),
461        WireValue::Date(n) => RtPayload::Date(n),
462        WireValue::Moment(n) => RtPayload::Moment(n),
463        WireValue::Span { months, days } => RtPayload::Span { months, days },
464        WireValue::Time(n) => RtPayload::Time(n),
465        WireValue::Word { width, bits } => RtPayload::Word { width, bits },
466        WireValue::Peer(topic) => RtPayload::Peer(topic),
467        WireValue::List(items) => RtPayload::List(items.into_iter().map(wire_to_rt).collect()),
468        WireValue::Tuple(items) => RtPayload::Tuple(items.into_iter().map(wire_to_rt).collect()),
469        WireValue::Set(items) => RtPayload::Set(items.into_iter().map(wire_to_rt).collect()),
470        WireValue::Map(pairs) => {
471            RtPayload::Map(pairs.into_iter().map(|(k, v)| (wire_to_rt(k), wire_to_rt(v))).collect())
472        }
473        WireValue::Struct { type_name, fields } => RtPayload::Struct {
474            type_name,
475            fields: fields.into_iter().map(|(n, v)| (n, wire_to_rt(v))).collect(),
476        },
477        WireValue::Inductive { type_name, constructor, args } => RtPayload::Inductive {
478            type_name,
479            constructor,
480            args: args.into_iter().map(wire_to_rt).collect(),
481        },
482    }
483}
484
485/// The wire encoding for a message body.
486///
487/// `Native` is the default and the fast path — *our* compact tagged-varint binary
488/// format, encoded and decoded in a SINGLE PASS straight to/from `RuntimeValue`
489/// with no intermediate trees: the hot loop for a list of scalars allocates only
490/// the output buffer. `Json` is offered for interop with non-Logos peers (or human
491/// debugging) through a real parser (`serde_json`), never a hand-rolled one. Both
492/// ride the same relay: every message self-describes its codec in a leading header
493/// byte, so any receiver decodes either.
494#[derive(Debug, Clone, Copy, PartialEq, Eq)]
495pub enum WireCodec {
496    /// Our single-pass tagged-varint binary (default) — the high-throughput path.
497    Native,
498    /// `serde_json` text — interop / debuggable, larger and slower.
499    Json,
500}
501
502/// Whether a message carries an integrity checksum.
503///
504/// Independent of the codec. Pay a few bytes + a hash to have the receiver reject
505/// a corrupted or mis-encoded message, or go bare for raw speed. This is
506/// *integrity*, not secrecy — for confidentiality run the relay over `wss://`/TLS
507/// at the transport layer; a message-level signing/encryption layer is separate.
508#[derive(Debug, Clone, Copy, PartialEq, Eq)]
509pub enum WireIntegrity {
510    /// No checksum — smallest and fastest; the receiver trusts the bytes.
511    Raw,
512    /// An FNV-1a checksum over the payload — the receiver rejects a corrupted or
513    /// mis-encoded message (`message_from_wire` returns `None`).
514    Checked,
515}
516
517// The framing header byte: bit 0 = integrity, bit 1 = compressed, bits 2-3 = the
518// compression codec id (when compressed), bit 4 = payload codec; any other bit set
519// is an unknown format and is rejected.
520const H_CHECKED: u8 = 0x01;
521const H_COMPRESSED: u8 = 0x02;
522const H_CODEC: u8 = 0x0C; // bits 2-3: 0=deflate, 1=lz4, 2=zstd (only meaningful when H_COMPRESSED)
523const H_JSON: u8 = 0x10;
524const H_KNOWN: u8 = H_CHECKED | H_COMPRESSED | H_CODEC | H_JSON;
525
526/// Encode a directed peer message for the relay wire: the sender's inbox topic
527/// plus the FULL language value — scalars, collections, structs, inductives,
528/// nested, type tags and all — as compact `bincode` under the process default
529/// integrity ([`default_integrity`]). Closures, and channel/task handles (local to
530/// this process), cannot travel between machines and are reported with a clear
531/// error rather than silently dropped.
532pub fn message_to_wire(from: &str, value: &RuntimeValue) -> Result<Vec<u8>, String> {
533    message_to_wire_with(from, value, WireCodec::Native, current_integrity())
534}
535
536/// Encode ONE value as the plain, self-describing recursive wire form — no envelope, no
537/// framing, no columnar/compression/dedup transforms. This is the exact format the shared
538/// [`logicaffeine_data::wire`] core decodes, so a `RuntimeValue` encoded here round-trips
539/// through an AOT-generated type's `wire_decode` (and vice versa). The speed-first form used
540/// to hand a program AST to a compile-once native partial evaluator.
541pub fn encode_value_raw(v: &RuntimeValue) -> Result<Vec<u8>, String> {
542    with_flat_lists(true, || {
543        with_structure(WireStructure::Off, || {
544            with_dedup(false, || {
545                let mut out = Vec::new();
546                native_encode(v, &mut out)?;
547                Ok(out)
548            })
549        })
550    })
551}
552
553/// Decode a value produced by [`encode_value_raw`] (or by an AOT-generated `wire_encode`)
554/// back into a `RuntimeValue`. `None` on any malformed or trailing-byte input.
555pub fn decode_value_raw(buf: &[u8]) -> Option<RuntimeValue> {
556    let mut pos = 0usize;
557    let v = native_decode(buf, &mut pos)?;
558    if pos == buf.len() {
559        Some(v)
560    } else {
561        None
562    }
563}
564
565/// What the [`message_to_wire_best`] auto-tuner optimizes for.
566#[derive(Clone, Copy, PartialEq, Eq, Debug)]
567pub enum WireGoal {
568    /// Fewest bytes on the wire — measure every applicable encoding and ship the smallest.
569    /// The bandwidth-bound choice (a network link).
570    Smallest,
571    /// Cheapest decode — fixed-width `memcpy` columns, no compression, no structural
572    /// transform. The latency / CPU-bound choice (datacenter, shared memory, RDMA).
573    Fastest,
574}
575
576/// The no-brainer encoder — "just use this." Picks the Pareto-optimal dial combination for
577/// `goal` and ships it. Because every wire form is self-describing by its leading tag, this
578/// is purely an ENCODE-side decision: the decoder reconstructs via `message_from_wire` with
579/// no hint, so `best` interoperates with every existing peer.
580///
581/// `Smallest` measures the FULL cross product of the size-affecting dials (numerics ×
582/// structure × float-coding × compression) and returns the minimum. Because every
583/// single-dial configuration is literally one of the candidates, the result is provably
584/// never larger than ANY single knob — on any workload. `Fastest` returns the fixed
585/// memcpy-decode form directly. (`Smallest` pays N encode passes for the minimum bytes; it
586/// is the opt-in "I am bandwidth-bound" choice, not the default.)
587pub fn message_to_wire_best(from: &str, value: &RuntimeValue, goal: WireGoal) -> Result<Vec<u8>, String> {
588    match goal {
589        WireGoal::Fastest => with_numerics(WireNumerics::Fixed, || {
590            with_structure(WireStructure::Off, || {
591                with_floats(WireFloats::Memcpy, || {
592                    with_compression_codec(WireCompression::None, || message_to_wire(from, value))
593                })
594            })
595        }),
596        WireGoal::Smallest => smallest_over(
597            from,
598            value,
599            &[WireCompression::None, WireCompression::Deflate, WireCompression::Lz4, WireCompression::Zstd],
600        ),
601    }
602}
603
604/// The size bake-off, parameterized by the compression codecs allowed (so a negotiated send only tries
605/// what the receiver can decode). Measures the FULL cross product of the size-affecting dials
606/// (numerics × structure/G5 × float-coding) against each allowed compression and returns the smallest —
607/// the maximal crush. Runs under whatever type registry is in scope (so name elision composes when the
608/// caller enabled it). Every form is self-describing, so the decoder needs no hint.
609fn smallest_over(
610    from: &str,
611    value: &RuntimeValue,
612    compressions: &[WireCompression],
613) -> Result<Vec<u8>, String> {
614    let mut best: Option<Vec<u8>> = None;
615    // Structure-sharing dimension: if the SAME subtree is reached more than once, Rc-dedup ships it
616    // ONCE + backrefs. It competes as just another bake-off candidate (each is a single dedup-scoped
617    // encode, so the per-encode id table never leaks across passes), so it wins ONLY when it actually
618    // beats the backref-tag overhead. The gather runs once HERE; no sharing → no dedup pass, no cost.
619    let dedup_opts: &[bool] = if value_has_sharing(value) { &[false, true] } else { &[false] };
620    for num in [WireNumerics::Varint, WireNumerics::Fixed, WireNumerics::GroupVarint] {
621        for st in [WireStructure::Off, WireStructure::Affine, WireStructure::Auto] {
622            for fl in [WireFloats::Memcpy, WireFloats::XorDelta] {
623                for &comp in compressions {
624                    for &dedup in dedup_opts {
625                        let bytes = with_dedup(dedup, || {
626                            with_numerics(num, || {
627                                with_structure(st, || {
628                                    with_floats(fl, || {
629                                        with_compression_codec(comp, || message_to_wire(from, value))
630                                    })
631                                })
632                            })
633                        })?;
634                        if best.as_ref().map_or(true, |b| bytes.len() < b.len()) {
635                            best = Some(bytes);
636                        }
637                    }
638                }
639            }
640        }
641    }
642    best.ok_or_else(|| "no encoding produced".to_string())
643}
644
645/// Encode a message TO a peer using EVERYTHING both sides support — the negotiated maximal crush.
646/// Applies all the self-describing dials (any peer decodes them) via the size bake-off, but restricts
647/// the receiver-capability knobs to the negotiated surface: only compression codecs the receiver can
648/// decode, and type-id NAME ELISION only when epochs matched (`neg.use_type_id`). Refuses to ship a
649/// computation the receiver declined. Stays MINIMAL in cost too: a tiny message that name-elision can't
650/// help ships the plain default without paying for the search. Never larger than the default; always
651/// self-describing, so it round-trips on the receiver with no hint.
652pub fn message_to_wire_negotiated(
653    from: &str,
654    value: &RuntimeValue,
655    neg: &Negotiated,
656    registry: WireTypeRegistry,
657) -> Result<Vec<u8>, String> {
658    if matches!(value, RuntimeValue::Function(_)) && !neg.may_send_computed {
659        return Err("the receiver does not accept computed (shipped-function) sends".to_string());
660    }
661    let default = message_to_wire(from, value)?;
662    // Minimal cost: a small message that type-id can't shrink skips the bake-off entirely.
663    if default.len() <= AUTO_SEARCH_THRESHOLD && !neg.use_type_id {
664        return Ok(default);
665    }
666    let codecs: Vec<WireCompression> = if neg.compression == WireCompression::None {
667        vec![WireCompression::None]
668    } else {
669        vec![WireCompression::None, neg.compression]
670    };
671    let search = || smallest_over(from, value, &codecs);
672    // Name elision only fires when the receiver shares our type registry (negotiated epoch match).
673    let best = if neg.use_type_id { with_type_registry(registry, search) } else { search() }?;
674    Ok(if best.len() < default.len() { best } else { default })
675}
676
677/// Below this default-encoding size the `Smallest` search cannot meaningfully shrink a message (the
678/// envelope + a scalar / short string is already near-minimal), so [`message_to_wire_auto`] skips the
679/// N-pass bake-off and ships the default. Tuned so a scalar / short message never pays for the search.
680const AUTO_SEARCH_THRESHOLD: usize = 64;
681
682/// The genuine no-brainer — "just send it." Runs the full [`WireGoal::Smallest`] bake-off ONLY when the
683/// payload is large enough for it to matter, and otherwise ships the plain default (so calling this on
684/// every message — including scalars and short strings — costs a single encode pass, not the N-pass
685/// search). The result is NEVER larger than the default, ALWAYS self-describing (so it interoperates
686/// with every peer, no hint), and round-trips exactly. This is the recommended default sender.
687pub fn message_to_wire_auto(from: &str, value: &RuntimeValue) -> Result<Vec<u8>, String> {
688    let default = message_to_wire(from, value)?;
689    if default.len() <= AUTO_SEARCH_THRESHOLD {
690        return Ok(default);
691    }
692    // The bake-off includes the default dial set as one candidate, so its winner is ≤ `default`.
693    let best = message_to_wire_best(from, value, WireGoal::Smallest)?;
694    Ok(if best.len() < default.len() { best } else { default })
695}
696
697/// A receiver's admission-control budget — the limits it will accept from a sender, so a malicious or
698/// buggy peer cannot exhaust the receiver's memory, stack, or CPU. Enforced DURING decode, BEFORE the
699/// offending allocation or recursion happens, so an over-budget message is refused cleanly (the decode
700/// returns `None`) rather than processed. A receiver advertises these in the capability handshake so a
701/// cooperative sender stays within them; an uncooperative one is still bounded by the enforcement.
702#[derive(Clone, Copy, Debug, PartialEq, Eq)]
703pub struct ReceiveLimits {
704    /// Largest message body (post-decompress framing aside) the receiver will decode, in bytes.
705    pub max_bytes: usize,
706    /// Maximum container-nesting depth. Bounds decode RECURSION, so a deeply-nested but byte-small
707    /// message cannot overflow the receiver's stack (a remote crash).
708    pub max_depth: usize,
709    /// Maximum element count for any single decoded collection (list / map / set / struct-list /
710    /// numeric column). A claimed count above this is refused before the elements are read.
711    pub max_elements: usize,
712    /// Maximum byte length of any single decoded string.
713    pub max_string_bytes: usize,
714    /// Whether to accept a SHIPPED computation (`T_FUNC`) at all. When `false`, a computed send is
715    /// refused at decode — independent of (and prior to) the C2 acceptance contract that gates whether
716    /// an accepted computation may be EVALUATED.
717    pub accept_computed: bool,
718}
719
720/// Generous-but-finite defaults: every real message passes (genuine nesting is almost always < 10
721/// deep); only the pathological / adversarial ones are refused. `max_depth` sits BELOW
722/// [`MAX_ENCODE_DEPTH`] on purpose — the recursive DECODER's stack frame is heavier than the encoder's
723/// (one giant `match`), so the depth that is safe to recurse on a small (wasm ~1 MiB) stack is lower
724/// than what we allow ourselves to encode. A deployment tightens these per peer through the handshake.
725pub const DEFAULT_RECEIVE_LIMITS: ReceiveLimits = ReceiveLimits {
726    max_bytes: 64 << 20,
727    max_depth: 64,
728    max_elements: 1 << 24,
729    max_string_bytes: 1 << 24,
730    accept_computed: true,
731};
732
733impl Default for ReceiveLimits {
734    fn default() -> Self {
735        DEFAULT_RECEIVE_LIMITS
736    }
737}
738
739thread_local! {
740    static RECEIVE_LIMITS: std::cell::Cell<ReceiveLimits> =
741        const { std::cell::Cell::new(DEFAULT_RECEIVE_LIMITS) };
742    static DECODE_DEPTH: std::cell::Cell<usize> = const { std::cell::Cell::new(0) };
743}
744
745/// Decode under `limits` for the duration of `f` — the receiver's admission gate. Restores the prior
746/// limits afterward (so it nests). Pair with [`message_from_wire`].
747pub fn with_receive_limits<T>(limits: ReceiveLimits, f: impl FnOnce() -> T) -> T {
748    let prev = RECEIVE_LIMITS.with(|c| c.replace(limits));
749    let r = f();
750    RECEIVE_LIMITS.with(|c| c.set(prev));
751    r
752}
753
754/// The limits in force on this thread (default [`DEFAULT_RECEIVE_LIMITS`] outside a
755/// [`with_receive_limits`] scope).
756fn receive_limits() -> ReceiveLimits {
757    RECEIVE_LIMITS.with(std::cell::Cell::get)
758}
759
760// ── Optional-capability feature bits a peer advertises in its [`PeerProfile`]. Unknown bits are
761//    ignored on receipt, so the set grows forward/backward-compatibly. ──
762/// The peer understands DEFLATE-compressed frames.
763pub const FEAT_DEFLATE: u32 = 1 << 0;
764/// The peer understands LZ4-compressed frames.
765pub const FEAT_LZ4: u32 = 1 << 1;
766/// The peer understands Zstd-compressed frames.
767pub const FEAT_ZSTD: u32 = 1 << 2;
768/// The peer can resolve type-id name elision against a shared type registry.
769pub const FEAT_TYPE_ID: u32 = 1 << 3;
770/// The peer is willing to receive a shipped computation (subject to its acceptance contracts).
771pub const FEAT_COMPUTED: u32 = 1 << 4;
772/// The peer can reconstruct FEC / erasure-coded redundant frames.
773pub const FEAT_FEC: u32 = 1 << 5;
774
775/// A peer's PUBLISHED acceptance surface — the single declarative object it EXPOSES to the other side
776/// AND that its own decoder ENFORCES. Declare it once: it is both advertised (in the handshake) and the
777/// budget the decode path checks, so the two can never drift. Carries the resource budget
778/// ([`ReceiveLimits`]), the peer's type-registry epoch (a content hash of its type table — when both
779/// peers' epochs match, struct/enum NAMES need not travel, since both derive the same ids), and a
780/// feature bitset (`FEAT_*`).
781#[derive(Clone, Copy, Debug, PartialEq, Eq)]
782pub struct PeerProfile {
783    /// What this peer will accept — enforced on decode, advertised so a cooperative sender stays within it.
784    pub limits: ReceiveLimits,
785    /// Content hash of this peer's type table (0 = none). Equal non-zero epochs on both sides unlock
786    /// name elision.
787    pub registry_epoch: u64,
788    /// `FEAT_*` capability bits this peer understands.
789    pub features: u32,
790}
791
792impl Default for PeerProfile {
793    fn default() -> Self {
794        Self {
795            limits: ReceiveLimits::default(),
796            registry_epoch: 0,
797            features: FEAT_DEFLATE | FEAT_LZ4 | FEAT_ZSTD | FEAT_TYPE_ID | FEAT_COMPUTED | FEAT_FEC,
798        }
799    }
800}
801
802impl PeerProfile {
803    /// The profile to ASSUME for a peer we have NOT yet heard from — NO optional capabilities and NO
804    /// shared type registry. Negotiating against it yields a plain, uncompressed, self-describing send
805    /// that ANY receiver (even a non-Logos relay consumer) can decode. A capability turns on only once
806    /// the peer ADVERTISES it in its handshake. (`Default` is the opposite — the FULL profile a Logos
807    /// node advertises for ITSELF.)
808    pub const fn conservative() -> Self {
809        Self { limits: DEFAULT_RECEIVE_LIMITS, registry_epoch: 0, features: 0 }
810    }
811}
812
813const PEER_PROFILE_VERSION: u8 = 1;
814
815/// Serialize a [`PeerProfile`] for the handshake — a version byte (so a future layout is recognized,
816/// not mis-parsed) followed by the budget, epoch, and feature bits.
817pub fn encode_peer_profile(p: &PeerProfile) -> Vec<u8> {
818    let mut out = Vec::with_capacity(32);
819    out.push(PEER_PROFILE_VERSION);
820    write_uvarint(p.limits.max_bytes as u64, &mut out);
821    write_uvarint(p.limits.max_depth as u64, &mut out);
822    write_uvarint(p.limits.max_elements as u64, &mut out);
823    write_uvarint(p.limits.max_string_bytes as u64, &mut out);
824    out.push(p.limits.accept_computed as u8);
825    write_uvarint(p.registry_epoch, &mut out);
826    write_uvarint(p.features as u64, &mut out);
827    out
828}
829
830/// Parse a peer's advertised [`PeerProfile`]. A version this build does not understand, or a truncated
831/// blob, yields `None` — the caller then falls back to the conservative defaults (never mis-decodes).
832pub fn decode_peer_profile(buf: &[u8]) -> Option<PeerProfile> {
833    let mut pos = 0;
834    let version = *buf.get(pos)?;
835    pos += 1;
836    if version != PEER_PROFILE_VERSION {
837        return None;
838    }
839    let max_bytes = read_uvarint(buf, &mut pos)? as usize;
840    let max_depth = read_uvarint(buf, &mut pos)? as usize;
841    let max_elements = read_uvarint(buf, &mut pos)? as usize;
842    let max_string_bytes = read_uvarint(buf, &mut pos)? as usize;
843    let accept_computed = *buf.get(pos)? != 0;
844    pos += 1;
845    let registry_epoch = read_uvarint(buf, &mut pos)?;
846    let features = read_uvarint(buf, &mut pos)? as u32;
847    Some(PeerProfile {
848        limits: ReceiveLimits { max_bytes, max_depth, max_elements, max_string_bytes, accept_computed },
849        registry_epoch,
850        features,
851    })
852}
853
854/// The encoding choices negotiated for sending TO a peer, from my profile and the peer's advertised one.
855#[derive(Clone, Copy, Debug, PartialEq, Eq)]
856pub struct Negotiated {
857    /// Elide type NAMES from the wire — only when both sides speak type-id AND share the same non-zero
858    /// registry epoch (so the receiver can resolve the ids).
859    pub use_type_id: bool,
860    /// Ship a computed function — only when the receiver both accepts computed sends and advertises the
861    /// capability. (The receiver still gates INVOCATION through its acceptance contracts.)
862    pub may_send_computed: bool,
863    /// The strongest compression BOTH peers understand (`None` if they share none).
864    pub compression: WireCompression,
865    /// The receiver's byte budget — keep each message under this so it is not refused.
866    pub peer_max_bytes: usize,
867}
868
869/// Negotiate how to send TO a peer from my profile + the peer's advertised one. CONSERVATIVE: a
870/// capability is used only when BOTH sides expose it. This is where "expose properly" pays off — the
871/// sender automatically restricts itself to exactly the surface the receiver published, so it never
872/// ships a form the receiver can't decode, won't run code the receiver declined, and stays under the
873/// receiver's size budget.
874pub fn negotiate(mine: &PeerProfile, theirs: &PeerProfile) -> Negotiated {
875    let both = |bit: u32| mine.features & bit != 0 && theirs.features & bit != 0;
876    let compression = if both(FEAT_ZSTD) {
877        WireCompression::Zstd
878    } else if both(FEAT_LZ4) {
879        WireCompression::Lz4
880    } else if both(FEAT_DEFLATE) {
881        WireCompression::Deflate
882    } else {
883        WireCompression::None
884    };
885    Negotiated {
886        use_type_id: both(FEAT_TYPE_ID)
887            && mine.registry_epoch != 0
888            && mine.registry_epoch == theirs.registry_epoch,
889        may_send_computed: theirs.limits.accept_computed && both(FEAT_COMPUTED),
890        compression,
891        peer_max_bytes: theirs.limits.max_bytes,
892    }
893}
894
895/// Magic prefix that marks a frame as a capability HANDSHAKE rather than a data message. A data frame
896/// begins with a 1-byte header in the small `H_KNOWN` range, so this ASCII prefix can never collide
897/// with one — the receiver tells them apart unambiguously.
898const HANDSHAKE_MAGIC: &[u8; 4] = b"LCHS";
899
900/// Build a handshake frame advertising `from`'s [`PeerProfile`]: the magic prefix, the sender identity,
901/// then the serialized profile. Published like any message but recognized + absorbed (not delivered as
902/// data) by the receiver.
903pub fn make_handshake_frame(from: &str, profile: &PeerProfile) -> Vec<u8> {
904    let mut out = Vec::with_capacity(8 + from.len() + 16);
905    out.extend_from_slice(HANDSHAKE_MAGIC);
906    write_str(from, &mut out);
907    out.extend_from_slice(&encode_peer_profile(profile));
908    out
909}
910
911/// Parse a handshake frame → `(sender, advertised profile)`. `None` when `data` is not a handshake (no
912/// magic) or is malformed — so a data message is never mistaken for one, and an unknown/garbage profile
913/// is ignored rather than mis-applied.
914pub fn parse_handshake_frame(data: &[u8]) -> Option<(String, PeerProfile)> {
915    let rest = data.strip_prefix(HANDSHAKE_MAGIC.as_slice())?;
916    let mut pos = 0;
917    let from = read_str(rest, &mut pos)?;
918    let profile = decode_peer_profile(rest.get(pos..)?)?;
919    Some((from, profile))
920}
921
922/// As [`message_to_wire`], with an explicit codec and integrity mode.
923pub fn message_to_wire_with(
924    from: &str,
925    value: &RuntimeValue,
926    codec: WireCodec,
927    integrity: WireIntegrity,
928) -> Result<Vec<u8>, String> {
929    let mut body = match codec {
930        // Single pass straight from the live value — no intermediate trees.
931        WireCodec::Native => {
932            // A small base capacity covers the envelope + a scalar/short message
933            // without a realloc; the packed-array arms reserve their own bulk.
934            let mut out = Vec::with_capacity(from.len() + 32);
935            write_str(from, &mut out);
936            native_encode(value, &mut out)?;
937            out
938        }
939        // JSON goes through the serde mirror (interop, not the speed path).
940        WireCodec::Json => {
941            let payload = materialize(value)
942                .map_err(|MarshalError::NotSendable(t)| format!("a {t} cannot be sent over the network"))?;
943            let msg = rt_to_wire(&payload)
944                .ok_or_else(|| "a channel or task handle cannot be sent over the network".to_string())?;
945            serde_json::to_vec(&WireMessage { from: from.to_string(), msg })
946                .map_err(|e| format!("message encode failed: {e}"))?
947        }
948    };
949    // Optional compression — but only KEEP it if it actually shrank the body, so a
950    // small/incompressible message is never made bigger or slower.
951    let mut compression = WireCompression::None;
952    if let Some((used, z)) = compress_body(compression_codec(), &body) {
953        if z.len() < body.len() {
954            body = z;
955            compression = used;
956        }
957    }
958    Ok(frame(codec, integrity, compression, body))
959}
960
961/// Decode a wire message (from [`message_to_wire`]) into `(sender, value)`,
962/// rebuilding the typed value in the local heap. Auto-detects the codec,
963/// integrity, and compression; a checksum mismatch, an unknown header, a bad
964/// inflate, trailing bytes, or any malformed input all return `None` — never a
965/// panic, never a half-rebuilt value.
966pub fn message_from_wire(bytes: &[u8]) -> Option<(String, RuntimeValue)> {
967    // Admission gate: refuse a message larger than the receiver's byte budget BEFORE decompressing or
968    // decoding it — a hostile peer cannot make the receiver spend memory/CPU on an over-budget frame.
969    if bytes.len() > receive_limits().max_bytes {
970        return None;
971    }
972    // Fresh dedup memo per top-level message (ids are message-local; never leak across messages).
973    DECODE_MEMO.with(|c| c.borrow_mut().clear());
974    let (codec, compression, framed) = unframe(bytes)?;
975    // Inflate first if needed (the checksum, already verified, covered the
976    // compressed bytes — so we never spend CPU inflating a corrupt message). The
977    // codec is read off the header, so any peer decodes any sender's choice.
978    let inflated;
979    let body: &[u8] = if compression == WireCompression::None {
980        framed
981    } else {
982        inflated = decompress_body(compression, framed)?;
983        &inflated
984    };
985    match codec {
986        WireCodec::Native => {
987            let mut pos = 0;
988            let from = read_str(body, &mut pos)?;
989            let value = native_decode(body, &mut pos)?;
990            (pos == body.len()).then_some((from, value)) // reject trailing bytes
991        }
992        WireCodec::Json => {
993            let WireMessage { from, msg } = serde_json::from_slice(body).ok()?;
994            Some((from, rebuild(wire_to_rt(msg))))
995        }
996    }
997}
998
999/// The plain-words name of the structural encoding a column tag selects — the codec's own
1000/// dial vocabulary, for surfacing *which* encoding actually won (benchmarks, docs, debug).
1001/// A non-column or unknown tag reads as the generic `"value"`.
1002fn column_tag_name(tag: u8) -> &'static str {
1003    match tag {
1004        T_INTS => "varint",
1005        T_INTS_FIXED => "fixed (memcpy)",
1006        T_INTS_GV => "group-varint",
1007        T_INTS_ALIGNED => "fixed-aligned",
1008        T_INTS_AFFINE => "affine (base,stride,n)",
1009        T_INTS_DELTA => "delta",
1010        T_INTS_DOD => "delta-of-delta",
1011        T_INTS_FOR => "FOR bit-pack",
1012        T_INTS_RLE => "run-length",
1013        T_INTS_DICT => "dictionary",
1014        T_INTS_POLY => "polynomial",
1015        T_INTS_GEOMETRIC => "geometric",
1016        T_INTS_PERIODIC => "periodic",
1017        T_INTS_SPARSE => "sparse",
1018        T_GEN => "generator",
1019        T_BYTES => "byte column",
1020        describe::T_INTS_LRECUR => "linear-recurrence",
1021        describe::T_INTS_LFSR => "LFSR",
1022        describe::T_INTS_FCSR => "FCSR",
1023        T_FLOATS => "memcpy floats",
1024        T_FLOATS_XOR => "xor-delta floats",
1025        T_FLOATS_CONST => "constant floats",
1026        T_FLOATS_AFFINE => "affine floats",
1027        T_FLOATS_SPARSE => "sparse floats",
1028        T_FLOATS_PERIODIC => "periodic floats",
1029        T_FLOATS_GEOMETRIC => "geometric floats",
1030        T_FLOATS_ALIGNED => "aligned floats",
1031        T_BOOLS => "bit-packed bools",
1032        T_BOOLS_PERIODIC => "periodic bools",
1033        T_BOOLS_RLE => "run-length bools",
1034        T_STRINGS => "flat strings",
1035        T_STRINGS_TEMPLATE => "templated strings",
1036        T_STRINGS_FRONT => "front-coded strings",
1037        T_STRINGS_AFFIX => "affix strings",
1038        T_STRINGS_DICT => "dictionary strings",
1039        T_SET_INTS => "int set (column menu)",
1040        T_SET_STRINGS => "string set (front-coded)",
1041        T_MAP_INTKEY => "int-keyed map (columnar)",
1042        _ => "value",
1043    }
1044}
1045
1046/// Name the structural encoding of each column in a native wire message — the codec
1047/// explaining its own output, so "which dial won" is legible to a human. A single-column
1048/// message (int / float / string / bool list, a set, an int-keyed map) yields one name; a
1049/// record list (`T_STRUCTS`) yields one `"field: encoding"` per field. Empty for a shape it
1050/// does not model (compressed, JSON, a bare scalar, or a malformed frame) — the caller then
1051/// shows a generic label. It reuses the real decode dispatch to skip each column body, so it
1052/// can never drift from the format it reports on.
1053pub fn describe_columns(bytes: &[u8]) -> Vec<String> {
1054    describe_columns_inner(bytes).unwrap_or_default()
1055}
1056
1057fn describe_columns_inner(bytes: &[u8]) -> Option<Vec<String>> {
1058    let (codec, compression, body) = unframe(bytes)?;
1059    if !matches!(codec, WireCodec::Native) || compression != WireCompression::None {
1060        return None; // callers inspect the uncompressed native bytes
1061    }
1062    DECODE_MEMO.with(|c| c.borrow_mut().clear());
1063    let mut pos = 0;
1064    let _from = read_str(body, &mut pos)?;
1065    let tag = *body.get(pos)?;
1066    if tag == T_STRUCTS {
1067        let mut p = pos + 1;
1068        let (_type_name, field_names) = read_struct_schema(body, &mut p)?;
1069        let _rows = read_uvarint(body, &mut p)?;
1070        let mut out = Vec::with_capacity(field_names.len());
1071        for name in &field_names {
1072            let col_tag = *body.get(p)?;
1073            native_decode(body, &mut p)?; // advance past the column via the real decoder
1074            out.push(format!("{name}: {}", column_tag_name(col_tag)));
1075        }
1076        return Some(out);
1077    }
1078    Some(vec![column_tag_name(tag).to_string()])
1079}
1080
1081/// How a connection-scoped schema dictionary identifies a struct schema on the wire.
1082/// All modes are corruption-free; they trade size against robustness.
1083#[derive(Clone, Copy, PartialEq, Eq, Debug, Default)]
1084pub enum WireSchemaMode {
1085    /// No dictionary — the schema is always inline (`T_STRUCTS`). Always safe.
1086    #[default]
1087    Off,
1088    /// Position ids: a 1-byte counter. The smallest, but the id only means anything
1089    /// relative to ONE sender's ordered stream — use only for a reliable
1090    /// point-to-point connection (one sender per receiver cache).
1091    Sequential,
1092    /// Content-addressed: the id is a 64-bit fingerprint of the schema itself, so it
1093    /// is sender-independent and order-independent. Multiple senders, reordering, and
1094    /// loss are all safe (a reference to an unknown fingerprint resolves to `None`,
1095    /// never to the wrong schema; a definition whose fingerprint conflicts with a
1096    /// different cached schema is rejected). The footgun-free default for a mesh.
1097    ContentAddressed,
1098}
1099
1100/// A connection-scoped schema dictionary (one per direction per peer). A struct
1101/// schema (type name + field names) is transmitted ONCE and referenced thereafter —
1102/// the RPC-grade win for streams of same-shaped struct messages. The mode picks the
1103/// id scheme (see [`WireSchemaMode`]); every mode is corruption-free — a decoder that
1104/// cannot resolve a reference returns `None` rather than mis-decoding. An optional
1105/// keyframe interval re-emits a definition every *k* references so a late or lossy
1106/// receiver self-heals.
1107#[derive(Debug)]
1108pub struct WireSchemaCache {
1109    mode: WireSchemaMode,
1110    // Sequential (position) state.
1111    send_seq: std::collections::HashMap<(String, Vec<String>), u32>,
1112    recv_seq: Vec<(String, Vec<String>)>,
1113    next: u32,
1114    // Content-addressed (fingerprint) state.
1115    send_ca: std::collections::HashSet<u64>,
1116    recv_ca: std::collections::HashMap<u64, (String, Vec<String>)>,
1117    // Self-healing: re-emit a definition every `keyframe` references (content mode).
1118    keyframe: Option<u32>,
1119    refs_since_def: std::collections::HashMap<u64, u32>,
1120}
1121
1122impl Default for WireSchemaCache {
1123    /// The footgun-free default: content-addressed.
1124    fn default() -> Self {
1125        Self::with_mode(WireSchemaMode::ContentAddressed)
1126    }
1127}
1128
1129impl WireSchemaCache {
1130    fn with_mode(mode: WireSchemaMode) -> Self {
1131        Self {
1132            mode,
1133            send_seq: std::collections::HashMap::new(),
1134            recv_seq: Vec::new(),
1135            next: 0,
1136            send_ca: std::collections::HashSet::new(),
1137            recv_ca: std::collections::HashMap::new(),
1138            keyframe: None,
1139            refs_since_def: std::collections::HashMap::new(),
1140        }
1141    }
1142    /// Content-addressed (footgun-free): safe for multiple senders, reordering, loss.
1143    pub fn content_addressed() -> Self {
1144        Self::with_mode(WireSchemaMode::ContentAddressed)
1145    }
1146    /// Position ids (smallest): for a single reliable ordered point-to-point stream.
1147    pub fn sequential() -> Self {
1148        Self::with_mode(WireSchemaMode::Sequential)
1149    }
1150    /// Re-emit a schema definition every `k` references, so a late/lossy receiver
1151    /// self-heals (content-addressed mode).
1152    pub fn with_keyframe(mut self, k: u32) -> Self {
1153        self.keyframe = Some(k);
1154        self
1155    }
1156}
1157
1158/// The 64-bit content fingerprint of a struct schema — a sender-independent identity.
1159/// Collisions are negligible for realistic schema counts, and a fingerprint clash
1160/// with a *different* cached schema is rejected on definition, so it cannot corrupt.
1161fn schema_fingerprint(type_name: &str, field_names: &[String]) -> u64 {
1162    let mut bytes = Vec::with_capacity(type_name.len() + 8);
1163    bytes.extend_from_slice(type_name.as_bytes());
1164    for f in field_names {
1165        bytes.push(0);
1166        bytes.extend_from_slice(f.as_bytes());
1167    }
1168    fnv1a_64(&bytes)
1169}
1170
1171/// What the encoder should emit for a struct list's schema, per the active cache.
1172enum SchemaEmit {
1173    Inline,
1174    SeqDef(u32),
1175    SeqRef(u32),
1176    CaDef,
1177    CaRef(u64),
1178}
1179
1180thread_local! {
1181    // The cache in force for the current cached encode/decode. Swapped in by the
1182    // `*_cached` entry points for the duration of the call, then swapped back out.
1183    static SCHEMA_CACHE: RefCell<Option<WireSchemaCache>> = const { RefCell::new(None) };
1184}
1185
1186/// RAII: install `cache` into the thread-local for the duration of a cached
1187/// encode/decode and ALWAYS swap it back out — on normal return AND on a panic
1188/// unwind — so a panic mid-codec can never strand or poison the schema state.
1189struct CacheScope<'a> {
1190    cache: &'a mut WireSchemaCache,
1191}
1192impl<'a> CacheScope<'a> {
1193    fn enter(cache: &'a mut WireSchemaCache) -> Self {
1194        SCHEMA_CACHE.with(|c| *c.borrow_mut() = Some(std::mem::take(cache)));
1195        Self { cache }
1196    }
1197}
1198impl Drop for CacheScope<'_> {
1199    fn drop(&mut self) {
1200        SCHEMA_CACHE.with(|c| *self.cache = c.borrow_mut().take().unwrap_or_default());
1201    }
1202}
1203
1204/// As [`message_to_wire_with`], but a known struct schema is sent by reference
1205/// instead of inline (per the cache's [`WireSchemaMode`]).
1206pub fn message_to_wire_cached(
1207    from: &str,
1208    value: &RuntimeValue,
1209    codec: WireCodec,
1210    integrity: WireIntegrity,
1211    cache: &mut WireSchemaCache,
1212) -> Result<Vec<u8>, String> {
1213    let _scope = CacheScope::enter(cache);
1214    message_to_wire_with(from, value, codec, integrity)
1215}
1216
1217/// As [`message_from_wire`], but resolves schema references against `cache` and
1218/// records schema definitions into it.
1219pub fn message_from_wire_cached(bytes: &[u8], cache: &mut WireSchemaCache) -> Option<(String, RuntimeValue)> {
1220    let _scope = CacheScope::enter(cache);
1221    message_from_wire(bytes)
1222}
1223
1224/// Encode side: decide how to transmit a struct schema, recording state as needed.
1225fn schema_send(type_name: &str, field_names: &[String]) -> SchemaEmit {
1226    SCHEMA_CACHE.with(|c| {
1227        let mut g = c.borrow_mut();
1228        let Some(cache) = g.as_mut() else { return SchemaEmit::Inline };
1229        match cache.mode {
1230            WireSchemaMode::Off => SchemaEmit::Inline,
1231            WireSchemaMode::Sequential => {
1232                let key = (type_name.to_string(), field_names.to_vec());
1233                if let Some(&id) = cache.send_seq.get(&key) {
1234                    SchemaEmit::SeqRef(id)
1235                } else {
1236                    let id = cache.next;
1237                    cache.next += 1;
1238                    cache.send_seq.insert(key, id);
1239                    SchemaEmit::SeqDef(id)
1240                }
1241            }
1242            WireSchemaMode::ContentAddressed => {
1243                let fp = schema_fingerprint(type_name, field_names);
1244                let known = cache.send_ca.contains(&fp);
1245                let count = cache.refs_since_def.entry(fp).or_insert(0);
1246                let keyframe_due = matches!(cache.keyframe, Some(k) if known && *count >= k);
1247                if known && !keyframe_due {
1248                    *count += 1;
1249                    SchemaEmit::CaRef(fp)
1250                } else {
1251                    *count = 0;
1252                    cache.send_ca.insert(fp);
1253                    SchemaEmit::CaDef
1254                }
1255            }
1256        }
1257    })
1258}
1259
1260/// Decode side (sequential): record a definition at `id`. Ids must arrive in order;
1261/// a matching re-definition is tolerated, a gap or a conflict is rejected. `true`
1262/// when there is no cache (a definition is self-decodable inline regardless).
1263fn schema_recv_register_seq(id: u32, type_name: &str, field_names: &[String]) -> bool {
1264    SCHEMA_CACHE.with(|c| {
1265        let mut g = c.borrow_mut();
1266        let Some(cache) = g.as_mut() else { return true };
1267        let entry = (type_name.to_string(), field_names.to_vec());
1268        let idx = id as usize;
1269        if idx == cache.recv_seq.len() {
1270            cache.recv_seq.push(entry);
1271            true
1272        } else if idx < cache.recv_seq.len() {
1273            cache.recv_seq[idx] == entry
1274        } else {
1275            false
1276        }
1277    })
1278}
1279
1280/// Decode side (sequential): resolve a reference; `None` if unknown.
1281fn schema_recv_lookup_seq(id: u32) -> Option<(String, Vec<String>)> {
1282    SCHEMA_CACHE.with(|c| c.borrow().as_ref().and_then(|cache| cache.recv_seq.get(id as usize).cloned()))
1283}
1284
1285/// Decode side (content-addressed): record a definition under its fingerprint. A
1286/// fingerprint that already maps to a DIFFERENT schema (a collision) is rejected —
1287/// so a clash can never corrupt, only fail. `true` when there is no cache.
1288fn schema_recv_register_ca(type_name: &str, field_names: &[String]) -> bool {
1289    SCHEMA_CACHE.with(|c| {
1290        let mut g = c.borrow_mut();
1291        let Some(cache) = g.as_mut() else { return true };
1292        let fp = schema_fingerprint(type_name, field_names);
1293        let entry = (type_name.to_string(), field_names.to_vec());
1294        match cache.recv_ca.get(&fp) {
1295            Some(existing) => *existing == entry, // collision with a different schema → reject
1296            None => {
1297                cache.recv_ca.insert(fp, entry);
1298                true
1299            }
1300        }
1301    })
1302}
1303
1304/// Decode side (content-addressed): resolve a reference by fingerprint; `None` if the
1305/// definition was never seen (reordering / loss / stale decode).
1306fn schema_recv_lookup_ca(fp: u64) -> Option<(String, Vec<String>)> {
1307    SCHEMA_CACHE.with(|c| c.borrow().as_ref().and_then(|cache| cache.recv_ca.get(&fp).cloned()))
1308}
1309
1310/// A program-derived registry of every struct/enum schema, shared by both ends of a
1311/// Logos↔Logos link (each side builds it from the SAME program type definitions). Every
1312/// type gets a stable small id — canonical by fingerprint, so declaration order is
1313/// irrelevant and sender + receiver always agree. The codec ships the id instead of the
1314/// type/field NAMES, and the receiver — running the same program — resolves it. This is
1315/// the "duh, you use that" default that drops names off the wire entirely.
1316#[derive(Debug, Default, Clone)]
1317pub struct WireTypeRegistry {
1318    by_id: Vec<(String, Vec<String>)>,
1319    by_fp: std::collections::HashMap<u64, u32>,
1320    // Enums: id → (type_name, ordered constructor list). The constructor ORDER is part of
1321    // the type def (we ship a constructor *index*), so it is preserved, not sorted.
1322    enums_by_id: Vec<(String, Vec<String>)>,
1323    enums_by_name: std::collections::HashMap<String, u32>,
1324}
1325
1326impl WireTypeRegistry {
1327    /// Build from `(type_name, field_names)` struct schemas. Field names are sorted (the
1328    /// codec's canonical order), duplicates collapsed, and the set ordered by fingerprint
1329    /// so two peers that declared the same types in any order assign identical ids.
1330    pub fn new(schemas: Vec<(String, Vec<String>)>) -> Self {
1331        let mut canon: Vec<(String, Vec<String>)> = schemas
1332            .into_iter()
1333            .map(|(n, mut f)| {
1334                f.sort();
1335                (n, f)
1336            })
1337            .collect();
1338        canon.sort_by_key(|(n, f)| schema_fingerprint(n, f));
1339        canon.dedup_by_key(|(n, f)| schema_fingerprint(n, f));
1340        let by_fp = canon
1341            .iter()
1342            .enumerate()
1343            .map(|(i, (n, f))| (schema_fingerprint(n, f), i as u32))
1344            .collect();
1345        Self { by_id: canon, by_fp, ..Self::default() }
1346    }
1347
1348    /// Add enum types `(type_name, ordered_constructors)`. Constructor order is preserved
1349    /// (the wire ships a constructor index); the enum set is ordered by fingerprint so
1350    /// both peers assign identical enum ids regardless of declaration order.
1351    pub fn with_enums(mut self, enums: Vec<(String, Vec<String>)>) -> Self {
1352        let mut canon = enums;
1353        canon.sort_by_key(|(n, c)| schema_fingerprint(n, c));
1354        canon.dedup_by_key(|(n, c)| schema_fingerprint(n, c));
1355        self.enums_by_name = canon
1356            .iter()
1357            .enumerate()
1358            .map(|(i, (n, _))| (n.clone(), i as u32))
1359            .collect();
1360        self.enums_by_id = canon;
1361        self
1362    }
1363
1364    /// A content hash of this registry's WHOLE type set — the registry EPOCH advertised in the
1365    /// handshake. Two peers that declared the SAME struct + enum types (in any order) compute the same
1366    /// epoch, so when their epochs MATCH they may elide type NAMES from the wire (type-id). `0` for an
1367    /// empty registry — no shared types, so never elide. Deterministic: folds the per-type
1368    /// fingerprints, which are already in canonical fingerprint order.
1369    pub fn epoch(&self) -> u64 {
1370        if self.by_id.is_empty() && self.enums_by_id.is_empty() {
1371            return 0;
1372        }
1373        let mut acc: u64 = 0xcbf2_9ce4_8422_2325;
1374        for (n, f) in &self.by_id {
1375            acc = acc.rotate_left(5) ^ schema_fingerprint(n, f);
1376        }
1377        for (n, c) in &self.enums_by_id {
1378            acc = acc.rotate_left(7) ^ schema_fingerprint(n, c).wrapping_mul(0x0000_0100_0000_01b3);
1379        }
1380        acc.max(1) // a non-empty registry is never epoch 0 (0 means "no registry")
1381    }
1382
1383    fn id_of(&self, type_name: &str, field_names: &[String]) -> Option<u32> {
1384        self.by_fp.get(&schema_fingerprint(type_name, field_names)).copied()
1385    }
1386    fn schema_of(&self, id: u32) -> Option<(String, Vec<String>)> {
1387        self.by_id.get(id as usize).cloned()
1388    }
1389    /// The enum id + the constructor's index, when this enum type is registered.
1390    fn enum_id_of(&self, type_name: &str, constructor: &str) -> Option<(u32, u32)> {
1391        let id = *self.enums_by_name.get(type_name)?;
1392        let (_, ctors) = self.enums_by_id.get(id as usize)?;
1393        let idx = ctors.iter().position(|c| c == constructor)? as u32;
1394        Some((id, idx))
1395    }
1396    /// The `(type_name, ordered constructors)` for an enum id.
1397    fn enum_schema_of(&self, id: u32) -> Option<(String, Vec<String>)> {
1398        self.enums_by_id.get(id as usize).cloned()
1399    }
1400}
1401
1402thread_local! {
1403    static TYPE_REGISTRY: RefCell<Option<WireTypeRegistry>> = const { RefCell::new(None) };
1404}
1405
1406/// Install a shared type registry for the duration of `f` (consulted by BOTH encode and
1407/// decode). Restores the previous registry on return or panic.
1408pub fn with_type_registry<T>(reg: WireTypeRegistry, f: impl FnOnce() -> T) -> T {
1409    struct Restore(Option<WireTypeRegistry>);
1410    impl Drop for Restore {
1411        fn drop(&mut self) {
1412            TYPE_REGISTRY.with(|c| *c.borrow_mut() = self.0.take());
1413        }
1414    }
1415    let _restore = Restore(TYPE_REGISTRY.with(|c| c.borrow_mut().replace(reg)));
1416    f()
1417}
1418
1419/// The id the active registry assigns this struct/enum schema, if it knows it.
1420fn type_registry_id(type_name: &str, field_names: &[String]) -> Option<u32> {
1421    TYPE_REGISTRY.with(|c| c.borrow().as_ref().and_then(|r| r.id_of(type_name, field_names)))
1422}
1423
1424/// Resolve a registry id back to its `(type_name, field_names)` schema.
1425fn type_registry_schema(id: u32) -> Option<(String, Vec<String>)> {
1426    TYPE_REGISTRY.with(|c| c.borrow().as_ref().and_then(|r| r.schema_of(id)))
1427}
1428
1429/// The active registry's `(enum_id, constructor_index)` for an enum value, if known.
1430fn type_registry_enum_id(type_name: &str, constructor: &str) -> Option<(u32, u32)> {
1431    TYPE_REGISTRY.with(|c| c.borrow().as_ref().and_then(|r| r.enum_id_of(type_name, constructor)))
1432}
1433
1434/// Resolve an enum id back to its `(type_name, ordered constructors)`.
1435fn type_registry_enum_schema(id: u32) -> Option<(String, Vec<String>)> {
1436    TYPE_REGISTRY.with(|c| c.borrow().as_ref().and_then(|r| r.enum_schema_of(id)))
1437}
1438
1439thread_local! {
1440    // Rc-DEDUP (G8): when enabled, a subtree that the SAME `Rc` reaches more than once on the value
1441    // graph ships ONCE (`T_SHARED_DEF id + value`) and every later occurrence ships a tiny backref
1442    // (`T_SHARED_REF id`) — and the decoder rebuilds the SHARING (one `Rc`, aliased), not N copies.
1443    // Off by default, so every existing byte-stream is untouched; a value with no actual sharing is
1444    // byte-identical even with the knob on (nothing is in `ENCODE_SHARED`, so no tag is emitted).
1445    static DEDUP_ENABLED: std::cell::Cell<bool> = const { std::cell::Cell::new(false) };
1446    // The set of `Rc` pointers that occur ≥2× — computed once at the root encode. `None` until the
1447    // root gathers it (the lazy-init signal).
1448    static ENCODE_SHARED: RefCell<Option<std::collections::HashSet<usize>>> = const { RefCell::new(None) };
1449    // Shared pointer → the id assigned at its first occurrence (so later occurrences reference it).
1450    static ENCODE_WRITTEN: RefCell<std::collections::HashMap<usize, u64>> =
1451        RefCell::new(std::collections::HashMap::new());
1452    // Decode side: id → the value first decoded under it, so a `T_SHARED_REF` resolves to the SAME
1453    // `Rc` (sharing preserved). Reset at the top of every top-level `message_from_wire`.
1454    static DECODE_MEMO: RefCell<std::collections::HashMap<u64, RuntimeValue>> =
1455        RefCell::new(std::collections::HashMap::new());
1456}
1457
1458/// Encode `f`'s value with Rc-dedup ON: shared subtrees ship once + backrefs. Self-describing by tag,
1459/// so the receiver rebuilds the sharing with no knob of its own. The default (OFF) is byte-unchanged.
1460pub fn with_dedup<T>(enabled: bool, f: impl FnOnce() -> T) -> T {
1461    let prev = DEDUP_ENABLED.with(|c| c.replace(enabled));
1462    ENCODE_SHARED.with(|c| *c.borrow_mut() = None);
1463    ENCODE_WRITTEN.with(|c| c.borrow_mut().clear());
1464    let r = f();
1465    DEDUP_ENABLED.with(|c| c.set(prev));
1466    ENCODE_SHARED.with(|c| *c.borrow_mut() = None);
1467    ENCODE_WRITTEN.with(|c| c.borrow_mut().clear());
1468    r
1469}
1470
1471/// The `Rc`-backed value types whose pointer identity can be shared — the dedup candidates. A
1472/// `usize` address uniquely keys an allocation (two `Rc`s of one allocation share it; distinct
1473/// allocations never collide, even across types).
1474fn shareable_ptr(v: &RuntimeValue) -> Option<usize> {
1475    match v {
1476        RuntimeValue::List(rc) => Some(Rc::as_ptr(rc) as *const () as usize),
1477        RuntimeValue::Tuple(rc) => Some(Rc::as_ptr(rc) as *const () as usize),
1478        RuntimeValue::Set(rc) => Some(Rc::as_ptr(rc) as *const () as usize),
1479        RuntimeValue::Map(rc) => Some(Rc::as_ptr(rc) as *const () as usize),
1480        RuntimeValue::Text(rc) => Some(Rc::as_ptr(rc) as *const () as usize),
1481        RuntimeValue::BigInt(rc) => Some(Rc::as_ptr(rc) as *const () as usize),
1482        RuntimeValue::Rational(rc) => Some(Rc::as_ptr(rc) as *const () as usize),
1483        RuntimeValue::Decimal(rc) => Some(Rc::as_ptr(rc) as *const () as usize),
1484        RuntimeValue::Money(rc) => Some(Rc::as_ptr(rc) as *const () as usize),
1485        RuntimeValue::Complex(rc) => Some(Rc::as_ptr(rc) as *const () as usize),
1486        RuntimeValue::Modular(rc) => Some(Rc::as_ptr(rc) as *const () as usize),
1487        RuntimeValue::Quantity(rc) => Some(Rc::as_ptr(rc) as *const () as usize),
1488        _ => None,
1489    }
1490}
1491
1492/// Walk the value graph counting `Rc` occurrences; any pointer seen ≥2× goes in `shared`. Cycle-safe
1493/// (a pointer is descended into only on its FIRST sighting; the 2nd marks it shared and stops) and
1494/// depth-bounded (deep non-cyclic nesting just stops gathering — missing a share only costs a little
1495/// size, never correctness).
1496fn gather_shared(
1497    v: &RuntimeValue,
1498    seen: &mut std::collections::HashMap<usize, u32>,
1499    shared: &mut std::collections::HashSet<usize>,
1500    depth: u32,
1501) {
1502    if depth >= MAX_ENCODE_DEPTH {
1503        return;
1504    }
1505    if let Some(p) = shareable_ptr(v) {
1506        let c = seen.entry(p).or_insert(0);
1507        *c += 1;
1508        if *c >= 2 {
1509            shared.insert(p);
1510            return; // already descended on the first sighting — stop (this is the cycle guard too)
1511        }
1512    }
1513    match v {
1514        RuntimeValue::List(rc) => {
1515            if let ListRepr::Boxed(items) = &*rc.borrow() {
1516                for x in items {
1517                    gather_shared(x, seen, shared, depth + 1);
1518                }
1519            }
1520        }
1521        RuntimeValue::Tuple(rc) => {
1522            for x in rc.iter() {
1523                gather_shared(x, seen, shared, depth + 1);
1524            }
1525        }
1526        RuntimeValue::Set(rc) => {
1527            for x in rc.borrow().iter() {
1528                gather_shared(x, seen, shared, depth + 1);
1529            }
1530        }
1531        RuntimeValue::Map(rc) => {
1532            for (k, val) in rc.borrow().iter() {
1533                gather_shared(k, seen, shared, depth + 1);
1534                gather_shared(val, seen, shared, depth + 1);
1535            }
1536        }
1537        RuntimeValue::Struct(b) => {
1538            for val in b.fields.values() {
1539                gather_shared(val, seen, shared, depth + 1);
1540            }
1541        }
1542        RuntimeValue::Inductive(b) => {
1543            for x in &b.args {
1544                gather_shared(x, seen, shared, depth + 1);
1545            }
1546        }
1547        _ => {}
1548    }
1549}
1550
1551/// Does `v` actually alias a subtree — the same `Rc` reached more than once? The auto-tuner asks this
1552/// (one cheap graph walk) to decide whether the dedup candidate is even worth trying; a tree-shaped
1553/// value answers `false` and pays nothing more.
1554fn value_has_sharing(v: &RuntimeValue) -> bool {
1555    let mut seen = std::collections::HashMap::new();
1556    let mut shared = std::collections::HashSet::new();
1557    gather_shared(v, &mut seen, &mut shared, 0);
1558    !shared.is_empty()
1559}
1560
1561/// At the encoder's entry for `v`: if dedup is on, lazily gather the shared set at the root, then —
1562/// for a shared value — emit a backref (and signal `caller returns`) or stamp a fresh def id (and
1563/// let the caller fall through to encode the value normally). Returns `Some(true)` = "I wrote a
1564/// backref, return now", `Some(false)`/`None` = "keep encoding".
1565fn dedup_encode_prefix(v: &RuntimeValue, out: &mut Vec<u8>) -> bool {
1566    if !DEDUP_ENABLED.with(|c| c.get()) {
1567        return false;
1568    }
1569    if ENCODE_SHARED.with(|c| c.borrow().is_none()) {
1570        let mut seen = std::collections::HashMap::new();
1571        let mut shared = std::collections::HashSet::new();
1572        gather_shared(v, &mut seen, &mut shared, 0);
1573        ENCODE_SHARED.with(|c| *c.borrow_mut() = Some(shared));
1574        ENCODE_WRITTEN.with(|c| c.borrow_mut().clear());
1575    }
1576    let Some(p) = shareable_ptr(v) else { return false };
1577    let is_shared = ENCODE_SHARED.with(|c| c.borrow().as_ref().is_some_and(|s| s.contains(&p)));
1578    if !is_shared {
1579        return false;
1580    }
1581    if let Some(id) = ENCODE_WRITTEN.with(|c| c.borrow().get(&p).copied()) {
1582        out.push(T_SHARED_REF);
1583        write_uvarint(id, out);
1584        return true; // a backref — caller returns
1585    }
1586    let id = ENCODE_WRITTEN.with(|c| {
1587        let mut m = c.borrow_mut();
1588        let id = m.len() as u64;
1589        m.insert(p, id);
1590        id
1591    });
1592    out.push(T_SHARED_DEF);
1593    write_uvarint(id, out);
1594    false // first occurrence — caller encodes the value normally after this def header
1595}
1596
1597thread_local! {
1598    static STRUCT_VIEW: std::cell::Cell<bool> = const { std::cell::Cell::new(false) };
1599    // Current value-recursion depth of the encoder — bounds nesting so a cyclic value
1600    // (only constructible via the `Rc<RefCell<…>>` a List wraps) returns a clean Err
1601    // instead of overflowing the stack. Reset to 0 by the guard as the recursion unwinds.
1602    static ENCODE_DEPTH: std::cell::Cell<u32> = const { std::cell::Cell::new(0) };
1603}
1604
1605// Bounds value-recursion depth (NESTING, not breadth — a million-element list is depth 2).
1606// 128 levels is far beyond any real payload yet safe on the small stacks this runs on: an
1607// unoptimized `native_encode`/`encode_list_repr` frame is several KiB in debug, so the cap
1608// must stay well under a 2 MiB worker/test or ~1 MiB wasm stack — 128 leaves a wide margin.
1609const MAX_ENCODE_DEPTH: u32 = 128;
1610
1611/// RAII depth counter for the recursive encoder. `enter()` fails (rather than recursing
1612/// into a stack overflow) once nesting passes [`MAX_ENCODE_DEPTH`]; `Drop` unwinds it.
1613struct DepthGuard;
1614impl DepthGuard {
1615    fn enter() -> Result<DepthGuard, String> {
1616        ENCODE_DEPTH.with(|d| {
1617            let n = d.get();
1618            if n >= MAX_ENCODE_DEPTH {
1619                return Err(format!(
1620                    "value nested deeper than {MAX_ENCODE_DEPTH} (cyclic or pathological) — not encodable"
1621                ));
1622            }
1623            d.set(n + 1);
1624            Ok(DepthGuard)
1625        })
1626    }
1627}
1628impl Drop for DepthGuard {
1629    fn drop(&mut self) {
1630        ENCODE_DEPTH.with(|d| d.set(d.get().saturating_sub(1)));
1631    }
1632}
1633
1634/// RAII depth counter for the recursive DECODER — the admission gate against a stack-smashing message.
1635/// `enter()` returns `None` (so `native_decode` rejects cleanly via `?`) once nesting reaches the
1636/// receiver's [`ReceiveLimits::max_depth`], instead of recursing into a stack overflow on a crafted
1637/// deeply-nested payload. `Drop` unwinds the count on every path — normal return, `?`-`None`, and panic
1638/// unwind — so a fresh top-level decode always starts at zero.
1639struct DecodeDepthGuard;
1640impl DecodeDepthGuard {
1641    fn enter() -> Option<DecodeDepthGuard> {
1642        DECODE_DEPTH.with(|d| {
1643            let n = d.get();
1644            if n >= receive_limits().max_depth {
1645                return None;
1646            }
1647            d.set(n + 1);
1648            Some(DecodeDepthGuard)
1649        })
1650    }
1651}
1652impl Drop for DecodeDepthGuard {
1653    fn drop(&mut self) {
1654        DECODE_DEPTH.with(|d| d.set(d.get().saturating_sub(1)));
1655    }
1656}
1657
1658/// Encode structs in the offset-table `T_STRUCT_VIEW` layout for the duration of `f`, so a
1659/// `WireView` reads any single field in O(1) (the Cap'n Proto-beating random-access mode).
1660/// Larger than the packed forms — it is the speed end of the size↔speed dial.
1661pub fn with_struct_view<T>(on: bool, f: impl FnOnce() -> T) -> T {
1662    let prev = STRUCT_VIEW.with(|c| c.replace(on));
1663    let out = f();
1664    STRUCT_VIEW.with(|c| c.set(prev));
1665    out
1666}
1667
1668fn struct_view_on() -> bool {
1669    STRUCT_VIEW.with(std::cell::Cell::get)
1670}
1671
1672// ---- The native single-pass codec: RuntimeValue <-> tagged-varint bytes -----
1673//
1674// One byte of type tag, then a varint/utf8 payload. Signed integers are
1675// zig-zag + LEB128 (small magnitudes cost a byte); lengths are LEB128. Structs
1676// and maps are written in canonical order (fields by name, entries by key bytes)
1677// so the encoding is deterministic. Non-portable values (closures, scheduler
1678// handles) are rejected here, on the spot.
1679
1680// =====================================================================================
1681// Zero-copy WireView — read ONE field/element without decoding the whole message.
1682// Borrows the wire bytes (`&'a [u8]`); a fixed-width array element is read in O(1) at its
1683// byte offset with ZERO allocation. Matches Cap'n Proto / Arrow random-access (O(1), no
1684// parse) while staying varint-small — `Send fast` (the fixed layout) is the zero-copy one.
1685// =====================================================================================
1686
1687/// Advance `pos` past a length-prefixed string without allocating it.
1688fn skip_str(buf: &[u8], pos: &mut usize) -> Option<()> {
1689    let n = read_uvarint(buf, pos)? as usize;
1690    let end = pos.checked_add(n)?;
1691    if end > buf.len() {
1692        return None;
1693    }
1694    *pos = end;
1695    Some(())
1696}
1697
1698/// Decode a received message LAZILY when its top-level value is a self-describing record-list view
1699/// (`T_STRUCTS_VIEW`): returns `(sender, List(WireStructs))` holding the raw frame, so NO row is
1700/// decoded until a field is touched — the production zero-copy receive ("no decode in production",
1701/// Cap'n Proto's home). Any other shape (scalars, maps, single structs, cached/compressed bodies)
1702/// falls back to a full [`message_from_wire`] decode, so every message still round-trips. The
1703/// receiver opts in with the `view` knob; without it, the eager path is used exactly as before.
1704/// Peek a frame: if its top-level value is a self-describing DEFERRABLE view — a record list
1705/// (`T_STRUCTS_VIEW`) or an aligned numeric column (`T_INTS_ALIGNED`/`T_FLOATS_ALIGNED`), all of
1706/// which have no schema-cache dependency — return the sender so its decode can be deferred to
1707/// `Await` (lazy under `view`, eager otherwise). `None` for anything else (scalars, single structs,
1708/// maps, cached, or compressed bodies), which must decode eagerly in arrival order. The drain loop
1709/// uses this to split deferrable views from order-sensitive messages.
1710pub fn peek_deferrable_sender(bytes: &[u8]) -> Option<String> {
1711    let view = view_message(bytes)?;
1712    let deferrable =
1713        view.structs_schema().is_some() || matches!(view.tag(), Some(T_INTS_ALIGNED) | Some(T_FLOATS_ALIGNED));
1714    if !deferrable {
1715        return None;
1716    }
1717    let (_, _, body) = unframe_with(bytes, false)?;
1718    let mut p = 0;
1719    read_str(body, &mut p)
1720}
1721
1722pub fn message_from_wire_view(bytes: &[u8]) -> Option<(String, RuntimeValue)> {
1723    // Only a self-describing native record-list view is lazily wrappable.
1724    if view_message(bytes).and_then(|v| v.structs_schema()).is_some() {
1725        let (_, _, body) = unframe_with(bytes, false)?;
1726        let mut p = 0;
1727        let sender = read_str(body, &mut p)?; // the sender prefix at the body's head
1728        let lazy = crate::interpreter::ListRepr::from_record_list_view(Rc::new(bytes.to_vec()))?;
1729        return Some((sender, RuntimeValue::List(Rc::new(RefCell::new(lazy)))));
1730    }
1731    message_from_wire(bytes)
1732}
1733
1734/// The leading marker of a batch STREAM message — distinct from any normal frame header (those use
1735/// only the low bits 0x01/0x02/0x10 + a 2-bit compression id) and from a FEC shard (0xFE), so the
1736/// drain loop tells the three apart by the first byte alone.
1737const STREAM_MAGIC: u8 = 0xFD;
1738
1739/// Frame a sequence of values as one batch STREAM message: `[magic][sender][framed value-message]*`,
1740/// each value length-delimited (via [`crate::concurrency::stream::frame_for_stream`]) so the
1741/// receiver deframes them incrementally and reads each in place. ONE relay publish ships the whole
1742/// batch — Kafka-style streaming that amortizes per-message overhead — and `Await stream` reassembles
1743/// the list. Each value is encoded self-describingly so it round-trips without the type registry.
1744pub fn frame_stream_message(from: &str, values: &[RuntimeValue]) -> Result<Vec<u8>, String> {
1745    let mut out = vec![STREAM_MAGIC];
1746    write_str(from, &mut out);
1747    for v in values {
1748        let elem = message_to_wire("", v)?;
1749        crate::concurrency::stream::frame_for_stream(&elem, &mut out);
1750    }
1751    Ok(out)
1752}
1753
1754/// Is `bytes` a batch stream message? If so, return its sender (so `Await stream … from <peer>`
1755/// matches it). `None` for a normal message / FEC shard / anything else.
1756pub fn peek_stream_sender(bytes: &[u8]) -> Option<String> {
1757    if bytes.first() != Some(&STREAM_MAGIC) {
1758        return None;
1759    }
1760    let mut p = 1;
1761    read_str(bytes, &mut p)
1762}
1763
1764/// Deframe a batch stream message into its values, in order. `None` if `bytes` is not a stream
1765/// message; a frame that fails to decode is skipped (never a panic).
1766pub fn deframe_stream_message(bytes: &[u8]) -> Option<Vec<RuntimeValue>> {
1767    if bytes.first() != Some(&STREAM_MAGIC) {
1768        return None;
1769    }
1770    let mut p = 1;
1771    read_str(bytes, &mut p)?;
1772    let mut deframer = crate::concurrency::stream::StreamDeframer::new();
1773    deframer.push(bytes.get(p..)?);
1774    let mut values = Vec::new();
1775    deframer.drain_frames(|frame| {
1776        if let Some((_, v)) = message_from_wire(frame) {
1777            values.push(v);
1778        }
1779    });
1780    Some(values)
1781}
1782
1783/// A borrowed view over one wire message's top-level value. Holds no owned data and never
1784/// decodes the rest of the message; reads are in place. Open it with [`view_message`].
1785#[derive(Clone, Copy)]
1786pub struct WireView<'a> {
1787    /// Slice starting at the top-level value's tag byte.
1788    val: &'a [u8],
1789}
1790
1791/// Open a borrowed, zero-alloc view over `bytes`. `None` for a compressed or JSON message
1792/// (those must be inflated/decoded first — the view is over raw native bytes) or a
1793/// malformed frame. Reads any single field in place afterward.
1794pub fn view_message(bytes: &[u8]) -> Option<WireView<'_>> {
1795    // `verify = false`: opening a view is O(1) even on a checksummed message — validating
1796    // the FNV sum would re-hash the whole body, defeating zero-copy random access. The view
1797    // trusts the bytes (Cap'n Proto / Arrow have no checksum at all); callers wanting
1798    // integrity use a full decode, which validates.
1799    let (codec, compression, body) = unframe_with(bytes, false)?;
1800    if !matches!(codec, WireCodec::Native) || compression != WireCompression::None {
1801        return None;
1802    }
1803    let mut pos = 0;
1804    skip_str(body, &mut pos)?; // skip the sender prefix
1805    Some(WireView { val: body.get(pos..)? })
1806}
1807
1808impl<'a> WireView<'a> {
1809    fn tag(&self) -> Option<u8> {
1810        self.val.first().copied()
1811    }
1812
1813    /// The top-level value as an integer (`T_INT`).
1814    pub fn as_int(&self) -> Option<i64> {
1815        if self.tag()? != T_INT {
1816            return None;
1817        }
1818        let mut p = 1;
1819        Some(unzigzag(read_uvarint(self.val, &mut p)?))
1820    }
1821
1822    /// The top-level value as a float (`T_FLOAT`).
1823    pub fn as_float(&self) -> Option<f64> {
1824        if self.tag()? != T_FLOAT {
1825            return None;
1826        }
1827        let b = self.val.get(1..9)?;
1828        Some(f64::from_le_bytes(b.try_into().ok()?))
1829    }
1830
1831    /// Read ONE field of an offset-table struct view (`T_STRUCT_VIEW`): scan the small
1832    /// name table, then jump to the field's value via the offset table — WITHOUT parsing
1833    /// any other field, however large. The Cap'n Proto-class random-access read; returns
1834    /// a sub-view you read with `as_int`/`as_float`/etc. `None` if not a view or no field.
1835    pub fn struct_field(&self, name: &str) -> Option<WireView<'a>> {
1836        if self.tag()? != T_STRUCT_VIEW {
1837            return None;
1838        }
1839        let mut p = 1;
1840        skip_str(self.val, &mut p)?; // type_name
1841        let count = read_uvarint(self.val, &mut p)? as usize;
1842        let mut idx = None;
1843        for i in 0..count {
1844            let nlen = read_uvarint(self.val, &mut p)? as usize;
1845            let nbytes = self.val.get(p..p.checked_add(nlen)?)?;
1846            if nbytes == name.as_bytes() {
1847                idx = Some(i);
1848            }
1849            p += nlen;
1850        }
1851        let idx = idx?;
1852        let table_pos = p;
1853        let off_at = table_pos.checked_add(idx.checked_mul(4)?)?;
1854        let off_bytes = self.val.get(off_at..off_at.checked_add(4)?)?;
1855        let offset = u32::from_le_bytes(off_bytes.try_into().ok()?) as usize;
1856        let values_start = table_pos.checked_add(count.checked_mul(4)?)?;
1857        Some(WireView { val: self.val.get(values_start.checked_add(offset)?..)? })
1858    }
1859
1860    /// Read an 8-byte-aligned i64 column (`T_INTS_ALIGNED`) as `&[i64]` with ZERO copy —
1861    /// the in-place column read (the kernel-bypass / RDMA path: no per-element decode, no
1862    /// `memcpy`). `None` if it is not an aligned column or the bytes are not 8-aligned in
1863    /// this buffer (then the caller decodes/copies instead, still one `memcpy`).
1864    pub fn as_i64_slice(&self) -> Option<&'a [i64]> {
1865        if self.tag()? != T_INTS_ALIGNED {
1866            return None;
1867        }
1868        let mut p = 1;
1869        let n = read_uvarint(self.val, &mut p)? as usize;
1870        let pad = *self.val.get(p)? as usize;
1871        p += 1 + pad;
1872        let nbytes = n.checked_mul(8)?;
1873        let blob = self.val.get(p..p.checked_add(nbytes)?)?;
1874        if blob.as_ptr() as usize % 8 != 0 {
1875            return None; // not 8-aligned in this buffer → caller copies
1876        }
1877        // SAFETY: `blob` is exactly `n*8` bytes, 8-byte aligned, borrowed for `'a`; every
1878        // bit pattern is a valid `i64`.
1879        Some(unsafe { std::slice::from_raw_parts(blob.as_ptr().cast::<i64>(), n) })
1880    }
1881
1882    /// Read an 8-byte-aligned f64 column (`T_FLOATS_ALIGNED`) as `&[f64]` with ZERO copy —
1883    /// the float twin of [`as_i64_slice`](Self::as_i64_slice). `None` if it is not an
1884    /// aligned float column or the bytes are not 8-aligned in this buffer (caller copies).
1885    pub fn as_f64_slice(&self) -> Option<&'a [f64]> {
1886        if self.tag()? != T_FLOATS_ALIGNED {
1887            return None;
1888        }
1889        let mut p = 1;
1890        let n = read_uvarint(self.val, &mut p)? as usize;
1891        let pad = *self.val.get(p)? as usize;
1892        p += 1 + pad;
1893        let nbytes = n.checked_mul(8)?;
1894        let blob = self.val.get(p..p.checked_add(nbytes)?)?;
1895        if blob.as_ptr() as usize % 8 != 0 {
1896            return None; // not 8-aligned in this buffer → caller copies
1897        }
1898        // SAFETY: `blob` is exactly `n*8` bytes, 8-byte aligned, borrowed for `'a`; every
1899        // bit pattern is a valid `f64` (NaN/Inf/subnormal included — all read verbatim).
1900        Some(unsafe { std::slice::from_raw_parts(blob.as_ptr().cast::<f64>(), n) })
1901    }
1902
1903    /// Read field `fi` of a COLUMNAR fixed struct list (`T_STRUCTS` whose every column is a
1904    /// `T_INTS_FIXED` blob) as its contiguous little-endian `i64` bytes — zero-copy, no per-cell
1905    /// navigation and no materialization. Because the layout is columnar, ALL of field `fi` is
1906    /// adjacent, so summing/scanning it is one CACHE-FRIENDLY contiguous pass — the columnar-
1907    /// analytics win over a row-major reader's strided walk (Cap'n Proto interleaves the fields).
1908    /// `None` if the value is not a columnar all-fixed struct list, or `fi` is out of range.
1909    pub fn structs_fixed_i64_col(&self, fi: usize) -> Option<&'a [u8]> {
1910        if self.tag()? != T_STRUCTS {
1911            return None;
1912        }
1913        let mut p = 1;
1914        skip_str(self.val, &mut p)?; // type_name
1915        let k = read_uvarint(self.val, &mut p)? as usize;
1916        if fi >= k {
1917            return None;
1918        }
1919        for _ in 0..k {
1920            skip_str(self.val, &mut p)?; // field names
1921        }
1922        let n = read_uvarint(self.val, &mut p)? as usize;
1923        for c in 0..=fi {
1924            if *self.val.get(p)? != T_INTS_FIXED {
1925                return None; // a non-fixed column — this fast path needs all columns fixed-width
1926            }
1927            p += 1;
1928            let cnt = read_uvarint(self.val, &mut p)? as usize;
1929            if cnt != n {
1930                return None;
1931            }
1932            let nbytes = n.checked_mul(8)?;
1933            let blob = self.val.get(p..p.checked_add(nbytes)?)?;
1934            if c == fi {
1935                return Some(blob);
1936            }
1937            p += nbytes;
1938        }
1939        None
1940    }
1941
1942    /// Read a byte column (`T_BYTES`) as `&[u8]` with ZERO copy — binary data (hashes, file
1943    /// chunks, crypto) read in place: no decode, no allocation, no `i64` expansion, and
1944    /// (unlike the i64/f64 columns) no alignment requirement, since a `u8` slice is always
1945    /// 1-aligned. The first-class `bytes`/`Data` read that bit-packing can never offer.
1946    /// `None` if this is not a byte column.
1947    pub fn as_byte_slice(&self) -> Option<&'a [u8]> {
1948        if self.tag()? != T_BYTES {
1949            return None;
1950        }
1951        let mut p = 1;
1952        let n = read_uvarint(self.val, &mut p)? as usize;
1953        self.val.get(p..p.checked_add(n)?)
1954    }
1955
1956    /// Row count of a record-list view (variable `T_STRUCTS_VIEW` or fixed `T_STRUCTS_FVIEW`),
1957    /// or `None` if not one.
1958    pub fn structs_len(&self) -> Option<usize> {
1959        let tag = self.tag()?;
1960        if tag != T_STRUCTS_VIEW && tag != T_STRUCTS_FVIEW {
1961            return None;
1962        }
1963        let mut p = 1;
1964        skip_str(self.val, &mut p)?; // type_name
1965        let f = read_uvarint(self.val, &mut p)? as usize;
1966        for _ in 0..f {
1967            let nlen = read_uvarint(self.val, &mut p)? as usize;
1968            p = p.checked_add(nlen)?;
1969        }
1970        if tag == T_STRUCTS_FVIEW {
1971            p = p.checked_add(f)?; // skip the F kind bytes
1972        }
1973        Some(read_uvarint(self.val, &mut p)? as usize)
1974    }
1975
1976    /// Read field `name` of row `row` in a record-list view (`T_STRUCTS_VIEW`) in O(1):
1977    /// scan the shared name table once for the field index, jump via the row-offset table
1978    /// to the row block, then via that row's field-offset table to the value — NEVER parsing
1979    /// the other rows or fields, however large the list. The Cap'n Proto-class random access
1980    /// into a record list. Returns a sub-view (`as_int`/`as_float`/…). `None` if not a record
1981    /// view, the row is out of range, or no such field.
1982    pub fn structs_row_field(&self, row: usize, name: &str) -> Option<WireView<'a>> {
1983        if self.tag()? != T_STRUCTS_VIEW {
1984            return None;
1985        }
1986        let mut p = 1;
1987        skip_str(self.val, &mut p)?; // type_name
1988        let f = read_uvarint(self.val, &mut p)? as usize;
1989        let mut field_idx = None;
1990        for i in 0..f {
1991            let nlen = read_uvarint(self.val, &mut p)? as usize;
1992            let nbytes = self.val.get(p..p.checked_add(nlen)?)?;
1993            if nbytes == name.as_bytes() {
1994                field_idx = Some(i);
1995            }
1996            p += nlen;
1997        }
1998        let fi = field_idx?;
1999        let n = read_uvarint(self.val, &mut p)? as usize;
2000        if row >= n {
2001            return None;
2002        }
2003        let row_table_pos = p;
2004        let rows_start = row_table_pos.checked_add(n.checked_mul(4)?)?;
2005        let row_off_at = row_table_pos.checked_add(row.checked_mul(4)?)?;
2006        let row_off =
2007            u32::from_le_bytes(self.val.get(row_off_at..row_off_at.checked_add(4)?)?.try_into().ok()?) as usize;
2008        let field_table_pos = rows_start.checked_add(row_off)?;
2009        let values_start = field_table_pos.checked_add(f.checked_mul(4)?)?;
2010        let field_off_at = field_table_pos.checked_add(fi.checked_mul(4)?)?;
2011        let field_off =
2012            u32::from_le_bytes(self.val.get(field_off_at..field_off_at.checked_add(4)?)?.try_into().ok()?) as usize;
2013        Some(WireView { val: self.val.get(values_start.checked_add(field_off)?..)? })
2014    }
2015
2016    /// Read field `name` of row `row` as an owned value for EITHER record-list view: the variable
2017    /// offset-table view (`T_STRUCTS_VIEW`) or the fixed-stride view (`T_STRUCTS_FVIEW`). Both are
2018    /// O(1) random access — the fixed view by pure arithmetic (no offset tables). Numeric/bool
2019    /// reads allocate nothing; a text read materializes the one string. The unified read the lazy
2020    /// `Await view` backing uses, so a peer's `Send indexed` (either layout) reads the same way.
2021    /// `None` if this is not a record view, the row is out of range, or there is no such field.
2022    pub fn structs_row_field_value(&self, row: usize, name: &str) -> Option<RuntimeValue> {
2023        match self.tag()? {
2024            T_STRUCTS_VIEW => self.structs_row_field(row, name)?.decode(),
2025            T_STRUCTS_FVIEW => {
2026                let mut p = 1;
2027                skip_str(self.val, &mut p)?; // type_name
2028                let f = read_uvarint(self.val, &mut p)? as usize;
2029                let mut field_idx = None;
2030                for i in 0..f {
2031                    let nlen = read_uvarint(self.val, &mut p)? as usize;
2032                    let nbytes = self.val.get(p..p.checked_add(nlen)?)?;
2033                    if nbytes == name.as_bytes() {
2034                        field_idx = Some(i);
2035                    }
2036                    p += nlen;
2037                }
2038                let fi = field_idx?;
2039                let kinds = self.val.get(p..p.checked_add(f)?)?;
2040                p += f;
2041                let n = read_uvarint(self.val, &mut p)? as usize;
2042                if row >= n {
2043                    return None;
2044                }
2045                let (offsets, stride) = fview_layout(kinds);
2046                let rows_start = p;
2047                let cell_pos = rows_start.checked_add(row.checked_mul(stride)?)?.checked_add(offsets[fi])?;
2048                // The string blob follows the fixed rows; its length varint sits right after them.
2049                let mut bp = rows_start.checked_add(n.checked_mul(stride)?)?;
2050                let blob_len = read_uvarint(self.val, &mut bp)? as usize;
2051                let blob = self.val.get(bp..bp.checked_add(blob_len)?)?;
2052                fview_read_cell(kinds[fi], self.val.get(cell_pos..)?, blob)
2053            }
2054            _ => None,
2055        }
2056    }
2057
2058    /// Fully decode the ONE value this view points at (a cell / field / element) into an owned
2059    /// `RuntimeValue` — the materialize-on-touch step a lazy reader runs after locating a field in
2060    /// place. Decodes only this value, never the rest of the message; the bytes outside it stay
2061    /// untouched. (Uses the ambient type registry, so it round-trips name-elided cells too.)
2062    pub fn decode(&self) -> Option<RuntimeValue> {
2063        let mut p = 0;
2064        native_decode(self.val, &mut p)
2065    }
2066
2067    /// The schema of a record-list view (`T_STRUCTS_VIEW`): `(type_name, field_names, row_count)`,
2068    /// read from the shared header WITHOUT decoding a single row — so a lazy backing can carry the
2069    /// schema + length while the row bytes stay un-decoded until a field is touched. `None` if this
2070    /// is not a record-list view.
2071    pub fn structs_schema(&self) -> Option<(String, Vec<String>, usize)> {
2072        let tag = self.tag()?;
2073        if tag != T_STRUCTS_VIEW && tag != T_STRUCTS_FVIEW {
2074            return None;
2075        }
2076        let mut p = 1;
2077        let type_name = read_str(self.val, &mut p)?;
2078        let f = read_uvarint(self.val, &mut p)? as usize;
2079        let mut field_names = Vec::with_capacity(f);
2080        for _ in 0..f {
2081            field_names.push(read_str(self.val, &mut p)?);
2082        }
2083        if tag == T_STRUCTS_FVIEW {
2084            p = p.checked_add(f)?; // skip the F kind bytes
2085        }
2086        let n = read_uvarint(self.val, &mut p)? as usize;
2087        Some((type_name, field_names, n))
2088    }
2089
2090    /// The top-level value as a bool.
2091    pub fn as_bool(&self) -> Option<bool> {
2092        match self.tag()? {
2093            T_TRUE => Some(true),
2094            T_FALSE => Some(false),
2095            _ => None,
2096        }
2097    }
2098
2099    /// Element count of a homogeneous int list (`T_INTS` varint or `T_INTS_FIXED`).
2100    pub fn int_list_len(&self) -> Option<usize> {
2101        let mut p = 1;
2102        match self.tag()? {
2103            T_INTS_FIXED => Some(read_uvarint(self.val, &mut p)? as usize),
2104            T_INTS => Some((read_uvarint(self.val, &mut p)? >> 1) as usize),
2105            _ => None,
2106        }
2107    }
2108
2109    /// Element `i` of an int list — O(1) + ZERO ALLOC for the fixed layout (seek to the
2110    /// byte offset, read 8 bytes); O(i) scan for the varint layout, still no full decode.
2111    pub fn int_list_get(&self, i: usize) -> Option<i64> {
2112        match self.tag()? {
2113            T_INTS_FIXED => {
2114                let mut p = 1;
2115                let n = read_uvarint(self.val, &mut p)? as usize;
2116                if i >= n {
2117                    return None;
2118                }
2119                let off = p + i * 8; // O(1): direct seek to element i
2120                let b = self.val.get(off..off + 8)?;
2121                Some(i64::from_le_bytes(b.try_into().ok()?))
2122            }
2123            T_INTS => {
2124                let mut p = 1;
2125                let header = read_uvarint(self.val, &mut p)?;
2126                let signed = header & 1 == 1;
2127                let n = (header >> 1) as usize;
2128                if i >= n {
2129                    return None;
2130                }
2131                for _ in 0..i {
2132                    read_uvarint(self.val, &mut p)?;
2133                }
2134                let u = read_uvarint(self.val, &mut p)?;
2135                Some(if signed { unzigzag(u) } else { u as i64 })
2136            }
2137            _ => None,
2138        }
2139    }
2140
2141    /// Element count of a memcpy float list (`T_FLOATS`).
2142    pub fn float_list_len(&self) -> Option<usize> {
2143        if self.tag()? != T_FLOATS {
2144            return None;
2145        }
2146        let mut p = 1;
2147        Some(read_uvarint(self.val, &mut p)? as usize)
2148    }
2149
2150    /// Element `i` of a memcpy float list — O(1), zero alloc.
2151    pub fn float_list_get(&self, i: usize) -> Option<f64> {
2152        if self.tag()? != T_FLOATS {
2153            return None;
2154        }
2155        let mut p = 1;
2156        let n = read_uvarint(self.val, &mut p)? as usize;
2157        if i >= n {
2158            return None;
2159        }
2160        let off = p + i * 8;
2161        let b = self.val.get(off..off + 8)?;
2162        Some(f64::from_le_bytes(b.try_into().ok()?))
2163    }
2164
2165    /// Open a parse-ONCE bulk cursor over a record-list view (either layout). `None` if this is not
2166    /// a record-list view. Use it to read a WHOLE list as fast as Cap'n Proto's lazy reader:
2167    /// `structs_row_field_value` re-parses the header on every call (fine for one read, O(n·f) for a
2168    /// full scan), whereas the cursor parses the schema/tables once and every access is O(1).
2169    pub fn structs_cursor(&self) -> Option<WireStructsCursor<'a>> {
2170        let tag = self.tag()?;
2171        if tag != T_STRUCTS_VIEW && tag != T_STRUCTS_FVIEW {
2172            return None;
2173        }
2174        let val = self.val;
2175        let mut p = 1;
2176        let tn_len = read_uvarint(val, &mut p)? as usize; // type_name (skipped)
2177        p = p.checked_add(tn_len)?;
2178        let f = read_uvarint(val, &mut p)? as usize;
2179        let mut field_names = Vec::with_capacity(f);
2180        for _ in 0..f {
2181            let nlen = read_uvarint(val, &mut p)? as usize;
2182            field_names.push(val.get(p..p.checked_add(nlen)?)?);
2183            p += nlen;
2184        }
2185        if tag == T_STRUCTS_FVIEW {
2186            let field_kinds = val.get(p..p.checked_add(f)?)?;
2187            p += f;
2188            let n = read_uvarint(val, &mut p)? as usize;
2189            let (field_offsets, stride) = fview_layout(field_kinds);
2190            let rows_start = p;
2191            let mut bp = rows_start.checked_add(n.checked_mul(stride)?)?;
2192            let blob_len = read_uvarint(val, &mut bp)? as usize;
2193            let blob = val.get(bp..bp.checked_add(blob_len)?)?;
2194            Some(WireStructsCursor {
2195                val,
2196                field_names,
2197                n,
2198                kind: CursorKind::Fixed { field_kinds, field_offsets, stride, rows_start, blob },
2199            })
2200        } else {
2201            let n = read_uvarint(val, &mut p)? as usize;
2202            let row_table_pos = p;
2203            let rows_start = row_table_pos.checked_add(n.checked_mul(4)?)?;
2204            Some(WireStructsCursor { val, field_names, n, kind: CursorKind::Variable { row_table_pos, rows_start } })
2205        }
2206    }
2207}
2208
2209/// A parse-once cursor over a record-list view (`T_STRUCTS_VIEW` / `T_STRUCTS_FVIEW`): the schema
2210/// and tables are read ONCE at open, then every `(row, field)` access is O(1) — pure arithmetic for
2211/// the fixed-stride view, a two-`u32` offset jump for the variable view — with no per-call re-scan.
2212pub struct WireStructsCursor<'a> {
2213    val: &'a [u8],
2214    field_names: Vec<&'a [u8]>,
2215    n: usize,
2216    kind: CursorKind<'a>,
2217}
2218
2219enum CursorKind<'a> {
2220    Variable { row_table_pos: usize, rows_start: usize },
2221    Fixed { field_kinds: &'a [u8], field_offsets: Vec<usize>, stride: usize, rows_start: usize, blob: &'a [u8] },
2222}
2223
2224impl<'a> WireStructsCursor<'a> {
2225    pub fn len(&self) -> usize {
2226        self.n
2227    }
2228    pub fn is_empty(&self) -> bool {
2229        self.n == 0
2230    }
2231    pub fn field_count(&self) -> usize {
2232        self.field_names.len()
2233    }
2234    /// Index of the field named `name`, scanned once by the caller and then reused for every row.
2235    pub fn field_index(&self, name: &str) -> Option<usize> {
2236        self.field_names.iter().position(|&n| n == name.as_bytes())
2237    }
2238
2239    /// Byte slice at the start of cell `(row, fi)` — the one arithmetic/offset step both layouts share.
2240    fn cell_slice(&self, row: usize, fi: usize) -> Option<&'a [u8]> {
2241        if row >= self.n || fi >= self.field_names.len() {
2242            return None;
2243        }
2244        match &self.kind {
2245            CursorKind::Fixed { field_offsets, stride, rows_start, .. } => {
2246                let pos = rows_start.checked_add(row.checked_mul(*stride)?)?.checked_add(field_offsets[fi])?;
2247                self.val.get(pos..)
2248            }
2249            CursorKind::Variable { row_table_pos, rows_start } => {
2250                let f = self.field_names.len();
2251                let row_off_at = row_table_pos.checked_add(row.checked_mul(4)?)?;
2252                let row_off =
2253                    u32::from_le_bytes(self.val.get(row_off_at..row_off_at.checked_add(4)?)?.try_into().ok()?) as usize;
2254                let field_table_pos = rows_start.checked_add(row_off)?;
2255                let values_start = field_table_pos.checked_add(f.checked_mul(4)?)?;
2256                let field_off_at = field_table_pos.checked_add(fi.checked_mul(4)?)?;
2257                let field_off =
2258                    u32::from_le_bytes(self.val.get(field_off_at..field_off_at.checked_add(4)?)?.try_into().ok()?) as usize;
2259                self.val.get(values_start.checked_add(field_off)?..)
2260            }
2261        }
2262    }
2263
2264    /// The `(row, field)` value as an owned `RuntimeValue` — O(1), no header re-scan.
2265    pub fn value(&self, row: usize, fi: usize) -> Option<RuntimeValue> {
2266        match &self.kind {
2267            CursorKind::Fixed { field_kinds, blob, .. } => {
2268                fview_read_cell(*field_kinds.get(fi)?, self.cell_slice(row, fi)?, blob)
2269            }
2270            CursorKind::Variable { .. } => {
2271                let cell = self.cell_slice(row, fi)?;
2272                let mut q = 0;
2273                native_decode(cell, &mut q)
2274            }
2275        }
2276    }
2277
2278    /// Read an ENTIRE int field of the fixed-stride view as a `Vec<i64>` in one tight pass — the
2279    /// Cap'n-Proto-class read-all: the cells are at a fixed `offset` every `stride` bytes, so after
2280    /// one bounds check on the last cell, the reads are unchecked raw 8-byte loads (no per-read
2281    /// bounds check, no slice indirection, no `RuntimeValue` box). `None` for the variable view
2282    /// (varint cells aren't strided) or a non-int field.
2283    pub fn i64_column(&self, fi: usize) -> Option<Vec<i64>> {
2284        let CursorKind::Fixed { field_kinds, field_offsets, stride, rows_start, .. } = &self.kind else {
2285            return None;
2286        };
2287        if *field_kinds.get(fi)? != FK_INT {
2288            return None;
2289        }
2290        let base = rows_start.checked_add(field_offsets[fi])?;
2291        let mut out = Vec::with_capacity(self.n);
2292        if self.n > 0 {
2293            // The extreme cell `base + (n-1)*stride .. +8` ⊆ val; every earlier cell is below it,
2294            // so this single check makes every loop read in-bounds.
2295            let last = base.checked_add((self.n - 1).checked_mul(*stride)?)?;
2296            self.val.get(last..last.checked_add(8)?)?;
2297            let ptr = self.val.as_ptr();
2298            for r in 0..self.n {
2299                let p = base + r * stride;
2300                // SAFETY: `p..p+8` ⊆ `[rows_start, rows_start + n*stride)` ⊆ `val` (checked above).
2301                let b = unsafe { std::slice::from_raw_parts(ptr.add(p), 8) };
2302                out.push(i64::from_le_bytes(b.try_into().unwrap()));
2303            }
2304        }
2305        Some(out)
2306    }
2307
2308    /// Fast integer read of an int cell — the Cap'n-Proto-class random read: pure arithmetic + a
2309    /// raw 8-byte read (fixed view) or a tagged-varint decode (variable view), NO `RuntimeValue` box.
2310    /// `None` if the cell is not an integer.
2311    pub fn i64(&self, row: usize, fi: usize) -> Option<i64> {
2312        let cell = self.cell_slice(row, fi)?;
2313        match &self.kind {
2314            CursorKind::Fixed { field_kinds, .. } => match *field_kinds.get(fi)? {
2315                FK_INT => Some(i64::from_le_bytes(cell.get(0..8)?.try_into().ok()?)),
2316                _ => None,
2317            },
2318            CursorKind::Variable { .. } => {
2319                if *cell.first()? != T_INT {
2320                    return None;
2321                }
2322                let mut q = 1;
2323                Some(unzigzag(read_uvarint(cell, &mut q)?))
2324            }
2325        }
2326    }
2327}
2328
2329const T_NOTHING: u8 = 0;
2330const T_FALSE: u8 = 1;
2331const T_TRUE: u8 = 2;
2332const T_INT: u8 = 3;
2333const T_FLOAT: u8 = 4;
2334const T_CHAR: u8 = 5;
2335const T_TEXT: u8 = 6;
2336const T_DURATION: u8 = 7;
2337const T_DATE: u8 = 8;
2338const T_MOMENT: u8 = 9;
2339const T_SPAN: u8 = 10;
2340const T_TIME: u8 = 11;
2341const T_PEER: u8 = 12;
2342const T_LIST: u8 = 13;
2343const T_TUPLE: u8 = 14;
2344const T_SET: u8 = 15;
2345const T_MAP: u8 = 16;
2346const T_STRUCT: u8 = 17;
2347const T_INDUCTIVE: u8 = 18;
2348// Packed homogeneous lists — one tag + count, NO per-element tag, encoded
2349// straight from the specialized `ListRepr` storage. The throughput path.
2350const T_INTS: u8 = 19; // zig-zag varint per element (covers Ints + IntsI32)
2351const T_FLOATS: u8 = 20; // 8-byte little-endian per element
2352const T_BOOLS: u8 = 21; // bit-packed, 8 booleans per byte
2353const T_STRINGS: u8 = 22; // flat string array: count + per-elem byte-lengths + one bytes blob
2354const T_INTS_FIXED: u8 = 23; // fixed-width i64 array: count + raw 8-byte-LE blob (memcpy)
2355const T_INTS_GV: u8 = 24; // group-varint (Stream VByte layout): control stream + data stream
2356// Columnar packing for homogeneous lists of compound values: the schema is written
2357// ONCE, then each field becomes its own packed column (reusing the array tags above).
2358const T_STRUCTS: u8 = 25; // homogeneous struct list: type_name + field names + one column per field
2359const T_INDUCTIVES: u8 = 26; // homogeneous enum list: type_name + ctor dictionary + index + arg columns
2360// Schema-dictionary forms of a struct list (cross-message, connection-scoped cache):
2361const T_STRUCTS_DEF: u8 = 27; // sequential: defines schema at `id` inline, then columns (self-decodable)
2362const T_STRUCTS_REF: u8 = 28; // sequential: references a previously-defined `id`, then columns
2363const T_STRUCTS_CDEF: u8 = 29; // content-addressed: schema inline (fingerprint derived), then columns
2364const T_STRUCTS_CREF: u8 = 30; // content-addressed: 8-byte schema fingerprint, then columns
2365const T_FLOATS_XOR: u8 = 31; // lossless XOR-delta + varint float array (Gorilla-style)
2366const T_INTS_AFFINE: u8 = 32; // closed-form: base + stride*i for all i (3 numbers, no data)
2367const T_BIGINT: u8 = 33; // exact out-of-i64 integer: sign byte + length + little-endian magnitude
2368const T_RATIONAL: u8 = 34; // exact fraction: signed numerator (sign+len+LE) then positive denominator (len+LE)
2369const T_DECIMAL: u8 = 75; // exact base-10 fixed-point (money): sign + coefficient magnitude (len+LE) + base-10 scale (uvarint)
2370const T_COMPLEX: u8 = 76; // exact complex re+im·i: two rationals back to back, each as sign + numerator (len+LE) + denominator (len+LE)
2371const T_MODULAR: u8 = 77; // ℤ/nℤ element: residue magnitude (len+LE) then modulus magnitude (len+LE), both non-negative
2372const T_QUANTITY: u8 = 79; // dimensioned quantity: SI magnitude (sign + num len+LE + den len+LE), 10 exponent (num,den) zigzag-varint pairs, then the unit symbol (len+UTF-8)
2373const T_MONEY: u8 = 80; // money: amount as Decimal (sign + coefficient len+LE + base-10 scale uvarint) then the ISO-4217 currency code (len + UTF-8)
2374const T_UUID: u8 = 81; // uuid: 16 big-endian bytes verbatim (fixed width, no length prefix)
2375// Schema-dictionary forms of a SINGLE struct (cross-message, connection-scoped cache),
2376// the lone-struct analog of the T_STRUCTS_* list forms: once both peers know a schema,
2377// a struct message ships its values in canonical field order with NO inline field-name
2378// strings — closing the postcard gap (a lone struct otherwise pays for "x","y",… every
2379// send). The DEF/CDEF forms are self-decodable (schema inline); REF/CREF carry values only.
2380const T_STRUCT_DEF: u8 = 35; // sequential: id + schema inline (registered), then values in field order
2381const T_STRUCT_REF: u8 = 36; // sequential: id resolved against the cache, then values
2382const T_STRUCT_CDEF: u8 = 37; // content-addressed: schema inline (fingerprint derived), then values
2383const T_STRUCT_CREF: u8 = 38; // content-addressed: 8-byte schema fingerprint, then values
2384// The per-column compression menu (WireStructure::Auto picks the smallest of these +
2385// the varint/affine baselines). Each is a categorical win on one data shape; the
2386// selector always includes the plain varint, so the chosen form is never larger.
2387const T_INTS_DELTA: u8 = 39; // count + first(zz) + (n-1) zig-zag deltas — monotone columns
2388const T_INTS_DOD: u8 = 40; // count + first(zz) + d1(zz) + (n-2) zig-zag delta-of-deltas — near-linear (timestamps)
2389const T_INTS_FOR: u8 = 41; // count + min(zz) + bit-width + bit-packed (v-min) residuals — clustered ints
2390const T_INTS_RLE: u8 = 42; // run count + (value(zz), run-length) pairs — runs of repeats
2391const T_INTS_DICT: u8 = 43; // dict size + distinct values(zz) + count + index-width + bit-packed indices — low cardinality
2392const T_INTS_POLY: u8 = 50; // degree + count + (degree+1) finite-difference seeds(zz) — SHIP THE GENERATOR for a polynomial column
2393const T_GEN: u8 = 51; // serialized GenExpr + count — a sandboxed pure generator over the index `i` (the general compute-shipping form)
2394const T_FUNC: u8 = 52; // arity + serialized GenExpr — a SHIPPED CALLABLE pure function (the receiver evaluates it in the sandbox)
2395const T_BYTES: u8 = 53; // count + raw 1-byte-per-element blob — a byte column; memcpy in/out and readable in place as &[u8] (zero-copy, no alignment)
2396const T_STRUCTS_TID: u8 = 54; // shared-registry struct LIST: type-id(varint) + N + columns — type/field NAMES elided (the struct-list analog of T_STRUCT_TID)
2397const T_SET_INTS: u8 = 55; // homogeneous int SET: the SORTED-canonical members shipped through the G5 int-column menu (delta/affine/RLE) — a consecutive set {1..n} collapses to base+stride+count, no data
2398const T_STRUCTS_FVIEW: u8 = 56; // FIXED-stride record-list view: type + F + names + F kind-bytes + N + [n×stride fixed rows] + blob_len + string blob. Random access = pure arithmetic (no offset tables): the `indexed fast` form — composes the struct-view with the fixed numeric dial.
2399const T_SET_STRINGS: u8 = 57; // homogeneous string SET, FRONT-CODED: members sorted to canonical order, each shipped as (shared-prefix-len-with-previous, suffix) — sorted similar strings share long prefixes so only the deltas go on the wire
2400const T_MAP_INTKEY: u8 = 58; // INT-KEYED map, COLUMNAR: entries sorted by numeric key → keys as a best int column (G5 menu: affine/delta/RLE) + values as a best-encoded list (reuses the full column menu). An affine int→int map {i↦2i} collapses BOTH columns to closed forms — ~no data. Canonical (insertion-order-invariant).
2401const T_STRINGS_DICT: u8 = 59; // DICTIONARY string column (low cardinality / categorical labels): dict-len + distinct strings (len+bytes) once + count + index-width + bit-packed per-row indices. The string twin of T_INTS_DICT — a handful of distinct labels repeated N times ships the labels once.
2402
2403// Fixed-view field kinds (1 byte each in the schema): the wire width of a cell.
2404const FK_INT: u8 = 0; // 8 bytes, raw i64 little-endian (NOT zig-zag — memcpy, like T_INTS_FIXED)
2405const FK_FLOAT: u8 = 1; // 8 bytes, f64 little-endian
2406const FK_BOOL: u8 = 2; // 1 byte (0/1)
2407const FK_TEXT: u8 = 3; // 8 bytes: u32 offset + u32 length, into the trailing string blob
2408
2409/// The byte width of one fixed-view cell of `kind`.
2410fn fview_width(kind: u8) -> usize {
2411    match kind {
2412        FK_BOOL => 1,
2413        _ => 8, // FK_INT / FK_FLOAT / FK_TEXT(ref)
2414    }
2415}
2416
2417/// Per-field byte offsets within a fixed-view row, and the row stride (their sum).
2418fn fview_layout(kinds: &[u8]) -> (Vec<usize>, usize) {
2419    let mut offsets = Vec::with_capacity(kinds.len());
2420    let mut cur = 0usize;
2421    for &k in kinds {
2422        offsets.push(cur);
2423        cur += fview_width(k);
2424    }
2425    (offsets, cur)
2426}
2427
2428/// The fixed-view kind for each column, or `None` if any column is not a fixed-width-encodable
2429/// leaf (Int/Float/Bool/Text) — then the caller keeps the variable offset-table view.
2430fn columns_fview_kinds(columns: &[ListRepr]) -> Option<Vec<u8>> {
2431    let mut kinds = Vec::with_capacity(columns.len());
2432    for col in columns {
2433        kinds.push(match col {
2434            ListRepr::Ints(_) | ListRepr::IntsI32(_) => FK_INT,
2435            ListRepr::Floats(_) => FK_FLOAT,
2436            ListRepr::Bools(_) => FK_BOOL,
2437            ListRepr::Strings { .. } => FK_TEXT,
2438            _ => return None,
2439        });
2440    }
2441    Some(kinds)
2442}
2443
2444/// Read one fixed-view cell (`kind` bytes at `cell`) into an owned value; `blob` backs FK_TEXT.
2445fn fview_read_cell(kind: u8, cell: &[u8], blob: &[u8]) -> Option<RuntimeValue> {
2446    match kind {
2447        FK_INT => Some(RuntimeValue::Int(i64::from_le_bytes(cell.get(0..8)?.try_into().ok()?))),
2448        FK_FLOAT => Some(RuntimeValue::Float(f64::from_le_bytes(cell.get(0..8)?.try_into().ok()?))),
2449        FK_BOOL => Some(RuntimeValue::Bool(*cell.first()? != 0)),
2450        FK_TEXT => {
2451            let off = u32::from_le_bytes(cell.get(0..4)?.try_into().ok()?) as usize;
2452            let len = u32::from_le_bytes(cell.get(4..8)?.try_into().ok()?) as usize;
2453            let s = blob.get(off..off.checked_add(len)?)?;
2454            Some(RuntimeValue::Text(Rc::new(String::from_utf8(s.to_vec()).ok()?)))
2455        }
2456        _ => None,
2457    }
2458}
2459// Type-id elided struct: when both ends share a program type registry, ship the type's
2460// small registry id + the values only — type/field NAMES never go on the wire (the
2461// Logos↔Logos default that beats raw varint). Falls back to T_STRUCT when unknown.
2462const T_STRUCT_TID: u8 = 44; // registry-id(varint) + values in canonical field order
2463const T_WORD: u8 = 60; // fixed-width wrapping int: width byte (32|64) + uvarint value (zero-extended to u64)
2464const T_INTS_GEOMETRIC: u8 = 61; // closed-form: base * ratio^i for all i (3 numbers, no data) — wrapping-exact
2465const T_INTS_PERIODIC: u8 = 62; // cyclic: period p + count + one block of p values → pattern[i % p]
2466const T_SHARED_DEF: u8 = 63; // dedup: id(uvarint) + the value — registers a shared subtree at `id`
2467const T_SHARED_REF: u8 = 64; // dedup: id(uvarint) — a backref to an already-shipped shared subtree
2468const T_FLOATS_CONST: u8 = 65; // closed-form: one f64 (8 LE bytes) + count — every element identical
2469const T_FLOATS_AFFINE: u8 = 66; // closed-form: base + i·stride (2 f64 + count), BIT-EXACT or not used
2470const T_INTS_SPARSE: u8 = 67; // dominant value + count + (delta-index, value) exceptions — sparse/default columns
2471const T_FLOATS_SPARSE: u8 = 68; // dominant f64 + count + (delta-index, f64) exceptions — sparse float columns
2472const T_FLOATS_PERIODIC: u8 = 69; // cyclic: period p + count + one block of p f64 → pattern[i % p]
2473const T_FLOATS_GEOMETRIC: u8 = 70; // closed-form: base * ratio^i (2 f64 + count), BIT-EXACT or not used
2474const T_STRINGS_TEMPLATE: u8 = 71; // templated: prefix + suffix + affine(base,stride) + count → prefix+(base+i·stride)+suffix
2475const T_STRINGS_FRONT: u8 = 72; // front-coded COLUMN (order-preserving): each string = (shared-prefix-len-with-previous, suffix); sorted/hierarchical columns share long prefixes
2476const T_BOOLS_PERIODIC: u8 = 73; // cyclic bool column: period p + count + one p-bit block → block[i % p] (covers const all-true/all-false at p=1, alternating at p=2)
2477const T_BOOLS_RLE: u8 = 74; // run-length bool column: first value + run lengths (alternating) → big runs ([F×n, T×m] / clustered flags) collapse to a few varints
2478const T_STRINGS_AFFIX: u8 = 78; // common prefix + common suffix + per-row ARBITRARY middle → emails (…@host), extensions (….log), wrapped ids; the non-affine sibling of T_STRINGS_TEMPLATE
2479// Type-id elided enum: ship the enum's registry id + the constructor INDEX (into the
2480// type's ordered constructor list) + the args — type and constructor names elided.
2481const T_INDUCTIVE_TID: u8 = 45; // enum-id(varint) + ctor-index(varint) + arg-count + args
2482// Offset-table struct view (the Cap'n Proto-beating random-access layout): a per-field
2483// byte-offset table precedes the values, so a `WireView` jumps to ANY field in O(1)
2484// without parsing the others (even a huge preceding field). Decodes normally too.
2485const T_STRUCT_VIEW: u8 = 46; // type_name + count + names + [u32 offset]×count + values
2486// 8-byte-aligned i64 column: `count + pad-len + pad + raw i64 LE blob`, padded so the blob
2487// lands on an 8-byte boundary in the final framed buffer (header len ≡ 1 mod 8, so the
2488// body offset is aligned to ≡ 7 mod 8). A `WireView` reads it as `&[i64]` with ZERO copy
2489// (`as_i64_slice`) — the in-place column read, for kernel-bypass / RDMA on a LAN.
2490const T_INTS_ALIGNED: u8 = 47; // count + pad-len(1) + pad + i64 LE blob (8-byte aligned blob)
2491// The float twin of `T_INTS_ALIGNED`: an 8-byte-aligned `f64` blob a `WireView` reads as
2492// `&[f64]` with ZERO copy (`as_f64_slice`). Same padding discipline → the blob is 8-aligned
2493// in the framed buffer, so the cast is sound on every architecture (the float column axis).
2494const T_FLOATS_ALIGNED: u8 = 48; // count + pad-len(1) + pad + f64 LE blob (8-byte aligned blob)
2495// A record-LIST view: the shared schema once, a per-ROW offset table, then each row's own
2496// per-FIELD offset table + values. `WireView::structs_row_field(row, name)` jumps to ANY
2497// (row, field) in O(1) — Cap'n Proto-class random access into a huge struct list, without
2498// parsing the other rows or fields. The list analog of `T_STRUCT_VIEW`.
2499const T_STRUCTS_VIEW: u8 = 49; // type + F + names + N + [u32 row_off]×N + per-row([u32 field_off]×F + values)
2500
2501/// How integer arrays are laid out on the wire — the sender's size↔speed dial.
2502/// The *decoder* always handles every variant (each has its own tag), so this is
2503/// purely a sender preference; mix freely on one relay.
2504#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2505pub enum WireNumerics {
2506    /// LEB128 varint — smallest, and the best *scalar* decode. The default; the
2507    /// right choice for a network link (bytes are the bottleneck).
2508    Varint,
2509    /// Raw fixed-width `i64` — a `memcpy` both ways (float speed) at 4× the size.
2510    /// For a CPU-bound / bandwidth-rich link (datacenter, shared memory, RDMA).
2511    Fixed,
2512    /// Group-varint (Stream VByte layout) — varint-class size with the widths
2513    /// hoisted into a control stream, so a SIMD shuffle decodes it several ints at
2514    /// a time. The "small AND fast" middle ground on a SIMD-capable host.
2515    GroupVarint,
2516}
2517
2518/// How float arrays are encoded. `Memcpy` is the raw 8-byte-per-element blob (the
2519/// memory-bandwidth ceiling, the default). `XorDelta` XORs each value's bits with the
2520/// previous and varint-codes the result — lossless and bit-exact (it operates on raw
2521/// bits, so NaN/Inf/±0/subnormals are preserved), and far smaller for slowly-varying
2522/// (time-series) columns. It is applied per-column only when it actually shrinks the
2523/// column, so it never grows a message.
2524#[derive(Clone, Copy, PartialEq, Eq, Debug)]
2525pub enum WireFloats {
2526    Memcpy,
2527    XorDelta,
2528}
2529
2530/// Whether the encoder may replace a column with a *closed-form generator* when the
2531/// data is mathematically structured — the Futamura move on the wire: if the values
2532/// are described by a formula, ship the formula, not the values. Every form is
2533/// lossless and gated by an exact-match proof, so it can never change the decoded
2534/// value; the decoder always reconstructs (each form has its own tag). `Off` by
2535/// default (detection is an O(n) scan the speed dials skip), opt-in per send.
2536#[derive(Clone, Copy, PartialEq, Eq, Debug)]
2537pub enum WireStructure {
2538    /// No structural analysis — integer columns encode by the numeric dial.
2539    Off,
2540    /// Detect an affine progression `v[i] = base + i·stride`; when *every* element
2541    /// matches exactly (wrapping i64), send `(base, stride, n)` — three numbers for
2542    /// the whole column — instead of the data. Falls back to the numeric dial when
2543    /// the data is not affine, so it never grows a message or loses a value.
2544    Affine,
2545    /// The full per-column compression menu: build every applicable encoding
2546    /// (varint baseline · affine · delta · delta-of-delta · frame-of-reference
2547    /// bit-packing · run-length · dictionary) and ship the SMALLEST. The varint
2548    /// baseline is always a candidate, so the result is never larger than `Off`'s
2549    /// varint — each encoding is a categorical win on its shape (monotone,
2550    /// near-linear timestamps, clustered, runs, low-cardinality) and silently loses
2551    /// the bake-off otherwise. The "smallest" knob.
2552    Auto,
2553}
2554
2555thread_local! {
2556    static NUMERICS: std::cell::Cell<WireNumerics> = const { std::cell::Cell::new(WireNumerics::Varint) };
2557    static FLOATS: std::cell::Cell<WireFloats> = const { std::cell::Cell::new(WireFloats::Memcpy) };
2558    static STRUCTURE: std::cell::Cell<WireStructure> = const { std::cell::Cell::new(WireStructure::Off) };
2559    /// When on, EVERY list encodes as the plain, self-describing `T_LIST` (count + per-element
2560    /// tagged values) — no columnar string/struct/inductive packing. This is the flat, fastest-to-
2561    /// decode form the shared [`logicaffeine_data::wire`] core reads. Off by default so the peer
2562    /// codec's columnar wins are untouched; opt-in via [`with_flat_lists`] (used by [`encode_value_raw`]).
2563    static FLAT_LISTS: std::cell::Cell<bool> = const { std::cell::Cell::new(false) };
2564}
2565
2566/// Run `f` with flat (columnar-free) list encoding forced on/off, restoring the prior value.
2567pub fn with_flat_lists<T>(on: bool, f: impl FnOnce() -> T) -> T {
2568    let prev = FLAT_LISTS.with(|c| c.replace(on));
2569    let out = f();
2570    FLAT_LISTS.with(|c| c.set(prev));
2571    out
2572}
2573
2574#[inline]
2575fn flat_lists() -> bool {
2576    FLAT_LISTS.with(|c| c.get())
2577}
2578
2579/// Encode integer arrays under `n` for the duration of `f`. Scoped — never leaks.
2580pub fn with_numerics<T>(n: WireNumerics, f: impl FnOnce() -> T) -> T {
2581    let prev = NUMERICS.with(|c| c.replace(n));
2582    let out = f();
2583    NUMERICS.with(|c| c.set(prev));
2584    out
2585}
2586
2587/// Convenience for [`WireNumerics::Fixed`] (back-compat).
2588pub fn with_fixed_numerics<T>(f: impl FnOnce() -> T) -> T {
2589    with_numerics(WireNumerics::Fixed, f)
2590}
2591
2592fn numerics() -> WireNumerics {
2593    NUMERICS.with(std::cell::Cell::get)
2594}
2595
2596/// Enable structural (closed-form) integer encoding under `s` for the duration of
2597/// `f`. Scoped — never leaks. See [`WireStructure`].
2598pub fn with_structure<T>(s: WireStructure, f: impl FnOnce() -> T) -> T {
2599    let prev = STRUCTURE.with(|c| c.replace(s));
2600    let out = f();
2601    STRUCTURE.with(|c| c.set(prev));
2602    out
2603}
2604
2605fn structure() -> WireStructure {
2606    STRUCTURE.with(std::cell::Cell::get)
2607}
2608
2609/// The longest repeating block the periodic detector will consider. A period beyond this is an
2610/// unusual "pattern" whose block barely beats storing the data, and it bounds the search cost.
2611const PERIOD_CAP: usize = 512;
2612
2613/// Lower a pure single-parameter arithmetic expression into a [`GenExpr`] over the index —
2614/// the bridge that lets a user's pure function be SHIPPED as the sandboxed generator (it
2615/// becomes data the receiver evaluates, never code it runs). Returns `None` for anything
2616/// outside the provably-total arithmetic subset (calls, indexing, unknown variables, non-
2617/// integer literals, comparison/logical/bitwise ops), so only a safe function is shippable.
2618pub(crate) fn lower_expr_to_genexpr(e: &crate::ast::stmt::Expr<'_>, param: logicaffeine_base::Symbol) -> Option<GenExpr> {
2619    use crate::ast::stmt::{BinaryOpKind, Expr, Literal};
2620    match e {
2621        Expr::Literal(Literal::Number(n)) => Some(GenExpr::Const(*n)),
2622        Expr::Identifier(s) if *s == param => Some(GenExpr::Index),
2623        Expr::BinaryOp { op, left, right } => {
2624            let l = Box::new(lower_expr_to_genexpr(left, param)?);
2625            let r = Box::new(lower_expr_to_genexpr(right, param)?);
2626            Some(match op {
2627                BinaryOpKind::Add => GenExpr::Add(l, r),
2628                BinaryOpKind::Subtract => GenExpr::Sub(l, r),
2629                BinaryOpKind::Multiply => GenExpr::Mul(l, r),
2630                BinaryOpKind::Divide => GenExpr::Div(l, r),
2631                BinaryOpKind::Modulo => GenExpr::Mod(l, r),
2632                _ => return None,
2633            })
2634        }
2635        _ => None,
2636    }
2637}
2638
2639/// Pack `vals` LSB-first at `width` bits each (1..=64). The inverse of [`bitunpack`].
2640fn bitpack(vals: &[u64], width: u8) -> Vec<u8> {
2641    if width == 0 {
2642        return Vec::new();
2643    }
2644    let total_bits = vals.len().saturating_mul(width as usize);
2645    let mut out = vec![0u8; total_bits.div_ceil(8)];
2646    let mut bitpos = 0usize;
2647    for &val in vals {
2648        let mut bits = val;
2649        let mut remaining = width as usize;
2650        while remaining > 0 {
2651            let byte = bitpos / 8;
2652            let off = bitpos % 8;
2653            let take = remaining.min(8 - off);
2654            let mask = (1u64 << take) - 1;
2655            out[byte] |= ((bits & mask) as u8) << off;
2656            bits >>= take;
2657            bitpos += take;
2658            remaining -= take;
2659        }
2660    }
2661    out
2662}
2663
2664/// Read `count` LSB-first `width`-bit values from `bytes`. `None` if `bytes` is too
2665/// short (clean failure on a corrupt length). The inverse of [`bitpack`].
2666fn bitunpack(bytes: &[u8], count: usize, width: u8) -> Option<Vec<u64>> {
2667    if width == 0 || width > 64 {
2668        return None;
2669    }
2670    let total_bits = count.checked_mul(width as usize)?;
2671    if bytes.len() < total_bits.div_ceil(8) {
2672        return None;
2673    }
2674    let mut out = Vec::with_capacity(count.min(PREALLOC_CAP));
2675    let mut bitpos = 0usize;
2676    for _ in 0..count {
2677        let mut val = 0u64;
2678        let mut got = 0usize;
2679        while got < width as usize {
2680            let byte = bitpos / 8;
2681            let off = bitpos % 8;
2682            let take = (width as usize - got).min(8 - off);
2683            let mask = (1u64 << take) - 1;
2684            val |= (((bytes[byte] >> off) as u64) & mask) << got;
2685            got += take;
2686            bitpos += take;
2687        }
2688        out.push(val);
2689    }
2690    Some(out)
2691}
2692
2693/// Encode float arrays under `mode` for the duration of `f`. Scoped — never leaks.
2694pub fn with_floats<T>(mode: WireFloats, f: impl FnOnce() -> T) -> T {
2695    let prev = FLOATS.with(|c| c.replace(mode));
2696    let out = f();
2697    FLOATS.with(|c| c.set(prev));
2698    out
2699}
2700
2701fn floats_mode() -> WireFloats {
2702    FLOATS.with(std::cell::Cell::get)
2703}
2704
2705/// If every element is BIT-IDENTICAL (compared by `to_bits`, so `-0.0`/`+0.0`/`NaN` are exact, not
2706/// `==`), return its bit pattern — the column ships as one f64 + a count (constant readings, padding,
2707/// defaults). `None` for an empty or non-constant column.
2708fn detect_float_const(v: &[f64]) -> Option<u64> {
2709    let bits = v.first()?.to_bits();
2710    v.iter().all(|x| x.to_bits() == bits).then_some(bits)
2711}
2712
2713/// If `v` is BIT-EXACTLY the closed form `base + i·stride` evaluated the SAME way the decoder will,
2714/// return `(base, stride)` — so it ships THREE numbers, not `n`. The bit-exact check (never `==`) means
2715/// it fires only when reconstruction is perfect: integer-valued float columns (ids/indices from JSON,
2716/// `0.0,1.0,2.0,…`), power-of-two-stride axes, exact linspace. Real noisy float data simply isn't
2717/// recognized and falls through to XOR-delta / memcpy — so the generator is a pure, lossless win.
2718fn detect_float_affine(v: &[f64]) -> Option<(f64, f64)> {
2719    if v.len() < 3 {
2720        return None;
2721    }
2722    let base = v[0];
2723    let stride = v[1] - v[0];
2724    for (i, &x) in v.iter().enumerate() {
2725        if (base + (i as f64) * stride).to_bits() != x.to_bits() {
2726            return None;
2727        }
2728    }
2729    Some((base, stride))
2730}
2731
2732/// The float twin of [`detect_sparse`]: if ONE f64 (by bit pattern) dominates ≥ ¾ of the column,
2733/// return its bits and the sorted `(index, value)` exceptions — a mostly-default/constant-with-
2734/// outliers float column (sparse telemetry, a mostly-zero signal). Boyer–Moore over `to_bits`, so a
2735/// column with no dominant value pays only the O(1)-memory pass.
2736fn detect_float_sparse(v: &[f64]) -> Option<(u64, Vec<(usize, u64)>)> {
2737    if v.len() < 8 {
2738        return None;
2739    }
2740    let mut cand = v[0].to_bits();
2741    let mut count: i64 = 0;
2742    for x in v {
2743        let b = x.to_bits();
2744        if count == 0 {
2745            cand = b;
2746            count = 1;
2747        } else if b == cand {
2748            count += 1;
2749        } else {
2750            count -= 1;
2751        }
2752    }
2753    let occ = v.iter().filter(|x| x.to_bits() == cand).count();
2754    if v.len() - occ > v.len() / 4 {
2755        return None;
2756    }
2757    let exceptions: Vec<(usize, u64)> = v
2758        .iter()
2759        .enumerate()
2760        .filter(|(_, x)| x.to_bits() != cand)
2761        .map(|(i, x)| (i, x.to_bits()))
2762        .collect();
2763    Some((cand, exceptions))
2764}
2765
2766/// The float twin of [`detect_period`]: the minimal period `2 ≤ p ≤ min(len/2, PERIOD_CAP)` such that
2767/// `v[i]` BIT-equals `v[i % p]` (a cyclic waveform / repeated frame). Pure bit-equality, so always
2768/// exact — ship one block of `p` f64 + the count, not all `n`.
2769fn detect_float_period(v: &[f64]) -> Option<usize> {
2770    let n = v.len();
2771    if n < 4 {
2772        return None;
2773    }
2774    let cap = (n / 2).min(PERIOD_CAP);
2775    'p: for p in 2..=cap {
2776        for i in p..n {
2777            if v[i].to_bits() != v[i - p].to_bits() {
2778                continue 'p;
2779            }
2780        }
2781        return Some(p);
2782    }
2783    None
2784}
2785
2786/// The float twin of [`detect_geometric`]: if `v` is BIT-EXACTLY `base · ratio^i` replayed by the same
2787/// `cur *= ratio` accumulation the decoder uses, return `(base, ratio)`. Float multiply rounds, so this
2788/// fires only when reconstruction is perfect — power-of-two ratios (doubling, halving / exponential
2789/// decay), which ARE exact in f64. Everything else falls through, so it is a pure lossless win.
2790fn detect_float_geometric(v: &[f64]) -> Option<(f64, f64)> {
2791    if v.len() < 3 {
2792        return None;
2793    }
2794    let base = v[0];
2795    if base == 0.0 || !base.is_finite() {
2796        return None;
2797    }
2798    let ratio = v[1] / base;
2799    if !ratio.is_finite() || ratio == 1.0 {
2800        return None; // ratio 1 → constant, handled by `detect_float_const`
2801    }
2802    let mut cur = base;
2803    for &x in v {
2804        if cur.to_bits() != x.to_bits() {
2805            return None;
2806        }
2807        cur *= ratio;
2808    }
2809    Some((base, ratio))
2810}
2811
2812/// XOR-delta encode a float column: count, then the LEB128 varint of each value's
2813/// bits XOR the previous value's bits. Lossless and bit-exact (raw-bit operation).
2814fn floats_xor_encode(out: &mut Vec<u8>, v: &[f64]) {
2815    write_uvarint(v.len() as u64, out);
2816    let mut prev = 0u64;
2817    for &f in v {
2818        let bits = f.to_bits();
2819        write_uvarint(bits ^ prev, out);
2820        prev = bits;
2821    }
2822}
2823
2824/// Bytes a `write_uvarint` of `x` occupies (LEB128, 1–10 bytes).
2825fn uvarint_byte_len(x: u64) -> usize {
2826    (((64 - x.leading_zeros()).max(1) + 6) / 7) as usize
2827}
2828
2829/// The body size of the memcpy float encoding (`T_FLOATS`): the count varint + 8
2830/// bytes per element. Used to keep the XOR-delta column ONLY when it actually shrinks.
2831fn floats_memcpy_body_len(n: usize) -> usize {
2832    uvarint_byte_len(n as u64) + n * 8
2833}
2834
2835/// The compression codec for an encoded body — the sender's dial. The wire is
2836/// self-describing (the header carries the codec), so this is purely a sender
2837/// preference; any peer decodes any codec. Each is kept only if it actually shrank
2838/// the body (see [`message_to_wire_with`]), so compression never hurts the fast path.
2839#[derive(Clone, Copy, PartialEq, Eq, Debug)]
2840pub enum WireCompression {
2841    /// No compression. The default — our binary is already compact, so compression
2842    /// is for large/redundant payloads on size-constrained links.
2843    None,
2844    /// DEFLATE (`miniz_oxide`). The balanced middle; what `Send compressed` selects.
2845    Deflate,
2846    /// LZ4 (`lz4_flex`, pure-Rust) — near-memcpy speed, lighter ratio. Ships on every
2847    /// target (native + browser).
2848    Lz4,
2849    /// Zstandard — the best ratio. Native uses the C encoder; the browser cannot
2850    /// encode it (falls back to lz4) but decodes it via the pure-Rust `ruzstd`.
2851    Zstd,
2852}
2853
2854/// The 2-bit on-wire id for a codec (header bits 2-3). `None`/`Deflate` share id 0;
2855/// `None` is distinguished by `H_COMPRESSED` being unset.
2856fn compression_id(c: WireCompression) -> u8 {
2857    match c {
2858        WireCompression::None | WireCompression::Deflate => 0,
2859        WireCompression::Lz4 => 1,
2860        WireCompression::Zstd => 2,
2861    }
2862}
2863
2864/// The compression effort dial — a sender-only preference (the codec output is
2865/// self-describing, so the decoder needs no knowledge of the level). `Fast` favors
2866/// throughput, `Max` favors ratio, `Balanced` is the default middle.
2867#[derive(Clone, Copy, PartialEq, Eq, Debug)]
2868pub enum WireCompressionLevel {
2869    Fast,
2870    Balanced,
2871    Max,
2872}
2873
2874thread_local! {
2875    static COMPRESSION_CODEC: std::cell::Cell<WireCompression> =
2876        const { std::cell::Cell::new(WireCompression::None) };
2877    static COMPRESSION_LEVEL: std::cell::Cell<WireCompressionLevel> =
2878        const { std::cell::Cell::new(WireCompressionLevel::Balanced) };
2879}
2880
2881/// Compress encoded bodies with `codec` (kept only if smaller) for the duration of
2882/// `f`. Scoped so it never leaks.
2883pub fn with_compression_codec<T>(codec: WireCompression, f: impl FnOnce() -> T) -> T {
2884    let prev = COMPRESSION_CODEC.with(|c| c.replace(codec));
2885    let out = f();
2886    COMPRESSION_CODEC.with(|c| c.set(prev));
2887    out
2888}
2889
2890/// Set the compression effort for the duration of `f`. Scoped so it never leaks.
2891pub fn with_compression_level<T>(level: WireCompressionLevel, f: impl FnOnce() -> T) -> T {
2892    let prev = COMPRESSION_LEVEL.with(|c| c.replace(level));
2893    let out = f();
2894    COMPRESSION_LEVEL.with(|c| c.set(prev));
2895    out
2896}
2897
2898fn compression_level() -> WireCompressionLevel {
2899    COMPRESSION_LEVEL.with(std::cell::Cell::get)
2900}
2901
2902/// DEFLATE effort: miniz_oxide levels 1 (fast) / 6 (balanced) / 9 (max).
2903fn deflate_level() -> u8 {
2904    match compression_level() {
2905        WireCompressionLevel::Fast => 1,
2906        WireCompressionLevel::Balanced => 6,
2907        WireCompressionLevel::Max => 9,
2908    }
2909}
2910
2911/// zstd effort: levels 1 (fast) / 9 (balanced) / 19 (max). Decode speed is
2912/// level-independent in zstd, so `Max` costs only encode time.
2913#[cfg(not(target_arch = "wasm32"))]
2914fn zstd_level() -> i32 {
2915    match compression_level() {
2916        WireCompressionLevel::Fast => 1,
2917        WireCompressionLevel::Balanced => 9,
2918        WireCompressionLevel::Max => 19,
2919    }
2920}
2921
2922/// Back-compat convenience: compress with DEFLATE (what the bare `Send compressed`
2923/// keyword selects).
2924pub fn with_compression<T>(f: impl FnOnce() -> T) -> T {
2925    with_compression_codec(WireCompression::Deflate, f)
2926}
2927
2928fn compression_codec() -> WireCompression {
2929    COMPRESSION_CODEC.with(std::cell::Cell::get)
2930}
2931
2932/// Compress `body` with `codec`, returning the codec actually used (it may differ
2933/// from the request: a wasm `Zstd` encode falls back to `Lz4`) and the bytes. The
2934/// caller keeps the result only if it shrank.
2935fn compress_body(codec: WireCompression, body: &[u8]) -> Option<(WireCompression, Vec<u8>)> {
2936    match codec {
2937        WireCompression::None => None,
2938        WireCompression::Deflate => Some((codec, miniz_oxide::deflate::compress_to_vec(body, deflate_level()))),
2939        WireCompression::Lz4 => Some((codec, lz4_flex::compress_prepend_size(body))),
2940        WireCompression::Zstd => {
2941            #[cfg(not(target_arch = "wasm32"))]
2942            {
2943                zstd::encode_all(body, zstd_level()).ok().map(|z| (WireCompression::Zstd, z))
2944            }
2945            #[cfg(target_arch = "wasm32")]
2946            {
2947                // No C encoder in the browser — fall back to lz4 (still universally
2948                // decodable). The header will record lz4, not zstd.
2949                Some((WireCompression::Lz4, lz4_flex::compress_prepend_size(body)))
2950            }
2951        }
2952    }
2953}
2954
2955/// The smallest `body` compresses to across the built-in compressors (deflate / lz4 / zstd), or its
2956/// raw length when none helps — the "fair fight" size for an arbitrary byte string. This is the same
2957/// shop-every-compressor rule [`message_to_wire_best`]'s `Smallest` goal applies to the LOGOS wire,
2958/// exposed so a benchmark can grant a COMPETITOR codec the identical compression opportunity: then a
2959/// size comparison is compressed-vs-compressed (fair), not compressed-LOGOS-vs-raw-competitor.
2960pub fn best_compressed_len(body: &[u8]) -> usize {
2961    [WireCompression::Deflate, WireCompression::Lz4, WireCompression::Zstd]
2962        .into_iter()
2963        .filter_map(|c| compress_body(c, body).map(|(_, z)| z.len()))
2964        .fold(body.len(), usize::min)
2965}
2966
2967/// Inflate `body` that was compressed with `codec`. `None` on any malformed input.
2968fn decompress_body(codec: WireCompression, body: &[u8]) -> Option<Vec<u8>> {
2969    match codec {
2970        WireCompression::None => Some(body.to_vec()),
2971        WireCompression::Deflate => miniz_oxide::inflate::decompress_to_vec(body).ok(),
2972        WireCompression::Lz4 => lz4_flex::decompress_size_prepended(body).ok(),
2973        WireCompression::Zstd => {
2974            #[cfg(not(target_arch = "wasm32"))]
2975            {
2976                zstd::decode_all(body).ok()
2977            }
2978            #[cfg(target_arch = "wasm32")]
2979            {
2980                zstd_decode_ruzstd(body)
2981            }
2982        }
2983    }
2984}
2985
2986/// Pure-Rust zstd decode (the browser's decode path; also the native C-vs-ruzstd
2987/// parity oracle). A standard zstd frame in, the inflated bytes out.
2988fn zstd_decode_ruzstd(body: &[u8]) -> Option<Vec<u8>> {
2989    use std::io::Read;
2990    let mut dec = ruzstd::StreamingDecoder::new(body).ok()?;
2991    let mut out = Vec::new();
2992    dec.read_to_end(&mut out).ok()?;
2993    Some(out)
2994}
2995
2996// ---- Group varint (Stream VByte layout) for int arrays ------------------------
2997//
2998// Each int (zig-zag → u64) is stored at the NARROWEST of {1,2,4,8} bytes; a 2-bit
2999// width code per int packs four codes into one control byte. The control stream is
3000// written BEFORE the data stream, so widths are known up front — DECODE reads one
3001// WIDE unaligned word per int and masks it (no per-byte continuation branch, no
3002// per-element zeroing/copy), and the layout is what a SIMD shuffle consumes.
3003
3004#[inline]
3005fn gv_code(zz: u64) -> u8 {
3006    if zz <= 0xFF {
3007        0
3008    } else if zz <= 0xFFFF {
3009        1
3010    } else if zz <= 0xFFFF_FFFF {
3011        2
3012    } else {
3013        3
3014    }
3015}
3016
3017/// LEB128 varint array (`T_INTS`): a header, then one varint per element. The smallest
3018/// layout and the best *scalar* decode — the default.
3019///
3020/// ADAPTIVE SIGN MODE (zero-overhead): the header is `(count << 1) | signed`, where
3021/// `signed` is set iff the column holds a negative value. A non-negative column ships as
3022/// PLAIN LEB128 — one byte for every value `< 128`, where zig-zag would spend two (it
3023/// doubles the magnitude, halving the one-byte range to `< 64`). Non-negative data (ids,
3024/// counts, sizes, timestamps) is then up to half the bytes, matching protobuf's `int64`;
3025/// a column with any negative keeps zig-zag (protobuf's `sint64`). The mode rides the
3026/// count's low bit, so it costs ZERO extra bytes.
3027fn leb128_encode<I: Iterator<Item = i64> + Clone>(out: &mut Vec<u8>, vals: I, n: usize) {
3028    let signed = vals.clone().any(|x| x < 0);
3029    write_uvarint(((n as u64) << 1) | signed as u64, out);
3030    out.reserve(n * 2);
3031    if signed {
3032        for x in vals {
3033            write_uvarint(zigzag(x), out);
3034        }
3035    } else {
3036        for x in vals {
3037            write_uvarint(x as u64, out);
3038        }
3039    }
3040}
3041
3042/// Fixed-width array (`T_INTS_FIXED`): the `i64` buffer's little-endian bytes ARE
3043/// the wire bytes — one `memcpy` (same trick as floats).
3044fn fixed_encode_i64(out: &mut Vec<u8>, v: &[i64]) {
3045    write_uvarint(v.len() as u64, out);
3046    #[cfg(target_endian = "little")]
3047    {
3048        // SAFETY: reading `&[i64]` as `&[u8]` of the same byte length.
3049        let bytes = unsafe { std::slice::from_raw_parts(v.as_ptr().cast::<u8>(), std::mem::size_of_val(v)) };
3050        out.extend_from_slice(bytes);
3051    }
3052    #[cfg(target_endian = "big")]
3053    {
3054        out.reserve(v.len() * 8);
3055        for &n in v {
3056            out.extend_from_slice(&n.to_le_bytes());
3057        }
3058    }
3059}
3060
3061fn gv_encode<I: Iterator<Item = i64> + Clone>(out: &mut Vec<u8>, vals: I, n: usize) {
3062    write_uvarint(n as u64, out);
3063    let control_at = out.len();
3064    out.resize(control_at + n.div_ceil(4), 0);
3065    out.reserve(n * 2);
3066    for (i, x) in vals.enumerate() {
3067        let zz = zigzag(x);
3068        let code = gv_code(zz);
3069        out[control_at + (i >> 2)] |= code << ((i & 3) * 2);
3070        out.extend_from_slice(&zz.to_le_bytes()[..1usize << code]);
3071    }
3072}
3073
3074fn gv_decode(buf: &[u8], pos: &mut usize) -> Option<Vec<i64>> {
3075    let n = read_uvarint(buf, pos)? as usize;
3076    let control_len = n.div_ceil(4);
3077    let control = buf.get(*pos..pos.checked_add(control_len)?)?;
3078    let mut dpos = *pos + control_len;
3079    let len = buf.len();
3080    let mut v = Vec::with_capacity(n.min(PREALLOC_CAP));
3081    for i in 0..n {
3082        let code = (control[i >> 2] >> ((i & 3) * 2)) & 0x3;
3083        let width = 1usize << code;
3084        let zz = if dpos + 8 <= len {
3085            // Fast path: one wide load, mask off the high `8 - width` bytes. The
3086            // `+ 8 <= len` guard makes the fixed-size read in-bounds.
3087            let word = u64::from_le_bytes(buf[dpos..dpos + 8].try_into().unwrap());
3088            let mask = if width == 8 { u64::MAX } else { (1u64 << (width * 8)) - 1 };
3089            word & mask
3090        } else {
3091            // Safe tail near the buffer end: an exact-width read.
3092            let raw = buf.get(dpos..dpos.checked_add(width)?)?;
3093            let mut b = [0u8; 8];
3094            b[..width].copy_from_slice(raw);
3095            u64::from_le_bytes(b)
3096        };
3097        dpos += width;
3098        v.push(unzigzag(zz));
3099    }
3100    *pos = dpos;
3101    Some(v)
3102}
3103
3104/// Decode a group-varint (`T_INTS_GV`) block, taking the SSSE3 shuffle fast path
3105/// when the CPU has it and falling back to [`gv_decode`] otherwise. Both produce
3106/// bit-identical output — `gv_decode` is the oracle the SIMD path is fuzzed against.
3107fn gv_decode_dispatch(buf: &[u8], pos: &mut usize) -> Option<Vec<i64>> {
3108    #[cfg(target_arch = "x86_64")]
3109    {
3110        if is_x86_feature_detected!("ssse3") {
3111            // SAFETY: guarded by the runtime SSSE3 feature check.
3112            return unsafe { gv_decode_ssse3(buf, pos) };
3113        }
3114    }
3115    gv_decode(buf, pos)
3116}
3117
3118/// The 16 PSHUFB control masks, indexed by `(code_a << 2) | code_b` where each
3119/// code ∈ {0,1,2,3} selects a width of {1,2,4,8} bytes. Lane 0 gathers int A's
3120/// `width_a` low bytes (rest zeroed); lane 1 gathers int B's `width_b` bytes from
3121/// offset `width_a`. A `0x80` index makes PSHUFB write a zero byte.
3122#[cfg(target_arch = "x86_64")]
3123fn gv_shuffle_masks() -> &'static [[u8; 16]; 16] {
3124    use std::sync::OnceLock;
3125    static MASKS: OnceLock<[[u8; 16]; 16]> = OnceLock::new();
3126    MASKS.get_or_init(|| {
3127        let mut m = [[0x80u8; 16]; 16];
3128        for ca in 0..4usize {
3129            for cb in 0..4usize {
3130                let (wa, wb) = (1usize << ca, 1usize << cb);
3131                let entry = &mut m[(ca << 2) | cb];
3132                for j in 0..wa {
3133                    entry[j] = j as u8;
3134                }
3135                for k in 0..wb {
3136                    entry[8 + k] = (wa + k) as u8;
3137                }
3138            }
3139        }
3140        m
3141    })
3142}
3143
3144/// SSSE3 group-varint decode: two ints per PSHUFB. Each 16-byte data load holds
3145/// both ints' little-endian bytes back-to-back; one shuffle splats them into the
3146/// two 8-byte lanes of an XMM register, then we read the lanes as `u64`s. The
3147/// `dpos + 16 <= len` guard keeps the wide load in-bounds; the odd/near-end tail
3148/// is finished with the exact-width scalar reader.
3149#[cfg(target_arch = "x86_64")]
3150#[target_feature(enable = "ssse3")]
3151unsafe fn gv_decode_ssse3(buf: &[u8], pos: &mut usize) -> Option<Vec<i64>> {
3152    use std::arch::x86_64::*;
3153    let n = read_uvarint(buf, pos)? as usize;
3154    let control_len = n.div_ceil(4);
3155    let control = buf.get(*pos..pos.checked_add(control_len)?)?;
3156    let mut dpos = *pos + control_len;
3157    let len = buf.len();
3158    let mut v = Vec::with_capacity(n.min(PREALLOC_CAP));
3159    let masks = gv_shuffle_masks();
3160    let mut i = 0;
3161    while i + 2 <= n && dpos + 16 <= len {
3162        let ctrl = control[i >> 2];
3163        let ca = ((ctrl >> ((i & 3) * 2)) & 0x3) as usize;
3164        let cb = ((ctrl >> (((i + 1) & 3) * 2)) & 0x3) as usize;
3165        let data = _mm_loadu_si128(buf.as_ptr().add(dpos).cast());
3166        let mask = _mm_loadu_si128(masks[(ca << 2) | cb].as_ptr().cast());
3167        let out = _mm_shuffle_epi8(data, mask);
3168        let mut tmp = [0u8; 16];
3169        _mm_storeu_si128(tmp.as_mut_ptr().cast(), out);
3170        v.push(unzigzag(u64::from_le_bytes(tmp[0..8].try_into().unwrap())));
3171        v.push(unzigzag(u64::from_le_bytes(tmp[8..16].try_into().unwrap())));
3172        dpos += (1usize << ca) + (1usize << cb);
3173        i += 2;
3174    }
3175    while i < n {
3176        let code = (control[i >> 2] >> ((i & 3) * 2)) & 0x3;
3177        let width = 1usize << code;
3178        let raw = buf.get(dpos..dpos.checked_add(width)?)?;
3179        let mut b = [0u8; 8];
3180        b[..width].copy_from_slice(raw);
3181        v.push(unzigzag(u64::from_le_bytes(b)));
3182        dpos += width;
3183        i += 1;
3184    }
3185    *pos = dpos;
3186    Some(v)
3187}
3188
3189#[inline]
3190fn write_uvarint(mut x: u64, out: &mut Vec<u8>) {
3191    while x >= 0x80 {
3192        out.push((x as u8) | 0x80);
3193        x >>= 7;
3194    }
3195    out.push(x as u8);
3196}
3197
3198#[inline]
3199fn read_uvarint(buf: &[u8], pos: &mut usize) -> Option<u64> {
3200    let mut result = 0u64;
3201    let mut shift = 0u32;
3202    loop {
3203        let b = *buf.get(*pos)?;
3204        *pos += 1;
3205        if shift >= 64 {
3206            return None; // overlong / overflow
3207        }
3208        result |= u64::from(b & 0x7f) << shift;
3209        if b & 0x80 == 0 {
3210            return Some(result);
3211        }
3212        shift += 7;
3213    }
3214}
3215
3216#[inline]
3217fn zigzag(x: i64) -> u64 {
3218    ((x << 1) ^ (x >> 63)) as u64
3219}
3220
3221#[inline]
3222fn unzigzag(x: u64) -> i64 {
3223    ((x >> 1) as i64) ^ -((x & 1) as i64)
3224}
3225
3226#[inline]
3227fn write_str(s: &str, out: &mut Vec<u8>) {
3228    write_uvarint(s.len() as u64, out);
3229    out.extend_from_slice(s.as_bytes());
3230}
3231
3232#[inline]
3233fn read_str(buf: &[u8], pos: &mut usize) -> Option<String> {
3234    let n = read_uvarint(buf, pos)? as usize;
3235    let bytes = buf.get(*pos..pos.checked_add(n)?)?;
3236    *pos += n;
3237    String::from_utf8(bytes.to_vec()).ok()
3238}
3239
3240/// Write a flat string array: count, each element's byte length (varint, derived
3241/// from the cumulative `ends`), then the whole bytes blob in one copy.
3242/// Dictionary-encode a string column (`T_STRINGS_DICT`): each distinct string is shipped once,
3243/// then a bit-packed per-row index into that dictionary — the string twin of [`dict_encode`].
3244/// A win exactly when cardinality is low (categorical labels); `emit_best_string_column` keeps
3245/// it only if it beats the plain flat array, so it is never larger.
3246fn dict_encode_strings(data: &[u8], ends: &[u32]) -> Vec<u8> {
3247    let n = ends.len();
3248    let mut dict: Vec<&[u8]> = Vec::new();
3249    let mut index_of: std::collections::HashMap<&[u8], u64> = std::collections::HashMap::new();
3250    let mut indices: Vec<u64> = Vec::with_capacity(n);
3251    let mut prev = 0u32;
3252    for &e in ends {
3253        let s = &data[prev as usize..e as usize];
3254        prev = e;
3255        let idx = *index_of.entry(s).or_insert_with(|| {
3256            dict.push(s);
3257            (dict.len() - 1) as u64
3258        });
3259        indices.push(idx);
3260    }
3261    let mut out = vec![T_STRINGS_DICT];
3262    write_uvarint(dict.len() as u64, &mut out);
3263    for d in &dict {
3264        write_uvarint(d.len() as u64, &mut out);
3265        out.extend_from_slice(d);
3266    }
3267    write_uvarint(n as u64, &mut out);
3268    let iw = if dict.len() <= 1 { 0 } else { (64 - ((dict.len() - 1) as u64).leading_zeros()) as u8 };
3269    out.push(iw);
3270    if iw > 0 {
3271        out.extend_from_slice(&bitpack(&indices, iw));
3272    }
3273    out
3274}
3275
3276/// Emit the smaller of the plain flat string array and the dictionary form. The flat array is
3277/// always a candidate, so the result is never larger than `T_STRINGS`.
3278/// The `(start, end)` byte range of each string in a flat `data`/`ends` column.
3279fn string_slices<'a>(data: &'a [u8], ends: &[u32]) -> Vec<&'a [u8]> {
3280    let mut out = Vec::with_capacity(ends.len());
3281    let mut prev = 0usize;
3282    for &e in ends {
3283        out.push(&data[prev..e as usize]);
3284        prev = e as usize;
3285    }
3286    out
3287}
3288
3289/// If every string is `<prefix><n><suffix>` for a common `prefix`/`suffix` and an AFFINE sequence of
3290/// integers `n = base + i·stride` whose EXACT decimal spelling is the middle (so reconstruction is
3291/// byte-perfect — no zero-padding / `+` quirks), return the templated encoding: the two affixes once +
3292/// `(base, stride, count)`. Sequential-id URLs / paths / labels (`item_0…item_999`, `…/items/0…`)
3293/// collapse from O(n) to a handful of bytes — the string twin of the affine int generator.
3294fn try_template_encode(data: &[u8], ends: &[u32]) -> Option<Vec<u8>> {
3295    let n = ends.len();
3296    if n < 3 {
3297        return None;
3298    }
3299    let strs = string_slices(data, ends);
3300    let first = strs[0];
3301    // Common prefix (byte-wise).
3302    let mut prefix_len = first.len();
3303    for s in &strs[1..] {
3304        let lim = prefix_len.min(s.len());
3305        let mut i = 0;
3306        while i < lim && first[i] == s[i] {
3307            i += 1;
3308        }
3309        prefix_len = i;
3310    }
3311    // Common suffix of the PREFIX-STRIPPED remainders (so prefix and suffix never overlap).
3312    let mut suffix_len = first.len() - prefix_len;
3313    for s in &strs[1..] {
3314        let lim = suffix_len.min(s.len() - prefix_len);
3315        let mut i = 0;
3316        while i < lim && first[first.len() - 1 - i] == s[s.len() - 1 - i] {
3317            i += 1;
3318        }
3319        suffix_len = i;
3320    }
3321    // Parse each middle as an i64 whose canonical decimal spelling is exactly the middle bytes.
3322    let mut nums = Vec::with_capacity(n);
3323    for s in &strs {
3324        let mid = &s[prefix_len..s.len() - suffix_len];
3325        let mid_str = std::str::from_utf8(mid).ok()?;
3326        let num: i64 = mid_str.parse().ok()?;
3327        if num.to_string().as_bytes() != mid {
3328            return None;
3329        }
3330        nums.push(num);
3331    }
3332    let (base, stride) = detect_affine(&nums)?;
3333    let mut c = vec![T_STRINGS_TEMPLATE];
3334    write_uvarint(prefix_len as u64, &mut c);
3335    c.extend_from_slice(&first[..prefix_len]);
3336    write_uvarint(suffix_len as u64, &mut c);
3337    c.extend_from_slice(&first[first.len() - suffix_len..]);
3338    write_uvarint(zigzag(base), &mut c);
3339    write_uvarint(zigzag(stride), &mut c);
3340    write_uvarint(n as u64, &mut c);
3341    Some(c)
3342}
3343
3344/// Front-code the column IN ORDER: each string ships `(shared-prefix-len-with-the-previous, suffix)`.
3345/// Sorted or hierarchical columns — file paths, object-store keys, zero-padded ids, sorted labels —
3346/// have adjacent strings that share long prefixes, so only the per-row delta goes on the wire. Order
3347/// is preserved (a column, not a set), so it round-trips a column the dictionary can't crush (all
3348/// strings distinct) and the template can't (non-affine / zero-padded middles). When no two adjacent
3349/// strings share a prefix it costs ~1 extra byte per row over flat — `emit_best_string_column`'s
3350/// `consider` then keeps the flat form, so this is never a loss.
3351fn front_code_strings(data: &[u8], ends: &[u32]) -> Vec<u8> {
3352    let strs = string_slices(data, ends);
3353    let mut out = vec![T_STRINGS_FRONT];
3354    write_uvarint(strs.len() as u64, &mut out);
3355    let mut prev: &[u8] = &[];
3356    for s in &strs {
3357        let lim = prev.len().min(s.len());
3358        let mut common = 0usize;
3359        while common < lim && prev[common] == s[common] {
3360            common += 1;
3361        }
3362        // Back off to a UTF-8 char boundary so the shipped suffix is itself valid UTF-8.
3363        while common > 0 && common < s.len() && (s[common] & 0xC0) == 0x80 {
3364            common -= 1;
3365        }
3366        write_uvarint(common as u64, &mut out);
3367        write_uvarint((s.len() - common) as u64, &mut out);
3368        out.extend_from_slice(&s[common..]);
3369        prev = s;
3370    }
3371    out
3372}
3373
3374/// The bit-packed bool baseline: `T_BOOLS` + count + 8 booleans per byte (LSB-first).
3375fn bool_bitpack(v: &[bool], out: &mut Vec<u8>) {
3376    out.push(T_BOOLS);
3377    write_uvarint(v.len() as u64, out);
3378    let mut cur = 0u8;
3379    let mut nbits = 0u8;
3380    for &b in v {
3381        cur |= u8::from(b) << nbits;
3382        nbits += 1;
3383        if nbits == 8 {
3384            out.push(cur);
3385            cur = 0;
3386            nbits = 0;
3387        }
3388    }
3389    if nbits > 0 {
3390        out.push(cur);
3391    }
3392}
3393
3394/// Bound on the cyclic period a bool column is probed for — small, since real bool cycles are tiny
3395/// (1 = constant, 2 = alternating, 7 = a weekly flag); a 256-bit block is still only 32 bytes.
3396const BOOL_PERIOD_CAP: usize = 256;
3397
3398/// The MINIMAL period `1 ≤ p ≤ n/2` such that `v[i] == v[i-p]` everywhere (so the column is exactly
3399/// `block[i % p]`). `p == 1` is a constant column (all-true / all-false); `p == 2` is alternating.
3400fn detect_bool_period(v: &[bool]) -> Option<usize> {
3401    let n = v.len();
3402    let cap = (n / 2).min(BOOL_PERIOD_CAP);
3403    'p: for p in 1..=cap {
3404        for i in p..n {
3405            if v[i] != v[i - p] {
3406                continue 'p;
3407            }
3408        }
3409        return Some(p);
3410    }
3411    None
3412}
3413
3414/// Ship `period p + count + one p-bit block`; the decoder replays `block[i % p]`.
3415fn bool_periodic_encode(v: &[bool], p: usize) -> Vec<u8> {
3416    let mut c = vec![T_BOOLS_PERIODIC];
3417    write_uvarint(p as u64, &mut c);
3418    write_uvarint(v.len() as u64, &mut c);
3419    let mut cur = 0u8;
3420    let mut nbits = 0u8;
3421    for &b in &v[..p] {
3422        cur |= u8::from(b) << nbits;
3423        nbits += 1;
3424        if nbits == 8 {
3425            c.push(cur);
3426            cur = 0;
3427            nbits = 0;
3428        }
3429    }
3430    if nbits > 0 {
3431        c.push(cur);
3432    }
3433    c
3434}
3435
3436/// Ship `first value + the run lengths` (runs alternate). One big run, or a handful of clustered
3437/// flips, collapses to a few varints; a high-flip column makes this larger than bit-pack, and
3438/// `emit_best_bool_column`'s `consider` then keeps the bit-packed form.
3439fn bool_rle_encode(v: &[bool]) -> Vec<u8> {
3440    let mut c = vec![T_BOOLS_RLE];
3441    write_uvarint(v.len() as u64, &mut c);
3442    if v.is_empty() {
3443        c.push(0); // `first` placeholder so the frame layout matches the decoder (bit-pack wins anyway)
3444        write_uvarint(0, &mut c);
3445        return c;
3446    }
3447    c.push(v[0] as u8);
3448    let mut runs: Vec<u64> = Vec::new();
3449    let mut cur = v[0];
3450    let mut len = 0u64;
3451    for &b in v {
3452        if b == cur {
3453            len += 1;
3454        } else {
3455            runs.push(len);
3456            cur = b;
3457            len = 1;
3458        }
3459    }
3460    runs.push(len);
3461    write_uvarint(runs.len() as u64, &mut c);
3462    for r in runs {
3463        write_uvarint(r, &mut c);
3464    }
3465    c
3466}
3467
3468fn emit_best_bool_column(v: &[bool], out: &mut Vec<u8>) {
3469    let mut best = Vec::new();
3470    bool_bitpack(v, &mut best);
3471    if let Some(p) = detect_bool_period(v) {
3472        consider(&mut best, bool_periodic_encode(v, p));
3473    }
3474    consider(&mut best, bool_rle_encode(v));
3475    out.extend_from_slice(&best);
3476}
3477
3478/// The longest common BYTE prefix and the longest common BYTE suffix (of the prefix-stripped
3479/// remainders, so they never overlap) shared by EVERY string, each clamped back to a UTF-8 char
3480/// boundary. Shared by the affix and template encoders.
3481fn common_affix_lens(strs: &[&[u8]]) -> (usize, usize) {
3482    let first = strs[0];
3483    let mut prefix_len = first.len();
3484    for s in &strs[1..] {
3485        let lim = prefix_len.min(s.len());
3486        let mut i = 0;
3487        while i < lim && first[i] == s[i] {
3488            i += 1;
3489        }
3490        prefix_len = i;
3491    }
3492    while prefix_len > 0 && prefix_len < first.len() && (first[prefix_len] & 0xC0) == 0x80 {
3493        prefix_len -= 1;
3494    }
3495    let mut suffix_len = first.len() - prefix_len;
3496    for s in &strs[1..] {
3497        let lim = suffix_len.min(s.len() - prefix_len);
3498        let mut i = 0;
3499        while i < lim && first[first.len() - 1 - i] == s[s.len() - 1 - i] {
3500            i += 1;
3501        }
3502        suffix_len = i;
3503    }
3504    while suffix_len > 0 && (first[first.len() - suffix_len] & 0xC0) == 0x80 {
3505        suffix_len -= 1;
3506    }
3507    (prefix_len, suffix_len)
3508}
3509
3510/// If every string is `<prefix><middle><suffix>` for a common `prefix`/`suffix` (ARBITRARY middles —
3511/// no affine constraint), ship the two affixes ONCE + each middle. Catches the column the dictionary
3512/// can't (all distinct), the template can't (non-affine middles), and front-coding can't (the shared
3513/// part is a SUFFIX): emails `…@example.com`, files `…​.log`, wrapped ids `v…​.json`. Worthwhile only
3514/// when there's a shared affix; `consider` keeps the flat form otherwise.
3515fn try_affix_encode(data: &[u8], ends: &[u32]) -> Option<Vec<u8>> {
3516    let n = ends.len();
3517    if n < 2 {
3518        return None;
3519    }
3520    let strs = string_slices(data, ends);
3521    let (prefix_len, suffix_len) = common_affix_lens(&strs);
3522    if prefix_len + suffix_len == 0 {
3523        return None;
3524    }
3525    let first = strs[0];
3526    let mut c = vec![T_STRINGS_AFFIX];
3527    write_uvarint(prefix_len as u64, &mut c);
3528    c.extend_from_slice(&first[..prefix_len]);
3529    write_uvarint(suffix_len as u64, &mut c);
3530    c.extend_from_slice(&first[first.len() - suffix_len..]);
3531    write_uvarint(n as u64, &mut c);
3532    for s in &strs {
3533        let mid = &s[prefix_len..s.len() - suffix_len];
3534        write_uvarint(mid.len() as u64, &mut c);
3535        c.extend_from_slice(mid);
3536    }
3537    Some(c)
3538}
3539
3540fn emit_best_string_column(data: &[u8], ends: &[u32], out: &mut Vec<u8>) {
3541    let mut best = Vec::new();
3542    write_string_array_from_ends(&mut best, data, ends);
3543    consider(&mut best, dict_encode_strings(data, ends));
3544    consider(&mut best, front_code_strings(data, ends));
3545    if let Some(tpl) = try_template_encode(data, ends) {
3546        consider(&mut best, tpl);
3547    }
3548    if let Some(affix) = try_affix_encode(data, ends) {
3549        consider(&mut best, affix);
3550    }
3551    out.extend_from_slice(&best);
3552}
3553
3554fn write_string_array_from_ends(out: &mut Vec<u8>, data: &[u8], ends: &[u32]) {
3555    out.push(T_STRINGS);
3556    write_uvarint(ends.len() as u64, out);
3557    let mut prev = 0u32;
3558    for &e in ends {
3559        write_uvarint(u64::from(e - prev), out);
3560        prev = e;
3561    }
3562    out.extend_from_slice(data);
3563}
3564
3565/// If `v` is a non-empty run of structs that all share one `type_name` and the
3566/// same field-name set, return `(type_name, sorted_field_names)` — the schema for a
3567/// columnar [`T_STRUCTS`] encoding. `None` otherwise (the list stays boxed). The
3568/// field order is canonical (sorted), matching the per-struct [`T_STRUCT`] path, so
3569/// a round-trip is byte-stable.
3570fn struct_schema(v: &[RuntimeValue]) -> Option<(String, Vec<String>)> {
3571    let first = match v.first()? {
3572        RuntimeValue::Struct(s) => s,
3573        _ => return None,
3574    };
3575    let mut names: Vec<String> = first.fields.keys().cloned().collect();
3576    names.sort();
3577    // A columnar store needs ≥1 column to carry the row count — a zero-field struct
3578    // list stays boxed (encodes as the generic per-element list).
3579    if names.is_empty() {
3580        return None;
3581    }
3582    for item in v {
3583        match item {
3584            RuntimeValue::Struct(s)
3585                if s.type_name == first.type_name
3586                    && s.fields.len() == names.len()
3587                    && names.iter().all(|n| s.fields.contains_key(n)) => {}
3588            _ => return None,
3589        }
3590    }
3591    Some((first.type_name.clone(), names))
3592}
3593
3594/// Emit a homogeneous struct list: the schema (type name + field names) followed by
3595/// `encode_columns`. With no schema cache active it is the self-describing `T_STRUCTS`
3596/// (schema inline). With a cache, the first occurrence of a schema is a `T_STRUCTS_DEF`
3597/// (schema inline + registered under an id, still self-decodable) and later ones are a
3598/// `T_STRUCTS_REF` (just the id) — the cross-message win. The columns are identical in
3599/// all three forms, so the only difference is whether the schema strings are present.
3600/// Write a struct schema (type name + field names) — the exact byte layout
3601/// [`read_struct_schema`] consumes. Shared by the struct-list and single-struct
3602/// schema-dictionary paths so their `def` forms can never drift.
3603fn write_struct_schema(type_name: &str, field_names: &[String], out: &mut Vec<u8>) {
3604    write_str(type_name, out);
3605    write_uvarint(field_names.len() as u64, out);
3606    for f in field_names {
3607        write_str(f, out);
3608    }
3609}
3610
3611fn emit_struct_list(
3612    type_name: &str,
3613    field_names: &[String],
3614    n: usize,
3615    out: &mut Vec<u8>,
3616    encode_columns: impl FnOnce(&mut Vec<u8>) -> Result<(), String>,
3617) -> Result<(), String> {
3618    let write_schema = |out: &mut Vec<u8>| write_struct_schema(type_name, field_names, out);
3619    if let Some(id) = type_registry_id(type_name, field_names) {
3620        // Both ends share this type's definition (the program-derived registry): ship the
3621        // small id and the columns only — type/field NAMES never go on the wire. The
3622        // struct-list analog of `T_STRUCT_TID`; takes precedence over the schema cache,
3623        // mirroring the single-struct path.
3624        out.push(T_STRUCTS_TID);
3625        write_uvarint(id as u64, out);
3626        write_uvarint(n as u64, out);
3627        return encode_columns(out);
3628    }
3629    match schema_send(type_name, field_names) {
3630        SchemaEmit::Inline => {
3631            out.push(T_STRUCTS);
3632            write_schema(out);
3633        }
3634        SchemaEmit::SeqDef(id) => {
3635            out.push(T_STRUCTS_DEF);
3636            write_uvarint(id as u64, out);
3637            write_schema(out);
3638        }
3639        SchemaEmit::SeqRef(id) => {
3640            out.push(T_STRUCTS_REF);
3641            write_uvarint(id as u64, out);
3642        }
3643        SchemaEmit::CaDef => {
3644            out.push(T_STRUCTS_CDEF);
3645            write_schema(out);
3646        }
3647        SchemaEmit::CaRef(fp) => {
3648            out.push(T_STRUCTS_CREF);
3649            out.extend_from_slice(&fp.to_le_bytes());
3650        }
3651    }
3652    write_uvarint(n as u64, out);
3653    encode_columns(out)
3654}
3655
3656/// Encode a homogeneous struct list in the random-access `T_STRUCTS_VIEW` layout: the
3657/// shared schema (type + sorted field names) once, then a per-ROW byte-offset table, then
3658/// each row's own per-FIELD byte-offset table followed by its values. A `WireView` reaches
3659/// ANY (row, field) in O(1) via the two offset tables — the record-list analog of the
3660/// single-struct view, beating Cap'n Proto's `items.get(i).get_field()` on open + access.
3661/// `field_names` MUST be canonically sorted and `get(row, field_index)` returns that row's
3662/// value for `field_names[field_index]`, so the Boxed and columnar `Structs` sources emit
3663/// byte-identical output for the same logical data.
3664fn emit_structs_view(
3665    type_name: &str,
3666    field_names: &[String],
3667    n: usize,
3668    out: &mut Vec<u8>,
3669    mut get: impl FnMut(usize, usize) -> RuntimeValue,
3670) -> Result<(), String> {
3671    let f = field_names.len();
3672    out.push(T_STRUCTS_VIEW);
3673    write_str(type_name, out);
3674    write_uvarint(f as u64, out);
3675    for name in field_names {
3676        write_str(name, out);
3677    }
3678    write_uvarint(n as u64, out);
3679    let row_table_pos = out.len();
3680    out.resize(row_table_pos + n * 4, 0);
3681    let rows_start = out.len();
3682    let mut row_offsets: Vec<u32> = Vec::with_capacity(n);
3683    for r in 0..n {
3684        row_offsets.push((out.len() - rows_start) as u32);
3685        let field_table_pos = out.len();
3686        out.resize(field_table_pos + f * 4, 0);
3687        let values_start = out.len();
3688        let mut field_offsets: Vec<u32> = Vec::with_capacity(f);
3689        for fi in 0..f {
3690            field_offsets.push((out.len() - values_start) as u32);
3691            native_encode(&get(r, fi), out)?;
3692        }
3693        for (i, off) in field_offsets.iter().enumerate() {
3694            out[field_table_pos + i * 4..field_table_pos + i * 4 + 4].copy_from_slice(&off.to_le_bytes());
3695        }
3696    }
3697    for (i, off) in row_offsets.iter().enumerate() {
3698        out[row_table_pos + i * 4..row_table_pos + i * 4 + 4].copy_from_slice(&off.to_le_bytes());
3699    }
3700    Ok(())
3701}
3702
3703/// The columnar fast path for [`emit_structs_view`]: writes each (row, field) cell straight
3704/// from the typed column instead of materializing a `RuntimeValue` per cell (the boxed `get`
3705/// allocates a fresh `Rc<String>` for every text cell — the dominant cost on record lists).
3706/// Byte-identical to `emit_structs_view` for the same logical data.
3707fn emit_structs_view_columnar(
3708    type_name: &str,
3709    field_names: &[String],
3710    columns: &[ListRepr],
3711    out: &mut Vec<u8>,
3712) -> Result<(), String> {
3713    let f = field_names.len();
3714    let n = columns.first().map_or(0, |c| c.len());
3715    out.push(T_STRUCTS_VIEW);
3716    write_str(type_name, out);
3717    write_uvarint(f as u64, out);
3718    for name in field_names {
3719        write_str(name, out);
3720    }
3721    write_uvarint(n as u64, out);
3722    let row_table_pos = out.len();
3723    out.resize(row_table_pos + n * 4, 0);
3724    let rows_start = out.len();
3725    let mut row_offsets: Vec<u32> = Vec::with_capacity(n);
3726    let mut field_offsets: Vec<u32> = Vec::with_capacity(f);
3727    for r in 0..n {
3728        row_offsets.push((out.len() - rows_start) as u32);
3729        let field_table_pos = out.len();
3730        out.resize(field_table_pos + f * 4, 0);
3731        let values_start = out.len();
3732        field_offsets.clear();
3733        for col in columns {
3734            field_offsets.push((out.len() - values_start) as u32);
3735            write_view_cell(col, r, out)?;
3736        }
3737        for (i, off) in field_offsets.iter().enumerate() {
3738            out[field_table_pos + i * 4..field_table_pos + i * 4 + 4].copy_from_slice(&off.to_le_bytes());
3739        }
3740    }
3741    for (i, off) in row_offsets.iter().enumerate() {
3742        out[row_table_pos + i * 4..row_table_pos + i * 4 + 4].copy_from_slice(&off.to_le_bytes());
3743    }
3744    Ok(())
3745}
3746
3747/// Write one struct-view cell straight from its typed column, matching `native_encode`'s
3748/// tagged bytes exactly. Uncommon column types fall back to materialize-then-encode.
3749fn write_view_cell(col: &ListRepr, row: usize, out: &mut Vec<u8>) -> Result<(), String> {
3750    match col {
3751        ListRepr::Ints(v) => {
3752            out.push(T_INT);
3753            write_uvarint(zigzag(v[row]), out);
3754        }
3755        ListRepr::IntsI32(v) => {
3756            out.push(T_INT);
3757            write_uvarint(zigzag(v[row] as i64), out);
3758        }
3759        ListRepr::Floats(v) => {
3760            out.push(T_FLOAT);
3761            out.extend_from_slice(&v[row].to_le_bytes());
3762        }
3763        ListRepr::Bools(v) => out.push(if v[row] { T_TRUE } else { T_FALSE }),
3764        ListRepr::Strings { data, ends, .. } => {
3765            let start = if row == 0 { 0 } else { ends[row - 1] as usize };
3766            let end = ends[row] as usize;
3767            let s = &data[start..end];
3768            out.push(T_TEXT);
3769            write_uvarint(s.len() as u64, out);
3770            out.extend_from_slice(s);
3771        }
3772        other => native_encode(&other.get(row).ok_or("struct-view column row out of bounds")?, out)?,
3773    }
3774    Ok(())
3775}
3776
3777/// Encode a record list as a FIXED-stride view (`T_STRUCTS_FVIEW`): every row is the same width
3778/// (Int/Float = 8 B raw, Bool = 1 B, Text = an 8 B (offset,len) into a trailing string blob), so a
3779/// reader reaches any (row, field) by ARITHMETIC — no row/field offset tables at all. Smaller than
3780/// the variable view and a near-memcpy encode, while still O(1) random-access. The `indexed fast`
3781/// form: the struct-view composed with the fixed numeric dial. `None` (out untouched) if any column
3782/// is not a fixed-width leaf, so the caller falls back to the variable offset-table view.
3783fn emit_structs_view_fixed(
3784    type_name: &str,
3785    field_names: &[String],
3786    columns: &[ListRepr],
3787    out: &mut Vec<u8>,
3788) -> Option<()> {
3789    let kinds = columns_fview_kinds(columns)?; // checked BEFORE any write — out stays clean on None
3790    let f = field_names.len();
3791    let n = columns.first().map_or(0, |c| c.len());
3792    let (_, stride) = fview_layout(&kinds);
3793    out.push(T_STRUCTS_FVIEW);
3794    write_str(type_name, out);
3795    write_uvarint(f as u64, out);
3796    for name in field_names {
3797        write_str(name, out);
3798    }
3799    out.extend_from_slice(&kinds);
3800    write_uvarint(n as u64, out);
3801    out.reserve(n.saturating_mul(stride));
3802    let mut blob: Vec<u8> = Vec::new();
3803    for r in 0..n {
3804        for col in columns {
3805            match col {
3806                ListRepr::Ints(v) => out.extend_from_slice(&v[r].to_le_bytes()),
3807                ListRepr::IntsI32(v) => out.extend_from_slice(&(v[r] as i64).to_le_bytes()),
3808                ListRepr::Floats(v) => out.extend_from_slice(&v[r].to_le_bytes()),
3809                ListRepr::Bools(v) => out.push(v[r] as u8),
3810                ListRepr::Strings { data, ends, .. } => {
3811                    let start = if r == 0 { 0 } else { ends[r - 1] as usize };
3812                    let end = ends[r] as usize;
3813                    let off = blob.len() as u32;
3814                    let len = (end - start) as u32;
3815                    blob.extend_from_slice(&data[start..end]);
3816                    out.extend_from_slice(&off.to_le_bytes());
3817                    out.extend_from_slice(&len.to_le_bytes());
3818                }
3819                // `columns_fview_kinds` already proved every column is one of the above.
3820                _ => unreachable!("non-fixed-viewable column passed the kind check"),
3821            }
3822        }
3823    }
3824    write_uvarint(blob.len() as u64, out);
3825    out.extend_from_slice(&blob);
3826    Some(())
3827}
3828
3829/// Emit an 8-byte-aligned i64 column (`T_INTS_ALIGNED`) the receiver reads as `&[i64]` with no
3830/// copy. The pad lands the blob's body offset ≡ 7 mod 8 → ≡ 0 mod 8 once the (≡ 1 mod 8) frame
3831/// header is prepended, so the slice cast is sound. Shared by the `RuntimeValue` encode path and
3832/// the build-in-place [`build_columnar_record`] API so both produce byte-identical aligned columns.
3833fn emit_aligned_i64(v: &[i64], out: &mut Vec<u8>) {
3834    out.push(T_INTS_ALIGNED);
3835    write_uvarint(v.len() as u64, out);
3836    let after_count = out.len();
3837    let pad = (14 - after_count % 8) % 8;
3838    out.push(pad as u8);
3839    out.resize(out.len() + pad, 0);
3840    #[cfg(target_endian = "little")]
3841    {
3842        // SAFETY: an `&[i64]` reinterpreted as `&[u8]` of the same byte length.
3843        let raw = unsafe { std::slice::from_raw_parts(v.as_ptr().cast::<u8>(), v.len() * 8) };
3844        out.extend_from_slice(raw);
3845    }
3846    #[cfg(target_endian = "big")]
3847    {
3848        out.reserve(v.len() * 8);
3849        for &n in v {
3850            out.extend_from_slice(&n.to_le_bytes());
3851        }
3852    }
3853}
3854
3855/// Emit an 8-byte-aligned f64 column (`T_FLOATS_ALIGNED`), the float twin of [`emit_aligned_i64`].
3856fn emit_aligned_f64(v: &[f64], out: &mut Vec<u8>) {
3857    out.push(T_FLOATS_ALIGNED);
3858    write_uvarint(v.len() as u64, out);
3859    let after_count = out.len();
3860    let pad = (14 - after_count % 8) % 8;
3861    out.push(pad as u8);
3862    out.resize(out.len() + pad, 0);
3863    #[cfg(target_endian = "little")]
3864    {
3865        // SAFETY: an `&[f64]` reinterpreted as `&[u8]` of the same byte length.
3866        let raw = unsafe { std::slice::from_raw_parts(v.as_ptr().cast::<u8>(), v.len() * 8) };
3867        out.extend_from_slice(raw);
3868    }
3869    #[cfg(target_endian = "big")]
3870    {
3871        out.reserve(v.len() * 8);
3872        for &x in v {
3873            out.extend_from_slice(&x.to_le_bytes());
3874        }
3875    }
3876}
3877
3878/// One column of a [`build_columnar_record`] message — a borrowed slice that lands in the wire's
3879/// zero-copy aligned layout with no intermediate `RuntimeValue`.
3880#[derive(Clone, Copy)]
3881pub enum WireColumn<'a> {
3882    /// An i64 column → `T_INTS_ALIGNED`, read back as `&[i64]`.
3883    Ints(&'a [i64]),
3884    /// An f64 column → `T_FLOATS_ALIGNED`, read back as `&[f64]`.
3885    Floats(&'a [f64]),
3886}
3887
3888/// Build a columnar record message **in place** — Cap'n Proto's home turf. The named columns are
3889/// written DIRECTLY into the offset-table `T_STRUCT_VIEW` + `T_*_ALIGNED` wire layout from borrowed
3890/// slices: no intermediate `RuntimeValue`, no second serialize pass over the data (each column is a
3891/// single `memcpy`). The receiver opens it with [`view_message`] and reads ANY column in O(1) and
3892/// zero-copy via [`WireView::struct_field`] + [`WireView::as_i64_slice`]/[`WireView::as_f64_slice`].
3893///
3894/// This is the encode side of the dual zero-encode / zero-decode story: where capnp builds the
3895/// message in its wire buffer and reads it in place, this writes the same aligned layout in one pass
3896/// and reads it back with no decode — while staying name-elided and 24–34 % smaller on the wire.
3897pub fn build_columnar_record(from: &str, type_name: &str, fields: &[(&str, WireColumn)]) -> Vec<u8> {
3898    // Canonical field order (by name) — byte-identical to the `RuntimeValue` struct-view path and
3899    // deterministic regardless of the caller's insertion order.
3900    let mut fields: Vec<(&str, WireColumn)> = fields.to_vec();
3901    fields.sort_by(|a, b| a.0.cmp(b.0));
3902    let mut out = Vec::with_capacity(from.len() + type_name.len() + 32 + fields.len() * 64);
3903    write_str(from, &mut out);
3904    out.push(T_STRUCT_VIEW);
3905    write_str(type_name, &mut out);
3906    write_uvarint(fields.len() as u64, &mut out);
3907    for (name, _) in &fields {
3908        write_str(name, &mut out);
3909    }
3910    let table_pos = out.len();
3911    out.resize(table_pos + fields.len() * 4, 0);
3912    let values_start = out.len();
3913    let mut offsets: Vec<u32> = Vec::with_capacity(fields.len());
3914    for (_, col) in fields {
3915        offsets.push((out.len() - values_start) as u32);
3916        match col {
3917            WireColumn::Ints(d) => emit_aligned_i64(d, &mut out),
3918            WireColumn::Floats(d) => emit_aligned_f64(d, &mut out),
3919        }
3920    }
3921    for (i, off) in offsets.iter().enumerate() {
3922        out[table_pos + i * 4..table_pos + i * 4 + 4].copy_from_slice(&off.to_le_bytes());
3923    }
3924    frame(WireCodec::Native, current_integrity(), WireCompression::None, out)
3925}
3926
3927/// Encode a `ListRepr` to the wire — the packed/columnar path. Homogeneous arrays
3928/// go out as one tag + the typed buffer (no per-element tag, no boxing); a `Structs`
3929/// repr streams its in-memory columns straight out (a near-memcpy). Shared by the
3930/// `RuntimeValue::List` arm and, recursively, by struct columns.
3931fn encode_list_repr(repr: &ListRepr, out: &mut Vec<u8>) -> Result<(), String> {
3932    let _depth = DepthGuard::enter()?;
3933    // Flat mode: one uniform, columnar-free `T_LIST` regardless of the in-memory repr — the
3934    // format the shared wire core decodes. Every element is a fully tagged value, so a native
3935    // decoder needs no columnar/string/struct/inductive special cases.
3936    if flat_lists() {
3937        let values = repr.to_values();
3938        out.push(T_LIST);
3939        write_uvarint(values.len() as u64, out);
3940        for x in &values {
3941            native_encode(x, out)?;
3942        }
3943        return Ok(());
3944    }
3945    match repr {
3946        // Integer arrays dispatch on the sender's numeric strategy; each lands on its
3947        // own tag, so the decoder reconstructs it regardless. First, if structural
3948        // encoding is on and the whole column is an exact affine progression, ship
3949        // the generating formula `(base, stride, n)` instead of the data.
3950        ListRepr::Ints(v) => {
3951            if struct_view_on() {
3952                emit_aligned_i64(v, out);
3953                return Ok(());
3954            }
3955            if structure() == WireStructure::Affine {
3956                if let Some((base, stride)) = detect_affine(v) {
3957                    out.push(T_INTS_AFFINE);
3958                    write_uvarint(zigzag(base), out);
3959                    write_uvarint(zigzag(stride), out);
3960                    write_uvarint(v.len() as u64, out);
3961                    return Ok(());
3962                }
3963            }
3964            if structure() == WireStructure::Auto {
3965                emit_best_int_column(v, out);
3966                return Ok(());
3967            }
3968            match numerics() {
3969                WireNumerics::Varint => {
3970                    out.push(T_INTS);
3971                    leb128_encode(out, v.iter().copied(), v.len());
3972                }
3973                WireNumerics::Fixed => {
3974                    out.push(T_INTS_FIXED);
3975                    fixed_encode_i64(out, v);
3976                }
3977                WireNumerics::GroupVarint => {
3978                    out.push(T_INTS_GV);
3979                    gv_encode(out, v.iter().copied(), v.len());
3980                }
3981            }
3982        }
3983        ListRepr::IntsI32(v) => {
3984          if structure() == WireStructure::Auto {
3985            let widened: Vec<i64> = v.iter().map(|&n| n as i64).collect();
3986            emit_best_int_column(&widened, out);
3987            return Ok(());
3988          }
3989          match numerics() {
3990            WireNumerics::Varint => {
3991                out.push(T_INTS);
3992                leb128_encode(out, v.iter().map(|&n| n as i64), v.len());
3993            }
3994            WireNumerics::Fixed => {
3995                out.push(T_INTS_FIXED);
3996                write_uvarint(v.len() as u64, out);
3997                out.reserve(v.len() * 8);
3998                for &n in v {
3999                    out.extend_from_slice(&(n as i64).to_le_bytes());
4000                }
4001            }
4002            WireNumerics::GroupVarint => {
4003                out.push(T_INTS_GV);
4004                gv_encode(out, v.iter().map(|&n| n as i64), v.len());
4005            }
4006          }
4007        }
4008        ListRepr::Floats(v) => {
4009            if struct_view_on() {
4010                emit_aligned_f64(v, out);
4011                return Ok(());
4012            }
4013            // The float dial is decided AHEAD OF TIME: under `Off` this path is a pure memcpy and
4014            // never inspects the data (the lightning-quick, know-the-shape-beforehand hot path). The
4015            // closed-form generators and the shrinking menu below run ONLY when the caller opts into
4016            // structural analysis (`Affine`/`Auto`) — mirroring the integer contract exactly.
4017            let st = structure();
4018            // Ship the GENERATOR, not the data — the float twin of the int closed-forms. A constant
4019            // column is one f64 + count; a bit-exact `base + i·stride` column is three numbers. Both
4020            // are LOSSLESS (constant by `to_bits`, affine verified bit-exact), so they only ever fire
4021            // when reconstruction is perfect, and they are always smaller than the n×8 raw form.
4022            if matches!(st, WireStructure::Affine | WireStructure::Auto) {
4023                if let Some(bits) = detect_float_const(v) {
4024                    out.push(T_FLOATS_CONST);
4025                    out.extend_from_slice(&bits.to_le_bytes());
4026                    write_uvarint(v.len() as u64, out);
4027                    return Ok(());
4028                }
4029                if let Some((base, stride)) = detect_float_affine(v) {
4030                    out.push(T_FLOATS_AFFINE);
4031                    out.extend_from_slice(&base.to_le_bytes());
4032                    out.extend_from_slice(&stride.to_le_bytes());
4033                    write_uvarint(v.len() as u64, out);
4034                    return Ok(());
4035                }
4036            }
4037            // The `Auto` size-shrinking menu: a sparse / mostly-one-value column ships its dominant
4038            // value + outliers; a `base·ratioⁱ` or a cyclic `pattern[i % p]` column ships the
4039            // generator, not the samples. Each is an O(n) scan, so it runs ONLY under `Auto` — the
4040            // default path never pays for it. Every candidate is kept only when genuinely smaller
4041            // than the raw `memcpy` floor. XOR-delta is the separate `WireFloats::XorDelta` DIAL
4042            // (independent of structure), so it is tried whenever that dial is selected.
4043            let sparse: Option<Vec<u8>> = if st == WireStructure::Auto {
4044                detect_float_sparse(v).map(|(dom, exc)| {
4045                    let mut c = vec![T_FLOATS_SPARSE];
4046                    c.extend_from_slice(&dom.to_le_bytes());
4047                    write_uvarint(v.len() as u64, &mut c);
4048                    write_uvarint(exc.len() as u64, &mut c);
4049                    let mut prev = 0usize;
4050                    for (i, bits) in &exc {
4051                        write_uvarint((i - prev) as u64, &mut c);
4052                        prev = *i;
4053                        c.extend_from_slice(&bits.to_le_bytes());
4054                    }
4055                    c
4056                })
4057            } else {
4058                None
4059            };
4060            let xor: Option<Vec<u8>> = if floats_mode() == WireFloats::XorDelta {
4061                let mut body = Vec::with_capacity(v.len() + 2);
4062                floats_xor_encode(&mut body, v);
4063                if body.len() < floats_memcpy_body_len(v.len()) {
4064                    let mut c = vec![T_FLOATS_XOR];
4065                    c.extend_from_slice(&body);
4066                    Some(c)
4067                } else {
4068                    None
4069                }
4070            } else {
4071                None
4072            };
4073            let geometric: Option<Vec<u8>> = if st == WireStructure::Auto {
4074                detect_float_geometric(v).map(|(base, ratio)| {
4075                    let mut c = vec![T_FLOATS_GEOMETRIC];
4076                    c.extend_from_slice(&base.to_le_bytes());
4077                    c.extend_from_slice(&ratio.to_le_bytes());
4078                    write_uvarint(v.len() as u64, &mut c);
4079                    c
4080                })
4081            } else {
4082                None
4083            };
4084            let periodic: Option<Vec<u8>> = if st == WireStructure::Auto {
4085                detect_float_period(v).map(|p| {
4086                    let mut c = vec![T_FLOATS_PERIODIC];
4087                    write_uvarint(p as u64, &mut c);
4088                    write_uvarint(v.len() as u64, &mut c);
4089                    for &x in &v[..p] {
4090                        c.extend_from_slice(&x.to_le_bytes());
4091                    }
4092                    c
4093                })
4094            } else {
4095                None
4096            };
4097            if let Some(c) = [sparse, xor, geometric, periodic].into_iter().flatten().min_by_key(Vec::len) {
4098                // The memcpy column is `1` (tag) + body; keep the candidate only if it is smaller.
4099                if c.len() < floats_memcpy_body_len(v.len()) + 1 {
4100                    out.extend_from_slice(&c);
4101                    return Ok(());
4102                }
4103            }
4104            out.push(T_FLOATS);
4105            write_uvarint(v.len() as u64, out);
4106            // Direct memory transfer: a float buffer's little-endian bytes ARE the wire
4107            // bytes, so the whole array is one `memcpy`. (Big-endian byte-swaps.)
4108            #[cfg(target_endian = "little")]
4109            {
4110                // SAFETY: reading an `&[f64]` as `&[u8]` of the same byte length.
4111                let bytes = unsafe { std::slice::from_raw_parts(v.as_ptr().cast::<u8>(), std::mem::size_of_val(&v[..])) };
4112                out.extend_from_slice(bytes);
4113            }
4114            #[cfg(target_endian = "big")]
4115            {
4116                out.reserve(v.len() * 8);
4117                for &f in v {
4118                    out.extend_from_slice(&f.to_le_bytes());
4119                }
4120            }
4121        }
4122        ListRepr::Bools(v) => {
4123            // Under the `Auto` per-column menu, run the bool generator bake-off (periodic / RLE / bit-
4124            // pack, smallest wins); otherwise the plain bit-packed array, byte-identical to before.
4125            if structure() == WireStructure::Auto {
4126                emit_best_bool_column(v, out);
4127            } else {
4128                bool_bitpack(v, out);
4129            }
4130        }
4131        ListRepr::Strings { data, ends, .. } => {
4132            // Under the `Auto` per-column menu, try the dictionary form (categorical labels) and
4133            // ship the smaller; otherwise the plain flat array.
4134            if structure() == WireStructure::Auto {
4135                emit_best_string_column(data, ends, out);
4136            } else {
4137                write_string_array_from_ends(out, data, ends);
4138            }
4139        }
4140        // A columnar struct store: the schema (inline, or by reference when a schema
4141        // cache is active), then each in-memory column streamed straight out.
4142        ListRepr::Structs { type_name, field_names, columns } => {
4143            let n = columns.first().map_or(0, |c| c.len());
4144            if struct_view_on() {
4145                // Random-access record-list view: O(1) (row, field) reads. `field_names` is
4146                // canonically sorted (from `struct_schema`) and `columns[fi]` is its column.
4147                // With the fixed numeric dial (`indexed fast`) over all-fixed-width columns, the
4148                // FIXED-stride view drops the offset tables (smaller + pure-arithmetic O(1));
4149                // otherwise the columnar offset-table view, written straight from the typed
4150                // columns (no per-cell `RuntimeValue`), byte-identical to the boxed `get` path.
4151                if numerics() == WireNumerics::Fixed
4152                    && emit_structs_view_fixed(type_name, field_names, columns, out).is_some()
4153                {
4154                    return Ok(());
4155                }
4156                return emit_structs_view_columnar(type_name, field_names, columns, out);
4157            }
4158            emit_struct_list(type_name, field_names, n, out, |out| {
4159                for col in columns {
4160                    encode_list_repr(col, out)?;
4161                }
4162                Ok(())
4163            })?;
4164        }
4165        // A columnar enum store (tagged union): the type once, a constructor
4166        // dictionary with arities, the per-row constructor-index column, then the
4167        // dense per-constructor argument columns. Nullary enums emit just the
4168        // dictionary + index column. `ranks` are recomputed on decode (not sent).
4169        ListRepr::Inductives { inductive_type, ctor_dict, ctors, ranks: _, arg_cols } => {
4170            out.push(T_INDUCTIVES);
4171            write_str(inductive_type, out);
4172            write_uvarint(ctor_dict.len() as u64, out);
4173            for (c, name) in ctor_dict.iter().enumerate() {
4174                write_str(name, out);
4175                write_uvarint(arg_cols[c].len() as u64, out); // arity
4176            }
4177            let idx: Vec<i64> = ctors.iter().map(|&c| c as i64).collect();
4178            encode_list_repr(&ListRepr::Ints(idx), out)?;
4179            for cols in arg_cols {
4180                for col in cols {
4181                    encode_list_repr(col, out)?;
4182                }
4183            }
4184        }
4185        // A received lazy view being re-sent: materialize its rows/elements once, then encode
4186        // through the normal path (re-columnarizes / re-views per the active dial).
4187        ListRepr::WireStructs { .. } | ListRepr::WireColumn { .. } => {
4188            let materialized = ListRepr::from_values(repr.to_values());
4189            return encode_list_repr(&materialized, out);
4190        }
4191        ListRepr::Boxed(v) => {
4192            if !v.is_empty() && v.iter().all(|x| matches!(x, RuntimeValue::Text(_))) {
4193                // ALL strings (e.g. a string-literal list). Under the `Auto` per-column menu, run the
4194                // FULL string-column menu — flat / dictionary / template — the same one the columnar
4195                // `Strings` repr gets (so categorical labels dictionary and `item_0…item_n` collapses
4196                // to a template); otherwise the plain flat array, byte-identical to the boxed path.
4197                let mut sdata = Vec::new();
4198                let mut sends = Vec::with_capacity(v.len());
4199                for x in v {
4200                    if let RuntimeValue::Text(s) = x {
4201                        sdata.extend_from_slice(s.as_bytes());
4202                        sends.push(sdata.len() as u32);
4203                    }
4204                }
4205                if structure() == WireStructure::Auto {
4206                    emit_best_string_column(&sdata, &sends, out);
4207                } else {
4208                    write_string_array_from_ends(out, &sdata, &sends);
4209                }
4210            } else if let Some((type_name, field_names)) = struct_schema(v) {
4211                if struct_view_on() {
4212                    // Random-access record-list view: O(1) (row, field) reads. `struct_schema`
4213                    // returns sorted field names, matching the columnar `Structs` repr above.
4214                    return emit_structs_view(&type_name, &field_names, v.len(), out, |row, fi| {
4215                        match &v[row] {
4216                            RuntimeValue::Struct(sv) => sv.fields.get(&field_names[fi]).cloned().unwrap(),
4217                            _ => unreachable!("struct_schema guaranteed all-struct"),
4218                        }
4219                    });
4220                }
4221                // A homogeneous struct list (stored boxed) packs COLUMNAR via the same
4222                // schema-inline-or-by-reference path as the in-memory `Structs` repr.
4223                emit_struct_list(&type_name, &field_names, v.len(), out, |out| {
4224                    for fname in &field_names {
4225                        let column: Vec<RuntimeValue> = v
4226                            .iter()
4227                            .map(|s| match s {
4228                                RuntimeValue::Struct(sv) => sv.fields.get(fname).cloned().unwrap(),
4229                                _ => unreachable!("struct_schema guaranteed all-struct"),
4230                            })
4231                            .collect();
4232                        encode_list_repr(&ListRepr::from_values(column), out)?;
4233                    }
4234                    Ok(())
4235                })?;
4236            } else if let Some(ind) = ListRepr::build_inductives(v) {
4237                // A homogeneous enum list (stored boxed) packs columnar via the same
4238                // tagged-union encoding as the in-memory `Inductives` repr.
4239                encode_list_repr(&ind, out)?;
4240            } else {
4241                // A mixed list keeps per-element tags.
4242                out.push(T_LIST);
4243                write_uvarint(v.len() as u64, out);
4244                for x in v {
4245                    native_encode(x, out)?;
4246                }
4247            }
4248        }
4249    }
4250    Ok(())
4251}
4252
4253/// Encode a `Money` to the wire: its Decimal amount (sign + LE coefficient + scale) then the
4254/// ISO-4217 code. `#[inline(never)]` so its locals stay out of the recursive `native_encode` frame.
4255#[inline(never)]
4256fn encode_money(m: &logicaffeine_base::Money, out: &mut Vec<u8>) {
4257    out.push(T_MONEY);
4258    let (negative, magnitude, scale) = m.amount.to_le_bytes();
4259    out.push(negative as u8);
4260    write_uvarint(magnitude.len() as u64, out);
4261    out.extend_from_slice(&magnitude);
4262    write_uvarint(scale as u64, out);
4263    let code = m.currency.code.as_bytes();
4264    write_uvarint(code.len() as u64, out);
4265    out.extend_from_slice(code);
4266}
4267
4268/// Decode a `Money` from the wire (inverse of [`encode_money`]). `#[inline(never)]` so its locals
4269/// stay out of the recursive `native_decode` frame.
4270#[inline(never)]
4271fn decode_money(buf: &[u8], pos: &mut usize) -> Option<RuntimeValue> {
4272    let negative = *buf.get(*pos)? != 0;
4273    *pos += 1;
4274    let len = read_uvarint(buf, pos)? as usize;
4275    let bytes = buf.get(*pos..pos.checked_add(len)?)?;
4276    *pos += len;
4277    let scale = u32::try_from(read_uvarint(buf, pos)?).ok()?;
4278    let amount = logicaffeine_base::Decimal::from_le_bytes(negative, bytes, scale);
4279    let clen = read_uvarint(buf, pos)? as usize;
4280    let cbytes = buf.get(*pos..pos.checked_add(clen)?)?;
4281    *pos += clen;
4282    let code = std::str::from_utf8(cbytes).ok()?;
4283    let currency = logicaffeine_base::money::currency::by_code(code)
4284        .unwrap_or(logicaffeine_base::Currency { code: "XXX", scale: 0 });
4285    Some(RuntimeValue::Money(Rc::new(logicaffeine_base::Money { amount, currency })))
4286}
4287
4288/// A UUID is a fixed 16 big-endian bytes — no length prefix needed.
4289fn encode_uuid(u: &logicaffeine_base::Uuid, out: &mut Vec<u8>) {
4290    out.push(T_UUID);
4291    out.extend_from_slice(u.as_bytes());
4292}
4293
4294/// Decode a `Uuid` from the wire (inverse of [`encode_uuid`]): the next 16 bytes verbatim.
4295fn decode_uuid(buf: &[u8], pos: &mut usize) -> Option<RuntimeValue> {
4296    let bytes = buf.get(*pos..pos.checked_add(16)?)?;
4297    *pos += 16;
4298    let mut arr = [0u8; 16];
4299    arr.copy_from_slice(bytes);
4300    Some(RuntimeValue::Uuid(Rc::new(logicaffeine_base::Uuid::from_bytes(arr))))
4301}
4302
4303/// Write a value as tagged varint bytes. `Err` for a non-portable value (with the
4304/// same messages the JSON path produces), caught at the exact offending node.
4305fn native_encode(v: &RuntimeValue, out: &mut Vec<u8>) -> Result<(), String> {
4306    let _depth = DepthGuard::enter()?;
4307    // Rc-dedup (G8): a shared subtree's repeat occurrences ship as a tiny backref; its first writes a
4308    // `T_SHARED_DEF` header here and then falls through to encode the value normally. No-op when the
4309    // dedup knob is off or the value isn't shared, so the default wire is byte-unchanged.
4310    if dedup_encode_prefix(v, out) {
4311        return Ok(());
4312    }
4313    match v {
4314        RuntimeValue::Nothing => out.push(T_NOTHING),
4315        RuntimeValue::Bool(false) => out.push(T_FALSE),
4316        RuntimeValue::Bool(true) => out.push(T_TRUE),
4317        RuntimeValue::Int(n) => {
4318            out.push(T_INT);
4319            write_uvarint(zigzag(*n), out);
4320        }
4321        RuntimeValue::Word(w) => {
4322            out.push(T_WORD);
4323            out.push(w.width() as u8);
4324            write_uvarint(w.to_u64(), out);
4325        }
4326        RuntimeValue::Lanes(_) => {
4327            return Err("a SIMD lane vector is a transient compute value, not a wire type".to_string());
4328        }
4329        // An out-of-i64 integer: ship sign + length + little-endian magnitude bytes —
4330        // exact (no base conversion), the typed alternative to a lossy JSON number.
4331        RuntimeValue::BigInt(b) => {
4332            out.push(T_BIGINT);
4333            let (negative, magnitude) = b.to_le_bytes();
4334            out.push(negative as u8);
4335            write_uvarint(magnitude.len() as u64, out);
4336            out.extend_from_slice(&magnitude);
4337        }
4338        // An exact fraction: signed numerator then positive denominator, each as
4339        // sign?+length+little-endian magnitude — `1/3` survives where a JSON number rounds.
4340        RuntimeValue::Rational(r) => {
4341            out.push(T_RATIONAL);
4342            let (num_negative, num_magnitude) = r.numerator().to_le_bytes();
4343            out.push(num_negative as u8);
4344            write_uvarint(num_magnitude.len() as u64, out);
4345            out.extend_from_slice(&num_magnitude);
4346            let (_den_sign, den_magnitude) = r.denominator().to_le_bytes();
4347            write_uvarint(den_magnitude.len() as u64, out);
4348            out.extend_from_slice(&den_magnitude);
4349        }
4350        // An exact base-10 fixed-point (money): sign + coefficient magnitude + base-10
4351        // scale — `19.99` survives bit-exact, scale and all (no lossy f64 round-trip).
4352        RuntimeValue::Decimal(d) => {
4353            out.push(T_DECIMAL);
4354            let (negative, magnitude, scale) = d.to_le_bytes();
4355            out.push(negative as u8);
4356            write_uvarint(magnitude.len() as u64, out);
4357            out.extend_from_slice(&magnitude);
4358            write_uvarint(scale as u64, out);
4359        }
4360        // Money: its Decimal amount, then the ISO-4217 currency code. Body lives in an
4361        // `#[inline(never)]` helper so its locals do not enlarge this RECURSIVE encoder's stack
4362        // frame (the codec recurses per nesting level; a fat frame overflows deep-but-finite values).
4363        RuntimeValue::Money(m) => encode_money(m, out),
4364        RuntimeValue::Uuid(u) => encode_uuid(u, out),
4365        // An exact complex number: its real then imaginary part, each shipped as a rational
4366        // (sign + numerator len+LE + denominator len+LE). `i·i = −1` survives bit-exact.
4367        RuntimeValue::Complex(c) => {
4368            out.push(T_COMPLEX);
4369            for part in [c.re(), c.im()] {
4370                let (neg, num) = part.numerator().to_le_bytes();
4371                out.push(neg as u8);
4372                write_uvarint(num.len() as u64, out);
4373                out.extend_from_slice(&num);
4374                let (_den_sign, den) = part.denominator().to_le_bytes();
4375                write_uvarint(den.len() as u64, out);
4376                out.extend_from_slice(&den);
4377            }
4378        }
4379        // A ℤ/nℤ element: its non-negative residue then its modulus, each len-prefixed LE.
4380        RuntimeValue::Modular(m) => {
4381            out.push(T_MODULAR);
4382            let (_, value) = m.value().to_le_bytes();
4383            write_uvarint(value.len() as u64, out);
4384            out.extend_from_slice(&value);
4385            let (_, modulus) = m.modulus().to_le_bytes();
4386            write_uvarint(modulus.len() as u64, out);
4387            out.extend_from_slice(&modulus);
4388        }
4389        RuntimeValue::Float(f) => {
4390            out.push(T_FLOAT);
4391            out.extend_from_slice(&f.to_le_bytes());
4392        }
4393        RuntimeValue::Char(c) => {
4394            out.push(T_CHAR);
4395            write_uvarint(*c as u64, out);
4396        }
4397        RuntimeValue::Text(s) => {
4398            out.push(T_TEXT);
4399            write_str(s, out);
4400        }
4401        RuntimeValue::Duration(n) => {
4402            out.push(T_DURATION);
4403            write_uvarint(zigzag(*n), out);
4404        }
4405        RuntimeValue::Date(n) => {
4406            out.push(T_DATE);
4407            write_uvarint(zigzag(*n as i64), out);
4408        }
4409        RuntimeValue::Moment(n) => {
4410            out.push(T_MOMENT);
4411            write_uvarint(zigzag(*n), out);
4412        }
4413        RuntimeValue::Span { months, days } => {
4414            out.push(T_SPAN);
4415            write_uvarint(zigzag(*months as i64), out);
4416            write_uvarint(zigzag(*days as i64), out);
4417        }
4418        RuntimeValue::Time(n) => {
4419            out.push(T_TIME);
4420            write_uvarint(zigzag(*n), out);
4421        }
4422        RuntimeValue::Peer(topic) => {
4423            out.push(T_PEER);
4424            write_str(topic, out);
4425        }
4426        RuntimeValue::List(items) => encode_list_repr(&items.borrow(), out)?,
4427        RuntimeValue::Tuple(items) => {
4428            out.push(T_TUPLE);
4429            write_uvarint(items.len() as u64, out);
4430            for x in items.iter() {
4431                native_encode(x, out)?;
4432            }
4433        }
4434        RuntimeValue::Set(items) => {
4435            let b = items.borrow();
4436            if !b.is_empty() && b.iter().all(|x| matches!(x, RuntimeValue::Int(_))) {
4437                // EXTREME SYMMETRY BREAKING: a homogeneous int set, sorted to its canonical
4438                // representative, is a strictly-MONOTONE column — the ideal input to the G5 int menu.
4439                // A consecutive set {1..n} collapses to T_INTS_AFFINE (base+stride+count, NO data); a
4440                // clustered set to delta+RLE. Same members in any order → byte-identical wire.
4441                let mut ints: Vec<i64> = b
4442                    .iter()
4443                    .map(|x| if let RuntimeValue::Int(n) = x { *n } else { unreachable!() })
4444                    .collect();
4445                ints.sort_unstable();
4446                ints.dedup();
4447                out.push(T_SET_INTS);
4448                emit_best_int_column(&ints, out);
4449            } else if !b.is_empty() && b.iter().all(|x| matches!(x, RuntimeValue::Text(_))) {
4450                // EXTREME SYMMETRY BREAKING (strings): sort to canonical order, then FRONT-CODE each
4451                // member as (shared-prefix-length-with-the-previous, suffix). Sorted similar strings
4452                // share long prefixes — "apple"/"apply"/"apricot" or "user_1".."user_999" or URL paths
4453                // — so only the deltas go on the wire. Same set in any order → byte-identical.
4454                let mut strs: Vec<String> = b
4455                    .iter()
4456                    .map(|x| if let RuntimeValue::Text(t) = x { (**t).clone() } else { unreachable!() })
4457                    .collect();
4458                strs.sort_unstable();
4459                strs.dedup();
4460                out.push(T_SET_STRINGS);
4461                write_uvarint(strs.len() as u64, out);
4462                let mut prev: &str = "";
4463                for s in &strs {
4464                    // common char-prefix length in BYTES (char-boundary-safe by construction).
4465                    let common: usize = s
4466                        .chars()
4467                        .zip(prev.chars())
4468                        .take_while(|(a, b)| a == b)
4469                        .map(|(a, _)| a.len_utf8())
4470                        .sum();
4471                    write_uvarint(common as u64, out);
4472                    write_str(&s[common..], out);
4473                    prev = s;
4474                }
4475            } else {
4476                // SYMMETRY BREAKING ON THE WIRE (general case). A Set is ORDER-INVARIANT — the decoder
4477                // rebuilds a Set, so element order carries NO information. Encode each element, then
4478                // sort by encoded bytes to ship the CANONICAL representative. Same set in any insertion
4479                // order → BYTE-IDENTICAL wire (content-addressing / dedup / cached keying / FEC hold).
4480                // Mirrors the canonical `T_MAP` (sort-by-encoded-key) / `T_STRUCT` (sort-by-field-name).
4481                out.push(T_SET);
4482                let mut encoded: Vec<Vec<u8>> = Vec::with_capacity(b.len());
4483                for x in b.iter() {
4484                    let mut xb = Vec::new();
4485                    native_encode(x, &mut xb)?;
4486                    encoded.push(xb);
4487                }
4488                encoded.sort_unstable();
4489                write_uvarint(encoded.len() as u64, out);
4490                for xb in &encoded {
4491                    out.extend_from_slice(xb);
4492                }
4493            }
4494        }
4495        RuntimeValue::Map(m) => {
4496            let b = m.borrow();
4497            if !b.is_empty() && b.keys().all(|k| matches!(k, RuntimeValue::Int(_))) {
4498                // SYMMETRY BREAKING (int-keyed map → struct-of-arrays). Sort entries by NUMERIC key
4499                // (canonical — insertion order carries nothing), then ship TWO columns: the keys as a
4500                // best int column (G5 menu: a {0..n} key range collapses to affine base+stride+count,
4501                // NO per-key data), and the values as a best-encoded LIST (composing the entire column
4502                // menu — int/float/string/struct columns). An affine int→int map crushes BOTH sides.
4503                let mut pairs: Vec<(i64, RuntimeValue)> = b
4504                    .iter()
4505                    .map(|(k, v)| match k {
4506                        RuntimeValue::Int(n) => (*n, v.clone()),
4507                        _ => unreachable!("all keys verified Int"),
4508                    })
4509                    .collect();
4510                pairs.sort_by_key(|(k, _)| *k);
4511                let keys: Vec<i64> = pairs.iter().map(|(k, _)| *k).collect();
4512                let vals: Vec<RuntimeValue> = pairs.into_iter().map(|(_, v)| v).collect();
4513                out.push(T_MAP_INTKEY);
4514                emit_best_int_column(&keys, out);
4515                // The value column crushes UNCONDITIONALLY (like the keys + the int-set), independent
4516                // of the structure dial: a 1-byte value-kind selects an int column (the int→int crush)
4517                // or the general per-value fallback. (kind 2+ — string/struct value columns — is a
4518                // future additive refinement, never a re-encoding of existing kinds.)
4519                if vals.iter().all(|v| matches!(v, RuntimeValue::Int(_))) {
4520                    out.push(1u8);
4521                    let int_vals: Vec<i64> = vals
4522                        .iter()
4523                        .map(|v| match v {
4524                            RuntimeValue::Int(n) => *n,
4525                            _ => unreachable!("all values verified Int"),
4526                        })
4527                        .collect();
4528                    emit_best_int_column(&int_vals, out);
4529                } else if vals.iter().all(|v| matches!(v, RuntimeValue::Text(_))) {
4530                    // String value column, FRONT-CODED in key order: each value ships as the shared-
4531                    // prefix length with the PREVIOUS value + the suffix. Sequential keys → sequential
4532                    // values (URLs / paths / ids — the database-table case) share long prefixes, so only
4533                    // the deltas go on the wire. Never worse than kind 0 (an unshared value just ships
4534                    // common=0 + the string). Char-boundary-safe by construction.
4535                    out.push(2u8);
4536                    write_uvarint(vals.len() as u64, out);
4537                    let mut prev: &str = "";
4538                    for v in &vals {
4539                        let s = match v {
4540                            RuntimeValue::Text(t) => t.as_str(),
4541                            _ => unreachable!("all values verified Text"),
4542                        };
4543                        let common: usize = s
4544                            .chars()
4545                            .zip(prev.chars())
4546                            .take_while(|(a, b)| a == b)
4547                            .map(|(a, _)| a.len_utf8())
4548                            .sum();
4549                        write_uvarint(common as u64, out);
4550                        write_str(&s[common..], out);
4551                        prev = s;
4552                    }
4553                } else if vals.iter().all(|v| matches!(v, RuntimeValue::Struct(_))) {
4554                    // Struct value column → the database-table crush. A homogeneous struct list packs
4555                    // COLUMNAR (the schema / field names ship ONCE, then one best-encoded column per
4556                    // field — the id column compresses, a bool column bit-packs) via the existing
4557                    // struct-list encoder; heterogeneous structs degrade to a tagged list. Either way it
4558                    // decodes back to the same value sequence.
4559                    out.push(3u8);
4560                    let vlist = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::from_values(vals.clone()))));
4561                    native_encode(&vlist, out)?;
4562                } else {
4563                    out.push(0u8);
4564                    write_uvarint(vals.len() as u64, out);
4565                    for v in &vals {
4566                        native_encode(v, out)?;
4567                    }
4568                }
4569            } else {
4570                out.push(T_MAP);
4571                // Canonical (general): encode each entry, then sort by encoded key.
4572                let mut entries: Vec<(Vec<u8>, Vec<u8>)> = Vec::with_capacity(b.len());
4573                for (k, val) in b.iter() {
4574                    let mut kb = Vec::new();
4575                    native_encode(k, &mut kb)?;
4576                    let mut vb = Vec::new();
4577                    native_encode(val, &mut vb)?;
4578                    entries.push((kb, vb));
4579                }
4580                entries.sort_by(|a, b| a.0.cmp(&b.0));
4581                write_uvarint(entries.len() as u64, out);
4582                for (kb, vb) in entries {
4583                    out.extend_from_slice(&kb);
4584                    out.extend_from_slice(&vb);
4585                }
4586            }
4587        }
4588        RuntimeValue::Struct(s) => {
4589            // Canonical field order (by name) is both the schema identity and the order
4590            // values are written in. With no cache this stays the self-describing
4591            // `T_STRUCT` (field names inline — byte-identical to before). With a cache
4592            // the schema is sent once and later structs of the same shape ship values
4593            // only (no field-name strings) — the cross-message win for lone structs.
4594            let mut fields: Vec<(&String, &RuntimeValue)> = s.fields.iter().collect();
4595            fields.sort_by(|a, b| a.0.cmp(b.0));
4596            let field_names: Vec<String> = fields.iter().map(|(n, _)| (*n).clone()).collect();
4597            if struct_view_on() {
4598                // Offset-table view: a per-field byte-offset table precedes the values so a
4599                // `WireView` jumps to ANY field in O(1) (Cap'n Proto-class random access),
4600                // never parsing the others. Offsets are backpatched after the values land.
4601                out.push(T_STRUCT_VIEW);
4602                write_str(&s.type_name, out);
4603                write_uvarint(fields.len() as u64, out);
4604                for (name, _) in &fields {
4605                    write_str(name, out);
4606                }
4607                let table_pos = out.len();
4608                out.resize(table_pos + fields.len() * 4, 0);
4609                let values_start = out.len();
4610                let mut offsets: Vec<u32> = Vec::with_capacity(fields.len());
4611                for (_, val) in &fields {
4612                    offsets.push((out.len() - values_start) as u32);
4613                    native_encode(val, out)?;
4614                }
4615                for (i, off) in offsets.iter().enumerate() {
4616                    out[table_pos + i * 4..table_pos + i * 4 + 4].copy_from_slice(&off.to_le_bytes());
4617                }
4618            } else if let Some(id) = type_registry_id(&s.type_name, &field_names) {
4619                // Both ends share this type's definition (the program-derived registry):
4620                // ship its small id and the values only — the type/field NAMES never go on
4621                // the wire. The default-on win that beats raw varint on Logos↔Logos.
4622                out.push(T_STRUCT_TID);
4623                write_uvarint(id as u64, out);
4624                for (_, val) in &fields {
4625                    native_encode(val, out)?;
4626                }
4627            } else {
4628            match schema_send(&s.type_name, &field_names) {
4629                SchemaEmit::Inline => {
4630                    out.push(T_STRUCT);
4631                    write_str(&s.type_name, out);
4632                    write_uvarint(fields.len() as u64, out);
4633                    for (name, val) in &fields {
4634                        write_str(name, out);
4635                        native_encode(val, out)?;
4636                    }
4637                }
4638                SchemaEmit::SeqDef(id) => {
4639                    out.push(T_STRUCT_DEF);
4640                    write_uvarint(id as u64, out);
4641                    write_struct_schema(&s.type_name, &field_names, out);
4642                    for (_, val) in &fields {
4643                        native_encode(val, out)?;
4644                    }
4645                }
4646                SchemaEmit::SeqRef(id) => {
4647                    out.push(T_STRUCT_REF);
4648                    write_uvarint(id as u64, out);
4649                    for (_, val) in &fields {
4650                        native_encode(val, out)?;
4651                    }
4652                }
4653                SchemaEmit::CaDef => {
4654                    out.push(T_STRUCT_CDEF);
4655                    write_struct_schema(&s.type_name, &field_names, out);
4656                    for (_, val) in &fields {
4657                        native_encode(val, out)?;
4658                    }
4659                }
4660                SchemaEmit::CaRef(fp) => {
4661                    out.push(T_STRUCT_CREF);
4662                    out.extend_from_slice(&fp.to_le_bytes());
4663                    for (_, val) in &fields {
4664                        native_encode(val, out)?;
4665                    }
4666                }
4667            }
4668            }
4669        }
4670        RuntimeValue::Inductive(ind) => {
4671            if let Some((enum_id, ctor_idx)) = type_registry_enum_id(&ind.inductive_type, &ind.constructor) {
4672                // Shared registry knows this enum: ship its id + the constructor index,
4673                // names elided (the receiver's ordered constructor list resolves it).
4674                out.push(T_INDUCTIVE_TID);
4675                write_uvarint(enum_id as u64, out);
4676                write_uvarint(ctor_idx as u64, out);
4677                write_uvarint(ind.args.len() as u64, out);
4678                for a in &ind.args {
4679                    native_encode(a, out)?;
4680                }
4681            } else {
4682                out.push(T_INDUCTIVE);
4683                write_str(&ind.inductive_type, out);
4684                write_str(&ind.constructor, out);
4685                write_uvarint(ind.args.len() as u64, out);
4686                for a in &ind.args {
4687                    native_encode(a, out)?;
4688                }
4689            }
4690        }
4691        RuntimeValue::Chan(_) | RuntimeValue::TaskHandle(_) => {
4692            return Err("a channel or task handle cannot be sent over the network".to_string());
4693        }
4694        RuntimeValue::Crdt(_) => {
4695            return Err("a CRDT value is shared via Merge/Sync, not sent inline".to_string());
4696        }
4697        RuntimeValue::Function(f) => {
4698            // Only a SHIPPED pure function (lowered to a sandboxed generator) crosses the
4699            // wire — an ordinary closure (an arena AST body) still cannot, since the receiver
4700            // never compiled it. A `generated` function ships its arity + the generator tree.
4701            match &f.generated {
4702                Some(expr) => {
4703                    out.push(T_FUNC);
4704                    write_uvarint(f.param_names.len() as u64, out);
4705                    serialize_gen(expr, out);
4706                }
4707                None => return Err("a Function cannot be sent over the network".to_string()),
4708            }
4709        }
4710        // A dimensioned quantity: its SI magnitude (rational), its dimension (10 exponent pairs as
4711        // zigzag varints), then the display unit symbol (len + UTF-8) — reconstructed exactly.
4712        RuntimeValue::Quantity(qv) => {
4713            out.push(T_QUANTITY);
4714            let (num_negative, num_magnitude) = qv.q.magnitude_si().numerator().to_le_bytes();
4715            out.push(num_negative as u8);
4716            write_uvarint(num_magnitude.len() as u64, out);
4717            out.extend_from_slice(&num_magnitude);
4718            let (_den_sign, den_magnitude) = qv.q.magnitude_si().denominator().to_le_bytes();
4719            write_uvarint(den_magnitude.len() as u64, out);
4720            out.extend_from_slice(&den_magnitude);
4721            let dim = qv.q.dimension();
4722            for d in logicaffeine_base::BaseDim::ALL {
4723                let e = dim.exponent(d);
4724                write_uvarint(zigzag(e.numerator() as i64), out);
4725                write_uvarint(zigzag(e.denominator() as i64), out);
4726            }
4727            let sym = qv.unit.symbol.as_bytes();
4728            write_uvarint(sym.len() as u64, out);
4729            out.extend_from_slice(sym);
4730        }
4731    }
4732    Ok(())
4733}
4734
4735/// A cap on a length prefix's pre-allocation, so a corrupt huge count can't ask
4736/// for gigabytes up front; the actual reads still bound-check every element.
4737const PREALLOC_CAP: usize = 4096;
4738
4739/// Reject a decoded element count that exceeds the receiver's `max_elements` budget BEFORE any
4740/// `count`-sized materialization. This is the gate the byte budget cannot provide: a generator column
4741/// (`T_INTS_AFFINE` / `T_INTS_POLY` / `T_GEN`) is a ~10-byte descriptor that expands to `count`
4742/// elements, so a crafted `count = 10^9` is a few bytes on the wire but gigabytes in memory — the
4743/// small-message-huge-output DoS. Returns the count as `usize` when within budget, else `None`.
4744fn bounded_count(n: u64) -> Option<usize> {
4745    let n = n as usize;
4746    (n <= receive_limits().max_elements).then_some(n)
4747}
4748
4749fn native_decode(buf: &[u8], pos: &mut usize) -> Option<RuntimeValue> {
4750    // Bound recursion depth FIRST — a crafted deeply-nested message is refused here (clean `None`),
4751    // never recursed into a stack overflow. Unwinds via `Drop` as the `?`s propagate back up.
4752    let _depth = DecodeDepthGuard::enter()?;
4753    let tag = *buf.get(*pos)?;
4754    *pos += 1;
4755    // Rc-dedup (G8): a backref resolves to the EXACT `Rc` first decoded under that id (sharing
4756    // preserved); a def decodes the value once and registers it. A dangling ref → clean `None`.
4757    if tag == T_SHARED_REF {
4758        let id = read_uvarint(buf, pos)?;
4759        return DECODE_MEMO.with(|c| c.borrow().get(&id).cloned());
4760    }
4761    if tag == T_SHARED_DEF {
4762        let id = read_uvarint(buf, pos)?;
4763        let v = native_decode(buf, pos)?;
4764        DECODE_MEMO.with(|c| c.borrow_mut().insert(id, v.clone()));
4765        return Some(v);
4766    }
4767    Some(match tag {
4768        T_NOTHING => RuntimeValue::Nothing,
4769        T_FALSE => RuntimeValue::Bool(false),
4770        T_TRUE => RuntimeValue::Bool(true),
4771        T_INT => RuntimeValue::Int(unzigzag(read_uvarint(buf, pos)?)),
4772        T_WORD => {
4773            let width = *buf.get(*pos)? as u32;
4774            *pos += 1;
4775            let bits = read_uvarint(buf, pos)?;
4776            RuntimeValue::Word(logicaffeine_base::WordVal::from_u64(width, bits)?)
4777        }
4778        T_BIGINT => {
4779            let negative = *buf.get(*pos)? != 0;
4780            *pos += 1;
4781            let len = read_uvarint(buf, pos)? as usize;
4782            let bytes = buf.get(*pos..pos.checked_add(len)?)?;
4783            *pos += len;
4784            RuntimeValue::from_bigint(logicaffeine_base::BigInt::from_le_bytes(negative, bytes))
4785        }
4786        T_RATIONAL => {
4787            let num_negative = *buf.get(*pos)? != 0;
4788            *pos += 1;
4789            let num_len = read_uvarint(buf, pos)? as usize;
4790            let num_bytes = buf.get(*pos..pos.checked_add(num_len)?)?;
4791            *pos += num_len;
4792            let num = logicaffeine_base::BigInt::from_le_bytes(num_negative, num_bytes);
4793            let den_len = read_uvarint(buf, pos)? as usize;
4794            let den_bytes = buf.get(*pos..pos.checked_add(den_len)?)?;
4795            *pos += den_len;
4796            let den = logicaffeine_base::BigInt::from_le_bytes(false, den_bytes);
4797            // A zero/garbage denominator is rejected (None) rather than panicking.
4798            RuntimeValue::from_rational(logicaffeine_base::Rational::new(num, den)?)
4799        }
4800        T_DECIMAL => {
4801            let negative = *buf.get(*pos)? != 0;
4802            *pos += 1;
4803            let len = read_uvarint(buf, pos)? as usize;
4804            let bytes = buf.get(*pos..pos.checked_add(len)?)?;
4805            *pos += len;
4806            let scale = u32::try_from(read_uvarint(buf, pos)?).ok()?;
4807            // Decimal does NOT downsize on a whole value (the scale is meaning), so build
4808            // the variant directly rather than through a downsizing chokepoint.
4809            RuntimeValue::Decimal(Rc::new(logicaffeine_base::Decimal::from_le_bytes(
4810                negative, bytes, scale,
4811            )))
4812        }
4813        // Body in an `#[inline(never)]` helper to keep this recursive decoder's frame small.
4814        T_MONEY => decode_money(buf, pos)?,
4815        T_UUID => decode_uuid(buf, pos)?,
4816        T_COMPLEX => {
4817            // Read the real part (a rational), then the imaginary part (a rational).
4818            let re_neg = *buf.get(*pos)? != 0;
4819            *pos += 1;
4820            let re_nlen = read_uvarint(buf, pos)? as usize;
4821            let re_nb = buf.get(*pos..pos.checked_add(re_nlen)?)?;
4822            *pos += re_nlen;
4823            let re_num = logicaffeine_base::BigInt::from_le_bytes(re_neg, re_nb);
4824            let re_dlen = read_uvarint(buf, pos)? as usize;
4825            let re_db = buf.get(*pos..pos.checked_add(re_dlen)?)?;
4826            *pos += re_dlen;
4827            let re = logicaffeine_base::Rational::new(re_num, logicaffeine_base::BigInt::from_le_bytes(false, re_db))?;
4828            let im_neg = *buf.get(*pos)? != 0;
4829            *pos += 1;
4830            let im_nlen = read_uvarint(buf, pos)? as usize;
4831            let im_nb = buf.get(*pos..pos.checked_add(im_nlen)?)?;
4832            *pos += im_nlen;
4833            let im_num = logicaffeine_base::BigInt::from_le_bytes(im_neg, im_nb);
4834            let im_dlen = read_uvarint(buf, pos)? as usize;
4835            let im_db = buf.get(*pos..pos.checked_add(im_dlen)?)?;
4836            *pos += im_dlen;
4837            let im = logicaffeine_base::Rational::new(im_num, logicaffeine_base::BigInt::from_le_bytes(false, im_db))?;
4838            RuntimeValue::Complex(Rc::new(logicaffeine_base::Complex::new(re, im)))
4839        }
4840        T_MODULAR => {
4841            let vlen = read_uvarint(buf, pos)? as usize;
4842            let vb = buf.get(*pos..pos.checked_add(vlen)?)?;
4843            *pos += vlen;
4844            let v = logicaffeine_base::BigInt::from_le_bytes(false, vb);
4845            let nlen = read_uvarint(buf, pos)? as usize;
4846            let nb = buf.get(*pos..pos.checked_add(nlen)?)?;
4847            *pos += nlen;
4848            let n = logicaffeine_base::BigInt::from_le_bytes(false, nb);
4849            RuntimeValue::Modular(Rc::new(logicaffeine_base::Modular::new(v, n)?))
4850        }
4851        T_QUANTITY => {
4852            // SI magnitude (rational): sign + numerator (len+LE) + denominator (len+LE).
4853            let num_neg = *buf.get(*pos)? != 0;
4854            *pos += 1;
4855            let nlen = read_uvarint(buf, pos)? as usize;
4856            let nb = buf.get(*pos..pos.checked_add(nlen)?)?;
4857            *pos += nlen;
4858            let num = logicaffeine_base::BigInt::from_le_bytes(num_neg, nb);
4859            let dlen = read_uvarint(buf, pos)? as usize;
4860            let db = buf.get(*pos..pos.checked_add(dlen)?)?;
4861            *pos += dlen;
4862            let magnitude =
4863                logicaffeine_base::Rational::new(num, logicaffeine_base::BigInt::from_le_bytes(false, db))?;
4864            // Dimension: 10 exponent (numerator, denominator) pairs as zig-zag varints.
4865            let mut exps = [logicaffeine_base::Exp::ZERO; logicaffeine_base::BaseDim::COUNT];
4866            for slot in exps.iter_mut() {
4867                let en = unzigzag(read_uvarint(buf, pos)?) as i32;
4868                let ed = unzigzag(read_uvarint(buf, pos)?) as i32;
4869                *slot = logicaffeine_base::Exp::new(en, if ed == 0 { 1 } else { ed });
4870            }
4871            let dim = logicaffeine_base::Dimension::from_exps(exps);
4872            // Display unit symbol — resolve by name, else fall back to the SI/dimension display.
4873            let sym = read_str(buf, pos)?;
4874            let unit = logicaffeine_base::quantity::units::by_name(&sym)
4875                .filter(|u| u.dimension == dim)
4876                .unwrap_or_else(|| {
4877                    logicaffeine_base::Unit::linear("", dim, logicaffeine_base::Rational::one())
4878                });
4879            RuntimeValue::Quantity(Rc::new(crate::interpreter::QuantityValue {
4880                q: logicaffeine_base::Quantity::si(magnitude, dim),
4881                unit,
4882            }))
4883        }
4884        T_FLOAT => {
4885            let b: [u8; 8] = buf.get(*pos..pos.checked_add(8)?)?.try_into().ok()?;
4886            *pos += 8;
4887            RuntimeValue::Float(f64::from_le_bytes(b))
4888        }
4889        T_CHAR => RuntimeValue::Char(char::from_u32(u32::try_from(read_uvarint(buf, pos)?).ok()?)?),
4890        T_TEXT => RuntimeValue::Text(Rc::new(read_str(buf, pos)?)),
4891        T_DURATION => RuntimeValue::Duration(unzigzag(read_uvarint(buf, pos)?)),
4892        T_DATE => RuntimeValue::Date(i32::try_from(unzigzag(read_uvarint(buf, pos)?)).ok()?),
4893        T_MOMENT => RuntimeValue::Moment(unzigzag(read_uvarint(buf, pos)?)),
4894        T_SPAN => RuntimeValue::Span {
4895            months: i32::try_from(unzigzag(read_uvarint(buf, pos)?)).ok()?,
4896            days: i32::try_from(unzigzag(read_uvarint(buf, pos)?)).ok()?,
4897        },
4898        T_TIME => RuntimeValue::Time(unzigzag(read_uvarint(buf, pos)?)),
4899        T_PEER => RuntimeValue::Peer(Rc::new(read_str(buf, pos)?)),
4900        // A mixed list rebuilds as `Boxed` directly — never re-specialized, so a
4901        // round-trip is byte-stable (only genuinely-homogeneous lists are packed).
4902        T_LIST => RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Boxed(read_seq(buf, pos)?)))),
4903        T_INTS
4904        | T_INTS_AFFINE
4905        | T_INTS_GEOMETRIC
4906        | T_INTS_PERIODIC
4907        | T_INTS_SPARSE
4908        | T_INTS_POLY
4909        | T_GEN
4910        | T_BYTES
4911        | T_INTS_DELTA
4912        | T_INTS_DOD
4913        | T_INTS_FOR
4914        | T_INTS_RLE
4915        | T_INTS_DICT
4916        | describe::T_INTS_LRECUR
4917        | describe::T_INTS_LFSR
4918        | describe::T_INTS_FCSR => {
4919            // The Auto column menu decodes through the shared engine (single source of the format);
4920            // the receiver's element budget is threaded in so the DoS gate is unchanged.
4921            let v = describe::decode_int_column_body(tag, buf, pos, receive_limits().max_elements, 0)?;
4922            RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Ints(v))))
4923        }
4924        T_INTS_GV => RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Ints(gv_decode_dispatch(buf, pos)?)))),
4925        // A shipped callable function: read the arity + the bounded generator tree, rebuild a
4926        // self-contained closure the receiver can invoke (the body is the sandboxed generator).
4927        T_FUNC => {
4928            if !receive_limits().accept_computed {
4929                return None;
4930            }
4931            let arity = read_uvarint(buf, pos)? as usize;
4932            if arity > 16 {
4933                return None;
4934            }
4935            let mut budget = MAX_GEN_NODES;
4936            let expr = deserialize_gen(buf, pos, &mut budget, 0)?;
4937            let param_names: Vec<logicaffeine_base::Symbol> =
4938                (0..arity).map(logicaffeine_base::Symbol::from_index).collect();
4939            RuntimeValue::Function(Box::new(ClosureValue {
4940                body_index: usize::MAX,
4941                captured_env: std::collections::HashMap::default(),
4942                param_names,
4943                generated: Some(Rc::new(expr)),
4944            }))
4945        }
4946        T_INTS_FIXED => {
4947            let n = read_uvarint(buf, pos)? as usize;
4948            let nbytes = n.checked_mul(8)?;
4949            let raw = buf.get(*pos..pos.checked_add(nbytes)?)?;
4950            *pos += nbytes;
4951            // Direct memory transfer: copy the little-endian bytes straight into a
4952            // fresh `Vec<i64>` (one `memcpy`), then take ownership.
4953            #[cfg(target_endian = "little")]
4954            let v: Vec<i64> = {
4955                let mut v = Vec::<i64>::with_capacity(n);
4956                // SAFETY: `raw` is exactly `n * 8` bytes; copy into the capacity of
4957                // a properly-aligned `Vec<i64>`, then set its length.
4958                unsafe {
4959                    std::ptr::copy_nonoverlapping(raw.as_ptr(), v.as_mut_ptr().cast::<u8>(), nbytes);
4960                    v.set_len(n);
4961                }
4962                v
4963            };
4964            #[cfg(target_endian = "big")]
4965            let v: Vec<i64> = raw
4966                .chunks_exact(8)
4967                .map(|c| i64::from_le_bytes(c.try_into().unwrap()))
4968                .collect();
4969            RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Ints(v))))
4970        }
4971        // 8-byte-aligned i64 blob: skip the pad, then the same memcpy as T_INTS_FIXED.
4972        T_INTS_ALIGNED => {
4973            let n = read_uvarint(buf, pos)? as usize;
4974            let pad = *buf.get(*pos)? as usize;
4975            *pos += 1 + pad;
4976            let nbytes = n.checked_mul(8)?;
4977            let raw = buf.get(*pos..pos.checked_add(nbytes)?)?;
4978            *pos += nbytes;
4979            #[cfg(target_endian = "little")]
4980            let v: Vec<i64> = {
4981                let mut v = Vec::<i64>::with_capacity(n);
4982                // SAFETY: `raw` is exactly `n * 8` bytes; copy into a properly-aligned
4983                // `Vec<i64>`'s capacity, then set its length.
4984                unsafe {
4985                    std::ptr::copy_nonoverlapping(raw.as_ptr(), v.as_mut_ptr().cast::<u8>(), nbytes);
4986                    v.set_len(n);
4987                }
4988                v
4989            };
4990            #[cfg(target_endian = "big")]
4991            let v: Vec<i64> = raw.chunks_exact(8).map(|c| i64::from_le_bytes(c.try_into().unwrap())).collect();
4992            RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Ints(v))))
4993        }
4994        T_FLOATS => {
4995            let n = bounded_count(read_uvarint(buf, pos)?)?;
4996            let nbytes = n.checked_mul(8)?;
4997            let raw = buf.get(*pos..pos.checked_add(nbytes)?)?;
4998            *pos += nbytes;
4999            // Direct memory transfer: copy the little-endian bytes straight into a
5000            // fresh `Vec<f64>` (one `memcpy`), then take ownership — no per-element
5001            // decode. Bounds were just checked, so the copy reads exactly `nbytes`.
5002            #[cfg(target_endian = "little")]
5003            let v: Vec<f64> = {
5004                let mut v = Vec::<f64>::with_capacity(n);
5005                // SAFETY: `raw` has exactly `n * 8` bytes; we copy them into the
5006                // capacity of a properly-aligned `Vec<f64>`, then set its length.
5007                unsafe {
5008                    std::ptr::copy_nonoverlapping(raw.as_ptr(), v.as_mut_ptr().cast::<u8>(), nbytes);
5009                    v.set_len(n);
5010                }
5011                v
5012            };
5013            #[cfg(target_endian = "big")]
5014            let v: Vec<f64> = raw
5015                .chunks_exact(8)
5016                .map(|c| f64::from_le_bytes(c.try_into().unwrap()))
5017                .collect();
5018            RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Floats(v))))
5019        }
5020        // Constant float column: one f64 + count → fill.
5021        T_FLOATS_CONST => {
5022            let bits = u64::from_le_bytes(buf.get(*pos..pos.checked_add(8)?)?.try_into().ok()?);
5023            *pos += 8;
5024            let n = bounded_count(read_uvarint(buf, pos)?)?;
5025            let mut v = Vec::with_capacity(n.min(PREALLOC_CAP));
5026            v.resize(n, f64::from_bits(bits));
5027            RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Floats(v))))
5028        }
5029        // Affine float column: reconstruct `base + i·stride` with the SAME f64 ops the encoder
5030        // verified bit-exact against, so it round-trips perfectly.
5031        T_FLOATS_AFFINE => {
5032            let base = f64::from_le_bytes(buf.get(*pos..pos.checked_add(8)?)?.try_into().ok()?);
5033            *pos += 8;
5034            let stride = f64::from_le_bytes(buf.get(*pos..pos.checked_add(8)?)?.try_into().ok()?);
5035            *pos += 8;
5036            let n = bounded_count(read_uvarint(buf, pos)?)?;
5037            let mut v = Vec::with_capacity(n.min(PREALLOC_CAP));
5038            for i in 0..n {
5039                v.push(base + (i as f64) * stride);
5040            }
5041            RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Floats(v))))
5042        }
5043        // Sparse float column: fill with the dominant value, then patch the delta-indexed outliers.
5044        T_FLOATS_SPARSE => {
5045            let dom = f64::from_bits(u64::from_le_bytes(buf.get(*pos..pos.checked_add(8)?)?.try_into().ok()?));
5046            *pos += 8;
5047            let n = bounded_count(read_uvarint(buf, pos)?)?;
5048            let num_exc = bounded_count(read_uvarint(buf, pos)?)?;
5049            let mut v = Vec::with_capacity(n.min(PREALLOC_CAP));
5050            v.resize(n, dom);
5051            let mut idx = 0usize;
5052            for _ in 0..num_exc {
5053                idx = idx.checked_add(read_uvarint(buf, pos)? as usize)?;
5054                let bits = u64::from_le_bytes(buf.get(*pos..pos.checked_add(8)?)?.try_into().ok()?);
5055                *pos += 8;
5056                *v.get_mut(idx)? = f64::from_bits(bits);
5057            }
5058            RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Floats(v))))
5059        }
5060        // Cyclic float column: read the period block, then emit `block[i % p]` for `i in 0..n`.
5061        T_FLOATS_PERIODIC => {
5062            let p = bounded_count(read_uvarint(buf, pos)?)?;
5063            if p == 0 {
5064                return None;
5065            }
5066            let n = bounded_count(read_uvarint(buf, pos)?)?;
5067            let mut block = Vec::with_capacity(p.min(PREALLOC_CAP));
5068            for _ in 0..p {
5069                let bits = u64::from_le_bytes(buf.get(*pos..pos.checked_add(8)?)?.try_into().ok()?);
5070                *pos += 8;
5071                block.push(f64::from_bits(bits));
5072            }
5073            let mut v = Vec::with_capacity(n.min(PREALLOC_CAP));
5074            for i in 0..n {
5075                v.push(block[i % p]);
5076            }
5077            RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Floats(v))))
5078        }
5079        // Geometric float column: replay `base · ratio^i` with the SAME `cur *= ratio` accumulation
5080        // the encoder verified bit-exact against.
5081        T_FLOATS_GEOMETRIC => {
5082            let base = f64::from_le_bytes(buf.get(*pos..pos.checked_add(8)?)?.try_into().ok()?);
5083            *pos += 8;
5084            let ratio = f64::from_le_bytes(buf.get(*pos..pos.checked_add(8)?)?.try_into().ok()?);
5085            *pos += 8;
5086            let n = bounded_count(read_uvarint(buf, pos)?)?;
5087            let mut v = Vec::with_capacity(n.min(PREALLOC_CAP));
5088            let mut cur = base;
5089            for _ in 0..n {
5090                v.push(cur);
5091                cur *= ratio;
5092            }
5093            RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Floats(v))))
5094        }
5095        // 8-byte-aligned f64 blob: skip the pad, then the same memcpy as T_FLOATS.
5096        T_FLOATS_ALIGNED => {
5097            let n = read_uvarint(buf, pos)? as usize;
5098            let pad = *buf.get(*pos)? as usize;
5099            *pos += 1 + pad;
5100            let nbytes = n.checked_mul(8)?;
5101            let raw = buf.get(*pos..pos.checked_add(nbytes)?)?;
5102            *pos += nbytes;
5103            #[cfg(target_endian = "little")]
5104            let v: Vec<f64> = {
5105                let mut v = Vec::<f64>::with_capacity(n);
5106                // SAFETY: `raw` is exactly `n * 8` bytes; copy into a properly-aligned
5107                // `Vec<f64>`'s capacity, then set its length.
5108                unsafe {
5109                    std::ptr::copy_nonoverlapping(raw.as_ptr(), v.as_mut_ptr().cast::<u8>(), nbytes);
5110                    v.set_len(n);
5111                }
5112                v
5113            };
5114            #[cfg(target_endian = "big")]
5115            let v: Vec<f64> = raw.chunks_exact(8).map(|c| f64::from_le_bytes(c.try_into().unwrap())).collect();
5116            RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Floats(v))))
5117        }
5118        // Lossless XOR-delta float array: undo the running XOR and rebuild each f64
5119        // from its exact bits (NaN/Inf/±0/subnormals preserved).
5120        T_FLOATS_XOR => {
5121            let n = read_uvarint(buf, pos)? as usize;
5122            let mut v = Vec::with_capacity(n.min(PREALLOC_CAP));
5123            let mut prev = 0u64;
5124            for _ in 0..n {
5125                let bits = read_uvarint(buf, pos)? ^ prev;
5126                prev = bits;
5127                v.push(f64::from_bits(bits));
5128            }
5129            RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Floats(v))))
5130        }
5131        T_BOOLS => {
5132            let n = read_uvarint(buf, pos)? as usize;
5133            let nbytes = n.div_ceil(8);
5134            let bits = buf.get(*pos..pos.checked_add(nbytes)?)?;
5135            *pos += nbytes;
5136            let mut v = Vec::with_capacity(n.min(PREALLOC_CAP));
5137            for i in 0..n {
5138                v.push((bits[i / 8] >> (i % 8)) & 1 == 1);
5139            }
5140            RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Bools(v))))
5141        }
5142        // Cyclic bool column: read the p-bit block, replay `block[i % p]` for `i in 0..n`.
5143        T_BOOLS_PERIODIC => {
5144            let p = bounded_count(read_uvarint(buf, pos)?)?;
5145            if p == 0 {
5146                return None;
5147            }
5148            let n = bounded_count(read_uvarint(buf, pos)?)?;
5149            let block_bytes = p.div_ceil(8);
5150            let raw = buf.get(*pos..pos.checked_add(block_bytes)?)?;
5151            *pos += block_bytes;
5152            let block: Vec<bool> = (0..p).map(|i| (raw[i / 8] >> (i % 8)) & 1 == 1).collect();
5153            let mut v = Vec::with_capacity(n.min(PREALLOC_CAP));
5154            for i in 0..n {
5155                v.push(block[i % p]);
5156            }
5157            RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Bools(v))))
5158        }
5159        // Run-length bool column: alternate from the first value, emitting each run length in turn.
5160        T_BOOLS_RLE => {
5161            let n = bounded_count(read_uvarint(buf, pos)?)?;
5162            let first = *buf.get(*pos)? != 0;
5163            *pos += 1;
5164            let nruns = bounded_count(read_uvarint(buf, pos)?)?;
5165            let mut v = Vec::with_capacity(n.min(PREALLOC_CAP));
5166            let mut cur = first;
5167            for _ in 0..nruns {
5168                let runlen = bounded_count(read_uvarint(buf, pos)?)?;
5169                // The runs must reconstruct EXACTLY `n` elements — a corrupt over-run is refused.
5170                if v.len().checked_add(runlen)? > n {
5171                    return None;
5172                }
5173                v.resize(v.len() + runlen, cur);
5174                cur = !cur;
5175            }
5176            if v.len() != n {
5177                return None;
5178            }
5179            RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Bools(v))))
5180        }
5181        T_STRINGS => {
5182            let n = read_uvarint(buf, pos)? as usize;
5183            let mut ends = Vec::with_capacity(n.min(PREALLOC_CAP));
5184            let mut total: u64 = 0;
5185            for _ in 0..n {
5186                total = total.checked_add(read_uvarint(buf, pos)?)?;
5187                ends.push(u32::try_from(total).ok()?);
5188            }
5189            let total = usize::try_from(total).ok()?;
5190            let raw = buf.get(*pos..pos.checked_add(total)?)?;
5191            *pos += total;
5192            // The concatenation of valid UTF-8 strings is itself valid UTF-8;
5193            // validate the whole blob once (SIMD-fast in std) so element access can
5194            // trust it, and reject corrupt data here. One bulk copy into the buffer.
5195            if std::str::from_utf8(raw).is_err() {
5196                return None;
5197            }
5198            RuntimeValue::List(Rc::new(RefCell::new(ListRepr::strings(raw.to_vec(), ends))))
5199        }
5200        // Templated string column: rebuild `prefix + (base + i·stride) + suffix` for `i in 0..n`.
5201        T_STRINGS_TEMPLATE => {
5202            let plen = bounded_count(read_uvarint(buf, pos)?)?;
5203            let prefix = buf.get(*pos..pos.checked_add(plen)?)?.to_vec();
5204            *pos += plen;
5205            let slen = bounded_count(read_uvarint(buf, pos)?)?;
5206            let suffix = buf.get(*pos..pos.checked_add(slen)?)?.to_vec();
5207            *pos += slen;
5208            let base = unzigzag(read_uvarint(buf, pos)?);
5209            let stride = unzigzag(read_uvarint(buf, pos)?);
5210            let n = bounded_count(read_uvarint(buf, pos)?)?;
5211            // The affixes came from valid strings; a corrupt frame that isn't UTF-8 is refused.
5212            if std::str::from_utf8(&prefix).is_err() || std::str::from_utf8(&suffix).is_err() {
5213                return None;
5214            }
5215            let mut data = Vec::new();
5216            let mut ends = Vec::with_capacity(n.min(PREALLOC_CAP));
5217            for i in 0..n {
5218                let num = base.wrapping_add((i as i64).wrapping_mul(stride));
5219                data.extend_from_slice(&prefix);
5220                data.extend_from_slice(num.to_string().as_bytes());
5221                data.extend_from_slice(&suffix);
5222                ends.push(u32::try_from(data.len()).ok()?);
5223            }
5224            RuntimeValue::List(Rc::new(RefCell::new(ListRepr::strings(data, ends))))
5225        }
5226        // Front-coded string column: rebuild each string as `prev[..common] + suffix`.
5227        T_STRINGS_FRONT => {
5228            let n = bounded_count(read_uvarint(buf, pos)?)?;
5229            let mut data: Vec<u8> = Vec::new();
5230            let mut ends = Vec::with_capacity(n.min(PREALLOC_CAP));
5231            let mut prev: Vec<u8> = Vec::new();
5232            for _ in 0..n {
5233                let common = bounded_count(read_uvarint(buf, pos)?)?;
5234                let suffix_len = bounded_count(read_uvarint(buf, pos)?)?;
5235                // Can't share more prefix than the previous string has — a corrupt frame is refused.
5236                if common > prev.len() {
5237                    return None;
5238                }
5239                let suffix = buf.get(*pos..pos.checked_add(suffix_len)?)?;
5240                *pos += suffix_len;
5241                let mut s = Vec::with_capacity(common.checked_add(suffix_len)?);
5242                s.extend_from_slice(&prev[..common]);
5243                s.extend_from_slice(suffix);
5244                data.extend_from_slice(&s);
5245                ends.push(u32::try_from(data.len()).ok()?);
5246                prev = s;
5247            }
5248            // The concatenation must be valid UTF-8 (front-coding cuts on char boundaries; a corrupt
5249            // `common`/suffix that lands mid-char is rejected here rather than producing bad strings).
5250            if std::str::from_utf8(&data).is_err() {
5251                return None;
5252            }
5253            RuntimeValue::List(Rc::new(RefCell::new(ListRepr::strings(data, ends))))
5254        }
5255        // Affixed string column: rebuild each string as `prefix + middle_i + suffix`.
5256        T_STRINGS_AFFIX => {
5257            let plen = bounded_count(read_uvarint(buf, pos)?)?;
5258            let prefix = buf.get(*pos..pos.checked_add(plen)?)?.to_vec();
5259            *pos += plen;
5260            let slen = bounded_count(read_uvarint(buf, pos)?)?;
5261            let suffix = buf.get(*pos..pos.checked_add(slen)?)?.to_vec();
5262            *pos += slen;
5263            let n = bounded_count(read_uvarint(buf, pos)?)?;
5264            let mut data: Vec<u8> = Vec::new();
5265            let mut ends = Vec::with_capacity(n.min(PREALLOC_CAP));
5266            for _ in 0..n {
5267                let mid_len = bounded_count(read_uvarint(buf, pos)?)?;
5268                let mid = buf.get(*pos..pos.checked_add(mid_len)?)?;
5269                *pos += mid_len;
5270                data.extend_from_slice(&prefix);
5271                data.extend_from_slice(mid);
5272                data.extend_from_slice(&suffix);
5273                ends.push(u32::try_from(data.len()).ok()?);
5274            }
5275            // Affixes + middles all came from valid strings; reject a corrupt non-UTF-8 frame.
5276            if std::str::from_utf8(&data).is_err() {
5277                return None;
5278            }
5279            RuntimeValue::List(Rc::new(RefCell::new(ListRepr::strings(data, ends))))
5280        }
5281        // Dictionary string column: the distinct strings once, then a bit-packed index per row.
5282        // Reconstruct the flat `Strings` buffer by replaying each row's dictionary entry.
5283        T_STRINGS_DICT => {
5284            let d = read_uvarint(buf, pos)? as usize;
5285            let mut dict: Vec<&[u8]> = Vec::with_capacity(d.min(PREALLOC_CAP));
5286            for _ in 0..d {
5287                let len = read_uvarint(buf, pos)? as usize;
5288                let s = buf.get(*pos..pos.checked_add(len)?)?;
5289                if std::str::from_utf8(s).is_err() {
5290                    return None;
5291                }
5292                dict.push(s);
5293                *pos += len;
5294            }
5295            let n = read_uvarint(buf, pos)? as usize;
5296            let iw = *buf.get(*pos)?;
5297            *pos += 1;
5298            if iw > 64 {
5299                return None;
5300            }
5301            let mut out_data: Vec<u8> = Vec::new();
5302            let mut out_ends: Vec<u32> = Vec::with_capacity(n.min(PREALLOC_CAP));
5303            let mut push = |s: &[u8], out_data: &mut Vec<u8>, out_ends: &mut Vec<u32>| {
5304                out_data.extend_from_slice(s);
5305                out_ends.push(out_data.len() as u32);
5306            };
5307            if iw == 0 {
5308                if n > 0 {
5309                    let s = *dict.first()?;
5310                    for _ in 0..n {
5311                        push(s, &mut out_data, &mut out_ends);
5312                    }
5313                }
5314            } else {
5315                let nbytes = n.checked_mul(iw as usize)?.div_ceil(8);
5316                let bytes = buf.get(*pos..pos.checked_add(nbytes)?)?;
5317                *pos += nbytes;
5318                for ix in bitunpack(bytes, n, iw)? {
5319                    push(*dict.get(ix as usize)?, &mut out_data, &mut out_ends);
5320                }
5321            }
5322            RuntimeValue::List(Rc::new(RefCell::new(ListRepr::strings(out_data, out_ends))))
5323        }
5324        T_TUPLE => RuntimeValue::Tuple(Rc::new(read_seq(buf, pos)?)),
5325        T_SET => RuntimeValue::Set(Rc::new(RefCell::new(read_seq(buf, pos)?))),
5326        T_SET_INTS => {
5327            // The body is a best-encoded int column (any `T_INTS_*` form); decode it as a list —
5328            // the recovered ints ARE the set's (already canonical-sorted) members.
5329            let ints = match native_decode(buf, pos)? {
5330                RuntimeValue::List(l) => l.borrow().to_values(),
5331                _ => return None,
5332            };
5333            RuntimeValue::Set(Rc::new(RefCell::new(ints)))
5334        }
5335        T_SET_STRINGS => {
5336            // Front-coded: reconstruct each member from `common` bytes of the previous + the suffix.
5337            let n = read_uvarint(buf, pos)? as usize;
5338            let mut items = Vec::with_capacity(n);
5339            let mut prev = String::new();
5340            for _ in 0..n {
5341                let common = read_uvarint(buf, pos)? as usize;
5342                if common > prev.len() || !prev.is_char_boundary(common) {
5343                    return None;
5344                }
5345                let suffix = read_str(buf, pos)?;
5346                let s = format!("{}{}", &prev[..common], suffix);
5347                items.push(RuntimeValue::Text(Rc::new(s.clone())));
5348                prev = s;
5349            }
5350            RuntimeValue::Set(Rc::new(RefCell::new(items)))
5351        }
5352        T_MAP => {
5353            let n = read_uvarint(buf, pos)?;
5354            let mut m = MapStorage::default();
5355            for _ in 0..n {
5356                let k = native_decode(buf, pos)?;
5357                let v = native_decode(buf, pos)?;
5358                m.insert(k, v);
5359            }
5360            RuntimeValue::Map(Rc::new(RefCell::new(m)))
5361        }
5362        T_MAP_INTKEY => {
5363            // The int key column, a value-kind byte, then the values. Re-pair positionally — keys were
5364            // written in numeric order, values in the corresponding order.
5365            let keys = match native_decode(buf, pos)? {
5366                RuntimeValue::List(l) => l.borrow().to_values(),
5367                _ => return None,
5368            };
5369            let kind = *buf.get(*pos)?;
5370            *pos += 1;
5371            let vals: Vec<RuntimeValue> = match kind {
5372                1 => match native_decode(buf, pos)? {
5373                    RuntimeValue::List(l) => l.borrow().to_values(),
5374                    _ => return None,
5375                },
5376                2 => {
5377                    // Front-coded string column: reconstruct each value from `common` bytes of the
5378                    // previous + the suffix (mirrors T_SET_STRINGS).
5379                    let n = read_uvarint(buf, pos)? as usize;
5380                    let mut vs = Vec::with_capacity(n.min(keys.len().saturating_add(1)));
5381                    let mut prev = String::new();
5382                    for _ in 0..n {
5383                        let common = read_uvarint(buf, pos)? as usize;
5384                        if common > prev.len() || !prev.is_char_boundary(common) {
5385                            return None;
5386                        }
5387                        let suffix = read_str(buf, pos)?;
5388                        let s = format!("{}{}", &prev[..common], suffix);
5389                        vs.push(RuntimeValue::Text(Rc::new(s.clone())));
5390                        prev = s;
5391                    }
5392                    vs
5393                }
5394                3 => match native_decode(buf, pos)? {
5395                    // Columnar struct value list (or a tagged list for heterogeneous structs).
5396                    RuntimeValue::List(l) => l.borrow().to_values(),
5397                    _ => return None,
5398                },
5399                0 => {
5400                    let n = read_uvarint(buf, pos)? as usize;
5401                    let mut vs = Vec::with_capacity(n.min(keys.len().saturating_add(1)));
5402                    for _ in 0..n {
5403                        vs.push(native_decode(buf, pos)?);
5404                    }
5405                    vs
5406                }
5407                _ => return None,
5408            };
5409            if keys.len() != vals.len() {
5410                return None;
5411            }
5412            let mut m = MapStorage::default();
5413            for (k, v) in keys.into_iter().zip(vals.into_iter()) {
5414                m.insert(k, v);
5415            }
5416            RuntimeValue::Map(Rc::new(RefCell::new(m)))
5417        }
5418        T_STRUCT => {
5419            let type_name = read_str(buf, pos)?;
5420            let n = read_uvarint(buf, pos)?;
5421            let mut fields = std::collections::HashMap::with_capacity((n as usize).min(PREALLOC_CAP));
5422            for _ in 0..n {
5423                let name = read_str(buf, pos)?;
5424                let val = native_decode(buf, pos)?;
5425                fields.insert(name, val);
5426            }
5427            RuntimeValue::Struct(Box::new(StructValue { type_name, fields }))
5428        }
5429        // Single-struct schema DEFINITION (sequential): id + schema inline (registered),
5430        // then values in field order. Self-decodable even without a cache.
5431        T_STRUCT_DEF => {
5432            let id = read_uvarint(buf, pos)? as u32;
5433            let (type_name, field_names) = read_struct_schema(buf, pos)?;
5434            if !schema_recv_register_seq(id, &type_name, &field_names) {
5435                return None; // out-of-order / conflicting schema definition
5436            }
5437            decode_struct_values(buf, pos, type_name, field_names)?
5438        }
5439        // Single-struct schema REFERENCE (sequential): id resolved against the cache,
5440        // then values only. `None` (clean) if the schema was never defined here.
5441        T_STRUCT_REF => {
5442            let id = read_uvarint(buf, pos)? as u32;
5443            let (type_name, field_names) = schema_recv_lookup_seq(id)?;
5444            decode_struct_values(buf, pos, type_name, field_names)?
5445        }
5446        // Single-struct schema DEFINITION (content-addressed): schema inline (its
5447        // fingerprint derived + registered), then values. A fingerprint that conflicts
5448        // with a different cached schema is rejected.
5449        T_STRUCT_CDEF => {
5450            let (type_name, field_names) = read_struct_schema(buf, pos)?;
5451            if !schema_recv_register_ca(&type_name, &field_names) {
5452                return None; // fingerprint collision with a different schema
5453            }
5454            decode_struct_values(buf, pos, type_name, field_names)?
5455        }
5456        // Single-struct schema REFERENCE (content-addressed): an 8-byte fingerprint,
5457        // then values. `None` (clean) if no definition for it was seen (reorder/loss).
5458        T_STRUCT_CREF => {
5459            let raw = buf.get(*pos..pos.checked_add(8)?)?;
5460            let fp = u64::from_le_bytes(raw.try_into().ok()?);
5461            *pos += 8;
5462            let (type_name, field_names) = schema_recv_lookup_ca(fp)?;
5463            decode_struct_values(buf, pos, type_name, field_names)?
5464        }
5465        // Type-id elided struct: resolve the id against the shared registry (the receiver
5466        // runs the same program), then read the values. Unknown id → None (clean fail).
5467        T_STRUCT_TID => {
5468            let id = read_uvarint(buf, pos)? as u32;
5469            let (type_name, field_names) = type_registry_schema(id)?;
5470            decode_struct_values(buf, pos, type_name, field_names)?
5471        }
5472        // Offset-table view struct: read the schema, SKIP the offset table (a full decode
5473        // reads the values sequentially; the table is only for `WireView` random access).
5474        T_STRUCT_VIEW => {
5475            let type_name = read_str(buf, pos)?;
5476            let n = read_uvarint(buf, pos)? as usize;
5477            let mut field_names = Vec::with_capacity(n.min(PREALLOC_CAP));
5478            for _ in 0..n {
5479                field_names.push(read_str(buf, pos)?);
5480            }
5481            *pos = pos.checked_add(n.checked_mul(4)?)?; // skip the offset table
5482            if *pos > buf.len() {
5483                return None;
5484            }
5485            decode_struct_values(buf, pos, type_name, field_names)?
5486        }
5487        // Random-access record-list view: shared schema, then the row table (skipped), then
5488        // each row's field table (skipped) + values. We zip the rows back into structs and
5489        // re-columnarize via `from_values`, so re-encoding is byte-stable with the original.
5490        T_STRUCTS_VIEW => {
5491            let type_name = read_str(buf, pos)?;
5492            let f = read_uvarint(buf, pos)? as usize;
5493            let mut field_names = Vec::with_capacity(f.min(PREALLOC_CAP));
5494            for _ in 0..f {
5495                field_names.push(read_str(buf, pos)?);
5496            }
5497            let n = read_uvarint(buf, pos)? as usize;
5498            *pos = pos.checked_add(n.checked_mul(4)?)?; // skip the row offset table
5499            if *pos > buf.len() {
5500                return None;
5501            }
5502            let mut rows = Vec::with_capacity(n.min(PREALLOC_CAP));
5503            for _ in 0..n {
5504                *pos = pos.checked_add(f.checked_mul(4)?)?; // skip this row's field offset table
5505                if *pos > buf.len() {
5506                    return None;
5507                }
5508                rows.push(decode_struct_values(buf, pos, type_name.clone(), field_names.clone())?);
5509            }
5510            RuntimeValue::List(Rc::new(RefCell::new(ListRepr::from_values(rows))))
5511        }
5512        // FIXED-stride record-list view: read the shared schema + the F kind bytes, then read
5513        // each row's cells by arithmetic (no offset tables), resolving FK_TEXT against the blob.
5514        T_STRUCTS_FVIEW => {
5515            let type_name = read_str(buf, pos)?;
5516            let f = read_uvarint(buf, pos)? as usize;
5517            let mut field_names = Vec::with_capacity(f.min(PREALLOC_CAP));
5518            for _ in 0..f {
5519                field_names.push(read_str(buf, pos)?);
5520            }
5521            let kinds = buf.get(*pos..pos.checked_add(f)?)?.to_vec();
5522            *pos += f;
5523            let n = read_uvarint(buf, pos)? as usize;
5524            let (offsets, stride) = fview_layout(&kinds);
5525            let rows_start = *pos;
5526            let rows_len = n.checked_mul(stride)?;
5527            let rows_bytes = buf.get(rows_start..rows_start.checked_add(rows_len)?)?;
5528            *pos = rows_start.checked_add(rows_len)?;
5529            let blob_len = read_uvarint(buf, pos)? as usize;
5530            let blob = buf.get(*pos..pos.checked_add(blob_len)?)?;
5531            *pos = pos.checked_add(blob_len)?;
5532            // Decode each field STRAIGHT into a typed column (no per-row HashMap, no `from_values`
5533            // re-scan) — the decode twin of the columnar encode. `field_names` is already the
5534            // canonical sorted order, so this is the same `Structs` repr `from_values` would build.
5535            let mut columns: Vec<ListRepr> = Vec::with_capacity(f);
5536            for j in 0..f {
5537                let off = offsets[j];
5538                let col = match kinds[j] {
5539                    FK_INT => {
5540                        let mut v = Vec::with_capacity(n.min(PREALLOC_CAP));
5541                        for r in 0..n {
5542                            let base = r.checked_mul(stride)?.checked_add(off)?;
5543                            v.push(i64::from_le_bytes(rows_bytes.get(base..base.checked_add(8)?)?.try_into().ok()?));
5544                        }
5545                        ListRepr::Ints(v)
5546                    }
5547                    FK_FLOAT => {
5548                        let mut v = Vec::with_capacity(n.min(PREALLOC_CAP));
5549                        for r in 0..n {
5550                            let base = r.checked_mul(stride)?.checked_add(off)?;
5551                            v.push(f64::from_le_bytes(rows_bytes.get(base..base.checked_add(8)?)?.try_into().ok()?));
5552                        }
5553                        ListRepr::Floats(v)
5554                    }
5555                    FK_BOOL => {
5556                        let mut v = Vec::with_capacity(n.min(PREALLOC_CAP));
5557                        for r in 0..n {
5558                            let base = r.checked_mul(stride)?.checked_add(off)?;
5559                            v.push(*rows_bytes.get(base)? != 0);
5560                        }
5561                        ListRepr::Bools(v)
5562                    }
5563                    FK_TEXT => {
5564                        let mut data: Vec<u8> = Vec::new();
5565                        let mut ends: Vec<u32> = Vec::with_capacity(n.min(PREALLOC_CAP));
5566                        for r in 0..n {
5567                            let base = r.checked_mul(stride)?.checked_add(off)?;
5568                            let toff =
5569                                u32::from_le_bytes(rows_bytes.get(base..base.checked_add(4)?)?.try_into().ok()?) as usize;
5570                            let tlen = u32::from_le_bytes(
5571                                rows_bytes.get(base.checked_add(4)?..base.checked_add(8)?)?.try_into().ok()?,
5572                            ) as usize;
5573                            data.extend_from_slice(blob.get(toff..toff.checked_add(tlen)?)?);
5574                            ends.push(data.len() as u32);
5575                        }
5576                        ListRepr::strings(data, ends)
5577                    }
5578                    _ => return None,
5579                };
5580                columns.push(col);
5581            }
5582            RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Structs { type_name, field_names, columns })))
5583        }
5584        T_INDUCTIVE => {
5585            let inductive_type = read_str(buf, pos)?;
5586            let constructor = read_str(buf, pos)?;
5587            let args = read_seq(buf, pos)?;
5588            RuntimeValue::Inductive(Box::new(InductiveValue { inductive_type, constructor, args }))
5589        }
5590        // Type-id elided enum: resolve the enum id + constructor index against the shared
5591        // registry, then read the args. Unknown id / out-of-range index → None (clean).
5592        T_INDUCTIVE_TID => {
5593            let enum_id = read_uvarint(buf, pos)? as u32;
5594            let ctor_idx = read_uvarint(buf, pos)? as usize;
5595            let (inductive_type, ctors) = type_registry_enum_schema(enum_id)?;
5596            let constructor = ctors.get(ctor_idx)?.clone();
5597            let args = read_seq(buf, pos)?;
5598            RuntimeValue::Inductive(Box::new(InductiveValue { inductive_type, constructor, args }))
5599        }
5600        // Columnar struct list: schema once, then one self-describing packed column
5601        // per field; we read the columns and zip them back into N structs. Decoding
5602        // to `Boxed` keeps re-encoding byte-stable (the schema re-derives identically).
5603        // Self-describing struct list: schema inline, then the columns.
5604        T_STRUCTS => {
5605            let (type_name, field_names) = read_struct_schema(buf, pos)?;
5606            decode_struct_columns(buf, pos, type_name, field_names)?
5607        }
5608        // Shared-registry struct list: resolve the type id (names elided), then columns.
5609        // `None` (clean) if the id can't be resolved against this decoder's registry.
5610        T_STRUCTS_TID => {
5611            let id = read_uvarint(buf, pos)? as u32;
5612            let (type_name, field_names) = type_registry_schema(id)?;
5613            decode_struct_columns(buf, pos, type_name, field_names)?
5614        }
5615        // Sequential schema DEFINITION: id + schema inline (registered), then columns.
5616        // Self-decodable even without a cache.
5617        T_STRUCTS_DEF => {
5618            let id = read_uvarint(buf, pos)? as u32;
5619            let (type_name, field_names) = read_struct_schema(buf, pos)?;
5620            if !schema_recv_register_seq(id, &type_name, &field_names) {
5621                return None; // out-of-order / conflicting schema definition
5622            }
5623            decode_struct_columns(buf, pos, type_name, field_names)?
5624        }
5625        // Sequential schema REFERENCE: id resolved against the cache, then columns.
5626        // `None` (clean) if the schema was never defined to this decoder.
5627        T_STRUCTS_REF => {
5628            let id = read_uvarint(buf, pos)? as u32;
5629            let (type_name, field_names) = schema_recv_lookup_seq(id)?;
5630            decode_struct_columns(buf, pos, type_name, field_names)?
5631        }
5632        // Content-addressed schema DEFINITION: schema inline (the fingerprint is
5633        // derived from it), registered under its fingerprint, then columns. A
5634        // fingerprint that conflicts with a different cached schema is rejected.
5635        T_STRUCTS_CDEF => {
5636            let (type_name, field_names) = read_struct_schema(buf, pos)?;
5637            if !schema_recv_register_ca(&type_name, &field_names) {
5638                return None; // fingerprint collision with a different schema
5639            }
5640            decode_struct_columns(buf, pos, type_name, field_names)?
5641        }
5642        // Content-addressed schema REFERENCE: an 8-byte fingerprint, then columns.
5643        // `None` (clean) if no definition for that fingerprint was seen (reorder/loss).
5644        T_STRUCTS_CREF => {
5645            let raw = buf.get(*pos..pos.checked_add(8)?)?;
5646            let fp = u64::from_le_bytes(raw.try_into().ok()?);
5647            *pos += 8;
5648            let (type_name, field_names) = schema_recv_lookup_ca(fp)?;
5649            decode_struct_columns(buf, pos, type_name, field_names)?
5650        }
5651        // Columnar enum list (tagged union): type once + constructor dictionary with
5652        // arities + the per-row index column + dense per-constructor arg columns.
5653        // Decodes STRAIGHT into the columnar `Inductives` repr (no per-row rebuild);
5654        // `ranks` are recomputed here. Nullary enums have all-zero arities.
5655        T_INDUCTIVES => {
5656            let inductive_type = read_str(buf, pos)?;
5657            let d = read_uvarint(buf, pos)? as usize;
5658            let mut ctor_dict = Vec::with_capacity(d.min(PREALLOC_CAP));
5659            let mut arities = Vec::with_capacity(d.min(PREALLOC_CAP));
5660            for _ in 0..d {
5661                ctor_dict.push(read_str(buf, pos)?);
5662                arities.push(read_uvarint(buf, pos)? as usize);
5663            }
5664            // The constructor-index column → `ctors: Vec<u32>` (each index < d).
5665            let idx = match native_decode(buf, pos)? {
5666                RuntimeValue::List(l) => Rc::try_unwrap(l).map(RefCell::into_inner).unwrap_or_else(|rc| rc.borrow().clone()),
5667                _ => return None,
5668            };
5669            let mut ctors: Vec<u32> = Vec::with_capacity(idx.len().min(PREALLOC_CAP));
5670            for v in idx.to_values() {
5671                match v {
5672                    RuntimeValue::Int(i) if i >= 0 && (i as usize) < d => ctors.push(i as u32),
5673                    _ => return None,
5674                }
5675            }
5676            // The dense per-constructor argument columns.
5677            let mut arg_cols: Vec<Vec<ListRepr>> = Vec::with_capacity(d.min(PREALLOC_CAP));
5678            for &arity in &arities {
5679                let mut cols = Vec::with_capacity(arity.min(PREALLOC_CAP));
5680                for _ in 0..arity {
5681                    let col = match native_decode(buf, pos)? {
5682                        RuntimeValue::List(l) => Rc::try_unwrap(l).map(RefCell::into_inner).unwrap_or_else(|rc| rc.borrow().clone()),
5683                        _ => return None,
5684                    };
5685                    cols.push(col);
5686                }
5687                arg_cols.push(cols);
5688            }
5689            // Recompute ranks and validate each constructor's column lengths.
5690            let mut counts = vec![0u32; d];
5691            let mut ranks = Vec::with_capacity(ctors.len());
5692            for &c in &ctors {
5693                ranks.push(counts[c as usize]);
5694                counts[c as usize] += 1;
5695            }
5696            for c in 0..d {
5697                if arg_cols[c].iter().any(|col| col.len() != counts[c] as usize) {
5698                    return None; // a column whose length disagrees with the constructor count
5699                }
5700            }
5701            RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Inductives {
5702                inductive_type,
5703                ctor_dict,
5704                ctors,
5705                ranks,
5706                arg_cols,
5707            })))
5708        }
5709        _ => return None,
5710    })
5711}
5712
5713fn read_seq(buf: &[u8], pos: &mut usize) -> Option<Vec<RuntimeValue>> {
5714    let n = bounded_count(read_uvarint(buf, pos)?)?;
5715    let mut v = Vec::with_capacity(n.min(PREALLOC_CAP));
5716    for _ in 0..n {
5717        v.push(native_decode(buf, pos)?);
5718    }
5719    Some(v)
5720}
5721
5722/// Read a struct schema (type name + field names) from the wire.
5723fn read_struct_schema(buf: &[u8], pos: &mut usize) -> Option<(String, Vec<String>)> {
5724    let type_name = read_str(buf, pos)?;
5725    let k = read_uvarint(buf, pos)? as usize;
5726    let mut field_names = Vec::with_capacity(k.min(PREALLOC_CAP));
5727    for _ in 0..k {
5728        field_names.push(read_str(buf, pos)?);
5729    }
5730    Some((type_name, field_names))
5731}
5732
5733/// Rebuild a single struct from a known schema (the schema-dictionary forms): one
5734/// value per field, in the schema's canonical field order, zipped back by name.
5735fn decode_struct_values(
5736    buf: &[u8],
5737    pos: &mut usize,
5738    type_name: String,
5739    field_names: Vec<String>,
5740) -> Option<RuntimeValue> {
5741    let mut fields = std::collections::HashMap::with_capacity(field_names.len().min(PREALLOC_CAP));
5742    for name in field_names {
5743        let val = native_decode(buf, pos)?;
5744        fields.insert(name, val);
5745    }
5746    Some(RuntimeValue::Struct(Box::new(StructValue { type_name, fields })))
5747}
5748
5749/// Read a struct list's body (the row count + one self-describing column per field)
5750/// given its schema, decoding STRAIGHT into the columnar `Structs` repr (no per-row
5751/// rebuild). A zero-field schema — which our encoder never emits — falls back to
5752/// boxed empty structs so the row count survives.
5753fn decode_struct_columns(
5754    buf: &[u8],
5755    pos: &mut usize,
5756    type_name: String,
5757    field_names: Vec<String>,
5758) -> Option<RuntimeValue> {
5759    let k = field_names.len();
5760    let n = read_uvarint(buf, pos)? as usize;
5761    let mut columns: Vec<ListRepr> = Vec::with_capacity(k.min(PREALLOC_CAP));
5762    for _ in 0..k {
5763        // Keep each decoded column AS its packed `ListRepr` (no `to_values`):
5764        // `native_decode` just minted this `Rc`, so `try_unwrap` takes the inner
5765        // buffer without cloning.
5766        let col = match native_decode(buf, pos)? {
5767            RuntimeValue::List(l) => Rc::try_unwrap(l).map(RefCell::into_inner).unwrap_or_else(|rc| rc.borrow().clone()),
5768            _ => return None,
5769        };
5770        if col.len() != n {
5771            return None; // a column whose length disagrees with the row count
5772        }
5773        columns.push(col);
5774    }
5775    Some(if columns.is_empty() {
5776        let rows = (0..n)
5777            .map(|_| {
5778                RuntimeValue::Struct(Box::new(StructValue {
5779                    type_name: type_name.clone(),
5780                    fields: std::collections::HashMap::new(),
5781                }))
5782            })
5783            .collect();
5784        RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Boxed(rows))))
5785    } else {
5786        RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Structs { type_name, field_names, columns })))
5787    })
5788}
5789
5790fn header(codec: WireCodec, integrity: WireIntegrity, compression: WireCompression) -> u8 {
5791    let c = if matches!(codec, WireCodec::Json) { H_JSON } else { 0 };
5792    let i = if matches!(integrity, WireIntegrity::Checked) { H_CHECKED } else { 0 };
5793    let z = if compression == WireCompression::None { 0 } else { H_COMPRESSED | (compression_id(compression) << 2) };
5794    c | i | z
5795}
5796
5797/// Wrap a body in its frame: the header byte, then (for `Checked`) an 8-byte
5798/// FNV-1a checksum over the (possibly compressed) body, then the body.
5799fn frame(codec: WireCodec, integrity: WireIntegrity, compression: WireCompression, body: Vec<u8>) -> Vec<u8> {
5800    let h = header(codec, integrity, compression);
5801    match integrity {
5802        WireIntegrity::Raw => {
5803            let mut out = Vec::with_capacity(body.len() + 1);
5804            out.push(h);
5805            out.extend_from_slice(&body);
5806            out
5807        }
5808        WireIntegrity::Checked => {
5809            let mut out = Vec::with_capacity(body.len() + 9);
5810            out.push(h);
5811            out.extend_from_slice(&fnv1a_64(&body).to_le_bytes());
5812            out.extend_from_slice(&body);
5813            out
5814        }
5815    }
5816}
5817
5818/// Strip the frame: return `(codec, compressed, body)`, verifying the checksum in
5819/// `Checked` mode. `None` on an unknown header, a short frame, or a checksum
5820/// mismatch. The checksum is verified BEFORE the caller inflates, so a corrupt
5821/// message never reaches the decompressor.
5822/// Decode the frame header into `(codec, compression, body)`. When `verify` is set and the
5823/// message carries a checksum, the body is FNV-validated (O(body)) — corruption → `None`.
5824/// A zero-copy view passes `verify = false` so opening a message is always O(1) (a checksum
5825/// hash would defeat random access; the view trusts the bytes, like Cap'n Proto / Arrow).
5826fn unframe_with(bytes: &[u8], verify: bool) -> Option<(WireCodec, WireCompression, &[u8])> {
5827    let (&h, rest) = bytes.split_first()?;
5828    if h & !H_KNOWN != 0 {
5829        return None; // an unknown format bit is set
5830    }
5831    let codec = if h & H_JSON != 0 { WireCodec::Json } else { WireCodec::Native };
5832    let compression = if h & H_COMPRESSED == 0 {
5833        WireCompression::None
5834    } else {
5835        match (h & H_CODEC) >> 2 {
5836            0 => WireCompression::Deflate,
5837            1 => WireCompression::Lz4,
5838            2 => WireCompression::Zstd,
5839            _ => return None, // a reserved codec id
5840        }
5841    };
5842    let body = if h & H_CHECKED != 0 {
5843        if rest.len() < 8 {
5844            return None;
5845        }
5846        let (sum, body) = rest.split_at(8);
5847        if verify {
5848            let expected = u64::from_le_bytes(sum.try_into().ok()?);
5849            if fnv1a_64(body) != expected {
5850                return None;
5851            }
5852        }
5853        body
5854    } else {
5855        rest
5856    };
5857    Some((codec, compression, body))
5858}
5859
5860/// Decode the frame, validating the integrity checksum if present (the full-decode path).
5861fn unframe(bytes: &[u8]) -> Option<(WireCodec, WireCompression, &[u8])> {
5862    unframe_with(bytes, true)
5863}
5864
5865/// FNV-1a, 64-bit — a small, fast, dependency-free checksum. Not cryptographic
5866/// (it detects corruption, not a forged message); a signing layer is separate. The
5867/// constants are part of the wire, so they must never change.
5868fn fnv1a_64(bytes: &[u8]) -> u64 {
5869    let mut hash = 0xcbf2_9ce4_8422_2325u64;
5870    for &b in bytes {
5871        hash ^= b as u64;
5872        hash = hash.wrapping_mul(0x0000_0100_0000_01b3);
5873    }
5874    hash
5875}
5876
5877/// The process integrity default — `Checked`, unless `LOGOS_WIRE=raw` opts into
5878/// the bare fast path. Read once.
5879pub(crate) fn default_integrity() -> WireIntegrity {
5880    static MODE: std::sync::OnceLock<WireIntegrity> = std::sync::OnceLock::new();
5881    *MODE.get_or_init(|| match std::env::var("LOGOS_WIRE").ok().as_deref() {
5882        Some("raw") => WireIntegrity::Raw,
5883        _ => WireIntegrity::Checked,
5884    })
5885}
5886
5887thread_local! {
5888    static INTEGRITY_OVERRIDE: std::cell::Cell<Option<WireIntegrity>> = const { std::cell::Cell::new(None) };
5889}
5890
5891/// The latency↔safety dial: run `f` with the checksum on (`Checked`) or off (`Raw`),
5892/// overriding the process default for the duration. Scoped — never leaks. `Raw` is
5893/// the fastest path (the FNV checksum is the bulk of small-message encode cost);
5894/// `Checked` detects corruption. Pairs with `with_numerics`/`with_compression_codec`.
5895pub fn with_integrity<T>(integrity: WireIntegrity, f: impl FnOnce() -> T) -> T {
5896    let prev = INTEGRITY_OVERRIDE.with(|c| c.replace(Some(integrity)));
5897    let out = f();
5898    INTEGRITY_OVERRIDE.with(|c| c.set(prev));
5899    out
5900}
5901
5902/// The integrity in force for a plain `message_to_wire`: a scoped [`with_integrity`]
5903/// override if set, else the process default.
5904fn current_integrity() -> WireIntegrity {
5905    INTEGRITY_OVERRIDE.with(std::cell::Cell::get).unwrap_or_else(default_integrity)
5906}
5907
5908/// Varint-encoded bincode: small ints and lengths cost a byte or two, so an array
5909/// of small numbers is genuinely compact (vs. the fixed 8-byte ints of the default
5910/// config). Both peers run this same code, so the encoding is shared by construction.
5911fn wire_options() -> impl bincode::Options {
5912    bincode::DefaultOptions::new()
5913}
5914
5915/// The canonical bytes of a wire value — used only to order map entries so the
5916/// encoding is independent of the source map's hash iteration order.
5917fn canon_bytes(w: &WireValue) -> Vec<u8> {
5918    use bincode::Options;
5919    wire_options().serialize(w).unwrap_or_default()
5920}
5921
5922#[cfg(test)]
5923mod tests {
5924    use super::*;
5925    use crate::interpreter::ClosureValue;
5926    use std::collections::HashMap;
5927
5928    // ─────────────────────────────────────────────────────────────────────────────
5929    // describe_columns — the codec naming its own output (the "which dial won" surface).
5930    // ─────────────────────────────────────────────────────────────────────────────
5931
5932    fn ints_list(v: Vec<i64>) -> RuntimeValue {
5933        RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Ints(v))))
5934    }
5935
5936    #[test]
5937    fn describe_columns_names_the_numeric_dials() {
5938        let ints = ints_list((0i64..64).map(|i| 3 + i * 7).collect());
5939        let enc = |num: WireNumerics| {
5940            with_structure(WireStructure::Off, || {
5941                with_numerics(num, || {
5942                    message_to_wire_with("", &ints, WireCodec::Native, WireIntegrity::Raw).unwrap()
5943                })
5944            })
5945        };
5946        assert_eq!(describe_columns(&enc(WireNumerics::Varint)), vec!["varint"]);
5947        assert_eq!(describe_columns(&enc(WireNumerics::Fixed)), vec!["fixed (memcpy)"]);
5948        assert_eq!(describe_columns(&enc(WireNumerics::GroupVarint)), vec!["group-varint"]);
5949    }
5950
5951    #[test]
5952    fn describe_columns_names_the_affine_structure() {
5953        let ints = ints_list((0i64..64).map(|i| 5 + i * 3).collect());
5954        let bytes = with_structure(WireStructure::Affine, || {
5955            with_numerics(WireNumerics::Varint, || {
5956                message_to_wire_with("", &ints, WireCodec::Native, WireIntegrity::Raw).unwrap()
5957            })
5958        });
5959        assert_eq!(describe_columns(&bytes), vec!["affine (base,stride,n)"]);
5960    }
5961
5962    #[test]
5963    fn describe_columns_names_the_float_dials() {
5964        // Slowly-varying floats: memcpy stays raw; xor-delta shrinks (the dial applies).
5965        let floats = floats_list((0..256).map(|i| 20.0 + i as f64 * 0.01).collect());
5966        let enc = |fl: WireFloats| {
5967            with_structure(WireStructure::Off, || {
5968                with_floats(fl, || {
5969                    message_to_wire_with("", &floats, WireCodec::Native, WireIntegrity::Raw).unwrap()
5970                })
5971            })
5972        };
5973        assert_eq!(describe_columns(&enc(WireFloats::Memcpy)), vec!["memcpy floats"]);
5974        assert_eq!(describe_columns(&enc(WireFloats::XorDelta)), vec!["xor-delta floats"]);
5975    }
5976
5977    #[test]
5978    fn describe_columns_names_strings_and_bools() {
5979        let strings = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::from_values(
5980            (0..24).map(|i| RuntimeValue::Text(Rc::new(format!("host-{i}-{}", i * 31 % 7)))).collect(),
5981        ))));
5982        let bools = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::from_values(
5983            (0..40).map(|i| RuntimeValue::Bool(i * 5 % 3 == 0)).collect(),
5984        ))));
5985        let enc = |rv: &RuntimeValue| {
5986            with_structure(WireStructure::Off, || {
5987                message_to_wire_with("", rv, WireCodec::Native, WireIntegrity::Raw).unwrap()
5988            })
5989        };
5990        assert_eq!(describe_columns(&enc(&strings)), vec!["flat strings"]);
5991        assert_eq!(describe_columns(&enc(&bools)), vec!["bit-packed bools"]);
5992    }
5993
5994    #[test]
5995    fn describe_columns_names_each_record_field() {
5996        let mut rows = Vec::new();
5997        for i in 0..32i64 {
5998            let mut f = HashMap::new();
5999            f.insert("id".to_string(), RuntimeValue::Int(i * 3 + 1));
6000            f.insert("name".to_string(), RuntimeValue::Text(Rc::new(format!("node-{i}"))));
6001            f.insert("active".to_string(), RuntimeValue::Bool(i % 2 == 0));
6002            rows.push(RuntimeValue::Struct(Box::new(StructValue { type_name: "Record".to_string(), fields: f })));
6003        }
6004        let rv = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::from_values(rows))));
6005        let bytes = with_structure(WireStructure::Off, || {
6006            with_numerics(WireNumerics::Varint, || {
6007                message_to_wire_with("", &rv, WireCodec::Native, WireIntegrity::Raw).unwrap()
6008            })
6009        });
6010        // Field order is schema-defined; compare as a set so the test is order-robust.
6011        let cols = describe_columns(&bytes);
6012        let got: std::collections::BTreeSet<&str> = cols.iter().map(String::as_str).collect();
6013        let want: std::collections::BTreeSet<&str> =
6014            ["active: bit-packed bools", "id: varint", "name: flat strings"].into_iter().collect();
6015        assert_eq!(got, want);
6016    }
6017
6018    #[test]
6019    fn column_tag_name_covers_the_structural_vocabulary() {
6020        // Every dial the codec can select must carry a plain-words name — none may ship as the
6021        // generic "value" fallback, or the benchmark card would hide which encoding actually won.
6022        for (tag, want) in [
6023            (T_INTS, "varint"),
6024            (T_INTS_FIXED, "fixed (memcpy)"),
6025            (T_INTS_GV, "group-varint"),
6026            (T_INTS_AFFINE, "affine (base,stride,n)"),
6027            (T_INTS_DELTA, "delta"),
6028            (T_INTS_DOD, "delta-of-delta"),
6029            (T_INTS_FOR, "FOR bit-pack"),
6030            (T_INTS_RLE, "run-length"),
6031            (T_INTS_DICT, "dictionary"),
6032            (T_FLOATS, "memcpy floats"),
6033            (T_FLOATS_XOR, "xor-delta floats"),
6034            (T_BOOLS, "bit-packed bools"),
6035            (T_STRINGS, "flat strings"),
6036        ] {
6037            assert_eq!(column_tag_name(tag), want, "tag {tag}");
6038            assert_ne!(column_tag_name(tag), "value", "tag {tag} must not be the generic fallback");
6039        }
6040    }
6041
6042    // ─────────────────────────────────────────────────────────────────────────────
6043    // Build-in-place columnar records — Cap'n Proto's home turf (zero-encode + zero-decode).
6044    // ─────────────────────────────────────────────────────────────────────────────
6045
6046    #[test]
6047    fn build_in_place_record_reads_back_zero_copy() {
6048        // Build a 1000-row record straight into the wire layout from borrowed slices (no
6049        // RuntimeValue), then read any column in O(1) and ZERO-COPY — `Some(slice)`, never the
6050        // copy fallback. The dual zero-encode/zero-decode story end to end.
6051        let ids: Vec<i64> = (0..1000).collect();
6052        let xs: Vec<f64> = (0..1000).map(|i| i as f64 * 0.5).collect();
6053        let bytes = build_columnar_record(
6054            "node",
6055            "Sensor",
6056            &[("id", WireColumn::Ints(&ids)), ("x", WireColumn::Floats(&xs))],
6057        );
6058        let view = view_message(&bytes).expect("the built record opens as a view");
6059        let id_slice = view.struct_field("id").expect("id field").as_i64_slice().expect("zero-copy i64");
6060        let x_slice = view.struct_field("x").expect("x field").as_f64_slice().expect("zero-copy f64");
6061        assert_eq!(id_slice, &ids[..], "id column round-trips bit-exact, zero-copy");
6062        assert_eq!(x_slice, &xs[..], "x column round-trips bit-exact, zero-copy");
6063    }
6064
6065    #[test]
6066    fn build_in_place_is_byte_identical_to_the_runtimevalue_path() {
6067        // The builder emits EXACTLY the canonical struct-view bytes the audited `RuntimeValue`
6068        // encode path produces — so it inherits every correctness property of that path for free,
6069        // while skipping the value materialization + second serialize pass.
6070        let a: Vec<i64> = vec![10, 20, 30, 40];
6071        let b: Vec<f64> = vec![1.5, 2.5, 3.5];
6072        let built = build_columnar_record(
6073            "p",
6074            "Rec",
6075            &[("alpha", WireColumn::Ints(&a)), ("beta", WireColumn::Floats(&b))],
6076        );
6077
6078        let mut fields = HashMap::new();
6079        fields.insert("alpha".to_string(), RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Ints(a.clone())))));
6080        fields.insert("beta".to_string(), RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Floats(b.clone())))));
6081        let sv = RuntimeValue::Struct(Box::new(StructValue { type_name: "Rec".to_string(), fields }));
6082        let canonical = with_struct_view(true, || {
6083            message_to_wire_with("p", &sv, WireCodec::Native, current_integrity()).unwrap()
6084        });
6085        assert_eq!(built, canonical, "build-in-place must equal the canonical struct-view encode byte-for-byte");
6086    }
6087
6088    #[test]
6089    fn build_in_place_record_full_decode_interop() {
6090        // A non-view receiver (a full `message_from_wire` decode) reconstructs the record too —
6091        // the build-in-place form is ordinary wire bytes, not a view-only dialect.
6092        let a: Vec<i64> = vec![7, 8, 9];
6093        let bytes = build_columnar_record("p", "R", &[("c", WireColumn::Ints(&a))]);
6094        let (from, val) = message_from_wire(&bytes).expect("full decode");
6095        assert_eq!(from, "p");
6096        match val {
6097            RuntimeValue::Struct(s) => {
6098                assert_eq!(s.type_name, "R");
6099                match s.fields.get("c").unwrap() {
6100                    RuntimeValue::List(l) => match &*l.borrow() {
6101                        ListRepr::Ints(v) => assert_eq!(v, &a),
6102                        other => panic!("expected Ints, got {other:?}"),
6103                    },
6104                    other => panic!("expected List, got {other:?}"),
6105                }
6106            }
6107            other => panic!("expected Struct, got {other:?}"),
6108        }
6109    }
6110
6111    #[test]
6112    #[ignore = "build-in-place encode-parity measurement — run with --ignored --nocapture"]
6113    fn build_in_place_encode_is_at_capnp_parity() {
6114        // Honest measurement: Logos's column encode was ALREADY memcpy-fast (the aligned column is
6115        // one `extend_from_slice`), so build-in-place does NOT dramatically beat the existing path —
6116        // it MATCHES it (capnp parity on encode) while needing no intermediate `RuntimeValue`. The
6117        // comparison is fair: the value is pre-built once (the realistic "you already hold it" case),
6118        // so neither side pays a clone. The proven capnp *win* is the read side, not encode.
6119        use std::time::Instant;
6120        const ITERS: usize = 4000;
6121        let cols: Vec<Vec<i64>> = (0..8).map(|c| (0..256).map(|i| (c * 256 + i) as i64).collect()).collect();
6122        let names: Vec<String> = (0..8).map(|c| format!("col{c}")).collect();
6123
6124        // Pre-build the RuntimeValue ONCE — the existing path then only serializes (no clone).
6125        let mut fields_map = HashMap::new();
6126        for (n, c) in names.iter().zip(&cols) {
6127            fields_map.insert(n.clone(), RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Ints(c.clone())))));
6128        }
6129        let sv = RuntimeValue::Struct(Box::new(StructValue { type_name: "Batch".to_string(), fields: fields_map }));
6130
6131        let t = Instant::now();
6132        for _ in 0..ITERS {
6133            let fields: Vec<(&str, WireColumn)> =
6134                names.iter().zip(&cols).map(|(n, c)| (n.as_str(), WireColumn::Ints(c))).collect();
6135            std::hint::black_box(build_columnar_record("p", "Batch", &fields));
6136        }
6137        let in_place = t.elapsed();
6138
6139        let t = Instant::now();
6140        for _ in 0..ITERS {
6141            let bytes = with_struct_view(true, || {
6142                message_to_wire_with("p", &sv, WireCodec::Native, current_integrity()).unwrap()
6143            });
6144            std::hint::black_box(bytes);
6145        }
6146        let serialize_existing = t.elapsed();
6147
6148        eprintln!(
6149            "encode 8×256 i64 record: build-in-place={in_place:?} serialize-existing={serialize_existing:?} ratio={:.2}x",
6150            serialize_existing.as_secs_f64() / in_place.as_secs_f64().max(f64::MIN_POSITIVE)
6151        );
6152        // Parity, not a fabricated win: build-in-place must be within a small band of the existing
6153        // memcpy-fast path (never meaningfully slower) — it ships the SAME bytes with no RuntimeValue.
6154        assert!(
6155            in_place.as_secs_f64() <= serialize_existing.as_secs_f64() * 1.5,
6156            "build-in-place must be at parity with the existing column encode: in_place={in_place:?} existing={serialize_existing:?}"
6157        );
6158    }
6159
6160    #[test]
6161    fn columnar_record_is_position_independent_mmap_and_ipc_ready() {
6162        // Cap'n Proto's FLAGSHIP: messages are position-independent (offset-based, never pointer-
6163        // based), so you can mmap a file or share a buffer across processes and read fields IN PLACE
6164        // — the OS pages in only what you touch, two processes share one segment with no kernel pipe.
6165        // `T_STRUCT_VIEW` uses RELATIVE offsets, so the SAME holds for Logos: the bytes read zero-copy
6166        // from ANY backing store at ANY base, with no relocation/fixup. This locks that property.
6167        let ids: Vec<i64> = (0..4096).collect();
6168        let xs: Vec<f64> = (0..4096).map(|i| i as f64 * 1.25).collect();
6169        let msg = build_columnar_record(
6170            "p",
6171            "Batch",
6172            &[("id", WireColumn::Ints(&ids)), ("x", WireColumn::Floats(&xs))],
6173        );
6174
6175        // Relocate the message to a different base address (an mmap maps at a page boundary; a shared
6176        // segment lands at its own offset). An 8-aligned shift keeps the columns zero-copy at the new
6177        // base; the read stays CORRECT at any base (position independence) — verified both ways.
6178        for &shift in &[0usize, 8, 16, 4096, 65536] {
6179            let mut arena = vec![0u8; shift];
6180            arena.extend_from_slice(&msg);
6181            let relocated = &arena[shift..]; // a fresh borrow at base + `shift`
6182            let view = view_message(relocated).expect("position-independent open at any base");
6183            let id_slice = view.struct_field("id").unwrap().as_i64_slice().expect("zero-copy at aligned base");
6184            let x_slice = view.struct_field("x").unwrap().as_f64_slice().expect("zero-copy at aligned base");
6185            assert_eq!(id_slice, &ids[..], "id column read in place at base+{shift}");
6186            assert_eq!(x_slice, &xs[..], "x column read in place at base+{shift}");
6187        }
6188
6189        // A NON-aligned base: the slice cast declines (alignment guard) — but the message is still
6190        // read correctly via the copy path, so correctness is base-independent, only the zero-copy
6191        // fast path needs alignment (which mmap/page boundaries always provide).
6192        let mut arena = vec![0u8; 3];
6193        arena.extend_from_slice(&msg);
6194        let view = view_message(&arena[3..]).expect("opens at an unaligned base too");
6195        let (_, val) = message_from_wire(&arena[3..]).expect("full decode at unaligned base");
6196        match val {
6197            RuntimeValue::Struct(s) => match s.fields.get("id").unwrap() {
6198                RuntimeValue::List(l) => match &*l.borrow() {
6199                    ListRepr::Ints(v) => assert_eq!(v, &ids, "correct at an unaligned base via the copy path"),
6200                    o => panic!("expected Ints, got {o:?}"),
6201                },
6202                o => panic!("expected List, got {o:?}"),
6203            },
6204            o => panic!("expected Struct, got {o:?}"),
6205        }
6206        // The field view still resolves at the unaligned base (offsets are relative); only the
6207        // zero-copy slice cast is alignment-gated.
6208        assert!(view.struct_field("id").is_some(), "field still locatable at an unaligned base");
6209    }
6210
6211    #[test]
6212    fn columnar_record_mmaps_a_column_zero_copy_from_disk() {
6213        // The visceral crush of Cap'n Proto's headline: write the columnar record to a FILE, mmap
6214        // it, and read one column ZERO-COPY straight from the mapped pages — no parse, no decode, no
6215        // per-element copy. mmap pages start at a page boundary (4 KiB-aligned ⇒ 8-aligned), so the
6216        // aligned columns cast soundly. The OS pages in only what we touch. Smaller file than capnp
6217        // for the same data (name elision), and read in place all the same.
6218        use std::io::Write;
6219        let ids: Vec<i64> = (0..50_000).collect();
6220        let xs: Vec<f64> = (0..50_000).map(|i| (i as f64).sqrt()).collect();
6221        let msg = build_columnar_record(
6222            "p",
6223            "Telemetry",
6224            &[("id", WireColumn::Ints(&ids)), ("x", WireColumn::Floats(&xs))],
6225        );
6226
6227        let mut tmp = tempfile::NamedTempFile::new().expect("temp file");
6228        tmp.write_all(&msg).expect("write the wire message to disk");
6229        tmp.flush().expect("flush");
6230        let file = tmp.reopen().expect("reopen for mapping");
6231        // SAFETY: the file is not mutated while mapped (single-test, exclusive temp file).
6232        let mmap = unsafe { memmap2::Mmap::map(&file).expect("mmap the message file") };
6233
6234        let view = view_message(&mmap[..]).expect("the mmap'd message opens in place");
6235        let id_slice = view.struct_field("id").unwrap().as_i64_slice().expect("zero-copy i64 from mmap");
6236        let x_slice = view.struct_field("x").unwrap().as_f64_slice().expect("zero-copy f64 from mmap");
6237        // The slices point INTO the mmap — no allocation, no decode. Verify against the source.
6238        assert_eq!(id_slice, &ids[..], "id column read zero-copy directly from the mmap");
6239        assert_eq!(x_slice, &xs[..], "x column read zero-copy directly from the mmap");
6240        // The slice genuinely aliases the mapped pages (zero-copy), not a decoded heap copy.
6241        let map_base = mmap.as_ptr() as usize;
6242        let slice_base = id_slice.as_ptr() as usize;
6243        assert!(
6244            slice_base >= map_base && slice_base < map_base + mmap.len(),
6245            "the i64 slice must alias the mapped pages, not a copy"
6246        );
6247    }
6248
6249    #[test]
6250    fn wireview_decode_and_schema_read_a_record_list_in_place() {
6251        // ZC1: a record-list view exposes its schema (type, fields, row count) and decodes any ONE
6252        // (row, field) cell in place — the primitives a lazy zero-copy receive backing reads through,
6253        // never decoding the rest of the list.
6254        let mk = |id: i64, x: f64| {
6255            let mut f = HashMap::new();
6256            f.insert("id".to_string(), RuntimeValue::Int(id));
6257            f.insert("x".to_string(), RuntimeValue::Float(x));
6258            RuntimeValue::Struct(Box::new(StructValue { type_name: "Rec".to_string(), fields: f }))
6259        };
6260        let rows = vec![mk(10, 1.5), mk(20, 2.5), mk(30, 3.5)];
6261        let list = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::from_values(rows))));
6262        let bytes = with_struct_view(true, || {
6263            message_to_wire_with("p", &list, WireCodec::Native, WireIntegrity::Raw).unwrap()
6264        });
6265        let view = view_message(&bytes).expect("record list opens as a view");
6266
6267        let (ty, fields, n) = view.structs_schema().expect("record-list schema in place");
6268        assert_eq!(ty, "Rec");
6269        assert_eq!(fields, vec!["id".to_string(), "x".to_string()], "sorted field schema");
6270        assert_eq!(n, 3, "row count from the header, no rows decoded");
6271
6272        assert_eq!(view.structs_row_field(1, "id").unwrap().decode(), Some(RuntimeValue::Int(20)));
6273        assert_eq!(view.structs_row_field(2, "x").unwrap().decode(), Some(RuntimeValue::Float(3.5)));
6274        assert_eq!(view.structs_row_field(0, "id").unwrap().decode(), Some(RuntimeValue::Int(10)));
6275        assert!(view.structs_row_field(3, "id").is_none(), "out-of-range row is None");
6276        assert!(view.structs_row_field(0, "nope").is_none(), "missing field is None");
6277    }
6278
6279    #[test]
6280    fn lazy_wirestructs_reads_records_without_eager_decode() {
6281        // ZC2: a received record-list held as RAW BYTES (ListRepr::WireStructs) reads any (row,
6282        // field) in place — `len` is O(1) with zero rows decoded, `get_field` touches one cell, and
6283        // full materialization matches the eager decode value-for-value.
6284        use crate::interpreter::{ListRepr, StructValue};
6285        let mk = |id: i64, x: f64, tag: &str| {
6286            let mut f = HashMap::new();
6287            f.insert("id".to_string(), RuntimeValue::Int(id));
6288            f.insert("x".to_string(), RuntimeValue::Float(x));
6289            f.insert("tag".to_string(), RuntimeValue::Text(Rc::new(tag.to_string())));
6290            RuntimeValue::Struct(Box::new(StructValue { type_name: "Rec".to_string(), fields: f }))
6291        };
6292        let rows: Vec<RuntimeValue> = (0..1000).map(|i| mk(i, i as f64 * 0.5, &format!("t{i}"))).collect();
6293        let eager = ListRepr::from_values(rows);
6294        let list = RuntimeValue::List(Rc::new(RefCell::new(eager.clone())));
6295        let bytes = with_struct_view(true, || {
6296            message_to_wire_with("p", &list, WireCodec::Native, WireIntegrity::Raw).unwrap()
6297        });
6298
6299        let lazy = ListRepr::from_record_list_view(Rc::new(bytes)).expect("wraps as a lazy view");
6300        assert_eq!(lazy.len(), 1000, "len is O(1) from the header — no rows decoded");
6301
6302        // Single-cell reads, located + decoded in place (never touching the other rows).
6303        assert_eq!(lazy.get_field(0, "id"), Some(RuntimeValue::Int(0)));
6304        assert_eq!(lazy.get_field(999, "id"), Some(RuntimeValue::Int(999)));
6305        assert_eq!(lazy.get_field(500, "x"), Some(RuntimeValue::Float(250.0)));
6306        match lazy.get_field(7, "tag") {
6307            Some(RuntimeValue::Text(s)) => assert_eq!(&*s, "t7"),
6308            o => panic!("expected tag text, got {o:?}"),
6309        }
6310        assert_eq!(lazy.get_field(0, "missing"), None, "missing field is None");
6311
6312        // Whole-row reconstruction on demand.
6313        match lazy.get(3) {
6314            Some(RuntimeValue::Struct(s)) => {
6315                assert_eq!(s.type_name, "Rec");
6316                assert_eq!(s.fields.get("id"), Some(&RuntimeValue::Int(3)));
6317                assert_eq!(s.fields.get("x"), Some(&RuntimeValue::Float(1.5)));
6318            }
6319            o => panic!("expected struct row, got {o:?}"),
6320        }
6321
6322        // Full materialization equals the eager decode, value-for-value.
6323        // Structural struct equality (the kernel's `values_equal` is reference-semantic for structs,
6324        // so compare type + every field by value).
6325        fn struct_eq(a: &RuntimeValue, b: &RuntimeValue) -> bool {
6326            match (a, b) {
6327                (RuntimeValue::Struct(x), RuntimeValue::Struct(y)) => {
6328                    x.type_name == y.type_name
6329                        && x.fields.len() == y.fields.len()
6330                        && x.fields.iter().all(|(k, v)| {
6331                            y.fields.get(k).is_some_and(|w| crate::semantics::compare::values_equal(v, w))
6332                        })
6333                }
6334                _ => crate::semantics::compare::values_equal(a, b),
6335            }
6336        }
6337        let lazy_vals = lazy.to_values();
6338        let eager_vals = eager.to_values();
6339        assert_eq!(lazy_vals.len(), eager_vals.len());
6340        for (idx, (a, b)) in lazy_vals.iter().zip(&eager_vals).enumerate() {
6341            assert!(struct_eq(a, b), "row {idx} differs:\n  lazy={a:?}\n eager={b:?}");
6342        }
6343    }
6344
6345    #[test]
6346    fn message_from_wire_view_is_lazy_for_record_lists_eager_otherwise() {
6347        // ZC3: the lazy receive entry point holds a record list as raw bytes (WireStructs, NO rows
6348        // decoded) while any other shape full-decodes exactly as before. Sender is preserved either
6349        // way; the receiver opts in via the `view` knob (ZC4).
6350        use crate::interpreter::{ListRepr, StructValue};
6351        let mk = |id: i64| {
6352            let mut f = HashMap::new();
6353            f.insert("id".to_string(), RuntimeValue::Int(id));
6354            RuntimeValue::Struct(Box::new(StructValue { type_name: "R".to_string(), fields: f }))
6355        };
6356        let list = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::from_values((0..100).map(mk).collect()))));
6357        let bytes =
6358            with_struct_view(true, || message_to_wire_with("alice", &list, WireCodec::Native, WireIntegrity::Raw).unwrap());
6359
6360        let (from, val) = message_from_wire_view(&bytes).expect("lazy view decode");
6361        assert_eq!(from, "alice", "sender preserved on the lazy path");
6362        match &val {
6363            RuntimeValue::List(rc) => {
6364                assert!(
6365                    matches!(&*rc.borrow(), ListRepr::WireStructs { .. }),
6366                    "a record list must be held LAZILY (no rows decoded), got {:?}",
6367                    rc.borrow()
6368                );
6369                assert_eq!(rc.borrow().len(), 100, "O(1) len, no decode");
6370                assert_eq!(rc.borrow().get_field(42, "id"), Some(RuntimeValue::Int(42)), "in-place field read");
6371            }
6372            o => panic!("expected a lazy list, got {o:?}"),
6373        }
6374
6375        // A scalar message has no record-list view → full decode, identical to `message_from_wire`.
6376        let sbytes = message_to_wire_with("bob", &RuntimeValue::Int(7), WireCodec::Native, WireIntegrity::Raw).unwrap();
6377        let (sfrom, sval) = message_from_wire_view(&sbytes).expect("scalar decode");
6378        assert_eq!(sfrom, "bob");
6379        assert_eq!(sval, RuntimeValue::Int(7), "non-record shape falls back to full decode");
6380    }
6381
6382    #[test]
6383    fn production_receive_path_defers_then_reads_record_list_lazily() {
6384        // ZC5: mirror EXACTLY the interpreter's receive decisions for a record list:
6385        //   drain      → `peek_deferrable_sender` says "DEFER" (buffer raw, decode NOTHING)
6386        //   Await view  → `from_record_list_view` (LAZY — no rows decoded until touched)
6387        //   Await       → `message_from_wire` (eager) — same values
6388        // and prove a scalar is NOT deferrable (decoded in order at drain). This is the
6389        // "no decode in production" path, verified at the exact functions it calls.
6390        use crate::interpreter::{ListRepr, StructValue};
6391        let mk = |id: i64, name: &str| {
6392            let mut f = HashMap::new();
6393            f.insert("id".to_string(), RuntimeValue::Int(id));
6394            f.insert("name".to_string(), RuntimeValue::Text(Rc::new(name.to_string())));
6395            RuntimeValue::Struct(Box::new(StructValue { type_name: "User".to_string(), fields: f }))
6396        };
6397        let rows: Vec<RuntimeValue> = (0..500).map(|i| mk(i, &format!("u{i}"))).collect();
6398        let list = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::from_values(rows))));
6399        let frame =
6400            with_struct_view(true, || message_to_wire_with("alice", &list, WireCodec::Native, WireIntegrity::Raw).unwrap());
6401
6402        // 1) Drain: a record-list view is a DEFERRABLE message — peek yields the sender, no decode.
6403        assert_eq!(peek_deferrable_sender(&frame).as_deref(), Some("alice"), "record list defers at drain");
6404
6405        // 2) `Await view`: wrap the buffered frame LAZILY — a WireStructs, zero rows decoded.
6406        let lazy = ListRepr::from_record_list_view(Rc::new(frame.clone())).expect("lazy wrap");
6407        assert!(matches!(lazy, ListRepr::WireStructs { .. }), "Await view holds the list lazily");
6408        assert_eq!(lazy.len(), 500, "O(1) len, nothing decoded");
6409        assert_eq!(lazy.get_field(123, "id"), Some(RuntimeValue::Int(123)), "in-place cell read");
6410
6411        // 3) `Await` (no view): the SAME buffered frame decodes eagerly to the same values.
6412        let (efrom, eager_val) = message_from_wire(&frame).expect("eager decode");
6413        assert_eq!(efrom, "alice");
6414        let eager_rows = match &eager_val {
6415            RuntimeValue::List(rc) => rc.borrow().to_values(),
6416            o => panic!("expected list, got {o:?}"),
6417        };
6418        let lazy_rows = lazy.to_values();
6419        assert_eq!(lazy_rows.len(), eager_rows.len());
6420        for (idx, (a, b)) in lazy_rows.iter().zip(&eager_rows).enumerate() {
6421            let eq = match (a, b) {
6422                (RuntimeValue::Struct(x), RuntimeValue::Struct(y)) => {
6423                    x.type_name == y.type_name
6424                        && x.fields.iter().all(|(k, v)| {
6425                            y.fields.get(k).is_some_and(|w| crate::semantics::compare::values_equal(v, w))
6426                        })
6427                }
6428                _ => false,
6429            };
6430            assert!(eq, "lazy and eager receive must agree at row {idx}");
6431        }
6432
6433        // 4) A scalar message is NOT a deferrable record list → decoded eagerly in arrival order.
6434        let sframe = message_to_wire_with("bob", &RuntimeValue::Int(7), WireCodec::Native, WireIntegrity::Raw).unwrap();
6435        assert_eq!(peek_deferrable_sender(&sframe), None, "a scalar is not deferred");
6436    }
6437
6438    #[test]
6439    fn lazy_wirecolumn_reads_received_numeric_columns_zero_copy() {
6440        // EXTEND: a received aligned NUMERIC column (`Seq of Int`/`Seq of Float` sent fast/aligned)
6441        // is deferred at drain and read ZERO-COPY out of the borrowed `&[i64]`/`&[f64]` — capnp's
6442        // `List<i64>` read-in-place. `len` O(1), `get(i)` reads one element, no eager decode.
6443        use crate::interpreter::ListRepr;
6444
6445        let ints: Vec<i64> = (0..2000).collect();
6446        let il = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Ints(ints.clone()))));
6447        let ibytes =
6448            with_struct_view(true, || message_to_wire_with("alice", &il, WireCodec::Native, WireIntegrity::Raw).unwrap());
6449        assert_eq!(peek_deferrable_sender(&ibytes).as_deref(), Some("alice"), "aligned int column defers");
6450        let lazy = ListRepr::from_received_view(Rc::new(ibytes)).expect("lazy int column");
6451        assert!(matches!(lazy, ListRepr::WireColumn { floats: false, .. }), "held as a lazy int column");
6452        assert_eq!(lazy.len(), 2000, "O(1) len, no decode");
6453        assert_eq!(lazy.get(0), Some(RuntimeValue::Int(0)), "zero-copy element read");
6454        assert_eq!(lazy.get(1999), Some(RuntimeValue::Int(1999)));
6455        assert_eq!(lazy.get(2000), None, "out of range");
6456        let vals = lazy.to_values();
6457        assert_eq!(vals.len(), 2000);
6458        assert_eq!(vals[500], RuntimeValue::Int(500));
6459
6460        let floats: Vec<f64> = (0..1000).map(|i| i as f64 * 0.25).collect();
6461        let fl = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Floats(floats.clone()))));
6462        let fbytes =
6463            with_struct_view(true, || message_to_wire_with("bob", &fl, WireCodec::Native, WireIntegrity::Raw).unwrap());
6464        assert_eq!(peek_deferrable_sender(&fbytes).as_deref(), Some("bob"), "aligned float column defers");
6465        let lazyf = ListRepr::from_received_view(Rc::new(fbytes)).expect("lazy float column");
6466        assert!(matches!(lazyf, ListRepr::WireColumn { floats: true, .. }), "held as a lazy float column");
6467        assert_eq!(lazyf.len(), 1000);
6468        assert_eq!(lazyf.get(4), Some(RuntimeValue::Float(1.0)), "zero-copy float read (0.25*4)");
6469        assert_eq!(lazyf.to_values()[8], RuntimeValue::Float(2.0));
6470    }
6471
6472    #[test]
6473    fn batch_stream_message_round_trips() {
6474        // The `Stream`/`Await stream` substrate: many values batched into ONE framed blob, deframed
6475        // back in order, with the sender peekable and a normal message never mistaken for a stream.
6476        let values = vec![
6477            RuntimeValue::Int(1),
6478            RuntimeValue::Int(-42),
6479            RuntimeValue::Text(Rc::new("hi".to_string())),
6480            RuntimeValue::Bool(true),
6481        ];
6482        let blob = frame_stream_message("alice", &values).expect("frames a stream");
6483        assert_eq!(peek_stream_sender(&blob).as_deref(), Some("alice"), "sender peekable at drain");
6484
6485        let got = deframe_stream_message(&blob).expect("deframes the stream");
6486        assert_eq!(got.len(), 4);
6487        assert_eq!(got[0], RuntimeValue::Int(1));
6488        assert_eq!(got[1], RuntimeValue::Int(-42));
6489        match &got[2] {
6490            RuntimeValue::Text(t) => assert_eq!(&**t, "hi"),
6491            o => panic!("expected text, got {o:?}"),
6492        }
6493        assert_eq!(got[3], RuntimeValue::Bool(true));
6494
6495        // A normal message is NOT a stream (the 0xFD marker disambiguates).
6496        let normal = message_to_wire("p", &RuntimeValue::Int(5)).unwrap();
6497        assert_eq!(peek_stream_sender(&normal), None, "a normal message is not a stream");
6498        assert_eq!(deframe_stream_message(&normal), None);
6499
6500        // An empty stream is valid (zero values).
6501        let empty = frame_stream_message("bob", &[]).unwrap();
6502        assert_eq!(peek_stream_sender(&empty).as_deref(), Some("bob"));
6503        assert_eq!(deframe_stream_message(&empty), Some(vec![]));
6504    }
6505
6506    #[test]
6507    fn build_in_place_edge_cases() {
6508        // Edge cases: an EMPTY column (still 8-aligned, reads back as `&[]`), a single element, and
6509        // a missing field (None, never a panic). The padding aligns even the zero-length blob.
6510        let empty: Vec<i64> = vec![];
6511        let one: Vec<i64> = vec![42];
6512        let bytes = build_columnar_record(
6513            "",
6514            "E",
6515            &[("z", WireColumn::Ints(&empty)), ("o", WireColumn::Ints(&one))],
6516        );
6517        let view = view_message(&bytes).unwrap();
6518        assert_eq!(view.struct_field("z").unwrap().as_i64_slice().expect("empty is still aligned"), &[] as &[i64]);
6519        assert_eq!(view.struct_field("o").unwrap().as_i64_slice().expect("singleton zero-copy"), &[42]);
6520        assert!(view.struct_field("missing").is_none(), "a missing field is None, not a panic");
6521    }
6522
6523    /// A value round-trips iff materialize∘rebuild∘materialize is the identity on
6524    /// the payload. We compare through `RtPayload` (which has structural
6525    /// equality), because `RuntimeValue`'s `PartialEq` returns false for
6526    /// collections/structs (reference semantics).
6527    fn assert_roundtrips(v: &RuntimeValue) -> RtPayload {
6528        let p = materialize(v).expect("materialize");
6529        let back = rebuild(p.clone());
6530        let p2 = materialize(&back).expect("re-materialize");
6531        assert_eq!(p, p2, "marshalling round-trip changed the value");
6532        p
6533    }
6534
6535    /// Encode `v` as an `Ints` list, decode it back, and return the recovered
6536    /// integers — the round-trip oracle for the affine math hack.
6537    fn affine_roundtrip(v: &[i64], s: WireStructure) -> (Vec<u8>, Vec<i64>) {
6538        let value = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Ints(v.to_vec()))));
6539        let bytes =
6540            with_structure(s, || message_to_wire_with("", &value, WireCodec::Native, WireIntegrity::Raw).unwrap());
6541        let (_, back) = message_from_wire(&bytes).expect("decode");
6542        let got = match back {
6543            RuntimeValue::List(l) => match &*l.borrow() {
6544                ListRepr::Ints(g) => g.clone(),
6545                _ => panic!("expected an Ints list back"),
6546            },
6547            _ => panic!("expected a List back"),
6548        };
6549        (bytes, got)
6550    }
6551
6552    #[test]
6553    fn affine_int_column_elides_to_a_formula_and_round_trips() {
6554        let v: Vec<i64> = (0..1000).collect();
6555        let (bytes, got) = affine_roundtrip(&v, WireStructure::Affine);
6556        // The whole 1000-element column becomes (base, stride, n) — a handful of bytes.
6557        assert!(bytes.len() < 40, "a 1000-element affine column should elide to O(1) bytes; got {}", bytes.len());
6558        assert_eq!(got, v, "affine round-trip must be exact");
6559    }
6560
6561    #[test]
6562    fn non_affine_column_is_not_elided_but_still_round_trips() {
6563        let mut v: Vec<i64> = (0..1000).collect();
6564        v[500] = 999_999; // break the progression — must NOT be mis-detected as affine
6565        let (bytes, got) = affine_roundtrip(&v, WireStructure::Affine);
6566        assert!(bytes.len() > 500, "a non-affine column must fall back to a real encoding; got {}", bytes.len());
6567        assert_eq!(got, v, "fallback round-trip must be exact");
6568    }
6569
6570    #[test]
6571    fn affine_is_bijective_across_i64_overflow() {
6572        // A progression that wraps past i64::MAX — the wrapping match must reproduce it.
6573        let base = i64::MAX - 3;
6574        let stride = 5i64;
6575        let v: Vec<i64> = (0..100).map(|i| base.wrapping_add((i as i64).wrapping_mul(stride))).collect();
6576        let (_, got) = affine_roundtrip(&v, WireStructure::Affine);
6577        assert_eq!(got, v, "wrapping-affine round-trip must be exact");
6578    }
6579
6580    // ---- G5: the per-column compression menu (WireStructure::Auto) -----------------
6581
6582    #[test]
6583    fn wire_auto_delta_wins_on_monotone() {
6584        // A monotone column with small steps → delta makes the deltas one byte each.
6585        let v: Vec<i64> = (0..200i64).scan(1000i64, |s, i| { *s += 1 + (i % 3); Some(*s) }).collect();
6586        let (auto, got) = affine_roundtrip(&v, WireStructure::Auto);
6587        let (varint, _) = affine_roundtrip(&v, WireStructure::Off);
6588        assert_eq!(got, v, "delta round-trips bit-exact");
6589        assert!(auto.len() < varint.len(), "Auto ({}) must beat varint ({}) on a monotone column", auto.len(), varint.len());
6590    }
6591
6592    #[test]
6593    fn wire_auto_dod_wins_on_timestamps() {
6594        // Near-linear timestamps (large base + i·step + tiny jitter) → delta-of-delta ≈ 0.
6595        let v: Vec<i64> = (0..300i64).map(|i| 1_700_000_000 + i * 1000 + (i % 5)).collect();
6596        let (auto, got) = affine_roundtrip(&v, WireStructure::Auto);
6597        let (varint, _) = affine_roundtrip(&v, WireStructure::Off);
6598        assert_eq!(got, v, "delta-of-delta round-trips bit-exact");
6599        assert!(auto.len() < varint.len(), "Auto ({}) must beat varint ({}) on timestamps", auto.len(), varint.len());
6600    }
6601
6602    #[test]
6603    fn wire_auto_for_wins_on_clustered() {
6604        // A tight cluster around a large base → frame-of-reference bit-packs the residuals.
6605        let mut rng = SplitMix64 { state: 0x0000_F00D };
6606        let v: Vec<i64> = (0..400).map(|_| 1_000_000 + (rng.next() % 16) as i64).collect();
6607        let (auto, got) = affine_roundtrip(&v, WireStructure::Auto);
6608        let (varint, _) = affine_roundtrip(&v, WireStructure::Off);
6609        assert_eq!(got, v, "frame-of-reference round-trips bit-exact");
6610        assert!(auto.len() < varint.len(), "Auto ({}) must beat varint ({}) on a clustered column", auto.len(), varint.len());
6611    }
6612
6613    #[test]
6614    fn wire_auto_polynomial_ships_the_generator_not_the_data() {
6615        // A degree-2 polynomial column ships a tiny GENERATOR (degree + a few seeds + n) —
6616        // "ship the computation, not the data" — and reconstructs bit-exact. The frontier
6617        // nobody else has: protobuf/capnp/arrow all ship the n raw values.
6618        let v: Vec<i64> = (0..10_000i64).map(|i| 3 * i * i - 5 * i + 7).collect();
6619        let (auto, got) = affine_roundtrip(&v, WireStructure::Auto);
6620        assert_eq!(got, v, "the polynomial column reconstructs bit-exact");
6621        let (varint, _) = affine_roundtrip(&v, WireStructure::Off);
6622        eprintln!(
6623            "polynomial generator: {} values → ours {} B vs raw varint {} B ({}× smaller)",
6624            v.len(),
6625            auto.len(),
6626            varint.len(),
6627            varint.len() / auto.len().max(1)
6628        );
6629        assert!(
6630            auto.len() < varint.len() / 100,
6631            "the generator ({} B) must ship ≪ the data ({} B)",
6632            auto.len(),
6633            varint.len()
6634        );
6635    }
6636
6637    #[test]
6638    fn wire_auto_polynomial_handles_cubic_and_negative_and_overflow() {
6639        // Degree-3 round-trips; a column whose differences overflow i64 falls back to the
6640        // menu (never mis-encodes); a non-polynomial column is left to the other candidates.
6641        let cubic: Vec<i64> = (0..500i64).map(|i| 2 * i * i * i - i * i + 11).collect();
6642        let (_, got) = affine_roundtrip(&cubic, WireStructure::Auto);
6643        assert_eq!(got, cubic, "cubic reconstructs bit-exact");
6644
6645        let overflowing: Vec<i64> = vec![i64::MIN, i64::MAX, i64::MIN, i64::MAX];
6646        let (_, got) = affine_roundtrip(&overflowing, WireStructure::Auto);
6647        assert_eq!(got, overflowing, "an overflowing column still round-trips (via the menu)");
6648
6649        let mut rng = SplitMix64 { state: 0xBADC_0FFE };
6650        let noise: Vec<i64> = (0..500).map(|_| rng.next() as i64).collect();
6651        let (_, got) = affine_roundtrip(&noise, WireStructure::Auto);
6652        assert_eq!(got, noise, "random noise round-trips (no false polynomial detection)");
6653    }
6654
6655    #[test]
6656    fn wire_auto_geometric_ships_the_generator_not_the_data() {
6657        // A geometric column `base * ratio^i` is NOT a polynomial (finite differences never
6658        // settle) and NOT affine, so without a dedicated detector it costs ~1 varint PER
6659        // element — the magnitude doubles every step. The generator ships THREE numbers
6660        // (base, ratio, count) regardless of length, and reconstructs bit-exact.
6661        let doubling: Vec<i64> = (0..40).map(|i| 3i64 * (1i64 << i)).collect();
6662        let (bytes, got) = affine_roundtrip(&doubling, WireStructure::Auto);
6663        assert_eq!(got, doubling, "a geometric column reconstructs bit-exact");
6664        assert!(
6665            bytes.len() < 20,
6666            "the geometric GENERATOR ships ~3 numbers, not 40 growing values: {} bytes",
6667            bytes.len()
6668        );
6669
6670        // Negative ratio (alternating sign, growing magnitude) is geometric too.
6671        let alternating: Vec<i64> = {
6672            let mut c = 1i64;
6673            (0..40)
6674                .map(|_| {
6675                    let v = c;
6676                    c = c.wrapping_mul(-2);
6677                    v
6678                })
6679                .collect()
6680        };
6681        let (bytes, got) = affine_roundtrip(&alternating, WireStructure::Auto);
6682        assert_eq!(got, alternating, "a negative-ratio geometric column reconstructs bit-exact");
6683        assert!(bytes.len() < 20, "negative-ratio geometric also ships the generator: {} bytes", bytes.len());
6684
6685        // SOUNDNESS under overflow: a doubling sequence that runs PAST i64 wraps deterministically
6686        // — the detector verifies reproduction under the SAME `wrapping_mul` the decoder uses, so it
6687        // is still recognized AND round-trips bit-exact across the wrap (2^63 → i64::MIN → 0 → 0…).
6688        let wrapping: Vec<i64> = {
6689            let mut c = 1i64;
6690            (0..70)
6691                .map(|_| {
6692                    let v = c;
6693                    c = c.wrapping_mul(2);
6694                    v
6695                })
6696                .collect()
6697        };
6698        let (_, got) = affine_roundtrip(&wrapping, WireStructure::Auto);
6699        assert_eq!(got, wrapping, "an overflowing geometric column still round-trips exactly");
6700
6701        // NO false positives: random noise, a near-geometric sequence with one perturbed element,
6702        // and an affine column are NOT mis-encoded as geometric — each round-trips exactly.
6703        let mut rng = SplitMix64 { state: 0x6E0_47E7 };
6704        let noise: Vec<i64> = (0..500).map(|_| rng.next() as i64).collect();
6705        let (_, got) = affine_roundtrip(&noise, WireStructure::Auto);
6706        assert_eq!(got, noise, "random noise round-trips (no false geometric detection)");
6707
6708        let mut perturbed: Vec<i64> = (0..30).map(|i| 5i64 * (1i64 << i)).collect();
6709        perturbed[17] += 1; // breaks the geometric law at one point
6710        let (_, got) = affine_roundtrip(&perturbed, WireStructure::Auto);
6711        assert_eq!(got, perturbed, "a perturbed near-geometric column round-trips (verification rejects it)");
6712
6713        let affine: Vec<i64> = (0..40).map(|i| 7 + 3 * i).collect();
6714        let (_, got) = affine_roundtrip(&affine, WireStructure::Auto);
6715        assert_eq!(got, affine, "an affine column round-trips (geometric does not steal it)");
6716    }
6717
6718    #[test]
6719    fn wire_auto_periodic_ships_the_repeating_block() {
6720        // A cyclic column `pattern[i % p]` (weekly schedules, repeating categories, sawtooth
6721        // bytes) is none of affine/geometric/polynomial — but it is fully described by ONE
6722        // period's worth of values plus the count. Ship the block, not the 500 repeats.
6723        let block = [10i64, 20, 30, 40, 50];
6724        let cyclic: Vec<i64> = (0..500).map(|i| block[i % block.len()]).collect();
6725        let (bytes, got) = affine_roundtrip(&cyclic, WireStructure::Auto);
6726        assert_eq!(got, cyclic, "a periodic column reconstructs bit-exact");
6727        assert!(
6728            bytes.len() < 30,
6729            "the periodic GENERATOR ships ONE period ({} values), not 500: {} bytes",
6730            block.len(),
6731            bytes.len()
6732        );
6733
6734        // Negative / mixed-magnitude period, and a non-trivial period length.
6735        let block2 = [-7i64, 0, 1000000, -3, 42, 42, -1];
6736        let cyclic2: Vec<i64> = (0..1001).map(|i| block2[i % block2.len()]).collect();
6737        let (bytes, got) = affine_roundtrip(&cyclic2, WireStructure::Auto);
6738        assert_eq!(got, cyclic2, "a mixed-magnitude periodic column reconstructs bit-exact");
6739        assert!(bytes.len() < 40, "still ships ONE period, not 1001 values: {} bytes", bytes.len());
6740
6741        // Minimal period wins: a column that is ALSO period-10 (because it is period-5) ships the
6742        // SMALLER period-5 block — and round-trips.
6743        let p5: Vec<i64> = (0..200).map(|i| block[i % 5]).collect();
6744        let (_, got) = affine_roundtrip(&p5, WireStructure::Auto);
6745        assert_eq!(got, p5, "the minimal period round-trips");
6746
6747        // NO false positives: random noise and an aperiodic column (period == length, no repeat)
6748        // are NOT mis-encoded as periodic — each round-trips exactly.
6749        let mut rng = SplitMix64 { state: 0x9E15_AB0 };
6750        let noise: Vec<i64> = (0..500).map(|_| rng.next() as i64).collect();
6751        let (_, got) = affine_roundtrip(&noise, WireStructure::Auto);
6752        assert_eq!(got, noise, "random noise round-trips (no false periodic detection)");
6753
6754        let aperiodic: Vec<i64> = (0..50).map(|i| i * i + 1).collect();
6755        let (_, got) = affine_roundtrip(&aperiodic, WireStructure::Auto);
6756        assert_eq!(got, aperiodic, "an aperiodic column round-trips");
6757    }
6758
6759    #[test]
6760    fn wire_float_default_dial_is_pure_memcpy() {
6761        // The lightning-quick contract: under the DEFAULT (`Off`) dial the float encoder never
6762        // inspects the data — even a constant / affine / periodic column ships as the raw n×8 memcpy
6763        // (`T_FLOATS`). Structural shrinking is opt-in via `Auto`/`Affine`. This mirrors the integer
6764        // contract (Off = straight varint, no detection) and is what keeps the hot encode path fast:
6765        // you pick the dial ahead of time, the encoder does not search on every send.
6766        let shapes: Vec<(&str, Vec<f64>)> = vec![
6767            ("constant", vec![3.14159f64; 1000]),
6768            ("affine", (0..1000).map(|i| i as f64).collect()),
6769            ("periodic", (0..1000).map(|i| [1.5f64, -2.25, 3.0, 0.0, 99.99][i % 5]).collect()),
6770        ];
6771        for (name, v) in &shapes {
6772            let val = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Floats(v.clone()))));
6773            let bytes = message_to_wire_with("", &val, WireCodec::Native, WireIntegrity::Raw).unwrap();
6774            // The tag is the plain memcpy form and the body carries all n×8 raw bytes — NOT a tiny
6775            // generator. (Framing adds a few bytes on top, so `>=` n×8 is the memcpy signature.)
6776            assert!(
6777                bytes.len() >= v.len() * 8,
6778                "[{name}] the Off dial must ship the raw memcpy (≥ {} B), got {} B (detection leaked into the hot path)",
6779                v.len() * 8,
6780                bytes.len()
6781            );
6782            let got = match message_from_wire(&bytes).unwrap().1 {
6783                RuntimeValue::List(l) => match &*l.borrow() {
6784                    ListRepr::Floats(g) => g.clone(),
6785                    _ => panic!("expected Floats"),
6786                },
6787                _ => panic!("expected List"),
6788            };
6789            assert_eq!(&got, v, "[{name}] memcpy float column round-trips bit-exact");
6790        }
6791        // The opt-in still works: the SAME constant column under `Auto` ships the tiny generator.
6792        let c = vec![3.14159f64; 1000];
6793        let val = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Floats(c))));
6794        let small = with_structure(WireStructure::Auto, || {
6795            message_to_wire_with("", &val, WireCodec::Native, WireIntegrity::Raw).unwrap()
6796        });
6797        assert!(small.len() < 30, "Auto still ships the generator (one f64 + count): {} B", small.len());
6798    }
6799
6800    #[test]
6801    fn wire_float_const_and_affine_ship_the_generator() {
6802        // Ship the GENERATOR for floats too: a constant column = one f64 + count; a bit-exact
6803        // `base + i·stride` column = three numbers. Both lossless; real noisy data falls through.
6804        fn roundtrip(v: Vec<f64>) -> (Vec<u8>, Vec<f64>) {
6805            let val = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Floats(v))));
6806            // Structural float forms are `Auto`/`Affine`-only now (the default dial is a pure memcpy —
6807            // see `wire_float_default_dial_is_pure_memcpy`); opt into the menu to exercise them.
6808            let bytes = with_structure(WireStructure::Auto, || {
6809                message_to_wire_with("", &val, WireCodec::Native, WireIntegrity::Raw).unwrap()
6810            });
6811            let got = match message_from_wire(&bytes).unwrap().1 {
6812                RuntimeValue::List(l) => match &*l.borrow() {
6813                    ListRepr::Floats(g) => g.clone(),
6814                    _ => panic!("expected Floats"),
6815                },
6816                _ => panic!("expected List"),
6817            };
6818            (bytes, got)
6819        }
6820
6821        // Constant — 1000 identical f64 ship in ~11 bytes.
6822        let c = vec![3.14159f64; 1000];
6823        let (bytes, got) = roundtrip(c.clone());
6824        assert_eq!(got, c, "constant float column reconstructs");
6825        assert!(bytes.len() < 30, "constant ships one f64 + count, not 8000 B: {} B", bytes.len());
6826
6827        // Affine — integer-valued floats (exact in f64) ship as base+stride+count.
6828        let ints: Vec<f64> = (0..1000).map(|i| i as f64).collect();
6829        let (bytes, got) = roundtrip(ints.clone());
6830        assert_eq!(got, ints, "integer-valued float column reconstructs bit-exact");
6831        assert!(bytes.len() < 40, "affine ships 3 numbers, not 8000 B: {} B", bytes.len());
6832
6833        // Affine with a power-of-two stride — `i·0.5` is bit-exact.
6834        let half: Vec<f64> = (0..500).map(|i| (i as f64) * 0.5).collect();
6835        let (bytes, got) = roundtrip(half.clone());
6836        assert_eq!(got, half, "power-of-two-stride affine reconstructs bit-exact");
6837        assert!(bytes.len() < 40, "still 3 numbers: {} B", bytes.len());
6838
6839        // NO false positives: noisy finite floats and a perturbed near-affine column round-trip
6840        // exactly via the raw/XOR path (the bit-exact check refuses anything that isn't perfect).
6841        let mut rng = SplitMix64 { state: 0xF10A7_C0DE };
6842        let noise: Vec<f64> = (0..500).map(|_| (rng.next() % 10_000_000) as f64 / 13.0).collect();
6843        let (_, got) = roundtrip(noise.clone());
6844        assert_eq!(got, noise, "noisy floats round-trip (no false generator detection)");
6845
6846        let mut perturbed: Vec<f64> = (0..50).map(|i| i as f64).collect();
6847        perturbed[37] = 36.9999999;
6848        let (_, got) = roundtrip(perturbed.clone());
6849        assert_eq!(got, perturbed, "a perturbed near-affine column round-trips");
6850    }
6851
6852    #[test]
6853    fn wire_auto_sparse_column_ships_dominant_plus_exceptions() {
6854        // A mostly-one-value column with a handful of DIVERSE-valued exceptions ships the dominant
6855        // value + a short (delta-index, value) list — beating dict (which would bit-pack 1000 indices
6856        // over 11 distinct values) and RLE (two run-entries per isolated exception).
6857        let mut v = vec![0i64; 1000];
6858        for k in 0..10 {
6859            v[k * 97] = (k as i64 + 1) * 12345;
6860        }
6861        let (bytes, got) = affine_roundtrip(&v, WireStructure::Auto);
6862        assert_eq!(got, v, "sparse column reconstructs exactly");
6863        assert!(bytes.len() < 80, "sparse ships ~10 exceptions, not 1000 values: {} bytes", bytes.len());
6864
6865        // A non-zero dominant value works too.
6866        let mut v2 = vec![42i64; 500];
6867        for k in 0..5 {
6868            v2[k * 80 + 3] = -(k as i64 + 1) * 7_000_003;
6869        }
6870        let (bytes, got) = affine_roundtrip(&v2, WireStructure::Auto);
6871        assert_eq!(got, v2, "non-zero-dominant sparse column reconstructs exactly");
6872        assert!(bytes.len() < 80, "still ~5 exceptions: {} bytes", bytes.len());
6873
6874        // NO false positives: a column with NO dominant value (random) round-trips via the menu,
6875        // not mis-encoded as sparse.
6876        let mut rng = SplitMix64 { state: 0x5A95E_C0DE };
6877        let noise: Vec<i64> = (0..500).map(|_| rng.next() as i64).collect();
6878        let (_, got) = affine_roundtrip(&noise, WireStructure::Auto);
6879        assert_eq!(got, noise, "random column round-trips (no false sparse detection)");
6880    }
6881
6882    #[test]
6883    fn wire_float_sparse_column_ships_dominant_plus_exceptions() {
6884        // The float twin of sparse: a mostly-one-value f64 column (sparse telemetry, a mostly-zero
6885        // signal with a few spikes) ships the dominant value + the outliers, not all n×8 bytes.
6886        fn roundtrip(v: Vec<f64>) -> (Vec<u8>, Vec<f64>) {
6887            let val = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Floats(v))));
6888            // Structural float forms are `Auto`/`Affine`-only now (the default dial is a pure memcpy —
6889            // see `wire_float_default_dial_is_pure_memcpy`); opt into the menu to exercise them.
6890            let bytes = with_structure(WireStructure::Auto, || {
6891                message_to_wire_with("", &val, WireCodec::Native, WireIntegrity::Raw).unwrap()
6892            });
6893            let got = match message_from_wire(&bytes).unwrap().1 {
6894                RuntimeValue::List(l) => match &*l.borrow() {
6895                    ListRepr::Floats(g) => g.clone(),
6896                    _ => panic!("expected Floats"),
6897                },
6898                _ => panic!("expected List"),
6899            };
6900            (bytes, got)
6901        }
6902
6903        let mut v = vec![0.0f64; 1000];
6904        for k in 0..10 {
6905            v[k * 97] = (k as f64 + 1.0) * 1234.5;
6906        }
6907        let (bytes, got) = roundtrip(v.clone());
6908        assert_eq!(got, v, "sparse float column reconstructs exactly");
6909        assert!(bytes.len() < 160, "sparse ships ~10 outliers, not 8000 B: {} B", bytes.len());
6910
6911        // Non-zero dominant, with negative outliers.
6912        let mut v2 = vec![3.5f64; 500];
6913        for k in 0..5 {
6914            v2[k * 80 + 3] = -(k as f64 + 1.0) * 99.0;
6915        }
6916        let (_, got) = roundtrip(v2.clone());
6917        assert_eq!(got, v2, "non-zero-dominant sparse float column reconstructs exactly");
6918
6919        // No dominant value (random finite floats) → not mis-encoded; round-trips via memcpy.
6920        let mut rng = SplitMix64 { state: 0xF10A7_5A95E };
6921        let noise: Vec<f64> = (0..500).map(|_| (rng.next() % 10_000_000) as f64 / 13.0).collect();
6922        let (_, got) = roundtrip(noise.clone());
6923        assert_eq!(got, noise, "random float column round-trips (no false sparse detection)");
6924    }
6925
6926    #[test]
6927    fn wire_float_periodic_and_geometric_ship_the_generator() {
6928        fn roundtrip(v: Vec<f64>) -> (Vec<u8>, Vec<f64>) {
6929            let val = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Floats(v))));
6930            // Structural float forms are `Auto`/`Affine`-only now (the default dial is a pure memcpy —
6931            // see `wire_float_default_dial_is_pure_memcpy`); opt into the menu to exercise them.
6932            let bytes = with_structure(WireStructure::Auto, || {
6933                message_to_wire_with("", &val, WireCodec::Native, WireIntegrity::Raw).unwrap()
6934            });
6935            let got = match message_from_wire(&bytes).unwrap().1 {
6936                RuntimeValue::List(l) => match &*l.borrow() {
6937                    ListRepr::Floats(g) => g.clone(),
6938                    _ => panic!("expected Floats"),
6939                },
6940                _ => panic!("expected List"),
6941            };
6942            (bytes, got)
6943        }
6944
6945        // Periodic — a repeating 5-float waveform ships ONE block, not 1000 samples.
6946        let block = [1.5f64, -2.25, 3.0, 0.0, 99.99];
6947        let cyclic: Vec<f64> = (0..1000).map(|i| block[i % 5]).collect();
6948        let (bytes, got) = roundtrip(cyclic.clone());
6949        assert_eq!(got, cyclic, "periodic float column reconstructs");
6950        assert!(bytes.len() < 80, "ships one 5-float block, not 1000: {} B", bytes.len());
6951
6952        // Geometric — doubling and halving (power-of-two ratios) are bit-exact in f64.
6953        let doubling: Vec<f64> = {
6954            let mut c = 1.0f64;
6955            (0..50).map(|_| { let x = c; c *= 2.0; x }).collect()
6956        };
6957        let (bytes, got) = roundtrip(doubling.clone());
6958        assert_eq!(got, doubling, "doubling float column reconstructs bit-exact");
6959        assert!(bytes.len() < 40, "geometric ships base+ratio+count: {} B", bytes.len());
6960
6961        let halving: Vec<f64> = {
6962            let mut c = 1024.0f64;
6963            (0..40).map(|_| { let x = c; c *= 0.5; x }).collect()
6964        };
6965        let (_, got) = roundtrip(halving.clone());
6966        assert_eq!(got, halving, "halving (exponential decay) reconstructs bit-exact");
6967
6968        // NO false positives: random finite floats are neither periodic nor geometric — round-trip exact.
6969        let mut rng = SplitMix64 { state: 0xC0FFEE_F10A7 };
6970        let noise: Vec<f64> = (0..500).map(|_| (rng.next() % 9_999_991) as f64 / 7.0 - 1234.5).collect();
6971        let (_, got) = roundtrip(noise.clone());
6972        assert_eq!(got, noise, "random floats round-trip (no false periodic/geometric detection)");
6973    }
6974
6975    #[test]
6976    fn wire_string_template_ships_prefix_suffix_and_affine_index() {
6977        // Sequential-id strings — REST URLs, file paths, generated labels — are `prefix + (base +
6978        // i·stride) + suffix`. Ship the two affixes once + the affine index, not all n strings.
6979        fn roundtrip(strings: &[String]) -> (Vec<u8>, Vec<String>) {
6980            let items: Vec<RuntimeValue> =
6981                strings.iter().map(|s| RuntimeValue::Text(Rc::new(s.clone()))).collect();
6982            let val = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::from_values(items))));
6983            let bytes = with_structure(WireStructure::Auto, || {
6984                message_to_wire_with("", &val, WireCodec::Native, WireIntegrity::Raw).unwrap()
6985            });
6986            let got = match message_from_wire(&bytes).unwrap().1 {
6987                RuntimeValue::List(l) => {
6988                    let b = l.borrow();
6989                    (0..b.len())
6990                        .map(|i| match b.get(i).unwrap() {
6991                            RuntimeValue::Text(s) => (*s).clone(),
6992                            other => panic!("expected Text, got {other:?}"),
6993                        })
6994                        .collect()
6995                }
6996                _ => panic!("expected List"),
6997            };
6998            (bytes, got)
6999        }
7000
7001        // Sequential-id URLs (long shared prefix) → ~40 bytes, not 37 KB.
7002        let urls: Vec<String> = (0..1000).map(|i| format!("https://api.example.com/v1/items/{i}")).collect();
7003        let (bytes, got) = roundtrip(&urls);
7004        assert_eq!(got, urls, "templated URLs reconstruct exactly");
7005        assert!(bytes.len() < 80, "ships prefix + affine index, not 1000 URLs: {} bytes", bytes.len());
7006
7007        // Non-unit stride, and a prefix+suffix template (`file_<i>.txt`).
7008        let stepped: Vec<String> = (0..500).map(|i| format!("row_{}", i * 2)).collect();
7009        let (_, got) = roundtrip(&stepped);
7010        assert_eq!(got, stepped, "stride-2 templated labels reconstruct exactly");
7011
7012        let files: Vec<String> = (0..300).map(|i| format!("file_{i}.txt")).collect();
7013        let (bytes, got) = roundtrip(&files);
7014        assert_eq!(got, files, "prefix+suffix template reconstructs exactly");
7015        assert!(bytes.len() < 60, "prefix+suffix template stays tiny: {} bytes", bytes.len());
7016
7017        // NO false positives: non-affine ids and ZERO-PADDED ids (exact-decimal check) round-trip
7018        // via the flat/dictionary path, never a wrong template.
7019        let mut rng = SplitMix64 { state: 0x57117_C0DE };
7020        let scattered: Vec<String> = (0..200).map(|_| format!("k{}", rng.next() % 1_000_000)).collect();
7021        let (_, got) = roundtrip(&scattered);
7022        assert_eq!(got, scattered, "non-affine ids round-trip (no false template)");
7023
7024        let padded: Vec<String> = (0..50).map(|i| format!("id_{i:03}")).collect();
7025        let (_, got) = roundtrip(&padded);
7026        assert_eq!(got, padded, "zero-padded ids round-trip (not templated — exact-decimal guard)");
7027    }
7028
7029    #[test]
7030    fn wire_string_front_coding_crushes_sorted_shared_prefix_columns() {
7031        // The structural string compressor the dictionary (all-distinct → no win) and template
7032        // (non-affine / zero-padded → bails) can't touch: a sorted or hierarchical column whose
7033        // adjacent strings share long prefixes ships each as (shared-prefix-len, suffix).
7034        fn roundtrip(strings: &[String]) -> (Vec<u8>, Vec<String>) {
7035            let items: Vec<RuntimeValue> =
7036                strings.iter().map(|s| RuntimeValue::Text(Rc::new(s.clone()))).collect();
7037            let val = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::from_values(items))));
7038            let bytes = with_structure(WireStructure::Auto, || {
7039                message_to_wire_with("", &val, WireCodec::Native, WireIntegrity::Raw).unwrap()
7040            });
7041            let got = match message_from_wire(&bytes).unwrap().1 {
7042                RuntimeValue::List(l) => {
7043                    let b = l.borrow();
7044                    (0..b.len())
7045                        .map(|i| match b.get(i).unwrap() {
7046                            RuntimeValue::Text(s) => (*s).clone(),
7047                            other => panic!("expected Text, got {other:?}"),
7048                        })
7049                        .collect()
7050                }
7051                _ => panic!("expected List"),
7052            };
7053            (bytes, got)
7054        }
7055        let flat_len = |v: &[String]| -> usize { v.iter().map(|s| s.len()).sum() };
7056
7057        // Zero-padded log paths (long shared prefix AND suffix; template bails on the zero-padding,
7058        // the dictionary can't help 500 distinct strings — front-coding crushes them).
7059        let paths: Vec<String> = (0..500).map(|i| format!("/var/log/app/2026/06/service-{i:04}.log")).collect();
7060        let (bytes, got) = roundtrip(&paths);
7061        assert_eq!(got, paths, "front-coded log paths reconstruct exactly");
7062        assert!(
7063            bytes.len() * 3 < flat_len(&paths),
7064            "front-coding crushes the shared path prefix: {} vs flat {}",
7065            bytes.len(),
7066            flat_len(&paths)
7067        );
7068
7069        // Sorted hierarchical object-store keys — non-affine, all distinct, deep shared prefixes.
7070        let mut keys: Vec<String> = Vec::new();
7071        for user in ["alice", "bob", "carol", "dave"] {
7072            for kind in ["profile", "settings", "avatar", "session"] {
7073                keys.push(format!("users/{user}/{kind}/data.json"));
7074            }
7075        }
7076        keys.sort();
7077        let (bytes, got) = roundtrip(&keys);
7078        assert_eq!(got, keys, "front-coded hierarchical keys reconstruct exactly");
7079        assert!(bytes.len() < flat_len(&keys), "front-coding beats flat on hierarchical keys");
7080
7081        // MULTI-BYTE UTF-8 shared prefix: the `café` prefix (é = 2 bytes) must be cut on a char
7082        // boundary so the suffix stays valid UTF-8 — round-trips bit-exact.
7083        let unicode: Vec<String> = (0..100).map(|i| format!("café/naïve/Москва/key-{i:03}")).collect();
7084        let (_, got) = roundtrip(&unicode);
7085        assert_eq!(got, unicode, "front-coding cuts on UTF-8 char boundaries (no corruption)");
7086
7087        // NO false win / NO corruption on a column with NO shared prefixes (high-entropy, unsorted):
7088        // `consider` keeps flat, and it still round-trips.
7089        let mut rng = SplitMix64 { state: 0xF20D_C0DE };
7090        let scattered: Vec<String> = (0..200)
7091            .map(|_| {
7092                let len = 6 + (rng.next() % 10) as usize;
7093                (0..len).map(|_| (b'a' + (rng.next() % 26) as u8) as char).collect()
7094            })
7095            .collect();
7096        let (_, got) = roundtrip(&scattered);
7097        assert_eq!(got, scattered, "prefix-free random strings round-trip (front-coding not falsely applied)");
7098    }
7099
7100    #[test]
7101    fn wire_bool_generators_ship_constant_alternating_and_run_columns() {
7102        // The generator theme completed for the LAST column type: a constant / alternating / cyclic
7103        // bool column ships its tiny period, a run-structured one ships its runs — none of which the
7104        // 1-bit bit-pack (≈ n/8 bytes) can touch — while a random column correctly falls back.
7105        fn roundtrip(v: &[bool]) -> (Vec<u8>, Vec<bool>) {
7106            let val = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Bools(v.to_vec()))));
7107            let bytes = with_structure(WireStructure::Auto, || {
7108                message_to_wire_with("", &val, WireCodec::Native, WireIntegrity::Raw).unwrap()
7109            });
7110            let got = match message_from_wire(&bytes).unwrap().1 {
7111                RuntimeValue::List(l) => match &*l.borrow() {
7112                    ListRepr::Bools(b) => b.clone(),
7113                    other => panic!("expected Bools, got {other:?}"),
7114                },
7115                _ => panic!("expected List"),
7116            };
7117            (bytes, got)
7118        }
7119
7120        // Constant columns (all-true / all-false) → period-1 generator, not 125 packed bytes.
7121        for constant in [true, false] {
7122            let col = vec![constant; 1000];
7123            let (bytes, got) = roundtrip(&col);
7124            assert_eq!(got, col, "constant bool column reconstructs exactly");
7125            assert!(bytes.len() < 20, "constant={constant} ships a period-1 generator: {} bytes", bytes.len());
7126        }
7127
7128        // Alternating → period-2; a weekly (period-7) flag → period-7.
7129        let alt: Vec<bool> = (0..1000).map(|i| i % 2 == 0).collect();
7130        let (bytes, got) = roundtrip(&alt);
7131        assert_eq!(got, alt, "alternating reconstructs exactly");
7132        assert!(bytes.len() < 20, "alternating ships a period-2 generator: {} bytes", bytes.len());
7133
7134        let weekly: Vec<bool> = (0..700).map(|i| [true, true, true, true, true, false, false][i % 7]).collect();
7135        let (bytes, got) = roundtrip(&weekly);
7136        assert_eq!(got, weekly, "weekly flag reconstructs exactly");
7137        assert!(bytes.len() < 20, "period-7 weekly flag ships as periodic: {} bytes", bytes.len());
7138
7139        // Two big runs ([F×500, T×500]) have NO short period → RLE crushes them.
7140        let runs: Vec<bool> = (0..1000).map(|i| i >= 500).collect();
7141        let (bytes, got) = roundtrip(&runs);
7142        assert_eq!(got, runs, "two big runs reconstruct exactly");
7143        assert!(bytes.len() < 20, "two big runs ship as RLE: {} bytes", bytes.len());
7144
7145        // Mostly-true with a few scattered flips → RLE beats the 125-byte bit-pack.
7146        let mut mostly = vec![true; 1000];
7147        for k in [37, 199, 450, 777, 988] {
7148            mostly[k] = false;
7149        }
7150        let (bytes, got) = roundtrip(&mostly);
7151        assert_eq!(got, mostly, "mostly-true-with-flips reconstructs exactly");
7152        assert!(bytes.len() < 60, "a handful of flips ships as RLE, not 125 packed bytes: {} bytes", bytes.len());
7153
7154        // Random → NO false generator: falls back to the bit-pack (~125 B) and round-trips.
7155        let mut rng = SplitMix64 { state: 0xB001_C0DE_F00D };
7156        let random: Vec<bool> = (0..1000).map(|_| rng.next() & 1 == 0).collect();
7157        let (bytes, got) = roundtrip(&random);
7158        assert_eq!(got, random, "random bools round-trip (no false generator detection)");
7159        assert!(bytes.len() >= 100, "random bools fall back to the bit-pack, not a false generator: {} bytes", bytes.len());
7160
7161        // Edges: empty + single element round-trip cleanly.
7162        for edge in [vec![], vec![true], vec![false], vec![true, false], vec![false, false, false]] {
7163            let (_, got) = roundtrip(&edge);
7164            assert_eq!(got, edge, "bool edge case {edge:?} round-trips");
7165        }
7166    }
7167
7168    #[test]
7169    fn wire_string_affix_ships_common_prefix_and_suffix_with_arbitrary_middles() {
7170        // The last string-column gap: a column sharing a common PREFIX and/or SUFFIX with ARBITRARY
7171        // middles — what the dictionary (all distinct), the template (non-affine middles), and front-
7172        // coding (shares only a PREFIX, pairwise) all miss.
7173        fn roundtrip(strings: &[String]) -> (Vec<u8>, Vec<String>) {
7174            let items: Vec<RuntimeValue> =
7175                strings.iter().map(|s| RuntimeValue::Text(Rc::new(s.clone()))).collect();
7176            let val = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::from_values(items))));
7177            let bytes = with_structure(WireStructure::Auto, || {
7178                message_to_wire_with("", &val, WireCodec::Native, WireIntegrity::Raw).unwrap()
7179            });
7180            let got = match message_from_wire(&bytes).unwrap().1 {
7181                RuntimeValue::List(l) => {
7182                    let b = l.borrow();
7183                    (0..b.len())
7184                        .map(|i| match b.get(i).unwrap() {
7185                            RuntimeValue::Text(s) => (*s).clone(),
7186                            other => panic!("expected Text, got {other:?}"),
7187                        })
7188                        .collect()
7189                }
7190                _ => panic!("expected List"),
7191            };
7192            (bytes, got)
7193        }
7194        let flat_len = |v: &[String]| -> usize { v.iter().map(|s| s.len()).sum() };
7195
7196        // Emails — common SUFFIX `@example.com`, arbitrary names (front-coding shares only prefixes,
7197        // so it can't crush the repeated suffix; affix ships the suffix ONCE).
7198        let names = ["alice", "bob", "charlie", "dave", "erin", "frank", "grace", "heidi"];
7199        let emails: Vec<String> = (0..400)
7200            .map(|i| format!("{}{}@example.com", names[i % names.len()], i))
7201            .collect();
7202        let (bytes, got) = roundtrip(&emails);
7203        assert_eq!(got, emails, "affixed emails reconstruct exactly");
7204        assert!(
7205            bytes.len() * 2 < flat_len(&emails),
7206            "affix ships the shared @example.com suffix once: {} vs flat {}",
7207            bytes.len(),
7208            flat_len(&emails)
7209        );
7210
7211        // Common extension `.log` (suffix only, arbitrary stems that don't sort-share prefixes).
7212        let stems = ["app", "db", "auth", "cache", "queue", "web", "cron", "mail"];
7213        let files: Vec<String> = (0..400).map(|i| format!("{}-{}.log", stems[i % stems.len()], i * 7)).collect();
7214        let (bytes, got) = roundtrip(&files);
7215        assert_eq!(got, files, "affixed log files reconstruct exactly");
7216        assert!(bytes.len() < flat_len(&files), "affix beats flat on a shared extension");
7217
7218        // Both prefix AND suffix, arbitrary (non-affine) middle → wrapped versioned ids.
7219        let mut rng = SplitMix64 { state: 0xAFF1_C0DE };
7220        let wrapped: Vec<String> = (0..300)
7221            .map(|_| format!("https://cdn.example.com/v2/{}/asset.json", rng.next() % 1_000_000))
7222            .collect();
7223        let (bytes, got) = roundtrip(&wrapped);
7224        assert_eq!(got, wrapped, "prefix+suffix wrapped ids reconstruct exactly");
7225        assert!(bytes.len() * 2 < flat_len(&wrapped), "affix crushes the shared URL wrapper");
7226
7227        // NO false win: a column with NO shared affix round-trips via flat/dict (affix returns None
7228        // when prefix+suffix is empty).
7229        let mut rng2 = SplitMix64 { state: 0x0FF1_DEAD };
7230        let scattered: Vec<String> = (0..200)
7231            .map(|_| {
7232                let len = 5 + (rng2.next() % 8) as usize;
7233                (0..len).map(|_| (b'a' + (rng2.next() % 26) as u8) as char).collect()
7234            })
7235            .collect();
7236        let (_, got) = roundtrip(&scattered);
7237        assert_eq!(got, scattered, "affix-free random strings round-trip (no false affix)");
7238    }
7239
7240    #[test]
7241    fn wire_gen_expr_substrate_round_trips_and_evaluates() {
7242        // `(i % 2 == 0) ? i*10 : i*10 + 5` — a piecewise column. The sandbox evaluates it
7243        // bit-exact, the tree round-trips through serialize/deserialize, and a T_GEN value
7244        // decodes to the evaluated column. This is the substrate a pure user function lowers
7245        // into — the receiver runs only this bounded evaluator, never arbitrary code.
7246        let expr = GenExpr::Select {
7247            op: GenCmp::Eq,
7248            lhs: Box::new(GenExpr::Mod(Box::new(GenExpr::Index), Box::new(GenExpr::Const(2)))),
7249            rhs: Box::new(GenExpr::Const(0)),
7250            then: Box::new(GenExpr::Mul(Box::new(GenExpr::Index), Box::new(GenExpr::Const(10)))),
7251            els: Box::new(GenExpr::Add(
7252                Box::new(GenExpr::Mul(Box::new(GenExpr::Index), Box::new(GenExpr::Const(10)))),
7253                Box::new(GenExpr::Const(5)),
7254            )),
7255        };
7256        let expected: Vec<i64> = (0..256i64).map(|i| if i % 2 == 0 { i * 10 } else { i * 10 + 5 }).collect();
7257        for (i, &e) in expected.iter().enumerate() {
7258            assert_eq!(gen_eval(&expr, i as i64), e, "sandbox eval matches at {i}");
7259        }
7260        let mut sbytes = Vec::new();
7261        serialize_gen(&expr, &mut sbytes);
7262        let mut p = 0;
7263        let mut budget = MAX_GEN_NODES;
7264        assert_eq!(deserialize_gen(&sbytes, &mut p, &mut budget, 0), Some(expr.clone()), "GenExpr round-trips");
7265        assert_eq!(p, sbytes.len(), "the tree is self-delimiting (no trailing bytes)");
7266
7267        let mut bytes = vec![T_GEN];
7268        serialize_gen(&expr, &mut bytes);
7269        write_uvarint(expected.len() as u64, &mut bytes);
7270        let mut p = 0;
7271        match native_decode(&bytes, &mut p).expect("T_GEN decodes") {
7272            RuntimeValue::List(l) => match &*l.borrow() {
7273                ListRepr::Ints(got) => assert_eq!(got, &expected, "T_GEN evaluates to the column"),
7274                _ => panic!("expected Ints"),
7275            },
7276            _ => panic!("expected List"),
7277        }
7278    }
7279
7280    #[test]
7281    fn wire_lower_pure_function_to_genexpr() {
7282        // The bridge for "ship a user function": a pure single-param arithmetic function
7283        // lowers to the sandboxed GenExpr (so the receiver evaluates data, never runs code).
7284        // `f(i) = 3*i*i - 5*i + 7` lowers and evaluates identically; anything outside the
7285        // safe arithmetic subset (unknown var, a call) is refused — never shippable.
7286        use crate::ast::stmt::{BinaryOpKind, Expr, Literal};
7287        use logicaffeine_base::{Arena, Symbol};
7288        fn num<'a>(a: &'a Arena<Expr<'a>>, v: i64) -> &'a Expr<'a> {
7289            a.alloc(Expr::Literal(Literal::Number(v)))
7290        }
7291        fn bin<'a>(a: &'a Arena<Expr<'a>>, op: BinaryOpKind, l: &'a Expr<'a>, r: &'a Expr<'a>) -> &'a Expr<'a> {
7292            a.alloc(Expr::BinaryOp { op, left: l, right: r })
7293        }
7294        let a: Arena<Expr> = Arena::new();
7295        let i = Symbol::from_index(0);
7296        let idx: &Expr = a.alloc(Expr::Identifier(i));
7297        // 3*i*i - 5*i + 7
7298        let body = bin(
7299            &a,
7300            BinaryOpKind::Add,
7301            bin(
7302                &a,
7303                BinaryOpKind::Subtract,
7304                bin(&a, BinaryOpKind::Multiply, bin(&a, BinaryOpKind::Multiply, num(&a, 3), idx), idx),
7305                bin(&a, BinaryOpKind::Multiply, num(&a, 5), idx),
7306            ),
7307            num(&a, 7),
7308        );
7309        let g = lower_expr_to_genexpr(body, i).expect("pure arithmetic lowers");
7310        for x in -50..50i64 {
7311            assert_eq!(gen_eval(&g, x), 3 * x * x - 5 * x + 7, "lowered generator matches f at {x}");
7312        }
7313        let other: &Expr = a.alloc(Expr::Identifier(Symbol::from_index(1)));
7314        assert!(lower_expr_to_genexpr(other, i).is_none(), "unknown variable → not shippable");
7315        let call: &Expr = a.alloc(Expr::Call { function: Symbol::from_index(2), args: vec![] });
7316        assert!(lower_expr_to_genexpr(call, i).is_none(), "a function call → not shippable");
7317    }
7318
7319    #[test]
7320    fn wire_computed_function_ships_callable_and_round_trips() {
7321        // A pure single-arg function lowered to a generator ships as T_FUNC, round-trips, and
7322        // the decoded function carries a generator that evaluates f(x) — a CALLABLE on a peer
7323        // that never compiled it. An ordinary closure (no generator) stays unsendable.
7324        use crate::ast::stmt::{BinaryOpKind, Expr, Literal};
7325        use logicaffeine_base::{Arena, Symbol};
7326        let a: Arena<Expr> = Arena::new();
7327        let i = Symbol::from_index(0);
7328        let idx: &Expr = a.alloc(Expr::Identifier(i));
7329        let sq: &Expr = a.alloc(Expr::BinaryOp { op: BinaryOpKind::Multiply, left: idx, right: idx });
7330        let one: &Expr = a.alloc(Expr::Literal(Literal::Number(1)));
7331        let body: &Expr = a.alloc(Expr::BinaryOp { op: BinaryOpKind::Add, left: sq, right: one });
7332        let expr = lower_expr_to_genexpr(body, i).expect("f(i)=i*i+1 lowers");
7333
7334        let f = RuntimeValue::Function(Box::new(ClosureValue {
7335            body_index: usize::MAX,
7336            captured_env: std::collections::HashMap::default(),
7337            param_names: vec![i],
7338            generated: Some(Rc::new(expr.clone())),
7339        }));
7340        let bytes = message_to_wire("p", &f).expect("a generated function is sendable");
7341        match message_from_wire(&bytes).unwrap().1 {
7342            RuntimeValue::Function(c) => {
7343                let g = c.generated.expect("decoded function carries its generator");
7344                assert_eq!(&*g, &expr, "the generator round-trips exactly");
7345                assert_eq!(c.param_names.len(), 1, "arity preserved");
7346                for x in -20..20i64 {
7347                    assert_eq!(gen_eval(&g, x), x * x + 1, "the shipped function evaluates f(x) on the receiver");
7348                }
7349            }
7350            _ => panic!("expected a Function back"),
7351        }
7352
7353        let plain = RuntimeValue::Function(Box::new(ClosureValue {
7354            body_index: 0,
7355            captured_env: std::collections::HashMap::default(),
7356            param_names: vec![],
7357            generated: None,
7358        }));
7359        assert!(message_to_wire("p", &plain).is_err(), "an un-lowered closure is still not sendable");
7360    }
7361
7362    #[test]
7363    fn receiver_refuses_a_shipped_computation_when_it_declines_code() {
7364        // THE EXECUTABLE-PAYLOAD GATE. The ONLY "code" the wire can carry is a bounded GenExpr sandbox
7365        // (never arbitrary bytecode — un-lowered closures are unsendable, proven above). A receiver that
7366        // declares `accept_computed: false` REFUSES even that, at decode — the first of three gates
7367        // against running code you didn't ask for (the C2 acceptance contract gates INVOCATION; the
7368        // sandbox bounds what an accepted call can do).
7369        use crate::ast::stmt::{BinaryOpKind, Expr, Literal};
7370        use logicaffeine_base::{Arena, Symbol};
7371        let a: Arena<Expr> = Arena::new();
7372        let i = Symbol::from_index(0);
7373        let idx: &Expr = a.alloc(Expr::Identifier(i));
7374        let one: &Expr = a.alloc(Expr::Literal(Literal::Number(1)));
7375        let body: &Expr = a.alloc(Expr::BinaryOp { op: BinaryOpKind::Add, left: idx, right: one });
7376        let expr = lower_expr_to_genexpr(body, i).expect("f(i)=i+1 lowers");
7377        let f = RuntimeValue::Function(Box::new(ClosureValue {
7378            body_index: usize::MAX,
7379            captured_env: std::collections::HashMap::default(),
7380            param_names: vec![i],
7381            generated: Some(Rc::new(expr)),
7382        }));
7383        let bytes = message_to_wire("p", &f).expect("a generated function is sendable");
7384        // Default: the computation decodes (it stays INERT until invoked through an acceptance contract).
7385        assert!(
7386            message_from_wire(&bytes).is_some(),
7387            "by default a shipped computation decodes (inert data until a contract invokes it)"
7388        );
7389        // A receiver that declines code refuses to decode it at all.
7390        let no_code = ReceiveLimits { accept_computed: false, ..Default::default() };
7391        assert!(
7392            with_receive_limits(no_code, || message_from_wire(&bytes)).is_none(),
7393            "a receiver with accept_computed=false must REFUSE a shipped computation at decode"
7394        );
7395    }
7396
7397    #[test]
7398    fn wire_auto_modular_affine_ships_a_generator() {
7399        // A sawtooth column `a + b·(i mod p)` ships a tiny GenExpr, not the values, bit-exact.
7400        let v: Vec<i64> = (0..5000i64).map(|i| 1000 + 7 * (i % 12)).collect();
7401        let (auto, got) = affine_roundtrip(&v, WireStructure::Auto);
7402        assert_eq!(got, v, "the modular-affine column reconstructs bit-exact");
7403        let (varint, _) = affine_roundtrip(&v, WireStructure::Off);
7404        assert!(
7405            auto.len() < varint.len() / 50,
7406            "the generator ({} B) must ship ≪ the data ({} B)",
7407            auto.len(),
7408            varint.len()
7409        );
7410    }
7411
7412    #[test]
7413    fn wire_auto_byte_column_ships_a_tight_zero_copy_blob() {
7414        // Wide-range, STRUCTURE-FREE bytes (deterministic random, no affine/geometric/periodic
7415        // law to exploit) ship as a tight 1-byte-per-element blob AND read back in place as
7416        // `&[u8]` with zero copy — the first-class binary type (capnp `Data`, protobuf `bytes`)
7417        // that FOR's bit-packing can't offer. Beats varint (2 bytes on every ≥128). The data is
7418        // random precisely so the GENERATORS (which legitimately win on structured columns) don't
7419        // preempt the blob — arbitrary binary is exactly when the zero-copy blob is the best form.
7420        let mut rng = SplitMix64 { state: 0x6B70_B10B_CAFE_F00D };
7421        let data: Vec<i64> = (0..1000).map(|_| (rng.next() % 256) as i64).collect();
7422        let v = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Ints(data.clone()))));
7423        let bytes = with_structure(WireStructure::Auto, || message_to_wire("p", &v).unwrap());
7424
7425        match &message_from_wire(&bytes).unwrap().1 {
7426            RuntimeValue::List(l) => match &*l.borrow() {
7427                ListRepr::Ints(g) => assert_eq!(g, &data, "byte column round-trips bit-exact"),
7428                _ => panic!("expected Ints"),
7429            },
7430            _ => panic!("expected List"),
7431        }
7432        assert!(bytes.len() <= data.len() + 32, "tight blob: {} bytes for {} values", bytes.len(), data.len());
7433
7434        let view = view_message(&bytes).unwrap();
7435        let slice = view.as_byte_slice().expect("a byte column reads zero-copy as &[u8]");
7436        assert_eq!(slice.len(), data.len(), "all bytes present");
7437        for (i, &b) in slice.iter().enumerate() {
7438            assert_eq!(b as i64, data[i], "byte {i} matches");
7439        }
7440        let base = bytes.as_ptr() as usize;
7441        let lo = slice.as_ptr() as usize;
7442        assert!(lo >= base && lo < base + bytes.len(), "the &[u8] borrows the message buffer (zero-copy)");
7443
7444        let varint = with_structure(WireStructure::Off, || message_to_wire("p", &v).unwrap());
7445        assert!(bytes.len() < varint.len(), "byte blob ({}) beats varint ({})", bytes.len(), varint.len());
7446    }
7447
7448    #[test]
7449    fn wire_narrow_byte_column_prefers_for_when_smaller() {
7450        // Narrow-range bytes (0..16) bit-pack SMALLER via FOR (≈4 bits each) than a 1-byte
7451        // blob, so the menu correctly chooses FOR — `T_BYTES` is only selected when it is
7452        // genuinely the best, never as a redundant default.
7453        let data: Vec<i64> = (0..1000).map(|i: i64| (i * 7).rem_euclid(16)).collect();
7454        let v = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Ints(data.clone()))));
7455        let bytes = with_structure(WireStructure::Auto, || message_to_wire("p", &v).unwrap());
7456
7457        match &message_from_wire(&bytes).unwrap().1 {
7458            RuntimeValue::List(l) => match &*l.borrow() {
7459                ListRepr::Ints(g) => assert_eq!(g, &data, "narrow byte column round-trips"),
7460                _ => panic!("expected Ints"),
7461            },
7462            _ => panic!("expected List"),
7463        }
7464        assert!(bytes.len() < data.len(), "narrow bytes pack below 1 byte/element ({} for {})", bytes.len(), data.len());
7465        assert!(
7466            view_message(&bytes).unwrap().as_byte_slice().is_none(),
7467            "the narrow column uses FOR/dict, not a T_BYTES blob"
7468        );
7469    }
7470
7471    #[test]
7472    fn wire_gen_decode_rejects_hostile_trees() {
7473        // Sandbox safety: an over-deep tree is rejected (not stack-overflowed); garbage and
7474        // truncated trees return None; a T_GEN value with a hostile body decodes to None —
7475        // never a panic, never unbounded work.
7476        let mut deep = GenExpr::Index;
7477        for _ in 0..(MAX_GEN_DEPTH + 5) {
7478            deep = GenExpr::Add(Box::new(deep), Box::new(GenExpr::Const(1)));
7479        }
7480        let mut sbytes = Vec::new();
7481        serialize_gen(&deep, &mut sbytes);
7482        let mut p = 0;
7483        let mut budget = MAX_GEN_NODES;
7484        assert!(deserialize_gen(&sbytes, &mut p, &mut budget, 0).is_none(), "over-deep tree rejected");
7485
7486        let mut p = 0;
7487        let mut budget = MAX_GEN_NODES;
7488        assert!(deserialize_gen(&[99u8], &mut p, &mut budget, 0).is_none(), "garbage node tag → None");
7489
7490        let mut p = 0;
7491        let mut budget = MAX_GEN_NODES;
7492        assert!(deserialize_gen(&[2u8], &mut p, &mut budget, 0).is_none(), "truncated binary op → None");
7493
7494        let mut p = 0;
7495        assert!(native_decode(&[T_GEN, 99u8, 5u8], &mut p).is_none(), "garbage T_GEN body → None, no panic");
7496    }
7497
7498    #[test]
7499    fn wire_matrix_blast_every_knob_combo_composes() {
7500        // MATRIX BLAST: the full Cartesian product of every codec knob, over representative
7501        // payloads. The risk in chaining knobs is INTERFERENCE — one silently corrupting
7502        // another. For each (payload × numerics × structure × floats × compression × integrity
7503        // × struct-view) we (1) encode, (2) decode without panic, and (3) prove the decoded
7504        // value is canonically IDENTICAL to the original by re-normalizing both to one fixed
7505        // baseline encoding and comparing bytes. So every combination must round-trip exactly.
7506        // Adding a knob = adding one loop dimension here; nothing else can quietly break.
7507        fn li(v: Vec<i64>) -> RuntimeValue {
7508            RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Ints(v))))
7509        }
7510        fn lf(v: Vec<f64>) -> RuntimeValue {
7511            RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Floats(v))))
7512        }
7513        fn rec(id: i64, name: &str, active: bool) -> RuntimeValue {
7514            let mut f = HashMap::new();
7515            f.insert("id".to_string(), RuntimeValue::Int(id));
7516            f.insert("name".to_string(), RuntimeValue::Text(Rc::new(name.to_string())));
7517            f.insert("active".to_string(), RuntimeValue::Bool(active));
7518            RuntimeValue::Struct(Box::new(StructValue { type_name: "Rec".to_string(), fields: f }))
7519        }
7520        let names = ["a", "bb", "ccc", "dddd"];
7521        let payloads: Vec<(&str, RuntimeValue)> = vec![
7522            ("scalar int", RuntimeValue::Int(-123456789)),
7523            ("bigint", RuntimeValue::Int(i64::MIN)),
7524            ("text", RuntimeValue::Text(Rc::new("hello, wire".to_string()))),
7525            ("bool", RuntimeValue::Bool(true)),
7526            ("nothing", RuntimeValue::Nothing),
7527            ("random ints", li((0..64).map(|i: i64| i.wrapping_mul(2_654_435_761)).collect())),
7528            ("monotone ints", li((0..64i64).scan(1000i64, |s, i| { *s += 1 + (i % 3); Some(*s) }).collect())),
7529            ("poly ints", li((0..64).map(|i: i64| 3 * i * i - 5 * i + 7).collect())),
7530            ("sawtooth ints", li((0..64).map(|i: i64| 100 + 5 * (i % 9)).collect())),
7531            ("clustered ints", li((0..64).map(|_| 1_000_000).collect())),
7532            ("wide bytes", li((0..64).map(|i: i64| (i * 37 + 128).rem_euclid(256)).collect())),
7533            ("narrow bytes", li((0..64).map(|i: i64| (i * 7).rem_euclid(16)).collect())),
7534            ("floats", lf((0..64).map(|i| i as f64 * 1.5 - 7.0).collect())),
7535            ("special floats", lf(vec![f64::NAN, f64::INFINITY, f64::NEG_INFINITY, -0.0, f64::MIN_POSITIVE])),
7536            ("bools", RuntimeValue::List(Rc::new(RefCell::new(ListRepr::from_values(
7537                (0..64).map(|i| RuntimeValue::Bool(i % 3 == 0)).collect(),
7538            ))))),
7539            ("strings", RuntimeValue::List(Rc::new(RefCell::new(ListRepr::from_values(
7540                (0..64).map(|i| RuntimeValue::Text(Rc::new(names[i % 4].to_string()))).collect(),
7541            ))))),
7542            ("struct", rec(7, "lone", false)),
7543            ("struct list", RuntimeValue::List(Rc::new(RefCell::new(ListRepr::from_values(
7544                (0..16).map(|i| rec(i, names[i as usize % 4], i % 2 == 0)).collect(),
7545            ))))),
7546            ("empty list", li(vec![])),
7547            ("int→int map", {
7548                let mut m = MapStorage::default();
7549                for k in 0..32i64 { m.insert(RuntimeValue::Int(k), RuntimeValue::Int(k * k)); }
7550                RuntimeValue::Map(Rc::new(RefCell::new(m)))
7551            }),
7552            ("int→string map", {
7553                let mut m = MapStorage::default();
7554                for k in 0..16i64 { m.insert(RuntimeValue::Int(k * 10), RuntimeValue::Text(Rc::new(format!("row_{k}")))); }
7555                RuntimeValue::Map(Rc::new(RefCell::new(m)))
7556            }),
7557            ("int→struct map", {
7558                // kind-0 values respond to the dials (struct_view etc.) — composes the map crush with
7559                // the struct encoders across every combo.
7560                let mut m = MapStorage::default();
7561                for k in 0..8i64 { m.insert(RuntimeValue::Int(k), rec(k, names[k as usize % 4], k % 2 == 0)); }
7562                RuntimeValue::Map(Rc::new(RefCell::new(m)))
7563            }),
7564            ("text→int map", {
7565                let mut m = MapStorage::default();
7566                for k in 0..8i64 { m.insert(RuntimeValue::Text(Rc::new(format!("k{k}"))), RuntimeValue::Int(k)); }
7567                RuntimeValue::Map(Rc::new(RefCell::new(m)))
7568            }),
7569        ];
7570
7571        // The fixed normalizer: encode under one canonical knob set so two values that are
7572        // canonically equal produce identical bytes regardless of how they were transmitted.
7573        let canon = |val: &RuntimeValue| -> Vec<u8> {
7574            with_numerics(WireNumerics::Varint, || {
7575                with_structure(WireStructure::Off, || {
7576                    with_floats(WireFloats::Memcpy, || {
7577                        message_to_wire_with("c", val, WireCodec::Native, WireIntegrity::Raw).unwrap()
7578                    })
7579                })
7580            })
7581        };
7582
7583        let mut combos = 0u64;
7584        for (name, v) in &payloads {
7585            let want = canon(v);
7586            for num in [WireNumerics::Varint, WireNumerics::Fixed, WireNumerics::GroupVarint] {
7587                for st in [WireStructure::Off, WireStructure::Affine, WireStructure::Auto] {
7588                    for fl in [WireFloats::Memcpy, WireFloats::XorDelta] {
7589                        for comp in
7590                            [WireCompression::None, WireCompression::Deflate, WireCompression::Lz4, WireCompression::Zstd]
7591                        {
7592                            for integ in [WireIntegrity::Raw, WireIntegrity::Checked] {
7593                                for sv in [false, true] {
7594                                    let bytes = with_numerics(num, || {
7595                                        with_structure(st, || {
7596                                            with_floats(fl, || {
7597                                                with_compression_codec(comp, || {
7598                                                    with_struct_view(sv, || {
7599                                                        message_to_wire_with("p", v, WireCodec::Native, integ).unwrap()
7600                                                    })
7601                                                })
7602                                            })
7603                                        })
7604                                    });
7605                                    let back = message_from_wire(&bytes).unwrap_or_else(|| {
7606                                        panic!(
7607                                            "{name} failed to decode under num={num:?} st={st:?} fl={fl:?} \
7608                                             comp={comp:?} integ={integ:?} sv={sv}"
7609                                        )
7610                                    });
7611                                    assert_eq!(
7612                                        canon(&back.1),
7613                                        want,
7614                                        "{name} corrupted under num={num:?} st={st:?} fl={fl:?} \
7615                                         comp={comp:?} integ={integ:?} sv={sv}"
7616                                    );
7617                                    combos += 1;
7618                                }
7619                            }
7620                        }
7621                    }
7622                }
7623            }
7624        }
7625        assert!(combos >= 4000, "matrix should blast thousands of knob combos, ran {combos}");
7626    }
7627
7628    #[test]
7629    fn wire_shared_type_id_composes_with_every_knob() {
7630        // Type-id elision (`shared`) drops struct names to a small id. This focuses on STRUCT
7631        // payloads — the only shapes type-id touches — and verifies the elided form COMPOSES
7632        // with every other knob: encode + decode under a registry, across all dials, must
7633        // decode canonically identical to the self-describing form. Kept small (structs only)
7634        // so it stays quick while still chaining the registry knob against everything else.
7635        fn rec(id: i64, name: &str, active: bool) -> RuntimeValue {
7636            let mut f = HashMap::new();
7637            f.insert("id".to_string(), RuntimeValue::Int(id));
7638            f.insert("name".to_string(), RuntimeValue::Text(Rc::new(name.to_string())));
7639            f.insert("active".to_string(), RuntimeValue::Bool(active));
7640            RuntimeValue::Struct(Box::new(StructValue { type_name: "Rec".to_string(), fields: f }))
7641        }
7642        let names = ["a", "bb", "ccc"];
7643        let payloads = vec![
7644            rec(7, "lone", false),
7645            RuntimeValue::List(Rc::new(RefCell::new(ListRepr::from_values(
7646                (0..12).map(|i| rec(i, names[i as usize % 3], i % 2 == 0)).collect(),
7647            )))),
7648        ];
7649        let mk_reg = || {
7650            WireTypeRegistry::new(vec![(
7651                "Rec".to_string(),
7652                vec!["active".to_string(), "id".to_string(), "name".to_string()],
7653            )])
7654        };
7655        let canon = |val: &RuntimeValue| -> Vec<u8> {
7656            with_numerics(WireNumerics::Varint, || {
7657                with_structure(WireStructure::Off, || {
7658                    message_to_wire_with("c", val, WireCodec::Native, WireIntegrity::Raw).unwrap()
7659                })
7660            })
7661        };
7662        let mut combos = 0u32;
7663        for v in &payloads {
7664            let want = canon(v);
7665            for num in [WireNumerics::Varint, WireNumerics::Fixed, WireNumerics::GroupVarint] {
7666                for st in [WireStructure::Off, WireStructure::Affine, WireStructure::Auto] {
7667                    for comp in [WireCompression::None, WireCompression::Zstd] {
7668                        for integ in [WireIntegrity::Raw, WireIntegrity::Checked] {
7669                            for sv in [false, true] {
7670                                let enc = || {
7671                                    with_numerics(num, || {
7672                                        with_structure(st, || {
7673                                            with_compression_codec(comp, || {
7674                                                with_struct_view(sv, || {
7675                                                    message_to_wire_with("p", v, WireCodec::Native, integ).unwrap()
7676                                                })
7677                                            })
7678                                        })
7679                                    })
7680                                };
7681                                // Type-id active for BOTH encode and decode (the id must resolve).
7682                                let bytes = with_type_registry(mk_reg(), enc);
7683                                let back = with_type_registry(mk_reg(), || message_from_wire(&bytes))
7684                                    .expect("a type-id-elided struct decodes with the registry");
7685                                assert_eq!(
7686                                    canon(&back.1),
7687                                    want,
7688                                    "shared struct corrupted under num={num:?} st={st:?} comp={comp:?} integ={integ:?} sv={sv}"
7689                                );
7690                                combos += 1;
7691                            }
7692                        }
7693                    }
7694                }
7695            }
7696        }
7697        assert!(combos >= 100, "shared-knob matrix ran {combos} combos");
7698    }
7699
7700    #[test]
7701    fn wire_auto_rle_wins_on_runs() {
7702        // 20 runs of 30 identical values → run-length collapses each run to one pair.
7703        let mut v = Vec::new();
7704        for k in 0..20i64 {
7705            for _ in 0..30 {
7706                v.push(k);
7707            }
7708        }
7709        let (auto, got) = affine_roundtrip(&v, WireStructure::Auto);
7710        let (varint, _) = affine_roundtrip(&v, WireStructure::Off);
7711        assert_eq!(got, v, "run-length round-trips bit-exact");
7712        assert!(auto.len() < varint.len(), "Auto ({}) must beat varint ({}) on runs", auto.len(), varint.len());
7713    }
7714
7715    #[test]
7716    fn wire_auto_dict_wins_on_low_cardinality() {
7717        // Five scattered distinct values (no runs, so RLE can't win) → dictionary + narrow
7718        // bit-packed indices.
7719        let mut rng = SplitMix64 { state: 0x0000_BEEF };
7720        let palette = [7i64, 42, 1000, -5, 999_999];
7721        let v: Vec<i64> = (0..500).map(|_| palette[(rng.next() % 5) as usize]).collect();
7722        let (auto, got) = affine_roundtrip(&v, WireStructure::Auto);
7723        let (varint, _) = affine_roundtrip(&v, WireStructure::Off);
7724        assert_eq!(got, v, "dictionary round-trips bit-exact");
7725        assert!(auto.len() < varint.len(), "Auto ({}) must beat varint ({}) on low cardinality", auto.len(), varint.len());
7726    }
7727
7728    #[test]
7729    fn wire_auto_never_worse_than_varint_on_random() {
7730        // Full-range random columns have no structure: the selector always includes the
7731        // plain-varint baseline, so Auto is never larger — and it still round-trips exactly.
7732        let mut rng = SplitMix64 { state: 0x00C0_FFEE };
7733        for _ in 0..50 {
7734            let n = (rng.next() % 200) as usize;
7735            let v: Vec<i64> = (0..n).map(|_| rng.next() as i64).collect();
7736            let (auto, got) = affine_roundtrip(&v, WireStructure::Auto);
7737            let (varint, _) = affine_roundtrip(&v, WireStructure::Off);
7738            assert_eq!(got, v, "Auto round-trips bit-exact on random data");
7739            assert!(auto.len() <= varint.len(), "Auto ({}) must never exceed varint ({})", auto.len(), varint.len());
7740        }
7741    }
7742
7743    #[test]
7744    fn wire_auto_decoder_never_panics_on_mutated_menu_messages() {
7745        // Every compression-menu tag, byte-mutated, must fail cleanly (None) — never panic
7746        // or over-allocate (the RLE/bit-pack lengths are attacker-controlled here).
7747        let mut rng = SplitMix64 { state: 0x00AB_1234 };
7748        let shapes: Vec<Vec<i64>> = vec![
7749            (0..50i64).collect(),
7750            vec![5i64; 80],
7751            (0..60i64).map(|i| 1_000_000 + (i % 8)).collect(),
7752            (0..70i64).map(|i| 1_700_000_000 + i * 7).collect(),
7753        ];
7754        for shape in &shapes {
7755            let value = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Ints(shape.clone()))));
7756            let base = with_structure(WireStructure::Auto, || {
7757                message_to_wire_with("", &value, WireCodec::Native, WireIntegrity::Raw).unwrap()
7758            });
7759            for _ in 0..2000 {
7760                let mut m = base.clone();
7761                let i = (rng.next() as usize) % m.len();
7762                m[i] ^= (rng.next() & 0xFF) as u8;
7763                let _ = message_from_wire(&m); // must not panic
7764            }
7765        }
7766    }
7767
7768    #[test]
7769    fn wire_intkey_map_decoder_never_panics_on_mutation() {
7770        // The T_MAP_INTKEY two-column form (int key column + value-kind byte + value column / per-value
7771        // list) is fully attacker-controlled on decode: the kind byte, both column lengths, and the
7772        // kind-0 value count can each be flipped. Byte-mutating both an int→int (kind 1) and an
7773        // int→text (kind 0) map message must fail cleanly — never panic, never over-allocate.
7774        let mut rng = SplitMix64 { state: 0x00CD_5678 };
7775        let mk_int = {
7776            let mut m = MapStorage::default();
7777            for k in 0..40i64 {
7778                m.insert(RuntimeValue::Int(k), RuntimeValue::Int(k * 3));
7779            }
7780            RuntimeValue::Map(Rc::new(RefCell::new(m)))
7781        };
7782        let mk_text = {
7783            let mut m = MapStorage::default();
7784            for k in 0..12i64 {
7785                m.insert(RuntimeValue::Int(k * 100), RuntimeValue::Text(Rc::new(format!("v{k}"))));
7786            }
7787            RuntimeValue::Map(Rc::new(RefCell::new(m)))
7788        };
7789        let mk_struct = {
7790            let mut m = MapStorage::default();
7791            for k in 0..10i64 {
7792                let mut f = HashMap::new();
7793                f.insert("id".to_string(), RuntimeValue::Int(k));
7794                f.insert("ok".to_string(), RuntimeValue::Bool(k % 2 == 0));
7795                m.insert(
7796                    RuntimeValue::Int(k),
7797                    RuntimeValue::Struct(Box::new(StructValue { type_name: "R".to_string(), fields: f })),
7798                );
7799            }
7800            RuntimeValue::Map(Rc::new(RefCell::new(m)))
7801        };
7802        for value in [mk_int, mk_text, mk_struct] {
7803            let base =
7804                message_to_wire_with("", &value, WireCodec::Native, WireIntegrity::Raw).unwrap();
7805            for _ in 0..3000 {
7806                let mut b = base.clone();
7807                let i = (rng.next() as usize) % b.len();
7808                b[i] ^= (rng.next() & 0xFF) as u8;
7809                let _ = message_from_wire(&b); // must not panic / OOM
7810            }
7811        }
7812    }
7813
7814    /// Encode an `Ints` list through the LEB128 varint path (structure off, the default
7815    /// `Varint` numerics), decode it, and return (bytes, recovered) — the oracle for the
7816    /// adaptive sign-mode encoding.
7817    fn varint_roundtrip(v: &[i64]) -> (Vec<u8>, Vec<i64>) {
7818        let value = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Ints(v.to_vec()))));
7819        let bytes = with_structure(WireStructure::Off, || {
7820            message_to_wire_with("", &value, WireCodec::Native, WireIntegrity::Raw).unwrap()
7821        });
7822        let (_, back) = message_from_wire(&bytes).expect("decode");
7823        let got = match back {
7824            RuntimeValue::List(l) => match &*l.borrow() {
7825                ListRepr::Ints(g) => g.clone(),
7826                _ => panic!("expected an Ints list back"),
7827            },
7828            _ => panic!("expected a List back"),
7829        };
7830        (bytes, got)
7831    }
7832
7833    #[test]
7834    fn a_non_negative_int_column_skips_zigzag_for_half_the_size() {
7835        // 100 copies of 64: plain LEB128 is one byte each (64 < 128); zigzag would spend
7836        // two (zigzag(64) = 128). The non-negative column must skip zigzag — matching
7837        // protobuf's `int64` instead of paying its `sint64` doubling penalty.
7838        let v = vec![64i64; 100];
7839        let (bytes, got) = varint_roundtrip(&v);
7840        assert_eq!(got, v, "non-negative round-trip must be exact");
7841        assert!(
7842            bytes.len() < 150,
7843            "a non-negative column must use plain LEB128 (≈100B), not zigzag (≈200B); got {} bytes",
7844            bytes.len()
7845        );
7846    }
7847
7848    #[test]
7849    fn a_column_with_any_negative_uses_zigzag_and_round_trips() {
7850        let v = vec![-1i64, -64, 5, -100, 0, 127];
7851        let (_, got) = varint_roundtrip(&v);
7852        assert_eq!(got, v, "mixed-sign round-trip must be exact");
7853    }
7854
7855    #[test]
7856    fn adaptive_sign_mode_round_trips_random_columns() {
7857        // Fill with RANDOM data (a deterministic xorshift, so the test is reproducible)
7858        // to be honest about the sign-mode decision: ~half the columns are forced
7859        // all-non-negative (exercising plain LEB128), the rest are full-range i64
7860        // (exercising zig-zag). Every column must round-trip exactly.
7861        let mut rng = 0x1234_5678_9ABC_DEF0u64;
7862        let mut next = || {
7863            rng ^= rng << 13;
7864            rng ^= rng >> 7;
7865            rng ^= rng << 17;
7866            rng
7867        };
7868        for _ in 0..3000 {
7869            let n = (next() % 80) as usize;
7870            let force_nonneg = next() & 1 == 0;
7871            let v: Vec<i64> = (0..n)
7872                .map(|_| {
7873                    let r = next() as i64;
7874                    if force_nonneg {
7875                        r & i64::MAX // clear the sign bit → non-negative
7876                    } else {
7877                        r
7878                    }
7879                })
7880                .collect();
7881            let (_, got) = varint_roundtrip(&v);
7882            assert_eq!(got, v, "random adaptive sign-mode round-trip failed for {v:?}");
7883        }
7884    }
7885
7886    #[test]
7887    fn adaptive_sign_mode_round_trips_every_boundary() {
7888        let cases: Vec<Vec<i64>> = vec![
7889            vec![],
7890            vec![0i64; 10],
7891            vec![1, 2, 3, 63, 64, 65, 127, 128, 255, 256],
7892            vec![-1, -2, -63, -64, -128, -129],
7893            vec![i64::MIN, i64::MAX, 0, -1, 1],
7894            vec![i64::MAX, i64::MAX - 1], // all non-negative, max magnitude
7895        ];
7896        for v in cases {
7897            let (_, got) = varint_roundtrip(&v);
7898            assert_eq!(got, v, "adaptive sign-mode round-trip failed for {v:?}");
7899        }
7900    }
7901
7902    #[test]
7903    fn wireview_reads_any_element_in_place_without_decoding() {
7904        // A million-element fixed-width int column. The view reads element N directly at
7905        // its byte offset — no full decode, no allocation, any index.
7906        let v: Vec<i64> = (0..1_000_000).map(|i| i as i64 * 3 - 7).collect();
7907        let value = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Ints(v.clone()))));
7908        let bytes = with_numerics(WireNumerics::Fixed, || {
7909            message_to_wire_with("", &value, WireCodec::Native, WireIntegrity::Raw).unwrap()
7910        });
7911        let view = view_message(&bytes).expect("view opens over the fixed-layout message");
7912        assert_eq!(view.int_list_len(), Some(1_000_000));
7913        for &i in &[0usize, 1, 12_345, 678_901, 999_999] {
7914            assert_eq!(view.int_list_get(i), Some(v[i]), "random-access element {i}");
7915        }
7916        assert_eq!(view.int_list_get(1_000_000), None, "out-of-bounds is None, not a panic");
7917    }
7918
7919    #[test]
7920    fn wireview_varint_and_float_and_scalar_views_agree_with_decode() {
7921        // The view must read varint-layout ints, memcpy floats, and scalars in agreement
7922        // with a full decode — every layout, not just fixed.
7923        let ints: Vec<i64> = vec![-5, 0, 7, 200, -3000, i64::MAX, i64::MIN];
7924        let iv = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Ints(ints.clone()))));
7925        let ib = with_numerics(WireNumerics::Varint, || {
7926            message_to_wire_with("", &iv, WireCodec::Native, WireIntegrity::Raw).unwrap()
7927        });
7928        let view = view_message(&ib).unwrap();
7929        assert_eq!(view.int_list_len(), Some(ints.len()));
7930        for (i, &x) in ints.iter().enumerate() {
7931            assert_eq!(view.int_list_get(i), Some(x), "varint element {i}");
7932        }
7933        let flts = vec![1.5f64, -2.25, 3.0e10, f64::MIN, f64::MAX];
7934        let fv = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Floats(flts.clone()))));
7935        let fb = message_to_wire_with("", &fv, WireCodec::Native, WireIntegrity::Raw).unwrap();
7936        let fview = view_message(&fb).unwrap();
7937        assert_eq!(fview.float_list_len(), Some(flts.len()));
7938        for (i, &x) in flts.iter().enumerate() {
7939            assert_eq!(fview.float_list_get(i), Some(x), "float element {i}");
7940        }
7941        let sb = message_to_wire_with("", &RuntimeValue::Int(-42), WireCodec::Native, WireIntegrity::Raw).unwrap();
7942        assert_eq!(view_message(&sb).unwrap().as_int(), Some(-42));
7943    }
7944
7945    #[test]
7946    fn wireview_single_field_read_is_far_cheaper_than_full_decode() {
7947        // The zero-copy win: reading ONE element of a 1M-element message — even a THOUSAND
7948        // of them — must be far cheaper than ONE full decode (O(1) access, no bulk copy).
7949        // A same-run comparison, so it is load-invariant.
7950        let v: Vec<i64> = (0..1_000_000).map(|i| i as i64).collect();
7951        let value = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Ints(v))));
7952        let bytes = with_numerics(WireNumerics::Fixed, || {
7953            message_to_wire_with("", &value, WireCodec::Native, WireIntegrity::Raw).unwrap()
7954        });
7955        let reads = {
7956            let t = std::time::Instant::now();
7957            for _ in 0..1000 {
7958                let view = view_message(&bytes).unwrap();
7959                std::hint::black_box(view.int_list_get(999_999));
7960            }
7961            t.elapsed().as_nanos()
7962        };
7963        let full = {
7964            let t = std::time::Instant::now();
7965            std::hint::black_box(message_from_wire(&bytes).unwrap());
7966            t.elapsed().as_nanos()
7967        };
7968        assert!(
7969            reads < full,
7970            "1000 zero-copy field reads ({reads}ns) must be cheaper than ONE full decode ({full}ns)"
7971        );
7972    }
7973
7974    #[test]
7975    fn wireview_open_is_o1_even_with_a_checksum() {
7976        // "Raw for certain": `view_message` never re-hashes the body, so opening a CHECKED
7977        // message (the default) and reading one element is O(1) — exactly as for a Raw one.
7978        // (Cap'n Proto / Arrow carry no checksum at all; our zero-copy view matches their
7979        // cost, while the FULL decode path still validates.) This would FAIL if the view
7980        // verified the 8 MB body's FNV sum on open.
7981        let v: Vec<i64> = (0..1_000_000).map(|i| i as i64).collect();
7982        let value = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Ints(v))));
7983        let bytes = with_numerics(WireNumerics::Fixed, || message_to_wire("", &value).unwrap());
7984        assert!(bytes[0] & H_CHECKED != 0, "the default message carries a checksum");
7985        let reads = {
7986            let t = std::time::Instant::now();
7987            for _ in 0..1000 {
7988                let view = view_message(&bytes).unwrap();
7989                std::hint::black_box(view.int_list_get(999_999));
7990            }
7991            t.elapsed().as_nanos()
7992        };
7993        let full = {
7994            let t = std::time::Instant::now();
7995            std::hint::black_box(message_from_wire(&bytes).unwrap());
7996            t.elapsed().as_nanos()
7997        };
7998        assert!(
7999            reads < full,
8000            "1000 view reads of a checksummed message ({reads}ns) must beat one full decode ({full}ns)"
8001        );
8002    }
8003
8004    #[test]
8005    fn wireview_rejects_compressed_and_malformed() {
8006        // The view is over raw native bytes; a compressed message returns None (it must be
8007        // inflated first), and a truncated/garbage frame never panics. Use REPETITIVE data
8008        // so zstd actually shrinks it (the codec keeps compression only when it helps).
8009        let v = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Ints(
8010            (0..4000).map(|i| (i % 4) as i64 * 1000).collect(),
8011        ))));
8012        let compressed = with_compression_codec(WireCompression::Zstd, || {
8013            message_to_wire_with("", &v, WireCodec::Native, WireIntegrity::Raw).unwrap()
8014        });
8015        assert!(compressed[0] & 0x02 != 0, "the test payload must actually be compressed");
8016        assert!(view_message(&compressed).is_none(), "a compressed message has no in-place view");
8017        assert!(view_message(&[]).is_none(), "empty");
8018        assert!(view_message(&[0xFF, 0x00, 0x01]).is_none(), "garbage header");
8019    }
8020
8021    #[test]
8022    fn structure_off_is_the_default_and_leaves_bytes_unchanged() {
8023        let v: Vec<i64> = (0..50).collect();
8024        let value = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Ints(v))));
8025        let default = message_to_wire_with("", &value, WireCodec::Native, WireIntegrity::Raw).unwrap();
8026        let (off, _) = {
8027            let b = with_structure(WireStructure::Off, || {
8028                message_to_wire_with("", &value, WireCodec::Native, WireIntegrity::Raw).unwrap()
8029            });
8030            (b, ())
8031        };
8032        assert_eq!(default, off, "Off must equal the default path byte-for-byte (no regression)");
8033    }
8034
8035    /// A BigInt beyond i64 — built straight from a decimal so the test does not depend
8036    /// on the arithmetic layer.
8037    fn big(decimal: &str) -> RuntimeValue {
8038        RuntimeValue::from_bigint(logicaffeine_base::BigInt::parse_decimal(decimal).unwrap())
8039    }
8040
8041    #[test]
8042    fn bigint_round_trips_through_the_binary_wire_exactly() {
8043        let v = big("123456789012345678901234567890");
8044        let bytes = message_to_wire("", &v).unwrap();
8045        let (_, back) = message_from_wire(&bytes).unwrap();
8046        assert_eq!(back.to_display_string(), "123456789012345678901234567890");
8047        assert!(matches!(back, RuntimeValue::BigInt(_)), "stays a BigInt across the wire");
8048    }
8049
8050    #[test]
8051    fn negative_bigint_round_trips_through_the_wire() {
8052        let v = big("-99999999999999999999999999999");
8053        let bytes = message_to_wire("", &v).unwrap();
8054        let (_, back) = message_from_wire(&bytes).unwrap();
8055        assert_eq!(back.to_display_string(), "-99999999999999999999999999999");
8056    }
8057
8058    #[test]
8059    fn bigint_round_trips_through_cross_task_materialize_rebuild() {
8060        let v = big("340282366920938463463374607431768211456"); // 2^128
8061        let back = rebuild(materialize(&v).unwrap());
8062        assert_eq!(back.to_display_string(), "340282366920938463463374607431768211456");
8063    }
8064
8065    /// An exact base-10 fixed-point, built straight from its literal so the test does
8066    /// not depend on the arithmetic layer.
8067    fn dec_lit(s: &str) -> RuntimeValue {
8068        RuntimeValue::Decimal(Rc::new(logicaffeine_base::Decimal::parse(s).unwrap()))
8069    }
8070
8071    #[test]
8072    fn decimal_round_trips_through_the_binary_wire_preserving_scale() {
8073        // Money must survive the wire bit-exact, SCALE INCLUDED: `100.00` comes back
8074        // `100.00`, not `100`, and `0.10` keeps its trailing zero.
8075        for s in ["19.99", "-0.005", "100.00", "0", "0.10", "123456789.000001"] {
8076            let bytes = message_to_wire("", &dec_lit(s)).unwrap();
8077            let (_, back) = message_from_wire(&bytes).unwrap();
8078            assert!(matches!(back, RuntimeValue::Decimal(_)), "stays a Decimal across the wire: {s}");
8079            assert_eq!(back.to_display_string(), s, "scale + value preserved exactly: {s}");
8080        }
8081    }
8082
8083    #[test]
8084    fn decimal_round_trips_through_cross_task_materialize_rebuild() {
8085        let v = dec_lit("19.99");
8086        let back = rebuild(materialize(&v).unwrap());
8087        assert!(matches!(back, RuntimeValue::Decimal(_)));
8088        assert_eq!(back.to_display_string(), "19.99");
8089    }
8090
8091    #[test]
8092    fn decimal_money_survives_wire_where_a_json_float_would_drift() {
8093        // `0.30` crosses the wire bit-exact, unlike the 0.30000000000000004 a JSON/f64
8094        // consumer would carry — the "JSON numbers ruin lives" footgun, removed for money.
8095        let bytes = message_to_wire("", &dec_lit("0.30")).unwrap();
8096        let (_, back) = message_from_wire(&bytes).unwrap();
8097        assert_eq!(back.to_display_string(), "0.30");
8098        assert_ne!(0.1_f64 + 0.2, 0.3);
8099    }
8100
8101    /// An exact complex from rational parts (`re_n/re_d + im_n/im_d · i`).
8102    fn cplx(re: (i64, i64), im: (i64, i64)) -> RuntimeValue {
8103        RuntimeValue::Complex(Rc::new(logicaffeine_base::Complex::new(
8104            logicaffeine_base::Rational::from_ratio_i64(re.0, re.1).unwrap(),
8105            logicaffeine_base::Rational::from_ratio_i64(im.0, im.1).unwrap(),
8106        )))
8107    }
8108
8109    #[test]
8110    fn complex_round_trips_through_the_binary_wire_exactly() {
8111        // Both rational parts (and `i·i = −1` exactness) survive the wire bit-for-bit.
8112        for z in [
8113            cplx((3, 1), (4, 1)),   // 3+4i
8114            cplx((0, 1), (1, 1)),   // i
8115            cplx((0, 1), (-1, 1)),  // -i
8116            cplx((-1, 2), (3, 4)),  // -1/2 + 3/4 i
8117            cplx((7, 1), (0, 1)),   // a real (7+0i)
8118        ] {
8119            let bytes = message_to_wire("", &z).unwrap();
8120            let (_, back) = message_from_wire(&bytes).unwrap();
8121            assert!(matches!(back, RuntimeValue::Complex(_)), "stays Complex on the wire");
8122            assert_eq!(back, z, "exact complex survives the wire");
8123        }
8124    }
8125
8126    #[test]
8127    fn complex_round_trips_through_cross_task_materialize_rebuild() {
8128        let z = cplx((3, 1), (-4, 1));
8129        let back = rebuild(materialize(&z).unwrap());
8130        assert!(matches!(back, RuntimeValue::Complex(_)));
8131        assert_eq!(back, z);
8132    }
8133
8134    fn modu(v: i64, n: i64) -> RuntimeValue {
8135        RuntimeValue::Modular(Rc::new(logicaffeine_base::Modular::from_i64(v, n).unwrap()))
8136    }
8137
8138    #[test]
8139    fn modular_round_trips_through_the_binary_wire_preserving_the_ring() {
8140        // Both the residue AND the modulus survive the wire — the ℤ/nℤ ring is preserved.
8141        for z in [modu(3, 7), modu(0, 13), modu(10, 7), modu(123456, 1_000_003)] {
8142            let bytes = message_to_wire("", &z).unwrap();
8143            let (_, back) = message_from_wire(&bytes).unwrap();
8144            assert!(matches!(back, RuntimeValue::Modular(_)), "stays Modular on the wire");
8145            assert_eq!(back, z, "exact residue + modulus survive the wire");
8146        }
8147    }
8148
8149    #[test]
8150    fn modular_round_trips_through_cross_task_materialize_rebuild() {
8151        let z = modu(42, 97);
8152        let back = rebuild(materialize(&z).unwrap());
8153        assert!(matches!(back, RuntimeValue::Modular(_)));
8154        assert_eq!(back, z);
8155    }
8156
8157    /// A quantity built straight from a magnitude + unit, independent of the arithmetic layer.
8158    fn qty(num: i64, den: i64, unit: &str) -> RuntimeValue {
8159        let unit = logicaffeine_base::quantity::units::by_name(unit).unwrap();
8160        let mag = logicaffeine_base::Rational::new(
8161            logicaffeine_base::BigInt::from_i64(num),
8162            logicaffeine_base::BigInt::from_i64(den),
8163        )
8164        .unwrap();
8165        RuntimeValue::Quantity(Rc::new(crate::interpreter::QuantityValue {
8166            q: logicaffeine_base::Quantity::of(mag, &unit),
8167            unit,
8168        }))
8169    }
8170
8171    #[test]
8172    fn quantity_round_trips_through_the_binary_wire_exactly() {
8173        // Value, dimension, AND display unit all survive — including a fractional magnitude
8174        // (the golden 42/127 ft) and an affine unit (°C, whose offset rides in the rebuilt unit).
8175        for (q, shown) in [
8176            (qty(2, 1, "inch"), "2 in"),
8177            (qty(20, 1, "celsius"), "20 °C"),
8178            (qty(5, 1, "kilogram"), "5 kg"),
8179            (qty(42, 127, "foot"), "42/127 ft"),
8180        ] {
8181            let bytes = message_to_wire("", &q).unwrap();
8182            let (_, back) = message_from_wire(&bytes).unwrap();
8183            assert!(matches!(back, RuntimeValue::Quantity(_)), "stays a Quantity on the wire: {shown}");
8184            assert_eq!(back.to_display_string(), shown, "value + unit preserved exactly: {shown}");
8185            assert_eq!(back, q, "physical equality preserved: {shown}");
8186        }
8187    }
8188
8189    #[test]
8190    fn quantity_round_trips_through_cross_task_materialize_rebuild() {
8191        let q = qty(42, 127, "foot");
8192        let back = rebuild(materialize(&q).unwrap());
8193        assert!(matches!(back, RuntimeValue::Quantity(_)));
8194        assert_eq!(back.to_display_string(), "42/127 ft");
8195        assert_eq!(back, q);
8196    }
8197
8198    // ===================================================================================
8199    // TYPE CONFORMANCE / LOCK-IN HARNESS
8200    //
8201    // The contract every first-class value type must honor, and the lock that makes it
8202    // impossible to add a new `RuntimeValue` variant without deciding its conformance.
8203    // ===================================================================================
8204
8205    /// Conformance class of a runtime value.
8206    #[derive(PartialEq, Eq, Debug)]
8207    enum ConfClass {
8208        /// A first-class value: must pass FULL conformance — `type_name`, `to_display_string`,
8209        /// reflexive equality, and lossless wire round-trip (both cross-task and binary).
8210        Value,
8211        /// A container of other values (its own round-trip is tested elsewhere; here we only
8212        /// require name/display/eq so the harness stays representation-agnostic).
8213        Container,
8214        /// An opaque handle or reference with no value-semantics wire identity.
8215        Opaque,
8216    }
8217
8218    /// THE LOCK. This match is exhaustive, so a NEW `RuntimeValue` variant will not compile until it
8219    /// is classified here — forcing a deliberate decision about its conformance. (Completeness
8220    /// Doctrine: no type enters the language without passing through the conformance harness.)
8221    fn conformance_class(v: &RuntimeValue) -> ConfClass {
8222        match v {
8223            RuntimeValue::Int(_)
8224            | RuntimeValue::BigInt(_)
8225            | RuntimeValue::Rational(_)
8226            | RuntimeValue::Decimal(_)
8227            | RuntimeValue::Complex(_)
8228            | RuntimeValue::Modular(_)
8229            | RuntimeValue::Float(_)
8230            | RuntimeValue::Bool(_)
8231            | RuntimeValue::Text(_)
8232            | RuntimeValue::Char(_)
8233            | RuntimeValue::Nothing
8234            | RuntimeValue::Duration(_)
8235            | RuntimeValue::Date(_)
8236            | RuntimeValue::Moment(_)
8237            | RuntimeValue::Span { .. }
8238            | RuntimeValue::Time(_)
8239            | RuntimeValue::Word(_)
8240            | RuntimeValue::Quantity(_)
8241            | RuntimeValue::Money(_)
8242            | RuntimeValue::Uuid(_)
8243            | RuntimeValue::Peer(_) => ConfClass::Value,
8244            RuntimeValue::List(_)
8245            | RuntimeValue::Tuple(_)
8246            | RuntimeValue::Set(_)
8247            | RuntimeValue::Map(_)
8248            | RuntimeValue::Struct(_)
8249            | RuntimeValue::Inductive(_) => ConfClass::Container,
8250            RuntimeValue::Function(_)
8251            | RuntimeValue::Chan(_)
8252            | RuntimeValue::TaskHandle(_)
8253            | RuntimeValue::Crdt(_)
8254            // A SIMD lane vector is a transient compute register: first-class at the AOT tier (the
8255            // crypto kernels compute over it), but NOT a wire type — you serialize the underlying
8256            // `Seq`, never the register. So it is not wire-round-tripped (hence Opaque here), yet it
8257            // IS AOT-wired to a concrete Rust type (declared in `aot_wiring` below).
8258            | RuntimeValue::Lanes(_) => ConfClass::Opaque,
8259        }
8260    }
8261
8262    /// One representative of every `ConfClass::Value` variant. If you add a value type, the lock above
8263    /// forces you to classify it; add its representative here so the conformance test exercises it.
8264    fn value_representatives() -> Vec<RuntimeValue> {
8265        vec![
8266            RuntimeValue::Int(7),
8267            // A genuine BigInt (2^64, beyond i64) so it does not narrow back to Int.
8268            RuntimeValue::BigInt(Rc::new(logicaffeine_base::BigInt::from_le_bytes(
8269                false,
8270                &[0, 0, 0, 0, 0, 0, 0, 0, 1],
8271            ))),
8272            // A non-integer rational (1/2) so it stays Rational.
8273            RuntimeValue::Rational(Rc::new(
8274                logicaffeine_base::Rational::from_ratio_i64(1, 2).unwrap(),
8275            )),
8276            dec_lit("19.99"),
8277            cplx((3, 1), (4, 1)),
8278            modu(3, 7),
8279            RuntimeValue::Float(2.5),
8280            RuntimeValue::Bool(true),
8281            RuntimeValue::Text(Rc::new("hi".to_string())),
8282            RuntimeValue::Char('x'),
8283            RuntimeValue::Nothing,
8284            RuntimeValue::Duration(10),
8285            RuntimeValue::Date(19_000),
8286            RuntimeValue::Moment(123),
8287            RuntimeValue::Span { months: 3, days: 14 },
8288            RuntimeValue::Time(99),
8289            RuntimeValue::Word(logicaffeine_base::WordVal::from_u64(32, 42).unwrap()),
8290            qty(42, 127, "foot"),
8291            RuntimeValue::Money(Rc::new(logicaffeine_base::Money::of(
8292                logicaffeine_base::Decimal::parse("19.99").unwrap(),
8293                logicaffeine_base::money::currency::by_code("USD").unwrap(),
8294            ))),
8295            RuntimeValue::Uuid(Rc::new(
8296                logicaffeine_base::Uuid::parse("550e8400-e29b-41d4-a716-446655440000").unwrap(),
8297            )),
8298            RuntimeValue::Peer(Rc::new("ws://host:9944".to_string())),
8299        ]
8300    }
8301
8302    /// The compiled-tier (AOT) wiring a runtime value's type MUST have.
8303    #[derive(Debug)]
8304    enum AotWiring {
8305        /// First-class at the AOT tier: the codegen lowers this type's name to this concrete Rust
8306        /// type (a primitive like `i64`, or a `Logos*` newtype like `LogosMoney`).
8307        Rust(&'static str),
8308        /// Deliberately runtime-only: a handle/reference/container with no single AOT value type
8309        /// (containers lower generically by element; handles never cross into compiled value code).
8310        RuntimeOnly,
8311    }
8312
8313    /// THE AOT WIRING LOCK. Exhaustive over `RuntimeValue`, so a NEW variant will not compile until
8314    /// its compiled-tier wiring is declared here — you cannot add a value type and forget to wire it
8315    /// into the AOT codegen. The test below then checks the REAL codegen (`map_type_to_rust`) agrees,
8316    /// so a type wired into the runtime + wire but missing from AOT FAILS. (Completeness Doctrine:
8317    /// all types must be wired through EVERY tier, not just the wire.)
8318    fn aot_wiring(v: &RuntimeValue) -> AotWiring {
8319        use AotWiring::{Rust, RuntimeOnly};
8320        match v {
8321            // A BigInt reports type_name "Int" (same logical type, wider repr) → i64 codegen path.
8322            RuntimeValue::Int(_) | RuntimeValue::BigInt(_) => Rust("i64"),
8323            RuntimeValue::Rational(_) => Rust("LogosRational"),
8324            RuntimeValue::Decimal(_) => Rust("LogosDecimal"),
8325            RuntimeValue::Complex(_) => Rust("LogosComplex"),
8326            RuntimeValue::Modular(_) => Rust("LogosModular"),
8327            RuntimeValue::Float(_) => Rust("f64"),
8328            RuntimeValue::Bool(_) => Rust("bool"),
8329            RuntimeValue::Text(_) => Rust("String"),
8330            RuntimeValue::Char(_) => Rust("char"),
8331            RuntimeValue::Nothing => Rust("()"),
8332            RuntimeValue::Duration(_) => Rust("std::time::Duration"),
8333            RuntimeValue::Date(_) => Rust("LogosDate"),
8334            RuntimeValue::Moment(_) => Rust("LogosMoment"),
8335            RuntimeValue::Span { .. } => Rust("LogosSpan"),
8336            RuntimeValue::Time(_) => Rust("LogosTime"),
8337            // The representative is a 32-bit word; its type_name "Word32" is in the codegen map.
8338            RuntimeValue::Word(_) => Rust("Word32"),
8339            // A lane vector is AOT-first-class (the crypto kernels' working registers) even though it
8340            // is not wire-round-tripped — `map_type_to_rust("Lanes8Word32")` lowers it.
8341            RuntimeValue::Lanes(_) => Rust("Lanes8Word32"),
8342            RuntimeValue::Quantity(_) => Rust("LogosQuantity"),
8343            RuntimeValue::Money(_) => Rust("LogosMoney"),
8344            RuntimeValue::Uuid(_) => Rust("LogosUuid"),
8345            // A peer is a runtime networking handle — it round-trips on the wire but is not a
8346            // compiled-tier value type.
8347            RuntimeValue::Peer(_) => RuntimeOnly,
8348            // Containers lower generically (LogosSeq<T>/LogosMap<K,V>/…) via codegen_type_expr, not by
8349            // a bare name; their own AOT coverage is the collection codegen tests.
8350            RuntimeValue::List(_)
8351            | RuntimeValue::Tuple(_)
8352            | RuntimeValue::Set(_)
8353            | RuntimeValue::Map(_)
8354            | RuntimeValue::Struct(_)
8355            | RuntimeValue::Inductive(_) => RuntimeOnly,
8356            // Opaque handles never cross into compiled value code.
8357            RuntimeValue::Function(_)
8358            | RuntimeValue::Chan(_)
8359            | RuntimeValue::TaskHandle(_)
8360            | RuntimeValue::Crdt(_) => RuntimeOnly,
8361        }
8362    }
8363
8364    /// Full conformance for one value: name, display, reflexive equality, and BOTH wire round-trips.
8365    fn assert_value_conformance(v: &RuntimeValue) {
8366        let name = v.type_name();
8367        assert!(!name.is_empty(), "type_name must be non-empty");
8368        // Display must not panic.
8369        let _ = v.to_display_string();
8370        // Equality is reflexive (representatives are finite — no NaN).
8371        assert!(v == v, "{name} value is not equal to itself");
8372        // Cross-task marshalling (materialize → rebuild) is the identity.
8373        let back = rebuild(materialize(v).unwrap_or_else(|_| panic!("{name} did not materialize")));
8374        assert_eq!(&back, v, "{name} changed across cross-task marshalling");
8375        assert_eq!(
8376            conformance_class(&back),
8377            ConfClass::Value,
8378            "{name} changed variant across marshalling"
8379        );
8380        // Binary wire (encode → decode) is the identity.
8381        let bytes = message_to_wire("", v).unwrap_or_else(|_| panic!("{name} did not encode to wire"));
8382        let (_, back2) = message_from_wire(&bytes).unwrap_or_else(|| panic!("{name} did not decode"));
8383        assert_eq!(&back2, v, "{name} changed across the binary wire");
8384    }
8385
8386    #[test]
8387    fn every_value_type_conforms_name_display_eq_and_both_wire_round_trips() {
8388        let reps = value_representatives();
8389        for v in &reps {
8390            assert_eq!(
8391                conformance_class(v),
8392                ConfClass::Value,
8393                "representative for {} must be a Value",
8394                v.type_name()
8395            );
8396            assert_value_conformance(v);
8397        }
8398        // Sanity: the representative set is non-trivial and covers the value types we have shipped.
8399        assert!(reps.len() >= 20, "expected a representative for every value type");
8400    }
8401
8402    #[test]
8403    fn every_value_type_is_wired_into_the_aot_codegen_tier() {
8404        // A first-class value must compile to Rust, not just travel the wire. For every Value
8405        // representative whose AOT wiring spec names a concrete Rust type, the real codegen
8406        // (`map_type_to_rust`, the single source of truth for type-name → Rust) MUST lower the
8407        // value's `type_name()` to exactly that. Adding a value type wired into the runtime + wire
8408        // but missing from the AOT codegen fails here — the gap the wire conformance test alone
8409        // could not catch. `RuntimeOnly` is the conscious, exhaustive-match-forced exemption (e.g. a
8410        // networking handle); the exhaustiveness of `aot_wiring` is what makes the decision
8411        // unavoidable for every new type.
8412        let mut checked = 0usize;
8413        for v in &value_representatives() {
8414            let name = v.type_name();
8415            if let AotWiring::Rust(expected) = aot_wiring(v) {
8416                let mapped = crate::codegen::types::map_type_to_rust(name);
8417                assert_eq!(
8418                    mapped, expected,
8419                    "{name}: AOT codegen lowers it to `{mapped}`, but the wiring lock expects `{expected}` \
8420                     — wire the type into codegen/types.rs::map_type_to_rust"
8421                );
8422                // ANALYSIS tier: where the type checker knows this type name, its lowering MUST agree
8423                // with the codegen — the two type-lowering paths cannot drift. (A type the checker does
8424                // not yet model by name, e.g. the width-indexed `Word`, returns `Unknown` and is left to
8425                // the codegen lock above; that exemption is documented, not silent.)
8426                let lt = crate::analysis::types::LogosType::from_type_name(name);
8427                if lt != crate::analysis::types::LogosType::Unknown {
8428                    assert_eq!(
8429                        lt.to_rust_type(), expected,
8430                        "{name}: analysis LogosType lowers to `{}`, codegen to `{expected}` — the type checker \
8431                         and codegen disagree; wire them consistently",
8432                        lt.to_rust_type()
8433                    );
8434                }
8435                checked += 1;
8436            }
8437        }
8438        // The lock must actually be exercising the AOT tier, not silently skipping everything.
8439        assert!(checked >= 18, "AOT wiring lock checked only {checked} value types");
8440    }
8441
8442    #[test]
8443    fn compound_dimension_quantity_survives_the_wire_as_its_signature() {
8444        // A dimension-combining product (Area, empty display symbol) preserves its dimension and
8445        // renders the signature on the far side.
8446        let m = logicaffeine_base::quantity::units::by_name("meter").unwrap();
8447        let area = logicaffeine_base::Quantity::of(logicaffeine_base::Rational::from_i64(3), &m)
8448            .mul(&logicaffeine_base::Quantity::of(logicaffeine_base::Rational::from_i64(4), &m));
8449        let area_unit =
8450            logicaffeine_base::Unit::linear("", area.dimension(), logicaffeine_base::Rational::one());
8451        let v = RuntimeValue::Quantity(Rc::new(crate::interpreter::QuantityValue { q: area, unit: area_unit }));
8452        let (_, back) = message_from_wire(&message_to_wire("", &v).unwrap()).unwrap();
8453        assert_eq!(back.to_display_string(), "12 L^2");
8454        assert_eq!(back, v);
8455    }
8456
8457    #[test]
8458    fn our_wire_preserves_an_integer_that_json_would_corrupt() {
8459        // 2^53 + 1 is the smallest integer a conforming JSON (f64) consumer rounds
8460        // away — the canonical "JSON numbers ruin lives" value. Our typed wire keeps
8461        // the i64 EXACT, with no 2^53 cliff.
8462        let n = 9_007_199_254_740_993i64;
8463        let bytes = message_to_wire("", &RuntimeValue::Int(n)).unwrap();
8464        let (_, back) = message_from_wire(&bytes).unwrap();
8465        assert_eq!(back, RuntimeValue::Int(n), "our wire keeps it exact");
8466        // The JSON number model (IEEE-754 double) loses it.
8467        assert_ne!(n as f64 as i64, n, "f64 round-trip corrupts 2^53+1 — the JSON footgun");
8468    }
8469
8470    fn rat(n: i64, d: i64) -> RuntimeValue {
8471        RuntimeValue::from_rational(logicaffeine_base::Rational::from_ratio_i64(n, d).unwrap())
8472    }
8473
8474    #[test]
8475    fn our_wire_preserves_a_fraction_that_json_would_round() {
8476        // 1/3 has no exact f64 / JSON-number representation — a JSON consumer stores
8477        // 0.3333… and can never recover 1/3. Our typed wire keeps the fraction EXACT —
8478        // the other half of "JSON numbers ruin lives", alongside the 2^53 cliff above.
8479        let bytes = message_to_wire("", &rat(1, 3)).unwrap();
8480        let (_, back) = message_from_wire(&bytes).unwrap();
8481        assert_eq!(back.to_display_string(), "1/3", "the fraction survives the wire exactly");
8482        assert!(matches!(back, RuntimeValue::Rational(_)), "stays a Rational across the wire");
8483        // The JSON/IEEE-754 model can't even add tenths exactly — the footgun this removes.
8484        assert_ne!(0.1_f64 + 0.2, 0.3);
8485    }
8486
8487    #[test]
8488    fn rational_round_trips_through_the_wire_and_cross_task() {
8489        // Includes a fraction that REDUCES to a whole number (6/2 → 3): it downsizes to
8490        // an Int and rides the wire as one, proving the canonical-representation invariant.
8491        for (n, d, shown) in [(7i64, 2i64, "7/2"), (-3, 4, "-3/4"), (6, 2, "3"), (22, 7, "22/7")] {
8492            let v = rat(n, d);
8493            let bytes = message_to_wire("", &v).unwrap();
8494            let (_, back) = message_from_wire(&bytes).unwrap();
8495            assert_eq!(back.to_display_string(), shown, "{n}/{d} via the binary wire");
8496            let back2 = rebuild(materialize(&v).unwrap());
8497            assert_eq!(back2.to_display_string(), shown, "{n}/{d} via materialize/rebuild");
8498        }
8499    }
8500
8501    #[test]
8502    fn scalars_and_temporals_roundtrip() {
8503        for v in [
8504            RuntimeValue::Int(5),
8505            RuntimeValue::Float(2.5),
8506            RuntimeValue::Bool(true),
8507            RuntimeValue::Char('z'),
8508            RuntimeValue::Nothing,
8509            RuntimeValue::Duration(10),
8510            RuntimeValue::Date(19_000),
8511            RuntimeValue::Moment(123),
8512            RuntimeValue::Span { months: 3, days: 14 },
8513            RuntimeValue::Time(99),
8514        ] {
8515            assert_roundtrips(&v);
8516        }
8517    }
8518
8519    #[test]
8520    fn text_roundtrips() {
8521        let v = RuntimeValue::Text(Rc::new("hello".to_string()));
8522        let p = assert_roundtrips(&v);
8523        assert_eq!(p, RtPayload::Text("hello".to_string()));
8524    }
8525
8526    #[test]
8527    fn peer_handle_roundtrips_exactly() {
8528        let v = RuntimeValue::Peer(Rc::new("ws://127.0.0.1:9944".to_string()));
8529        let p = assert_roundtrips(&v);
8530        assert_eq!(p, RtPayload::Peer("ws://127.0.0.1:9944".to_string()));
8531        // …and rebuilds back to a Peer (not a bare Text).
8532        assert!(matches!(rebuild(p), RuntimeValue::Peer(t) if t.as_str() == "ws://127.0.0.1:9944"));
8533    }
8534
8535    #[test]
8536    fn int_list_roundtrips() {
8537        let v = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::from_values(vec![
8538            RuntimeValue::Int(1),
8539            RuntimeValue::Int(2),
8540            RuntimeValue::Int(3),
8541        ]))));
8542        let p = assert_roundtrips(&v);
8543        assert_eq!(p, RtPayload::List(vec![RtPayload::Int(1), RtPayload::Int(2), RtPayload::Int(3)]));
8544    }
8545
8546    #[test]
8547    fn set_and_tuple_roundtrip() {
8548        let set = RuntimeValue::Set(Rc::new(RefCell::new(vec![RuntimeValue::Int(7), RuntimeValue::Int(8)])));
8549        let p = assert_roundtrips(&set);
8550        assert_eq!(p, RtPayload::Set(vec![RtPayload::Int(7), RtPayload::Int(8)]));
8551
8552        let tup = RuntimeValue::Tuple(Rc::new(vec![RuntimeValue::Int(1), RuntimeValue::Bool(false), RuntimeValue::Char('x')]));
8553        let p = assert_roundtrips(&tup);
8554        assert_eq!(p, RtPayload::Tuple(vec![RtPayload::Int(1), RtPayload::Bool(false), RtPayload::Char('x')]));
8555    }
8556
8557    #[test]
8558    fn sets_are_canonical_regardless_of_insertion_order() {
8559        // SYMMETRY BREAKING ON THE WIRE: a set is order-invariant, so the SAME members in ANY
8560        // insertion order MUST serialize to byte-identical wire — so content-addressing, dedup,
8561        // `Send cached` keying, and FEC all hold for sets. Mirrors canonical T_MAP / T_STRUCT.
8562        let mk = |order: &[i64]| {
8563            RuntimeValue::Set(Rc::new(RefCell::new(
8564                order.iter().map(|&n| RuntimeValue::Int(n)).collect::<Vec<_>>(),
8565            )))
8566        };
8567        let mut e1 = Vec::new();
8568        native_encode(&mk(&[5, 1, 3, 2, 4]), &mut e1).unwrap();
8569        let mut e2 = Vec::new();
8570        native_encode(&mk(&[4, 2, 3, 1, 5]), &mut e2).unwrap();
8571        let mut e3 = Vec::new();
8572        native_encode(&mk(&[1, 2, 3, 4, 5]), &mut e3).unwrap();
8573        assert_eq!(e1, e2, "same set, different insertion order → byte-identical wire");
8574        assert_eq!(e1, e3, "...identical to the already-sorted insertion order too");
8575
8576        let mut pos = 0;
8577        match native_decode(&e1, &mut pos).expect("decode") {
8578            RuntimeValue::Set(s) => {
8579                let mut got: Vec<i64> = s
8580                    .borrow()
8581                    .iter()
8582                    .map(|v| match v {
8583                        RuntimeValue::Int(n) => *n,
8584                        other => panic!("expected Int in set, got {other:?}"),
8585                    })
8586                    .collect();
8587                got.sort_unstable();
8588                assert_eq!(got, vec![1, 2, 3, 4, 5], "canonical bytes round-trip to the same members");
8589            }
8590            other => panic!("expected a Set, got {other:?}"),
8591        }
8592    }
8593
8594    #[test]
8595    fn int_set_crushes_to_a_compressed_column() {
8596        // The extreme symmetry-break case: a CONSECUTIVE int set {1..1000} (built in reverse order).
8597        // Sorted, it's a perfect affine column → base+stride+count, ZERO per-element data. It must be
8598        // a tiny fraction of the ~1000+ bytes the naive tagged-element encoding would write, and round
8599        // -trip exactly. (A clustered/sparse set instead gets delta/RLE — never worse than the naive.)
8600        let n = 1000i64;
8601        let order: Vec<RuntimeValue> = (1..=n).rev().map(RuntimeValue::Int).collect();
8602        let set = RuntimeValue::Set(Rc::new(RefCell::new(order)));
8603        let mut enc = Vec::new();
8604        native_encode(&set, &mut enc).unwrap();
8605        assert!(
8606            enc.len() < 64,
8607            "a consecutive int set of {n} must collapse to a closed-form column, got {} bytes",
8608            enc.len()
8609        );
8610        let mut pos = 0;
8611        match native_decode(&enc, &mut pos).unwrap() {
8612            RuntimeValue::Set(s) => {
8613                let mut got: Vec<i64> = s
8614                    .borrow()
8615                    .iter()
8616                    .map(|v| match v {
8617                        RuntimeValue::Int(k) => *k,
8618                        other => panic!("expected Int, got {other:?}"),
8619                    })
8620                    .collect();
8621                got.sort_unstable();
8622                assert_eq!(got, (1..=n).collect::<Vec<_>>(), "round-trips to the full set");
8623            }
8624            other => panic!("expected a Set, got {other:?}"),
8625        }
8626    }
8627
8628    #[test]
8629    fn int_keyed_map_columnarizes_keys_and_values() {
8630        // The map analog of the int-set crush. A map with CONSECUTIVE integer keys {0..1000} mapping
8631        // to an affine value {i ↦ 2i} (inserted in REVERSE) ships as TWO columns: the keys collapse to
8632        // an affine closed form (base+stride+count, no per-key data) AND the values collapse the same
8633        // way (they reuse the full best-list column menu). So the whole int→int map — 1000 entries —
8634        // becomes a handful of bytes, vs the ~5–6 KB the per-entry `T_MAP` would write (each key AND
8635        // value a tagged inline varint). Must round-trip exactly and be insertion-order-invariant.
8636        let n = 1000i64;
8637        let build = |rev: bool| {
8638            let mut keys: Vec<i64> = (0..n).collect();
8639            if rev {
8640                keys.reverse();
8641            }
8642            let mut m = MapStorage::default();
8643            for k in keys {
8644                m.insert(RuntimeValue::Int(k), RuntimeValue::Int(k * 2));
8645            }
8646            RuntimeValue::Map(Rc::new(RefCell::new(m)))
8647        };
8648
8649        let mut enc = Vec::new();
8650        native_encode(&build(false), &mut enc).unwrap();
8651        assert!(
8652            enc.len() < 64,
8653            "an affine int→int map of {n} entries must collapse BOTH columns to closed forms, got {} bytes",
8654            enc.len()
8655        );
8656
8657        // Canonical: the SAME map built in the opposite insertion order is BYTE-IDENTICAL.
8658        let mut enc_rev = Vec::new();
8659        native_encode(&build(true), &mut enc_rev).unwrap();
8660        assert_eq!(enc, enc_rev, "int-keyed map encoding must be insertion-order-invariant");
8661
8662        // Round-trips exactly.
8663        let mut pos = 0;
8664        match native_decode(&enc, &mut pos).unwrap() {
8665            RuntimeValue::Map(m) => {
8666                let b = m.borrow();
8667                assert_eq!(b.len(), n as usize, "all entries recovered");
8668                for k in 0..n {
8669                    let got = b.get(&RuntimeValue::Int(k)).expect("key present");
8670                    assert_eq!(*got, RuntimeValue::Int(k * 2), "value for key {k} survived");
8671                }
8672            }
8673            other => panic!("expected a Map, got {other:?}"),
8674        }
8675    }
8676
8677    #[test]
8678    fn int_keyed_map_with_non_int_values_still_columnarizes_keys() {
8679        // Keys all Int but values heterogeneous-ish (Text) — the KEY column still collapses; the value
8680        // list takes its own best encoding (here a string column). Must round-trip + stay canonical.
8681        let build = |rev: bool| {
8682            let mut ks: Vec<i64> = vec![10, 20, 30, 40];
8683            if rev {
8684                ks.reverse();
8685            }
8686            let mut m = MapStorage::default();
8687            for k in ks {
8688                m.insert(RuntimeValue::Int(k), RuntimeValue::Text(Rc::new(format!("item_{k}"))));
8689            }
8690            RuntimeValue::Map(Rc::new(RefCell::new(m)))
8691        };
8692        let mut a = Vec::new();
8693        native_encode(&build(false), &mut a).unwrap();
8694        let mut b = Vec::new();
8695        native_encode(&build(true), &mut b).unwrap();
8696        assert_eq!(a, b, "int-keyed map with text values must be insertion-order-invariant");
8697        let mut pos = 0;
8698        match native_decode(&a, &mut pos).unwrap() {
8699            RuntimeValue::Map(m) => {
8700                let mb = m.borrow();
8701                assert_eq!(mb.len(), 4);
8702                for k in [10i64, 20, 30, 40] {
8703                    let got = mb.get(&RuntimeValue::Int(k)).expect("key present");
8704                    assert_eq!(*got, RuntimeValue::Text(Rc::new(format!("item_{k}"))));
8705                }
8706            }
8707            other => panic!("expected a Map, got {other:?}"),
8708        }
8709    }
8710
8711    #[test]
8712    fn int_keyed_map_front_codes_string_value_column() {
8713        // The database-table case: int primary key → string column with shared prefixes (URLs/paths/
8714        // ids). Keys collapse to an affine column; the VALUES front-code in key order (each shipped as
8715        // shared-prefix-len-with-previous + suffix), so a column of `https://…/items/<i>` ships only
8716        // the changing suffix. Must be far smaller than the per-value fallback, round-trip, be canonical.
8717        let n = 100i64;
8718        let build = |rev: bool| {
8719            let mut ks: Vec<i64> = (0..n).collect();
8720            if rev {
8721                ks.reverse();
8722            }
8723            let mut m = MapStorage::default();
8724            for k in ks {
8725                m.insert(
8726                    RuntimeValue::Int(k),
8727                    RuntimeValue::Text(Rc::new(format!("https://example.com/items/{k}"))),
8728                );
8729            }
8730            RuntimeValue::Map(Rc::new(RefCell::new(m)))
8731        };
8732
8733        let mut enc = Vec::new();
8734        native_encode(&build(false), &mut enc).unwrap();
8735        // Per-value (kind 0) would ship ~30 bytes × 100 ≈ 3 KB; front-coding the ~26-char shared prefix
8736        // leaves only the suffix deltas.
8737        assert!(
8738            enc.len() < 1200,
8739            "an int→string map with a shared value prefix must front-code its value column, got {} bytes",
8740            enc.len()
8741        );
8742
8743        let mut enc_rev = Vec::new();
8744        native_encode(&build(true), &mut enc_rev).unwrap();
8745        assert_eq!(enc, enc_rev, "int→string map must be insertion-order-invariant");
8746
8747        let mut pos = 0;
8748        match native_decode(&enc, &mut pos).unwrap() {
8749            RuntimeValue::Map(m) => {
8750                let b = m.borrow();
8751                assert_eq!(b.len(), n as usize);
8752                for k in 0..n {
8753                    let got = b.get(&RuntimeValue::Int(k)).expect("key present");
8754                    assert_eq!(
8755                        *got,
8756                        RuntimeValue::Text(Rc::new(format!("https://example.com/items/{k}"))),
8757                        "value for key {k} survived"
8758                    );
8759                }
8760            }
8761            other => panic!("expected a Map, got {other:?}"),
8762        }
8763    }
8764
8765    #[test]
8766    fn int_keyed_map_columnarizes_struct_value_column() {
8767        // The full database-table crush: int primary key → homogeneous struct record (id/name/active).
8768        // The values pack COLUMNAR like a struct list — the field NAMES ship ONCE, then one column per
8769        // field (the id column compresses, the active column bit-packs) — instead of re-shipping the
8770        // whole self-describing struct per row (the per-value fallback). Must round-trip + be canonical.
8771        let n = 100i64;
8772        let rec = |id: i64| {
8773            let mut f = HashMap::new();
8774            f.insert("id".to_string(), RuntimeValue::Int(id));
8775            f.insert("name".to_string(), RuntimeValue::Text(Rc::new(format!("user_{id}"))));
8776            f.insert("active".to_string(), RuntimeValue::Bool(id % 2 == 0));
8777            RuntimeValue::Struct(Box::new(StructValue { type_name: "Rec".to_string(), fields: f }))
8778        };
8779        let build = |rev: bool| {
8780            let mut ks: Vec<i64> = (0..n).collect();
8781            if rev {
8782                ks.reverse();
8783            }
8784            let mut m = MapStorage::default();
8785            for k in ks {
8786                m.insert(RuntimeValue::Int(k), rec(k));
8787            }
8788            RuntimeValue::Map(Rc::new(RefCell::new(m)))
8789        };
8790
8791        let mut enc = Vec::new();
8792        native_encode(&build(false), &mut enc).unwrap();
8793        // Per-value (kind 0) re-ships "Rec"+"id"+"name"+"active" per row ≈ 27 B × 100 ≈ 2.7 KB; the
8794        // columnar form ships the schema once.
8795        assert!(
8796            enc.len() < 1500,
8797            "an int→struct map must pack its value column columnarly (schema once), got {} bytes",
8798            enc.len()
8799        );
8800
8801        let mut enc_rev = Vec::new();
8802        native_encode(&build(true), &mut enc_rev).unwrap();
8803        assert_eq!(enc, enc_rev, "int→struct map must be insertion-order-invariant");
8804
8805        // Round-trip proof by BYTE-STABILITY (re-encode the decoded value and compare bytes), the
8806        // canonical method in this codec — `RuntimeValue`'s `PartialEq` does not deep-compare struct
8807        // values, so direct `assert_eq!` on a decoded struct is unavailable; byte-identity is strictly
8808        // stronger (any dropped/corrupted field would perturb the re-encoding).
8809        let mut pos = 0;
8810        let decoded = native_decode(&enc, &mut pos).unwrap();
8811        match &decoded {
8812            RuntimeValue::Map(m) => assert_eq!(m.borrow().len(), n as usize, "all rows recovered"),
8813            other => panic!("expected a Map, got {other:?}"),
8814        }
8815        let mut reenc = Vec::new();
8816        native_encode(&decoded, &mut reenc).unwrap();
8817        assert_eq!(reenc, enc, "decoded int→struct map must re-encode byte-identically");
8818    }
8819
8820    #[test]
8821    fn string_set_front_codes_shared_prefixes() {
8822        // Sorted strings share prefixes → front-coding ships only the suffix deltas. A set of strings
8823        // with long common prefixes must be smaller than the naive concat, round-trip exactly, and be
8824        // canonical (insertion-order-invariant).
8825        let words = ["user_1000", "user_1001", "user_1002", "user_1003", "user_2000"];
8826        let mk = |order: &[usize]| {
8827            RuntimeValue::Set(Rc::new(RefCell::new(
8828                order
8829                    .iter()
8830                    .map(|&i| RuntimeValue::Text(Rc::new(words[i].to_string())))
8831                    .collect::<Vec<_>>(),
8832            )))
8833        };
8834        let mut e1 = Vec::new();
8835        native_encode(&mk(&[0, 1, 2, 3, 4]), &mut e1).unwrap();
8836        let mut e2 = Vec::new();
8837        native_encode(&mk(&[4, 2, 0, 3, 1]), &mut e2).unwrap();
8838        assert_eq!(e1, e2, "same string set, different insertion order → identical wire");
8839
8840        let naive: usize = words.iter().map(|w| w.len()).sum();
8841        assert!(
8842            e1.len() < naive,
8843            "front-coding must beat the {naive}-byte naive concat (shared prefixes elided), got {}",
8844            e1.len()
8845        );
8846
8847        let mut pos = 0;
8848        match native_decode(&e1, &mut pos).unwrap() {
8849            RuntimeValue::Set(s) => {
8850                let mut got: Vec<String> = s
8851                    .borrow()
8852                    .iter()
8853                    .map(|v| match v {
8854                        RuntimeValue::Text(t) => (**t).clone(),
8855                        other => panic!("expected Text, got {other:?}"),
8856                    })
8857                    .collect();
8858                got.sort();
8859                let mut want: Vec<String> = words.iter().map(|w| w.to_string()).collect();
8860                want.sort();
8861                assert_eq!(got, want, "round-trips to the same members");
8862            }
8863            other => panic!("expected a Set, got {other:?}"),
8864        }
8865    }
8866
8867    #[test]
8868    fn single_entry_map_roundtrips_exactly() {
8869        let mut m: MapStorage = MapStorage::default();
8870        m.insert(RuntimeValue::Int(1), RuntimeValue::Text(Rc::new("a".to_string())));
8871        let v = RuntimeValue::Map(Rc::new(RefCell::new(m)));
8872        let p = assert_roundtrips(&v);
8873        assert_eq!(p, RtPayload::Map(vec![(RtPayload::Int(1), RtPayload::Text("a".to_string()))]));
8874    }
8875
8876    #[test]
8877    fn multi_entry_map_preserves_entries() {
8878        let mut m: MapStorage = MapStorage::default();
8879        m.insert(RuntimeValue::Int(1), RuntimeValue::Int(10));
8880        m.insert(RuntimeValue::Int(2), RuntimeValue::Int(20));
8881        let v = RuntimeValue::Map(Rc::new(RefCell::new(m)));
8882        let p = materialize(&v).unwrap();
8883        let entries = match &p {
8884            RtPayload::Map(e) => e,
8885            _ => panic!("expected map"),
8886        };
8887        assert_eq!(entries.len(), 2);
8888        assert!(entries.contains(&(RtPayload::Int(1), RtPayload::Int(10))));
8889        assert!(entries.contains(&(RtPayload::Int(2), RtPayload::Int(20))));
8890
8891        // Round-trip preserves the entry set (order may differ — hashmap).
8892        let p2 = materialize(&rebuild(p.clone())).unwrap();
8893        let e2 = match &p2 {
8894            RtPayload::Map(e) => e,
8895            _ => panic!("expected map"),
8896        };
8897        assert_eq!(entries.len(), e2.len());
8898        for e in entries {
8899            assert!(e2.contains(e), "entry {e:?} lost in round-trip");
8900        }
8901    }
8902
8903    #[test]
8904    fn single_field_struct_roundtrips_exactly() {
8905        let mut fields = HashMap::new();
8906        fields.insert("x".to_string(), RuntimeValue::Int(7));
8907        let v = RuntimeValue::Struct(Box::new(StructValue { type_name: "Point".to_string(), fields }));
8908        let p = assert_roundtrips(&v);
8909        assert_eq!(
8910            p,
8911            RtPayload::Struct {
8912                type_name: "Point".to_string(),
8913                fields: vec![("x".to_string(), RtPayload::Int(7))],
8914            }
8915        );
8916    }
8917
8918    #[test]
8919    fn inductive_roundtrips() {
8920        let v = RuntimeValue::Inductive(Box::new(InductiveValue {
8921            inductive_type: "Option".to_string(),
8922            constructor: "Some".to_string(),
8923            args: vec![RuntimeValue::Int(42)],
8924        }));
8925        let p = assert_roundtrips(&v);
8926        assert_eq!(
8927            p,
8928            RtPayload::Inductive {
8929                type_name: "Option".to_string(),
8930                constructor: "Some".to_string(),
8931                args: vec![RtPayload::Int(42)],
8932            }
8933        );
8934    }
8935
8936    #[test]
8937    fn nested_collections_roundtrip() {
8938        let v = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::from_values(vec![
8939            RuntimeValue::Tuple(Rc::new(vec![RuntimeValue::Int(1), RuntimeValue::Bool(true)])),
8940            RuntimeValue::Text(Rc::new("nested".to_string())),
8941        ]))));
8942        assert_roundtrips(&v);
8943    }
8944
8945    // ── Best-of-both-worlds interop: the peer codec (RuntimeValue) and the shared wire core
8946    //    (an AOT-generated-style type) must produce and read the SAME bytes. This is the lock
8947    //    that lets a compile-once native PE receive a program over the real fast codec. ──────
8948    use logicaffeine_data::wire::{self, WireDecode, WireEncode};
8949
8950    // A hand-written mirror of exactly what codegen emits for a `## A CE is one of:` enum.
8951    #[derive(Debug, Clone, PartialEq)]
8952    enum CE {
8953        CInt(i64),
8954        CText(String),
8955        CBool(bool),
8956        CBinOp { op: String, left: Box<CE>, right: Box<CE> },
8957        CList(Vec<CE>),
8958    }
8959    impl WireEncode for CE {
8960        fn wire_encode(&self, out: &mut Vec<u8>) {
8961            match self {
8962                CE::CInt(v) => { wire::write_inductive_header(out, "CE", "CInt", 1); v.wire_encode(out); }
8963                CE::CText(s) => { wire::write_inductive_header(out, "CE", "CText", 1); s.wire_encode(out); }
8964                CE::CBool(b) => { wire::write_inductive_header(out, "CE", "CBool", 1); b.wire_encode(out); }
8965                CE::CBinOp { op, left, right } => {
8966                    wire::write_inductive_header(out, "CE", "CBinOp", 3);
8967                    op.wire_encode(out);
8968                    left.wire_encode(out);
8969                    right.wire_encode(out);
8970                }
8971                CE::CList(xs) => { wire::write_inductive_header(out, "CE", "CList", 1); xs.wire_encode(out); }
8972            }
8973        }
8974    }
8975    impl WireDecode for CE {
8976        fn wire_decode(buf: &[u8], pos: &mut usize) -> Option<Self> {
8977            let (ty, ctor, _n) = wire::read_inductive_header(buf, pos)?;
8978            debug_assert_eq!(ty, "CE");
8979            Some(match ctor.as_str() {
8980                "CInt" => CE::CInt(i64::wire_decode(buf, pos)?),
8981                "CText" => CE::CText(String::wire_decode(buf, pos)?),
8982                "CBool" => CE::CBool(bool::wire_decode(buf, pos)?),
8983                "CBinOp" => CE::CBinOp {
8984                    op: String::wire_decode(buf, pos)?,
8985                    left: Box::<CE>::wire_decode(buf, pos)?,
8986                    right: Box::<CE>::wire_decode(buf, pos)?,
8987                },
8988                "CList" => CE::CList(Vec::<CE>::wire_decode(buf, pos)?),
8989                _ => return None,
8990            })
8991        }
8992    }
8993
8994    // The same logical program in both value models.
8995    fn ce_tree() -> CE {
8996        CE::CBinOp {
8997            op: "+".to_string(),
8998            left: Box::new(CE::CInt(2)),
8999            right: Box::new(CE::CList(vec![CE::CInt(3), CE::CBool(true), CE::CText("hi".to_string())])),
9000        }
9001    }
9002    fn rt_ind(ty: &str, ctor: &str, args: Vec<RuntimeValue>) -> RuntimeValue {
9003        RuntimeValue::Inductive(Box::new(InductiveValue {
9004            inductive_type: ty.to_string(),
9005            constructor: ctor.to_string(),
9006            args,
9007        }))
9008    }
9009    fn rt_tree() -> RuntimeValue {
9010        rt_ind("CE", "CBinOp", vec![
9011            RuntimeValue::Text(Rc::new("+".to_string())),
9012            rt_ind("CE", "CInt", vec![RuntimeValue::Int(2)]),
9013            rt_ind("CE", "CList", vec![RuntimeValue::List(Rc::new(RefCell::new(ListRepr::from_values(vec![
9014                rt_ind("CE", "CInt", vec![RuntimeValue::Int(3)]),
9015                rt_ind("CE", "CBool", vec![RuntimeValue::Bool(true)]),
9016                rt_ind("CE", "CText", vec![RuntimeValue::Text(Rc::new("hi".to_string()))]),
9017            ]))))]),
9018        ])
9019    }
9020
9021    #[test]
9022    fn peer_and_wire_core_produce_identical_bytes() {
9023        let peer_bytes = encode_value_raw(&rt_tree()).expect("peer encode");
9024        let mut wire_bytes = Vec::new();
9025        ce_tree().wire_encode(&mut wire_bytes);
9026        assert_eq!(
9027            peer_bytes, wire_bytes,
9028            "the shared wire core must be byte-identical to the peer codec"
9029        );
9030    }
9031
9032    #[test]
9033    fn peer_encode_then_wire_decode_reconstructs_the_generated_type() {
9034        // The exact path a compile-once native PE uses: host peer-encodes, native wire-decodes.
9035        let bytes = encode_value_raw(&rt_tree()).expect("peer encode");
9036        let mut pos = 0usize;
9037        let decoded = CE::wire_decode(&bytes, &mut pos).expect("wire decode");
9038        assert_eq!(pos, bytes.len(), "must consume every byte");
9039        assert_eq!(decoded, ce_tree());
9040    }
9041
9042    #[test]
9043    fn wire_encode_then_peer_decode_reconstructs_the_runtime_value() {
9044        // The reverse direction: native wire-encodes, host peer-decodes.
9045        let mut bytes = Vec::new();
9046        ce_tree().wire_encode(&mut bytes);
9047        let rv = decode_value_raw(&bytes).expect("peer decode");
9048        assert_eq!(materialize(&rv).unwrap(), materialize(&rt_tree()).unwrap());
9049    }
9050
9051    #[test]
9052    fn function_is_not_sendable() {
9053        let v = RuntimeValue::Function(Box::new(ClosureValue {
9054            body_index: 0,
9055            captured_env: HashMap::default(),
9056            param_names: vec![],
9057            generated: None,
9058        }));
9059        assert_eq!(materialize(&v), Err(MarshalError::NotSendable("Function")));
9060    }
9061
9062    // -------------------------------------------------------------------------
9063    // Wire codec — a message is any language value
9064    // -------------------------------------------------------------------------
9065
9066    /// A value survives the wire iff its `RtPayload` is unchanged across
9067    /// encode→decode (we compare through `RtPayload`, which has structural eq).
9068    fn assert_wire_roundtrips(v: &RuntimeValue, from: &str) {
9069        let bytes = message_to_wire(from, v).expect("message_to_wire");
9070        let (got_from, back) = message_from_wire(&bytes).expect("message_from_wire");
9071        assert_eq!(got_from, from, "sender lost on the wire");
9072        assert_eq!(
9073            materialize(v).expect("before"),
9074            materialize(&back).expect("after"),
9075            "wire round-trip changed the value"
9076        );
9077    }
9078
9079    #[test]
9080    fn message_wire_scalars_roundtrip() {
9081        for v in [
9082            RuntimeValue::Int(42),
9083            RuntimeValue::Float(2.5),
9084            RuntimeValue::Bool(true),
9085            RuntimeValue::Char('z'),
9086            RuntimeValue::Text(Rc::new("ping".to_string())),
9087            RuntimeValue::Nothing,
9088            RuntimeValue::Duration(1000),
9089        ] {
9090            assert_wire_roundtrips(&v, "alice");
9091        }
9092    }
9093
9094    #[test]
9095    fn message_wire_is_compact_binary() {
9096        // A 100-element int list encodes to compact binary (a few bytes/element),
9097        // far tighter than a text encoding, and round-trips exactly.
9098        let items: Vec<RuntimeValue> = (0..100).map(RuntimeValue::Int).collect();
9099        let v = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::from_values(items))));
9100        let bytes = message_to_wire("", &v).unwrap();
9101        assert!(bytes.len() < 100 * 12, "wire should be compact, was {} bytes", bytes.len());
9102        assert_wire_roundtrips(&v, "");
9103    }
9104
9105    #[test]
9106    fn message_wire_anonymous_sender_is_empty_from() {
9107        let bytes = message_to_wire("", &RuntimeValue::Int(1)).unwrap();
9108        let (from, _) = message_from_wire(&bytes).unwrap();
9109        assert_eq!(from, "");
9110    }
9111
9112    #[test]
9113    fn message_wire_list_and_tuple_and_set_roundtrip() {
9114        let list = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::from_values(vec![
9115            RuntimeValue::Int(1),
9116            RuntimeValue::Text(Rc::new("two".to_string())),
9117            RuntimeValue::Bool(true),
9118        ]))));
9119        assert_wire_roundtrips(&list, "");
9120
9121        let tup = RuntimeValue::Tuple(Rc::new(vec![RuntimeValue::Int(1), RuntimeValue::Char('q')]));
9122        assert_wire_roundtrips(&tup, "");
9123
9124        let set = RuntimeValue::Set(Rc::new(RefCell::new(vec![RuntimeValue::Int(7), RuntimeValue::Int(8)])));
9125        assert_wire_roundtrips(&set, "");
9126    }
9127
9128    #[test]
9129    fn message_wire_single_entry_map_roundtrips() {
9130        let mut m: MapStorage = MapStorage::default();
9131        m.insert(RuntimeValue::Text(Rc::new("k".to_string())), RuntimeValue::Int(9));
9132        let v = RuntimeValue::Map(Rc::new(RefCell::new(m)));
9133        assert_wire_roundtrips(&v, "");
9134    }
9135
9136    #[test]
9137    fn message_wire_struct_roundtrips_by_field() {
9138        let mut fields = HashMap::new();
9139        fields.insert("x".to_string(), RuntimeValue::Int(1));
9140        fields.insert("y".to_string(), RuntimeValue::Int(2));
9141        let v = RuntimeValue::Struct(Box::new(StructValue { type_name: "Point".to_string(), fields }));
9142        let bytes = message_to_wire("alice", &v).unwrap();
9143        let (_from, back) = message_from_wire(&bytes).unwrap();
9144        match back {
9145            RuntimeValue::Struct(s) => {
9146                assert_eq!(s.type_name, "Point");
9147                assert_eq!(s.fields.get("x"), Some(&RuntimeValue::Int(1)));
9148                assert_eq!(s.fields.get("y"), Some(&RuntimeValue::Int(2)));
9149            }
9150            other => panic!("expected a struct, got {other:?}"),
9151        }
9152    }
9153
9154    #[test]
9155    fn message_wire_inductive_roundtrips() {
9156        let v = RuntimeValue::Inductive(Box::new(InductiveValue {
9157            inductive_type: "Option".to_string(),
9158            constructor: "Some".to_string(),
9159            args: vec![RuntimeValue::Int(42)],
9160        }));
9161        assert_wire_roundtrips(&v, "");
9162    }
9163
9164    #[test]
9165    fn message_wire_nested_list_of_structs_roundtrips() {
9166        let mut fields = HashMap::new();
9167        fields.insert("n".to_string(), RuntimeValue::Int(1));
9168        let s = RuntimeValue::Struct(Box::new(StructValue { type_name: "Item".to_string(), fields }));
9169        let v = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::from_values(vec![
9170            s,
9171            RuntimeValue::Tuple(Rc::new(vec![RuntimeValue::Int(3), RuntimeValue::Bool(false)])),
9172        ]))));
9173        assert_wire_roundtrips(&v, "carol");
9174    }
9175
9176    #[test]
9177    fn message_wire_channel_handle_is_not_network_portable() {
9178        // A channel id is local to this process's scheduler — it cannot travel.
9179        let v = RuntimeValue::Chan(logicaffeine_runtime::ChanId(3));
9180        let err = message_to_wire("", &v).expect_err("a channel must not be sendable over the network");
9181        assert!(err.contains("channel") || err.contains("task"), "got: {err}");
9182    }
9183
9184    #[test]
9185    fn message_wire_function_is_rejected_with_a_clear_error() {
9186        let v = RuntimeValue::Function(Box::new(ClosureValue {
9187            body_index: 0,
9188            captured_env: HashMap::default(),
9189            param_names: vec![],
9190            generated: None,
9191        }));
9192        let err = message_to_wire("", &v).expect_err("a closure must not be sendable");
9193        assert!(err.contains("Function"), "got: {err}");
9194    }
9195
9196    #[test]
9197    fn message_wire_malformed_bytes_decode_to_none() {
9198        assert!(message_from_wire(b"").is_none()); // empty
9199        assert!(message_from_wire(b"\xff\xff\xff\xff garbage").is_none()); // not a valid frame
9200        // A truncated-but-plausible prefix of a real message must not panic.
9201        let good = message_to_wire("alice", &RuntimeValue::Text(Rc::new("hi".to_string()))).unwrap();
9202        assert!(message_from_wire(&good[..good.len() / 2]).is_none());
9203    }
9204
9205    // =========================================================================
9206    // Codec hardening — fidelity, canonicality, integrity, speed, to the point
9207    // of absurdity.
9208    // =========================================================================
9209
9210    /// A round-trip is byte-stable: encode → decode → re-encode yields identical
9211    /// bytes. This proves the value reconstructed EXACTLY (bit-for-bit — floats,
9212    /// NaN, `-0.0` and all, since we compare bytes not `PartialEq`), that encoding
9213    /// is deterministic, and that structs/maps are canonical (hash order can't
9214    /// leak in). It's the workhorse assertion for the property fuzzer.
9215    fn assert_wire_stable(v: &RuntimeValue) {
9216        let once = message_to_wire("peer", v).expect("encode");
9217        let (from, back) = message_from_wire(&once).expect("decode");
9218        assert_eq!(from, "peer", "sender lost");
9219        let twice = message_to_wire("peer", &back).expect("re-encode");
9220        assert_eq!(once, twice, "round-trip was not byte-stable for {v:?}");
9221    }
9222
9223    #[test]
9224    fn wire_boundary_ints_roundtrip() {
9225        for n in [0i64, 1, -1, i64::MIN, i64::MAX, i64::MIN + 1, i64::MAX - 1, i32::MIN as i64, i32::MAX as i64] {
9226            assert_wire_stable(&RuntimeValue::Int(n));
9227        }
9228    }
9229
9230    #[test]
9231    fn wire_special_floats_roundtrip_bit_exact() {
9232        for f in [
9233            0.0f64, -0.0, 1.0, -1.0, f64::INFINITY, f64::NEG_INFINITY, f64::NAN,
9234            f64::MIN, f64::MAX, f64::MIN_POSITIVE, 1e-308, -1e308, std::f64::consts::PI,
9235        ] {
9236            let bytes = message_to_wire("", &RuntimeValue::Float(f)).unwrap();
9237            let (_, back) = message_from_wire(&bytes).unwrap();
9238            let RuntimeValue::Float(g) = back else { panic!("not a float") };
9239            assert_eq!(f.to_bits(), g.to_bits(), "float {f} lost bits");
9240        }
9241    }
9242
9243    #[test]
9244    fn wire_unicode_text_and_char_roundtrip() {
9245        for s in ["", "ascii", "héllo", "日本語", "emoji 😀🎉", "null\0byte", "tabs\tand\nnewlines"] {
9246            assert_wire_stable(&RuntimeValue::Text(Rc::new(s.to_string())));
9247        }
9248        for c in ['a', '\0', '😀', '\u{10FFFF}', 'λ', '\n', '\u{1}'] {
9249            assert_wire_stable(&RuntimeValue::Char(c));
9250        }
9251    }
9252
9253    #[test]
9254    fn wire_empty_collections_roundtrip() {
9255        assert_wire_stable(&RuntimeValue::List(Rc::new(RefCell::new(ListRepr::from_values(vec![])))));
9256        assert_wire_stable(&RuntimeValue::Tuple(Rc::new(vec![])));
9257        assert_wire_stable(&RuntimeValue::Set(Rc::new(RefCell::new(vec![]))));
9258        assert_wire_stable(&RuntimeValue::Map(Rc::new(RefCell::new(MapStorage::default()))));
9259        assert_wire_stable(&RuntimeValue::Struct(Box::new(StructValue {
9260            type_name: "Empty".to_string(),
9261            fields: HashMap::new(),
9262        })));
9263        assert_wire_stable(&RuntimeValue::Inductive(Box::new(InductiveValue {
9264            inductive_type: "Unit".to_string(),
9265            constructor: "Unit".to_string(),
9266            args: vec![],
9267        })));
9268    }
9269
9270    #[test]
9271    fn wire_temporal_and_misc_scalars_roundtrip() {
9272        for v in [
9273            RuntimeValue::Nothing,
9274            RuntimeValue::Bool(true),
9275            RuntimeValue::Bool(false),
9276            RuntimeValue::Duration(i64::MAX),
9277            RuntimeValue::Date(i32::MIN),
9278            RuntimeValue::Moment(-1),
9279            RuntimeValue::Span { months: i32::MAX, days: i32::MIN },
9280            RuntimeValue::Time(0),
9281            RuntimeValue::Peer(Rc::new("ws://host:9944".to_string())),
9282        ] {
9283            assert_wire_stable(&v);
9284        }
9285    }
9286
9287    #[test]
9288    fn wire_struct_field_order_is_canonical() {
9289        // The same fields in a different insertion order encode to the SAME bytes.
9290        let mut a = HashMap::new();
9291        a.insert("z".to_string(), RuntimeValue::Int(1));
9292        a.insert("a".to_string(), RuntimeValue::Int(2));
9293        a.insert("m".to_string(), RuntimeValue::Int(3));
9294        let mut b = HashMap::new();
9295        b.insert("m".to_string(), RuntimeValue::Int(3));
9296        b.insert("z".to_string(), RuntimeValue::Int(1));
9297        b.insert("a".to_string(), RuntimeValue::Int(2));
9298        let va = RuntimeValue::Struct(Box::new(StructValue { type_name: "S".into(), fields: a }));
9299        let vb = RuntimeValue::Struct(Box::new(StructValue { type_name: "S".into(), fields: b }));
9300        assert_eq!(
9301            message_to_wire("x", &va).unwrap(),
9302            message_to_wire("x", &vb).unwrap(),
9303            "struct encoding must be canonical (field order independent)"
9304        );
9305    }
9306
9307    #[test]
9308    fn wire_map_entry_order_is_canonical() {
9309        let mut a = MapStorage::default();
9310        a.insert(RuntimeValue::Int(3), RuntimeValue::Int(30));
9311        a.insert(RuntimeValue::Int(1), RuntimeValue::Int(10));
9312        a.insert(RuntimeValue::Int(2), RuntimeValue::Int(20));
9313        let mut b = MapStorage::default();
9314        b.insert(RuntimeValue::Int(1), RuntimeValue::Int(10));
9315        b.insert(RuntimeValue::Int(2), RuntimeValue::Int(20));
9316        b.insert(RuntimeValue::Int(3), RuntimeValue::Int(30));
9317        let va = RuntimeValue::Map(Rc::new(RefCell::new(a)));
9318        let vb = RuntimeValue::Map(Rc::new(RefCell::new(b)));
9319        assert_eq!(
9320            message_to_wire("x", &va).unwrap(),
9321            message_to_wire("x", &vb).unwrap(),
9322            "map encoding must be canonical (entry order independent)"
9323        );
9324    }
9325
9326    #[test]
9327    fn wire_rejects_nonportable_buried_in_a_container() {
9328        // A channel buried in a list — caught, with a clear error, never dropped.
9329        let in_list = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::from_values(vec![
9330            RuntimeValue::Int(1),
9331            RuntimeValue::Chan(logicaffeine_runtime::ChanId(5)),
9332        ]))));
9333        let err = message_to_wire("", &in_list).expect_err("buried channel must be rejected");
9334        assert!(err.contains("channel") || err.contains("task"), "got: {err}");
9335
9336        // A task handle buried in a map value.
9337        let mut m = MapStorage::default();
9338        m.insert(RuntimeValue::Int(1), RuntimeValue::TaskHandle(logicaffeine_runtime::TaskId(7)));
9339        let in_map = RuntimeValue::Map(Rc::new(RefCell::new(m)));
9340        assert!(message_to_wire("", &in_map).is_err(), "buried task handle must be rejected");
9341
9342        // A closure buried in a struct field.
9343        let mut fields = HashMap::new();
9344        fields.insert(
9345            "f".to_string(),
9346            RuntimeValue::Function(Box::new(ClosureValue {
9347                body_index: 0,
9348                captured_env: HashMap::default(),
9349                param_names: vec![],
9350                generated: None,
9351            })),
9352        );
9353        let in_struct = RuntimeValue::Struct(Box::new(StructValue { type_name: "Holder".into(), fields }));
9354        let err = message_to_wire("", &in_struct).expect_err("buried closure must be rejected");
9355        assert!(err.contains("Function"), "got: {err}");
9356    }
9357
9358    #[test]
9359    fn wire_checked_detects_corruption() {
9360        let v = RuntimeValue::Text(Rc::new("important".to_string()));
9361        let good = message_to_wire_with("a", &v, WireCodec::Native, WireIntegrity::Checked).unwrap();
9362        assert!(message_from_wire(&good).is_some(), "intact checked message decodes");
9363        // Flip the final payload byte — the checksum must catch it.
9364        let mut bad = good.clone();
9365        *bad.last_mut().unwrap() ^= 0xFF;
9366        assert!(message_from_wire(&bad).is_none(), "corruption must be rejected");
9367        // Flip a checksum byte too.
9368        let mut bad2 = good;
9369        bad2[1] ^= 0xFF;
9370        assert!(message_from_wire(&bad2).is_none(), "a mangled checksum must be rejected");
9371    }
9372
9373    #[test]
9374    fn wire_raw_skips_the_checksum_for_speed() {
9375        let v = RuntimeValue::Int(7);
9376        let raw = message_to_wire_with("", &v, WireCodec::Native, WireIntegrity::Raw).unwrap();
9377        let checked = message_to_wire_with("", &v, WireCodec::Native, WireIntegrity::Checked).unwrap();
9378        assert_eq!(checked.len(), raw.len() + 8, "checked adds exactly the 8-byte checksum");
9379        assert_eq!(message_from_wire(&raw).unwrap().1, RuntimeValue::Int(7));
9380        // A flipped byte in a RAW message is NOT caught (no integrity) — it just
9381        // decodes to whatever it decodes to, or fails to decode; either way no panic.
9382        let mut tampered = raw;
9383        *tampered.last_mut().unwrap() ^= 0x01;
9384        let _ = message_from_wire(&tampered);
9385    }
9386
9387    #[test]
9388    fn wire_all_codec_and_integrity_modes_interoperate() {
9389        let v = RuntimeValue::Text(Rc::new("hello".to_string()));
9390        for codec in [WireCodec::Native, WireCodec::Json] {
9391            for integrity in [WireIntegrity::Raw, WireIntegrity::Checked] {
9392                let bytes = message_to_wire_with("s", &v, codec, integrity).unwrap();
9393                let (from, back) = message_from_wire(&bytes).expect("decodes any mode");
9394                assert_eq!(from, "s");
9395                assert_eq!(back, v, "{codec:?}/{integrity:?} did not round-trip");
9396            }
9397        }
9398    }
9399
9400    #[test]
9401    fn wire_compression_shrinks_redundant_payloads_and_roundtrips() {
9402        // A big redundant payload (the same string 500×) compresses hard.
9403        let v = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Boxed(
9404            (0..500).map(|_| RuntimeValue::Text(Rc::new("the same repeated string".to_string()))).collect(),
9405        ))));
9406        let plain = message_to_wire("", &v).unwrap();
9407        let zipped = with_compression(|| message_to_wire("", &v).unwrap());
9408        assert!(zipped.len() * 2 < plain.len(), "redundant data should compress: {} vs {}", zipped.len(), plain.len());
9409        // …and inflates transparently on the way back in.
9410        let count = |b: &[u8]| match message_from_wire(b).unwrap().1 {
9411            RuntimeValue::List(l) => l.borrow().len(),
9412            other => panic!("expected a list, got {other:?}"),
9413        };
9414        assert_eq!(count(&zipped), 500);
9415        assert_eq!(count(&plain), 500);
9416    }
9417
9418    #[test]
9419    fn wire_compression_never_grows_a_message() {
9420        // A tiny / already-compact value: compression wouldn't help, so it's shipped
9421        // RAW ("keep only if it shrank") — never bigger, never a panic.
9422        let v = RuntimeValue::Int(42);
9423        let plain = message_to_wire("", &v).unwrap();
9424        let maybe = with_compression(|| message_to_wire("", &v).unwrap());
9425        assert!(maybe.len() <= plain.len(), "compression must never grow a message");
9426        assert_eq!(message_from_wire(&maybe).unwrap().1, RuntimeValue::Int(42));
9427    }
9428
9429    #[test]
9430    fn wire_compressed_message_integrity_is_checked_before_inflate() {
9431        let v = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Boxed(
9432            (0..500).map(|_| RuntimeValue::Text(Rc::new("redundant".to_string()))).collect(),
9433        ))));
9434        let mut zipped =
9435            with_compression(|| message_to_wire_with("", &v, WireCodec::Native, WireIntegrity::Checked)).unwrap();
9436        assert!(message_from_wire(&zipped).is_some(), "intact compressed message decodes");
9437        // Corrupt a compressed byte: the checksum (over the compressed bytes) rejects
9438        // it BEFORE we ever try to inflate — a clean None, no decompressor panic.
9439        *zipped.last_mut().unwrap() ^= 0xFF;
9440        assert!(message_from_wire(&zipped).is_none(), "corruption of a compressed message must be rejected");
9441    }
9442
9443    fn redundant_list(n: usize) -> RuntimeValue {
9444        RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Boxed(
9445            (0..n).map(|_| RuntimeValue::Text(Rc::new("the same repeated string value".to_string()))).collect(),
9446        ))))
9447    }
9448    fn count_list(v: &RuntimeValue) -> usize {
9449        match v {
9450            RuntimeValue::List(l) => l.borrow().len(),
9451            other => panic!("expected a list, got {other:?}"),
9452        }
9453    }
9454
9455    #[test]
9456    fn wire_lz4_roundtrips_and_shrinks_redundant() {
9457        let v = redundant_list(500);
9458        let plain = message_to_wire("", &v).unwrap();
9459        let lz = with_compression_codec(WireCompression::Lz4, || message_to_wire("", &v).unwrap());
9460        assert!(lz.len() < plain.len(), "lz4 should shrink redundant data: {} vs {}", lz.len(), plain.len());
9461        // Self-describing: the header records the codec, so decode auto-detects it.
9462        assert_eq!(count_list(&message_from_wire(&lz).unwrap().1), 500);
9463    }
9464
9465    #[test]
9466    fn wire_compression_codec_is_self_describing() {
9467        // Deflate + lz4 ship everywhere (pure-Rust). Each is auto-detected on decode
9468        // with no out-of-band hint — the header byte carries the codec id.
9469        let v = redundant_list(300);
9470        for c in [WireCompression::Deflate, WireCompression::Lz4] {
9471            let bytes = with_compression_codec(c, || message_to_wire("", &v).unwrap());
9472            assert_eq!(count_list(&message_from_wire(&bytes).unwrap().1), 300, "codec {c:?} self-describes");
9473            let (_, comp, _) = unframe(&bytes).unwrap();
9474            assert_eq!(comp, c, "header round-trips the codec id for {c:?}");
9475        }
9476    }
9477
9478    #[test]
9479    fn wire_old_deflate_bytes_still_decode() {
9480        // Back-compat: a message framed the OLD way (H_COMPRESSED set, codec bits 0 =
9481        // deflate) must still decode after the 2-bit codec field was added.
9482        let v = redundant_list(200);
9483        let body = {
9484            let mut out = Vec::new();
9485            write_str("", &mut out);
9486            native_encode(&v, &mut out).unwrap();
9487            miniz_oxide::deflate::compress_to_vec(&out, 6)
9488        };
9489        let mut legacy = vec![H_COMPRESSED]; // legacy header: no codec bits
9490        legacy.extend_from_slice(&body);
9491        assert_eq!(count_list(&message_from_wire(&legacy).unwrap().1), 200);
9492    }
9493
9494    #[cfg(not(target_arch = "wasm32"))]
9495    #[test]
9496    fn wire_zstd_roundtrips_native_and_is_self_describing() {
9497        let v = redundant_list(500);
9498        let plain = message_to_wire("", &v).unwrap();
9499        let z = with_compression_codec(WireCompression::Zstd, || message_to_wire("", &v).unwrap());
9500        assert!(z.len() < plain.len(), "zstd should shrink redundant data: {} vs {}", z.len(), plain.len());
9501        assert_eq!(count_list(&message_from_wire(&z).unwrap().1), 500);
9502        let (_, comp, _) = unframe(&z).unwrap();
9503        assert_eq!(comp, WireCompression::Zstd, "header records zstd");
9504    }
9505
9506    #[cfg(not(target_arch = "wasm32"))]
9507    #[test]
9508    fn wire_zstd_decodes_via_ruzstd_parity() {
9509        // The native C zstd encoder writes a standard frame; the pure-Rust ruzstd
9510        // decoder (the browser's decode path) must inflate it byte-identically — so a
9511        // native-sent zstd message is decodable by a wasm peer.
9512        let v = redundant_list(500);
9513        let z = with_compression_codec(WireCompression::Zstd, || message_to_wire("", &v).unwrap());
9514        let (_codec, comp, body) = unframe(&z).expect("unframe");
9515        assert_eq!(comp, WireCompression::Zstd);
9516        let via_c = zstd::decode_all(body).expect("C zstd decode");
9517        let via_ruzstd = zstd_decode_ruzstd(body).expect("ruzstd decode");
9518        assert_eq!(via_c, via_ruzstd, "ruzstd must match C zstd byte-for-byte");
9519    }
9520
9521    #[cfg(not(target_arch = "wasm32"))]
9522    #[test]
9523    fn wire_compression_level_dial_trades_size_and_roundtrips() {
9524        // A moderately-compressible payload so the effort level actually moves the
9525        // size. Max ≤ Balanced ≤ Fast in bytes; every level decodes exactly.
9526        let v = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Boxed(
9527            (0..2000).map(|i| RuntimeValue::Text(Rc::new(format!("event-{i}-status-{}", i % 37)))).collect(),
9528        ))));
9529        let at = |lvl| {
9530            with_compression_level(lvl, || with_compression_codec(WireCompression::Zstd, || message_to_wire("", &v).unwrap()))
9531        };
9532        let fast = at(WireCompressionLevel::Fast);
9533        let bal = at(WireCompressionLevel::Balanced);
9534        let max = at(WireCompressionLevel::Max);
9535        assert!(max.len() <= bal.len() && bal.len() <= fast.len(), "max {} ≤ bal {} ≤ fast {}", max.len(), bal.len(), fast.len());
9536        for b in [&fast, &bal, &max] {
9537            assert!(message_from_wire(b).is_some(), "every level decodes");
9538        }
9539        // The level is a sender-only preference — it never leaks past the scope.
9540        let default = with_compression_codec(WireCompression::Zstd, || message_to_wire("", &v).unwrap());
9541        assert_eq!(default.len(), bal.len(), "default level is Balanced");
9542    }
9543
9544    #[cfg(not(target_arch = "wasm32"))]
9545    #[test]
9546    fn wire_zstd_ratio_beats_deflate_on_redundant() {
9547        let v = redundant_list(1000);
9548        let d = with_compression_codec(WireCompression::Deflate, || message_to_wire("", &v).unwrap());
9549        let z = with_compression_codec(WireCompression::Zstd, || message_to_wire("", &v).unwrap());
9550        assert!(z.len() <= d.len(), "zstd should match or beat deflate: zstd {} vs deflate {}", z.len(), d.len());
9551    }
9552
9553    fn point(x: i64, y: i64) -> RuntimeValue {
9554        let mut f = HashMap::new();
9555        f.insert("x".to_string(), RuntimeValue::Int(x));
9556        f.insert("y".to_string(), RuntimeValue::Int(y));
9557        RuntimeValue::Struct(Box::new(StructValue { type_name: "Point".to_string(), fields: f }))
9558    }
9559    fn struct_list(n: i64) -> RuntimeValue {
9560        RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Boxed((0..n).map(|i| point(i, i * 2)).collect()))))
9561    }
9562    fn enum_val(ty: &str, ctor: &str, args: Vec<RuntimeValue>) -> RuntimeValue {
9563        RuntimeValue::Inductive(Box::new(InductiveValue {
9564            inductive_type: ty.to_string(),
9565            constructor: ctor.to_string(),
9566            args,
9567        }))
9568    }
9569
9570    /// Encode `v` (asserting its top tag), decode it, then re-encode the decoded
9571    /// value and assert byte-equality. Encoding is canonical (fields sorted), so this
9572    /// proves "decodes to the exact rows" deterministically — unlike comparing
9573    /// `materialize` output, whose struct field order is per-HashMap random.
9574    fn assert_columnar_roundtrip(v: &RuntimeValue, expect_tag: u8) {
9575        let mut buf = Vec::new();
9576        native_encode(v, &mut buf).unwrap();
9577        assert_eq!(buf[0], expect_tag, "top wire tag");
9578        let mut pos = 0;
9579        let back = native_decode(&buf, &mut pos).unwrap();
9580        assert_eq!(pos, buf.len(), "decode consumes the whole buffer");
9581        let mut buf2 = Vec::new();
9582        native_encode(&back, &mut buf2).unwrap();
9583        assert_eq!(buf2, buf, "re-encode of the decoded value is byte-identical (exact rows, canonical)");
9584    }
9585
9586    #[test]
9587    fn wire_homogeneous_struct_list_packs_columnar() {
9588        assert_columnar_roundtrip(&struct_list(1000), T_STRUCTS);
9589    }
9590
9591    #[test]
9592    fn wire_columnar_struct_list_is_far_smaller_than_boxed() {
9593        // The old boxed path re-emitted "Point"/"x"/"y" strings on EVERY row
9594        // (~16 B/row ⇒ ~16 KB for 1000). Columnar writes the schema once + two packed
9595        // int columns ⇒ a few KB. A threshold cleanly between the two regimes.
9596        let mut buf = Vec::new();
9597        native_encode(&struct_list(1000), &mut buf).unwrap();
9598        assert!(buf.len() < 6000, "columnar 1000×Point should be well under boxed's ~16 KB, was {}", buf.len());
9599    }
9600
9601    #[test]
9602    fn wire_columnar_int_field_is_memcpy_under_fixed() {
9603        // Columnar fields honor the numeric dial: under Fixed, each int column is raw
9604        // 8-byte i64 (memcpy) — wider than varint. Boxed structs ignored the dial, so
9605        // this size difference is exactly what proves the fields pack as columns.
9606        let v = struct_list(200);
9607        let varint = {
9608            let mut b = Vec::new();
9609            native_encode(&v, &mut b).unwrap();
9610            b
9611        };
9612        let fixed = {
9613            let mut b = Vec::new();
9614            with_fixed_numerics(|| native_encode(&v, &mut b).unwrap());
9615            b
9616        };
9617        assert_eq!(varint[0], T_STRUCTS);
9618        assert_eq!(fixed[0], T_STRUCTS);
9619        assert!(fixed.len() > varint.len(), "fixed int columns are memcpy-wide: fixed {} vs varint {}", fixed.len(), varint.len());
9620        // The fixed encoding decodes and re-encodes (under fixed) byte-identically.
9621        let mut pos = 0;
9622        let back = native_decode(&fixed, &mut pos).unwrap();
9623        let mut re = Vec::new();
9624        with_fixed_numerics(|| native_encode(&back, &mut re).unwrap());
9625        assert_eq!(re, fixed, "fixed columnar decodes to the exact rows");
9626    }
9627
9628    #[test]
9629    fn wire_ragged_struct_list_falls_back_to_boxed() {
9630        // Different field sets ⇒ not homogeneous ⇒ the generic per-element path.
9631        let a = point(1, 2);
9632        let mut bf = HashMap::new();
9633        bf.insert("x".to_string(), RuntimeValue::Int(3)); // no "y"
9634        let b = RuntimeValue::Struct(Box::new(StructValue { type_name: "Point".to_string(), fields: bf }));
9635        let v = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Boxed(vec![a, b]))));
9636        assert_columnar_roundtrip(&v, T_LIST); // ragged struct list stays boxed
9637    }
9638
9639    #[test]
9640    fn wire_columnar_struct_roundtrip_is_byte_stable() {
9641        assert_wire_stable(&struct_list(50));
9642    }
9643
9644    #[test]
9645    fn wire_in_memory_columnar_structs_encode_identically_to_boxed() {
9646        // A `from_values`-built Structs repr (in-memory columns) and a hand-built
9647        // Boxed struct list with the same rows must encode to byte-identical wire —
9648        // the in-memory columns stream out exactly as the boxed path would gather them.
9649        let rows: Vec<RuntimeValue> = (0..100).map(|i| point(i, i * 2)).collect();
9650        let repr = ListRepr::from_values(rows.clone());
9651        assert!(matches!(repr, ListRepr::Structs { .. }), "from_values de-boxes a struct list to columns");
9652        let columnar = RuntimeValue::List(Rc::new(RefCell::new(repr)));
9653        let boxed = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Boxed(rows))));
9654        assert_eq!(
9655            message_to_wire("p", &columnar).unwrap(),
9656            message_to_wire("p", &boxed).unwrap(),
9657            "in-memory columns encode byte-identically to the boxed columnar path"
9658        );
9659    }
9660
9661    #[test]
9662    fn wire_struct_list_decodes_to_columnar_repr() {
9663        // A received struct list decodes DIRECTLY into the columnar in-memory repr —
9664        // no per-row `StructValue` rebuild (the receive-throughput win).
9665        let bytes = message_to_wire("p", &struct_list(100)).unwrap();
9666        match message_from_wire(&bytes).unwrap().1 {
9667            RuntimeValue::List(l) => {
9668                assert!(matches!(&*l.borrow(), ListRepr::Structs { .. }), "decodes to the columnar Structs repr");
9669                assert_eq!(l.borrow().len(), 100);
9670            }
9671            other => panic!("expected a list, got {other:?}"),
9672        }
9673    }
9674
9675    #[test]
9676    fn wire_nullary_enum_list_packs_dictionary() {
9677        let names = ["Red", "Green", "Blue"];
9678        let v = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Boxed(
9679            (0..900).map(|i| enum_val("Color", names[i % 3], vec![])).collect(),
9680        ))));
9681        let mut buf = Vec::new();
9682        native_encode(&v, &mut buf).unwrap();
9683        assert!(buf.len() < 1200, "dictionaried enum list should be tiny, was {}", buf.len());
9684        assert_columnar_roundtrip(&v, T_INDUCTIVES);
9685    }
9686
9687    #[test]
9688    fn wire_arg_enum_list_packs_columnar() {
9689        // Arg-bearing enums now pack as a tagged union (T_INDUCTIVES) — a constructor
9690        // dictionary + index column + dense per-constructor arg columns — not boxed.
9691        let v = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Boxed(
9692            (0..10).map(|i| enum_val("Option", "Some", vec![RuntimeValue::Int(i)])).collect(),
9693        ))));
9694        assert_columnar_roundtrip(&v, T_INDUCTIVES);
9695    }
9696
9697    #[test]
9698    fn wire_mixed_arity_enum_list_packs_columnar() {
9699        // Some(1), None, Some(2), None — mixed constructors/arities round-trip exact.
9700        let rows: Vec<RuntimeValue> = (0..20)
9701            .map(|i| {
9702                if i % 2 == 0 {
9703                    enum_val("Option", "Some", vec![RuntimeValue::Int(i)])
9704                } else {
9705                    enum_val("Option", "None", vec![])
9706                }
9707            })
9708            .collect();
9709        let v = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Boxed(rows))));
9710        assert_columnar_roundtrip(&v, T_INDUCTIVES);
9711    }
9712
9713    #[test]
9714    fn wire_enum_list_decodes_to_columnar_repr() {
9715        // A received enum list decodes DIRECTLY into the columnar Inductives repr.
9716        let rows: Vec<RuntimeValue> =
9717            (0..50).map(|i| enum_val("Option", "Some", vec![RuntimeValue::Int(i)])).collect();
9718        let bytes = message_to_wire("p", &RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Boxed(rows))))).unwrap();
9719        match message_from_wire(&bytes).unwrap().1 {
9720            RuntimeValue::List(l) => {
9721                assert!(matches!(&*l.borrow(), ListRepr::Inductives { .. }), "decodes to the columnar Inductives repr");
9722                assert_eq!(l.borrow().len(), 50);
9723            }
9724            other => panic!("expected a list, got {other:?}"),
9725        }
9726    }
9727
9728    #[test]
9729    fn wire_schema_dictionary_sends_schema_once_and_shrinks() {
9730        // With a connection-scoped cache, a struct schema (type + field names) is sent
9731        // ONCE; later messages of the same shape reference it by id and are smaller.
9732        let v = struct_list(50);
9733        let mut send_cache = WireSchemaCache::default();
9734        let mut recv_cache = WireSchemaCache::default();
9735        let m1 = message_to_wire_cached("p", &v, WireCodec::Native, WireIntegrity::Raw, &mut send_cache).unwrap();
9736        let m2 = message_to_wire_cached("p", &v, WireCodec::Native, WireIntegrity::Raw, &mut send_cache).unwrap();
9737        assert!(m2.len() < m1.len(), "the 2nd message references the schema and is smaller: {} vs {}", m2.len(), m1.len());
9738        // The receiver decodes both in order with its own cache; each reconstructs the
9739        // exact rows (proven by canonical stateless re-encode equality).
9740        let d1 = message_from_wire_cached(&m1, &mut recv_cache).unwrap().1;
9741        let d2 = message_from_wire_cached(&m2, &mut recv_cache).unwrap().1;
9742        let canon = |x: &RuntimeValue| message_to_wire("p", x).unwrap();
9743        assert_eq!(canon(&d1), canon(&v));
9744        assert_eq!(canon(&d2), canon(&v));
9745    }
9746
9747    #[test]
9748    fn wire_single_struct_schema_ref_drops_field_names_and_shrinks() {
9749        // G4: a LONE struct (not a list) under a connection cache sends its schema
9750        // once; the next same-shaped struct ships values only — no inline "x"/"y" —
9751        // so it is strictly smaller, and both still decode to the exact struct.
9752        let v = point(1, 2);
9753        let mut sc = WireSchemaCache::default();
9754        let mut rc = WireSchemaCache::default();
9755        let m1 = message_to_wire_cached("p", &v, WireCodec::Native, WireIntegrity::Raw, &mut sc).unwrap();
9756        let m2 = message_to_wire_cached("p", &v, WireCodec::Native, WireIntegrity::Raw, &mut sc).unwrap();
9757        assert!(m2.len() < m1.len(), "2nd lone struct references the schema and is smaller: {} vs {}", m2.len(), m1.len());
9758        let canon = |x: &RuntimeValue| message_to_wire("p", x).unwrap();
9759        let d1 = message_from_wire_cached(&m1, &mut rc).unwrap().1;
9760        let d2 = message_from_wire_cached(&m2, &mut rc).unwrap().1;
9761        assert_eq!(canon(&d1), canon(&v));
9762        assert_eq!(canon(&d2), canon(&v));
9763    }
9764
9765    #[test]
9766    fn wire_single_struct_sequential_ref_beats_inline_field_names() {
9767        // The sequential (1-byte id) ref is strictly smaller than the uncached inline
9768        // struct, because it replaces the type-name + every field-name string with one
9769        // id — the clean, uncompressed size win that closes the postcard gap.
9770        let v = point(7, 9);
9771        let inline = message_to_wire("p", &v).unwrap();
9772        let mut sc = WireSchemaCache::sequential();
9773        let _def = message_to_wire_cached("p", &v, WireCodec::Native, WireIntegrity::Raw, &mut sc).unwrap();
9774        let refmsg = message_to_wire_cached("p", &v, WireCodec::Native, WireIntegrity::Raw, &mut sc).unwrap();
9775        assert!(refmsg.len() < inline.len(), "schema-ref ({}) must beat inline field-names ({})", refmsg.len(), inline.len());
9776    }
9777
9778    #[test]
9779    fn wire_single_struct_def_decodes_without_a_cache() {
9780        // The FIRST cached lone-struct message carries its schema inline (a "def"), so
9781        // a stateless decoder still reconstructs it.
9782        let v = point(3, 4);
9783        let mut sc = WireSchemaCache::default();
9784        let m1 = message_to_wire_cached("p", &v, WireCodec::Native, WireIntegrity::Raw, &mut sc).unwrap();
9785        let d = message_from_wire(&m1).unwrap().1;
9786        assert_eq!(message_to_wire("p", &d).unwrap(), message_to_wire("p", &v).unwrap());
9787    }
9788
9789    #[test]
9790    fn wire_single_struct_ref_without_cache_fails_cleanly() {
9791        // A schema-reference lone struct decoded WITHOUT the cache that defined it
9792        // returns None (clean) — never a mis-decode, never a panic.
9793        let v = point(5, 6);
9794        let mut sc = WireSchemaCache::default();
9795        let _m1 = message_to_wire_cached("p", &v, WireCodec::Native, WireIntegrity::Raw, &mut sc).unwrap();
9796        let m2 = message_to_wire_cached("p", &v, WireCodec::Native, WireIntegrity::Raw, &mut sc).unwrap();
9797        assert!(message_from_wire(&m2).is_none(), "a bare schema-ref must not decode without its cache");
9798    }
9799
9800    #[test]
9801    fn wire_single_struct_uncached_stays_inline_tag() {
9802        // No cache → the lone struct still uses the self-describing T_STRUCT tag (field
9803        // names inline), keeping every non-cached encode byte-identical to before G4.
9804        let v = point(1, 2);
9805        let bytes = message_to_wire("p", &v).unwrap();
9806        let (codec, _comp, body) = unframe(&bytes).unwrap();
9807        assert!(matches!(codec, WireCodec::Native));
9808        let mut pos = 0;
9809        skip_str(body, &mut pos).unwrap();
9810        assert_eq!(body[pos], T_STRUCT, "uncached lone struct must stay the inline T_STRUCT form");
9811    }
9812
9813    // ---- Pillar B: type-id substrate (default-on name elision, beats raw varint) ----
9814
9815    #[test]
9816    fn wire_struct_type_id_elides_names_and_beats_inline() {
9817        // With a shared type registry (both ends derive it from their program's type
9818        // defs), a struct ships its small registry id instead of its type/field NAMES —
9819        // strictly smaller than the self-describing inline form, on the FIRST message.
9820        let v = point(1, 2);
9821        let schemas = vec![("Point".to_string(), vec!["x".to_string(), "y".to_string()])];
9822        let with_reg = with_type_registry(WireTypeRegistry::new(schemas.clone()), || {
9823            message_to_wire("p", &v).unwrap()
9824        });
9825        let inline = message_to_wire("p", &v).unwrap();
9826        assert!(
9827            with_reg.len() < inline.len(),
9828            "type-id encode ({}) must elide names vs inline ({})",
9829            with_reg.len(),
9830            inline.len()
9831        );
9832        // Decoding with the same registry reconstructs the exact struct.
9833        let back = with_type_registry(WireTypeRegistry::new(schemas), || {
9834            message_from_wire(&with_reg).unwrap().1
9835        });
9836        assert_eq!(message_to_wire("p", &back).unwrap(), inline, "type-id round-trips to the exact value");
9837    }
9838
9839    #[test]
9840    fn wire_struct_type_id_falls_back_to_inline_for_unknown_type() {
9841        // A registry that does NOT contain the struct's type → byte-identical inline form
9842        // (so a cross-version / non-Logos peer is never confused).
9843        let v = point(1, 2);
9844        let other = vec![("Other".to_string(), vec!["a".to_string()])];
9845        let bytes = with_type_registry(WireTypeRegistry::new(other), || message_to_wire("p", &v).unwrap());
9846        assert_eq!(bytes, message_to_wire("p", &v).unwrap(), "unknown type falls back to byte-identical inline");
9847    }
9848
9849    #[test]
9850    fn wire_struct_type_id_unknown_id_fails_cleanly() {
9851        // Bytes encoded against one registry, decoded against an EMPTY one: the id can't
9852        // resolve → None (clean), never a mis-decode.
9853        let v = point(1, 2);
9854        let schemas = vec![("Point".to_string(), vec!["x".to_string(), "y".to_string()])];
9855        let bytes = with_type_registry(WireTypeRegistry::new(schemas), || message_to_wire("p", &v).unwrap());
9856        let decoded = with_type_registry(WireTypeRegistry::new(vec![]), || message_from_wire(&bytes));
9857        assert!(decoded.is_none(), "an unresolvable type-id must fail cleanly, not mis-decode");
9858    }
9859
9860    // ---- Pillar D: the no-brainer auto-tuner (`best`) ----
9861
9862    #[test]
9863    fn wire_best_smallest_is_never_larger_than_any_single_knob() {
9864        // The auto-tuner's contract: `best(Smallest)` ≤ EVERY single-dial encoding, on EVERY
9865        // workload — and it round-trips with no decode hint (every form is self-describing).
9866        let il = |v: Vec<i64>| RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Ints(v))));
9867        let fl = |v: Vec<f64>| RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Floats(v))));
9868        let workloads: Vec<(&str, RuntimeValue)> = vec![
9869            ("sequential", il((0..256).collect())),
9870            ("random", il((0..256).map(|i: i64| i.wrapping_mul(2_654_435_761)).collect())),
9871            ("repetitive", il(vec![7i64; 256])),
9872            ("clustered", il((0..256).map(|i| 1000 + (i % 8)).collect())),
9873            ("timeseries", fl((0..256).map(|i| 100.0 + i as f64 * 0.5).collect())),
9874            ("structs", RuntimeValue::List(Rc::new(RefCell::new(ListRepr::from_values(
9875                (0..40).map(|i| point(i, i * 2)).collect(),
9876            ))))),
9877            ("int map", {
9878                let mut m = MapStorage::default();
9879                for k in 0..128i64 { m.insert(RuntimeValue::Int(k), RuntimeValue::Int(k * k)); }
9880                RuntimeValue::Map(Rc::new(RefCell::new(m)))
9881            }),
9882            ("id→row map", {
9883                let mut m = MapStorage::default();
9884                for k in 0..40i64 { m.insert(RuntimeValue::Int(k), point(k, k * 2)); }
9885                RuntimeValue::Map(Rc::new(RefCell::new(m)))
9886            }),
9887        ];
9888        for (name, v) in &workloads {
9889            let best = message_to_wire_best("p", v, WireGoal::Smallest).unwrap();
9890            for num in [WireNumerics::Varint, WireNumerics::Fixed, WireNumerics::GroupVarint] {
9891                let s = with_numerics(num, || message_to_wire("p", v)).unwrap();
9892                assert!(best.len() <= s.len(), "[{name}] best {} > numerics {:?} {}", best.len(), num, s.len());
9893            }
9894            for st in [WireStructure::Off, WireStructure::Affine, WireStructure::Auto] {
9895                let s = with_structure(st, || message_to_wire("p", v)).unwrap();
9896                assert!(best.len() <= s.len(), "[{name}] best {} > structure {:?} {}", best.len(), st, s.len());
9897            }
9898            for comp in [WireCompression::None, WireCompression::Deflate, WireCompression::Lz4, WireCompression::Zstd] {
9899                let s = with_compression_codec(comp, || message_to_wire("p", v)).unwrap();
9900                assert!(best.len() <= s.len(), "[{name}] best {} > compression {:?} {}", best.len(), comp, s.len());
9901            }
9902            for f in [WireFloats::Memcpy, WireFloats::XorDelta] {
9903                let s = with_floats(f, || message_to_wire("p", v)).unwrap();
9904                assert!(best.len() <= s.len(), "[{name}] best {} > floats {:?} {}", best.len(), f, s.len());
9905            }
9906            // Round-trips: decoding `best` then re-encoding under the default dials yields the
9907            // exact default encoding of the original value.
9908            let back = message_from_wire(&best).unwrap().1;
9909            assert_eq!(
9910                message_to_wire("p", &back).unwrap(),
9911                message_to_wire("p", v).unwrap(),
9912                "[{name}] best must round-trip to the exact value"
9913            );
9914        }
9915    }
9916
9917    #[test]
9918    fn wire_best_fastest_is_the_fixed_memcpy_form_and_round_trips() {
9919        let v = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Ints((0..100).collect()))));
9920        let fast = message_to_wire_best("p", &v, WireGoal::Fastest).unwrap();
9921        let fixed = with_numerics(WireNumerics::Fixed, || message_to_wire("p", &v)).unwrap();
9922        assert_eq!(fast, fixed, "Fastest must be the fixed memcpy-decode form");
9923        let back = message_from_wire(&fast).unwrap().1;
9924        assert_eq!(
9925            message_to_wire("p", &back).unwrap(),
9926            message_to_wire("p", &v).unwrap(),
9927            "Fastest must round-trip to the exact value"
9928        );
9929    }
9930
9931    #[test]
9932    fn wire_auto_is_the_no_brainer_default_searching_only_when_it_pays() {
9933        // `auto` is the "just send it" entry point. On a tiny message it ships the plain default (no
9934        // search overhead); on a bulk payload it runs the full Smallest bake-off. It is NEVER larger
9935        // than the default and always round-trips.
9936        let scalar = RuntimeValue::Int(42);
9937        assert_eq!(
9938            message_to_wire_auto("p", &scalar).unwrap(),
9939            message_to_wire("p", &scalar).unwrap(),
9940            "a tiny message skips the search and ships the plain default"
9941        );
9942
9943        let bulk = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Ints((0..256).collect()))));
9944        let auto_bulk = message_to_wire_auto("p", &bulk).unwrap();
9945        assert_eq!(
9946            auto_bulk,
9947            message_to_wire_best("p", &bulk, WireGoal::Smallest).unwrap(),
9948            "a bulk payload gets the full Smallest search"
9949        );
9950        assert!(
9951            auto_bulk.len() < message_to_wire("p", &bulk).unwrap().len(),
9952            "and the search actually shrinks it below the default"
9953        );
9954
9955        // Universal safety: never larger than the default, always round-trips — on every shape.
9956        let mut big_map = MapStorage::default();
9957        for k in 0..200i64 {
9958            big_map.insert(RuntimeValue::Int(k), RuntimeValue::Int(k * k));
9959        }
9960        for v in [scalar, bulk, RuntimeValue::Map(Rc::new(RefCell::new(big_map)))] {
9961            let a = message_to_wire_auto("p", &v).unwrap();
9962            assert!(
9963                a.len() <= message_to_wire("p", &v).unwrap().len(),
9964                "auto is never larger than the default"
9965            );
9966            let back = message_from_wire(&a).unwrap().1;
9967            assert_eq!(
9968                message_to_wire("p", &back).unwrap(),
9969                message_to_wire("p", &v).unwrap(),
9970                "auto round-trips to the exact value"
9971            );
9972        }
9973    }
9974
9975    #[test]
9976    fn receiver_limits_refuse_a_too_deeply_nested_message() {
9977        // A 30-deep nested value encodes fine (well under MAX_ENCODE_DEPTH) and decodes by default, but
9978        // a receiver that declares a shallower max_depth REFUSES it — admission control enforced during
9979        // decode, before the recursion happens.
9980        let mut v = RuntimeValue::Nothing;
9981        for _ in 0..30 {
9982            v = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::from_values(vec![v]))));
9983        }
9984        let bytes = message_to_wire("p", &v).unwrap();
9985        assert!(message_from_wire(&bytes).is_some(), "default limits accept a 30-deep message");
9986        let tight = ReceiveLimits { max_depth: 10, ..Default::default() };
9987        assert!(
9988            with_receive_limits(tight, || message_from_wire(&bytes)).is_none(),
9989            "a receiver with max_depth=10 must refuse a 30-deep message"
9990        );
9991    }
9992
9993    #[test]
9994    fn receiver_survives_a_crafted_pathologically_deep_message_no_stack_overflow() {
9995        // THE DoS: an attacker crafts a message that is tiny in bytes (2 per level) but THOUSANDS of
9996        // containers deep. Without a decode-depth bound this recurses until the receiver's stack
9997        // overflows — a remote crash. The guard must REFUSE it cleanly, never overflow. (Hand-built raw
9998        // frame: 0x00 header = Native/uncompressed/raw, then from="" , then N×[T_LIST, count=1], then a
9999        // terminal — bypassing the encoder's own depth cap exactly as a hostile peer would.)
10000        let mut bytes = vec![0x00u8, 0x00u8]; // frame header + from=""
10001        for _ in 0..8000 {
10002            bytes.push(T_LIST);
10003            bytes.push(0x01); // uvarint count = 1
10004        }
10005        bytes.push(T_NOTHING);
10006        // A tight depth budget makes the guard bail far below any stack pressure — proving the
10007        // MECHANISM stops the recursion (the conservative default `max_depth` carries the same
10008        // protection with margin to spare in production release builds).
10009        let limits = ReceiveLimits { max_depth: 16, ..Default::default() };
10010        assert!(
10011            with_receive_limits(limits, || message_from_wire(&bytes)).is_none(),
10012            "an 8000-deep crafted message must be refused, not crash the receiver"
10013        );
10014    }
10015
10016    #[test]
10017    fn receiver_refuses_a_generator_bomb_tiny_descriptor_huge_array() {
10018        // The small-message-huge-output DoS that a byte budget CANNOT see: an affine column descriptor
10019        // `base,stride,count` is ~12 bytes but materializes `count` ints — a crafted billion-count is a
10020        // handful of bytes yet allocates gigabytes. `max_elements` gates the count before materializing.
10021        let affine = |count: u64| {
10022            let mut b = vec![0x00u8, 0x00u8, T_INTS_AFFINE]; // frame + from="" + tag
10023            write_uvarint(zigzag(0), &mut b); // base 0
10024            write_uvarint(zigzag(1), &mut b); // stride 1
10025            write_uvarint(count, &mut b);
10026            b
10027        };
10028        assert!(
10029            message_from_wire(&affine(1_000_000_000)).is_none(),
10030            "a 1e9-count affine descriptor (~12 bytes) must be refused, never allocated"
10031        );
10032        // A within-budget descriptor still decodes to exactly that many ints (the math-hack still works).
10033        match message_from_wire(&affine(100)).unwrap().1 {
10034            RuntimeValue::List(l) => assert_eq!(l.borrow().to_values().len(), 100, "affine still expands within budget"),
10035            other => panic!("expected a List, got {other:?}"),
10036        }
10037        // A tighter max_elements refuses a moderate count the default would allow, and admits a small one.
10038        let tight = ReceiveLimits { max_elements: 1000, ..Default::default() };
10039        assert!(with_receive_limits(tight, || message_from_wire(&affine(100_000))).is_none(), "max_elements=1000 refuses 100k");
10040        assert!(with_receive_limits(tight, || message_from_wire(&affine(500))).is_some(), "max_elements=1000 admits 500");
10041    }
10042
10043    #[test]
10044    fn receiver_refuses_an_oversized_message_before_decoding() {
10045        // A well-formed but large message is refused at the door when it exceeds the receiver's byte
10046        // budget — the gross-size admission gate, checked before any decompress / decode work.
10047        let big = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Ints((0..5000).collect()))));
10048        let bytes = message_to_wire("p", &big).unwrap();
10049        assert!(message_from_wire(&bytes).is_some(), "default byte budget accepts it");
10050        let tight = ReceiveLimits { max_bytes: bytes.len() - 1, ..Default::default() };
10051        assert!(
10052            with_receive_limits(tight, || message_from_wire(&bytes)).is_none(),
10053            "a message one byte over max_bytes is refused before decode"
10054        );
10055    }
10056
10057    #[test]
10058    fn peer_profile_round_trips_and_falls_back_on_unknown() {
10059        let p = PeerProfile {
10060            limits: ReceiveLimits {
10061                max_bytes: 1 << 20,
10062                max_depth: 16,
10063                max_elements: 10_000,
10064                max_string_bytes: 4096,
10065                accept_computed: false,
10066            },
10067            registry_epoch: 0xDEAD_BEEF,
10068            features: FEAT_ZSTD | FEAT_TYPE_ID,
10069        };
10070        assert_eq!(decode_peer_profile(&encode_peer_profile(&p)), Some(p), "profile round-trips exactly");
10071        assert_eq!(
10072            decode_peer_profile(&encode_peer_profile(&PeerProfile::default())),
10073            Some(PeerProfile::default()),
10074            "the default profile round-trips"
10075        );
10076        // An unknown version is recognized and not mis-parsed.
10077        let mut bad = encode_peer_profile(&p);
10078        bad[0] = 99;
10079        assert!(decode_peer_profile(&bad).is_none(), "an unknown profile version → None (caller uses defaults)");
10080        // Truncation at any offset never panics or mis-decodes.
10081        let full = encode_peer_profile(&p);
10082        for cut in 0..full.len() {
10083            let _ = decode_peer_profile(&full[..cut]);
10084        }
10085        assert!(decode_peer_profile(&[]).is_none());
10086    }
10087
10088    #[test]
10089    fn negotiate_restricts_the_sender_to_the_receivers_exposed_surface() {
10090        // Both peers share an epoch and speak type-id → names elided; receiver accepts computed + both
10091        // speak it → may ship code; strongest shared compression chosen; the receiver's budget surfaces.
10092        let me = PeerProfile {
10093            registry_epoch: 7,
10094            features: FEAT_ZSTD | FEAT_LZ4 | FEAT_TYPE_ID | FEAT_COMPUTED,
10095            ..Default::default()
10096        };
10097        let peer = PeerProfile {
10098            limits: ReceiveLimits { max_bytes: 4096, ..Default::default() },
10099            registry_epoch: 7,
10100            features: FEAT_LZ4 | FEAT_TYPE_ID | FEAT_COMPUTED,
10101        };
10102        let n = negotiate(&me, &peer);
10103        assert!(n.use_type_id, "matching epochs + both type-id → elide names");
10104        assert!(n.may_send_computed, "receiver accepts computed + both speak it → may ship a computation");
10105        assert_eq!(n.compression, WireCompression::Lz4, "strongest compression BOTH understand (peer lacks zstd)");
10106        assert_eq!(n.peer_max_bytes, 4096, "the receiver's byte budget surfaces to the sender");
10107
10108        // A receiver that declines code, has a different epoch, and shares no compression: the sender
10109        // backs OFF on every axis — exposed surface respected.
10110        let strict = PeerProfile {
10111            limits: ReceiveLimits { accept_computed: false, ..Default::default() },
10112            registry_epoch: 999,
10113            features: FEAT_TYPE_ID, // no compression, no computed
10114        };
10115        let n2 = negotiate(&me, &strict);
10116        assert!(!n2.use_type_id, "different epochs → names must travel");
10117        assert!(!n2.may_send_computed, "receiver declines code → never ship a computation");
10118        assert_eq!(n2.compression, WireCompression::None, "no shared compression → send uncompressed");
10119    }
10120
10121    #[test]
10122    fn negotiated_send_uses_all_knobs_within_the_receivers_surface() {
10123        let from = "p";
10124        let bulk = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Ints((0..256).collect()))));
10125        let default = message_to_wire(from, &bulk).unwrap();
10126        // Round-trip proof by byte-stability (container `PartialEq` is shallow): decode, re-encode under
10127        // the default dials, compare to the default encoding of the original.
10128        let roundtrips = |enc: &[u8]| {
10129            let back = message_from_wire(enc).unwrap().1;
10130            assert_eq!(message_to_wire(from, &back).unwrap(), default, "negotiated send must round-trip exactly");
10131        };
10132
10133        // FULL surface (both speak zstd): the bake-off crushes the bulk list below the default, and it
10134        // still decodes with no hint.
10135        let full = Negotiated {
10136            use_type_id: false,
10137            may_send_computed: true,
10138            compression: WireCompression::Zstd,
10139            peer_max_bytes: 1 << 20,
10140        };
10141        let enc = message_to_wire_negotiated(from, &bulk, &full, WireTypeRegistry::new(Vec::new())).unwrap();
10142        assert!(enc.len() <= default.len(), "negotiated is never larger than the default");
10143        assert!(enc.len() < default.len(), "the negotiated bake-off shrinks a 256-int list");
10144        roundtrips(&enc);
10145
10146        // A receiver that shares NO compression: the send never uses a codec it can't decode, still
10147        // round-trips, and is still ≤ default.
10148        let nocomp = Negotiated { compression: WireCompression::None, ..full };
10149        let enc_nc = message_to_wire_negotiated(from, &bulk, &nocomp, WireTypeRegistry::new(Vec::new())).unwrap();
10150        assert!(enc_nc.len() <= default.len());
10151        roundtrips(&enc_nc);
10152
10153        // TYPE-ID name elision fires ONLY when negotiated, shrinking a struct with long field names.
10154        use crate::interpreter::StructValue;
10155        let mut fields = HashMap::new();
10156        fields.insert("organization_identifier".to_string(), RuntimeValue::Int(1));
10157        fields.insert("organization_display_name".to_string(), RuntimeValue::Text(Rc::new("ACME".to_string())));
10158        let s = RuntimeValue::Struct(Box::new(StructValue { type_name: "Organization".to_string(), fields }));
10159        let names = vec!["organization_display_name".to_string(), "organization_identifier".to_string()];
10160        let inline = message_to_wire(from, &s).unwrap();
10161        let with_id = Negotiated { use_type_id: true, ..nocomp };
10162        let elided = message_to_wire_negotiated(
10163            from,
10164            &s,
10165            &with_id,
10166            WireTypeRegistry::new(vec![("Organization".to_string(), names.clone())]),
10167        )
10168        .unwrap();
10169        assert!(elided.len() < inline.len(), "type-id elides the long field NAMES from the wire");
10170        // It decodes when the receiver shares the same registry (the negotiated condition), to the same value.
10171        let back = with_type_registry(
10172            WireTypeRegistry::new(vec![("Organization".to_string(), names)]),
10173            || message_from_wire(&elided),
10174        )
10175        .unwrap()
10176        .1;
10177        assert_eq!(message_to_wire(from, &back).unwrap(), inline, "the struct round-trips through the shared registry");
10178
10179        // A computation the receiver DECLINED is refused at send (defense in depth).
10180        use crate::ast::stmt::{BinaryOpKind, Expr, Literal};
10181        use logicaffeine_base::{Arena, Symbol};
10182        let a: Arena<Expr> = Arena::new();
10183        let i = Symbol::from_index(0);
10184        let idx: &Expr = a.alloc(Expr::Identifier(i));
10185        let one: &Expr = a.alloc(Expr::Literal(Literal::Number(1)));
10186        let fbody: &Expr = a.alloc(Expr::BinaryOp { op: BinaryOpKind::Add, left: idx, right: one });
10187        let gen = lower_expr_to_genexpr(fbody, i).unwrap();
10188        let f = RuntimeValue::Function(Box::new(ClosureValue {
10189            body_index: usize::MAX,
10190            captured_env: std::collections::HashMap::default(),
10191            param_names: vec![i],
10192            generated: Some(Rc::new(gen)),
10193        }));
10194        let declined = Negotiated { may_send_computed: false, ..full };
10195        assert!(
10196            message_to_wire_negotiated(from, &f, &declined, WireTypeRegistry::new(Vec::new())).is_err(),
10197            "a computation the receiver declined is refused at SEND"
10198        );
10199        let accepted = Negotiated { may_send_computed: true, ..full };
10200        assert!(
10201            message_to_wire_negotiated(from, &f, &accepted, WireTypeRegistry::new(Vec::new())).is_ok(),
10202            "an accepted computation is sent"
10203        );
10204    }
10205
10206    #[test]
10207    fn wire_type_registry_epoch_is_deterministic_and_distinguishes_type_sets() {
10208        // The registry epoch is the handshake's "do we share types?" key. Same types declared in any
10209        // field order → SAME epoch (so two same-program peers match and may elide names); a different
10210        // type set → a different epoch; empty → 0 (never elide).
10211        let a = WireTypeRegistry::new(vec![("Org".to_string(), vec!["id".to_string(), "name".to_string()])]);
10212        let b = WireTypeRegistry::new(vec![("Org".to_string(), vec!["name".to_string(), "id".to_string()])]);
10213        assert_eq!(a.epoch(), b.epoch(), "same types in any field order → identical epoch");
10214        assert_ne!(a.epoch(), 0, "a non-empty registry is never epoch 0");
10215        let c = WireTypeRegistry::new(vec![("User".to_string(), vec!["id".to_string()])]);
10216        assert_ne!(a.epoch(), c.epoch(), "a different type set → a different epoch");
10217        assert_eq!(WireTypeRegistry::new(vec![]).epoch(), 0, "empty registry → epoch 0 (never elide)");
10218        // Enums participate too: adding an enum changes the epoch, order-independently.
10219        let with_enum = WireTypeRegistry::new(vec![("Org".to_string(), vec!["id".to_string(), "name".to_string()])])
10220            .with_enums(vec![("Color".to_string(), vec!["Red".to_string(), "Green".to_string()])]);
10221        assert_ne!(a.epoch(), with_enum.epoch(), "adding an enum type changes the epoch");
10222    }
10223
10224    #[test]
10225    fn handshake_frame_round_trips_and_is_never_confused_with_a_data_message() {
10226        let prof = PeerProfile {
10227            limits: ReceiveLimits { max_bytes: 4096, accept_computed: false, ..Default::default() },
10228            registry_epoch: 42,
10229            features: FEAT_LZ4 | FEAT_TYPE_ID,
10230        };
10231        let frame = make_handshake_frame("alice", &prof);
10232        assert_eq!(parse_handshake_frame(&frame), Some(("alice".to_string(), prof)), "handshake round-trips");
10233
10234        // A real data message is NEVER parsed as a handshake (the magic can't collide with a frame header).
10235        let data = message_to_wire("alice", &RuntimeValue::Int(7)).unwrap();
10236        assert!(parse_handshake_frame(&data).is_none(), "a data message is not a handshake");
10237        // …and a handshake frame is not a decodable data message.
10238        assert!(message_from_wire(&frame).is_none(), "a handshake frame is not a data message");
10239        // Truncations never panic or mis-parse.
10240        for cut in 0..frame.len() {
10241            let _ = parse_handshake_frame(&frame[..cut]);
10242        }
10243    }
10244
10245    #[test]
10246    fn wire_struct_list_type_id_elides_names_and_beats_inline() {
10247        // The BULK case: a homogeneous struct LIST. With a shared registry, the columnar
10248        // list ships its type id + N + columns — the type/field NAMES never go on the wire,
10249        // on the FIRST message. Strictly smaller than the self-describing `T_STRUCTS`.
10250        let v = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::from_values(
10251            (0..50).map(|i| point(i, i * 2)).collect(),
10252        ))));
10253        let schemas = vec![("Point".to_string(), vec!["x".to_string(), "y".to_string()])];
10254        let with_reg = with_type_registry(WireTypeRegistry::new(schemas.clone()), || {
10255            message_to_wire("p", &v).unwrap()
10256        });
10257        let inline = message_to_wire("p", &v).unwrap();
10258        assert!(
10259            with_reg.len() < inline.len(),
10260            "struct-list type-id ({}) must elide names vs inline ({})",
10261            with_reg.len(),
10262            inline.len()
10263        );
10264        let back = with_type_registry(WireTypeRegistry::new(schemas), || {
10265            message_from_wire(&with_reg).unwrap().1
10266        });
10267        assert_eq!(
10268            message_to_wire("p", &back).unwrap(),
10269            inline,
10270            "struct-list type-id round-trips to the exact value"
10271        );
10272    }
10273
10274    #[test]
10275    fn wire_struct_list_type_id_falls_back_for_unknown_type() {
10276        // A registry without this type → byte-identical self-describing `T_STRUCTS`.
10277        let v = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::from_values(
10278            (0..10).map(|i| point(i, i)).collect(),
10279        ))));
10280        let other = vec![("Other".to_string(), vec!["a".to_string()])];
10281        let bytes = with_type_registry(WireTypeRegistry::new(other), || message_to_wire("p", &v).unwrap());
10282        assert_eq!(
10283            bytes,
10284            message_to_wire("p", &v).unwrap(),
10285            "unknown type falls back to byte-identical inline T_STRUCTS"
10286        );
10287    }
10288
10289    #[test]
10290    fn wire_struct_list_type_id_unknown_id_fails_cleanly() {
10291        // Encoded against one registry, decoded against an EMPTY one: the id can't resolve
10292        // → None (clean), never a mis-decode.
10293        let v = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::from_values(
10294            (0..10).map(|i| point(i, i)).collect(),
10295        ))));
10296        let schemas = vec![("Point".to_string(), vec!["x".to_string(), "y".to_string()])];
10297        let bytes = with_type_registry(WireTypeRegistry::new(schemas), || message_to_wire("p", &v).unwrap());
10298        let decoded = with_type_registry(WireTypeRegistry::new(vec![]), || message_from_wire(&bytes));
10299        assert!(decoded.is_none(), "an unresolvable struct-list type-id must fail cleanly, not mis-decode");
10300    }
10301
10302    #[test]
10303    fn wire_struct_type_id_registry_order_independent() {
10304        // The id is content-addressed (canonical by fingerprint), so two registries that
10305        // declare the same types in different ORDER assign the same ids — sender and
10306        // receiver always agree regardless of declaration order.
10307        let v = point(7, 9);
10308        let a = vec![
10309            ("Point".to_string(), vec!["x".to_string(), "y".to_string()]),
10310            ("Other".to_string(), vec!["a".to_string()]),
10311        ];
10312        let mut b = a.clone();
10313        b.reverse();
10314        let enc_a = with_type_registry(WireTypeRegistry::new(a), || message_to_wire("p", &v).unwrap());
10315        let dec_b = with_type_registry(WireTypeRegistry::new(b), || message_from_wire(&enc_a).unwrap().1);
10316        assert_eq!(message_to_wire("p", &dec_b).unwrap(), message_to_wire("p", &v).unwrap());
10317    }
10318
10319    #[test]
10320    fn wire_enum_type_id_elides_type_and_constructor_names() {
10321        // An enum (Inductive) under a shared registry ships its enum-id + a constructor
10322        // INDEX instead of the type and constructor NAMES — both ends know the ordered
10323        // constructor list from their shared type def. Strictly smaller than inline.
10324        let v = enum_val("Color", "Green", vec![]);
10325        let enums = vec![("Color".to_string(), vec!["Red".to_string(), "Green".to_string(), "Blue".to_string()])];
10326        let reg = || WireTypeRegistry::new(vec![]).with_enums(enums.clone());
10327        let with_reg = with_type_registry(reg(), || message_to_wire("p", &v).unwrap());
10328        let inline = message_to_wire("p", &v).unwrap();
10329        assert!(with_reg.len() < inline.len(), "enum type-id ({}) elides names vs inline ({})", with_reg.len(), inline.len());
10330        let back = with_type_registry(reg(), || message_from_wire(&with_reg).unwrap().1);
10331        assert_eq!(message_to_wire("p", &back).unwrap(), inline, "enum type-id round-trips to the exact value");
10332    }
10333
10334    #[test]
10335    fn wire_enum_type_id_carries_args_and_falls_back_when_unknown() {
10336        // A non-nullary constructor's args ride along; an enum NOT in the registry stays
10337        // the byte-identical self-describing inline form.
10338        let some = enum_val("Option", "Some", vec![RuntimeValue::Int(7)]);
10339        let enums = vec![("Option".to_string(), vec!["None".to_string(), "Some".to_string()])];
10340        let with_reg = with_type_registry(
10341            WireTypeRegistry::new(vec![]).with_enums(enums.clone()),
10342            || message_to_wire("p", &some).unwrap(),
10343        );
10344        let back = with_type_registry(
10345            WireTypeRegistry::new(vec![]).with_enums(enums),
10346            || message_from_wire(&with_reg).unwrap().1,
10347        );
10348        assert_eq!(message_to_wire("p", &back).unwrap(), message_to_wire("p", &some).unwrap());
10349        // An unrelated registry (no Option) → byte-identical inline.
10350        let other = WireTypeRegistry::new(vec![]).with_enums(vec![("X".to_string(), vec!["A".to_string()])]);
10351        let bytes = with_type_registry(other, || message_to_wire("p", &some).unwrap());
10352        assert_eq!(bytes, message_to_wire("p", &some).unwrap(), "unknown enum falls back to inline");
10353    }
10354
10355    // ---- Pillar A: offset-table struct view (beat Cap'n Proto random access) --------
10356
10357    #[test]
10358    fn wire_struct_view_round_trips() {
10359        let mut fields = HashMap::new();
10360        fields.insert("a".to_string(), RuntimeValue::Int(1));
10361        fields.insert("b".to_string(), RuntimeValue::Int(2));
10362        fields.insert("c".to_string(), RuntimeValue::Int(99));
10363        let v = RuntimeValue::Struct(Box::new(StructValue { type_name: "Rec".to_string(), fields }));
10364        let bytes = with_struct_view(true, || message_to_wire("p", &v).unwrap());
10365        let back = message_from_wire(&bytes).unwrap().1;
10366        assert_eq!(
10367            message_to_wire("p", &back).unwrap(),
10368            message_to_wire("p", &v).unwrap(),
10369            "offset-table view round-trips to the exact struct"
10370        );
10371    }
10372
10373    #[test]
10374    fn wire_struct_view_reads_one_field_without_parsing_the_rest() {
10375        // Cap'n Proto-class random access: a struct with a HUGE field and a small field.
10376        // Reading the small field via the offset table is O(1) — a THOUSAND such reads must
10377        // be cheaper than ONE full decode, proving it never parses the huge field.
10378        let big: Vec<i64> = (0..1_000_000).map(|i| i as i64).collect();
10379        let mut fields = HashMap::new();
10380        fields.insert("big".to_string(), RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Ints(big)))));
10381        fields.insert("small".to_string(), RuntimeValue::Int(4242));
10382        let v = RuntimeValue::Struct(Box::new(StructValue { type_name: "Rec".to_string(), fields }));
10383        // The DEFAULT (checksummed) message — the view is STILL O(1): `view_message` does
10384        // not re-hash the body (that would defeat random access), so `Raw` is NOT required
10385        // for zero-copy. The offset-table field jump never touches the 1M-element field.
10386        let bytes = with_struct_view(true, || message_to_wire("p", &v).unwrap());
10387
10388        let view = view_message(&bytes).unwrap();
10389        assert_eq!(
10390            view.struct_field("small").and_then(|f| f.as_int()),
10391            Some(4242),
10392            "the offset table reads the small field directly"
10393        );
10394
10395        let reads = {
10396            let t = std::time::Instant::now();
10397            for _ in 0..1000 {
10398                let view = view_message(&bytes).unwrap();
10399                std::hint::black_box(view.struct_field("small").and_then(|f| f.as_int()));
10400            }
10401            t.elapsed().as_nanos()
10402        };
10403        let full = {
10404            let t = std::time::Instant::now();
10405            std::hint::black_box(message_from_wire(&bytes).unwrap());
10406            t.elapsed().as_nanos()
10407        };
10408        assert!(
10409            reads < full,
10410            "1000 O(1) view reads ({reads}ns) must beat ONE full decode ({full}ns) — capnp-class random access"
10411        );
10412    }
10413
10414    #[test]
10415    fn wire_aligned_int_column_reads_zero_copy_as_slice() {
10416        // The in-place column read — the LAN / kernel-bypass axis Cap'n Proto owns. An
10417        // aligned i64 column reads back as `&[i64]` with ZERO copy: the slice BORROWS the
10418        // message bytes, no allocation and no per-element decode, the way an io_uring / RDMA
10419        // receiver reads pre-registered, alignment-guaranteed buffers in place.
10420        let data: Vec<i64> = (0..1000).map(|i| i * 7 - 3).collect();
10421        let value = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Ints(data.clone()))));
10422        let bytes = with_struct_view(true, || message_to_wire("p", &value).unwrap());
10423
10424        // Place the framed message in an 8-byte-aligned buffer, as a real zero-copy receiver
10425        // would — a `Vec<i64>` allocation is 8-aligned by `i64`'s alignment, and the encoder
10426        // padded the column so its final-buffer offset is ≡ 0 mod 8.
10427        let mut backing = vec![0i64; bytes.len() / 8 + 2];
10428        // SAFETY: copy the message into the aligned backing's bytes; thereafter read-only.
10429        unsafe {
10430            std::ptr::copy_nonoverlapping(bytes.as_ptr(), backing.as_mut_ptr().cast::<u8>(), bytes.len());
10431        }
10432        let abytes: &[u8] = unsafe { std::slice::from_raw_parts(backing.as_ptr().cast::<u8>(), bytes.len()) };
10433
10434        let view = view_message(abytes).unwrap();
10435        let slice = view.as_i64_slice().expect("an aligned column reads zero-copy as &[i64]");
10436        assert_eq!(slice, &data[..], "the zero-copy slice equals the column data");
10437
10438        // It BORROWS the message buffer (zero allocation): the slice lives inside `abytes`
10439        // and is 8-byte aligned (a sound `&[i64]` cast on every architecture, not just x86).
10440        let base = abytes.as_ptr() as usize;
10441        let lo = slice.as_ptr() as usize;
10442        assert!(lo >= base && lo < base + abytes.len(), "the slice borrows the message bytes (zero-copy)");
10443        assert_eq!(lo % 8, 0, "the column blob is 8-byte aligned");
10444
10445        // The same bytes still round-trip through a full owned decode (the T_INTS_ALIGNED
10446        // decode arm), re-encoding to the exact aligned form.
10447        let back = message_from_wire(abytes).unwrap().1;
10448        let re = with_struct_view(true, || message_to_wire("p", &back).unwrap());
10449        assert_eq!(re, bytes, "the aligned column also decodes + re-encodes to the exact bytes");
10450    }
10451
10452    #[test]
10453    fn wire_aligned_int_column_falls_back_to_copy_when_unaligned() {
10454        // When the receiver's buffer is NOT 8-aligned at the column, `as_i64_slice` returns
10455        // None (no UB) and the caller copies via the full decode — which still round-trips.
10456        let data: Vec<i64> = (0..64).map(|i| i - 32).collect();
10457        let value = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Ints(data.clone()))));
10458        let bytes = with_struct_view(true, || message_to_wire("p", &value).unwrap());
10459
10460        // Force a deliberate 1-byte misalignment by prepending a byte to an aligned backing,
10461        // so the message body starts at an odd offset and the column can't be 8-aligned.
10462        let mut backing = vec![0i64; bytes.len() / 8 + 2];
10463        let raw = unsafe { std::slice::from_raw_parts_mut(backing.as_mut_ptr().cast::<u8>(), bytes.len() + 1) };
10464        raw[1..bytes.len() + 1].copy_from_slice(&bytes);
10465        let shifted: &[u8] = &raw[1..bytes.len() + 1];
10466
10467        let view = view_message(shifted).unwrap();
10468        // Either the misalignment made the cast unsound (→ None, copy fallback) — the
10469        // important invariant is no panic and a correct owned decode regardless.
10470        if let Some(slice) = view.as_i64_slice() {
10471            assert_eq!(slice.as_ptr() as usize % 8, 0, "if it returned a slice it MUST be aligned");
10472        }
10473        let back = message_from_wire(shifted).unwrap().1;
10474        let re = with_struct_view(true, || message_to_wire("p", &back).unwrap());
10475        assert_eq!(re, bytes, "the unaligned column still decodes correctly via copy");
10476    }
10477
10478    #[test]
10479    fn wire_aligned_float_column_reads_zero_copy_as_slice() {
10480        // The float twin of the zero-copy i64 read: an aligned f64 column reads back as
10481        // `&[f64]` with no copy, BIT-EXACT — including NaN / ±Inf / subnormals, which the
10482        // `&[f64]` cast carries verbatim (no per-element decode could change a bit).
10483        let mut data: Vec<f64> = (0..1000).map(|i| i as f64 * 1.5 - 7.0).collect();
10484        data[3] = f64::NAN;
10485        data[5] = f64::INFINITY;
10486        data[7] = f64::NEG_INFINITY;
10487        data[9] = f64::MIN_POSITIVE / 4.0; // a subnormal
10488        data[11] = -0.0;
10489        let value = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Floats(data.clone()))));
10490        let bytes = with_struct_view(true, || message_to_wire("p", &value).unwrap());
10491
10492        let mut backing = vec![0i64; bytes.len() / 8 + 2];
10493        // SAFETY: copy the message into the 8-aligned backing's bytes; thereafter read-only.
10494        unsafe {
10495            std::ptr::copy_nonoverlapping(bytes.as_ptr(), backing.as_mut_ptr().cast::<u8>(), bytes.len());
10496        }
10497        let abytes: &[u8] = unsafe { std::slice::from_raw_parts(backing.as_ptr().cast::<u8>(), bytes.len()) };
10498
10499        let view = view_message(abytes).unwrap();
10500        let slice = view.as_f64_slice().expect("an aligned float column reads zero-copy as &[f64]");
10501        // Bit-exact comparison (NaN != NaN under `==`, so compare the raw bits).
10502        let got: Vec<u64> = slice.iter().map(|x| x.to_bits()).collect();
10503        let want: Vec<u64> = data.iter().map(|x| x.to_bits()).collect();
10504        assert_eq!(got, want, "the zero-copy float slice is bit-exact (NaN/Inf/subnormal/-0 preserved)");
10505
10506        // It BORROWS the message buffer (zero allocation) and is 8-byte aligned.
10507        let base = abytes.as_ptr() as usize;
10508        let lo = slice.as_ptr() as usize;
10509        assert!(lo >= base && lo < base + abytes.len(), "the float slice borrows the message bytes (zero-copy)");
10510        assert_eq!(lo % 8, 0, "the float column blob is 8-byte aligned");
10511
10512        // Full owned decode round-trips the exact aligned form too.
10513        let back = message_from_wire(abytes).unwrap().1;
10514        let re = with_struct_view(true, || message_to_wire("p", &back).unwrap());
10515        assert_eq!(re, bytes, "the aligned float column also decodes + re-encodes to the exact bytes");
10516    }
10517
10518    #[test]
10519    fn wire_structs_view_round_trips() {
10520        // A record LIST in the random-access view round-trips to the exact same bytes.
10521        let mut rows = Vec::new();
10522        for i in 0..50i64 {
10523            let mut fields = HashMap::new();
10524            fields.insert("id".to_string(), RuntimeValue::Int(i));
10525            fields.insert("score".to_string(), RuntimeValue::Int(i * 3 - 7));
10526            fields.insert("active".to_string(), RuntimeValue::Bool(i % 2 == 0));
10527            rows.push(RuntimeValue::Struct(Box::new(StructValue { type_name: "Row".to_string(), fields })));
10528        }
10529        let v = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::from_values(rows))));
10530        let bytes = with_struct_view(true, || message_to_wire("p", &v).unwrap());
10531        let back = message_from_wire(&bytes).unwrap().1;
10532        assert_eq!(
10533            with_struct_view(true, || message_to_wire("p", &back).unwrap()),
10534            bytes,
10535            "record-list view round-trips to the exact bytes"
10536        );
10537    }
10538
10539    #[test]
10540    fn wire_structs_view_reads_one_field_of_one_row_without_parsing_the_rest() {
10541        // O(1) random access into a record list: each row carries a big `blob` column, but
10542        // reading row r's small `id` must jump straight there via the row + field offset
10543        // tables — never materializing the blobs. The Cap'n Proto-class record-list read.
10544        let big: Vec<i64> = (0..1000).collect();
10545        let mut rows = Vec::new();
10546        for i in 0..200i64 {
10547            let mut fields = HashMap::new();
10548            fields.insert("id".to_string(), RuntimeValue::Int(i * 1000 + 1));
10549            fields.insert(
10550                "blob".to_string(),
10551                RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Ints(big.clone())))),
10552            );
10553            rows.push(RuntimeValue::Struct(Box::new(StructValue { type_name: "Row".to_string(), fields })));
10554        }
10555        let v = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::from_values(rows))));
10556        let bytes = with_struct_view(true, || message_to_wire("p", &v).unwrap());
10557        let view = view_message(&bytes).unwrap();
10558
10559        assert_eq!(view.structs_len(), Some(200), "row count read from the view head");
10560        assert_eq!(
10561            view.structs_row_field(7, "id").and_then(|f| f.as_int()),
10562            Some(7 * 1000 + 1),
10563            "O(1) read of row 7's id"
10564        );
10565        assert_eq!(
10566            view.structs_row_field(199, "id").and_then(|f| f.as_int()),
10567            Some(199 * 1000 + 1),
10568            "O(1) read of the last row's id"
10569        );
10570        assert!(view.structs_row_field(200, "id").is_none(), "row out of range → None");
10571        assert!(view.structs_row_field(0, "nope").is_none(), "unknown field → None");
10572
10573        // The O(1) random reads beat ONE full decode (which materializes every blob column).
10574        let idxs: Vec<usize> = (0..1000).map(|k| (k * 7) % 200).collect();
10575        let reads = {
10576            let t = std::time::Instant::now();
10577            let mut acc = 0i64;
10578            for &i in &idxs {
10579                acc = acc.wrapping_add(view.structs_row_field(i, "id").unwrap().as_int().unwrap());
10580            }
10581            std::hint::black_box(acc);
10582            t.elapsed().as_nanos()
10583        };
10584        let full = {
10585            let t = std::time::Instant::now();
10586            std::hint::black_box(message_from_wire(&bytes).unwrap());
10587            t.elapsed().as_nanos()
10588        };
10589        assert!(
10590            reads < full,
10591            "1000 O(1) row-field reads ({reads}ns) must beat ONE full decode ({full}ns) — record-list random access"
10592        );
10593    }
10594
10595    #[test]
10596    fn wire_cyclic_value_fails_cleanly_instead_of_overflowing() {
10597        // A self-referential list (constructible via the `Rc<RefCell<…>>` a List wraps) must
10598        // NOT stack-overflow the recursive encoder — it returns a clean Err. Completeness /
10599        // robustness: the codec never crashes on a value, however pathological.
10600        let cell = Rc::new(RefCell::new(ListRepr::Boxed(vec![])));
10601        let list = RuntimeValue::List(cell.clone());
10602        *cell.borrow_mut() = ListRepr::Boxed(vec![list.clone()]); // the list now contains itself
10603        let result = message_to_wire("p", &list);
10604        *cell.borrow_mut() = ListRepr::Boxed(vec![]); // break the cycle so the Rc doesn't leak
10605        assert!(result.is_err(), "a cyclic value must return Err, not overflow the stack");
10606    }
10607
10608    #[test]
10609    fn wire_deeply_nested_value_round_trips_below_the_guard() {
10610        // A legitimately deep (but finite) nesting still round-trips — the cycle guard only
10611        // rejects the pathological, never real data. Build via `from_values` so the value is
10612        // already canonical (the codec de-boxes on decode, so a hand-built `Boxed` would not
10613        // compare equal — that is canonicalization, not a round-trip failure).
10614        let mut v = RuntimeValue::Int(7);
10615        for _ in 0..40 {
10616            v = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::from_values(vec![v]))));
10617        }
10618        let bytes = message_to_wire("p", &v).expect("deep-but-finite nesting encodes");
10619        let back = message_from_wire(&bytes).expect("deep nesting decodes").1;
10620        // Byte-stable round-trip (List equality is Rc-identity, so re-encode and compare the
10621        // canonical bytes — the idiom every round-trip lock-in in this file uses).
10622        assert_eq!(message_to_wire("p", &back).unwrap(), bytes, "deep nesting round-trips exactly");
10623    }
10624
10625    #[test]
10626    fn wire_schema_def_decodes_without_a_cache() {
10627        // The FIRST cached message carries the schema inline (a "def"), so even a
10628        // stateless decoder handles it.
10629        let v = struct_list(20);
10630        let mut send_cache = WireSchemaCache::default();
10631        let m1 = message_to_wire_cached("p", &v, WireCodec::Native, WireIntegrity::Raw, &mut send_cache).unwrap();
10632        let d = message_from_wire(&m1).unwrap().1;
10633        assert_eq!(message_to_wire("p", &d).unwrap(), message_to_wire("p", &v).unwrap());
10634    }
10635
10636    #[test]
10637    fn wire_schema_ref_without_cache_fails_cleanly() {
10638        // A later message is a schema "ref"; a stateless decoder has no schema for that
10639        // id, so it returns None — never a panic, never a wrong value.
10640        let v = struct_list(20);
10641        let mut send_cache = WireSchemaCache::default();
10642        let _m1 = message_to_wire_cached("p", &v, WireCodec::Native, WireIntegrity::Raw, &mut send_cache).unwrap();
10643        let m2 = message_to_wire_cached("p", &v, WireCodec::Native, WireIntegrity::Raw, &mut send_cache).unwrap();
10644        assert!(message_from_wire(&m2).is_none(), "a schema-ref without a cache decodes to None");
10645    }
10646
10647    fn person(i: i64) -> RuntimeValue {
10648        let mut f = HashMap::new();
10649        f.insert("name".to_string(), RuntimeValue::Text(Rc::new(format!("n{i}"))));
10650        f.insert("score".to_string(), RuntimeValue::Int(i));
10651        RuntimeValue::Struct(Box::new(StructValue { type_name: "Person".to_string(), fields: f }))
10652    }
10653
10654    #[test]
10655    fn wire_schema_dictionary_distinct_schemas_get_distinct_ids() {
10656        // Two different struct shapes each get their own schema id; interleaved sends
10657        // round-trip exactly through synchronized caches.
10658        let points = struct_list(10);
10659        let people = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Boxed((0..10).map(person).collect()))));
10660        let mut sc = WireSchemaCache::default();
10661        let mut rc = WireSchemaCache::default();
10662        let mut enc = |x: &RuntimeValue, c: &mut WireSchemaCache| {
10663            message_to_wire_cached("p", x, WireCodec::Native, WireIntegrity::Raw, c).unwrap()
10664        };
10665        let seq = [enc(&points, &mut sc), enc(&people, &mut sc), enc(&points, &mut sc), enc(&people, &mut sc)];
10666        let originals = [&points, &people, &points, &people];
10667        for (bytes, orig) in seq.iter().zip(originals) {
10668            let d = message_from_wire_cached(bytes, &mut rc).unwrap().1;
10669            assert_eq!(message_to_wire("p", &d).unwrap(), message_to_wire("p", orig).unwrap());
10670        }
10671    }
10672
10673    #[test]
10674    fn wire_schema_cache_handles_nested_struct_columns() {
10675        // A struct whose field is itself a list of structs — the NESTED schema is also
10676        // dictionaried (its own id), so the 2nd message is smaller and both round-trip.
10677        let inner = || RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Boxed((0..3).map(|i| point(i, i)).collect()))));
10678        let outer: Vec<RuntimeValue> = (0..5)
10679            .map(|i| {
10680                let mut f = HashMap::new();
10681                f.insert("id".to_string(), RuntimeValue::Int(i));
10682                f.insert("pts".to_string(), inner());
10683                RuntimeValue::Struct(Box::new(StructValue { type_name: "Bag".to_string(), fields: f }))
10684            })
10685            .collect();
10686        let v = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Boxed(outer))));
10687        let mut sc = WireSchemaCache::default();
10688        let mut rc = WireSchemaCache::default();
10689        let mut enc = |c: &mut WireSchemaCache| message_to_wire_cached("p", &v, WireCodec::Native, WireIntegrity::Raw, c).unwrap();
10690        let m1 = enc(&mut sc);
10691        let m2 = enc(&mut sc);
10692        assert!(m2.len() < m1.len(), "nested schemas reference on the 2nd message: {} vs {}", m2.len(), m1.len());
10693        let d1 = message_from_wire_cached(&m1, &mut rc).unwrap().1;
10694        let d2 = message_from_wire_cached(&m2, &mut rc).unwrap().1;
10695        assert_eq!(message_to_wire("p", &d1).unwrap(), message_to_wire("p", &v).unwrap());
10696        assert_eq!(message_to_wire("p", &d2).unwrap(), message_to_wire("p", &v).unwrap());
10697    }
10698
10699    #[cfg(not(target_arch = "wasm32"))]
10700    #[test]
10701    fn wire_schema_cache_composes_with_compression_and_checksum() {
10702        // Schema-by-reference + zstd + FNV checksum all stack: the ref message is
10703        // smaller and round-trips through the verified, inflated, schema-resolved path.
10704        let v = struct_list(300);
10705        let mut sc = WireSchemaCache::default();
10706        let mut rc = WireSchemaCache::default();
10707        let mut enc = |c: &mut WireSchemaCache| {
10708            with_compression_codec(WireCompression::Zstd, || {
10709                message_to_wire_cached("p", &v, WireCodec::Native, WireIntegrity::Checked, c).unwrap()
10710            })
10711        };
10712        let m1 = enc(&mut sc);
10713        let m2 = enc(&mut sc);
10714        assert!(m2.len() < m1.len(), "compressed+checked ref < def: {} vs {}", m2.len(), m1.len());
10715        assert!(message_from_wire_cached(&m1, &mut rc).is_some());
10716        let d2 = message_from_wire_cached(&m2, &mut rc).unwrap().1;
10717        assert_eq!(message_to_wire("p", &d2).unwrap(), message_to_wire("p", &v).unwrap());
10718    }
10719
10720    #[test]
10721    fn wire_schema_cache_fuzz_never_diverges_from_stateless() {
10722        // The proof: over many random message sequences through synchronized caches,
10723        // every decoded value equals the original (canonical stateless re-encode). The
10724        // cached protocol must never change the MEANING — only the bytes. Schemas
10725        // repeat, so definitions, references, and non-struct messages all interleave.
10726        fn gen_msg(rng: &mut SplitMix64) -> RuntimeValue {
10727            match rng.below(6) {
10728                0 => RuntimeValue::Int(rng.next() as i64),
10729                1 => RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Ints((0..rng.below(20) as i64).collect())))),
10730                2 => struct_list(rng.below(20) as i64),
10731                3 => RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Boxed(
10732                    (0..rng.below(20) as i64).map(person).collect(),
10733                )))),
10734                4 => RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Boxed(
10735                    (0..rng.below(15)).map(|i| RuntimeValue::Text(Rc::new(format!("s{i}")))).collect(),
10736                )))),
10737                _ => RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Boxed(
10738                    (0..rng.below(12) as i64)
10739                        .map(|i| if i % 2 == 0 { enum_val("Option", "Some", vec![RuntimeValue::Int(i)]) } else { enum_val("Option", "None", vec![]) })
10740                        .collect(),
10741                )))),
10742            }
10743        }
10744        for seed in [1u64, 7, 42, 99, 1000, 0xDEAD_BEEF, 0x00AB_CDEF] {
10745            let mut rng = SplitMix64 { state: seed };
10746            let mut sc = WireSchemaCache::default();
10747            let mut rc = WireSchemaCache::default();
10748            for step in 0..120 {
10749                let v = gen_msg(&mut rng);
10750                let bytes = message_to_wire_cached("p", &v, WireCodec::Native, WireIntegrity::Raw, &mut sc).unwrap();
10751                let (_from, back) = message_from_wire_cached(&bytes, &mut rc).unwrap_or_else(|| panic!("seed {seed} step {step}: cached decode returned None"));
10752                assert_eq!(
10753                    message_to_wire("p", &back).unwrap(),
10754                    message_to_wire("p", &v).unwrap(),
10755                    "seed {seed} step {step}: cached round-trip changed the value"
10756                );
10757            }
10758        }
10759    }
10760
10761    #[test]
10762    fn wire_schema_content_addressed_survives_multi_sender_reorder_and_loss() {
10763        // THE FOOTGUN PROOF. Many senders share ONE receiver cache; the stream is
10764        // adversarially reordered and ~20% dropped. Every decode is EITHER exactly
10765        // correct OR None — never a wrong value. (Sequential ids would corrupt here;
10766        // content-addressing cannot, because the id IS the schema's content.)
10767        fn gen(rng: &mut SplitMix64) -> RuntimeValue {
10768            match rng.below(4) {
10769                0 => struct_list(rng.below(15) as i64),
10770                1 => RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Boxed((0..rng.below(15) as i64).map(person).collect())))),
10771                2 => RuntimeValue::Int(rng.next() as i64),
10772                _ => RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Ints((0..rng.below(15) as i64).collect())))),
10773            }
10774        }
10775        for seed in [3u64, 17, 71, 2024, 0xFEED, 0xBADF00D] {
10776            let mut rng = SplitMix64 { state: seed };
10777            // Three senders, each its OWN content-addressed send cache.
10778            let mut sends: Vec<WireSchemaCache> = (0..3).map(|_| WireSchemaCache::content_addressed()).collect();
10779            let mut stream: Vec<(Vec<u8>, RuntimeValue)> = Vec::new();
10780            for _ in 0..80 {
10781                let s = rng.below(3) as usize;
10782                let v = gen(&mut rng);
10783                let bytes = message_to_wire_cached("p", &v, WireCodec::Native, WireIntegrity::Raw, &mut sends[s]).unwrap();
10784                stream.push((bytes, v));
10785            }
10786            // Adversary: Fisher–Yates shuffle (reordering) ...
10787            for i in (1..stream.len()).rev() {
10788                let j = rng.below((i + 1) as u64) as usize;
10789                stream.swap(i, j);
10790            }
10791            // ... and decode through ONE shared receiver, dropping ~20%.
10792            let mut recv = WireSchemaCache::content_addressed();
10793            for (bytes, orig) in &stream {
10794                if rng.below(5) == 0 {
10795                    continue; // dropped before reaching the decoder (loss)
10796                }
10797                if let Some((_from, back)) = message_from_wire_cached(bytes, &mut recv) {
10798                    assert_eq!(
10799                        message_to_wire("p", &back).unwrap(),
10800                        message_to_wire("p", orig).unwrap(),
10801                        "seed {seed}: a shared cache under reorder+loss decoded the WRONG value"
10802                    );
10803                }
10804                // None is an acceptable outcome (a reference whose definition was
10805                // dropped or has not yet arrived) — it is a clean miss, not corruption.
10806            }
10807        }
10808    }
10809
10810    #[test]
10811    fn wire_schema_keyframe_self_heals_after_missed_definition() {
10812        // With a keyframe interval, the sender re-defines the schema every k references,
10813        // so a receiver that joined late (missed the first definition) recovers.
10814        let v = struct_list(10);
10815        let mut send = WireSchemaCache::content_addressed().with_keyframe(2);
10816        let msgs: Vec<Vec<u8>> = (0..6)
10817            .map(|_| message_to_wire_cached("p", &v, WireCodec::Native, WireIntegrity::Raw, &mut send).unwrap())
10818            .collect();
10819        // Emission pattern is [Def, Ref, Ref, Def(keyframe), Ref, Ref].
10820        let mut recv = WireSchemaCache::content_addressed();
10821        assert!(message_from_wire_cached(&msgs[1], &mut recv).is_none(), "a reference before any definition → None");
10822        assert!(message_from_wire_cached(&msgs[3], &mut recv).is_some(), "the keyframe re-definition decodes and heals the cache");
10823        let d = message_from_wire_cached(&msgs[4], &mut recv).unwrap().1;
10824        assert_eq!(message_to_wire("p", &d).unwrap(), message_to_wire("p", &v).unwrap(), "references resolve after the keyframe");
10825    }
10826
10827    #[test]
10828    fn wire_schema_mode_dial_trades_size() {
10829        // The dial: sequential (1-byte id) < content-addressed (8-byte fingerprint) <
10830        // inline (full schema). All three round-trip; smaller modes need more
10831        // discipline (sequential = one ordered sender), proven safe elsewhere.
10832        let v = struct_list(50);
10833        let ref_size = |mode_cache: fn() -> WireSchemaCache| {
10834            let mut c = mode_cache();
10835            let _def = message_to_wire_cached("p", &v, WireCodec::Native, WireIntegrity::Raw, &mut c).unwrap();
10836            message_to_wire_cached("p", &v, WireCodec::Native, WireIntegrity::Raw, &mut c).unwrap().len()
10837        };
10838        let seq = ref_size(WireSchemaCache::sequential);
10839        let ca = ref_size(WireSchemaCache::content_addressed);
10840        let inline = message_to_wire("p", &v).unwrap().len();
10841        assert!(seq < ca, "sequential ref ({seq}) < content-addressed ref ({ca})");
10842        assert!(ca < inline, "content-addressed ref ({ca}) < inline schema ({inline})");
10843        // Sequential round-trips on a single ordered stream.
10844        let mut s = WireSchemaCache::sequential();
10845        let mut r = WireSchemaCache::sequential();
10846        let m1 = message_to_wire_cached("p", &v, WireCodec::Native, WireIntegrity::Raw, &mut s).unwrap();
10847        let m2 = message_to_wire_cached("p", &v, WireCodec::Native, WireIntegrity::Raw, &mut s).unwrap();
10848        let d1 = message_from_wire_cached(&m1, &mut r).unwrap().1;
10849        let d2 = message_from_wire_cached(&m2, &mut r).unwrap().1;
10850        assert_eq!(message_to_wire("p", &d1).unwrap(), message_to_wire("p", &v).unwrap());
10851        assert_eq!(message_to_wire("p", &d2).unwrap(), message_to_wire("p", &v).unwrap());
10852    }
10853
10854    #[test]
10855    fn schema_cache_survives_a_panic_in_the_codec() {
10856        // The CacheScope RAII guard restores the thread-local cache on a panic unwind,
10857        // so a panic mid-codec can't strand or reset the schema state.
10858        let v = struct_list(20);
10859        let mut cache = WireSchemaCache::content_addressed();
10860        let _def = message_to_wire_cached("p", &v, WireCodec::Native, WireIntegrity::Raw, &mut cache).unwrap();
10861        let r = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
10862            let _scope = CacheScope::enter(&mut cache);
10863            panic!("boom mid-codec");
10864        }));
10865        assert!(r.is_err(), "the panic propagated");
10866        // The cache still remembers the schema → the next send is a (smaller) reference.
10867        let after = message_to_wire_cached("p", &v, WireCodec::Native, WireIntegrity::Raw, &mut cache).unwrap();
10868        let fresh = {
10869            let mut f = WireSchemaCache::content_addressed();
10870            message_to_wire_cached("p", &v, WireCodec::Native, WireIntegrity::Raw, &mut f).unwrap()
10871        };
10872        assert!(after.len() < fresh.len(), "cache survived the panic (ref {} < fresh def {})", after.len(), fresh.len());
10873    }
10874
10875    #[test]
10876    fn schema_cache_sequential_and_content_addressed_recv_are_disjoint() {
10877        // One receiver decoding interleaved sequential AND content-addressed messages
10878        // never cross-resolves — sequential uses recv_seq (ids), content uses recv_ca
10879        // (fingerprints), which are separate state. (Disproves the audit's "mode-mixing
10880        // collision" worry.)
10881        let v = struct_list(20);
10882        let mut seq = WireSchemaCache::sequential();
10883        let s_def = message_to_wire_cached("p", &v, WireCodec::Native, WireIntegrity::Raw, &mut seq).unwrap();
10884        let s_ref = message_to_wire_cached("p", &v, WireCodec::Native, WireIntegrity::Raw, &mut seq).unwrap();
10885        let mut ca = WireSchemaCache::content_addressed();
10886        let c_def = message_to_wire_cached("p", &v, WireCodec::Native, WireIntegrity::Raw, &mut ca).unwrap();
10887        let c_ref = message_to_wire_cached("p", &v, WireCodec::Native, WireIntegrity::Raw, &mut ca).unwrap();
10888        let mut rc = WireSchemaCache::content_addressed();
10889        for (bytes, label) in [(&s_def, "seq def"), (&c_def, "ca def"), (&s_ref, "seq ref"), (&c_ref, "ca ref")] {
10890            let d = message_from_wire_cached(bytes, &mut rc).unwrap_or_else(|| panic!("{label} failed to decode")).1;
10891            assert_eq!(message_to_wire("p", &d).unwrap(), message_to_wire("p", &v).unwrap(), "{label} reconstructs the list");
10892        }
10893    }
10894
10895    #[test]
10896    fn wire_integrity_dial_toggles_the_checksum() {
10897        // The latency↔safety dial: `Raw` drops the 8-byte FNV checksum (faster, header
10898        // bit 0x01 unset), `Checked` keeps it. Scoped — never leaks.
10899        let v = struct_list(50);
10900        let raw = with_integrity(WireIntegrity::Raw, || message_to_wire("p", &v).unwrap());
10901        let checked = with_integrity(WireIntegrity::Checked, || message_to_wire("p", &v).unwrap());
10902        assert_eq!(raw[0] & 0x01, 0, "Raw carries no checksum");
10903        assert_eq!(checked[0] & 0x01, 0x01, "Checked sets the checksum bit");
10904        assert_eq!(checked.len(), raw.len() + 8, "the checksum is 8 bytes");
10905        assert!(message_from_wire(&raw).is_some() && message_from_wire(&checked).is_some(), "both decode");
10906        // Scoped: outside the override the process default is restored.
10907        let default_bit = if default_integrity() == WireIntegrity::Checked { 0x01 } else { 0 };
10908        assert_eq!(message_to_wire("p", &v).unwrap()[0] & 0x01, default_bit, "the override does not leak");
10909    }
10910
10911    #[test]
10912    fn uvarint_byte_len_matches_write_uvarint() {
10913        for x in [0u64, 1, 127, 128, 16_383, 16_384, u32::MAX as u64, u64::MAX, 0x1234_5678_9ABC_DEF0] {
10914            let mut buf = Vec::new();
10915            write_uvarint(x, &mut buf);
10916            assert_eq!(uvarint_byte_len(x), buf.len(), "uvarint_byte_len({x:#x}) must match write_uvarint");
10917        }
10918    }
10919
10920    #[test]
10921    fn wire_json_codec_is_real_json() {
10922        let v = RuntimeValue::Text(Rc::new("hi".to_string()));
10923        let bytes = message_to_wire_with("alice", &v, WireCodec::Json, WireIntegrity::Raw).unwrap();
10924        // The body after the 1-byte header parses as JSON via a real parser.
10925        let json: serde_json::Value = serde_json::from_slice(&bytes[1..]).expect("valid JSON body");
10926        assert_eq!(json["from"], "alice");
10927    }
10928
10929    #[test]
10930    fn wire_native_is_far_tighter_than_json() {
10931        // The throughput win: a 100-int array is a fraction of the JSON size.
10932        let items: Vec<RuntimeValue> = (0..100).map(RuntimeValue::Int).collect();
10933        let v = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::from_values(items))));
10934        let bin = message_to_wire_with("", &v, WireCodec::Native, WireIntegrity::Raw).unwrap();
10935        let json = message_to_wire_with("", &v, WireCodec::Json, WireIntegrity::Raw).unwrap();
10936        assert!(
10937            bin.len() * 2 < json.len(),
10938            "native ({} bytes) should be far tighter than json ({} bytes)",
10939            bin.len(),
10940            json.len()
10941        );
10942    }
10943
10944    #[test]
10945    fn wire_decoder_never_panics_on_arbitrary_bytes() {
10946        let mut rng = SplitMix64 { state: 0x1234_5678 };
10947        for _ in 0..5000 {
10948            let len = rng.below(80) as usize;
10949            let bytes: Vec<u8> = (0..len).map(|_| (rng.next() & 0xFF) as u8).collect();
10950            let _ = message_from_wire(&bytes); // must not panic
10951        }
10952        // Every possible header byte with a short body.
10953        for h in 0u16..=255 {
10954            let _ = message_from_wire(&[h as u8, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
10955        }
10956    }
10957
10958    #[test]
10959    fn wire_decoder_never_panics_on_mutated_valid_messages() {
10960        // Random bytes almost never form a valid tag, so they never reach the deep
10961        // columnar / schema-cache paths. Here we take a VALID message of each archetype
10962        // and mutate it every which way — truncate at every length, flip every byte to
10963        // a few values, scramble bytes — and assert the decoder NEVER panics (it
10964        // returns None or a structurally-valid Some that itself re-encodes without
10965        // panicking). This is the robustness floor the whole protocol rests on.
10966        fn archetypes() -> Vec<RuntimeValue> {
10967            vec![
10968                RuntimeValue::Int(42),
10969                RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Ints((0..5).collect())))),
10970                RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Floats((0..5).map(|i| i as f64 * 1.5).collect())))),
10971                RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Bools((0..5).map(|i| i % 2 == 0).collect())))),
10972                RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Boxed(
10973                    (0..4).map(|i| RuntimeValue::Text(Rc::new(format!("s{i}")))).collect(),
10974                )))),
10975                struct_list(4),
10976                RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Boxed(
10977                    (0..6)
10978                        .map(|i| if i % 2 == 0 { enum_val("Option", "Some", vec![RuntimeValue::Int(i)]) } else { enum_val("Option", "None", vec![]) })
10979                        .collect(),
10980                )))),
10981            ]
10982        }
10983        // A mutated buffer must never panic; if it decodes, the value re-encodes.
10984        let check = |bytes: &[u8]| {
10985            if let Some((_from, v)) = message_from_wire(bytes) {
10986                let _ = message_to_wire("p", &v);
10987            }
10988            let mut c = WireSchemaCache::content_addressed();
10989            if let Some((_from, v)) = message_from_wire_cached(bytes, &mut c) {
10990                let _ = message_to_wire("p", &v);
10991            }
10992        };
10993        let mut rng = SplitMix64 { state: 0x00AB_CDEF };
10994        for v in archetypes() {
10995            // Plain, cached-def, and cached-ref encodings all get mutated.
10996            let mut sc = WireSchemaCache::content_addressed();
10997            let bases = [
10998                message_to_wire("p", &v).unwrap(),
10999                message_to_wire_cached("p", &v, WireCodec::Native, WireIntegrity::Raw, &mut sc).unwrap(),
11000                message_to_wire_cached("p", &v, WireCodec::Native, WireIntegrity::Raw, &mut sc).unwrap(),
11001            ];
11002            for base in &bases {
11003                check(base); // the valid form decodes
11004                for k in 0..base.len() {
11005                    check(&base[..k]); // every truncation
11006                }
11007                for i in 0..base.len() {
11008                    for delta in [0x01u8, 0x40, 0x7F, 0x80, 0xFF] {
11009                        let mut m = base.clone();
11010                        m[i] ^= delta;
11011                        check(&m); // every single-byte flip
11012                    }
11013                }
11014                for _ in 0..30 {
11015                    let mut m = base.clone();
11016                    if !m.is_empty() {
11017                        let i = rng.below(m.len() as u64) as usize;
11018                        m[i] = (rng.next() & 0xFF) as u8;
11019                    }
11020                    check(&m); // random scramble
11021                }
11022            }
11023        }
11024    }
11025
11026    #[test]
11027    fn wire_property_random_values_are_byte_stable() {
11028        for seed in [1u64, 2, 7, 42, 99, 1000, 0x00AB_CDEF, 0xDEAD_BEEF] {
11029            let mut rng = SplitMix64 { state: seed };
11030            for _ in 0..150 {
11031                let v = gen_value(&mut rng, 4);
11032                assert_wire_stable(&v);
11033            }
11034        }
11035    }
11036
11037    #[test]
11038    fn wire_packed_int_array_is_tight_and_stays_packed() {
11039        let n = 5000i64;
11040        let v = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Ints((0..n).collect()))));
11041        assert_wire_stable(&v);
11042        let bytes = message_to_wire_with("", &v, WireCodec::Native, WireIntegrity::Raw).unwrap();
11043        // Packed: ~2 bytes/int at these magnitudes — far under a tagged element each.
11044        assert!(bytes.len() < n as usize * 3, "packed ints should be tight, was {} bytes", bytes.len());
11045        match message_from_wire(&bytes).unwrap().1 {
11046            RuntimeValue::List(l) => assert!(matches!(&*l.borrow(), ListRepr::Ints(_)), "decodes to a packed Ints buffer"),
11047            other => panic!("expected a list, got {other:?}"),
11048        }
11049    }
11050
11051    #[test]
11052    fn wire_fixed_width_int_mode_is_memcpy_and_interops() {
11053        let v = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Ints((0..1000).collect()))));
11054        let varint = message_to_wire("", &v).unwrap();
11055        let fixed = with_fixed_numerics(|| message_to_wire("", &v).unwrap());
11056        // Fixed-width is the raw i64 bytes — bigger than varint (no compression),
11057        // but a memcpy to load (8 bytes/int + small framing).
11058        assert!(fixed.len() > varint.len(), "fixed-width should be larger than varint");
11059        assert!(fixed.len() >= 1000 * 8, "fixed is 8 bytes/int, was {}", fixed.len());
11060        // Both encodings interoperate — the decoder handles either tag.
11061        let vals = |bytes: &[u8]| match message_from_wire(bytes).unwrap().1 {
11062            RuntimeValue::List(l) => l.borrow().to_values(),
11063            other => panic!("expected a list, got {other:?}"),
11064        };
11065        let expected: Vec<RuntimeValue> = (0..1000).map(RuntimeValue::Int).collect();
11066        assert_eq!(vals(&varint), expected);
11067        assert_eq!(vals(&fixed), expected);
11068        // Scoped: the mode does not leak past `with_fixed_numerics`.
11069        assert_eq!(message_to_wire("", &v).unwrap(), varint);
11070    }
11071
11072    #[test]
11073    fn gv_simd_decode_matches_scalar_oracle_over_fuzz() {
11074        // The SSSE3 fast path must be bit-identical to the scalar `gv_decode`
11075        // oracle. We sweep magnitudes so every 2-bit width code {1,2,4,8 bytes}
11076        // and thus every adjacent `(code_a, code_b)` shuffle-mask is exercised,
11077        // and lengths so the even SIMD body, the odd tail, and the near-buffer-end
11078        // tail all fire. `gv_decode_dispatch` takes the SIMD path on this host.
11079        for seed in [1u64, 2, 7, 42, 99, 1000, 0xDEAD_BEEF, 0x00AB_CDEF] {
11080            let mut rng = SplitMix64 { state: seed };
11081            for _ in 0..200 {
11082                let n = (rng.below(37)) as usize; // 0, odd, and >16-int blocks
11083                let vals: Vec<i64> = (0..n)
11084                    .map(|_| {
11085                        let bits = rng.below(64) as u32; // span all four width buckets
11086                        let mask = (1u128 << bits).wrapping_sub(1) as u64;
11087                        let mag = (rng.next() & mask) as i64;
11088                        if rng.next() & 1 == 0 { mag } else { -mag }
11089                    })
11090                    .collect();
11091                let mut buf = Vec::new();
11092                gv_encode(&mut buf, vals.iter().copied(), vals.len());
11093
11094                let (mut p1, mut p2) = (0usize, 0usize);
11095                let scalar = gv_decode(&buf, &mut p1).expect("scalar decode");
11096                let simd = gv_decode_dispatch(&buf, &mut p2).expect("dispatch decode");
11097
11098                assert_eq!(scalar, vals, "scalar oracle lost data (seed {seed}, n {n})");
11099                assert_eq!(simd, vals, "simd/dispatch lost data (seed {seed}, n {n})");
11100                assert_eq!(p1, p2, "decoders consumed a different byte count (seed {seed})");
11101            }
11102        }
11103    }
11104
11105    #[test]
11106    fn wire_group_varint_mode_interops_with_varint() {
11107        let v = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Ints(
11108            (0..1000).map(|i| i * i - 500_000).collect(),
11109        ))));
11110        let varint = message_to_wire("", &v).unwrap();
11111        let gv = with_numerics(WireNumerics::GroupVarint, || message_to_wire("", &v).unwrap());
11112        // The numeric tag is self-describing — either encoding decodes to the same
11113        // values, regardless of which strategy produced it.
11114        let vals = |bytes: &[u8]| match message_from_wire(bytes).unwrap().1 {
11115            RuntimeValue::List(l) => l.borrow().to_values(),
11116            other => panic!("expected a list, got {other:?}"),
11117        };
11118        assert_eq!(vals(&varint), vals(&gv));
11119        let expected: Vec<RuntimeValue> = (0..1000).map(|i| RuntimeValue::Int(i * i - 500_000)).collect();
11120        assert_eq!(vals(&gv), expected);
11121        // Scoped: the mode does not leak past `with_numerics`.
11122        assert_eq!(message_to_wire("", &v).unwrap(), varint);
11123    }
11124
11125    #[test]
11126    fn wire_packed_float_array_roundtrips_bit_exact() {
11127        let v = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Floats(vec![
11128            0.0, -0.0, 1.5, f64::NAN, f64::INFINITY, f64::NEG_INFINITY, f64::MIN, f64::MAX,
11129        ]))));
11130        assert_wire_stable(&v); // byte-stability ⇒ bit-exact, NaN included
11131        match message_from_wire(&message_to_wire("", &v).unwrap()).unwrap().1 {
11132            RuntimeValue::List(l) => assert!(matches!(&*l.borrow(), ListRepr::Floats(_))),
11133            other => panic!("expected a list, got {other:?}"),
11134        }
11135    }
11136
11137    fn floats_list(vals: Vec<f64>) -> RuntimeValue {
11138        RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Floats(vals))))
11139    }
11140    fn float_bits(v: &RuntimeValue) -> Vec<u64> {
11141        match v {
11142            RuntimeValue::List(l) => match &*l.borrow() {
11143                ListRepr::Floats(f) => f.iter().map(|x| x.to_bits()).collect(),
11144                other => panic!("not a float list: {other:?}"),
11145            },
11146            other => panic!("not a list: {other:?}"),
11147        }
11148    }
11149
11150    #[test]
11151    fn wire_floats_xor_is_bit_exact_including_special_values() {
11152        // The XOR-delta float codec operates on raw bits, so it is LOSSLESS and
11153        // bit-exact for every f64 — NaN payloads, ±Inf, ±0.0, subnormals included.
11154        let vals = vec![1.0, 1.0000001, 1.0000002, f64::NAN, f64::INFINITY, f64::NEG_INFINITY, -0.0, 0.0, f64::MIN, f64::MAX, f64::MIN_POSITIVE];
11155        let v = floats_list(vals.clone());
11156        let bytes = with_floats(WireFloats::XorDelta, || message_to_wire("p", &v).unwrap());
11157        let back = message_from_wire(&bytes).unwrap().1;
11158        let orig: Vec<u64> = vals.iter().map(|x| x.to_bits()).collect();
11159        assert_eq!(float_bits(&back), orig, "XOR-delta float column is bit-exact");
11160    }
11161
11162    #[test]
11163    fn wire_floats_xor_shrinks_slow_varying() {
11164        // Consecutive samples share their high bits, so XOR-delta + varint is far
11165        // smaller than 8 bytes/elem memcpy — the time-series win.
11166        let vals: Vec<f64> = (0..1000).map(|i| 100.0 + i as f64 * 1e-6).collect();
11167        let v = floats_list(vals);
11168        let memcpy = message_to_wire("p", &v).unwrap();
11169        let xor = with_floats(WireFloats::XorDelta, || message_to_wire("p", &v).unwrap());
11170        assert!(xor.len() < memcpy.len(), "XOR-delta shrinks a slow-varying column: {} vs {}", xor.len(), memcpy.len());
11171        assert_eq!(float_bits(&message_from_wire(&xor).unwrap().1), float_bits(&message_from_wire(&memcpy).unwrap().1));
11172    }
11173
11174    #[test]
11175    fn wire_floats_xor_never_grows() {
11176        // A high-entropy column: XOR-delta would be larger, so the encoder falls back
11177        // to memcpy — never bigger than the baseline.
11178        let mut rng = SplitMix64 { state: 12345 };
11179        let vals: Vec<f64> = (0..1000).map(|_| f64::from_bits(rng.next())).collect();
11180        let v = floats_list(vals);
11181        let memcpy = message_to_wire("p", &v).unwrap();
11182        let xor = with_floats(WireFloats::XorDelta, || message_to_wire("p", &v).unwrap());
11183        assert!(xor.len() <= memcpy.len(), "XOR-delta must never grow vs memcpy: {} vs {}", xor.len(), memcpy.len());
11184        assert_eq!(float_bits(&message_from_wire(&xor).unwrap().1), float_bits(&message_from_wire(&memcpy).unwrap().1));
11185    }
11186
11187    #[test]
11188    fn wire_floats_xor_fuzz_bit_identical() {
11189        // Random columns mixing slow-varying runs and arbitrary bit patterns: the
11190        // XOR-delta decode is bit-identical to the original, always.
11191        for seed in [1u64, 7, 42, 1000, 0xBEEF, 0xC0FFEE] {
11192            let mut rng = SplitMix64 { state: seed };
11193            for _ in 0..200 {
11194                let n = rng.below(30) as usize;
11195                let base = f64::from_bits(rng.next());
11196                let vals: Vec<f64> = (0..n)
11197                    .map(|i| if rng.below(2) == 0 { base + i as f64 * 1e-9 } else { f64::from_bits(rng.next()) })
11198                    .collect();
11199                let v = floats_list(vals.clone());
11200                let xor = with_floats(WireFloats::XorDelta, || message_to_wire("p", &v).unwrap());
11201                let orig: Vec<u64> = vals.iter().map(|x| x.to_bits()).collect();
11202                assert_eq!(float_bits(&message_from_wire(&xor).unwrap().1), orig, "seed {seed}: XOR-delta diverged");
11203            }
11204        }
11205    }
11206
11207    #[test]
11208    fn wire_packed_bool_array_is_bit_packed() {
11209        let n = 1000usize;
11210        let v = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Bools((0..n).map(|i| i % 3 == 0).collect()))));
11211        assert_wire_stable(&v);
11212        let bytes = message_to_wire_with("", &v, WireCodec::Native, WireIntegrity::Raw).unwrap();
11213        // 8 booleans per byte → ~125 bytes for 1000, not ~1000.
11214        assert!(bytes.len() < n / 4, "bools must be bit-packed: {} bytes for {} bools", bytes.len(), n);
11215        match message_from_wire(&bytes).unwrap().1 {
11216            RuntimeValue::List(l) => assert!(matches!(&*l.borrow(), ListRepr::Bools(_))),
11217            other => panic!("expected a list, got {other:?}"),
11218        }
11219    }
11220
11221    #[test]
11222    fn wire_mixed_list_stays_generic() {
11223        let v = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Boxed(vec![
11224            RuntimeValue::Int(1),
11225            RuntimeValue::Text(Rc::new("x".to_string())),
11226            RuntimeValue::Bool(true),
11227        ]))));
11228        assert_wire_stable(&v);
11229        match message_from_wire(&message_to_wire("", &v).unwrap()).unwrap().1 {
11230            RuntimeValue::List(l) => assert!(matches!(&*l.borrow(), ListRepr::Boxed(_)), "a mixed list stays Boxed"),
11231            other => panic!("expected a list, got {other:?}"),
11232        }
11233    }
11234
11235    #[test]
11236    fn wire_string_array_packs_flat_and_loads_flat() {
11237        let strs = ["alpha", "", "héllo", "日本語", "emoji😀", "z"];
11238        let v = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Boxed(
11239            strs.iter().map(|s| RuntimeValue::Text(Rc::new(s.to_string()))).collect(),
11240        ))));
11241        // Byte-stable: Boxed-of-Text → T_STRINGS → Strings → T_STRINGS (same bytes).
11242        assert_wire_stable(&v);
11243        let bytes = message_to_wire_with("", &v, WireCodec::Native, WireIntegrity::Raw).unwrap();
11244        match message_from_wire(&bytes).unwrap().1 {
11245            RuntimeValue::List(l) => {
11246                let b = l.borrow();
11247                assert!(matches!(&*b, ListRepr::Strings { .. }), "a string array loads FLAT, not per-element");
11248                assert_eq!(b.len(), strs.len());
11249                let got: Vec<String> = b
11250                    .to_values()
11251                    .into_iter()
11252                    .map(|x| match x {
11253                        RuntimeValue::Text(s) => (*s).clone(),
11254                        other => panic!("expected text, got {other:?}"),
11255                    })
11256                    .collect();
11257                assert_eq!(got, strs);
11258                // Indexed access (get) also materializes the right element.
11259                assert!(matches!(b.get(2), Some(RuntimeValue::Text(s)) if s.as_str() == "héllo"));
11260            }
11261            other => panic!("expected a list, got {other:?}"),
11262        }
11263    }
11264
11265    #[test]
11266    fn wire_flat_strings_memoize_repeated_get() {
11267        // Best-of-both: load flat, but a *repeated* get of the same element returns
11268        // the cached `Rc` (a refcount bump) rather than re-materializing the String.
11269        let v = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Boxed(vec![
11270            RuntimeValue::Text(Rc::new("a".to_string())),
11271            RuntimeValue::Text(Rc::new("bb".to_string())),
11272            RuntimeValue::Text(Rc::new("ccc".to_string())),
11273        ]))));
11274        let back = message_from_wire(&message_to_wire("", &v).unwrap()).unwrap().1;
11275        let RuntimeValue::List(l) = back else { panic!("expected a list") };
11276        let b = l.borrow();
11277        let (RuntimeValue::Text(first), RuntimeValue::Text(again)) = (b.get(1).unwrap(), b.get(1).unwrap())
11278        else {
11279            panic!("expected text")
11280        };
11281        assert_eq!(first.as_str(), "bb");
11282        assert!(Rc::ptr_eq(&first, &again), "a repeated get must reuse the memoized Rc, not re-allocate");
11283    }
11284
11285    #[test]
11286    fn wire_mixed_with_one_nonstring_stays_generic() {
11287        // All-string ⇒ flat; one non-string ⇒ falls back to the tagged list.
11288        let v = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Boxed(vec![
11289            RuntimeValue::Text(Rc::new("a".to_string())),
11290            RuntimeValue::Int(1),
11291            RuntimeValue::Text(Rc::new("c".to_string())),
11292        ]))));
11293        assert_wire_stable(&v);
11294        match message_from_wire(&message_to_wire("", &v).unwrap()).unwrap().1 {
11295            RuntimeValue::List(l) => assert!(matches!(&*l.borrow(), ListRepr::Boxed(_)), "mixed stays Boxed"),
11296            other => panic!("expected a list, got {other:?}"),
11297        }
11298    }
11299
11300    #[test]
11301    fn wire_i32_packed_list_roundtrips_through_ints() {
11302        // A half-width IntsI32 buffer encodes through the same packed path; it
11303        // rebuilds as full-width Ints (same values, same bytes — byte-stable).
11304        let v = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::IntsI32(vec![1, -2, 3, -4, 100]))));
11305        assert_wire_stable(&v);
11306        let (_, back) = message_from_wire(&message_to_wire("", &v).unwrap()).unwrap();
11307        match back {
11308            RuntimeValue::List(l) => match &*l.borrow() {
11309                ListRepr::Ints(got) => assert_eq!(got, &vec![1i64, -2, 3, -4, 100]),
11310                other => panic!("expected Ints, got {other:?}"),
11311            },
11312            other => panic!("expected a list, got {other:?}"),
11313        }
11314    }
11315
11316    /// A running (non-ignored) report: for every payload × codec it prints the wire
11317    /// size + ratios and a light throughput sample, AND asserts the deterministic
11318    /// invariants (round-trip, native<json, zstd≤deflate, lz4 shrinks, columnar
11319    /// structs are compact). Run with `--nocapture` to read the numbers; the asserts
11320    /// hold either way. zstd is native-only, so this is a native-target test.
11321    #[cfg(not(target_arch = "wasm32"))]
11322    #[test]
11323    fn wire_codec_report() {
11324        use std::time::Instant;
11325
11326        fn enc(v: &RuntimeValue, comp: WireCompression, num: WireNumerics) -> Vec<u8> {
11327            with_numerics(num, || with_compression_codec(comp, || message_to_wire("p", v).unwrap()))
11328        }
11329
11330        let ints = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Ints((0..1000).collect()))));
11331        let floats =
11332            RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Floats((0..1000).map(|i| i as f64 * 1.5).collect()))));
11333        let bools = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Bools((0..1000).map(|i| i % 3 == 0).collect()))));
11334        let strings = redundant_list(200);
11335        let records = struct_list(1000);
11336        let payloads: [(&str, &RuntimeValue); 5] = [
11337            ("1000 ints", &ints),
11338            ("1000 floats", &floats),
11339            ("1000 bools", &bools),
11340            ("200 redundant strings", &strings),
11341            ("1000 structs (Point)", &records),
11342        ];
11343
11344        println!("\n=== WIRE CODEC REPORT ===");
11345        for (name, v) in payloads {
11346            let raw = enc(v, WireCompression::None, WireNumerics::Varint);
11347            let json = message_to_wire_with("p", v, WireCodec::Json, WireIntegrity::Raw).unwrap();
11348            println!(
11349                "\n{name}: native {} B | json {} B  ({:.1}× tighter than json)",
11350                raw.len(),
11351                json.len(),
11352                json.len() as f64 / raw.len() as f64
11353            );
11354            for comp in [WireCompression::None, WireCompression::Deflate, WireCompression::Lz4, WireCompression::Zstd] {
11355                let b = enc(v, comp, WireNumerics::Varint);
11356                assert!(message_from_wire(&b).is_some(), "{name}/{comp:?} must round-trip");
11357                let cn = format!("{comp:?}");
11358                println!("  {cn:<8} {:>7} B  ({:.2}× of native raw)", b.len(), b.len() as f64 / raw.len() as f64);
11359            }
11360            assert!(raw.len() < json.len(), "{name}: native must beat json");
11361        }
11362
11363        // Compression invariants on a hard-to-compress-no-more redundant payload.
11364        let red = redundant_list(1000);
11365        let raw = enc(&red, WireCompression::None, WireNumerics::Varint);
11366        let deflate = enc(&red, WireCompression::Deflate, WireNumerics::Varint);
11367        let lz4 = enc(&red, WireCompression::Lz4, WireNumerics::Varint);
11368        let zstd = enc(&red, WireCompression::Zstd, WireNumerics::Varint);
11369        assert!(lz4.len() < raw.len(), "lz4 shrinks redundant data ({} vs {})", lz4.len(), raw.len());
11370        assert!(deflate.len() < raw.len(), "deflate shrinks redundant data");
11371        assert!(zstd.len() <= deflate.len(), "zstd ratio ≤ deflate ({} vs {})", zstd.len(), deflate.len());
11372
11373        // Columnar structs are far smaller than the old per-row-boxed form.
11374        assert!(records_is_compact(&records), "columnar struct list must be compact");
11375
11376        // Light throughput sample (encode+decode), so the numbers are visible.
11377        for (name, v) in [("1000 ints", &ints), ("1000 structs", &records)] {
11378            let it = 2000u32;
11379            let t = Instant::now();
11380            let mut total = 0usize;
11381            for _ in 0..it {
11382                let b = message_to_wire("p", v).unwrap();
11383                total += message_from_wire(&b).map(|_| b.len()).unwrap();
11384            }
11385            let el = t.elapsed();
11386            println!(
11387                "  throughput {name:<13}: {:>9.0} msg/s  {:>7.1} MB/s",
11388                it as f64 / el.as_secs_f64(),
11389                total as f64 / el.as_secs_f64() / 1e6
11390            );
11391        }
11392    }
11393
11394    #[cfg(not(target_arch = "wasm32"))]
11395    fn records_is_compact(records: &RuntimeValue) -> bool {
11396        let b = message_to_wire("p", records).unwrap();
11397        b.len() < 6000
11398    }
11399
11400    #[test]
11401    #[ignore = "throughput benchmark — run with: cargo test -p logicaffeine-compile marshal::tests::bench_wire_throughput --release -- --ignored --nocapture"]
11402    fn bench_wire_throughput() {
11403        use bincode::Options;
11404        use std::time::Instant;
11405
11406        fn bench<F: FnMut() -> usize>(label: &str, iters: u32, mut f: F) {
11407            for _ in 0..(iters / 10).max(1) {
11408                f();
11409            } // warm up
11410            let t = Instant::now();
11411            let mut bytes = 0usize;
11412            for _ in 0..iters {
11413                bytes += f();
11414            }
11415            let el = t.elapsed();
11416            println!(
11417                "  {label:<26} {:>11.0} msg/s  {:>9.1} MB/s  ({:>8.0?}/op)",
11418                iters as f64 / el.as_secs_f64(),
11419                bytes as f64 / el.as_secs_f64() / 1e6,
11420                el / iters
11421            );
11422        }
11423
11424        // bincode-of-WireValue — an off-the-shelf binary format, for comparison.
11425        let bincode_enc = |v: &RuntimeValue| {
11426            let p = materialize(v).unwrap();
11427            let msg = rt_to_wire(&p).unwrap();
11428            wire_options().serialize(&WireMessage { from: "p".to_string(), msg }).unwrap()
11429        };
11430
11431        // Payloads across the type space.
11432        let mk_record = |i: i64| {
11433            let mut f = HashMap::new();
11434            f.insert("id".to_string(), RuntimeValue::Int(i));
11435            f.insert("name".to_string(), RuntimeValue::Text(Rc::new(format!("item-{i}"))));
11436            f.insert("active".to_string(), RuntimeValue::Bool(i % 2 == 0));
11437            RuntimeValue::Struct(Box::new(StructValue { type_name: "Record".to_string(), fields: f }))
11438        };
11439        let ints = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Ints((0..1000).collect()))));
11440        let floats =
11441            RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Floats((0..1000).map(|i| i as f64 * 1.5).collect()))));
11442        let bools = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Bools((0..1000).map(|i| i % 3 == 0).collect()))));
11443        let strings = RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Boxed(
11444            (0..200).map(|i| RuntimeValue::Text(Rc::new(format!("string-value-{i}")))).collect(),
11445        ))));
11446        let records =
11447            RuntimeValue::List(Rc::new(RefCell::new(ListRepr::Boxed((0..200).map(mk_record).collect()))));
11448
11449        let payloads: [(&str, &RuntimeValue); 5] = [
11450            ("1000 ints", &ints),
11451            ("1000 floats", &floats),
11452            ("1000 bools", &bools),
11453            ("200 strings", &strings),
11454            ("200 records", &records),
11455        ];
11456
11457        for (name, v) in payloads {
11458            let nat = message_to_wire_with("p", v, WireCodec::Native, WireIntegrity::Raw).unwrap();
11459            let json = message_to_wire_with("p", v, WireCodec::Json, WireIntegrity::Raw).unwrap();
11460            let binc = bincode_enc(v);
11461            println!(
11462                "\n=== {name}: native {} B | bincode {} B | json {} B  ({:.1}× tighter than json) ===",
11463                nat.len(),
11464                binc.len(),
11465                json.len(),
11466                json.len() as f64 / nat.len() as f64
11467            );
11468            let it = 100_000;
11469            bench("native encode (raw)", it, || {
11470                message_to_wire_with("p", v, WireCodec::Native, WireIntegrity::Raw).unwrap().len()
11471            });
11472            bench("native encode (checked)", it, || {
11473                message_to_wire_with("p", v, WireCodec::Native, WireIntegrity::Checked).unwrap().len()
11474            });
11475            bench("bincode encode", it, || bincode_enc(v).len());
11476            bench("json encode", it, || {
11477                message_to_wire_with("p", v, WireCodec::Json, WireIntegrity::Raw).unwrap().len()
11478            });
11479            // Fixed-width numeric mode (memcpy) — only differs for int arrays.
11480            let nat_fixed = with_fixed_numerics(|| {
11481                message_to_wire_with("p", v, WireCodec::Native, WireIntegrity::Raw).unwrap()
11482            });
11483            if nat_fixed != nat {
11484                println!("  (fixed-width numerics: {} B vs varint {} B)", nat_fixed.len(), nat.len());
11485                bench("native encode (fixed)", it, || {
11486                    with_fixed_numerics(|| message_to_wire_with("p", v, WireCodec::Native, WireIntegrity::Raw).unwrap().len())
11487                });
11488                bench("native decode (fixed)", it, || {
11489                    message_from_wire(&nat_fixed).unwrap();
11490                    nat_fixed.len()
11491                });
11492            }
11493            // Group-varint numeric mode (SSSE3 shuffle decode) — also int-only. The
11494            // decode line is the headline: does SIMD beat LEB128 at varint size?
11495            let nat_gv = with_numerics(WireNumerics::GroupVarint, || {
11496                message_to_wire_with("p", v, WireCodec::Native, WireIntegrity::Raw).unwrap()
11497            });
11498            if nat_gv != nat {
11499                println!("  (group-varint numerics: {} B vs varint {} B)", nat_gv.len(), nat.len());
11500                bench("native encode (gv)", it, || {
11501                    with_numerics(WireNumerics::GroupVarint, || message_to_wire_with("p", v, WireCodec::Native, WireIntegrity::Raw).unwrap().len())
11502                });
11503                bench("native decode (gv/simd)", it, || {
11504                    message_from_wire(&nat_gv).unwrap();
11505                    nat_gv.len()
11506                });
11507            }
11508            bench("native decode (raw)", it, || {
11509                message_from_wire(&nat).unwrap();
11510                nat.len()
11511            });
11512            bench("bincode decode", it, || {
11513                let _: WireMessage = wire_options().deserialize(&binc).unwrap();
11514                binc.len()
11515            });
11516            bench("json decode", it, || {
11517                message_from_wire(&json).unwrap();
11518                json.len()
11519            });
11520        }
11521    }
11522
11523    // --- A seeded generator of arbitrary (network-portable) values ----------
11524
11525    struct SplitMix64 {
11526        state: u64,
11527    }
11528    impl SplitMix64 {
11529        fn next(&mut self) -> u64 {
11530            self.state = self.state.wrapping_add(0x9E37_79B9_7F4A_7C15);
11531            let mut z = self.state;
11532            z = (z ^ (z >> 30)).wrapping_mul(0xBF58_476D_1CE4_E5B9);
11533            z = (z ^ (z >> 27)).wrapping_mul(0x94D0_49BB_1331_11EB);
11534            z ^ (z >> 31)
11535        }
11536        fn below(&mut self, n: u64) -> u64 {
11537            self.next() % n
11538        }
11539    }
11540
11541    fn gen_char(rng: &mut SplitMix64) -> char {
11542        loop {
11543            if let Some(c) = char::from_u32((rng.next() % 0x11_0000) as u32) {
11544                return c;
11545            }
11546        }
11547    }
11548
11549    fn gen_string(rng: &mut SplitMix64) -> String {
11550        (0..rng.below(6)).map(|_| gen_char(rng)).collect()
11551    }
11552
11553    fn gen_value(rng: &mut SplitMix64, depth: u32) -> RuntimeValue {
11554        // At depth 0 only scalars (indices 0..12); deeper, containers too.
11555        let kinds = if depth == 0 { 12 } else { 18 };
11556        match rng.below(kinds) {
11557            0 => RuntimeValue::Int(rng.next() as i64),
11558            1 => RuntimeValue::Float(f64::from_bits(rng.next())),
11559            2 => RuntimeValue::Bool(rng.next() & 1 == 0),
11560            3 => RuntimeValue::Char(gen_char(rng)),
11561            4 => RuntimeValue::Text(Rc::new(gen_string(rng))),
11562            5 => RuntimeValue::Nothing,
11563            6 => RuntimeValue::Duration(rng.next() as i64),
11564            7 => RuntimeValue::Date(rng.next() as i32),
11565            8 => RuntimeValue::Moment(rng.next() as i64),
11566            9 => RuntimeValue::Span { months: rng.next() as i32, days: rng.next() as i32 },
11567            10 => RuntimeValue::Time(rng.next() as i64),
11568            11 => RuntimeValue::Peer(Rc::new(gen_string(rng))),
11569            12 => RuntimeValue::List(Rc::new(RefCell::new(ListRepr::from_values(
11570                (0..rng.below(4)).map(|_| gen_value(rng, depth - 1)).collect(),
11571            )))),
11572            13 => RuntimeValue::Tuple(Rc::new((0..rng.below(4)).map(|_| gen_value(rng, depth - 1)).collect())),
11573            14 => RuntimeValue::Set(Rc::new(RefCell::new(
11574                (0..rng.below(4)).map(|_| gen_value(rng, depth - 1)).collect(),
11575            ))),
11576            15 => {
11577                let mut m = MapStorage::default();
11578                for _ in 0..rng.below(4) {
11579                    // Keys are scalars (depth 0) so they stay hashable + simple.
11580                    m.insert(gen_value(rng, 0), gen_value(rng, depth - 1));
11581                }
11582                RuntimeValue::Map(Rc::new(RefCell::new(m)))
11583            }
11584            16 => {
11585                let mut fields = HashMap::new();
11586                for i in 0..rng.below(4) {
11587                    fields.insert(format!("f{i}"), gen_value(rng, depth - 1));
11588                }
11589                RuntimeValue::Struct(Box::new(StructValue { type_name: format!("T{}", rng.below(5)), fields }))
11590            }
11591            _ => RuntimeValue::Inductive(Box::new(InductiveValue {
11592                inductive_type: format!("I{}", rng.below(5)),
11593                constructor: format!("C{}", rng.below(5)),
11594                args: (0..rng.below(4)).map(|_| gen_value(rng, depth - 1)).collect(),
11595            })),
11596        }
11597    }
11598}