Inspiration

One of our teammates’ dads works in construction. He does not talk about architecture as a design problem. He talks about the hassle: a drawing set lands, someone has to walk it against a thick standards manual, a room type repeats across a whole floor, and a missed dimension turns into a site visit, a rework, and another revision.

That loop is slow even when everyone is trying. Checking a hotel drawing set against a 349-page brand manual can take a person days, by hand, and it gets redone every time the plans change. The comments that come back are often things a computer could have caught: a bathroom that is too small, a door that is too narrow, a corridor that does not clear. Most of the pain is not taste. It is measurement, repetition, and provenance.

We built Archetype because that work should not live in a highlighter and a weekend. The failure mode is not “bad design.” It is a drawing database wrapped in a PDF, hundreds of repeating space types, and rules that only count when a human has approved them — then geometry that can actually be measured.

What it does

Archetype is a local-first desktop editor for architectural projects. You can start from a short brief and generate a building, or drop in a real drawing set — PDF, DXF, or IFC — and get a living model instead of a static file.

From there you can:

  • Edit the 2D floor plan and see a derived 3D model
  • Place the building on a real site, with terrain, sun, and context
  • Check spaces against standards with page citations, not vibes
  • Ask an assistant to review or repair issues, then preview the commands before anything is applied
  • Keep undo, redo, and versioned history on a model the app actually owns

The important part: the model does not guess pass/fail. Geometry is measured. Rules are extracted and approved. Failures attach to a space type, so one bad bathroom can show up as ×84 units instead of 84 separate hunts.

Under the hood there are three agent-shaped systems, and none of them is allowed to grade the building:

  • Generate agent — at most two LLM calls for a space program; the host packs floors and compiles a wall graph.
  • Edit agent — an orchestrator plans steps; geometry / finish / appear subagents emit typed command batches; the host dry-runs them; you approve the batch.
  • Deterministic repair — for known failure modes, Python proposes offset_partition / opening updates that re-verify clean, with no LLM in the loop.

The agent may propose a fix. A human applies it. Load-bearing walls stay off-limits — enforced in code, not in a prompt.

How we built it

Archetype is two systems that share one building model.

The desktop is Electron, React, Konva for the plan, and Three.js / R3F for the model, with a dockable workspace for 2D, 3D, furniture, materials, site, and chat. The backend is FastAPI. It owns versioned model.json, command history, jobs, and compliance. The renderer applies patches; it never writes project JSON directly. Optimistic concurrency uses expected_revision so 2D, 3D, and the checker cannot drift apart.

Import pipeline: classify → extract → collapse → bridge → polygonize → tag → openings

We treat CAD-exported PDFs as a drawing database, not a picture. AutoCAD layers survive the export as OCGs, so a path already knows if it is WALL-STUD-LOADBEARING, DOOR, or furniture. No computer vision for walls. No DWG round-trip required.

  1. Classify — parse title blocks after accounting for page /Rotate (often 270°). Assign roles: floor plan, unit plan, enlarged plan, schedule, elevation, section, MEP, and the rest. Resolve scale strings such as 1/4" = 1'-0" into pt/ft. On a real hotel set we keep the extractable subset of pages and skip sheets that cannot become rooms.
  2. Extract — PyMuPDF get_drawings() with layer → bucket mapping. Hard pages can hit on the order of ~210k paths; extract runs in a process pool. Furniture and hatch layers are excluded but counted.
  3. Collapse — pair parallel wall strokes into centerlines plus thickness.
  4. Bridge — extend segments by about 3 ft across doorway gaps before polygonize. Without the bridge, rooms shatter into slivers or swallow half the floor.
  5. Polygonize — Shapely faces become rooms in feet; faces below a minimum area are dropped.
  6. Tag — prefer annotation room-tag boxes; merge stacked labels; fall back carefully so dimensions do not become names. Unit plans feed a type catalogue with instance_count.
  7. Openings — cluster door fragments with union-find and a spatial hash; snap doors and windows to wall gaps, preferring collinear gap width as ground truth.

Coordinate rule we refused to break: PDF points, building feet, and 3D world space disagree about which way is up. We flip Y once, at the PDF→feet boundary, and treat every other transform as a view. Ambiguous geometry stays marked for review instead of being promoted into “truth.”

DXF and IFC feed the same wall graph — layer names and IFC LoadBearing properties set structural locks the same way.

Standards → rules → measure

Standards documents become rule candidates with source_doc, source_page, clause text, and metric type (area, min_side, aperture_width, clear_width, opening_distance). Extraction never activates a rule. Status starts pending. Only approved rules emit check rows. Clear width uses morphological opening (binary search on buffer radius) when the metric demands it. Blast radius walks type_ref so one type failure reports as ×N instances.

Generate agent pipeline: research → program (≤2 LLM calls) → pack → compile → check / repair → save

Generation works the other way from import. A short brief becomes a building without a free-running tool loop:

  1. Research (host) — detect building kind, consult an internal program library, gather required rooms.
  2. Program (LLM) — return JSON for the space program only. Hard cap: MAX_LLM_CALLS = 2 (one main call, one corrective turn) and a wall-clock deadline. The model does not invent wall geometry.
  3. Pack (host) — kind-specific layout schemes: corridor for hotel / hospital / school / office; cluster for home; hall / edge for worship, retail, gym, and similar. Water-fill distribution for minimum sides; stair cores stack across floors.
  4. Compile (host) — rectangles become a shared-vertex wall graph. Exterior edges are locked loadbearing. Interior partitions stay movable. Doors and windows are placed by convention.
  5. Check + deterministic repair once, then save an editable project with a program audit trail.

Edit agent pipeline: chat → orchestrator → subagents → dry-run → preview → human apply → recheck

