Cube design grew on the front of the apps: screens, tiles, a cube to turn. Today it was read for what holds underneath, and the apps were held to it on every layer.

one thing, three words

The distilled version of cube design from yesterday (one person, many agents) was merged this morning as 0.4, after two rounds in which Selim answered most of the open questions on the pull request. He corrected the agent several times on the way. Agents had made face and colour into core words (“face is just another word for a cube”), had invented whose it is, and had turned names into rules: “names are not rules, don’t try to make rules out of them.” What is left is one thing, the piece, and three words: piece, cube, part. Everything else is another name for those.

His sharpest new idea became a principle: “principles always hold true. Guidelines leave room for exceptions. If cube design has a solution of its own, or can have its own, avoid it.” And a reminder of what the thing is: “cube design is not a picture but a living thing.”

held to it

Living things get checked. The navigation run of 31 October (checking the design against itself) had left a list of issues, and today four threads fixed them in parallel, one per app. Selim asked them to “first really confirm those issues are there, because we did some changes yesterday.” That turned out to matter: one issue had already been fixed by the shared context cube the day before, and the distillation had settled several of the run’s questions. The spec had also moved under the run. Selim had reworded a principle to “I step in and I step out”, which turned cube design’s own website from following into a violation overnight. So the website learned to step out the way you came and to answer a hold, and the violation was written down before it was fixed, so it stays on the page afterwards. In the todarch cube, the app’s top now zooms out to Mosaic’s home rather than stopping, because an app inside another app is just a piece. In Anlat, holding a moment shows every name it has ever had, with its day and who gave it, and any of them can be made its name again. In Anlat titles are found slowly, so each earlier title is part of finding the right one.

The shared Angular package met the same test from the other side: three apps took it in a day. Cubes went first, an hour after the release, and found a gap the library alone could not show: the app’s page-wide arrow keys turned the whole cube while the square’s arrow keys turned a row. Anlat, the first app with a strict rule that nothing is written under 19 pixels, found that the package fixed its word sizes and had no variable for them. The todarch cube found that renaming a to-do through its context cube worked but the screen stayed put, because the package compared the held piece by identity. Each gap went to the library as a pull request, never as a patch inside the app, as the library’s rule says. That is what moving in early was for.

the package explains itself

The library had grown quietly, and Selim no longer knew what was in it. “Imagine that I am a developer and I would like to use this library,” he said, “it should have a website.” The plan: a small docs app, built with the package itself, at /angular/ on cube design’s site. It opens on a square of the package’s pieces, has no sidebar and no search, and zooms in and out like everything else. A check fails when an export has no page, so a piece cannot be added without its documentation.

Selim asked for the work to be split “where the division can start”. A lead wrote the contract first, the page shape and the script that collects exports, and three agents built the app, the pages and the tooling without touching each other’s files. Then five agents each wrote one group of pages from the code, in their own folders: the hold, the drawing and the icons, the square and the turning rows, the context cube, the guides. Writing from the code instead of the readme turned up drifts everywhere: two view icons that draw the same picture, a sorting function that puts moment 10 before moment 2 although it claims to read like a person, a default of 3 × 3 that is really columns by columns. Each went in as a finding, not a fix on the way.

One of them became a decision instead. Selim didn’t pick a winner between the two sorting orders: “just go with one, but have two as a possibility.” Natural order became the default and letter-by-letter stayed as an option apps can offer. It is solutions do not compete, they become options, used in code. By the evening all seventeen pages were written, every one of seventy-five exports had a page, and the package’s checks now fail when a change leaves its page behind. One pull request for Selim to merge.

the layers underneath

The larger study of the day started from one sentence of Selim’s: the screen is only one place cube design is implemented. The code and the database are layers too, and he wanted compliance tests for them like the one the front end already has.

First the design had to be freed from the words it grew up with. A thread classified every principle: 21 of 34 hold on every layer, but 8 of those are written in screen words. Four words clash between the screen and the database: row, table, view, column. The neat finding came from there. In a relational database the natural word for a side is column, which is exactly what cube design’s data shape rules out. That gives the data layer its first dial: is a side fixed by the developer, or noticed while the app runs?

Cube design read as layers, and the first database run per app: the twelve checks that need no decision, how many each app follows.

Cube design read as layers, and the first database run per app: the twelve checks that need no decision, how many each app follows.

Then small threads zoomed in, one per app, and read the tables and the Java side by side with the same table shape, so they could be set next to each other, Selim’s zoom in, zoom out. A synthesis zoomed back out: 22 database checks, 5 backend checks, eight decisions for Selim. Where the surveys disagreed on facts, the code was read, a reminder that a synthesis must check the code and not just merge reports. The biggest finding: the three apps’ placement tables took three shapes, and each shape followed where the app was born, in Notion rows, in Notion relations copied as arrays, or in a join table born in Postgres. Not a decision anywhere, just origin.

By the evening both checks ran as one command, the migrations on a throwaway database, the Java read from outside. The run needed a new verdict word, waiting, for checks that are named but wait on one of Selim’s answers. Reading the schema was sharper than the hand-written studies in about ten places. The backend run, once a bug in how it joined calls was fixed, agreed with the hand-written studies on fourteen of fifteen cells and kept the one disagreement in the open rather than tuning it away. It also found, by itself, the todarch cube assistant’s weak spot: it can take off a placement the person kept without asking. Fixing was out of scope all day, by Selim’s rule. It is a study.

the same work, three times

The study ended where the library had started. Three backends, 9,600 lines, and about half of them are fourteen ideas written more than once: the core tables, an owner on every row, earlier names, hiding, placing, zooming in. Anlat’s code says it out loud, in a comment on its names class: the same shape as Cubes’ names, written apart because sub-apps do not depend on one another. The drift shows in small things. A missing thing is a 500 in one app, a 400 in another and a 404 in the third.

Selim’s framing: “even though their domain is different, what they’re doing is all same.” Two threads surveyed what a backend library should look like and designed one, and reached nearly the same answer on their own. The turning insight: in cube design the apps differ by data, their given sides and their dials, not by structure. So the right model is a framework that owns its own tables, like Spring Batch, and not a mapper for the app’s own entities, which would bring sides back as columns. A core of plain Java, a store that generates the schema so the database checks pass by construction, a test kit, a thin starter. About half the lines would go. It is the backend twin of the Angular package, and it is a design, not yet code.

as far as an operating system

One thread went the other way, up instead of down. Selim came in unsure, “a bit ambitious”, “I am not confident in the technical part”, asking whether a whole Linux desktop could be dressed in cube design. Not built, dressed: “we are not gonna build an operating system with cube design, but we are gonna dress the operating system with cube design.” Six routes were compared. A theme alone was ruled out, because a theme can only recolour folders, a taskbar and a start menu, the very things cube design replaces. What kept both his sides, the browser being easy but “not giving us the good feeling” and a virtual machine being real but expensive, was one web shell tried in three places. A clickable prototype shows the desktop as one cube: names, kinds, days, places, open now, hidden, with windows as pieces seen close up. The cube company got a new team for it the same evening.

A day that began by cutting cube design down to three words ended with those words read in tables, in Java, in a library’s documentation and on a desktop that doesn’t exist yet. The design is smaller than it was yesterday, and it reaches further.