KiCad - the KiCad Bridge
Public Made by Adomby adom
Reference implementation of the KiCad bridge: multi-instance Python server, forward path via kicad-cli, reverse path via in-process plugin. Most complex of the three bundled bridges.
Astra routing video: ESC G431 through kicad_route_net
GPT-6 Astra in Codex inside Hydrogen routed the shared Fable-placed ESC G431 fixture on arav-rog, Windows user arav, KiCad 10.0.3 and kicad-bridge 1.0.3. This is an independently calculated routing candidate. No Freerouting or other model's routing plan was used. The component placement and two existing inner planes were preserved. The board was never saved.
Result: 0 new DRC errors, 13 inherited errors, 0 unconnected items. 59 of 59 routable nets are fully connected after native zone refill. 59 distinct nets received copper. The accepted take has 67 successful route_net commits, 2759 native segments, 254 through vias and 1610.893 mm of track centerline. Native connectivity is complete when the unconnected count above is zero. This is a routing demonstration, not motor-current or manufacturing qualification.
Planning to the first route_net request, which was a dry run: 260.081 s. Accepted replay routing, first commit request to last response: 388.74 s. That accepted-replay measurement includes per-net DRC and the one-second viewing pauses. Across the whole task, first successful commit to last took 5840.999 s across 379 successful commits, including superseded takes. First routing-state request through the final commit took 6487.485 s. The recordings array below lists every take separately. The full task accounting includes planning refinement, discarded takes, the earlier published incomplete take, capture diagnostics, corrective rip-up and rerouting, resets and publication through its stated cutoff.
The final video is 414.866667 s, silent, 1920-wide H.264/yuv420p with faststart. No cuts, speed changes or fabricated frames were applied to this take. It begins with an eight-second untouched-board hold showing 0 tracks and 0 vias, then the native commits, then validation and a final hold. The recorder's wall-clock duration is 416.809 s. A single Python worker updates an elapsed-time desktop caption to prevent the recorder's sparse-frame behavior; it does not plan or commit routes. The router and its C++ search helper run serially, with zero AI sub-agents.
Method and constraints:
- Read the live revision and pad/net coordinates, then parsed the fixture's actual copper pad geometry, including custom MOSFET shapes, pad clearances, plated holes and board outline. Used an independent eight-direction A* search over F.Cu and B.Cu, initially at 0.1 mm and then at 0.05 mm for the MCU pin pitch. The small exact-pad-to-grid links can have non-45-degree angles; this is not claimed to be a fully octilinear layout.
- Kept the specified 0.25 mm signal width and 0.8/0.4 mm through vias. Used 0.5 mm power connections and widened 34 clearance-safe power segments to 1.0 mm. Native DRC preflight remained enabled for every routing call.
- Reserved individual short plane stubs for the GND and +3V3 SMD pads. Existing through-hole pads reach the inner planes. Signal routes stay on the outer copper layers. The initial file has its stackup and pad/zone settings but no embedded netclass block or sibling project rules; the explicit widths/vias follow John's fixture contract and native default clearance is 0.2 mm. Larger footprint-specific clearances were preserved.
- Routed short nets first. Each call carried the previous accepted revision and created native undo items. Large branched nets and width groups use multiple calls for the same net, always one net per call.
- The shunt and INA stay at the supplied placement. GND follows the requested plane-stub rule, so the sense inputs are not a separately routed Kelvin pair. The fixed-placement sense connection requires electrical/layout review. This demo does not establish motor-current capacity or thermal qualification.
Remaining connections:
| Net | Native unconnected endpoints |
|---|
The earlier publication left 13 real unconnected items and failed the requested connectivity goal. This corrected candidate replaces that incomplete result. The repair uses copper-connected components, valid pad-edge starts, selective path removal, weighted congestion costs and repair of displaced nets. Candidate crossings are permitted only inside the planner's temporary search, where conflicting paths are removed and rerouted; native route_net always keeps its DRC guard enabled. No pads were moved and no rule was bypassed. Planning failures and intermediate regressions are retained in the source logs.
Native validation: errors=13, unconnected=0, warnings=64, zonesRefilled=True, violationReportMayBeTruncated=False. The inherited error type/item UUID sets match the initial fixture. Error types: {"clearance": 7, "malformed_courtyard": 6}. Full validation and the remaining item UUIDs are attached. Validation refills a disposable live-board snapshot. The final take also invokes KiCad's native Fill All Zones menu before validation, so the live editor displays the filled connectivity result. The reported count is still taken from native DRC.
Rejected, retried and discarded:
A later take achieved zero native unconnected items but failed video review: 407.325 s of wall time produced 326.1381 s of media and only 1153 frames, with a stale canvas. Read-only power diagnostics showed a 60-second AC display timeout. The final take uses a temporary SetThreadExecutionState display/system-awake lease, automatically bounded to 20 minutes and released at cleanup. The machine's power settings were not changed. The routed candidate itself was unchanged.
A corrective replay passed all 67 commits with no new DRC errors but native validation found one HSE input pad-edge tangency. Its recording was rejected. Extending that endpoint 0.05 mm into the pad passed a native dry run with zero unconnected items. The final take includes this correction and fills the live planes before validation, so the editor counter is also meaningful.
The previous published take had 13 unconnected items. John correctly rejected that as incomplete. This repair started again from the unchanged zero-track fixture. Broad net reordering and an initial rip-up pass merely moved blockages, so they were rejected. The accepted corrective search retained successful copper, freed individual conflicting paths, restored displaced nets, and checked connectivity and clearance before the new native replay.
An unsupported Redraw menu lookup was refused. The read-only powercfg /requests query required elevation, so it was not used as proof and no elevation was requested; the temporary lease was verified through its named event and sustained capture beyond the timeout. A run_script call initially omitted its required reason and was retried with the explanation.
Two local helper mistakes, a missing function import and an id-versus-uuid lookup, were fixed before any associated mutation. The input approval grant later expired; renewed it through the human-only bridge prompt and dismissed an unrelated banner without answering its approval request.
The desktop's transfer gate initially required approval for write_file_chunk. Waited for the grant, then retried the original transfer to arav-rog.
Rejected the initial 0.1 mm planner candidate for missed dense pad escapes. Refined to 0.05 mm, added same-net drill spacing, allowed legal pad-edge starts and reduced the planner's extra clearance margin while keeping the native 0.2 mm requirement. Native dry runs checked the resulting geometry.
First complete live pass: 13 inherited errors and 15 unconnected. Discarded its recording: 361.286 s recorder wall time became 201.489267 s of media, with long static intervals missing and early copper updates not reliably visible. Checked the Appearance panel, tried a background refresh key, and focused the canvas. No board geometry changed in those display diagnostics.
The reset initially exceeded remove_route's 1024-item limit and was refused. Reset only this task's copper in accepted batches of at most 1000 items, verifying the original zero-copper revision afterward.
The second take stopped when a +VBAT width-group exceeded route_net's 128-path limit. The rejected call landed no copper. Preserved that failed take and split the net into permitted batches before the next replay. No final-take route was forced past validation.
Two added connection repairs and the 1.0 mm widening groups passed native dry runs. The final take replayed the revised independent geometry from the verified untouched fixture. All prior takes and all their calls are included in task costs, but excluded from the accepted-take performance metrics.
Comparison data:
{
"engine": "GPT-6 Astra",
"model": "gpt-6-astra",
"board": "ESC G431, shared Fable placement, 149 footprints, 4 copper layers, initial GND and +3V3 planes",
"desktop": "arav-rog, Windows user arav, KiCad 10.0.3, kicad-bridge 1.0.3",
"window": [
"2026-09-13T13:29:56.203Z",
"2026-09-13T15:29:57.300Z"
],
"windowNote": "Whole routing task through the stated accounting cutoff, including rejected planning candidates, first discarded recording, display/capture diagnostics, replay, the previously published incomplete take, the subsequent corrective routing work and publication preparation. Earlier placement and six-net tasks excluded.",
"planning": {
"wallSeconds": 260.081,
"definition": "First kicad_routing_state request to first kicad_route_net request, a dry run",
"toAcceptedTakeFirstCommitSeconds": 6098.745,
"firstStateThroughFinalCommitWallSeconds": 6487.485
},
"routing": {
"commits": 67,
"wallSeconds": 388.74,
"firstToLastCompletionSeconds": 384.583,
"netsTouched": 59,
"segments": 2759,
"vias": 254,
"copperLengthMm": 1610.893,
"lengthDefinition": "Sum of native track centerline lengths, excluding pads, planes and vertical via barrels",
"trackWidths": {
"0.5": 705,
"1.0": 34,
"0.25": 2020
},
"netsFullyConnected": 59,
"netsRemaining": [],
"liveUnfilledNetsRemaining": [],
"drcErrors": 13,
"newDrcErrors": 0,
"inheritedDrcErrors": 13,
"unconnected": 0,
"violationTypes": {
"clearance": 7,
"malformed_courtyard": 6
},
"zonesRefilled": true,
"violationReportMayBeTruncated": false,
"wholeTaskSuccessfulCommits": 379,
"wholeTaskFirstCommitToLastWallSeconds": 5840.999
},
"tokens": {
"thread": {
"input_tokens": 51148097,
"cached_input_tokens": 50530944,
"cache_write_input_tokens": 0,
"output_tokens": 145097,
"reasoning_output_tokens": 73580,
"total_tokens": 51293194
},
"uncachedInputTokens": 617153,
"threadTurns": 333,
"agentLaunches": 0,
"agents": 0,
"workerThreads": 5,
"acceptedTakeWorkerThreads": 1,
"maxConcurrentWorkerThreads": 1,
"displayAwakeHelperProcesses": 1,
"displayAwakeHelperNote": "One temporary hidden PowerShell process holds a display/system-awake lease for the final recording; released at cleanup, with a 20-minute automatic timeout. Power settings unchanged.",
"workerNote": "One elapsed-time-caption Python worker per take after the first take. The count is cumulative across those takes; one ran in the accepted take. Routing and C++ path search are serial. No AI sub-agents.",
"withAgents": {
"input_tokens": 51148097,
"cached_input_tokens": 50530944,
"cache_write_input_tokens": 0,
"output_tokens": 145097,
"reasoning_output_tokens": 73580,
"total_tokens": 51293194
},
"accountingSource": "/home/adom/.codex/sessions/2026/09/12/rollout-2026-09-12T12-08-00-01a09697-1b14-7111-9897-63815e098b24.jsonl",
"accountingCutoff": "2026-09-13T15:29:57.300Z",
"accountingNote": "input_tokens includes cached_input_tokens. Reasoning output is included in output_tokens. No cache writes reported. Reporting after cutoff excluded.",
"maxRequestInputTokens": 244135
},
"usdApiEquivalent": {
"thread": 63.957324,
"withAgents": 63.957324,
"priceBasis": "OpenAI GPT-6 Astra model page checked 2026-09-13: $10 uncached input, $1 cached input, $50 output, $12.50 cache writes per million tokens (no writes reported). Standard API equivalent. Requests above 272K input use 2x input/cache and 1.5x output prices.",
"priceUrl": "https://developers.openai.com/api/docs/models/gpt-6-astra"
},
"planShare": {
"planUsdPerMonth": 200,
"threadPercent": 31.978662,
"withAgentsPercent": 31.978662,
"note": "API-equivalent cost divided by $200, not actual subscription billing or quota consumption"
},
"recordings": [
{
"recordingId": "rec-0245f0ecd10e4d19b3a8bf5421656a9a",
"startUTC": "2026-09-13T13:42:28.294784+00:00",
"wallSeconds": 361.286,
"bytes": 116522591,
"path": "C:/Users/arav/AppData/Local/Temp/adom-bridge-recordings/desktop-m0-20260913-134228.mp4",
"accepted": false,
"successfulCommits": 58,
"errors": 13,
"unconnected": 15
},
{
"recordingId": "rec-d9cd35fee72d4c748c4bd36a9f02c1e3",
"startUTC": "2026-09-13T13:53:59.785515+00:00",
"wallSeconds": 332.127,
"bytes": 364886213,
"path": "C:/Users/arav/AppData/Local/Temp/adom-bridge-recordings/desktop-m0-20260913-135400.mp4",
"accepted": false,
"successfulCommits": 56,
"errors": 13,
"unconnected": 140
},
{
"recordingId": "rec-9e97e30c0089447385bdbcd5f1111929",
"startUTC": "2026-09-13T14:00:41.012894+00:00",
"wallSeconds": 386.784,
"bytes": 416138912,
"path": "C:/Users/arav/AppData/Local/Temp/adom-bridge-recordings/desktop-m0-20260913-140041.mp4",
"accepted": false,
"successfulCommits": 64,
"errors": 13,
"unconnected": 13
},
{
"recordingId": "rec-190eefdf17734314abbbf349834f2ee1",
"startUTC": "2026-09-13T14:46:20.623074+00:00",
"wallSeconds": 416.661,
"bytes": 487562286,
"path": "C:/Users/arav/AppData/Local/Temp/adom-bridge-recordings/desktop-m0-20260913-144621.mp4",
"accepted": false,
"successfulCommits": 67,
"errors": 13,
"unconnected": 1
},
{
"recordingId": "rec-9765d406bb834da39a366185f56ba432",
"startUTC": "2026-09-13T14:59:47.299493+00:00",
"wallSeconds": 407.325,
"bytes": 52501625,
"path": "C:/Users/arav/AppData/Local/Temp/adom-bridge-recordings/desktop-m0-20260913-145947.mp4",
"accepted": false,
"successfulCommits": 67,
"errors": 13,
"unconnected": 0
},
{
"recordingId": "rec-670c880b85c2475798e07e2ab8eb96af",
"startUTC": "2026-09-13T15:13:24.370869+00:00",
"wallSeconds": 416.809,
"bytes": 452693456,
"path": "C:/Users/arav/AppData/Local/Temp/adom-bridge-recordings/desktop-m0-20260913-151324.mp4",
"accepted": true,
"successfulCommits": 67,
"errors": 13,
"unconnected": 0
}
]
}
Prices are the standard API-equivalent rates on OpenAI's GPT-6 Astra model page, checked 2026-09-13. The percentage of $200 is arithmetic, not actual subscription billing or quota usage.
Source and editorial handoff:
- Geometry parser, planner, C++ search, repair search, repair pass, second repair pass, power widening, component search, congestion search, corrective planner, weighted C++ search, final plan builder.
- Bridge logger, accepted replay script, exact final plan, narration notes.
- Attached bridge-calls.csv contains every instrumented call's UTC start/end, duration, outcome, revision, item count and exact shell command. bridge-commands.txt is the literal transcript, including recording/transfer/reset calls. media-commands.txt lists the exact frame extraction, transcode and verification commands. astra-stats.json supplies the chart data; final-validate.json is native KiCad's result.
Setup and publication:
adom-codex context
adom-wiki pkg install adom/kicad-bridge
adom-bridge --ai-thread "Astra ESC routing video" targets
adom-bridge --ai-thread "Astra ESC routing video" --target arav-rog kicad_status '{}'
adom-bridge --ai-thread "Astra ESC routing video" --target arav-rog kicad_close '{}'
adom-bridge --ai-thread "Astra ESC routing video" --target arav-rog kicad_ipc_api '{}'
curl -sLo esc-g431-fable-placed-planes.kicad_pcb https://wiki.adom.inc/api/pages/adom/kicad-bridge/files/demo/routing/esc/esc-g431-fable-placed-planes.kicad_pcb
adom-wiki repo push adom/codex --files docs/videos/astra-routing-esc-g431.mp4 docs/videos/astra-routing-esc-g431-poster.jpg -m "Astra routing video: ESC G431 through kicad_route_net"
curl -s -o /dev/null -w "%{http_code}" https://wiki.adom.inc/api/pages/adom/codex/files/docs/videos/astra-routing-esc-g431.mp4
Cleanup: KiCad closed with discardChanges:true. The fixture was pulled back and its SHA-256 matches the original public download. The published MP4 was downloaded again, decoded and checked against the local hash.