From 0b9c117c2aa8f4d1d849873b180db0f0ac8f8b71 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 6 Nov 2026 08:15:17 +0000 Subject: [PATCH 1/3] dt64: property-to-lane socket and joint route/frame witness (D-LANESOCK-1) LaneSource is implemented by a source owner: it maps (classid, SchemaRev, field position) to a LaneAddr (lane, coordinate space, reader scope) and lends its own lane. BindStore::bind_lanes resolves the class at a route, checks the basis and the frame, and takes one lane per requested field into a LaneBinding that holds addresses only. LaneBinding::check revalidates route (against the store's current version), frame, basis and mapping without allocating. Refuses: schema/basis/route errors, a re-route, foreign or stale frames, fields outside the basis, unbound fields, a lane in another row order than the selection (CoordinateSpace), another reader scope, a changed mapping and a vanished lane. dir-sim lab: two AD-owned property lanes bound through one ClassView basis, folded with Quack under the Ruler-plane selection (oracle parity), an Entra-order lane refused under the AD selection, reorder refusal, and zero hot allocations at 64K slots. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01XAqKMMJzKZrYnckXRC8x2U --- .../tests/ordinal_chain_lab.rs | 353 +++++++++++++++++- crates/lance-graph-dt64/src/lane.rs | 293 +++++++++++++++ crates/lance-graph-dt64/src/lib.rs | 2 + crates/lance-graph-dt64/tests/lane_socket.rs | 316 ++++++++++++++++ 4 files changed, 963 insertions(+), 1 deletion(-) create mode 100644 crates/lance-graph-dt64/src/lane.rs create mode 100644 crates/lance-graph-dt64/tests/lane_socket.rs diff --git a/crates/lance-graph-dir-sim/tests/ordinal_chain_lab.rs b/crates/lance-graph-dir-sim/tests/ordinal_chain_lab.rs index 0273ae37f..a4a33c7af 100644 --- a/crates/lance-graph-dir-sim/tests/ordinal_chain_lab.rs +++ b/crates/lance-graph-dir-sim/tests/ordinal_chain_lab.rs @@ -26,7 +26,7 @@ use lance_graph_dt64::{ use lance_graph_mask_risc::{ execute_into, Foreign, LaneRef, Out, Planes as QueryPlanes, Scratch, Value, }; -use lance_graph_quack::{lower, Agg, Col, Filter, Mask, Query}; +use lance_graph_quack::{lower, Agg, Cmp, Col, Filter, Mask, Query}; use ogar_dir_core::correspond::{ fold, fold_aligned, state, AdStatus, IdColumn, Index, Lanes, Output, Planes, Rows, Ruler, NO_ROW, @@ -998,3 +998,354 @@ fn batch_selection_at_64k_allocates_nothing() { count_time.as_nanos() / u128::from(PASSES), ); } + +// ---- D-LANESOCK-1: property lanes through the DR × DT64 socket -------------- +// +// The selection is the Ruler-plane batch above, in AD slot space (slot i is +// AD row i). The properties are AD-owned lanes, already in that row order, +// borrowed through `lance_graph_dt64::LaneSource`. An Entra-owned lane is in +// Entra row order and is refused, never re-indexed. + +mod lanesock { + use super::*; + use lance_graph_contract::class_view::{ClassId, ClassView}; + use lance_graph_contract::ontology::{DisplayTemplate, FieldRef}; + use lance_graph_dt64::dr::Scope; + use lance_graph_dt64::{ + CoordSpace, LaneAddr, LaneBinding, LaneRefusal, LaneRequest, LaneSource, RouteAt, + }; + + pub const HYBRID_USER: u32 = 0x0C1B_0001; + const VIEW_CLASS: ClassId = 0x0C1B; + pub const POSITION: u16 = 3; + pub const READER: Scope = Scope { id: 1 }; + pub const DEPARTMENT: u8 = 0; + pub const COST_CENTER: u8 = 1; + pub const LICENSES: u8 = 2; + + pub struct View(pub Vec); + impl ClassView for View { + fn fields(&self, class: ClassId) -> &[FieldRef] { + if class == VIEW_CLASS { + &self.0 + } else { + &[] + } + } + fn template(&self, _class: ClassId) -> DisplayTemplate { + DisplayTemplate::Detail + } + fn dolce_category_id(&self, _class: ClassId) -> u8 { + 0 + } + } + + pub fn view() -> View { + View(vec![ + FieldRef::new("ad:department", "Department"), + FieldRef::new("ad:costCenter", "Cost centre"), + FieldRef::new("entra:licenseCount", "Licenses"), + ]) + } + + /// The source owner: AD lanes in AD row order, an Entra lane in Entra row + /// order. It hands out its own slices. + pub struct Directory { + pub ad_space: CoordSpace, + pub entra_space: CoordSpace, + pub department: Vec, + pub cost_center: Vec, + pub licenses: Vec, + } + + impl Directory { + pub fn over(l: &Lanes, coordinates: u64) -> Directory { + Directory { + ad_space: CoordSpace { + population: 1, + coordinates, + }, + entra_space: CoordSpace { + population: 2, + coordinates, + }, + department: (0..l.ad.len()).map(|i| (i % 7) as i32).collect(), + cost_center: (0..l.ad.len()).map(|i| ((i * 37) % 300) as i32).collect(), + licenses: (0..l.entra.len()).map(|j| (j % 50) as i32).collect(), + } + } + } + + impl LaneSource for Directory { + type Lane<'a> = LaneRef<'a>; + fn lane_of( + &self, + class: u32, + rev: SchemaRev, + field: u8, + _frame: &Frame, + ) -> Option { + if class != HYBRID_USER || rev != SchemaRev(1) { + return None; + } + let (space, lane) = match field { + DEPARTMENT => (self.ad_space, 0), + COST_CENTER => (self.ad_space, 1), + LICENSES => (self.entra_space, 2), + _ => return None, + }; + Some(LaneAddr { + space, + lane, + scope: READER, + }) + } + fn borrow(&self, addr: &LaneAddr) -> Option> { + Some(LaneRef::I32(match addr.lane { + 0 => &self.department, + 1 => &self.cost_center, + 2 => &self.licenses, + _ => return None, + })) + } + } + + pub fn method(id: u32, reads: u8) -> MethodBinding { + MethodBinding { + id: MethodId(id), + sig_rev: SigRev(1), + name: format!("op{id}"), + on: WideFieldMask::EMPTY, + when: None, + reads: WideFieldMask::from_positions(&[reads]), + effects: Vec::new(), + population: Population::Distinct, + truth: Truth::TwoValued, + demand: ValueDemand::Values, + } + } + + pub struct Bound { + pub store: BindStore, + pub view: View, + pub frames: FrameStore, + pub frame: Frame, + pub route: RouteAt, + } + + pub fn bound() -> Bound { + let mut store = BindStore::new(); + store + .register( + HYBRID_USER, + ClassSchema { + schema_rev: SchemaRev(1), + field_count: 3, + extent: Extent::DR64_CUBE, + }, + vec![method(1, DEPARTMENT), method(2, COST_CENTER)], + ) + .unwrap(); + let version = store.route(POSITION, HYBRID_USER).unwrap(); + let frames = FrameStore::new(revisions(1, 1, 1)); + let frame = frames.seal(); + Bound { + store, + view: view(), + frames, + frame, + route: RouteAt { + position: POSITION, + version, + }, + } + } + + pub fn bind( + b: &Bound, + dir: &Directory, + fields: &[u8], + selection: CoordSpace, + ) -> Result { + let mask = WideFieldMask::from_positions(fields); + b.store.bind_lanes( + &b.view, + &b.frames, + dir, + LaneRequest { + route: b.route, + rev: SchemaRev(1), + fields: &mask, + frame: &b.frame, + scope: READER, + selection, + }, + ) + } +} + +/// Two properties of one ClassView basis, selected by one WideFieldMask, +/// bound under a witnessed frame; a DT64-admitted method drives a Quack fold +/// over a borrowed lane, and the same binding drives a second operation. +/// Scalar oracle parity on every seed. +#[test] +fn bound_property_lanes_fold_under_the_ruler_selection() { + use lanesock::*; + for seed in [2_u64, 13, 77] { + let l = faulted(300, seed); + let f = Fold::new(&l); + let b = bound(); + let dir = Directory::over(&l, 1); + let binding = bind(&b, &dir, &[DEPARTMENT, COST_CENTER], dir.ad_space).unwrap(); + assert!(binding.fields().has(DEPARTMENT) && binding.fields().has(COST_CENTER)); + + // Operation 1: the admitted method's `reads` names the lane it folds. + let m1 = MethodRef::of(HYBRID_USER, &method(1, DEPARTMENT)); + let admitted = b.store.admit(&m1).unwrap(); + assert!(admitted.reads.has(DEPARTMENT) && binding.fields().has(DEPARTMENT)); + let sum = lowered(confirmed_hybrid(), Agg::SumI32(Col(0))); + let dept = binding + .lane(&b.store, &b.view, &b.frames, &dir, DEPARTMENT) + .unwrap(); + let masks = plane_refs(&f.planes); + let lanes = [dept]; + let inputs = QueryPlanes { + n_rows: f.n, + masks: &masks, + lanes: &lanes, + }; + let mut scratch = Scratch::for_program(&sum, f.n).unwrap(); + let got = execute_into(&sum, &inputs, &Foreign::NONE, &mut scratch, Out::None).unwrap(); + + // Operation 2, same binding: confirmed ∧ cost_center > 150, counted. + let m2 = MethodRef::of(HYBRID_USER, &method(2, COST_CENTER)); + assert!(b.store.admit(&m2).unwrap().reads.has(COST_CENTER)); + let count = lowered( + Filter::and([confirmed_hybrid(), Filter::cmp(Col(0), Cmp::GtI32(150))]), + Agg::Count, + ); + let cost = binding + .lane(&b.store, &b.view, &b.frames, &dir, COST_CENTER) + .unwrap(); + let lanes = [cost]; + let inputs = QueryPlanes { + n_rows: f.n, + masks: &masks, + lanes: &lanes, + }; + let mut scratch = Scratch::for_program(&count, f.n).unwrap(); + let counted = + execute_into(&count, &inputs, &Foreign::NONE, &mut scratch, Out::None).unwrap(); + + // Independent scalar oracle over the raw lanes. + let confirmed: Vec = (0..f.n) + .filter(|&i| oracle_bound(&l, i).is_some()) + .collect(); + let want_sum: i64 = confirmed + .iter() + .map(|&i| i64::from(dir.department[i])) + .sum(); + let want_count = confirmed + .iter() + .filter(|&&i| dir.cost_center[i] > 150) + .count(); + assert_eq!(got, Value::SumI64(want_sum), "seed {seed}"); + assert_eq!(counted, Value::Count(want_count), "seed {seed}"); + assert!( + want_count > 0 && want_count < confirmed.len(), + "seed {seed}: non-trivial filter" + ); + } +} + +/// The Ruler selection is in AD slot space; an Entra-owned lane is in Entra +/// row order. Binding it under the AD selection refuses instead of reading +/// Entra values at AD positions. +#[test] +fn an_entra_lane_is_refused_under_an_ad_selection() { + use lanesock::*; + let l = faulted(130, 4); + let b = bound(); + let dir = Directory::over(&l, 1); + assert_eq!( + bind(&b, &dir, &[DEPARTMENT, LICENSES], dir.ad_space).err(), + Some(lance_graph_dt64::LaneRefusal::CoordinateSpace { + field: LICENSES, + selection: dir.ad_space, + lane: dir.entra_space, + }) + ); +} + +/// After the source reorders its AD rows and advances the frame, the old +/// binding refuses; a rebind under the new frame folds the reordered lanes. +#[test] +fn a_reordered_source_refuses_the_old_binding() { + use lanesock::*; + let l = faulted(130, 6); + let mut b = bound(); + let dir = Directory::over(&l, 1); + let binding = bind(&b, &dir, &[DEPARTMENT], dir.ad_space).unwrap(); + b.frames.advance(revisions(1, 1, 2)); + assert_eq!( + binding.check(&b.store, &b.view, &b.frames, &dir), + Err(lance_graph_dt64::LaneRefusal::Frame( + FrameRefusal::CoordinatesChanged + )) + ); + b.frame = b.frames.seal(); + let dir2 = Directory::over(&l, 2); + assert!(bind(&b, &dir2, &[DEPARTMENT], dir2.ad_space).is_ok()); + // The old directory's row-order revision no longer matches the selection. + assert!(matches!( + bind(&b, &dir, &[DEPARTMENT], dir2.ad_space), + Err(lance_graph_dt64::LaneRefusal::CoordinateSpace { .. }) + )); +} + +/// The hot path — revalidate the binding, borrow the lane, run the fold — +/// allocates nothing, at 64K slots. +#[test] +fn bound_lane_fold_at_64k_allocates_nothing() { + use lanesock::*; + use std::time::Instant; + let n = 1 << 16; + let l = faulted(n, 0xFEED); + let f = Fold::new(&l); + let b = bound(); + let dir = Directory::over(&l, 1); + let binding = bind(&b, &dir, &[DEPARTMENT, COST_CENTER], dir.ad_space).unwrap(); + let sum = lowered(confirmed_hybrid(), Agg::SumI32(Col(0))); + let mut scratch = Scratch::for_program(&sum, n).unwrap(); + let masks = plane_refs(&f.planes); + + const PASSES: u32 = 200; + let before = allocations(); + let t = Instant::now(); + let mut got = Value::SumI64(0); + for _ in 0..PASSES { + let dept = binding + .lane(&b.store, &b.view, &b.frames, &dir, DEPARTMENT) + .unwrap(); + let lanes = [dept]; + let inputs = QueryPlanes { + n_rows: n, + masks: &masks, + lanes: &lanes, + }; + got = execute_into(&sum, &inputs, &Foreign::NONE, &mut scratch, Out::None).unwrap(); + } + let hot = t.elapsed(); + let hot_allocations = allocations() - before; + + let want: i64 = (0..n) + .filter(|&i| oracle_bound(&l, i).is_some()) + .map(|i| i64::from(dir.department[i])) + .sum(); + assert_eq!(got, Value::SumI64(want)); + assert_eq!(hot_allocations, 0, "the bound-lane hot path allocated"); + eprintln!( + "64K slots: check+borrow+SumI32 {} ns/pass | hot allocations {hot_allocations}", + hot.as_nanos() / u128::from(PASSES) + ); +} diff --git a/crates/lance-graph-dt64/src/lane.rs b/crates/lance-graph-dt64/src/lane.rs new file mode 100644 index 000000000..dcfd26b6f --- /dev/null +++ b/crates/lance-graph-dt64/src/lane.rs @@ -0,0 +1,293 @@ +//! The property-to-lane socket and its joint version witness (D-LANESOCK-1, +//! `.claude/plans/d-lanesock-dr-dt64-lane-socket-v1.md`). +//! +//! A [`ClassView`] gives a class its field basis and a [`WideFieldMask`] +//! names the requested fields; neither is a physical address. The source +//! owner says, through [`LaneSource`], which of its own lanes holds a field +//! and in whose row order. [`BindStore::bind_lanes`] joins that answer with +//! the class route and the source frame into a [`LaneBinding`], which holds +//! addresses only, never a value. +//! +//! The class route and the frame are checked as a pair: the route against +//! this store's own route log, the frame against the [`FrameStore`] that +//! issued it. Neither clock stands in for the other. +//! +//! A lane whose row order differs from the selection's row order is refused +//! ([`LaneRefusal::CoordinateSpace`]): no mapping between coordinate spaces +//! is admitted here, so reading one through the other would be a gather. + +use lance_graph_contract::class_view::{ClassView, WideFieldMask}; + +use crate::dr::{Frame, FrameRefusal, FrameStore, RouteVersion, Scope}; +use crate::{BindStore, Refusal, SchemaRev}; + +/// Whose row order a lane is in: a source population and the revision of +/// that population's row order. +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct CoordSpace { + pub population: u64, + pub coordinates: u64, +} + +/// A source-owned lane: which lane, in whose row order, for which reader +/// scope. An address; it carries no value. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub struct LaneAddr { + pub space: CoordSpace, + pub lane: u16, + pub scope: Scope, +} + +/// The socket a source owner implements. `lane_of` returning `None` means +/// the field is unbound, which is refused, never read as empty. `borrow` +/// hands out the source's own lane; it must not copy, reorder or allocate a +/// lane. +pub trait LaneSource { + /// The borrowed lane (for example a mask-RISC `LaneRef`). + type Lane<'a> + where + Self: 'a; + + fn lane_of(&self, class: u32, rev: SchemaRev, field: u8, frame: &Frame) -> Option; + + fn borrow(&self, addr: &LaneAddr) -> Option>; +} + +/// A DR position and the route version it was resolved at. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub struct RouteAt { + pub position: u16, + pub version: RouteVersion, +} + +/// What [`BindStore::bind_lanes`] is asked to bind. +#[derive(Debug, Clone, Copy)] +pub struct LaneRequest<'a> { + pub route: RouteAt, + pub rev: SchemaRev, + pub fields: &'a WideFieldMask, + pub frame: &'a Frame, + /// The reader's scope; every lane must serve exactly this scope. + pub scope: Scope, + /// The row order of the selection the lanes will be read under. + pub selection: CoordSpace, +} + +/// Why a lane binding was refused. +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum LaneRefusal { + /// The class, route, schema revision or field basis (see [`Refusal`]). + Bind(Refusal), + /// The position routes to another class (or none) than it did at bind. + RouteChanged { + position: u16, + bound: u32, + now: Option, + }, + /// The frame is foreign, stale or re-sealed. + Frame(FrameRefusal), + /// A requested field lies outside the class basis. + FieldNotInBasis { class: u32, field: u8 }, + /// The source declares no lane for the field. + Unbound { class: u32, field: u8 }, + /// The lane's row order is not the selection's. + CoordinateSpace { + field: u8, + selection: CoordSpace, + lane: CoordSpace, + }, + /// The lane serves another reader scope. + Scope { + field: u8, + reader: Scope, + lane: Scope, + }, + /// The source maps the field to another lane than it did at bind. + MappingChanged { field: u8 }, + /// The source no longer holds the lane. + Vanished { field: u8 }, + /// The field was not part of the binding. + NotBound { field: u8 }, +} + +impl From for LaneRefusal { + fn from(r: Refusal) -> LaneRefusal { + LaneRefusal::Bind(r) + } +} + +/// A validated set of lane addresses for one class under one route and one +/// frame. Holds addresses only. +#[derive(Debug, Clone)] +pub struct LaneBinding { + class: u32, + rev: SchemaRev, + route: RouteAt, + frame: Frame, + scope: Scope, + selection: CoordSpace, + fields: WideFieldMask, + lanes: Vec<(u8, LaneAddr)>, +} + +impl BindStore { + /// Cold: resolve the class at `req.route`, check the basis at `req.rev`, + /// check the frame, and take one lane per requested field from `source`. + /// Every condition in [`LaneRefusal`] refuses. + pub fn bind_lanes( + &self, + view: &V, + frames: &FrameStore, + source: &S, + req: LaneRequest<'_>, + ) -> Result { + frames.check(req.frame).map_err(LaneRefusal::Frame)?; + let class = self + .routed_at(req.route.version, req.route.position)? + .ok_or(Refusal::Unrouted { + position: req.route.position, + version: req.route.version, + })?; + current_route(self, req.route.position, class)?; + let resolved = self.resolve(view, class, req.rev)?; + let basis = resolved.fields.len(); + let mut lanes = Vec::with_capacity(req.fields.count() as usize); + for field in 0..=u8::MAX { + if !req.fields.has(field) { + continue; + } + if usize::from(field) >= basis { + return Err(LaneRefusal::FieldNotInBasis { class, field }); + } + let addr = source + .lane_of(class, req.rev, field, req.frame) + .ok_or(LaneRefusal::Unbound { class, field })?; + admit_lane(field, &addr, req.scope, req.selection)?; + lanes.push((field, addr)); + } + Ok(LaneBinding { + class, + rev: req.rev, + route: req.route, + frame: req.frame.clone(), + scope: req.scope, + selection: req.selection, + fields: req.fields.clone(), + lanes, + }) + } +} + +/// The position must still route to `class` at the store's current version. +fn current_route(store: &BindStore, position: u16, class: u32) -> Result<(), LaneRefusal> { + let now = store.routed_at(store.current_version(), position)?; + if now == Some(class) { + Ok(()) + } else { + Err(LaneRefusal::RouteChanged { + position, + bound: class, + now, + }) + } +} + +fn admit_lane( + field: u8, + addr: &LaneAddr, + scope: Scope, + selection: CoordSpace, +) -> Result<(), LaneRefusal> { + if addr.space != selection { + return Err(LaneRefusal::CoordinateSpace { + field, + selection, + lane: addr.space, + }); + } + if addr.scope != scope { + return Err(LaneRefusal::Scope { + field, + reader: scope, + lane: addr.scope, + }); + } + Ok(()) +} + +impl LaneBinding { + pub fn class(&self) -> u32 { + self.class + } + + pub fn rev(&self) -> SchemaRev { + self.rev + } + + pub fn route(&self) -> RouteAt { + self.route + } + + pub fn frame(&self) -> &Frame { + &self.frame + } + + pub fn selection(&self) -> CoordSpace { + self.selection + } + + /// The bound fields. + pub fn fields(&self) -> &WideFieldMask { + &self.fields + } + + /// The bound lane of `field`. + pub fn addr(&self, field: u8) -> Option<&LaneAddr> { + self.lanes.iter().find(|(f, _)| *f == field).map(|(_, a)| a) + } + + /// Hot: everything the bind checked, again, without allocating. The frame + /// against its store; the route against the store's CURRENT version (a + /// re-route since the bind is refused); the basis at the bound revision; + /// and every lane against what the source maps now. + pub fn check( + &self, + store: &BindStore, + view: &V, + frames: &FrameStore, + source: &S, + ) -> Result<(), LaneRefusal> { + frames.check(&self.frame).map_err(LaneRefusal::Frame)?; + current_route(store, self.route.position, self.class)?; + store.resolve(view, self.class, self.rev)?; + for (field, addr) in &self.lanes { + let field = *field; + match source.lane_of(self.class, self.rev, field, &self.frame) { + Some(current) if current == *addr => {} + Some(_) => return Err(LaneRefusal::MappingChanged { field }), + None => { + return Err(LaneRefusal::Unbound { + class: self.class, + field, + }) + } + } + admit_lane(field, addr, self.scope, self.selection)?; + } + Ok(()) + } + + /// [`LaneBinding::check`], then borrow `field`'s lane from the source. + pub fn lane<'s, V: ClassView + ?Sized, S: LaneSource>( + &self, + store: &BindStore, + view: &V, + frames: &FrameStore, + source: &'s S, + field: u8, + ) -> Result, LaneRefusal> { + self.check(store, view, frames, source)?; + let addr = self.addr(field).ok_or(LaneRefusal::NotBound { field })?; + source.borrow(addr).ok_or(LaneRefusal::Vanished { field }) + } +} diff --git a/crates/lance-graph-dt64/src/lib.rs b/crates/lance-graph-dt64/src/lib.rs index 68494c8c4..88eaf14f6 100644 --- a/crates/lance-graph-dt64/src/lib.rs +++ b/crates/lance-graph-dt64/src/lib.rs @@ -88,7 +88,9 @@ use lance_graph_contract::set_rules::{Population, Truth}; pub mod dr; pub use dr::{Axis, Claim, Extent, RouteVersion, Width, MAX_RESERVED}; +pub mod lane; use dr::{RouteLog, RouteRefusal}; +pub use lane::{CoordSpace, LaneAddr, LaneBinding, LaneRefusal, LaneRequest, LaneSource, RouteAt}; /// A method's identity within its class, independent of its source name. #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] diff --git a/crates/lance-graph-dt64/tests/lane_socket.rs b/crates/lance-graph-dt64/tests/lane_socket.rs new file mode 100644 index 000000000..83a58848e --- /dev/null +++ b/crates/lance-graph-dt64/tests/lane_socket.rs @@ -0,0 +1,316 @@ +//! D-LANESOCK-1: the property-to-lane socket. Every refusal fires on a +//! realistic input, and a binding that passes borrows the source's own lane. + +use lance_graph_contract::class_view::{ClassId, ClassView, WideFieldMask}; +use lance_graph_contract::ontology::{DisplayTemplate, FieldRef}; +use lance_graph_dt64::dr::{Frame, FrameRefusal, FrameRevisions, FrameStore, Scope}; +use lance_graph_dt64::{ + BindStore, ClassSchema, CoordSpace, Extent, LaneAddr, LaneRefusal, LaneRequest, LaneSource, + Refusal, RouteAt, SchemaRev, +}; + +const HYBRID: u32 = 0x0C1A_0001; +const HYBRID_V2: u32 = 0x0C1A_0002; +const VIEW_CLASS: ClassId = 0x0C1A; +const POSITION: u16 = 5; + +/// Fields: 0 department (AD), 1 cost centre (AD), 2 license count (Entra). +struct View(Vec); + +impl View { + fn three() -> View { + View(vec![ + FieldRef::new("ad:department", "Department"), + FieldRef::new("ad:costCenter", "Cost centre"), + FieldRef::new("entra:licenseCount", "Licenses"), + ]) + } +} + +impl ClassView for View { + fn fields(&self, class: ClassId) -> &[FieldRef] { + if class == VIEW_CLASS { + &self.0 + } else { + &[] + } + } + fn template(&self, _class: ClassId) -> DisplayTemplate { + DisplayTemplate::Detail + } + fn dolce_category_id(&self, _class: ClassId) -> u8 { + 0 + } +} + +const AD: CoordSpace = CoordSpace { + population: 1, + coordinates: 1, +}; +const ENTRA: CoordSpace = CoordSpace { + population: 2, + coordinates: 1, +}; +const READER: Scope = Scope { id: 7 }; + +/// A source owner: its lanes, and which lane holds which field. +struct Source { + lanes: Vec>, + map: Vec<(u8, LaneAddr)>, +} + +impl Source { + fn hybrid() -> Source { + let at = |space, lane| LaneAddr { + space, + lane, + scope: READER, + }; + Source { + lanes: vec![vec![6, 7, 6], vec![100, 200, 300], vec![25, 40]], + map: vec![(0, at(AD, 0)), (1, at(AD, 1)), (2, at(ENTRA, 2))], + } + } +} + +impl LaneSource for Source { + type Lane<'a> = &'a [i32]; + fn lane_of(&self, class: u32, rev: SchemaRev, field: u8, _frame: &Frame) -> Option { + if class != HYBRID || rev != SchemaRev(1) { + return None; + } + self.map.iter().find(|(f, _)| *f == field).map(|(_, a)| *a) + } + fn borrow(&self, addr: &LaneAddr) -> Option<&[i32]> { + self.lanes.get(usize::from(addr.lane)).map(Vec::as_slice) + } +} + +fn schema(fields: usize) -> ClassSchema { + ClassSchema { + schema_rev: SchemaRev(1), + field_count: fields, + extent: Extent::DR64_CUBE, + } +} + +struct World { + store: BindStore, + view: View, + frames: FrameStore, + frame: Frame, + source: Source, + route: RouteAt, +} + +fn world() -> World { + let mut store = BindStore::new(); + store.register(HYBRID, schema(3), Vec::new()).unwrap(); + let version = store.route(POSITION, HYBRID).unwrap(); + let frames = FrameStore::new(FrameRevisions { + source: 1, + relation_map: 1, + coordinates: 1, + }); + let frame = frames.seal(); + World { + store, + view: View::three(), + frames, + frame, + source: Source::hybrid(), + route: RouteAt { + position: POSITION, + version, + }, + } +} + +fn request<'a>(w: &'a World, fields: &'a WideFieldMask) -> LaneRequest<'a> { + LaneRequest { + route: w.route, + rev: SchemaRev(1), + fields, + frame: &w.frame, + scope: READER, + selection: AD, + } +} + +fn bind(w: &World, fields: &WideFieldMask) -> Result { + w.store + .bind_lanes(&w.view, &w.frames, &w.source, request(w, fields)) +} + +#[test] +fn two_fields_of_one_basis_bind_and_borrow_the_source_lanes() { + let w = world(); + let both = WideFieldMask::from_positions(&[0, 1]); + let b = bind(&w, &both).unwrap(); + assert_eq!(b.class(), HYBRID); + assert!(b.fields().has(0) && b.fields().has(1)); + let dept = b.lane(&w.store, &w.view, &w.frames, &w.source, 0).unwrap(); + let cost = b.lane(&w.store, &w.view, &w.frames, &w.source, 1).unwrap(); + // Borrowed, not copied: the very slices the source holds. + assert!(std::ptr::eq(dept, w.source.lanes[0].as_slice())); + assert!(std::ptr::eq(cost, w.source.lanes[1].as_slice())); + assert_eq!( + b.lane(&w.store, &w.view, &w.frames, &w.source, 2), + Err(LaneRefusal::NotBound { field: 2 }) + ); +} + +#[test] +fn a_lane_in_another_row_order_is_refused() { + let w = world(); + let mask = WideFieldMask::from_positions(&[0, 2]); + assert_eq!( + bind(&w, &mask).err(), + Some(LaneRefusal::CoordinateSpace { + field: 2, + selection: AD, + lane: ENTRA, + }) + ); + // The same field binds under its own row order. + let only = WideFieldMask::from_positions(&[2]); + let mut req = request(&w, &only); + req.selection = ENTRA; + assert!(w + .store + .bind_lanes(&w.view, &w.frames, &w.source, req) + .is_ok()); +} + +#[test] +fn wrong_schema_revision_and_changed_basis_are_refused() { + let w = world(); + let mask = WideFieldMask::from_positions(&[0]); + let mut req = request(&w, &mask); + req.rev = SchemaRev(2); + assert!(matches!( + w.store.bind_lanes(&w.view, &w.frames, &w.source, req), + Err(LaneRefusal::Bind(Refusal::SchemaRevisionMismatch { .. })) + )); + + let b = bind(&w, &mask).unwrap(); + let narrower = View(View::three().0[..2].to_vec()); + assert!(matches!( + b.check(&w.store, &narrower, &w.frames, &w.source), + Err(LaneRefusal::Bind(Refusal::FieldBasisChanged { .. })) + )); +} + +#[test] +fn a_field_outside_the_basis_or_without_a_lane_is_refused() { + let w = world(); + let outside = WideFieldMask::from_positions(&[0, 9]); + assert_eq!( + bind(&w, &outside).err(), + Some(LaneRefusal::FieldNotInBasis { + class: HYBRID, + field: 9, + }) + ); + let mut w = w; + w.source.map.retain(|(f, _)| *f != 1); + let both = WideFieldMask::from_positions(&[0, 1]); + assert_eq!( + bind(&w, &both).err(), + Some(LaneRefusal::Unbound { + class: HYBRID, + field: 1, + }) + ); +} + +#[test] +fn a_lane_for_another_scope_is_refused() { + let mut w = world(); + w.source.map[1].1.scope = Scope { id: 8 }; + let both = WideFieldMask::from_positions(&[0, 1]); + assert_eq!( + bind(&w, &both).err(), + Some(LaneRefusal::Scope { + field: 1, + reader: READER, + lane: Scope { id: 8 }, + }) + ); +} + +#[test] +fn a_changed_mapping_or_a_vanished_lane_is_refused_on_use() { + let mut w = world(); + let both = WideFieldMask::from_positions(&[0, 1]); + let b = bind(&w, &both).unwrap(); + w.source.map[0].1.lane = 1; + assert_eq!( + b.check(&w.store, &w.view, &w.frames, &w.source), + Err(LaneRefusal::MappingChanged { field: 0 }) + ); + + let mut w = world(); + let b = bind(&w, &both).unwrap(); + w.source.lanes.truncate(1); + assert_eq!( + b.lane(&w.store, &w.view, &w.frames, &w.source, 1), + Err(LaneRefusal::Vanished { field: 1 }) + ); +} + +#[test] +fn stale_and_foreign_frames_are_refused() { + let w = world(); + let mask = WideFieldMask::from_positions(&[0]); + let twin = FrameStore::new(FrameRevisions { + source: 1, + relation_map: 1, + coordinates: 1, + }); + assert_eq!( + w.store + .bind_lanes(&w.view, &twin, &w.source, request(&w, &mask)) + .err(), + Some(LaneRefusal::Frame(FrameRefusal::ForeignFrame)) + ); + + let mut w = w; + let b = bind(&w, &mask).unwrap(); + w.frames.advance(FrameRevisions { + source: 1, + relation_map: 2, + coordinates: 1, + }); + assert_eq!( + b.check(&w.store, &w.view, &w.frames, &w.source), + Err(LaneRefusal::Frame(FrameRefusal::MapChanged)) + ); +} + +/// The route and the frame are checked as a pair: a re-route alone, with the +/// frame untouched, refuses. +#[test] +fn a_re_route_refuses_even_under_a_current_frame() { + let mut w = world(); + let mask = WideFieldMask::from_positions(&[0]); + let b = bind(&w, &mask).unwrap(); + w.store + .register_derived(HYBRID, HYBRID_V2, schema(3), Vec::new()) + .unwrap(); + w.store.route(POSITION, HYBRID_V2).unwrap(); + assert!(w.frames.check(b.frame()).is_ok(), "the frame did not move"); + assert_eq!( + b.check(&w.store, &w.view, &w.frames, &w.source), + Err(LaneRefusal::RouteChanged { + position: POSITION, + bound: HYBRID, + now: Some(HYBRID_V2), + }) + ); + // And a bind at the old route version refuses too. + assert!(matches!( + bind(&w, &mask), + Err(LaneRefusal::RouteChanged { .. }) + )); +} From 6f883e16281a57de8b41807aaf07af2af424a51c Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 6 Nov 2026 08:17:23 +0000 Subject: [PATCH 2/3] test(lab): bound-lane 64K check uses a scalar plane re-derivation; time the socket alone The scan oracle is quadratic at 64K slots; its parity stays pinned at 300 slots across three seeds. Reports check+borrow separately from the fold. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01XAqKMMJzKZrYnckXRC8x2U --- .../tests/ordinal_chain_lab.rs | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/crates/lance-graph-dir-sim/tests/ordinal_chain_lab.rs b/crates/lance-graph-dir-sim/tests/ordinal_chain_lab.rs index a4a33c7af..b5672bcbb 100644 --- a/crates/lance-graph-dir-sim/tests/ordinal_chain_lab.rs +++ b/crates/lance-graph-dir-sim/tests/ordinal_chain_lab.rs @@ -1336,16 +1336,30 @@ fn bound_lane_fold_at_64k_allocates_nothing() { got = execute_into(&sum, &inputs, &Foreign::NONE, &mut scratch, Out::None).unwrap(); } let hot = t.elapsed(); + let t = Instant::now(); + for _ in 0..PASSES { + let _ = binding + .lane(&b.store, &b.view, &b.frames, &dir, DEPARTMENT) + .unwrap(); + } + let socket = t.elapsed(); let hot_allocations = allocations() - before; + // Scalar re-derivation over the plane bits (independent of Quack; the + // scan oracle is quadratic, and its parity is pinned at 300 slots in + // `bound_property_lanes_fold_under_the_ruler_selection`). + let p = &f.planes; let want: i64 = (0..n) - .filter(|&i| oracle_bound(&l, i).is_some()) + .filter(|&i| { + bit(&p.forward, i) && bit(&p.backsync, i) && bit(&p.aligned, i) && bit(&p.cloud, i) + }) .map(|i| i64::from(dir.department[i])) .sum(); assert_eq!(got, Value::SumI64(want)); assert_eq!(hot_allocations, 0, "the bound-lane hot path allocated"); eprintln!( - "64K slots: check+borrow+SumI32 {} ns/pass | hot allocations {hot_allocations}", - hot.as_nanos() / u128::from(PASSES) + "64K slots: check+borrow+SumI32 {} ns/pass | check+borrow alone {} ns | hot allocations {hot_allocations}", + hot.as_nanos() / u128::from(PASSES), + socket.as_nanos() / u128::from(PASSES) ); } From 7ac42549898c44c9877a9f523530657ec415ffbd Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 6 Nov 2026 08:17:45 +0000 Subject: [PATCH 3/3] board: D-LANESOCK-0 shipped, D-LANESOCK-1 in PR Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01XAqKMMJzKZrYnckXRC8x2U --- .claude/board/STATUS_BOARD.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.claude/board/STATUS_BOARD.md b/.claude/board/STATUS_BOARD.md index ab8027124..5466a20fc 100644 --- a/.claude/board/STATUS_BOARD.md +++ b/.claude/board/STATUS_BOARD.md @@ -2,8 +2,8 @@ | D-id | Deliverable | State | | --- | --- | --- | -| D-LANESOCK-0 | normative spec: socket, joint version witness, refusals | In PR | -| D-LANESOCK-1 | `LaneSource` + `BindStore::bind_lanes` + falsifiers in lance-graph-dt64 and the dir-sim lab | Queued | +| D-LANESOCK-0 | normative spec: socket, joint version witness, refusals | Shipped (#1966) | +| D-LANESOCK-1 | `LaneSource` + `BindStore::bind_lanes` + falsifiers in lance-graph-dt64 and the dir-sim lab | In PR | ## D-CGMM — Lazy Codegraph fact/demand + MeTTa class-method scratch (2026-11-04)