The pipeline
One sentence goes in; a directory of fab files comes out. In between are ten stages, each of which reports what it could not do. The command line prints them in order; the app runs the same code (soldermask/workspace.py) and shows the stage names as a build progresses.
prompt ──▶ design ──▶ resolve ──┬──▶ ERC · simulation
(the model) (parts · footprints · symbols)
├──▶ place ──▶ route ──┬──▶ Gerbers · drill · BOM · CPL
│ (freerouting, then └──▶ .kicad_pcb · 3D models
│ the A* router if a
│ net is left short)
└──▶ stock & price
all of it ──▶ one immutable version on disk| Stage | Module | Decides | Reports |
|---|---|---|---|
| Design | design.py, schema.py, priors.py | which parts, which packages, which pins wire together | assumptions, decisions, unsupported |
| Parts and packages | resolve.py, parts.py, packages.py, easyeda.py | a real LCSC part for each component, its footprint | gaps (no part), notes (substitutions, unverified footprints, stock) |
| Symbols and pins | symbols.py | pad numbers from pin function names | gaps (no symbol, unverifiable pin), notes (borrowed pinouts) |
| ERC | erc.py | nothing — it only checks | errors and warnings by rule |
| Simulation | spice.py | nothing — it switches the declared rails on in ngspice and reads what settles | the rails a regulator drives against their declaration, LED currents, the parts with no model; the traces as sim.json for the scope |
| Placement and routing | placer.py, dsn.py, ses.py, pour.py, fillet.py | where parts go, where copper goes, what stays clear of an antenna, what ground is poured over | overlap, incomplete nets pin by pin, which placement was kept, what the pour came to |
| Two routers | astar.py | whether a board left short of a pin gets a second opinion, and whose copper is kept | which pins the second router reached that the first did not |
| Routability | congestion.py, corpus.py, routability.py, precedent.py | which placement the router sees first, and which corpus board one anneal starts from | the prediction beside the verdict; the model's own score; the precedent it used |
| Fab files | gerber.py, assembly.py | — | read-back verification |
| KiCad and 3D | kicad.py, models3d.py, kicadcli.py | — | frame agreement, model orientation, DRC when KiCad is installed |
| Stock and pricing | inventory.py | — | buildable or not at each quantity, headroom |
| Repair and evaluation | repair.py, evaluate.py | whether a revision is better | score, dropped parts, pass@1 |
The last page, What is not guaranteed, collects every honest limitation in one place.
The instruments built to ask whether any of this can be predicted rather than run — the mould, the fold, the rubric — are not stages and live under Research.