Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .claude/board/STATUS_BOARD.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
## D-SC — OGAR × DR × DT64 semantic continuity (2026-11-07)

Execution admitted = meaning valid (OGAR/DT64) ∧ representation compatible (DR/source) ∧ access permitted now (IAM, owned by the OGAR auth session, EXO-206). Linear: EXO-202 (D, BLOCKED), EXO-204, EXO-205.

| D-id | Deliverable | Status |
|---|---|---|
| D-SC-E1 | `MapTable::map_at` fenced as `diagnose_at` → `MapDiagnostic`; executable maps only via `map(frame)` | Shipped (#1981) |
| D-SC-E2a | dt64 `CodeTable` (versioned code space, advances the lanes' FrameStore) + quack `bind_typed` / `TypedQuery::admit` (`StaleCodeSpace`, `Unwitnessed`) | In PR |
| D-SC-E2b | per-owner adoption (`CamLabels`, dir-sim, sap): each real mutation path invalidates stale execution | Queued |
| D-SC-D | witness-only Activation + `SealedBasis` + historical typed equivalence; blocked on OGAR-P2 and evidence, not on rulings | Blocked |
| D-SC-H1 | coded and scaled facade queries (`ScaleMismatch`, `DomainMismatch`) | Queued |

## D-LANESOCK — DR × DT64 property-to-lane socket (2026-11-06)

| D-id | Deliverable | State |
Expand Down
164 changes: 164 additions & 0 deletions crates/lance-graph-dt64/src/dr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1083,3 +1083,167 @@ pub fn coordinates(width: Width, code: Morton8x8) -> Result<(u8, u8), MapRefusal
pub fn rotate_yz(code: Morton8x8) -> Morton8x8 {
Morton8x8::from_xy(code.y(), code.x())
}

// ---- code space: value key <-> source-local code ---------------------------

/// A canonical value key: the meaning of one value of a property (for
/// example the OGAR key of the order status `shipped`). OGAR owns the key; a
/// source owns the numbers it assigns to keys ([`CodeTable`]). The key is
/// never an executable number.
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct ValueKey(pub String);

/// One namespace of codes: a full classid and the canonical identity of one
/// of its properties. Two properties never share a code space, and one
/// property of two classes does not either.
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct CodeSpaceId {
pub class: u32,
pub property: String,
}

/// Why a [`CodeTable`] read or advance was refused.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CodeRead {
/// The [`FrameStore`] passed to [`CodeTable::advance`] is not the one the
/// table is bound to. Nothing changed.
ForeignStore,
/// The frame was not issued by the store the table is bound to, even at
/// equal revisions and versions. A frame of the bound store is never
/// stale here: it reads the generation in force at its own version.
ForeignFrame,
/// The table holds no generation of this space at the frame's version.
NoSpace,
/// The generation maps no key to this code.
UnknownCode,
/// The generation maps no code to this key.
UnknownKey,
/// A change set maps one key to two codes, two keys to one code, or names
/// a space twice. Nothing changed.
Duplicate,
}

#[derive(Debug)]
struct CodeGeneration<C> {
at: RouteVersion,
by_key: BTreeMap<ValueKey, C>,
by_code: BTreeMap<C, ValueKey>,
}

/// The code-space sibling of [`MapTable`]: per [`CodeSpaceId`], an
/// append-only history of generations, each a bijection between canonical
/// [`ValueKey`]s and the source's local codes `C`.
///
/// Unlike [`MapTable`] it owns no [`FrameStore`]. It is bound to the store
/// that the lanes are sealed under, and [`CodeTable::advance`] advances THAT
/// store, so a code change cannot leave a lane [`Frame`] current
/// ([`FrameStore::check`]). Reads are keyed by a [`Frame`], never by a bare
/// version number: a historical frame reads the mapping in force at its
/// version, which says what a code meant then, not what a row held.
#[derive(Debug)]
pub struct CodeTable<C: Copy + Ord> {
store: Weak<()>,
spaces: BTreeMap<CodeSpaceId, Vec<CodeGeneration<C>>>,
}

impl<C: Copy + Ord> CodeTable<C> {
/// An empty table bound to the identity of `frames`.
pub fn new(frames: &FrameStore) -> Self {
Self {
store: Arc::downgrade(&frames.identity),
spaces: BTreeMap::new(),
}
}

/// Replace the generation of each listed space and advance `frames`
/// exactly once. A space absent from `changes` keeps its generation.
/// The new generation of a listed space is exactly its entries.
///
/// # Errors
///
/// [`CodeRead::ForeignStore`] if `frames` is not the bound store, and
/// [`CodeRead::Duplicate`] if a change set is not a bijection or names a
/// space twice. Both are checked before anything changes: on `Err` the
/// table and `frames` are untouched.
pub fn advance(
&mut self,
frames: &mut FrameStore,
changes: Vec<(CodeSpaceId, Vec<(ValueKey, C)>)>,
) -> Result<(), CodeRead> {
if !Weak::ptr_eq(&self.store, &Arc::downgrade(&frames.identity)) {
return Err(CodeRead::ForeignStore);
}
let mut seen = BTreeSet::new();
let mut staged = Vec::with_capacity(changes.len());
for (space, entries) in changes {
if !seen.insert(space.clone()) {
return Err(CodeRead::Duplicate);
}
let mut by_key = BTreeMap::new();
let mut by_code = BTreeMap::new();
for (key, code) in entries {
if by_key.insert(key.clone(), code).is_some() || by_code.insert(code, key).is_some()
{
return Err(CodeRead::Duplicate);
}
}
staged.push((space, by_key, by_code));
}
let r = frames.revisions();
let at = frames.advance(FrameRevisions {
source: r.source.wrapping_add(1),
..r
});
for (space, by_key, by_code) in staged {
self.spaces.entry(space).or_default().push(CodeGeneration {
at,
by_key,
by_code,
});
}
Ok(())
}

/// The key `code` meant in `space` as of `frame`.
///
/// # Errors
///
/// [`CodeRead::ForeignFrame`], [`CodeRead::NoSpace`] or
/// [`CodeRead::UnknownCode`].
pub fn key(&self, frame: &Frame, space: &CodeSpaceId, code: C) -> Result<&ValueKey, CodeRead> {
self.generation(frame, space)?
.by_code
.get(&code)
.ok_or(CodeRead::UnknownCode)
}

/// The code `key` had in `space` as of `frame`.
///
/// # Errors
///
/// [`CodeRead::ForeignFrame`], [`CodeRead::NoSpace`] or
/// [`CodeRead::UnknownKey`].
pub fn code(&self, frame: &Frame, space: &CodeSpaceId, key: &ValueKey) -> Result<C, CodeRead> {
self.generation(frame, space)?
.by_key
.get(key)
.copied()
.ok_or(CodeRead::UnknownKey)
}

fn generation(
&self,
frame: &Frame,
space: &CodeSpaceId,
) -> Result<&CodeGeneration<C>, CodeRead> {
if !Weak::ptr_eq(&frame.store, &self.store) {
return Err(CodeRead::ForeignFrame);
}
let gens = self.spaces.get(space).ok_or(CodeRead::NoSpace)?;
let in_force = gens.partition_point(|g| g.at <= frame.version);
in_force
.checked_sub(1)
.map(|i| &gens[i])
.ok_or(CodeRead::NoSpace)
}
}
5 changes: 4 additions & 1 deletion crates/lance-graph-dt64/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,10 @@ use lance_graph_contract::set_rules::{Population, Truth};

pub mod dr;

pub use dr::{Axis, Claim, Extent, RouteVersion, Width, MAX_RESERVED};
pub use dr::{
Axis, Claim, CodeRead, CodeSpaceId, CodeTable, Extent, RouteVersion, ValueKey, Width,
MAX_RESERVED,
};
pub mod lane;
use dr::{RouteLog, RouteRefusal};
pub use lane::{CoordSpace, LaneAddr, LaneBinding, LaneRefusal, LaneRequest, LaneSource, RouteAt};
Expand Down
188 changes: 186 additions & 2 deletions crates/lance-graph-dt64/tests/dr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

use lance_graph_contract::morton8x8::Morton8x8;
use lance_graph_dt64::dr::{
address, coordinates, rotate_yz, Focus, FrameRefusal, FrameRevisions, FrameStore, GuardRefusal,
Guards, LocalMap, MapRefusal, Scope, Width,
address, coordinates, rotate_yz, CodeRead, CodeSpaceId, CodeTable, Focus, FrameRefusal,
FrameRevisions, FrameStore, GuardRefusal, Guards, LocalMap, MapRefusal, Scope, ValueKey, Width,
};

fn revisions() -> FrameRevisions {
Expand Down Expand Up @@ -600,3 +600,187 @@ mod vmap {
assert_ne!(d.digest(), b.map(&fb, 1).unwrap().digest());
}
}

// ---- CodeTable: the code-space G2L ----------------------------------------

fn status() -> CodeSpaceId {
CodeSpaceId {
class: 0x0202_0002,
property: "status".into(),
}
}
fn priority() -> CodeSpaceId {
CodeSpaceId {
class: 0x0202_0002,
property: "priority".into(),
}
}
fn vk(s: &str) -> ValueKey {
ValueKey(s.into())
}
fn entries(e: &[(&str, u32)]) -> Vec<(ValueKey, u32)> {
e.iter().map(|(k, c)| (vk(k), *c)).collect()
}

/// t1: a frame reads the generation in force at its own version.
#[test]
fn code_reads_are_frame_keyed_and_historical() {
let mut fs = FrameStore::new(revisions());
let mut t: CodeTable<u32> = CodeTable::new(&fs);
t.advance(
&mut fs,
vec![(status(), entries(&[("shipped", 3), ("cancelled", 7)]))],
)
.unwrap();
let f1 = fs.seal();
t.advance(
&mut fs,
vec![(status(), entries(&[("cancelled", 3), ("shipped", 7)]))],
)
.unwrap();
let f2 = fs.seal();
assert_eq!(t.key(&f1, &status(), 3), Ok(&vk("shipped")));
assert_eq!(t.key(&f2, &status(), 3), Ok(&vk("cancelled")));
assert_eq!(t.code(&f2, &status(), &vk("shipped")), Ok(7));
assert_eq!(t.code(&f1, &status(), &vk("shipped")), Ok(3));
assert_eq!(
t.code(&f1, &status(), &vk("lost")),
Err(CodeRead::UnknownKey)
);
assert_eq!(t.key(&f1, &status(), 9), Err(CodeRead::UnknownCode));
}

/// t1b: a frame sealed before any generation of the space reads nothing, and
/// an unknown space reads nothing.
#[test]
fn a_frame_before_the_first_generation_has_no_space() {
let mut fs = FrameStore::new(revisions());
let mut t: CodeTable<u32> = CodeTable::new(&fs);
let before = fs.seal();
t.advance(&mut fs, vec![(status(), entries(&[("shipped", 3)]))])
.unwrap();
let after = fs.seal();
assert_eq!(
t.code(&before, &status(), &vk("shipped")),
Err(CodeRead::NoSpace)
);
assert_eq!(
t.code(&after, &priority(), &vk("shipped")),
Err(CodeRead::NoSpace)
);
assert_eq!(t.code(&after, &status(), &vk("shipped")), Ok(3));
}

/// t2: a frame of another store is refused although its version equals.
#[test]
fn a_frame_of_another_store_is_refused_at_equal_version() {
let mut fs = FrameStore::new(revisions());
let mut t: CodeTable<u32> = CodeTable::new(&fs);
t.advance(&mut fs, vec![(status(), entries(&[("shipped", 3)]))])
.unwrap();
let mut other = FrameStore::new(revisions());
other.advance(revisions());
let foreign = other.seal();
let own = fs.seal();
assert_eq!(foreign.version(), own.version());
assert_eq!(t.code(&own, &status(), &vk("shipped")), Ok(3));
assert_eq!(
t.code(&foreign, &status(), &vk("shipped")),
Err(CodeRead::ForeignFrame)
);
assert_eq!(t.key(&foreign, &status(), 3), Err(CodeRead::ForeignFrame));
}

/// t3: advancing with a store the table is not bound to changes nothing,
/// neither the table nor either store.
#[test]
fn a_foreign_store_is_refused_before_anything_changes() {
let mut fs = FrameStore::new(revisions());
let mut t: CodeTable<u32> = CodeTable::new(&fs);
t.advance(&mut fs, vec![(status(), entries(&[("shipped", 3)]))])
.unwrap();
let bound_frame = fs.seal();
let mut other = FrameStore::new(revisions());
let other_frame = other.seal();
let other_rev = other.revisions();
let r = t.advance(
&mut other,
vec![(status(), entries(&[("shipped", 9), ("cancelled", 3)]))],
);
assert_eq!(r, Err(CodeRead::ForeignStore));
assert_eq!(other.revisions(), other_rev);
assert_eq!(other.check(&other_frame), Ok(()));
assert_eq!(fs.check(&bound_frame), Ok(()));
assert_eq!(t.code(&bound_frame, &status(), &vk("shipped")), Ok(3));
assert_eq!(
t.code(&bound_frame, &status(), &vk("cancelled")),
Err(CodeRead::UnknownKey)
);
}

/// t4: a change set that is not a bijection, or names a space twice, is
/// refused and the store is not advanced.
#[test]
fn a_duplicate_change_set_is_refused_and_the_store_is_not_advanced() {
let mut fs = FrameStore::new(revisions());
let mut t: CodeTable<u32> = CodeTable::new(&fs);
let f = fs.seal();
let two_keys_one_code = entries(&[("shipped", 3), ("cancelled", 3)]);
let one_key_two_codes = entries(&[("shipped", 3), ("shipped", 7)]);
for bad in [
vec![(status(), two_keys_one_code)],
vec![(status(), one_key_two_codes)],
vec![
(status(), entries(&[("shipped", 3)])),
(status(), entries(&[("cancelled", 7)])),
],
// the valid space listed first must not leak when a later one fails
vec![
(priority(), entries(&[("high", 1)])),
(status(), entries(&[("a", 1), ("b", 1)])),
],
] {
assert_eq!(t.advance(&mut fs, bad), Err(CodeRead::Duplicate));
assert_eq!(fs.check(&f), Ok(()), "store must not have advanced");
}
assert_eq!(t.code(&f, &priority(), &vk("high")), Err(CodeRead::NoSpace));
// the silence twin: a valid set advances
t.advance(&mut fs, vec![(status(), entries(&[("shipped", 3)]))])
.unwrap();
assert!(fs.check(&f).is_err());
}

/// t5: a code change advances the store, so a lane frame sealed before it is
/// no longer current.
#[test]
fn advancing_the_code_table_retires_lane_frames() {
let mut fs = FrameStore::new(revisions());
let mut t: CodeTable<u32> = CodeTable::new(&fs);
let lane_frame = fs.seal();
assert_eq!(fs.check(&lane_frame), Ok(()));
t.advance(&mut fs, vec![(status(), entries(&[("shipped", 3)]))])
.unwrap();
assert!(fs.check(&lane_frame).is_err());
assert_eq!(fs.check(&fs.seal()), Ok(()));
}

/// t6: a space absent from a change set keeps its generation.
#[test]
fn an_unchanged_space_survives_an_advance_of_another() {
let mut fs = FrameStore::new(revisions());
let mut t: CodeTable<u32> = CodeTable::new(&fs);
t.advance(
&mut fs,
vec![
(status(), entries(&[("shipped", 3)])),
(priority(), entries(&[("high", 1)])),
],
)
.unwrap();
t.advance(&mut fs, vec![(status(), entries(&[("shipped", 9)]))])
.unwrap();
let f = fs.seal();
assert_eq!(t.code(&f, &status(), &vk("shipped")), Ok(9));
assert_eq!(t.code(&f, &priority(), &vk("high")), Ok(1));
assert_eq!(t.key(&f, &priority(), 1), Ok(&vk("high")));
}
Loading
Loading