feat(dbt+ai): build out cubedbt and cubeai packages (Package 4, PDF §549/§551)

cubedbt: DBT runtime that reads CZYX-stored translation rules and patches
them into a code cache to execute mimicked behavior. TranslationRule (CZYX
Variant record in c220 band) maps an op-class to a replacement bytecode
fragment; CodeCache patches an original CodeCell under eligible rules and
writes the result as a Variant (preserving behavior descriptors), and
DbRuntime.mimic() fetches -> patches -> runs in the real Vm, proving
're-run or modify behavior without the original binary'.

cubeai: models over cube-stored traces/graphs to classify blocks
(Computation/Branch/CallTrampoline/IoSection/Sequence from the op-class
histogram + behavior descriptors) and suggest new code sequences as
cubedbt TranslationRules (persisted into the c220 rule band, discoverable
by DbRuntime). End-to-end: trace -> classify -> suggest -> mimic.

Both crates are dependency-free and operate on the real CubeStore/CodeCell/
Vm/Behavior types, so they are exercisable today on HashBackend and slot
into ConcurrentStore later without an API change. ./check quick green:
cubedbt 4 tests, cubeai 5 tests, full workspace green.
This commit is contained in:
CUBELinux-2
2026-08-13 16:23:00 -04:00
parent 0074f3112c
commit 3121459138
5 changed files with 781 additions and 0 deletions
+429
View File
@@ -0,0 +1,429 @@
//! CUBELinux-2 DBT (dynamic binary translation) runtime.
//!
//! Per the PDF (Package 4, §549): *"cubedbt: a runtime that reads CZYX‑stored
//! translation rules and code fragments and patches them into a code cache to
//! execute mimicked behavior."*
//!
//! This crate is the substrate for the PDF's "watch a binary, archive its
//! behavior structurally, replay or transform it as if it were its own program"
//! story (§554). It is deliberately dependency-free and operates on the real
//! `CubeStore` / `CodeCell` / `Vm` types from the rest of the workspace, so it
//! is exercisable today on `HashBackend` and slots into `ConcurrentStore`
//! later without an API change.
//!
//! Model
//! -----
//! * A **translation rule** is a CZYX record (`Kind::Variant`) whose body is a
//! serialized [`TranslationRule`]. It names an *op kind* it can replace and
//! carries a *replacement fragment* (a `Vec<Op>`). The rule record links to
//! the original code cell it may substitute (the association edge).
//! * A **code cache** is the patched working set: `patch()` rewrites an
//! original `CodeCell`'s bytecode under the eligible rules and writes the
//! result back as a new record (preserving the original header's kind/title
//! and behavior descriptors, so it runs through the same `Vm`).
//! * A **DBT runtime** discovers rules in a store and can `mimic` a target
//! coordinate: fetch original → apply rules → run the patched version in the
//! `Vm`, returning the `RunResult`.
use cubecode::{opcode::Op, CodeCell, Kind, Vm};
use cubecoords::{Czyx, CubeHeader};
use cubestore::{CubeBackend, CubeStore, HashBackend};
/// `C` axis band where DBT translation rules are stored, kept distinct from the
/// `c210` OS-kernel band (`cubecode::C_OS_KERNEL`) and the `c200` snapshot data.
pub const C_DBT_RULE: u8 = 220;
/// `C` axis band where patched/mimicked code-cache entries are written.
pub const C_DBT_CACHE: u8 = 221;
/// The `Op` kinds a translation rule can target.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum OpClass {
Const,
Add,
Sub,
Mul,
Div,
Mod,
And,
Or,
Xor,
Shl,
Shr,
Eq,
Ne,
Lt,
Gt,
Le,
Ge,
Load,
Store,
CallLink,
Any,
}
impl OpClass {
/// Classify a live [`Op`].
pub fn of(op: &Op) -> OpClass {
match op {
Op::Const(_) => OpClass::Const,
Op::Add => OpClass::Add,
Op::Sub => OpClass::Sub,
Op::Mul => OpClass::Mul,
Op::Div => OpClass::Div,
Op::Mod => OpClass::Mod,
Op::And => OpClass::And,
Op::Or => OpClass::Or,
Op::Xor => OpClass::Xor,
Op::Shl => OpClass::Shl,
Op::Shr => OpClass::Shr,
Op::Eq => OpClass::Eq,
Op::Ne => OpClass::Ne,
Op::Lt => OpClass::Lt,
Op::Gt => OpClass::Gt,
Op::Le => OpClass::Le,
Op::Ge => OpClass::Ge,
Op::Load(_) => OpClass::Load,
Op::Store(_) => OpClass::Store,
Op::CallLink(_) => OpClass::CallLink,
_ => OpClass::Any,
}
}
}
/// A translation rule: a named, CZYX-addressed mapping from an op class to a
/// replacement bytecode fragment. Serialized into a rule record's body.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct TranslationRule {
/// Human name (also the rule record's title).
pub name: String,
/// Which op class this rule can substitute.
pub target: OpClass,
/// Replacement bytecode fragment (must itself be valid; it replaces every
/// matched op in the original, in place, preserving program length-agnostic
/// semantics the caller is responsible for).
pub fragment: Vec<Op>,
}
impl TranslationRule {
/// Serialize to a stable byte form (name length-prefixed, target byte,
/// fragment as opcode codec). No external deps.
pub fn to_bytes(&self) -> Vec<u8> {
let mut out = Vec::new();
let nb = self.name.as_bytes();
out.push(nb.len() as u8);
out.extend_from_slice(nb);
out.push(self.target as u8);
out.push(self.fragment.len() as u8);
for op in &self.fragment {
out.extend_from_slice(&cubecode::opcode::encode(&[*op]));
}
out
}
/// Inverse of [`to_bytes`]. Returns `None` on any malformed input.
pub fn from_bytes(b: &[u8]) -> Option<TranslationRule> {
let mut i = 0;
let nlen = *b.get(i)? as usize;
i += 1;
if i + nlen > b.len() {
return None;
}
let name = String::from_utf8(b[i..i + nlen].to_vec()).ok()?;
i += nlen;
let target = *b.get(i)?;
i += 1;
let target = match target {
0 => OpClass::Const,
1 => OpClass::Add,
2 => OpClass::Sub,
3 => OpClass::Mul,
4 => OpClass::Div,
5 => OpClass::Mod,
6 => OpClass::And,
7 => OpClass::Or,
8 => OpClass::Xor,
9 => OpClass::Shl,
10 => OpClass::Shr,
11 => OpClass::Eq,
12 => OpClass::Ne,
13 => OpClass::Lt,
14 => OpClass::Gt,
15 => OpClass::Le,
16 => OpClass::Ge,
17 => OpClass::Load,
18 => OpClass::Store,
19 => OpClass::CallLink,
_ => OpClass::Any,
};
let flen = *b.get(i)? as usize;
i += 1;
let mut fragment = Vec::new();
for _ in 0..flen {
// Each fragment op was encoded individually; decode one at a time,
// advancing `i` by its encoded byte length.
let one = decode_one(&b[i..])?;
i += one.len;
fragment.push(one.op);
}
Some(TranslationRule {
name,
target,
fragment,
})
}
}
/// One decoded opcode plus its encoded length, used by `from_bytes`.
struct One {
op: Op,
len: usize,
}
fn decode_one(b: &[u8]) -> Option<One> {
let op = cubecode::opcode::decode(b).ok()?;
let op = op.into_iter().next()?;
let len = cubecode::opcode::encode(&[op]).len();
Some(One { op, len })
}
/// A patched working set ("code cache") inside a [`CubeStore`].
///
/// `patch` rewrites an original [`CodeCell`]'s bytecode under the eligible
/// rules and writes the result back as a new record (preserving the original
/// header's kind/title and behavior descriptors, so it runs through the same
/// `Vm`). This is the literal "patches them into a code cache to execute
/// mimicked behavior" step from the PDF §549.
pub struct CodeCache {
store: CubeStore<HashBackend>,
/// Coordinate of the next cache slot to allocate.
next_x: u8,
}
impl CodeCache {
/// Build an empty cache over a fresh in-memory backend.
pub fn new() -> Self {
CodeCache {
store: CubeStore::new(HashBackend::new()),
next_x: 1,
}
}
/// Patch `original` under `rules`: every op whose class matches a rule's
/// target (or whose rule target is `Any`) is replaced by that rule's
/// fragment. The rewritten cell is stored at a fresh cache coordinate and
/// returned (with its new label). The original store is untouched.
pub fn patch(
&mut self,
original: &CodeCell,
rules: &[TranslationRule],
) -> CodeCell {
let mut patched: Vec<Op> = Vec::with_capacity(original.code.len());
for op in &original.code {
let class = OpClass::of(op);
let mut applied = false;
for r in rules {
if r.target == class || r.target == OpClass::Any {
patched.extend_from_slice(&r.fragment);
applied = true;
break;
}
}
if !applied {
patched.push(*op);
}
}
let label = Czyx::new(C_DBT_CACHE, 1, 1, self.next_x);
self.next_x = self.next_x.wrapping_add(1).max(1);
let (h, body) = cache_header_for(original, &cubecode::opcode::encode(&patched));
self.store.put_record(label, &h, &body);
CodeCell::from_record(label, &h, &body)
.expect("patched cell is always valid bytecode")
}
/// Run a patched cache entry in the VM, returning its result.
pub fn run(&self, cell: &CodeCell) -> cubecode::RunResult {
let mut vm = Vm::new(self.store.clone());
vm.run(cell.label)
}
/// Borrow the backing store (e.g. to persist or inspect).
pub fn store(&self) -> &CubeStore<HashBackend> {
&self.store
}
}
/// Build a cache record header that preserves the original's kind/title and
/// behavior descriptors, but marks it a `Variant` (a mimicked implementation).
fn cache_header_for(original: &CodeCell, body: &[u8]) -> (CubeHeader, Vec<u8>) {
let mut h = CubeHeader::new();
h.title = original.name().map(|s| format!("mimic:{}", s));
h.doc_type = Some(Kind::Variant.as_str().into());
h.size_bytes = Some(body.len() as u64);
// Carry the original's behavior descriptors forward (spec: descriptors
// travel with the mimicked behavior).
h.flags.0 |= original.header.flags.0 & cubecode::HEADER_FLAG_BEHAVIOR;
h.refresh_flags();
(h, body.to_vec())
}
/// The DBT runtime: discovers CZYX-stored translation rules and can `mimic` a
/// target code cell by patching it under those rules and running the result.
pub struct DbRuntime<B: CubeBackend> {
store: CubeStore<B>,
}
impl<B: CubeBackend> DbRuntime<B> {
/// Wrap a store that already contains rule records (or will, via
/// [`store_rule`]). The runtime is read-only over this store.
pub fn new(store: CubeStore<B>) -> Self {
DbRuntime { store }
}
/// Collect every translation rule currently in the `c220` rule band.
pub fn discover_rules(&self) -> Vec<TranslationRule> {
let mut rules = Vec::new();
for k in self.store.keys() {
if k.c != C_DBT_RULE {
continue;
}
if let Some((_, body)) = self.store.get_record(&k) {
if let Some(r) = TranslationRule::from_bytes(&body) {
rules.push(r);
}
}
}
rules
}
/// Fetch a code cell by coordinate from the wrapped store.
pub fn fetch(&self, label: Czyx) -> Option<CodeCell> {
let (h, b) = self.store.get_record(&label)?;
CodeCell::from_record(label, &h, &b)
}
/// Mimic `target`: fetch it, apply all discovered rules, patch into a fresh
/// cache, and run the patched version — returning the `RunResult`. This is
/// the end-to-end "re-run or modify behavior without the original binary"
/// path (PDF §554).
pub fn mimic(&self, target: Czyx) -> Option<cubecode::RunResult> {
let original = self.fetch(target)?;
let rules = self.discover_rules();
let mut cache = CodeCache::new();
let patched = cache.patch(&original, &rules);
Some(cache.run(&patched))
}
}
/// Store a translation rule into the `c220` rule band at a fresh coordinate.
/// Returns the coordinate it was written to.
pub fn store_rule<B: CubeBackend>(
store: &mut CubeStore<B>,
rule: &TranslationRule,
x: u8,
) -> Czyx {
let label = Czyx::new(C_DBT_RULE, 1, 1, x);
let mut h = CubeHeader::new();
h.title = Some(rule.name.clone());
h.doc_type = Some(Kind::Variant.as_str().into());
h.size_bytes = Some(rule.to_bytes().len() as u64);
h.refresh_flags();
store.put_record(label, &h, &rule.to_bytes());
label
}
#[cfg(test)]
mod tests {
use super::*;
use cubecode::opcode::Op;
use cubecode::RunResult;
use cubecoords::Czyx;
fn sample_cell(coord: Czyx, code: Vec<Op>) -> CodeCell {
let mut h = CubeHeader::new();
h.title = Some("sample".into());
h.doc_type = Some(Kind::Fn.as_str().into());
h.refresh_flags();
CodeCell::from_record(coord, &h, &cubecode::opcode::encode(&code))
.expect("sample is valid bytecode")
}
#[test]
fn rule_round_trips_through_bytes() {
let r = TranslationRule {
name: "double-add".into(),
target: OpClass::Add,
fragment: vec![Op::Const(2), Op::Mul],
};
let bytes = r.to_bytes();
let back = TranslationRule::from_bytes(&bytes).expect("rule decodes");
assert_eq!(r, back);
}
#[test]
fn cache_patches_and_runs() {
// Original: Const 3, Const 4, Add, Halt => 3+4 = 7.
let orig = sample_cell(Czyx::new(1, 1, 1, 1), vec![
Op::Const(3),
Op::Const(4),
Op::Add,
Op::Halt,
]);
// Rule: replace `Add` with `Const 2, Mul` => (a)*(2). With a=3,b=4:
// naive in-place substitution yields Const3, Const4, Const2, Mul =>
// 4*2 = 8. This proves the patched fragment is what runs.
let rule = TranslationRule {
name: "mul-by-2".into(),
target: OpClass::Add,
fragment: vec![Op::Const(2), Op::Mul],
};
let mut cache = CodeCache::new();
let patched = cache.patch(&orig, &[rule]);
assert_eq!(patched.kind(), Kind::Variant, "cache entry is a Variant");
match cache.run(&patched) {
RunResult::Halted { top: Some(v) } => assert_eq!(v, 8, "patched semantics differ"),
other => panic!("patched run failed: {:?}", other),
}
}
#[test]
fn runtime_mimic_end_to_end() {
let mut store = CubeStore::new(HashBackend::new());
// Original target at c1.
let target = Czyx::new(1, 1, 1, 1);
let orig = sample_cell(target, vec![Op::Const(10), Op::Const(5), Op::Sub, Op::Halt]);
store.put_record(orig.label, &orig.header, &orig.body());
// Rule in the c220 band: replace Sub with Add (10+5=15 instead of 5).
let rule = TranslationRule {
name: "sub->add".into(),
target: OpClass::Sub,
fragment: vec![Op::Add],
};
store_rule(&mut store, &rule, 1);
let rt = DbRuntime::new(store);
let rules = rt.discover_rules();
assert_eq!(rules.len(), 1, "rule discovered in c220 band");
match rt.mimic(target) {
Some(RunResult::Halted { top: Some(v) }) => assert_eq!(v, 15, "mimic applied rule"),
other => panic!("mimic failed: {:?}", other),
}
}
#[test]
fn mimic_without_rules_matches_original() {
let mut store = CubeStore::new(HashBackend::new());
let target = Czyx::new(1, 1, 1, 2);
let orig = sample_cell(target, vec![Op::Const(7), Op::Const(2), Op::Mul, Op::Halt]);
store.put_record(orig.label, &orig.header, &orig.body());
let rt = DbRuntime::new(store);
match rt.mimic(target) {
Some(RunResult::Halted { top: Some(v) }) => assert_eq!(v, 14),
other => panic!("mimic without rules should run original: {:?}", other),
}
}
}