//! CUBELinux-2 cubebook / kernel-convention constants. //! //! These are the conventions the *OS* layer uses to store its computational //! behavior in CUBE. Per the PDF (Package 4, and the "behavior descriptors" //! discussion at PDF §524–525), functions/operators that live in CUBE are: //! * addressed in a reserved `C` axis band (here `c210..=c219`), //! * tagged with a `kind` (`fn`/`kernel`/`layer`/`checkpoint`/`variant`), and //! * annotated with *behavior descriptor* flags carried in the record //! header's out-of-band flag bits (tag 12, see cubestore encode/decode). //! //! The full spec-derived descriptor set (PDF §524–525) is: "pure function," //! "I/O heavy," "allocates memory," "touches network," "hot path," and //! "security sensitive." We store each directly as a dedicated header-flag bit //! inside the spare 8..=15 range, deliberately leaving bit 12 //! (`cubecrypt::HEADER_FLAG_ENCRYPTED`) clear. `CubeHeader::refresh_flags()` //! preserves spare bits 8..=15, so a header carrying descriptors survives an //! encode→decode→refresh round-trip. //! //! This is deliberately NOT a store-IO model: the cubevm never reads or writes //! OS state records directly. The OS's *decisions/computation* live as CUBE //! kernels; the native OS layer is a thin effector that reads a kernel's //! computed result and applies the effect (writes the record, runs the //! command). See `cubesys/src/commands.rs` `tick` + `native-apply`. /// First `C` axis value reserved for OS operator kernels (call-graph roots and /// leaves). The OS keeps its behavioral substrate here, separate from the /// `c200` operational-snapshot data band and the `c001/c002` doc examples. pub const C_OS_KERNEL: u8 = 210; /// `C` axis band for OS *data* records the native layer writes after a kernel /// decides an effect (kept distinct from the compute-kernel band above). pub const C_OS_EFFECT: u8 = 211; /// Header-flag bits reserved for the behavior-descriptor field. Six spec /// descriptors, each a dedicated bit in the spare 8..=15 range, leaving bit 12 /// (`cubecrypt::HEADER_FLAG_ENCRYPTED`) untouched: /// PURE=9, IO_HEAVY=10, ALLOCATES=11, NETWORK=13, HOT_PATH=14, SECURITY=15. pub const HEADER_FLAG_BEHAVIOR: u16 = 0b1110_1110_0000_0000; // bits 9,10,11,13,14,15 (bit12 reserved) /// Behavior descriptors for an OS operator kernel (PDF §524–525, full set). /// /// Each variant is stored directly as its dedicated header-flag bit (subset of /// `HEADER_FLAG_BEHAVIOR`), so `Behavior` carries the raw descriptor bits and /// round-trips through the header codec without bit-shift collisions. #[derive(Copy, Clone, Debug, Default, PartialEq, Eq)] pub struct Behavior(pub u16); impl Behavior { /// Pure function: no side effects, deterministic on inputs. pub const PURE: u16 = 1 << 9; // 0x0200 /// I/O heavy: performs significant store/device I/O. pub const IO_HEAVY: u16 = 1 << 10; // 0x0400 /// Allocates memory: grows the heap / maps pages. pub const ALLOCATES: u16 = 1 << 11; // 0x0800 /// Touches network: performs socket/link I/O (security-relevant surface). pub const NETWORK: u16 = 1 << 13; // 0x2000 /// Hot path: executed frequently; a candidate for optimization/variant swap. pub const HOT_PATH: u16 = 1 << 14; // 0x4000 /// Security sensitive: elevated privilege / trust boundary crossing. pub const SECURITY_SENSITIVE: u16 = 1 << 15; // 0x8000 /// Combine descriptor bits (e.g. `Behavior::PURE | Behavior::HOT_PATH`). pub fn new(bits: u16) -> Self { Behavior(bits & HEADER_FLAG_BEHAVIOR) } /// Encode into the out-of-band header flag bits. pub fn to_flags(self) -> u16 { self.0 & HEADER_FLAG_BEHAVIOR } /// Decode from a raw 16-bit flag word (keeps only the behavior bits). pub fn from_flags(flags: u16) -> Self { Behavior(flags & HEADER_FLAG_BEHAVIOR) } /// True if any descriptor bit is set. pub fn is_any(self) -> bool { self.0 != 0 } /// Human-readable descriptor tags (used by `ls`/`stat` and the effector). pub fn tags(self) -> Vec<&'static str> { let mut out = Vec::new(); if self.0 & Self::PURE != 0 { out.push("pure"); } if self.0 & Self::IO_HEAVY != 0 { out.push("io"); } if self.0 & Self::ALLOCATES != 0 { out.push("alloc"); } if self.0 & Self::NETWORK != 0 { out.push("net"); } if self.0 & Self::HOT_PATH != 0 { out.push("hot"); } if self.0 & Self::SECURITY_SENSITIVE != 0 { out.push("sec"); } out } } #[cfg(test)] mod tests { use super::*; use cubecoords::{CubeHeader, Czyx}; use cubestore::{CubeStore, HashBackend}; #[test] fn behavior_round_trips_through_store() { // All six spec descriptors must survive the real store round-trip // (what native-apply reads back). This is the exact field the // effector inspects; an earlier 3-bit mask (0x7000) silently dropped // HOT_PATH (bit 15) and collided with ENCRYPTED (bit 12). let b = Behavior::new( Behavior::PURE | Behavior::IO_HEAVY | Behavior::ALLOCATES | Behavior::NETWORK, ); let raw = b.to_flags(); assert_eq!( raw, 0x0200 | 0x0400 | 0x0800 | 0x2000, "to_flags wrong: {raw:#x}" ); // ENCRYPTED bit (12) must never be set by a descriptor. assert_eq!(raw & (1 << 12), 0, "descriptor must not set ENCRYPTED bit"); let mut store = CubeStore::new(HashBackend::new()); let coord = Czyx::new(210, 1, 1, 3); let mut h = CubeHeader::new(); h.doc_type = Some("kernel".into()); h.title = Some("summarize-procs".into()); h.flags.0 |= raw; h.refresh_flags(); store.put_record(coord, &h, &[1, 2, 3]); let (read_h, _) = store.get_record(&coord).expect("record present"); let back = Behavior::from_flags(read_h.flags.bits()); assert_eq!( back, b, "behavior dropped on store round-trip: stored {raw:#x}, got {:#x}", read_h.flags.bits() ); } #[test] fn security_sensitive_bit_used_and_round_trips() { // Explicitly cover the 6th spec descriptor (security sensitive, bit15). let b = Behavior::new(Behavior::SECURITY_SENSITIVE | Behavior::HOT_PATH); let mut store = CubeStore::new(HashBackend::new()); let coord = Czyx::new(210, 1, 1, 5); let mut h = CubeHeader::new(); h.doc_type = Some("kernel".into()); h.title = Some("privileged-op".into()); h.flags.0 |= b.to_flags(); h.refresh_flags(); store.put_record(coord, &h, &[]); let (read_h, _) = store.get_record(&coord).expect("record present"); assert_eq!( Behavior::from_flags(read_h.flags.bits()), b, "security-sensitive descriptor lost on round-trip" ); } }