The edit agent is an orchestrator / subagent system with a strict host boundary:

Role Who Job
Orchestrator LLM Plans intent and ordered steps only. Never invents measurements or pass/fail.
Geometry / finish / appear subagents LLM Emit typed JSON command batches.
Host validation Python Dry-run apply_commands(..., actor="agent"), structural locks, one retry with the dry-run error.
Compliance Python Grades pass/fail after edits.
Deterministic repair Python Geometry offsets / opening updates that must re-verify clean — no LLM.

Command kinds stay narrow on purpose. Geometry: offset_partition, update_wall, create_wall, split_wall, place_opening, update_opening, delete, object place/update/duplicate. Finish: materials, environment, rename, type-wide finishes, furniture. Appear: photoreal / Gaussian splat paths. Geometry prompts forbid raw move_wall; the preferred tool is offset_partition, which moves partition endpoints, refuses locked structural buffers, auto-corrects neighbors that go diagonal, decouples pinned vertices when needed, then recomputes rooms.

Apply flow: agent job writes a preview under repairs/{run_id}.json and does not mutate the model. The UI reviews the batch. Apply creates a new revision and rechecks. If the assistant can silently edit a load-bearing wall, nobody on a job site will use it — so blocked edits live in the command layer (locked / non-nonstructural walls raise), and unlock requires an explicit human review step.

Chat can move walls, change finishes, drop furniture from a catalog with clearance-aware placement, or reconstruct appearance from a photo via image edit → Gaussian splats. Site view sits the same footprint on real terrain. Same model. Same command history.

The rule we refused to break: an LLM never decides whether a building passes. Compliance is code. The model explains and proposes. The human keeps the pen.

Challenges we ran into

Real drawings fight back.

One floor-plan page had on the order of 210,000 paths. Doorway gaps leaked when we polygonized walls, so rooms either exploded into slivers or swallowed half the floor until we learned how far to extend segments — about three feet before polygonize. Room tags grabbed dimensions instead of names. Unit plans looked like floors and were not. PDF pages arrived rotated 270°. Imperial fractions came out mangled. HVAC and plumbing sheets were flattened and useless, so fixtures had to come from the architectural drawing.

Then there was the coordinate problem: PDF points, building feet, and 3D world space all disagree about which way is up. We flipped Y once, at the boundary, and treated every other transform as a view.

Standards text fought us too. Rule extraction is conservative regex over messy manuals. Unsupported metrics stay visible instead of being silently invented. Candidates start pending; oversized scope gets held for review. If we had auto-activated every extracted line, we could not defend a single check.

On the agent side, the hard line was trust. Free-running tool loops invent geometry and skip provenance. So generation is capped at two LLM calls with host packing and compile. Edit uses orchestrator → subagent → dry-run → human apply. Deterministic repairs reject any proposal that introduces or worsens failures. Load-bearing edits are impossible for actor="agent" even if the model asks.

On the product side: if the assistant can silently edit a structural wall, the tool is dead on arrival. Blocked edits live in code, not in a prompt, and every repair is a reviewable command batch.

Accomplishments that we're proud of

A real editor, not a slideshow: generate, import, draw, check, repair, undo.

A real import path: CAD layers → classify → extract → collapse → gap-bridge → polygonize → tagged rooms with openings, without treating drawings as images.

A generate agent that stays bounded: research and packing in host code, ≤2 LLM calls for program JSON, compiled wall graph with locked exteriors.

An edit agent that uses real geometry tools — especially offset_partition and opening updates — and still has to ask before it writes. Dry-run, preview JSON, human apply, recheck.

Compliance that cites the clause and the page, measures with Shapely (not vibes), then shows blast radius across repeating units.

Uncertainty that stays visible: low-confidence geometry is hatched and marked for review instead of being promoted into “truth.”

A local-first workflow. Drawings stay on the machine. The project is a folder you can reopen. Revisions, undo, and redo live next to model.json, so the plan, the 3D view, and the checker stay on one source of truth.

The thing we are proudest of is smaller than the 3D view. It is that a construction-shaped hassle — “did this room type actually pass?” — now has an answer you can inspect.

What we learned

Architecture software fails when it pretends drawings are images and code is taste.

Layers, scales, title blocks, and grids are the product. If you lose the layer, you lose the right to propose a structural edit. If you skip the human approval step on a rule, you cannot defend the check. If you let the model grade the building, you will get a fluent answer that is wrong.

We also learned that agent design is mostly about what the model is not allowed to do. Generation does not freely tool-loop wall endpoints. The edit orchestrator does not invent pass/fail. Subagents emit commands; the host validates them. Deterministic repair exists so the common fix path does not need another LLM turn. Structural locks belong in apply_commands, not in system-prompt hope.

And we learned that “local-first” is a design constraint, not a slogan. Jobs, revisions, and command history have to live in one place, or the 2D plan, the 3D model, and the checker drift apart.

We learned the pitch from the people who actually live this: lead with this takes a person two days, not nobody catches these.

What's next for Archetype

Deeper rule coverage: corridor width, accessible turning space, door clear width, more of the manual that today comes back unsupported.

Stronger extract on the hard sheets, so fewer rooms land in “needs review,” and tighter linking between unit plans and floor instances.

A live agent path with the same geometry tools, still blocked from load-bearing work, still dry-run → preview → apply.

Site and furniture that survive into presentation: walkthroughs, cutaways, exports a superintendent would actually open.

The obvious next documents: city code as another ruleset, revision diff across drawing sets, and a cost / BOM view of a proposed change.

The long-term version is the one our teammate’s dad would keep open on a job: drop the set, see what failed, see what it would take to fix it, and apply nothing until someone on the team says yes.

Built With

  • baseten
  • claude
  • codex
  • cursor
Share this project:

Updates

Submission history