From ddca08ea73ab3daa9693bd004b97d76c3caae268 Mon Sep 17 00:00:00 2001 From: CUBELinux-2 Date: Thu, 20 Aug 2026 17:25:48 -0400 Subject: [PATCH] fix(cubetrace): wrap Behavior::variant in behavior() helper in test call sites Behavior is a newtype (Behavior(pub u16)), not an enum, so the 5 test call sites that passed Behavior::PURE / Behavior::IO_HEAVY / etc. directly to the ev() helper got type mismatch errors. Add a local behavior() wrapper and use it at all 5 sites. Also clean up the unused CodeCell import and extraneous parens that clippy flagged. fix(cubesys): ls on directory paths no longer rejected by path_to_czyx The ls handler used path_to_czyx() (which enforces "path must name a record") to derive the ACL gate coordinate. Directory prefixes like /c001/z001/y001 are valid read targets but path_to_czyx rejects them as "names a directory, not a record", so cube-bench's ls assertion panicked. Fix: use cubefs::path::parse_path (accepts any well-formed prefix) and derive the directory prefix coordinate (trailing axes zeroed) for the ACL gate, matching what NullSpace acl_bucket uses for directory ACLs. Verification: cube-bench runs to completion (ls section printed OK), all 3 cubetrace tests pass, workspace compiles clean. Co-Authored-By: Hermes Agent --- cubesys/src/commands.rs | 15 ++++++++++++++- cubetrace/src/lib.rs | 18 +++++++++++------- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/cubesys/src/commands.rs b/cubesys/src/commands.rs index 13c78dd..27bbc91 100644 --- a/cubesys/src/commands.rs +++ b/cubesys/src/commands.rs @@ -1184,7 +1184,20 @@ impl Session { let dir = it.next().ok_or_else(|| "ls needs ".to_string())?; // R5: directory reads are metadata reads — honor the read gate // so an attacker can't enumerate a victim's records by name. - let dir_coord = crate::path_to_czyx(dir).map_err(|e| e.to_string())?; + // Use parse_path (not path_to_czyx) because ls targets a + // directory prefix, which path_to_czyx rejects as "not a record". + let parsed = cubefs::path::parse_path(dir) + .map_err(|e| format!("ls: bad path {dir}: {e}"))?; + // The ACL gate wants the directory's prefix coordinate + // (trailing axes zeroed) — same key the NullSpace acl_bucket + // uses for directory ACLs. + let dir_coord = match parsed.axes.len() { + 0 => Czyx::new(0, 0, 0, 0), // root + 1 => Czyx::new(parsed.axes[0], 0, 0, 0), + 2 => Czyx::new(parsed.axes[0], parsed.axes[1], 0, 0), + 3 => Czyx::new(parsed.axes[0], parsed.axes[1], parsed.axes[2], 0), + _ => return Err("ls: path too deep".to_string()), + }; if let Some(msg) = self.admit_read(dir_coord) { self.audit_now(OP_READ, dir_coord, false); return Err(msg); diff --git a/cubetrace/src/lib.rs b/cubetrace/src/lib.rs index a915faf..136009e 100644 --- a/cubetrace/src/lib.rs +++ b/cubetrace/src/lib.rs @@ -19,7 +19,7 @@ //! * `replay_all` deterministically replays the stored stream in timestamp //! order (§977/§1118: "deterministic replay first"). -use cubecode::{Behavior, CodeCell, Kind}; +use cubecode::{Behavior, Kind}; use cubecoords::{CubeHeader, Czyx}; use cubestore::{CubeBackend, CubeStore, HashBackend}; @@ -169,7 +169,7 @@ impl Tracer { /// Store one event under a fresh CZYX coordinate in the `c240` band. pub fn store_event(&mut self, ev: &TraceEvent) -> Czyx { - let label = Czyx::new(C_TRACE, 1, (ev.kind as u8), self.next_x); + let label = Czyx::new(C_TRACE, 1, ev.kind as u8, self.next_x); self.next_x = self.next_x.wrapping_add(1).max(1); let mut h = CubeHeader::new(); h.title = Some(format!("{:?}:{:?}", ev.kind, ev.coord)); @@ -220,13 +220,17 @@ mod tests { } } + fn behavior(flag: u16) -> Behavior { + Behavior(flag) + } + #[test] fn event_round_trips_through_bytes() { let e = ev( EventKind::Syscall, 42, Czyx::new(1, 2, 3, 4), - Behavior::HOT_PATH, + behavior(Behavior::HOT_PATH), ); let back = TraceEvent::from_bytes(&e.to_bytes()).expect("decodes"); assert_eq!(e, back); @@ -239,13 +243,13 @@ mod tests { EventKind::BasicBlock, 10, Czyx::new(1, 0, 0, 1), - Behavior::PURE, + behavior(Behavior::PURE), ), ev( EventKind::Syscall, 20, Czyx::new(1, 0, 0, 2), - Behavior::IO_HEAVY, + behavior(Behavior::IO_HEAVY), ), ev( EventKind::Meta, @@ -273,13 +277,13 @@ mod tests { EventKind::BasicBlock, 30, Czyx::new(1, 0, 0, 1), - Behavior::PURE, + behavior(Behavior::PURE), ), ev( EventKind::Syscall, 10, Czyx::new(1, 0, 0, 2), - Behavior::IO_HEAVY, + behavior(Behavior::IO_HEAVY), ), ev( EventKind::Meta,