app
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.
← Commit history
plan: phase 4 gate 73/2/15 with the residual steal explained
1 file changed
+1
docs/rust-port-plan.md+1@@ -17,6 +17,7 @@ Written 2026-09-11 from a full audit of the 0.9.350 source, the Adom Bridge (ab) | 2026-09-11 | Phases 2 and 3 verified live. On arav-rog (KiCad 10.0.3): live routing state in 15 ms, dry run with snapshot DRC, commits as native undo steps, stale-revision refusal, vias, a crossing route rejected by DRC with nothing landed, removal verified, and both regression demo modes at zero errors and zero unconnected (the Python gate's numbers). On ConfRoomROG (KiCad 10.0.5) the full verb runner against the phase 3 binary: 61 pass, 18 fail, 16 skip, with every window verb passing and zero foreground steals. The 18 failures were verbs the binary did not carry yet (show family, progress, verb_times, upgrade, demo, the retired plugin verbs, the export_gerbers alias) plus one runner ordering bug, all addressed the same day: alias added, plugin verbs answer `plugin_retired` with the replacement verb, runner phases fixed, show and upgrade ports in progress. The server became multithreaded (six workers, a GUI lock serialising window and IPC verbs) so status and progress polls answer in tens of milliseconds during a long verb. Two facts learned on the boxes: KiCad runs one API server per machine (first process wins; a standalone PCB editor beside the project manager gets none), now reported as `no_pcb_frame` with the remedy; and ab spawned a legacy `bridges\kicad` folder (bridge 0.9.65) on both boxes while its registry claimed the cache build, filed as [adom/adom-bridge#186](https://wiki.adom.inc/adom/adom-bridge/issues/186) and moved aside on both. | | 2026-09-11 | Phase 3 complete: alpha.3 (94 verbs: show family, progress registry with `kicad_progress`, `kicad_verb_times` and the `operations` block on status, `kicad_upgrade` with the silent NSIS install behind the platform trait, `kicad_rescan_libraries`, the retired plugin verbs answering honestly). Full verb runner on ConfRoomROG against the native binary: 72 pass, 3 fail, 15 skip, zero foreground steals; the Python baseline on the same box was 72, 1, 15. The three failures: `kicad_demo` (phase 5) and the two retired plugin verbs, which returned an honest error where the runner expects a status (now they answer success with `retired:true`). 180 tests. Phase 4 (etiquette loop) and phase 5 (tour) start next, on a trait surface fixed in advance so the two run in parallel. | | 2026-09-11 | Phase 4 landed and is live on ConfRoomROG: the etiquette loop runs inside the binary (a 120 ms sentinel thread and a WinEventHook thread on EVENT_SYSTEM_FOREGROUND and EVENT_OBJECT_SHOW feeding one tested decision table; the once-per-window ledger; the owned-pid ledger with the parent-chain walk, persisted in the Python's file format; the 60 s spawn watch; sanctioned foregrounds; user-click and alt-tab detection; the idle rule; the 20 s and 60 s heals). Two judgement calls recorded in the code: WS_EX_NOACTIVATE is never set (John's 0.9.181 rule), and the idle rule ranks below the guards so an unattended run still bounces self-raises. First boot on the box: both hooks armed, the launched project manager registered and pushed back exactly once. The tour input primitives (SendInput mouse, wheel, key; MCI audio) exist behind the trait and refuse unless the target window is the measured foreground. |+| 2026-09-11 | Gate with the loop running, ConfRoomROG: 73 pass, 2 fail, 15 skip. The two: `kicad_demo` (phase 5, in progress) and one foreground note on `open_board`. The loop's own event log shows exactly what happened there: the new PCB editor frame took the foreground and was bounced once by the hook within milliseconds, its "Load PCB" progress dialog took it and was bounced once, and the frame's load-complete self-raise a moment later was left alone under the "background once, then hands off" rule, which is the Python's rule and the Python's behaviour on this box. Kept as is. | ## The goal in one sentence