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 placement video: ESC G431, 149 parts through kicad_move_footprint
Video: https://wiki.adom.inc/api/pages/adom/codex/files/docs/videos/astra-placement-esc-g431.mp4
Poster: https://wiki.adom.inc/api/pages/adom/codex/files/docs/videos/astra-placement-esc-g431-poster.jpg
GPT-6 Astra in Codex inside Hydrogen independently placed the public ESC G431 fixture on arav-rog, Windows user arav, KiCad 10.0.3 and kicad-bridge 1.0.3. All 122 movable footprints are now inside the 64 x 74 mm outline on F.Cu. The 23 MC contacts and four MP pins remain locked at exactly their original positions, rotations, sides, pad nets and courtyard bounds. Every accepted pose was read back. Only the task copy at C:/Users/arav/Downloads/adom-gate/esc-demo/astra/esc-g431-unplaced.kicad_pcb was edited. No copper was routed and the fixture was never saved.
The accepted take has 16 native Undo commits, eight parts per batch except the final two, with a one-second pause after each batch. Placement wall time: 19.219 seconds from first commit request to last commit response, or 18.968 seconds between first and last commit completions. Planning: 294.514 seconds from the first placement_state request to the first move_footprint request, which was a non-mutating dry run of the full plan. This metric excludes initial setup; the task accounting includes setup, planning, all failed captures, recovery, verification and publication through its stated cutoff.
Validation: ratsnest 1529.010 mm, down from 4476.222 mm; 0 courtyard overlaps, 0 outside the outline, 0 parked. Placement DRC has 13 errors, all inherited: six malformed MOSFET courtyard shapes and seven clearances between pads inside U2. The error type and item UUID sets match the initial fixture exactly, with zero new errors and zero removed errors. placementClean remains false; this is a placement candidate, not a fabrication-ready board. Full validation is attached. The fixture's live net count is 82 including unconnected-pad nets, rather than the prompt's shorthand 59.
Placement decisions:
- Put the two bulk capacitors and TVS under the fixed top battery input, with the shunt directly beneath the fixed GND_OUT contact and the INA181 beside it. Current sense still needs Kelvin routing when copper is designed.
- Arrange the three MOSFET pairs beside their respective fixed right-edge phase contacts, in C, B, A order from top to bottom. High-side devices are rotated 180 degrees; low-side devices remain at zero. Gate resistors and pull-downs target the actual transistor gate-pad positions. Place local ceramic VBAT capacitors at each high-side power pad.
- Put DRV8300 between the power stage and MCU, with its PWM inputs facing the MCU. Bootstrap and 12 V decoupling parts target the actual driver pins. The resulting gate routes still need electrical review and length/loop control.
- Put the MCU near the fixed left-side control contacts; crystal and load capacitors beside HSE pins, four supply decouplers beside their respective MCU supply pins, VDDA filtering at the analog-supply pins, and BEMF/divider filters near their analog inputs. The buck and 3.3 V supply form a separate upper-left group. Debug header and reset switch are accessible at the left edge.
- The plan used hand-selected functional anchors plus a deterministic, single-threaded local search over courtyard-safe positions and 90-degree rotations. Its objective attracts each specified component pad to its associated IC/transistor pad while enforcing a 0.25 mm courtyard gap. It does not use another model's placement or claim a global optimum. The comparison stats file was read only for reporting shape.
Watch the parked grid empty in batches while the fixed interface stays still, then the final camera fit shows the complete board. The published video is 38.133 seconds, silent 1920-wide H.264/yuv420p with faststart. No cuts or speed changes were applied. Recorder wall time was 41.332 seconds. Encoded video timestamps and recorder wall time differ; use the logged commit timestamps for the benchmark. The final native status-caption updates were a capture-completion hold, not additional placement. Raw start/middle/end frames and sequential samples were inspected, including the final two testpoints. Full transcoded decode passed.
Rejected and retried:
- The local planner rejected an initial C3 anchor because its courtyard encroached on the fixed phase-C contact. Both bulk-capacitor anchors were shifted before any move call. No bridge courtyard or outline check was bypassed.
- A local plot failed because matplotlib was absent, then a font path was unavailable. The local plan preview was rendered with Pillow's available font. This did not affect the native board.
- The first 16-commit take placed all 122 parts and validated, but its static-desktop recording ended before the last two testpoints and final fit. That take is not the published video.
- A CPU-frame-path capture diagnostic did not resolve sparse-frame behavior. A caption diagnostic initially returned reason_required; the same caption was retried with an explicit reason. A subsequent native-caption hold captured the final view correctly. These were recorder diagnostics, with no part moves.
- The next replay was stopped before any committed move because the newly opened PCB editor had no IPC socket. placement_state/dryRun had answered from file, while the first actual move returned ipc_unavailable. Closed KiCad gracefully, waited, reopened the same fixture and explicitly verified live-editor IPC before the accepted replay.
- The accepted replay used the unchanged validated plan and completed all 16 commits with verified readback. No rejected placement commits, allowOverlap, allowOutside, allowLocked, side flips, forced process kills or saves were used. Both successful 16-commit executions and the zero-commit failed attempt are included in the task token accounting. Zero sub-agents and zero worker threads were spawned.
Benchmark stats in the comparison schema:
{
"engine": "GPT-6 Astra",
"model": "gpt-6-astra",
"board": "ESC G431 (149 parts; 27 machine pins and contacts fixed and locked; 122 placed)",
"desktop": "arav-rog, KiCad 10.0.3, kicad-bridge 1.0.3",
"window": [
"2026-09-12T20:43:04.222597+00:00",
"2026-09-12T20:54:41.403466+00:00"
],
"windowNote": "First live placement_state through last accepted-take commit; includes planning and a rejected recording plus capture diagnostics. No sub-agents or worker threads.",
"planning": {
"wallSeconds": 294.514,
"definition": "First placement_state request start to first move_footprint request start; first move was a non-mutating full-plan dry run",
"toFirstCommitSeconds": 294.679
},
"placement": {
"commits": 16,
"wallSeconds": 19.219,
"firstToLastCompletionSeconds": 18.968,
"partsPlaced": 122,
"ratsnestMm": 1529.01,
"initialRatsnestMm": 4476.222,
"courtyardOverlaps": 0,
"outsideOutline": 0,
"parked": 0,
"placementDrcErrors": 13,
"placementDrcNote": "13 inherited errors: six malformed MOSFET courtyards and seven internal U2 pad clearance errors; item UUID signatures match baseline. No new placement errors. placementClean is false."
},
"tokens": {
"thread": {
"input_tokens": 10866836,
"cached_input_tokens": 10645888,
"cache_write_input_tokens": 0,
"output_tokens": 25901,
"reasoning_output_tokens": 6749,
"total_tokens": 10892737
},
"uncachedInputTokens": 220948,
"threadTurns": 57,
"agentLaunches": 0,
"agents": 0,
"workerThreads": 0,
"withAgents": {
"input_tokens": 10866836,
"cached_input_tokens": 10645888,
"cache_write_input_tokens": 0,
"output_tokens": 25901,
"reasoning_output_tokens": 6749,
"total_tokens": 10892737
},
"accountingSource": "/home/adom/.codex/sessions/2026/09/12/rollout-2026-09-12T12-08-00-01a09697-1b14-7111-9897-63815e098b24.jsonl",
"accountingCutoff": "2026-09-12T20:57:45.252Z",
"accountingNote": "Task delta from Codex cumulative token_count events, excluding the earlier six-net routing task. Codex input_tokens includes cached_input_tokens; reasoning_output_tokens is a subset of output_tokens. No cache writes reported. Counts stop at the explicit cutoff; subsequent issue update and final response are excluded.",
"maxRequestInputTokens": 224224
},
"usdApiEquivalent": {
"thread": 14.150418,
"withAgents": 14.150418,
"priceBasis": "OpenAI GPT-6 Astra model page, checked 2026-09-12: per 1M tokens $10 uncached input, $1 cached input, $12.50 cache writes (zero here), $50 output. Standard API equivalent, not a subscription invoice.",
"priceUrl": "https://developers.openai.com/api/docs/models/gpt-6-astra",
"formula": "((input_tokens - cached_input_tokens)*10 + cached_input_tokens*1 + output_tokens*50)/1000000"
},
"planShare": {
"planUsdPerMonth": 200,
"threadPercent": 7.075209,
"withAgentsPercent": 7.075209,
"note": "Arithmetic API-equivalent cost divided by $200, not actual subscription quota consumption."
}
}
The API-equivalent cost uses OpenAI's published GPT-6 Astra prices. Codex input_tokens includes cached_input_tokens, so cached input is subtracted before applying the uncached rate. The cost divided by $200 is an arithmetic comparison, not actual subscription billing or quota usage. The attached stats identify the exact accounting cutoff and excluded final reporting tail.
Accepted commit results:
| Batch | Start UTC | End UTC | Parts | Verified | Revision |
|---|---|---|---|---|---|
| 1 | 2026-09-12T20:54:22.184893+00:00 | 2026-09-12T20:54:22.435401+00:00 | C2, C3, D1, R32, U6, U2, U3, U1 | True | 08a44f64cb57f60fe3c303f3ffca5db087cd59c10dc5cb7841b4c90203cea60a |
| 2 | 2026-09-12T20:54:23.486742+00:00 | 2026-09-12T20:54:23.707174+00:00 | U5, U4, J1, SW1, Y1, Q5, Q6, Q3 | True | 5cc71c7dfe3616ec90a21d1e5641844165beb4a306de018230d3907545d33bff |
| 3 | 2026-09-12T20:54:24.757666+00:00 | 2026-09-12T20:54:24.962650+00:00 | Q4, Q1, Q2, D2, C17, C4, C10, C11 | True | dae52b1ee1046f62992b3378df1073ec83e9a1f00253776998ab102633f6f73e |
| 4 | 2026-09-12T20:54:25.996751+00:00 | 2026-09-12T20:54:26.242184+00:00 | C14, C15, C16, C18, C19, C31, C33, C37 | True | c33c5591e2c86ba1c872ab5e685628db35ad52754ac7cbf84bf02939fbe05fd9 |
| 5 | 2026-09-12T20:54:27.277375+00:00 | 2026-09-12T20:54:27.499511+00:00 | C7, C23, C1, C8, C20, FB1, C25, C29 | True | 536b83fd0f11ae024d68459a9fd7a3a5d8da0965cf2525bc8163c15b9be1f5a8 |
| 6 | 2026-09-12T20:54:28.546223+00:00 | 2026-09-12T20:54:28.789692+00:00 | C40, C6, C12, C45, C24, C26, C27, C28 | True | 5722a0d9dd2ebacc2ca183f97ff848d9339f1e882f594c0488c8cbeab04f3c5c |
| 7 | 2026-09-12T20:54:29.826465+00:00 | 2026-09-12T20:54:30.088502+00:00 | C30, C44, C35, C36, C39, C9, C5, C22 | True | 1429a820e8c5a1bd855b39dac7fb678a6aeaf81e64d7751b97154c3abfb39c3e |
| 8 | 2026-09-12T20:54:31.124896+00:00 | 2026-09-12T20:54:31.316960+00:00 | C13, C21, C32, C34, C38, C41, C42, C43 | True | 5a5f745339e6f030fe3f7f25670293acacc1bc96797cfa57e85145f09fdb8856 |
| 9 | 2026-09-12T20:54:32.347199+00:00 | 2026-09-12T20:54:32.567785+00:00 | JP1, R19, R17, R21, R13, R15, R23, R25 | True | 066013bf3c271c6c3226590cd202afb6901836b33b4ddc5b4be37b51a9bf192a |
| 10 | 2026-09-12T20:54:33.602467+00:00 | 2026-09-12T20:54:33.798800+00:00 | R27, R29, R2, R4, R8, R10, R12, R30 | True | 940441ff980d32719f6a5c9488d79357614f1e4939c6086d37aeb2b09a8010a1 |
| 11 | 2026-09-12T20:54:34.834053+00:00 | 2026-09-12T20:54:35.052424+00:00 | R33, R6, R20, R18, R22, R14, R24, R26 | True | 63a4f1173ccad581dd6bba0e33c41bc3c50553d5a296583403c17f23c7b8169b |
| 12 | 2026-09-12T20:54:36.089156+00:00 | 2026-09-12T20:54:36.317647+00:00 | R28, R16, R1, R3, R5, R7, R9, R31 | True | 160db67f64bb89f47a92f6205bb6fda483ffb7a64dcefcb8e9a4319a96ae731c |
| 13 | 2026-09-12T20:54:37.403861+00:00 | 2026-09-12T20:54:37.635882+00:00 | R34, R11, LED2, LED1, LED3, TP12, TP13, TP14 | True | 8d00ffdc29c704acb1f831635a7054130bc7931b819affda6019e1332f1c03b1 |
| 14 | 2026-09-12T20:54:38.674289+00:00 | 2026-09-12T20:54:38.885128+00:00 | TP8, TP17, TP5, TP4, TP7, TP3, TP16, TP20 | True | e87ea931b162afcd93447ffe2a107d6825677cbb17cae5a073052ddc55357437 |
| 15 | 2026-09-12T20:54:39.923108+00:00 | 2026-09-12T20:54:40.160452+00:00 | TP9, TP1, TP19, TP11, TP15, TP2, TP10, TP6 | True | 3a53e77cd89051ee54a899333fe2a3291d778d6ae0ed2cc30eb7ef72937ece67 |
| 16 | 2026-09-12T20:54:41.198724+00:00 | 2026-09-12T20:54:41.403466+00:00 | TP18, TP21 | True | 0e76c8c7f3f37102b2d541f303ed321c79f088fc293a59b9e1eac674181b2dbe |
The attached bridge-calls.csv lists every instrumented Bridge call with UTC start/end, duration, result and exact shell command, including failed takes and diagnostics. bridge-commands.txt is the full replayable command transcript; media-commands.txt records the exact ffmpeg commands. plan.json contains Astra's independent placement coordinates.
Setup and publication commands:
adom-codex context
adom-wiki pkg install adom/kicad-bridge
adom-bridge --ai-thread "Astra ESC G431 placement video" --target arav-rog kicad_status '{}'
adom-bridge --ai-thread "Astra ESC G431 placement video" --target arav-rog kicad_close '{}'
curl -sLo esc-g431-unplaced.kicad_pcb https://wiki.adom.inc/api/pages/adom/kicad-bridge/files/demo/placement/clean/esc-g431-unplaced.kicad_pcb
adom-wiki repo push adom/codex --files docs/videos/astra-placement-esc-g431.mp4 docs/videos/astra-placement-esc-g431-poster.jpg -m "Astra placement video: ESC G431 through kicad_move_footprint"
curl -s -o /dev/null -w "%{http_code}" https://wiki.adom.inc/api/pages/adom/codex/files/docs/videos/astra-placement-esc-g431.mp4
Cleanup completed using kicad_close {"discardChanges":true} on arav-rog. KiCad confirmed closure after Discard Changes, without a forced kill. Pulled the fixture back after closure and verified that its bytes exactly match the original download. The published MP4 also matches the local verified MP4 by SHA-256.
Publication retry: the initial issue command rejected .sh attachments locally before creating an issue. Checked for duplicates, changed the transcript attachment filenames to .txt, and posted successfully. The token accounting snapshot includes this retry and final cleanup/readback; it excludes only the final issue refresh and final response after the stated cutoff.