Files
cubelinux-2/RESUME-20260821-os-in-cube.md
T

7.3 KiB

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<C>/z<Z>/y<Y>/x<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)

  1. 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