Danish Bricks Builder

the lab's map

Atlas

One recursive noun, four layers, three axes — and every one of the 59 routes placed against them. The domain model is from EDITOR-REDESIGN.md §0; this page reconciles it with what is actually built.

1The spine

Four layers. Each answers a different question, and most confusion comes from collapsing two of them into one word.

IDENTITYwhich thing?HISTORYwhich version?CONTENTwhat is it?REPRESENTATIONhow encoded?Setnamed, frozen (tag)Projectmoving ref + historya user signing in owns refs; “new build” = branchfrom empty · “remix” = branch from a set’s tagrevisionrevisionrevisiontrajectorytrajectorybranchnodes = values (content-hashed)edges = the recorded process:prompt · tools · renders · searches · costAssemblyPart | Assembly ⋈ Assemblyone recursive noun — a Part is the size-1 atom,a Mate is the composition operatorDecompositiona criterion’s subsetsconnectivity · kinematic · design · semantic(they overlap and disagree — by design)PROJECTIONSdeterministic — ground truth by constructionmeshvoxelprimitivegraphsemanticCORRESPONDENCESinferred / annotated — the research tasksbooklet cropcamera photoSKUPRESENTATIONwidget = (unit × representation × transform) · editor = widget + write · page = composition · flow = a walk along an axis

Identity

which thing is this?

A Set is a named frozen bundle (a tag). A Project is a moving pointer with history (a branch). Identity persists while content changes.

History

which version?

A Revision is an immutable, content-hashed snapshot (a commit). A Trajectory is the labeled EDGE between two revisions — the recorded process that made the change.

Content

what is it?

Assembly = Part (atom) | Assembly ⋈ Assembly (joined by a Mate). One recursive noun. Decompositions cut it into subassemblies many different ways.

Representation

how is it encoded?

Projections are deterministic (mesh, voxel, graph, exploded). Correspondences are inferred (booklet crop, camera photo, SKU) — those are the research tasks.

2One recursive noun

Part, subassembly and set are not a ladder of three types — they are the same type at three scales.

partpartpartpartpartmatesubassembly — encapsulatedanother decomposition — overlapsthis part belongs to both — many-to-manyAssemblyPart | Assembly ⋈ Assemblyrecurses down tothe atomic partport

A Part is an Assembly of size 1 that happens to be atomic — it cannot be cut. Everything a part has (connectors, a collision box, representations, images, procurement links) an assembly has too, which is why one set of viewers serves both.

A Subassembly is any labeled subset — a node-induced subgraph, not a slot in a tree. So a part belongs to many subassemblies at once: the relation is many-to-many.

A Decomposition is one criterion's family of subsets. Different criteria disagree, and that is correct — editor2 already renders four of them side by side.

  • connectivity → connected components (a partition)
  • kinematic → rigid bodies after locking DOF (a partition)
  • design → authored submodels (a hierarchy)
  • semantic → named function, “the cockpit” (overlapping)

A subassembly whose mates leave no dangling connector is encapsulated — its unmated connectors become its ports, and it can be reused as a black-box meta-part. An “assembly-level mate” is just a part-level mate whose two connectors sit on the boundary of two encapsulated subassemblies. The mate never changes; the framing does.

3Version, project, trajectory

The revision DAG already exists in lib/project — and it already says that traces are the edges. A trajectory is not a new noun; it is that edge, fully recorded.

set 4904-1r0r1r2r3trajectory“build a wheel arch”12 tool calls · 3 renderstrajectory“open the door”1 joint optrajectory“recolor the roof”reference search + 2 editsr2′a variant — branching is just two children of one parentproject HEADlib/project/types.ts: “PROJECTS own an editable Design as a revision DAG whose edges carry agent TRACES” — the model is already written down.

The git correspondence

githereis
commitRevisionimmutable Assembly value, content-hashed
branch / refProjectidentity + history; variants are branches
tagSeta named frozen revision (official or published)
reflog + diffTrajectory (Trace)the recorded edge: prompt, tools, renders, cost
forkremixnew project starting from a set's tag

A user's projectis a ref they own: “new build” branches from the empty assembly, “remix this set” branches from its tag, “save” commits a revision and moves the pointer. Different versions of the same set are tags(4904-1 vs 4904-2); a user's edits are commits on their own branch.

