Files
cubelinux/STATUS-packages.md
T
luulu e4a662c459 The artifacts that describe a different product, or a sentence nobody wrote
Two documents in this tree present themselves as current and describe CUBELINUX-2:
CUBELinux-whitepaper-final-draft.txt (added 2026-09-06, untouched since, 0% CUBE-OS — no
#548, no cube(2), no v3, no build #50, none of the 183 tests, and every /home/CUBELinux/...
path it cites as authority is ENOENT) and CUBE-FUSE-project.txt. Both get banners naming
what is stale, rather than rewrites: the whitepaper's coordinate design is still the
substrate's design, and the FUSE review is the record of the edge view working — which is
worth having, because DESIGN-coordinate-interface §2.4 blesses that view and §6 explains
why its readdir is fine there and disqualifying in the core.

STATUS-packages.md: the TriWord/TriEnc row said "deliberately not ported" and the crate is
here (cube-core/src/wordflags.rs, re-exported); §3.3's heading said the same and is now
"ported as a reader, not as the body", which is the narrower claim the section actually
argues. The cube-os row linked two files that no longer exist, the counts are 183 now rather
than 156/161, and the mount/inode rows are marked as what they are: the ledger of a period
when one tree carried every package.

Two citations are corrected rather than quietly left: PLAN-cube-os-and-cubed.md attributed a
sentence to "whitepaper §6" that the whitepaper does not contain ("third impl" has zero
occurrences in it) and called FUSE's format-proof role "Whitepaper §7.1", a section about the
physical workhorse — "format-proof" appears zero times there, and the phrase is from
CUBE-FUSE-project.txt:229. Invented attributions are worse than missing ones: they make a
sound argument look sourced.
2026-09-21 17:46:51 -04:00

18 KiB
Raw Blame History

Package status — Tree A against CUBELinux.pdf

Status: all five PDF packages are implemented in Tree A · 2026-08 · 161 tests green then; 183 measured today

Read this first (2026-09-18). The tables below are the ledger of the period when one tree carried every package. That is no longer the shape of the project: CUBE OS (/home/CUBE-OS) is now the coordinate substrate — whitepaper §5's crate set — and CUBED (/home/CUBEdb) is the standalone CUBE where namespaces, paths, the VM, the ball index and the FUSE mount live. Several crates named below (cube-fs, cube-os, cube-plane, cube-fuse-proxy, cube-code, cube-trace, cube-dbt, cube-ai, the platform services) have left CUBE OS; the per-crate decision table is in PLAN-cube-os-and-cubed.md §4 and the split itself in REVIEW-two-cubes.md.

