← Commit history

autorouting guide: both engines, Freerouting on demand, live run on ConfRoomROG with screenshots

John Lauer ·0518faea95 ·24d ago ·parent 919943d
6 files changed +83−1
README.md+1−1
@@ -60,7 +60,7 @@ with the IPC API server enabled): `kicad_routing_state`, `kicad_route_net`, `kic and `kicad_routing_validate`. The AI chooses the waypoints; each call lands as one native Undo step, carries a revision guard, and is DRC-checked against a snapshot before it commits. This is not an autorouter and not an electrical sign-off. Details and the regression demo: [SKILL.md](SKILL.md#live-routing-from-09340)-and [demo/routing/README.md](demo/routing/README.md).+and [demo/routing/README.md](demo/routing/README.md). The guide to both engines, with a live run and screenshots: [docs/autorouting.md](docs/autorouting.md).  ## The demo verb: `kicad_demo` 
docs/autorouting.mdadded+80
@@ -0,0 +1,80 @@+# Routing a board: the AI engine and Freerouting on demand++The Adom KiCad Bridge routes a board two ways, and the user picks. The AI engine is the recommendation: the AI plans every trace and lands it through KiCad's IPC API as a native Undo step with a DRC check before it commits. Freerouting is the deterministic alternative: an open-source autorouter that is not part of KiCad, never installed by default, fetched only when the user says yes, and removed with one call. This page is the guide for both, and it ends with a live run on ConfRoomROG with screenshots.++The short version for the AI lives in the [kicad-autorouting skill](../skills/kicad-autorouting/SKILL.md). The nine IPC routing verbs and their regression demo are in [demo/routing/README.md](../demo/routing/README.md).++## What Freerouting is, and why it is optional++- **Who made it.** Freerouting was written by Alfons Wirtz in 2004 as a shape-based autorouter and open-sourced in 2014. Since 2018 it has been maintained by Andras Bodor at [freerouting.org](https://www.freerouting.org/) and [github.com/freerouting/freerouting](https://github.com/freerouting/freerouting), GPL-3.0. It is not a KiCad project; KiCad removed its own autorouter years ago and points users at Freerouting through the Specctra DSN and SES files both sides understand.+- **What it is made of.** Java. That is the reason it is optional here. The 2.4.1 release bundles its own Java 25 runtime inside the application folder, so nothing named Java is installed on the PC, nothing goes on PATH, and no elevation is needed. The Windows bundle is an 88 MB MSI that the bridge extracts as files only (an administrative extract, no registry, no shortcuts), 147 MB on disk.+- **Where it runs.** On the user's desktop, next to KiCad, in the bridge's own cache folder. Three placements were weighed on 2026-09-12: a shared Adom service (rejected, Adom will not run every user's autorouting), the user's own container (workable), and the desktop. The desktop won because the bundle is self-contained, the board is already there, and the result lands in the live editor as undo steps.+- **The rules.** Never installed by default. Always offered when routing comes up, with the size. Installed only on the user's yes. Uninstalled on its own without touching the bridge. `kicad_uninstall` (the bridge's own removal) removes it too.++## The two engines++| Engine | What happens | When to use it |+|---|---|---|+| `ai` (recommended) | The AI reads the board through `kicad_routing_state` (pads, nets, existing copper, a revision hash), plans a trace as waypoints and layers, and commits it with `kicad_route_net`. Each call is one native Undo step, carries the expected revision, and is DRC-checked on a snapshot before it lands; a violation comes back as `drc_rejected` and nothing changes. The AI sees the schematic's intent (currents, return paths, thermals) and can explain every trace. | The default for anything a person will review or ship. GPT-6 Astra in Codex routed a 94-footprint public board this way to zero unconnected items (recordings on the [adom/codex page](https://wiki.adom.inc/adom/codex)); Claude Fable 5.1 drives the same verbs. |+| `freerouting` | The bridge writes a Specctra DSN from the parsed board (its own writer; kicad-cli has no DSN export), runs Freerouting headless with a pass limit and a deadline, reads the SES back, and lands the copper as native Undo steps through the IPC API when the editor has the board open, or into the file with a `.adom-bak` when it does not. Then a DRC. | A quick deterministic pass, or a first draft to hand-tune. Connectivity, not electrical sign-off. |++`kicad_autoroute` with no `engine` answers `engine_required` and describes both. The bridge never picks for the user and never routes on its own initiative; its hints tell the AI to ask, in one sentence, with the recommendation and the reason.++## The verbs++| Verb | Input | What you get back |+|---|---|---|+| `kicad_freerouting` | `{"action": "status"}` | `installed`, `version`, `dir`, `exe`, the bundle it would fetch (`url`, `downloadMb`, `onDiskMb`), `bundledJava: true`, and the exact install call. Cheap: call it before offering the engine so you can say "installed" or "88 MB download". |+| `kicad_freerouting` | `{"action": "install"}` | Starts a background job and returns at once. Poll `status`: `installing.phase` and `installing.percent` move, then `installed: true` with `version` and `timings` (download, extract, verify). Pass `wait: true` to block instead. |+| `kicad_freerouting` | `{"action": "uninstall"}` | Removes the folder and nothing else: `removed: true`, `freedMb`. The bridge keeps working and the engine is offered again next time. |+| `kicad_autoroute` | `{"engine": "ai" \| "freerouting", "filePath": B, "nets"?: [...], "passes"?: 20, "dryRun"?: true}` | For `ai`: a plan request with the board state, for the AI to answer with `kicad_route_net` calls. For `freerouting`: `routed` (per-net segments and vias, `unroutedNets`, `skippedExisting`), `applied` (`ipc` or `file`), `undoSteps`, `drc`, `freerouting` (exe, args, passes used, seconds, stdout tail), `dsn` (rules and stats it wrote). `dryRun: true` routes but lands nothing. |+| `kicad_routing_state` | `{"filePath": B}` | `revision`, pads, tracks, `netsRemaining`. Read it before every mutation. |+| `kicad_route_net` | `{"filePath": B, "expectedRevision": R, "net": "NET_1", "points": ["J1.1", [112, 85], [138, 85], "J2.1"], "width": 0.25, "dryRun"?: true}` | `itemIds` of the committed items, the new `revision`, and `drc` from the snapshot. A stale revision is `stale_board`; a violation is `drc_rejected`. |+| `kicad_remove_route` | `{"filePath": B, "itemIds": [...]}` | Takes a commit back. |+| `kicad_routing_validate` | `{"filePath": B}` | The board-level DRC: `errors`, `warnings`, `unconnected`, `violations`. |++## Honesty rules the bridge enforces through its hints++- Never say a board is routed because a verb returned success. Say what `drc` and `unconnected` say.+- Freerouting's result is connectivity. Current, impedance and thermal review remain the AI's or the user's job.+- If Freerouting is not installed and the user did not ask for it, do not install it. Offer, with the size, and wait.+- Report which engine produced the copper.++## Live run on ConfRoomROG (KiCad 10.0.5, bridge 1.0.2, 2026-09-12)++The fixture is the six-net board from the routing demo: 13 pads on three footprints, one branched net (NET_6 goes J1.6 to J2.6 with a spur to J3.1), two copper layers, IPC API on, board open in the PCB editor. Every screenshot below was taken in the background without the window coming forward.++1. **Before.** `kicad_routing_state`: 13 pads, 0 tracks, `netsRemaining` NET_1 to NET_6, revision `259d41b5...`.++   ![The unrouted fixture in the PCB editor](docs/autorouting/01-unrouted.png)++2. **Freerouting status before.** `kicad_freerouting {"action":"status"}`: `installed: false`, bundle `freerouting-2.4.1-windows-x64.msi`, 88.2 MB download, 141 MB on disk, `bundledJava: true`, `elevation: none`.++3. **Install on request.** `kicad_freerouting {"action":"install"}` returned at once with the job running; status reached `installed: true`, version 2.4.1, exe under `Adom Bridge\freerouting\freerouting\freerouting.exe`, 147.4 MB on disk. Timings on the conference room line: download 2.3 s, extract 1.3 s, verify 2.5 s, total 6.0 s.++4. **The AI engine lands one net.** `kicad_route_net` for NET_1 with the waypoints J1.1, (112, 85), (138, 85), J2.1 at 0.25 mm: three items committed as one Undo step, new revision `a4cd9b1a...`. The snapshot DRC reported the five other nets as still unconnected, which is the truth at that moment, and no clearance error.++   ![NET_1 routed by the AI engine, the other five still ratsnest](docs/autorouting/02-ai-net1.png)++5. **Freerouting takes the rest.** `kicad_autoroute {"engine":"freerouting","passes":20}`: the bridge wrote the DSN (4 boundary points from Edge.Cuts, 3 components, 13 pins, 6 nets, KiCad default rules: 0.25 mm track, 0.2 mm clearance, 0.8/0.4 mm via), Freerouting finished in 2 passes and 3.16 s, and the SES came back as 8 segments on 5 nets, 0 vias (NET_6 in four segments through the spur). `applied: ipc`, `undoSteps: 5`. Freerouting listed NET_1 under `unroutedNets` only because it was already routed: the DSN carried the three existing wires and Freerouting left them alone. Snapshot DRC: 0 errors.++   ![All six nets routed: NET_1 by the AI, NET_2 to NET_6 by Freerouting](docs/autorouting/03-freerouting-all.png)++6. **Board-level DRC.** `kicad_routing_validate`: 0 errors, 0 unconnected, 3 warnings, all of them "the current configuration does not include the footprint library RoutingFixture" (the fixture's footprints are not in a library table on this box, which is expected and not a routing issue).++7. **Uninstall on request.** `kicad_freerouting {"action":"uninstall"}`: `removed: true`, `freedMb: 147.4`. Status afterwards: `installed: false`, and the bridge kept answering every other verb. Nothing else on the machine changed.++8. **Cleanup.** KiCad asked to save the fixture on close; the bridge refused to answer that prompt on its own (`kicad_close` reports the save prompt instead of clicking through it) and closed with `discardChanges: true` only because this was a throwaway fixture.++## What the run shows++- The two engines compose. The AI can take the nets it cares about and hand the rest to Freerouting, or the other way around; both land as Undo steps in the same editor session and the same DRC judges both.+- Freerouting costs the user six seconds and 147 MB, only when asked, and disappears cleanly. Nothing named Java is installed.+- The bridge is honest about state: the mid-run DRC reported the unrouted nets as errors, the final DRC reported zero, and the library warnings were passed through rather than hidden.++## Related++- [kicad-autorouting skill](../skills/kicad-autorouting/SKILL.md): the version the AI reads.+- [demo/routing/README.md](../demo/routing/README.md): the nine IPC routing verbs and the regression demo.+- [Comparison with other KiCad automation tools](comparison.md): the routing row and the Astra evidence.+- [Rust port plan](rust-port-plan.md): the 2026-09-12 Freerouting decision record.
docs/autorouting/01-unrouted.pngadded
⋯ 1 unchanged line ⋯
docs/autorouting/02-ai-net1.pngadded
⋯ 1 unchanged line ⋯
docs/autorouting/03-freerouting-all.pngadded
⋯ 1 unchanged line ⋯
skills/kicad-autorouting/SKILL.md+2
@@ -5,6 +5,8 @@ description: How to route a KiCad board through the Adom KiCad Bridge, and how t  # Routing a board: two engines, the user chooses +The long version with the live run and screenshots: [docs/autorouting.md](https://wiki.adom.inc/adom/kicad-bridge/files/docs/autorouting.md).+ The bridge never routes on its own initiative and never picks the engine for the user. `kicad_autoroute` with no `engine` answers `engine_required` and describes both. Ask the user which they want, in one sentence, with the recommendation and the reason. Then do exactly that.  | Engine | What it is | When |