Because a revision is a pure value, ids are content hashes— two people who build the identical subassembly produce the same hash. Dedup is free, and “this user reinvented an official subassembly” becomes a hash match.

A trajectory carries what the revisions cannot: the intent (the prompt/task), the observations (renders, reference searches, sketches, inspections) and the dead ends. Nodes are what was built; edges are how, and why. The benchmark grades edges, not nodes — which is exactly why a run IS a project.

4Three axes

These are not more nouns. They are independent parameters — sliders a viewer exposes over one unchanged assembly.

Time

assembly progression

emptycomplete

Scrub the build order. A valid step ordering is one where each inserted part has a collision-free insertion path — that constraint is itself a benchmark task.

/steps2 · /parsed · /instructions · /booklets

Granularity

sketch → refined

massingmated

The authoring axis. Coarse: blocks placed by position, no connectors engaged. Fine: every part mated and validated. Place and mate are the same act at two maturities.

mostly MISSING — see §6

Lens

how it is cut open

solidexplained

Exploded, semantic highlight, kinematic bodies, section/cut, hide-subassembly. All the same geometry under a different presentation transform.

/editor2 · /semantic · /hierarchy

Granularity couples to the fidelity ladder of representation — coarse design wants coarse geometry:

exact geometrypure symbolmeshexact trianglesrender, exportvoxelsampled occupancycollisionprimitivebox / hull / cylcoarse layoutgraphgeometry-free structureidentity, editsemanticwhat it ISsearch, namingcoarse design authors at the coarse rungs (blocks standing in for parts); validated design needs mesh + connectors

5Widgets, pages, flows

A widget is one cell of (unit × representation × transform). A page is a composition of widgets scoped to one unit. A flow is a walk along an axis.

Viewer

An assembly at a representation, under axis transforms. Viewer3D, ModelViewer, StructureViewer, ConnectionGraph.

Editor

A viewer + a write bit. Same widget, plus mutation: place, mate, recolor, hide, cut. That is the only difference.

Picker

A collection of units as choosable thumbs: the palette, the set browser, the design picker.

Report

A corpus or a run reduced to tables and charts: census, vocabulary, gaps, cost, experiments.

Every route, grouped by the unit it acts on. writes · dup duplicated elsewhere.

PARTthe atom — uncuttable6
  • /anatomyevery representation of a part, side by sidemixed
  • /parts/[partNum]part detail: meta, usage, sets, 3Dmixed
  • /census/partone part's corpus statisticsstats
  • /rulesstep through every legal placement of B on Amesh
  • /collision-labpose two parts, interrogate voxel collisionvoxel
  • /connectionsgallery of every connection style, animatedmeshdup
ASSEMBLYone model / set / build29
  • /assemblies/[id]THE assembly page: step-aware 3D + mates + graph + structure + plan, provenance drawersmixed
  • /editorTHE editor: copilot (connect+mate), structure, jointsmixed
  • /editor-legacyfirst-generation editor, kept for referencemixeddup
  • /buildStudio-style keyboard-first brick editormeshdup
  • /hierarchylegacy editor forced into rigid-body/joint modetreedup
  • /leocadbrowser LeoCAD: nested docs + build stepsmesh
  • /stepsone step in EVERY representation at oncemixed
  • /steps2step-through in the connection language, 7 panesgraphdup
  • /instructionsgenerate bottom-up steps for any designstepsdup
  • /booklets/[setNum]instruction PDF beside the 3D modelimages
  • /alignstep ↔ booklet-page alignment benchsteps
  • /align-pipelineread-only staged view of alignmentstepsdup
  • /pipelinea set through five representation stagesgraph
  • /connection-classifierclassify every contact into classes + DOFgraphdup
  • /semanticassign inferred bodies to named nodestree
  • /groundgrounding bench: phrase → box → bodymesh
  • /ground2agentic variant — the model picks the viewmeshdup
  • /internalsfive ways to expose hidden interior partsmesh
  • /sets/[setNum]set detail: inventory, minifigs, 3Dmixed
  • /models/[id]one generated structure + captionsmesh
  • /projects/[id]project as a repo page: revisions + tracesmixed
  • /generatetext → brick structure, with soundnessmesh
  • /sourcingBOM, cost estimate, buy linkstable
  • /renderheadless screenshot targetmesh
  • /evals/decomposescored partitions, parts colored by modulemesh
  • /evals/motorDC motor driving an 8t→24t gear pairmeshdup
  • /evals/physicsthe same scene under a Rapier rigid-body simmesh
  • /evals/rcfunctional roles → kinematic vehicle mockmesh
  • /evals/technicthree copilot-authored Technic mechanismsimages
