freeroute/docs/PORTING_PLAN.md
Ryan Malloy 0270137b9f Scaffold freeroute: Python port of the FreeRouting engine
Pure-Python PCB autorouter replacing the freerouting.jar step in kicad-mcp.
Contract is Specctra DSN in, SES out — a drop-in for the JAR so the toolchain
needs no JVM. Includes pyproject (uv/ruff/pytest, src-layout) and a porting
plan seeded for study of the upstream FreeRouting Java source.
2026-07-11 14:51:42 -06:00

2.8 KiB

FreeRouting → Python porting plan

Seed document. The routing agent expands this after studying the upstream Java source. Treat sections marked (TBD from source study) as the first research deliverable.

Ground truth: study the source

Port from the actual FreeRouting Java source, not from the Specctra spec alone. The algorithm details (rip-up-and-retry ordering, cost functions, 45°/free-angle geometry, autoroute vs. optimize passes) live in the code.

# Cloned into ./reference (gitignored — we don't vendor GPL source into history)
git clone --depth 1 https://github.com/freerouting/freerouting reference/freerouting

Key upstream packages to map first (verify paths against the clone):

  • app/freerouting/designforms/specctra/ — DSN/SES read/write. This is the I/O boundary we must match byte-compatibly enough for kicad-cli to import.
  • app/freerouting/autoroute/ — the maze/rip-up router core.
  • app/freerouting/board/ — the routing board data model (items, traces, vias, nets, clearance matrix).
  • app/freerouting/geometry/planar/ — points, lines, tile shapes, the 45°/free-angle geometry primitives.

The contract (fixed)

Input: Specctra .dsn. Output: Specctra .ses. kicad-cli pcb export specctra-dsn produces the input; kicad-cli pcb import specctra-ses consumes the output. Match that I/O and the rest of kicad-mcp is unchanged.

Phased roadmap

  1. DSN parser — tokenize + parse the S-expression DSN into a typed board model (layers, components, padstacks, nets, keepouts, rules/clearances). First concrete, fully-testable module. Round-trip fixtures from kicad-cli.
  2. SES writer — emit a minimal valid session file KiCad imports cleanly, starting with an empty/no-op route to prove the I/O loop end to end.
  3. Board model + geometry — planar primitives and the item/net/clearance model the router operates on. (TBD from source study.)
  4. Autorouter core — maze routing with rip-up-and-retry. Start grid-based Manhattan/45° for an MVP; converge toward FreeRouting's approach. (TBD.)
  5. Optimize pass — via minimization, trace smoothing. (TBD.)
  6. CLI + kicad-mcp integrationfreeroute board.dsn -o board.ses, then swap it in behind kicad_mcp/utils/freerouting_engine.py's JAR step.

Validation strategy

For any .dsn, FreeRouting's JAR gives a reference .ses. Diff our output against it (connectivity first — every ratsnest resolved — then geometry). The JVM stays available as an oracle during development even though the shipped product has no Java dependency.

Conventions

uv for everything, src-layout, ruff, pytest. Author: Ryan Malloy. Keep modules small and single-purpose. Tests alongside every parser/writer from the first commit.