← Commit history

v0.9.100: background audit fixes — demo worker thread arms its own full-duration focus guardian (dispatcher's 45s expired mid-job); slow-tier guard 45->120s for cold 3D flows

John Lauer ·0e830a12b0 ·2mo ago ·parent 3f4cdf7
6 files changed +24−8
BRIDGE_VERSION+1−1
@@ -1 +1 @@-0.9.99+0.9.100
adom-bridge-kicad-manifest.json+5−5
@@ -1,15 +1,15 @@ {   "manifest_version": 1,   "name": "kicad",-  "version": "0.9.99",-  "url": "https://wiki.adom.inc/download/adom/kicad-bridge/0.9.99/adom-bridge-kicad-v0.9.99.zip",-  "sha256": "b6051a2f88bb12c775830d81e50d93abc00acc2f450d67a42125d8de756dfc4a",-  "size": 391591,+  "version": "0.9.100",+  "url": "https://wiki.adom.inc/download/adom/kicad-bridge/0.9.100/adom-bridge-kicad-v0.9.100.zip",+  "sha256": "9b1e10da5e79e8f24c8a1317602fd7af790f5c2484b4a8c37fd0fd779cd37b6b",+  "size": 391976,   "verbPrefixes": [     "kicad_"   ],   "healthEndpoint": "/status",-  "released_at": "2026-08-15T09:25:48Z",+  "released_at": "2026-08-15T09:44:48Z",   "hero": "https://wiki.adom.inc/blob/app/kicad-bridge/kicad-hero.png",   "languages": [     "Python",
adom-bridge-kicad-v0.9.100.zipadded
⋯ 1 unchanged line ⋯
bridge.json+1−1
@@ -2,7 +2,7 @@   "manifest_version": 1,   "name": "kicad",   "displayName": "KiCad EDA",-  "version": "0.9.99",+  "version": "0.9.100",   "description": "Reverse bridge for KiCad \u2014 board/schematic introspection, lint via kicad-cli, plugin install, multi-instance probe, in-process DRC.",   "homepage": "https://wiki.adom.inc/adom/adom-bridge",   "author": "Adom Inc.",
handlers/demo.py+13
@@ -446,6 +446,19 @@ def _run_demo_background(kicad_info: dict) -> None:     import time as _t     t0 = _t.monotonic()     total_est = sum(_BEAT_EST.values())+    # BACKGROUND CONTRACT: the dispatcher's focus guardian only covers the+    # INITIAL call (45s) — this job spawns windows for the whole run (~100s),+    # including the board_3d render self-raise near the END. Arm a guardian from+    # inside the thread for the full job + margin. The guardian is KiCad-aware+    # (adopts the user's own window switches, never fights them), so a long arm+    # is harmless. (Gap found in the 2026-08-15 background audit.)+    try:+        from handlers import win_focus+        _ufg = win_focus.capture_foreground()+        if _ufg and not win_focus.is_kicad_window(_ufg):+            win_focus.restore_foreground_persistent(_ufg, seconds=total_est + 90)+    except Exception:  # pylint: disable=broad-except+        pass     done_weight = 0.0     try:         prep = _prepare(kicad_info)
server.py+4−1
@@ -818,7 +818,10 @@ def dispatch_command(command: str, args: dict) -> dict:                 # lands 30s+ out on slow boxes, well past the old 16s window. The                 # guardian is KiCad-aware now (never fights the user), so a long                 # guard has no downside.-                _restore_secs = 45.0 if command in ("open_3d_viewer", "place_footprint", "demo", "launch", "show_3d_chip", "show_3d_board") else 20.0+                # 120s for the slow flows: a COLD show_3d_* is board-open (~30s) + 3D open ++                # render self-raise — 45s expired mid-flow. Guardian never fights the user,+                # so the long guard has no downside. (2026-08-15 background audit.)+                _restore_secs = 120.0 if command in ("open_3d_viewer", "place_footprint", "demo", "launch", "show_3d_chip", "show_3d_board") else 20.0                 win_focus.restore_foreground_persistent(_user_fg, seconds=_restore_secs)             if isinstance(result, dict):                 result["_userFocusRestored"] = bool(restored)