CORPUSmany assemblies15
  • /assembliesTHE assembly directory: all sets, faceted (model/parsed)thumbs
  • /corpus1,400+ OMR sets with ingredient badgestabledup
  • /setsofficial sets, searchable by theme/decadethumbs
  • /partsparts directory + sticky detail panethumbs
  • /censusparts, pairs, partners, per-set timelinesstats
  • /vocabularyZipf, Lorenz/Gini, TF-IDF, t-SNE mapstats
  • /gapsposes the enumerator cannot yet producemesh
  • /costparts ranked by enumeration coststats
  • /parsedsets understood completely: LDraw vs matesmixed
  • /bookletsindex of available instruction PDFsthumbs
  • /models47k captioned generated structurestable
  • /designseverything you made (localStorage)mesh
  • /projectsproject browser (lib/project store)tabledup
  • /comparetwo-set inventory diffstats
  • /evals/graphs500-model graph dataset browserstats
TRAJECTORYa recorded session4
  • /experimentstask library + run launcher + past runstable
  • /experiments/[id]one experiment's run table → replaytable
  • /reviewflight-recorder playback + keyboard gradingtimeline
  • /evals/assemblyrebuild-a-set: survival curves per stepsteps
METAdocs + infra5
  • /landing, with live dataset countsmixed
  • /aboutdata sources and licencestable
  • /evalsbenchmark hub → the sub-benchmarksmixed
  • /testingengine test suites, run live in-browsertable
  • /evals/elevatorlumped motor+winch simulationsteps

6What the map exposes

Reading the grid against the model, four things stand out.

Generations, not features

12 routes duplicate another. editor/editor2 are an "independent fork, same UI today"; /hierarchy is a third entry into the same component. steps/steps2, ground/ground2, align/align-pipeline, pipeline/connection-classifier, designs/projects, motor/physics all pair off. The nav groups by WHEN a thing was built ("Pipelines", "Archive") rather than what unit it acts on.

Two eras, one nav

There is a consumer-app era (landing, parts, sets, compare, designs, generate, sourcing, connections — untouched since early July) and a research era (census, gaps, rules, parsed, steps2, cost — edited this month). They are different products sharing a menu bar. The /evals/* simulation demos are a third, frozen branch.

Granularity has no home

Time and lens are richly served — /internals is literally a bench comparing five lens transforms (visibility, peel, cut, explode, ghost). But the sketch→refined axis has no surface at all: no massing mode, no place-without-mate fidelity, no way to block out a shape and then tighten it. It is the axis authoring actually moves along.

Trajectory is thinnest

The recorder captures everything — every SSE event, every tool call with full I/O, content-addressed image blobs, a snapshot after each state change. Only 4 routes read any of it, and replay is revision-level, not event-level. The richest data in the lab has the least UI.

The one structural claim

The connection graph is the better source of truth, but not alone. LDraw states absolute poses, so it can assert the impossible (floating, interpenetrating, studs not engaged) and it is pose-redundant — many encodings, one model. The graph is pose-invariant and buildable by construction, but cannot alone recover geometry: it is missing free-DOF values, globally-pinned poses, and unmated parts. The non-lying object is graph + DOF + anchor pose — and the asymmetry is the point:

graph + DOF + anchor ──deterministic solve──▶ LDraw
LDraw ──fallible inference (98.7%)──▶ graph

So the graph is logically upstream: LDraw is a rendering of it, and version control belongs on the graph (a mate diff is semantic; an LDraw text diff drowns in pose noise). Today the app authors LDraw and derives the graph by detection — closing that gap is the research.

Domain model: EDITOR-REDESIGN.md §0 (2026-07-27) · lib/project/types.ts · lib/exp/recorder.ts