Two rows have also moved on since this ledger was written: the daemon no longer serves a namespace API but the command language over coordinates, and cube-api is deleted (CUTOVER-language-protocol.md). Current state: 183 tests green in CUBE OS (measured 2026-09-21 with cargo test --release --workspace; the 156 and 161 above are this ledger's period), no clippy warnings; the daemon cutover on the live machine is recorded in CUTOVER-language-protocol.md.

Three rows below are also wrong as statements of CUBE OS today, corrected here rather than silently: TriWord/TriEnc ARE ported (crates/cube-core/src/wordflags.rs, re-exported from lib.rs) — the ❌ at §3.3 and the row at :40 are stale, and PLAN-cube-os-and-cubed.md §3 has them as built. The cube-os row at :42 links crates/cube-os/src/bind.rs and os.rs, and neither file exists — cube-os left this tree. And the cubefs mount row at :37, plus the "inode generation scheme" at :203, describe a mount and its inode machinery as CUBE OS backlog; DESIGN-cube-interface.md §2 rejected a mount in the core and DESIGN-coordinate-surface.md §6 says why the inode machinery is not wanted back. This file is the ledger of the period when one tree carried every package; it is not a current status, which is what its own banner above already says.

This document is the completion ledger for the source specification. The PDF (66 pp, a transcript rather than a spec) names five packages, a tri-channel word encoding, and a header/flag scheme. Each row below says where that lands in Tree A, and — where Tree A deliberately departs — why.

The short version: Tree A implements every package, and disagrees with the specification in exactly three places, each for a measured reason. The disagreements are recorded as decisions, not gaps.


1. Package-by-package

PDF package What the PDF asks for Tree A State
1. cubecoords Core primitives, Czyx + pack/unpack to u32, null vs user space, no dependencies cube-core — SpaceId (256-bit) + Point (three u64) + Coord, Curve (Morton/Hilbert), portal, Region ✅ implemented, coordinate model width differs by design (§3)
2. cubestore A generic cube abstraction over any CubeBackend: put/get/delete by coordinate, CubeHeader, CubeRecord, associate(src,dst), "all records linked to X" cube-store (Store trait, MemStore, FileBackedStore, Region queries), cube-header (CubeHeader + HeaderStore + edges in NULL_SPACE), cube-index (adjacency/portal index) ✅ implemented
3. cubefs Mount the cube as a namespace; map axes to directories/files; Null cubes for ACLs, xattrs, journaling cube-fuse-proxy (FUSE mount), cube-cli, cube-daemon + cube-client (shared store over a socket) ⚠️ partial — see §4. Gap analysis in progress
4. cubevm / cubecode Code and AI artifacts as records; call graphs, dependency edges, variants, version history via links; a runtime that walks links to dispatch functions cube-code (opcode codec, CodeCell, deterministic Vm, edges as the call graph, ball index, trace/golden artifacts), cube-trace (capture head), cube-dbt (translation rules → code cache), cube-ai (classify → suggest → feed the translator) ✅ implemented
5. cubecrypt Null cubes as environment settings; key material in cells; record-level selectors; audited crypto only; access logs and tamper-evident metadata in separate null ranges cube-crypt — CubeEnv, KeySlot, sealed envelopes (AES-256-GCM / ChaCha20-Poly1305 / AES-XTS), keyinit (OS keystore), AccessLog, HMAC hello auth ✅ implemented
Tri-channel word (TriWord/TriEnc) Pack 6 ASCII chars + 4 control bits into 64 bits cube-core::wordflags — wordflags.rs keeps the original layout and TriEnc::pack_6 is the PDF's packing ✅ ported (§3.3 — this row said "deliberately not ported" and was wrong; the crate is here and re-exported from lib.rs)
Header/flag scheme Titles, types, dates, sizes, permissions, associations, counters as Null-space flag bytes or a typed header struct cube-header::CubeHeader — fixed 26 bytes: kind, size, created_at, links, visibility, 16 flag bits, 8 meta bytes; Behavior descriptors in the out-of-band half ✅ implemented as the typed struct the PDF's Rust sketch prefers (§3.2)
The layer the PDF implies but never names Something that makes packages 3–5 interoperate cube-os — bind crossed between path/coordinate/code/ciphertext; os was a store, an identity and an environment where every operation is admitted before it is applied and recorded whether or not it was ✅ was implemented — and cube-os has left this tree (2026-09-21: neither linked path exists any more; see the banner above)

2. Reserved spaces (the "Null cubes")

The PDF reserves coordinate ranges. Tree A reserves whole 256-bit spaces, each owned by the layer that needs it:

0xFF…  association edges       cube-header::NULL_SPACE
0xFE…  portal descriptors      cube-index::PORTAL_SPACE
0xFD…  OS keystore             cube-crypt::KEYSTORE_SPACE
0xFC…  captured trace events   cube-trace::TRACE_SPACE
0xFB…  code + run artifacts    cube-code::CODE_SPACE   (bands on the Y axis)
0xFA…  stored index structures cube-code::INDEX_SPACE
0xF9…  ordinal registry        cube-fs::REGISTRY_SPACE
       per-space header space  cube_header::null_space_for(space)
       per-domain registry     cube-fs::Registry::for_domain(space)

The reservation convention is a rule, not a list: a reserved space is an all-equal-byte space in 0xF0..=0xFF (cube-fs::is_reserved_space). That is what lets a namespace listing skip the control plane without a hard-coded table that drifts every time a layer is added, and it is why a user space should not be chosen from that range.

Which space is C?

ordinal 0    reserved, never names a space (the PDF's "0 = Null")
ordinal 1    the fixed root: SpaceId::from_name("cube/root")   — public by design
ordinal 2..  allocated through a registry, in a space of the registry's choosing

A space id is a capability, so ordinals are labels, not identities: C=2 resolves through a registry record to a SpaceId, exactly as a hostname resolves through DNS. If C were the identity, spaces would be enumerable and the capability property would be gone — the same measurement that ruled out a 32-bit keyspace. Ordinals also are not invariant under copying a store, and a bare 1 in a path already means the space 0x…01, so ordinals are spelled c1, c2, … in paths.

The root is derived from a name, hence publicly computable. That is deliberate: the OS must find its own space at boot with no prior secret. A boot-discoverable root and an unguessable tenant space are different jobs. Isolation for the rest comes from where the registry lives: Registry::global is the OS's own table, Registry::for_domain derives a private one from a domain's SpaceId, so reading a tenant's mounts requires already holding that tenant's capability.

CODE_SPACE carries its bands as addresses, not as separate spaces: y = 0 Kernel · 1 Effect · 2 DbtRule · 3 DbtCache · 4 Trace · 5 Golden · 6 BlockTrace. That is the shape a 192-bit address space is for — one reserved space can hold a structured namespace without spending a reservation per feature.


3. The three deliberate departures

3.1 Coordinate width: Point is u64 × 3, not u8 × 4

The PDF's Czyx is four 8-bit axes, giving a 32-bit keyspace. Tree A uses a 256-bit SpaceId plus three 64-bit axes: 2^192 points per space.

Measured reason (see REVIEW-cubelinux-pdf.md §2 and cube-core's module docs): a 32-bit keyspace holds ~4.23 × 10^9 cells and is exhaustively enumerable. A coordinate in this system is a capability — knowing it is the authorisation — and a capability you can enumerate by brute force is not one. 256 bits of space is unguessable; 192 bits of point is unenumerable.

Everything else in the spec is separable from coordinate width, which is why Packages 2–5 ported onto the wider model without changing what they mean.

3.2 Headers carry a kind byte, not title/type strings

The PDF's header sketch (from the 2006 notes) has free-text title, doc_type, owner. That is a name space bolted onto a system whose entire claim is that a position in space resolves to bytes. Tree A stores a typed EntityKind byte instead:

0 Data  1 Memory  2 Session  3 Project  4 Edge  5 Fn  6 Kernel  7 Layer
8 Checkpoint  9 Variant  10 Trace  11 Golden  12 IndexNode  0x80|d NullSpace(d)

Kinds 5..=12 are the PDF's Package 4 types, added additively in a previously unused range — the 26-byte layout never changed. Naming belongs to a namespace layer (a cubefs path, a project record, an association), where the PDF's own Package 3 already puts it.

3.3 Tri-channel word encoding: ported as a reader, not as the body

Corrected 2026-09-21: this heading read "not ported", which was false. TriWord and TriEnc are implemented in crates/cube-core/src/wordflags.rs and re-exported from lib.rs; PLAN-cube-os-and-cubed.md §3 lists them as built. What the section below argues is the narrower and still-good point — that the encoding is not used as the store's record framing, because the density arithmetic does not pay off against this store's actual record shape.

TriWord packs 6 ASCII characters plus 4 control bits into 64 bits to trade CPU for I/O density. Measured against the store's actual record shape, it raises stored size by ~25% on this workload (reflated density regression, recorded during the A/B comparison) — the encoding pays off only when a backend is byte-addressed at 6-byte granularity, which cube-store is not. The claim ("trading CPU for I/O/space efficiency") is a hypothesis about a KV store's block layout, and on this one it loses.

Revisit if a byte-addressed backend is ever the target; it is an encoding choice, not a foundation, so nothing else depends on the decision.


4. What is genuinely not done

Item Where it stands
Package 3 control plane Shipped: volume metadata (label + layout version), grants (the authority primitive, including OWN as a grant so a record needs no owner field), extended attributes mirrored in their own space, and the journal band, which cube-os uses for its decision trail. Not implemented: POSIX mode/uid/gid as views over grants, a general inode-generation scheme, and the ring/wrap semantics a long-lived journal wants.
Sharded multi-writer MVCC store The sibling tree has an MvwBackend (shards, per-shard WAL, LSM-lite compaction). Not ported: it is a storage engine, not a coordinate-layer feature, and Tree A's durability story is already FileBackedStore + the pinned raw-block format (cube-store-raw) + the daemon. Porting it would mean a second, competing durability model. Decide deliberately, not by drift.
OS integration (cubesys) Explicitly the next phase, and deliberately after this ledger: the OS layer should be built on a frozen substrate.
Kernel work PLAN-kernelize-cube.md tracks it; the running 6.19.3-cube+ kernel contains no CUBE code yet. Two format questions belong with it: an explicit record count or terminator in the raw header (the padding class is fixed by a reader rule, but the format still cannot say how many records it holds), and whether the kernel reads the store directly or through cubed.
Shared-store access Shipped as the daemon boundary: cubed holds one store and serves the command language over a Unix socket, and cube_client::DaemonStore presents that same store through the Store contract, so a mount and the system layer address one store instead of each holding a private copy. The old raw_* coordinate operations are gone with the namespace API they sat under — one protocol, not two. What is not there: change notification, so a client learns about another process's write only when it asks again.

4.1 The Package 3 control plane: what shipped, and where

The PDF says "use Null cubes/rows for ACLs, extended attributes, journaling, volume metadata" but not which one holds which. Two derivation rules cover it, and a namespace listing needs to recognise both:

header partition    null_space_for(space)          one 26-byte header per record
metadata plane      meta_space_for(space)          bands, plus a plane header
attribute mirror    xattr_space_for(space)         the subject's point, mirrored

Bands in the plane, for records whose address is synthetic:

y=0  volume metadata   label + layout version
y=1  grants            who may do what, where
y=2  xattr             (reserved: attributes use the mirror space instead)
y=3  journal           the decision trail, appended by `cube-os`
y=4  identity          reserved for named ownership records
y=5  registry          ordinal -> SpaceId, per domain

Mirroring in its own space, for records addressed by the subject they describe: an attribute of the record at (x, y, z) is at (x, y, z). That needed a separate space rather than a band, because a band consumes an axis and a subject's y is data, not a category — a distinction that only showed up when a subject's coordinates happened to look like a band's.

Each metadata space carries a plane header naming the domain it describes. That is not decoration: the derivation is a bit flip, so it is its own inverse, and a hiding rule based on presence alone cannot tell a plane from its domain — the first attempt hid the domain and emptied a listing. The header makes the direction a fact.

Still missing, in the order it should be done:

  1. POSIX views over grants — a mode bit is a grant with a one-point scope, and chmod/chown become ways to write that grant. The OS layer already answers "may this identity do this" without them, which is why they are a view rather than a second authority model.
  2. Journal ring semantics — the trail appends and reads back; wrap, retention and what must survive a crash are undecided.
  3. A general inode generation scheme, so a mount can reuse inodes rather than only ever allocating new ones.

5. How to see each package working

# Package 1+2: coordinates, records, headers, edges
cubecli --store /tmp/demo.store put  root:1,2,3 hello
cubecli --store /tmp/demo.store hdr  root:1,2,3
cubecli --store /tmp/demo.store link root:1,2,3 root:4,5,6
cubecli --store /tmp/demo.store follow root:1,2,3 0

# Package 4: code as data, runs, goldens, translation rules
cubecli --store /tmp/demo.store code  root:10,0,0 const:3 const:4 mul halt
cubecli --store /tmp/demo.store run   root:10,0,0
cubecli --store /tmp/demo.store capture root:10,0,0 root:20,0,0 root:21,0,0
cubecli --store /tmp/demo.store verify  root:10,0,0 root:20,0,0 root:21,0,0
cubecli --store /tmp/demo.store lineage root:21,0,0 4
cubecli --store /tmp/demo.store rule  code:1,2,0 mul shl
cubecli --store /tmp/demo.store mimic root:10,0,0

# Package 5: sealing by coordinate
cubecli --store /tmp/demo.store keys
cubecli --store /tmp/demo.store seal root:30,0,0 "a secret"
cubecli --store /tmp/demo.store open root:30,0,0

# Package 3: the namespace by path (C may be a space id, a name, or `c1`, `c2` …)
cubecli --store /tmp/demo.store ls    /
cubecli --store /tmp/demo.store mkdir /c1/3
cubecli --store /tmp/demo.store write /c1/3/2/1 "hello namespace"
cubecli --store /tmp/demo.store stat  /c1/3/2/1
cubecli --store /tmp/demo.store ls    /c1/3/2
cubecli --store /tmp/demo.store alloc docs      # label a space, then use /c2/...
cubecli --store /tmp/demo.store spaces

# Package 3 control plane: labels, authority, attributes
cubecli --store /tmp/demo.store label  c1 "os volume"
cubecli --store /tmp/demo.store grant  c1 root root o c1        # claim the domain
cubecli --store /tmp/demo.store grant  c1 root alice rw /c1/3/2/1
cubecli --store /tmp/demo.store allows c1 alice /c1/3/2/1 r     # allow
cubecli --store /tmp/demo.store allows c1 alice /c1/3/2/1 x     # deny
cubecli --store /tmp/demo.store grants c1
cubecli --store /tmp/demo.store xattr  /c1/3/2/1 user.note "kept"

hdr prints the flag word and the encrypted bit, which is how you can see the metadata model doing its job rather than taking it on faith.


6. Where each decision is written down

| The name tier living at the edge, not in the store | CUTOVER-language-protocol.md |

A-vs-B port ledger (per crate, with rationales) this document + the commit messages on feat/kernelize-cube-rawblock
Coordinate width, curve choice, aggregation DESIGN-coordinate-layer.md, REVIEW-cubelinux-pdf.md §2
Entity/kernel model, edges, provenance DESIGN-os-entities.md
Kernel direction PLAN-kernelize-cube.md
Debugging/tracing plan PLAN-debugging.md
Agent integration INTEGRATION-cube-agent.md
A-vs-B port ledger (per crate, with rationales) this document + the commit messages on feat/kernelize-cube-rawblock