Skip to content

Build log: the living cosmos

July 20, 2026 · Milestone M12 scope

System orbits now encode flow instead of member order: a structure’s ring is its call depth from the region’s entry node, found by walking only certain calls so an unproven “possible call” can never decide where something sits. Members no sibling calls reach join ring one alongside the entry’s direct callees, and anything still unreached takes the outermost ring, ordered by node id, rather than being guessed into place. Layout stays deterministic and hash-seeded — no clock, no random source — and although coordinates moved once, saved progress did not: region signatures are hashed from file content, never from position.

A second Map layer now sits beside the galaxy, switchable from the header. Both of its tabs — Architecture, and Workflow — read a new GET /api/map built entirely in codemble/graph/, the same graph layer the 3D galaxy reads through GET /api/graph, so the two views cannot disagree. Architecture groups modules by directory and layers them by import distance from Home, cutting cycles rather than looping forever; modules with no import route from Home get their own row instead of a guess. Workflow walks the call tree from your entrypoint — its first hop is labelled defines, not calls, because a module containing a function is parser-observed containment, not a call the parser ever saw. The Map is plain SVG: it draws possible relationships as genuinely dashed lines and needs no WebGL, so it still works where the galaxy cannot draw.

The galaxy itself gained real depth. Every node now carries a canvas-generated halo (no image assets ship — the textures are drawn at runtime), and a bloom pass runs over the whole frame with its threshold set so understood amber blooms hard while the unlit brightness ramp barely registers: glow is a claim, so it is spent where a claim exists. At galaxy level each Python, JavaScript, or TypeScript system sits inside a faint nebula tinted by language — and a system in any other language renders no fog at all, because a borrowed hue would imply evidence the parser does not have. A background starfield is seeded from the project’s own file hashes, so the same project always renders the same sky. Drifting particles now mark certain call edges only; a possible call stays visible but motionless, so motion can never imply proof the parser doesn’t have. Passing a region’s checks triggers a 1.2-second “nebula dawn” the next time you are at galaxy level — amber washing out through that system’s halo and fog and receding. The lit state is committed before the animation starts, so the dawn marks a fact rather than delivering one, and a learner who has asked for reduced motion gets the finished, lit state instantly instead of a faster version of the same animation.

Easy mode now lands on the Map by default and Expert lands on the galaxy, but an explicit layer switch always wins over what the mode picked, in either direction. Easy mode also hides everything but a selection’s own connections instead of just fading them, and shows a hint chip naming the nearest unlit region to Home, counted in graph route hops with ties broken by region id — deterministic graph truth, never a model’s guess, and the hint only ever names a place to look, not a claim about what the code does. First-run coach-marks explain what you see, how to move, and what lights a star; dismissing them is a local UI preference, never mixed into saved progress. The breadcrumb is now a real, clickable control instead of static text, and the legend gained a swatch per language plus a possible-relationship entry that matches whichever layer is on screen — a dash on the Map, a colour on the galaxy, because 3d-force-graph has no line-dash support to draw a 3D dash with.