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
background doctrine: the always-on focus sentinel (0.9.113-0.9.115)
1 file changed
+26
skills/kicad-bridge-background/SKILL.md+26@@ -212,3 +212,29 @@ minimized, it just has to be in the background.") The passive `fg_assert` (fail the verb if KiCad is z:0) still runs as the regression check; `_keep_background()` is the active remedy that keeps the user's screen clean during the run.++## The always-on focus sentinel (0.9.113-0.9.115)++The per-verb guardians PREVENT steals while a verb runs, but they expire, and KiCad+windows self-raise LATE (3D render / footprint-library load finishing minutes after+the verb). John caught those flashes live (2026-08-16: "i just saw some of your+windows auto-foreground"). The sentinel is a process-lifetime thread that watches+every foreground transition:++- KiCad window reaches the foreground with no user cause: minimize-bounce it back+ (never touching any user window) and log it.+- User cause means a mouse CLICK landing with the cursor ON that window, or an+ in-progress alt-tab. RECENT INPUT ALONE IS NOT USER INTENT: the user typing in+ another app is exactly when a self-raise is most disruptive (the 0.9.113 bless+ test got this wrong; 0.9.115 fixed it, verified adversarially).+- Sanctioned bridge foregrounds (bring_to_user / announce_foreground paths) call+ expect_foreground() so the sentinel never fights foreground:true or the+ announced allowForeground last resorts.+- Every transition lands in kicad_state.focusEvents and stderr (bridge-logs), so+ background compliance is PROVABLE from the log. Callers sampling z-order every+ few seconds CANNOT see sub-second flashes; the sentinel can.++Adversarial verification recipe: open a surface, wait out every guard tier, force+the window to the foreground via ab desktop_set_window_state {activate:true}, and+assert the sentinel logs self-raise (bounced) and the user's window is back in+front within ~300ms.