# RESUME POINT — 2026-08-21: all ./check stages green, cube-bench fixed, docs synced ## WHERE WE ARE (verified on disk this session) ### Git state Branch `feat/os-kernel-in-cube`, clean working tree. Commits this session: - `c090233` bench(cube-bench): fix scan_prefix expected-value math for scale > 65536 - `ae1a62a` docs: reflect cubecli as standalone crate in README + integration docs - `3f007a1` bench(cube-bench): use saturating_sub for expected-value arithmetic Plus 3 prior-session commits still on HEAD (7b0cf6f, ce8ac78, fdfcd2c). ### ./check gate `./check` → ALL CHECKS PASSED (fmt clean, 223 tests, clippy -D clean). ### ./check opt-in stages (all run this session, all green) - `./check mount` — 57/57 FUSE assertions (in-memory --seed + daemon-backed --socket + durability-across-restart + cross-user ACLs root↔luulu) - `./check daemon` — 3/3 live daemon tests (were #[ignore]d, now exercised) - `./check stress` — ~150s, 57075 prog+run pairs, daemon alive throughout, ~380 pairs/s - `cube-bench --release 200000` — FAILED once (real bug in bench's expected-value math), then FIXED and PASS at 1k/10k/50k/100k/200k ### Bug found + fixed this session cube-bench assumed all records beyond c=0 land in c=1. `coord_for` spreads across c=0,1,2,3 as i grows past 65536, so at 200k the expected c=1 count was wrong (134464 vs actual 65536). Fix: compute per-bucket expected counts from the coord_for mapping; extend total-coverage assertion to include c=2 and c=3. Verified at all scales with bench's own correctness assertions. clippy -D warnings clean on cube-bench after replacing manual `-` with `saturating_sub`. ### Docs synced - `STARTUP-README.md`: cube CLI now references `cubecli/src/main.rs` (was `cubesys/src/bin/cube.rs`) - `cubesys/docs/integration.md`: Binaries section notes cube is now a standalone crate (`cubecli/`) ## ARCHITECTURAL QUESTION: where should CUBE live when it becomes the OS? Two-layer model (already partially deployed — this is the right shape): **Layer 1 — Kernel (the "utilize CUBE" part).** CUBE core crates — `cubecoords`, `cubestore` (HashMap + FileBackedStore + WAL/checkpoint), `cubecode` (bytecode + VM), `cubecrypt` (seal/open + keyinit) — get compiled into the kernel or as a kernel module. Kernel gets direct syscalls: `open_by_czyz()`, `write_czyz()`, `seal_czyz()`, `run_czyz()`. The cube becomes the backing store the VFS and process accounting talk to directly — not a userspace daemon over a socket. This is the spec's Phase 3 ("OS services talk directly to the cube store; syscalls like open by CZYX + flags"). **Layer 2 — Userspace daemon (`cube-server`).** Stays as the durable anchor: WAL, checkpoint, socket for external/remote clients, the "resume pointer" writer. Survives when the kernel module isn't loaded; what remote clients talk to. Currently at `/run/cube/cube.sock` (system) + `/run/user/1000/cube/` (luulu session). Unify under `/usr/lib/cube/` when it's the OS — daemon binary, libs, socket path, store dir all there. **Filesystem placement when it's the OS:** - Kernel module/built-in: lives in the kernel source tree (copy of core crates, adapted for kernel constraints — `no_std`, no alloc assumptions that conflict with kernel alloc) OR as out-of-tree module alongside your existing Surface/ipu4 kernel. - Userspace daemon + libs: `/usr/lib/cube/`. Socket at `/run/cube/cube.sock`. **Honest gaps before this is real (both still open, from STARTUP-README §5):** - (a) **cubefs directory model** — only `c/z/y/x` with x as fixed 3-digit leaf. No nested dirs, no arbitrary POSIX filenames, no rename/whiteout. Overlayfs rejects cubefs with EINVAL. A real OS tree can't be bound until this is done. Level-B crate feature. - (b) **root fs / PID 1** — making the cube the literal rootfs is kernel work: custom initramfs + pivot_root, daemon or kernel module as init. Heavy, image-bake, off-peak. Current deployment: ext4 root + CZYX-call OS state = Phase 2 target. **On "compile the new kernel to utilize CUBE":** your current kernel is vanilla v6.19.3 + ipu4 drivers (GRUB entry `LOCALVERSION=-ipu4p`); camera work is paused. Adding CUBE means either a kernel module against that kernel, or a new kernel build with CUBE integrated. That's a resource-heavy compile (saturates all 8 cores + memory). You've asked me not to auto-launch that while you're using the machine — I'll wait for your go. ## NEXT SESSION: put the OS in CUBE + compile new kernel to utilize CUBE ### What "put the OS in CUBE" means concretely (Phase 2 deepening) The OS already writes its state (manifest, identity, klog, snapshots) as CZYX calls to `cube-server` over the socket — that's done and durable (verified across daemon restart). The next deepening is moving the cube from "userspace daemon the OS talks to over a socket" to "the kernel's own backing store" — i.e. the kernel module layer above. ### Concrete first step (before any kernel compile) 1. **Pick the kernel target.** Current: vanilla v6.19.3 + ipu4 (LOCALVERSION=-ipu4p). Option A: add CUBE as an out-of-tree module to that kernel. Option B: new kernel build with CUBE integrated. Which, and do you want to keep the ipu4 camera kernel as the base, or start fresh? 2. **Decide CUBE's kernel boundary.** What goes into the kernel vs stays in userspace? - Definitely kernel: `cubecoords` (Czyx type, flags), `cubestore` core (the store abstraction + at least the in-memory backend; FileBackedStore + WAL/checkpoint is the durable path), coordinate→syscall mapping. - Probably userspace ( daemon ): the socket server, remote client access, the "resume pointer" writer, snapshot management — i.e. the control plane, while the kernel is the data plane. - `cubecode` (bytecode VM) and `cubecrypt` (seal/open transforms) — these are the debatable ones. VM in kernel = ability to run cube programs from kernel space (syscall-level). Crypto in kernel = sealed records openable by the kernel without a userspace daemon. Both are plausible; both add kernel surface area. Your call. 3. **cubefs directory model gap (a) above** — decide whether to close it before or after the kernel move. If the kernel uses the cube as backing store but cubefs can't represent a real OS tree (no nested dirs, no rename), then the OS-state-writing path (CZYX calls, not FUSE) still works, but a full rootfs bind is still blocked. Closing (a) is a crate feature, independent of the kernel move. ### Concrete second step (kernel compile — heavy, ask before launching) 4. **Build the kernel/module.** Depends on step 1-3. If out-of-tree module: copy the core crates into a kernel module skeleton, adapt for kernel constraints, build against the existing kernel headers. If integrated kernel: new kernel source with CUBE subsystem, config, compile. Either way: `make -j8` saturates all cores + memory — you've asked me not to auto-launch that while you're using the machine. ## FILES - Workspace: `/home/CUBELinux/CUBELinux-2/` - Canonical gate: `./check` (run from workspace root) - Resume procedure: read this file + STARTUP-README.md + REPORT-INDEX.md, then `python3` against `/root/.hermes/state.db` for thread review. - Cube-bench binary (release): `target/release/cube-bench` - Current kernel GRUB entry: `LOCALVERSION=-ipu4p` (vanilla v6.19.3 + ipu4 drivers) - System daemon socket: `/run/cube/cube.sock` - luulu session daemon socket: `/run/user/1000/cube/cube.sock`