September 16, 2026

Imports point inward: how we keep our code tidy

A rule that nobody checks slowly breaks. Here is the one rule we follow for how parts of genvi connect, and the automatic checks that enforce it.

There is one big rule in the genvi code: imports point inward or sideways, never outward. An import is when one piece of code uses another piece. The rule is easy to say and easy to break, because breaking it still works. So we stopped relying on memory and set up automatic checks that say no when someone breaks it.

The rule

Our code is arranged in four layers, from the outside in.
  • Pages, and the server code that answers them.
  • The screens you use, with a shared set for every area.
  • The memory each area keeps while you work.
  • Everything else, which does not know what is on screen.
Inner layers must never depend on outer ones. The shared inner layer cannot use a screen or a page. The memory cannot use a screen. A shared screen part cannot reach into one area's memory.
When a shared part truly needs to behave differently in two areas, it takes a small plug-in from each area. It never checks which area is calling it.

Why it breaks without anyone noticing

A review found 49 loose files in the shared layer and nothing stopping it from depending on a screen. The direction of these links is the part that decays quietly. One link from the shared layer to a page turns a shared tool into a piece of that page. One link from a shared screen part to one area's memory turns it into that area's part. That is how we ended up with four file browsers and two versions of the node body.
None of these links was wrong on its own. Each was the shortest way to get a feature working that afternoon.

Check one: a rule in the editor

We added an automatic rule to every layer. The most useful part is the message. It does not just say no. It tells you where the code belongs instead. For example, one message says the shared layer does not know what is on screen, and tells you to keep the page outside it. Another says memory holds information, not screens, and tells you to pass in what you need.

Check two: a test that proves the rule works

A rule that matches nothing looks just as clean as a rule that matches everything. So we do not trust the rule alone. A second check tries real examples of bad and good code and confirms that each bad one is caught and each good one is allowed.
For example, a shared tool using a screen is refused. A screen part using one area's memory is refused. But a shared screen part using the feedback memory is fine, because feedback belongs to no single area. The same feedback buttons appear in chat, the node canvas and the 3D studio.
The same test then checks the whole code base and expects zero mistakes. So a new bad link fails our automatic tests instead of waiting for a person to notice it in review. It also checks that the shared layer stays tidy, with only files that truly belong nowhere else.
A built-in plaster reading nook with linen cushions, seen from the doorway
Built in, not bolted on: structure that stays where it was put. Made with Grok Imagine 2.0.

Plug-ins instead of special cases

This rule pushes us toward a better design. Say a shared tool must behave differently on the node canvas and on the whiteboard. It cannot use either one, so it takes a plug-in, and each area supplies its own. Adding a new area then means writing one plug-in instead of editing seven files.
The cost is one extra step when you read a change that touches a single area. At six areas, we think it is the right trade.

What to take from it

Write the rule once. Add a check that fails when someone breaks it. Make the error message say where the code should go. We use two checks because a rule can fail in two ways: a link points the wrong way, or the rule quietly matches nothing.