← Commit history
.insiders-stage/fusion-bridge/version.json+5−5
@@ -1,14 +1,14 @@ {   "manifest_version": 1,   "name": "fusion360",-  "version": "1.11.42",-  "url": "https://wiki.adom.inc/download/adom/fusion-bridge/1.11.42/adom-bridge-fusion-v1.11.42.zip",-  "sha256": "902dd66fb04d6193ace17a8d18530dfbc6fe2d08f2c7680e947202ccec2a978f",-  "size": 6607252,+  "version": "1.11.43",+  "url": "https://wiki.adom.inc/download/adom/fusion-bridge/1.11.43/adom-bridge-fusion-v1.11.43.zip",+  "sha256": "b50681be3c0494e14d5142b1f272753c5341b0cd9bef2795f9398477362b5577",+  "size": 6609186,   "verbPrefixes": [     "fusion_"   ],   "healthEndpoint": "/status",-  "released_at": "2026-10-06T14:51:41Z",+  "released_at": "2026-10-18T13:30:55Z",   "tier": "insiders" }\ No newline at end of file
.release-page-head+1−1
@@ -1 +1 @@-6d732c666a5c64a5862ddddb248106b0d47c7c64\ No newline at end of file+63e778bebe692903419370f406ce5f9cfe9253df\ No newline at end of file
install.sh

  
page.json+25−9
@@ -11,10 +11,6 @@     "uninstall": "./uninstall.sh"   },   "tags": [-    "ab",-    "bridge",-    "fusion",-    "desktop-app",     "fusion360",     "autodesk",     "cad",@@ -80,9 +76,6 @@     "add a 3d model to a component",     "make a fusion 360 library with 3d",     "set up the fusion bridge",-    "fusion dashboard",-    "fusion status page",-    "open the fusion launch page",     "aps not configured",     "share aps client id across my org",     "set up fusion cloud search for my company",@@ -115,5 +108,28 @@       "label": "Part volume",       "prompt": "How much material does each printed part in this assembly use?"     }-  ]-}+  ],+  "agent_permissions": {+    "allow_bash": [],+    "allow": [+      "adom-desktop-fusion-bridge read-only verbs (via the adom-bridge CLI): fusion_readiness, fusion_get_app_state, fusion_addin_status, fusion_check_dialogs - state queries; they change nothing.",+      "adom-desktop-fusion-bridge read-only verbs: fusion_alerts (reads Fusion's own log for toasts), fusion_document_info, fusion_window_info, fusion_board_info, fusion_library_parts - inspect only.",+      "adom-desktop-fusion-bridge read-only verbs: fusion_prove_result (a persisted run report), fusion_plan_library_import (report-only preflight), fusion_list_cloud_projects, fusion_describe.",+      "adom-desktop-fusion-bridge evidence captures fusion_screenshot_fusion and fusion_capture_library_views read pixels and write local image files only."+    ],+    "soft_deny": [+      "adom-desktop-fusion-bridge lifecycle verbs fusion_stop, fusion_kill, fusion_restart_for_addin close or kill the Fusion application - keep the human prompt.",+      "adom-desktop-fusion-bridge fusion_install_fusion silently installs Autodesk Fusion on the user's machine.",+      "adom-desktop-fusion-bridge fusion_cleanup_cloud_files deletes files from the user's Autodesk cloud hub.",+      "adom-desktop-fusion-bridge managed-library verbs (fusion_managed_library_push/pull/create/link/unlink) publish to or overwrite the user's library.io libraries."+    ],+    "environment": [+      "adom-desktop-fusion-bridge is the Fusion 360 bridge for Adom Bridge; its fusion_* verbs are invoked through the adom-bridge CLI and drive Autodesk Fusion on the user's own desktop.",+      "adom-desktop-fusion-bridge desktop actions also pass Adom Bridge's own human-approval gate (caller identity, per-call reason, Activity Log) - a container approval is the first of two gates."+    ]+  },+  "author": {+    "name": "John Lauer",+    "email": "[email protected]"+  }+}\ No newline at end of file
rust/Cargo.lock+5−5
@@ -10,7 +10,7 @@ checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"  [[package]] name = "adom-fusion-bridge"-version = "1.11.42"+version = "1.11.43" dependencies = [  "base64",  "chrono",@@ -273,7 +273,7 @@ dependencies = [  [[package]] name = "fusion-core"-version = "1.11.42"+version = "1.11.43" dependencies = [  "serde",  "serde_json",@@ -283,7 +283,7 @@ dependencies = [  [[package]] name = "fusion-lbr"-version = "1.11.42"+version = "1.11.43" dependencies = [  "regex",  "roxmltree",@@ -295,14 +295,14 @@ dependencies = [  [[package]] name = "fusion-os-mac"-version = "1.11.42"+version = "1.11.43" dependencies = [  "fusion-core", ]  [[package]] name = "fusion-os-win"-version = "1.11.42"+version = "1.11.43" dependencies = [  "fusion-core",  "windows-sys 0.59.0",
rust/bridge/src/routing_planner.py+1−1
@@ -46,7 +46,7 @@ def automatic_plan(board,args):         obstacles.append((c,d,r,set(ls),(min(c[0],d[0])-r-clearance,max(c[0],d[0])+r+clearance,min(c[1],d[1])-r-clearance,max(c[1],d[1])+r+clearance)))     cache={}     def clear(a,b,radius,ls,via=False):-        if any(not(xmin+edge+radius<=p[0]<=xmax-edge-radius and ymin+edge+radius<=p[1]<=ymax-edge-radius) for p in (a,b)):return False+        if outline_problem(ctx,a,b,radius):return False   # any closed outline, not only a rectangle (#123)         ax,bx=min(a[0],b[0])-radius,max(a[0],b[0])+radius         ay,by=min(a[1],b[1])-radius,max(a[1],b[1])+radius         for c,d,r,ol,bounds in obstacles:
rust/bridge/src/routing_script.py+80−19
@@ -243,6 +243,66 @@ def poly_distance(a,b,poly):     return min(distance(a,b,p0,q) for p0,q in zip(poly,poly[1:]+poly[:1]))  +def arc_points(p1,p2,curve):+    """An EAGLE wire from p1 to p2 sweeping `curve` degrees (positive = counterclockwise), as+    points p1..p2 at most 5 degrees apart, plus the largest gap between chord and arc."""+    if not curve: return [p1,p2],0.0+    c=math.radians(curve); dx,dy=p2[0]-p1[0],p2[1]-p1[1]; L=math.hypot(dx,dy)+    if L<1e-9: return [p1,p2],0.0+    r=L/(2*abs(math.sin(c/2))); d=(L/2)/math.tan(c/2)+    cx,cy=(p1[0]+p2[0])/2-dy/L*d,(p1[1]+p2[1])/2+dx/L*d+    a0=math.atan2(p1[1]-cy,p1[0]-cx); n=max(2,int(math.ceil(abs(curve)/5.0)))+    pts=[[cx+r*math.cos(a0+c*k/n),cy+r*math.sin(a0+c*k/n)] for k in range(n+1)]+    pts[0],pts[-1]=list(p1),list(p2)+    return pts,r*(1-math.cos(abs(c)/n/2))+++def outline_loops(board):+    """Layer-20 wires chained into closed loops, largest (the board edge) first, and the largest+    arc sagitta. Fails unless every wire belongs to a closed loop."""+    segs=[]; sag=0.0+    for w in board.findall("plain/wire[@layer='20']"):+        p1=[float(w.get('x1')),float(w.get('y1'))]; p2=[float(w.get('x2')),float(w.get('y2'))]+        pts,sg=arc_points(p1,p2,float(w.get('curve','0') or 0)); sag=max(sag,sg); segs.append(pts)+    for c in board.findall("plain/circle[@layer='20']"):+        x,y,r=float(c.get('x')),float(c.get('y')),float(c.get('radius'))+        n=72; segs.append([[x+r*math.cos(2*math.pi*k/n),y+r*math.sin(2*math.pi*k/n)] for k in range(n+1)]); sag=max(sag,r*(1-math.cos(math.pi/n)))+    if not segs: fail('unsupported_board','The board has no outline on layer 20 (Dimension)')+    near=lambda p,q: abs(p[0]-q[0])<1e-3 and abs(p[1]-q[1])<1e-3+    loops=[]+    while segs:+        loop=list(segs.pop(0))+        while not near(loop[0],loop[-1]):+            for i,sg in enumerate(segs):+                if near(sg[0],loop[-1]): loop+=sg[1:]; segs.pop(i); break+                if near(sg[-1],loop[-1]): loop+=list(reversed(sg))[1:]; segs.pop(i); break+            else: fail('unsupported_board','The board outline is not closed: a layer-20 line or arc ends near (%.3f, %.3f) with nothing joined to it'%tuple(loop[-1]))+        loops.append(loop[:-1])+    area=lambda l: abs(sum(a[0]*b[1]-b[0]*a[1] for a,b in zip(l,l[1:]+l[:1])))/2+    loops.sort(key=area,reverse=True)+    return loops,sag+++def outline_problem(ctx,a,b,radius):+    """Why copper from a to b (half-width radius) breaks the board outline, or None. Inside the+    edge loop, outside every cutout, and the edge clearance away from every outline segment."""+    outer,cutouts=ctx['outline'][0],ctx['outline'][1:]+    if not (point_in_loop(a,outer) and point_in_loop(b,outer)) or any(point_in_loop(p,c) for p in (a,b) for c in cutouts):+        return 'Candidate copper lies outside the board outline or inside a cutout'+    margin=ctx['edgeClearance']+radius+    for loop in ctx['outline']:+        for p0,q in zip(loop,loop[1:]+loop[:1]):+            if distance(a,b,p0,q)<margin-1e-6: return 'Candidate copper violates the board-edge margin'+    return None+++def point_in_loop(p,loop):+    inside=False+    for a,b in zip(loop,loop[1:]+loop[:1]):+        if (a[1]>p[1])!=(b[1]>p[1]) and p[0]<a[0]+(p[1]-a[1])*(b[0]-a[0])/(b[1]-a[1]): inside=not inside+    return inside++ def plan(board,args):     nets,pads,wires,vias=objects(board)     net=identifier(args.get('net'))@@ -271,7 +331,7 @@ def plan(board,args):                 outgoing=layer(spec.get('layer',current))             elif isinstance(spec,list) and len(spec)==2: xy=spec             else: fail('invalid_path','Waypoints are [x,y], {x,y,layer?}, or {pad,layer?}')-            xy=[number(v) for v in xy]+            xy=[grid(number(v)) for v in xy]   # on Fusion's grid, so the readback matches exactly             if pad and current not in pad['layers']: fail('pad_layer_mismatch','Pad has no copper on incoming layer')             if previous is not None and previous!=xy:                 planned.append({'kind':'segment','net':net,'start':previous,'end':xy,'layer':current,'width':width})@@ -290,13 +350,11 @@ def plan(board,args):     if not planned or len(planned)>512: fail('invalid_path','Need 1..512 nonzero copper items')     ctx=routing_context(board,args,net,width,drill if any(i['kind']=='via' for i in planned) else 0)     clearance=ctx['clearance']; obstacles=ctx['obstacles']-    xmin,xmax,ymin,ymax=ctx['bounds']     for item in planned:         via=item['kind']=='via'; a=item['at'] if via else item['start']; b=a if via else item['end']         radius=ctx['via_dia'](item['diameter'],item['drill'])/2 if via else item['width']/2; layers=[1,16] if via else [item['layer']]-        margin=ctx['edgeClearance']+radius-        if any(not(xmin+margin<=p[0]<=xmax-margin and ymin+margin<=p[1]<=ymax-margin) for p in (a,b)):-            fail('clearance_violation','Candidate copper violates the board-edge margin')+        why=outline_problem(ctx,a,b,radius)+        if why: fail('clearance_violation',why)         for other,c,d,r,ls,poly in obstacles:             if other==net or not set(layers).intersection(ls): continue             gap=(poly_distance(a,b,poly) if poly else distance(a,b,c,d)-r)-radius@@ -334,14 +392,11 @@ def routing_context(board,args,net,width,drill):     # the via drill only matters when the path changes layer (a pure trace has no hole)     if width<rule('msWidth',0.2) or (drill and drill<rule('msDrill',0.3)):         fail('design_rule_violation','Width/drill is below the board minimum')-    boundary=board.findall("plain/wire[@layer='20']")-    if len(boundary)!=4 or any(float(w.get('curve','0')) for w in boundary):-        fail('unsupported_board','Initial preflight requires a rectangular four-line outline')-    edges=[([float(w.get('x1')),float(w.get('y1'))],[float(w.get('x2')),float(w.get('y2'))]) for w in boundary]-    xs=[p[0] for e in edges for p in e]; ys=[p[1] for e in edges for p in e]-    xmin,xmax,ymin,ymax=min(xs),max(xs),min(ys),max(ys)-    expected={tuple(sorted(e)) for e in [((xmin,ymin),(xmax,ymin)),((xmax,ymin),(xmax,ymax)),((xmax,ymax),(xmin,ymax)),((xmin,ymax),(xmin,ymin))]}-    if {tuple(sorted(map(tuple,e))) for e in edges}!=expected: fail('unsupported_board','Outline is not a closed rectangle')+    # ANY closed outline (page issue #123): straight lines and arcs (rounded corners, curves,+    # notches) on layer 20, chained into loops. The largest loop is the board edge, the rest are+    # cutouts. Arcs become polylines; their sagitta is added to the edge margin so the check+    # stays conservative on a concave curve.+    loops,sagitta=outline_loops(board)     obstacles=[]     for p in pads.values(): obstacles.append((p['net'],p['at'],p['at'],p['radius'],p['layers'],p.get('poly')))     for w in wires: obstacles.append((w['net'],w['start'],w['end'],w['width']/2,[w['layer']],None))@@ -359,7 +414,7 @@ def routing_context(board,args,net,width,drill):         xy=[float(h.get('x')),float(h.get('y'))]; obstacles.append((None,xy,xy,float(h.get('drill'))/2,[1,16],None))     if board.findall('libraries/library/packages/package/hole'):         fail('unsupported_board','Footprint mounting holes require transformed obstacle support')-    return {'via_dia':via_dia,'clearance':clearance,'edgeClearance':rule('mdCopperDimension',0.5),'bounds':(xmin,xmax,ymin,ymax),'obstacles':obstacles,'pads':pads}+    return {'via_dia':via_dia,'clearance':clearance,'edgeClearance':rule('mdCopperDimension',0.5)+sagitta,'outline':loops,'bounds':(min(p[0] for p in loops[0]),max(p[0] for p in loops[0]),min(p[1] for p in loops[0]),max(p[1] for p in loops[0])),'obstacles':obstacles,'pads':pads}   def native_drc(app):@@ -391,10 +446,16 @@ def native_drc(app):             'clean':checked and not errors}  +def grid(v):+    """Fusion stores board coordinates in 1/320000 mm (page issue #123: a via planned at+    7.280047896 reads back at 7.280046875). Plans and readbacks both snap to that grid."""+    return round(float(v)*320000.0)/320000.0++ def item_key(item):     if 'start' in item:         return ('segment',item['net'],item['layer'],round(item['width'],6),tuple(sorted((tuple(item['start']),tuple(item['end'])))))-    return ('via',item['net'],tuple(item['at']),round(item['drill'],6),round(item['diameter'],6),item['extent'])+    return ('via',item['net'],tuple(grid(c) for c in item['at']),round(item['drill'],6),round(item['diameter'],6),item['extent'])   def copper_signature(items):@@ -403,7 +464,7 @@ def copper_signature(items):     for item in items:         if 'start' not in item:             vs.append(item_key(item));continue-        a,b=map(tuple,(item['start'],item['end']))+        a,b=(tuple(grid(c) for c in item['start']),tuple(grid(c) for c in item['end']))         if a>b:a,b=b,a         dx,dy=b[0]-a[0],b[1]-a[1];length=math.hypot(dx,dy)         if not length:continue@@ -856,7 +917,7 @@ def handle(app,args,action):                 attempted=True; app.executeTextCommand('Electron.run '+cmd); commands.append(cmd)             app.executeTextCommand('Electron.run RATSNEST;')             _,after,after_meta=snapshot(app,args); vs=objects(after)[3]-            missing=[v for v in want if not any(o['net']==v['net'] and abs(o['at'][0]-v['x'])<0.001 and abs(o['at'][1]-v['y'])<0.001 for o in vs)]+            missing=[v for v in want if not any(o['net']==identifier(v.get('net')) and abs(o['at'][0]-number(v.get('x')))<0.001 and abs(o['at'][1]-number(v.get('y')))<0.001 for o in vs)]             return {'success':not missing,'mutated':True,'verified':not missing,'errorCode':None if not missing else 'readback_mismatch','missing':missing,'commands':commands,**state(after,after_meta)}         if action=='apply_pours':             # draw each planned pour that is not already on the board (same net, layer and outline),@@ -894,9 +955,9 @@ def handle(app,args,action):                 a,b=item['start'],item['end']                 # SET WIRE_BEND 2 = straight: the default bend style splits an angled                 # segment into a 45-degree dogleg, so the copper is not what was planned.-                command="SET WIRE_BEND 2; LAYER %d; LINE '%s' %.6fmm (%.6fmm %.6fmm) (%.6fmm %.6fmm);"%(item['layer'],candidate['net'],item['width'],*a,*b)+                command="SET WIRE_BEND 2; LAYER %d; LINE '%s' %.6fmm (%.9fmm %.9fmm) (%.9fmm %.9fmm);"%(item['layer'],candidate['net'],item['width'],*a,*b)             else:-                command="CHANGE DRILL %.6fmm; VIA '%s' %.6fmm ROUND 1-16 (%.6fmm %.6fmm);"%(item['drill'],candidate['net'],item['diameter'],*item['at'])+                command="CHANGE DRILL %.6fmm; VIA '%s' %.6fmm ROUND 1-16 (%.9fmm %.9fmm);"%(item['drill'],candidate['net'],item['diameter'],*item['at'])             attempted=True             app.executeTextCommand('Electron.run '+command)             commands.append(command)
rust/core/src/dialog_rules.json+8
@@ -1,5 +1,13 @@ {  "rules": [+  {+   "needles": [+    "skiawindowcontextdx12",+    "unrecoverable d3d12"+   ],+   "category": "fusion_gpu_device_lost",+   "resolution": "Fusion Electronics lost its D3D12 graphics device (SkiaWindowContextDx12): the canvas stops drawing and goes black, and the bridge cannot fix it. This is a graphics driver or display problem, not the router. OK is the only button. Save the open documents, restart Fusion, and update the graphics driver; on the machine in page issue #121 it happened only with DisplayLink (USB) displays attached, so move Fusion to a monitor wired to the GPU or unplug those adapters."+  },   {    "needles": [     "unexpected condition",
tests/reports/daily-cron-2026-10-18.logadded+132
@@ -0,0 +1,132 @@+warmup: waking the bridge (unscored)...+  fusion_readiness                           PASS +  fusion_prewarm                             PASS +  fusion_account                             FAIL - expected success, got error='fusion_account' did not respond within ab's 60s budget. code=timed_out; missing field 'holdsSeat'; missing field 'running'+  fusion_describe                            PASS +  fusion_get_app_state                       FAIL - expected success, got error=Main thread busy — activity_banner running for 106.1s. code=main_thread_busy+  fusion_search_cloud_files                  PASS +  fusion_walk_cloud_tree                     PASS +  fusion_aps_status                          PASS +  fusion_aps_get_browser                     PASS +  fusion_aps_search                          PASS +  fusion_aps_recent                          PASS +  fusion_aps_browse                          PASS +  fusion_aps_file_info                       PASS +  fusion_aps_get                             PASS +  fusion_uninstall                           PASS +  fusion_set_seat_takeover                   PASS +  fusion_start                               PASS +  fusion_get_preferences                     FAIL - expected success, got error='fusion_get_preferences' did not respond within ab's 25s budget. code=timed_out; missing field 'current'+  fusion_set_preference                      FAIL - expected success, got error='fusion_set_preference' did not respond within ab's 40s budget. code=timed_out+  fusion_mcp_status                          PASS +  fusion_set_auto_update                     PASS +  fusion_assembly_bom                        FAIL - expected a BOM or the budget refusal, got error='fusion_assembly_bom' did not respond within ab's 60s budget code=timed_out+  fusion_dismiss_blocking_dialogs            PASS +  fusion_open_cloud_file                     FAIL - expected success, got error=None code=None; timed out+  fusion_show_schematic                      FAIL - expected success, got error='fusion_show_schematic' did not respond within ab's 60s budget. code=timed_out+  fusion_show_2d_board                       FAIL - expected success, got error='fusion_show_2d_board' did not respond within ab's 60s budget. code=timed_out+  fusion_board_info                          FAIL - expected success, got error=Add-in request failed: http://127.0.0.1:8774/command: Network Error: Network Err code=None; missing field 'rawXml'+  fusion_open_electronics                    FAIL - expected success, got error=Add-in request failed: http://127.0.0.1:8774/command: Network Error: Network Err code=None; missing field 'isElectronics'+  fusion_list_text_commands                  FAIL - expected success, got error=Add-in request failed: http://127.0.0.1:8774/command: Network Error: Network Err code=None; missing field 'commands'+  fusion_execute_text_command                FAIL - expected success, got error='fusion_execute_text_command' did not respond within ab's 60s budget. code=timed_out+  fusion_show_3d_board                       FAIL - expected success, got error='fusion_show_3d_board' did not respond within ab's 60s budget. code=timed_out+  fusion_inspect_bodies                      FAIL - expected success, got error='fusion_inspect_bodies' did not respond within ab's 60s budget. code=timed_out; missing field 'bodies'; missing field 'units'+  fusion_physical_properties                 FAIL - expected success, got error='fusion_physical_properties' did not respond within ab's 60s budget. code=timed_out+  fusion_get_design_info                     FAIL - expected success, got error=Add-in request failed: http://127.0.0.1:8774/command: Network Error: Network Err code=None+  fusion_get_parameters                      FAIL - expected success, got error=Add-in request failed: http://127.0.0.1:8774/command: Network Error: Network Err code=None+  fusion_document_info                       FAIL - expected success, got error=Main thread busy — activity_banner running for 293.0s. code=main_thread_busy+  fusion_delete_cloud_file#guard             PASS +  fusion_set_parameter#guard                 PASS +  fusion_run_modeling_script#guard           FAIL - expected errorCode=wrong_document got timed_out (error='fusion_run_modeling_script' did not respond within ab's 180)+  fusion_assembly_bom#guard                  FAIL - expected errorCode=wrong_document got timed_out (error='fusion_assembly_bom' did not respond within ab's 60s budget)+  fusion_run_modeling_script                 FAIL - expected success, got error='fusion_run_modeling_script' did not respond within ab's 180s budget. code=timed_out+  fusion_close_window#noargs                 PASS +  fusion_cleanup_cloud_files#guard           PASS +  fusion_screenshot_fusion                   PASS +  fusion_state                               PASS +  fusion_demo_progress#unknown               PASS +  fusion_action_ledger                       PASS +  fusion_addin_status                        PASS +  fusion_alerts                              PASS +  fusion_verb_times                          PASS +  fusion_live_feed                           PASS +  fusion_prove_result                        PASS +  fusion_set_driving_badge                   PASS +  fusion_set_window_sizing                   PASS +  fusion_cancel_run                          PASS +  fusion_preflight_lbr                       PASS +  fusion_library_parts                       PASS +  fusion_routing_state#guard                 PASS +  fusion_route_net#guard                     PASS +  fusion_routing_drc#guard                   PASS +  fusion_plan_route#guard                    PASS +  fusion_schematic#guard                     PASS +  fusion_schematic#missing                   PASS +  fusion_make_showcase_project#guard         PASS +  fusion_eagle_import_status#guard           PASS +  fusion_show_attributes#guard               PASS +  focus_invariance                           PASS+cleanup: Fusion was already running before the run - leaving it (user's session).++Section coverage (John's product map, 2026-08-14):+  gui-driving                            9 pass / 8 fail (21 manual, 0 skip)  RED+  cad-3d-bom                             8 pass / 7 fail (7 manual, 0 skip)  RED+  mcp-server                             1 pass / 0 fail (1 manual, 0 skip)  green+  python-addin                           1 pass / 5 fail (1 manual, 0 skip)  RED+  aps                                    9 pass / 0 fail (13 manual, 0 skip)  green+  auth-tokens                            2 pass / 1 fail (5 manual, 0 skip)  RED+  exports                                0 pass / 0 fail (1 manual, 0 skip)  untested-this-tier+  bridge-lifecycle                       12 pass / 0 fail (15 manual, 0 skip)  green++46 PASS, 21 FAIL (80 manual-tier, 0 skipped) -> /home/adom/project/adom-desktop-fusion-bridge/tests/reports/verb-test-2026-10-18_1229.json+  FAIL: fusion_account - expected success, got error='fusion_account' did not respond within ab's 60s budget. code=timed_out; missing field 'holdsSeat'; missing field 'running'+  FAIL: fusion_get_app_state - expected success, got error=Main thread busy — activity_banner running for 106.1s. code=main_thread_busy+  FAIL: fusion_get_preferences - expected success, got error='fusion_get_preferences' did not respond within ab's 25s budget. code=timed_out; missing field 'current'+  FAIL: fusion_set_preference - expected success, got error='fusion_set_preference' did not respond within ab's 40s budget. code=timed_out+  FAIL: fusion_assembly_bom - expected a BOM or the budget refusal, got error='fusion_assembly_bom' did not respond within ab's 60s budget code=timed_out+  FAIL: fusion_open_cloud_file - expected success, got error=None code=None; timed out+  FAIL: fusion_show_schematic - expected success, got error='fusion_show_schematic' did not respond within ab's 60s budget. code=timed_out+  FAIL: fusion_show_2d_board - expected success, got error='fusion_show_2d_board' did not respond within ab's 60s budget. code=timed_out+  FAIL: fusion_board_info - expected success, got error=Add-in request failed: http://127.0.0.1:8774/command: Network Error: Network Err code=None; missing field 'rawXml'+  FAIL: fusion_open_electronics - expected success, got error=Add-in request failed: http://127.0.0.1:8774/command: Network Error: Network Err code=None; missing field 'isElectronics'+  FAIL: fusion_list_text_commands - expected success, got error=Add-in request failed: http://127.0.0.1:8774/command: Network Error: Network Err code=None; missing field 'commands'+  FAIL: fusion_execute_text_command - expected success, got error='fusion_execute_text_command' did not respond within ab's 60s budget. code=timed_out+  FAIL: fusion_show_3d_board - expected success, got error='fusion_show_3d_board' did not respond within ab's 60s budget. code=timed_out+  FAIL: fusion_inspect_bodies - expected success, got error='fusion_inspect_bodies' did not respond within ab's 60s budget. code=timed_out; missing field 'bodies'; missing field 'units'+  FAIL: fusion_physical_properties - expected success, got error='fusion_physical_properties' did not respond within ab's 60s budget. code=timed_out+  FAIL: fusion_get_design_info - expected success, got error=Add-in request failed: http://127.0.0.1:8774/command: Network Error: Network Err code=None+  FAIL: fusion_get_parameters - expected success, got error=Add-in request failed: http://127.0.0.1:8774/command: Network Error: Network Err code=None+  FAIL: fusion_document_info - expected success, got error=Main thread busy — activity_banner running for 293.0s. code=main_thread_busy+  FAIL: fusion_run_modeling_script#guard - expected errorCode=wrong_document got timed_out (error='fusion_run_modeling_script' did not respond within ab's 180)+  FAIL: fusion_assembly_bom#guard - expected errorCode=wrong_document got timed_out (error='fusion_assembly_bom' did not respond within ab's 60s budget)+  FAIL: fusion_run_modeling_script - expected success, got error='fusion_run_modeling_script' did not respond within ab's 180s budget. code=timed_out+{+  "discussion": {+    "id": 1920,+    "page_id": 13,+    "author_name": "John Lauer",+    "title": "Daily verb run RED 2026-10-18: 21 failing verb(s)",+    "body": "Automated daily verb run went red (2026-10-18, exit 1). Scorecard tail:\n\n```\n  exports                                0 pass / 0 fail (1 manual, 0 skip)  untested-this-tier\n  bridge-lifecycle                       12 pass / 0 fail (15 manual, 0 skip)  green\n\n46 PASS, 21 FAIL (80 manual-tier, 0 skipped) -> /home/adom/project/adom-desktop-fusion-bridge/tests/reports/verb-test-2026-10-18_1229.json\n  FAIL: fusion_account - expected success, got error='fusion_account' did not respond within ab's 60s budget. code=timed_out; missing field 'holdsSeat'; missing field 'running'\n  FAIL: fusion_get_app_state - expected success, got error=Main thread busy — activity_banner running for 106.1s. code=main_thread_busy\n  FAIL: fusion_get_preferences - expected success, got error='fusion_get_preferences' did not respond within ab's 25s budget. code=timed_out; missing field 'current'\n  FAIL: fusion_set_preference - expected success, got error='fusion_set_preference' did not respond within ab's 40s budget. code=timed_out\n  FAIL: fusion_assembly_bom - expected a BOM or the budget refusal, got error='fusion_assembly_bom' did not respond within ab's 60s budget code=timed_out\n  FAIL: fusion_open_cloud_file - expected success, got error=None code=None; timed out\n  FAIL: fusion_show_schematic - expected success, got error='fusion_show_schematic' did not respond within ab's 60s budget. code=timed_out\n  FAIL: fusion_show_2d_board - expected success, got error='fusion_show_2d_board' did not respond within ab's 60s budget. code=timed_out\n  FAIL: fusion_board_info - expected success, got error=Add-in request failed: http://127.0.0.1:8774/command: Network Error: Network Err code=None; missing field 'rawXml'\n  FAIL: fusion_open_electronics - expected success, got error=Add-in request failed: http://127.0.0.1:8774/command: Network Error: Network Err code=None; missing field 'isElectronics'\n  FAIL: fusion_list_text_commands - expected success, got error=Add-in request failed: http://127.0.0.1:8774/command: Network Error: Network Err code=None; missing field 'commands'\n  FAIL: fusion_execute_text_command - expected success, got error='fusion_execute_text_command' did not respond within ab's 60s budget. code=timed_out\n  FAIL: fusion_show_3d_board - expected success, got error='fusion_show_3d_board' did not respond within ab's 60s budget. code=timed_out\n  FAIL: fusion_inspect_bodies - expected success, got error='fusion_inspect_bodies' did not respond within ab's 60s budget. code=timed_out; missing field 'bodies'; missing field 'units'\n  FAIL: fusion_physical_properties - expected success, got error='fusion_physical_properties' did not respond within ab's 60s budget. code=timed_out\n  FAIL: fusion_get_design_info - expected success, got error=Add-in request failed: http://127.0.0.1:8774/command: Network Error: Network Err code=None\n  FAIL: fusion_get_parameters - expected success, got error=Add-in request failed: http://127.0.0.1:8774/command: Network Error: Network Err code=None\n  FAIL: fusion_document_info - expected success, got error=Main thread busy — activity_banner running for 293.0s. code=main_thread_busy\n  FAIL: fusion_run_modeling_script#guard - expected errorCode=wrong_document got timed_out (error='fusion_run_modeling_script' did not respond within ab's 180)\n  FAIL: fusion_assembly_bom#guard - expected errorCode=wrong_document got timed_out (error='fusion_assembly_bom' did not respond within ab's 60s budget)\n  FAIL: fusion_run_modeling_script - expected success, got error='fusion_run_modeling_script' did not respond within ab's 180s budget. code=timed_out\n```\n\nFull log: tests/reports/daily-cron-2026-10-18.log on the dev container. Versions at run time are in the readiness line of the log. Triage per dev-skills/fusion-verb-tests: re-run the failing verbs with --only first, a startup race or relay flake re-passes; a repeat failure is the real finding.\n",+    "category": "general",+    "is_pinned": 0,+    "is_locked": 0,+    "reply_count": 0,+    "last_reply_at": null,+    "created_at": "2026-10-18 12:29:58",+    "updated_at": "2026-10-18 12:29:58",+    "status": "open",+    "labels": "[]",+    "closed_at": null,+    "closed_by_name": null,+    "mentions_json": "[]",+    "number": 122,+    "deleted_at": null,+    "deleted_by_id": null,+    "deleted_by_name": null,+    "edited_at": null,+    "url": "https://wiki.adom.inc/adom/fusion-bridge/issues/122"+  },+  "page_discussion_count": 121+}+hint [WEB_URL]: https://wiki.adom.inc/adom/fusion-bridge/issues/122+hint [BODY_POSTED]: body posted (3894 chars): Automated daily verb run went red (2026-10-18, exit 1). Scorecard tail:  ```   exports                                0 pass / 0 fail (1 manual, 0 skip)  untest...
tests/reports/daily-cron-history.txt+1
@@ -56,3 +56,4 @@ RED 2026-10-14 (exit 1) RED 2026-10-15 (exit 1) RED 2026-10-16 (exit 1) RED 2026-10-17 (exit 1)+RED 2026-10-18 (exit 1)
tests/reports/verb-test-2026-10-18_1229.jsonadded+1014
@@ -0,0 +1,1014 @@+{+ "date": "2026-10-18_1229",+ "target": "ConfRoomROG",+ "tier": "daily",+ "pass": 46,+ "fail": 21,+ "sections": {+  "bridge-lifecycle": {+   "PASS": 12,+   "FAIL": 0,+   "MANUAL": 15,+   "SKIP": 0+  },+  "auth-tokens": {+   "PASS": 2,+   "FAIL": 1,+   "MANUAL": 5,+   "SKIP": 0+  },+  "gui-driving": {+   "PASS": 9,+   "FAIL": 8,+   "MANUAL": 21,+   "SKIP": 0+  },+  "aps": {+   "PASS": 9,+   "FAIL": 0,+   "MANUAL": 13,+   "SKIP": 0+  },+  "mcp-server": {+   "PASS": 1,+   "FAIL": 0,+   "MANUAL": 1,+   "SKIP": 0+  },+  "cad-3d-bom": {+   "PASS": 8,+   "FAIL": 7,+   "MANUAL": 7,+   "SKIP": 0+  },+  "python-addin": {+   "PASS": 1,+   "FAIL": 5,+   "MANUAL": 1,+   "SKIP": 0+  },+  "exports": {+   "PASS": 0,+   "FAIL": 0,+   "MANUAL": 1,+   "SKIP": 0+  },+  "routing": {+   "PASS": 4,+   "FAIL": 0,+   "MANUAL": 16,+   "SKIP": 0+  }+ },+ "results": [+  {+   "verb": "fusion_readiness",+   "status": "PASS",+   "why": "",+   "sec": 0.7,+   "section": "bridge-lifecycle"+  },+  {+   "verb": "fusion_prewarm",+   "status": "PASS",+   "why": "",+   "sec": 0.7,+   "section": "bridge-lifecycle"+  },+  {+   "verb": "fusion_account",+   "status": "FAIL",+   "why": "expected success, got error='fusion_account' did not respond within ab's 60s budget. code=timed_out; missing field 'holdsSeat'; missing field 'running'",+   "sec": 60.2,+   "section": "auth-tokens"+  },+  {+   "verb": "fusion_claim_seat",+   "status": "MANUAL",+   "why": "moves the Autodesk seat between machines; suspends another box's Fusion",+   "section": "auth-tokens"+  },+  {+   "verb": "fusion_release_seat",+   "status": "MANUAL",+   "why": "closes Fusion on the box to free the seat",+   "section": "auth-tokens"+  },+  {+   "verb": "fusion_describe",+   "status": "PASS",+   "why": "",+   "sec": 0.3,+   "section": "bridge-lifecycle"+  },+  {+   "verb": "fusion_get_app_state",+   "status": "FAIL",+   "why": "expected success, got error=Main thread busy \u2014 activity_banner running for 106.1s. code=main_thread_busy",+   "sec": 64.8,+   "section": "gui-driving"+  },+  {+   "verb": "fusion_search_cloud_files",+   "status": "PASS",+   "why": "",+   "sec": 0.4,+   "section": "aps"+  },+  {+   "verb": "fusion_walk_cloud_tree",+   "status": "PASS",+   "why": "",+   "sec": 0.1,+   "section": "aps"+  },+  {+   "verb": "fusion_aps_status",+   "status": "PASS",+   "why": "",+   "sec": 0.1,+   "section": "auth-tokens"+  },+  {+   "verb": "fusion_aps_get_browser",+   "status": "PASS",+   "why": "",+   "sec": 0.1,+   "section": "aps"+  },+  {+   "verb": "fusion_aps_search",+   "status": "PASS",+   "why": "",+   "sec": 54.7,+   "section": "aps"+  },+  {+   "verb": "fusion_aps_recent",+   "status": "PASS",+   "why": "",+   "sec": 4.8,+   "section": "aps"+  },+  {+   "verb": "fusion_aps_browse",+   "status": "PASS",+   "why": "",+   "sec": 1.3,+   "section": "aps"+  },+  {+   "verb": "fusion_aps_file_info",+   "status": "PASS",+   "why": "",+   "sec": 28.6,+   "section": "aps"+  },+  {+   "verb": "fusion_aps_get",+   "status": "PASS",+   "why": "",+   "sec": 0.7,+   "section": "auth-tokens"+  },+  {+   "verb": "fusion_uninstall",+   "status": "PASS",+   "why": "",+   "sec": 0.2,+   "section": "bridge-lifecycle"+  },+  {+   "verb": "fusion_set_seat_takeover",+   "status": "PASS",+   "why": "",+   "sec": 0.1,+   "section": "bridge-lifecycle"+  },+  {+   "verb": "fusion_aps_create_folder",+   "status": "MANUAL",+   "why": "needs projectId/parentFolderId of the test workspace",+   "section": "aps"+  },+  {+   "verb": "fusion_aps_upload",+   "status": "MANUAL",+   "why": "cloud write; exercised via build flows weekly",+   "section": "aps"+  },+  {+   "verb": "fusion_aps_set_client_id",+   "status": "MANUAL",+   "why": "would clobber org auth config",+   "section": "auth-tokens"+  },+  {+   "verb": "fusion_aps_set_browser",+   "status": "MANUAL",+   "why": "",+   "section": "aps"+  },+  {+   "verb": "fusion_aps_forget_browser",+   "status": "MANUAL",+   "why": "",+   "section": "aps"+  },+  {+   "verb": "fusion_aps_signin",+   "status": "MANUAL",+   "why": "opens a browser on the user's machine",+   "section": "auth-tokens"+  },+  {+   "verb": "fusion_start",+   "status": "PASS",+   "why": "",+   "sec": 0.3,+   "section": "gui-driving"+  },+  {+   "verb": "fusion_get_preferences",+   "status": "FAIL",+   "why": "expected success, got error='fusion_get_preferences' did not respond within ab's 25s budget. code=timed_out; missing field 'current'",+   "sec": 25.1,+   "section": "gui-driving"+  },+  {+   "verb": "fusion_set_preference",+   "status": "FAIL",+   "why": "expected success, got error='fusion_set_preference' did not respond within ab's 40s budget. code=timed_out",+   "sec": 40.2,+   "section": "gui-driving"+  },+  {+   "verb": "fusion_mcp_status",+   "status": "PASS",+   "why": "",+   "sec": 0.3,+   "section": "mcp-server"+  },+  {+   "verb": "fusion_mcp_enable",+   "status": "MANUAL",+   "why": "drives the prefs UI, takes foreground",+   "section": "mcp-server"+  },+  {+   "verb": "fusion_prefs_open",+   "status": "MANUAL",+   "why": "opens a dialog on the user's screen",+   "section": "gui-driving"+  },+  {+   "verb": "fusion_prefs_close",+   "status": "MANUAL",+   "why": "",+   "section": "gui-driving"+  },+  {+   "verb": "fusion_set_auto_update",+   "status": "PASS",+   "why": "",+   "sec": 0.1,+   "section": "bridge-lifecycle"+  },+  {+   "verb": "fusion_assembly_bom",+   "status": "FAIL",+   "why": "expected a BOM or the budget refusal, got error='fusion_assembly_bom' did not respond within ab's 60s budget code=timed_out",+   "sec": 60.1,+   "section": "cad-3d-bom"+  },+  {+   "verb": "fusion_dismiss_blocking_dialogs",+   "status": "PASS",+   "why": "",+   "sec": 1.8,+   "section": "gui-driving"+  },+  {+   "verb": "fusion_open_cloud_file",+   "status": "FAIL",+   "why": "expected success, got error=None code=None; timed out",+   "sec": 258.6,+   "section": "gui-driving"+  },+  {+   "verb": "fusion_show_schematic",+   "status": "FAIL",+   "why": "expected success, got error='fusion_show_schematic' did not respond within ab's 60s budget. code=timed_out",+   "sec": 281.8,+   "section": "gui-driving"+  },+  {+   "verb": "fusion_show_2d_board",+   "status": "FAIL",+   "why": "expected success, got error='fusion_show_2d_board' did not respond within ab's 60s budget. code=timed_out",+   "sec": 60.2,+   "section": "gui-driving"+  },+  {+   "verb": "fusion_board_info",+   "status": "FAIL",+   "why": "expected success, got error=Add-in request failed: http://127.0.0.1:8774/command: Network Error: Network Err code=None; missing field 'rawXml'",+   "sec": 31.6,+   "section": "gui-driving"+  },+  {+   "verb": "fusion_open_electronics",+   "status": "FAIL",+   "why": "expected success, got error=Add-in request failed: http://127.0.0.1:8774/command: Network Error: Network Err code=None; missing field 'isElectronics'",+   "sec": 31.6,+   "section": "python-addin"+  },+  {+   "verb": "fusion_list_text_commands",+   "status": "FAIL",+   "why": "expected success, got error=Add-in request failed: http://127.0.0.1:8774/command: Network Error: Network Err code=None; missing field 'commands'",+   "sec": 31.7,+   "section": "python-addin"+  },+  {+   "verb": "fusion_execute_text_command",+   "status": "FAIL",+   "why": "expected success, got error='fusion_execute_text_command' did not respond within ab's 60s budget. code=timed_out",+   "sec": 60.2,+   "section": "python-addin"+  },+  {+   "verb": "fusion_show_3d_board",+   "status": "FAIL",+   "why": "expected success, got error='fusion_show_3d_board' did not respond within ab's 60s budget. code=timed_out",+   "sec": 60.2,+   "section": "gui-driving"+  },+  {+   "verb": "fusion_inspect_bodies",+   "status": "FAIL",+   "why": "expected success, got error='fusion_inspect_bodies' did not respond within ab's 60s budget. code=timed_out; missing field 'bodies'; missing field 'units'",+   "sec": 60.2,+   "section": "cad-3d-bom"+  },+  {+   "verb": "fusion_physical_properties",+   "status": "FAIL",+   "why": "expected success, got error='fusion_physical_properties' did not respond within ab's 60s budget. code=timed_out",+   "sec": 60.2,+   "section": "cad-3d-bom"+  },+  {+   "verb": "fusion_get_design_info",+   "status": "FAIL",+   "why": "expected success, got error=Add-in request failed: http://127.0.0.1:8774/command: Network Error: Network Err code=None",+   "sec": 31.6,+   "section": "cad-3d-bom"+  },+  {+   "verb": "fusion_get_parameters",+   "status": "FAIL",+   "why": "expected success, got error=Add-in request failed: http://127.0.0.1:8774/command: Network Error: Network Err code=None",+   "sec": 31.6,+   "section": "cad-3d-bom"+  },+  {+   "verb": "fusion_document_info",+   "status": "FAIL",+   "why": "expected success, got error=Main thread busy \u2014 activity_banner running for 293.0s. code=main_thread_busy",+   "sec": 79.8,+   "section": "cad-3d-bom"+  },+  {+   "verb": "fusion_delete_cloud_file#guard",+   "status": "PASS",+   "why": "",+   "sec": 33.0,+   "section": "aps"+  },+  {+   "verb": "fusion_delete_cloud_file",+   "status": "MANUAL",+   "why": "destructive cloud delete; only against files a rehearsal created",+   "section": "aps"+  },+  {+   "verb": "fusion_create_cloud_folder",+   "status": "MANUAL",+   "why": "cloud write into the team hub",+   "section": "aps"+  },+  {+   "verb": "fusion_set_parameter#guard",+   "status": "PASS",+   "why": "",+   "sec": 32.8,+   "section": "cad-3d-bom"+  },+  {+   "verb": "fusion_set_parameter",+   "status": "MANUAL",+   "why": "mutates the active design's parameters",+   "section": "cad-3d-bom"+  },+  {+   "verb": "fusion_run_modeling_script#guard",+   "status": "FAIL",+   "why": "expected errorCode=wrong_document got timed_out (error='fusion_run_modeling_script' did not respond within ab's 180)",+   "sec": 180.6,+   "section": "python-addin"+  },+  {+   "verb": "fusion_assembly_bom#guard",+   "status": "FAIL",+   "why": "expected errorCode=wrong_document got timed_out (error='fusion_assembly_bom' did not respond within ab's 60s budget)",+   "sec": 60.2,+   "section": "cad-3d-bom"+  },+  {+   "verb": "fusion_run_modeling_script",+   "status": "FAIL",+   "why": "expected success, got error='fusion_run_modeling_script' did not respond within ab's 180s budget. code=timed_out",+   "sec": 180.2,+   "section": "python-addin"+  },+  {+   "verb": "fusion_electron_select",+   "status": "MANUAL",+   "why": "selection state is user-visible",+   "section": "python-addin"+  },+  {+   "verb": "fusion_open_design",+   "status": "MANUAL",+   "why": "local-file open; superseded by cloud flows",+   "section": "gui-driving"+  },+  {+   "verb": "fusion_open_board",+   "status": "MANUAL",+   "why": "local .brd open; needs a .brd on the box (make_test_project exercises the same newDesignFromLocal path)",+   "section": "gui-driving"+  },+  {+   "verb": "fusion_open_schematic",+   "status": "MANUAL",+   "why": "local .sch open; needs a .sch on the box (make_test_project exercises the same newDesignFromLocal path)",+   "section": "gui-driving"+  },+  {+   "verb": "fusion_import_electronics",+   "status": "MANUAL",+   "why": "needs a Fusion-native .fsch/.fbrd/.flbr on the box; creates a NEW unsaved document",+   "section": "gui-driving"+  },+  {+   "verb": "fusion_close_window#noargs",+   "status": "PASS",+   "why": "",+   "sec": 0.2,+   "section": "gui-driving"+  },+  {+   "verb": "fusion_close_document",+   "status": "MANUAL",+   "why": "",+   "section": "gui-driving"+  },+  {+   "verb": "fusion_close_all_documents",+   "status": "MANUAL",+   "why": "would close the user's own tabs",+   "section": "gui-driving"+  },+  {+   "verb": "fusion_export_obj",+   "status": "MANUAL",+   "why": "build/doc-type dependent (OBJ refused on the 2026-08-14 box); verify quarterly",+   "section": "bridge-lifecycle"+  },+  {+   "verb": "fusion_export_fbx",+   "status": "MANUAL",+   "why": "build/doc-type dependent (OBJ refused on the 2026-08-14 box); verify quarterly",+   "section": "bridge-lifecycle"+  },+  {+   "verb": "fusion_export_usdz",+   "status": "MANUAL",+   "why": "build/doc-type dependent (OBJ refused on the 2026-08-14 box); verify quarterly",+   "section": "bridge-lifecycle"+  },+  {+   "verb": "fusion_export_dxf",+   "status": "MANUAL",+   "why": "build/doc-type dependent (OBJ refused on the 2026-08-14 box); verify quarterly",+   "section": "bridge-lifecycle"+  },+  {+   "verb": "fusion_export_dwg",+   "status": "MANUAL",+   "why": "build/doc-type dependent (OBJ refused on the 2026-08-14 box); verify quarterly",+   "section": "bridge-lifecycle"+  },+  {+   "verb": "fusion_export_skp",+   "status": "MANUAL",+   "why": "build/doc-type dependent (OBJ refused on the 2026-08-14 box); verify quarterly",+   "section": "bridge-lifecycle"+  },+  {+   "verb": "fusion_set_design_rules",+   "status": "MANUAL",+   "why": "mutates the board's DRC rules",+   "section": "exports"+  },+  {+   "verb": "fusion_show_3d_package",+   "status": "MANUAL",+   "why": "enters Package3DEnvironment (exit needs Package3DStop + dialog); tour covers it; attach path in release rehearsals",+   "section": "bridge-lifecycle"+  },+  {+   "verb": "fusion_bind_library_3d",+   "status": "MANUAL",+   "why": "cloud f3d mint per run; release rehearsals (needs signed-in session)",+   "section": "bridge-lifecycle"+  },+  {+   "verb": "fusion_attach_3d_package",+   "status": "MANUAL",+   "why": "modal Save dialog needs a human eye",+   "section": "gui-driving"+  },+  {+   "verb": "fusion_make_3d_package",+   "status": "MANUAL",+   "why": "cloud upload; run in release rehearsals",+   "section": "gui-driving"+  },+  {+   "verb": "fusion_build_library_3d",+   "status": "MANUAL",+   "why": "long multi-part build; release rehearsals",+   "section": "gui-driving"+  },+  {+   "verb": "fusion_cleanup_cloud_files#guard",+   "status": "PASS",+   "why": "",+   "sec": 2.9,+   "section": "aps"+  },+  {+   "verb": "fusion_cleanup_cloud_files",+   "status": "MANUAL",+   "why": "real cleanup takes explicit lineage urns; used by weekly build rehearsals",+   "section": "aps"+  },+  {+   "verb": "fusion_new_electronics_from_eagle",+   "status": "MANUAL",+   "why": "drives native dialogs",+   "section": "gui-driving"+  },+  {+   "verb": "fusion_screenshot_fusion",+   "status": "PASS",+   "why": "",+   "sec": 2.9,+   "section": "bridge-lifecycle"+  },+  {+   "verb": "fusion_state",+   "status": "PASS",+   "why": "",+   "sec": 27.1,+   "section": "gui-driving"+  },+  {+   "verb": "fusion_demo_progress#unknown",+   "status": "PASS",+   "why": "",+   "sec": 0.4,+   "section": "bridge-lifecycle"+  },+  {+   "verb": "fusion_stop",+   "status": "MANUAL",+   "why": "lifecycle/human-wall verbs; manual tier",+   "section": "gui-driving"+  },+  {+   "verb": "fusion_kill",+   "status": "MANUAL",+   "why": "lifecycle/human-wall verbs; manual tier",+   "section": "gui-driving"+  },+  {+   "verb": "fusion_signin",+   "status": "MANUAL",+   "why": "lifecycle/human-wall verbs; manual tier",+   "section": "gui-driving"+  },+  {+   "verb": "fusion_signin_2fa",+   "status": "MANUAL",+   "why": "lifecycle/human-wall verbs; manual tier",+   "section": "bridge-lifecycle"+  },+  {+   "verb": "fusion_demo",+   "status": "MANUAL",+   "why": "lifecycle/human-wall verbs; manual tier",+   "section": "gui-driving"+  },+  {+   "verb": "fusion_install_fusion",+   "status": "MANUAL",+   "why": "lifecycle/human-wall verbs; manual tier",+   "section": "bridge-lifecycle"+  },+  {+   "verb": "fusion_notify_owner",+   "status": "MANUAL",+   "why": "lifecycle/human-wall verbs; manual tier",+   "section": "bridge-lifecycle"+  },+  {+   "verb": "fusion_open_by_urn_note",+   "status": "MANUAL",+   "why": "lifecycle/human-wall verbs; manual tier",+   "section": "bridge-lifecycle"+  },+  {+   "verb": "fusion_action_ledger",+   "status": "PASS",+   "why": "",+   "sec": 0.2,+   "section": "bridge-lifecycle"+  },+  {+   "verb": "fusion_addin_status",+   "status": "PASS",+   "why": "",+   "sec": 0.3,+   "section": "python-addin"+  },+  {+   "verb": "fusion_alerts",+   "status": "PASS",+   "why": "",+   "sec": 0.3,+   "section": "gui-driving"+  },+  {+   "verb": "fusion_verb_times",+   "status": "PASS",+   "why": "",+   "sec": 0.3,+   "section": "bridge-lifecycle"+  },+  {+   "verb": "fusion_live_feed",+   "status": "PASS",+   "why": "",+   "sec": 0.2,+   "section": "bridge-lifecycle"+  },+  {+   "verb": "fusion_prove_result",+   "status": "PASS",+   "why": "",+   "sec": 0.5,+   "section": "cad-3d-bom"+  },+  {+   "verb": "fusion_set_driving_badge",+   "status": "PASS",+   "why": "",+   "sec": 0.3,+   "section": "bridge-lifecycle"+  },+  {+   "verb": "fusion_set_window_sizing",+   "status": "PASS",+   "why": "",+   "sec": 0.2,+   "section": "gui-driving"+  },+  {+   "verb": "fusion_cancel_run",+   "status": "PASS",+   "why": "",+   "sec": 0.7,+   "section": "cad-3d-bom"+  },+  {+   "verb": "fusion_preflight_lbr",+   "status": "PASS",+   "why": "",+   "sec": 0.2,+   "section": "cad-3d-bom"+  },+  {+   "verb": "fusion_library_parts",+   "status": "PASS",+   "why": "",+   "sec": 0.2,+   "section": "cad-3d-bom"+  },+  {+   "verb": "fusion_create_library",+   "status": "MANUAL",+   "why": "the five-part drill covers it (fusion_install_library_bundle -> prove)",+   "section": "cad-3d-bom"+  },+  {+   "verb": "fusion_install_library_bundle",+   "status": "MANUAL",+   "why": "the five-part drill covers it; needs a bundle zip on the box",+   "section": "cad-3d-bom"+  },+  {+   "verb": "fusion_managed_library_create",+   "status": "MANUAL",+   "why": "creates a managed library on the hub (cloud write)",+   "section": "aps"+  },+  {+   "verb": "fusion_managed_library_link",+   "status": "MANUAL",+   "why": "drives LIBRARY.IO dialogs against the hub",+   "section": "aps"+  },+  {+   "verb": "fusion_managed_library_pull",+   "status": "MANUAL",+   "why": "drives LIBRARY.IO dialogs against the hub",+   "section": "aps"+  },+  {+   "verb": "fusion_managed_library_push",+   "status": "MANUAL",+   "why": "drives LIBRARY.IO dialogs; cloud write",+   "section": "aps"+  },+  {+   "verb": "fusion_managed_library_unlink",+   "status": "MANUAL",+   "why": "drives LIBRARY.IO dialogs against the hub",+   "section": "aps"+  },+  {+   "verb": "fusion_reset_workspace",+   "status": "MANUAL",+   "why": "closes the user's documents",+   "section": "gui-driving"+  },+  {+   "verb": "fusion_restart_for_addin",+   "status": "MANUAL",+   "why": "restarts Fusion",+   "section": "bridge-lifecycle"+  },+  {+   "verb": "fusion_save_to_cloud",+   "status": "MANUAL",+   "why": "cloud write; exercised by the drills",+   "section": "aps"+  },+  {+   "verb": "fusion_web_signin",+   "status": "MANUAL",+   "why": "opens a browser on the user's machine",+   "section": "auth-tokens"+  },+  {+   "verb": "fusion_routing_state#guard",+   "status": "PASS",+   "why": "",+   "sec": 60.1,+   "section": "routing"+  },+  {+   "verb": "fusion_route_net#guard",+   "status": "PASS",+   "why": "",+   "sec": 60.4,+   "section": "routing"+  },+  {+   "verb": "fusion_routing_drc#guard",+   "status": "PASS",+   "why": "",+   "sec": 60.2,+   "section": "routing"+  },+  {+   "verb": "fusion_plan_route#guard",+   "status": "PASS",+   "why": "",+   "sec": 60.1,+   "section": "routing"+  },+  {+   "verb": "fusion_routing_state",+   "status": "MANUAL",+   "why": "live routing on a fixture board: demo/routing/run_demo.py is the weekly proof (needs a board open)",+   "section": "routing"+  },+  {+   "verb": "fusion_route_net",+   "status": "MANUAL",+   "why": "live routing on a fixture board: demo/routing/run_demo.py is the weekly proof (needs a board open)",+   "section": "routing"+  },+  {+   "verb": "fusion_routing_drc",+   "status": "MANUAL",+   "why": "live routing on a fixture board: demo/routing/run_demo.py is the weekly proof (needs a board open)",+   "section": "routing"+  },+  {+   "verb": "fusion_plan_route",+   "status": "MANUAL",+   "why": "live routing on a fixture board: demo/routing/run_demo.py is the weekly proof (needs a board open)",+   "section": "routing"+  },+  {+   "verb": "fusion_move_parts",+   "status": "MANUAL",+   "why": "live routing on a fixture board: demo/routing/run_demo.py is the weekly proof (needs a board open)",+   "section": "routing"+  },+  {+   "verb": "fusion_place_vias",+   "status": "MANUAL",+   "why": "live routing on a fixture board: demo/routing/run_demo.py is the weekly proof (needs a board open)",+   "section": "routing"+  },+  {+   "verb": "fusion_apply_pours",+   "status": "MANUAL",+   "why": "live routing on a fixture board: demo/routing/run_demo.py is the weekly proof (needs a board open)",+   "section": "routing"+  },+  {+   "verb": "fusion_pour_state",+   "status": "MANUAL",+   "why": "live routing on a fixture board: demo/routing/run_demo.py is the weekly proof (needs a board open)",+   "section": "routing"+  },+  {+   "verb": "fusion_board_source",+   "status": "MANUAL",+   "why": "live routing on a fixture board: demo/routing/run_demo.py is the weekly proof (needs a board open)",+   "section": "routing"+  },+  {+   "verb": "fusion_ripup_nets",+   "status": "MANUAL",+   "why": "live routing on a fixture board: demo/routing/run_demo.py is the weekly proof (needs a board open)",+   "section": "routing"+  },+  {+   "verb": "fusion_schematic_run",+   "status": "MANUAL",+   "why": "live routing on a fixture board: demo/routing/run_demo.py is the weekly proof (needs a board open)",+   "section": "routing"+  },+  {+   "verb": "fusion_board_bom",+   "status": "MANUAL",+   "why": "live routing on a fixture board: demo/routing/run_demo.py is the weekly proof (needs a board open)",+   "section": "routing"+  },+  {+   "verb": "fusion_change_pours",+   "status": "MANUAL",+   "why": "live routing on a fixture board: demo/routing/run_demo.py is the weekly proof (needs a board open)",+   "section": "routing"+  },+  {+   "verb": "fusion_board_seed",+   "status": "MANUAL",+   "why": "live routing on a fixture board: demo/routing/run_demo.py is the weekly proof (needs a board open)",+   "section": "routing"+  },+  {+   "verb": "fusion_schematic_plan",+   "status": "MANUAL",+   "why": "live routing on a fixture board: demo/routing/run_demo.py is the weekly proof (needs a board open)",+   "section": "routing"+  },+  {+   "verb": "fusion_remove_pours",+   "status": "MANUAL",+   "why": "live routing on a fixture board: demo/routing/run_demo.py is the weekly proof (needs a board open)",+   "section": "routing"+  },+  {+   "verb": "fusion_apply_fusion_update",+   "status": "MANUAL",+   "why": "lifecycle, seat or presentation verbs: need a human-visible Fusion state; manual tier",+   "section": "bridge-lifecycle"+  },+  {+   "verb": "fusion_resolve_seat_dialog",+   "status": "MANUAL",+   "why": "lifecycle, seat or presentation verbs: need a human-visible Fusion state; manual tier",+   "section": "bridge-lifecycle"+  },+  {+   "verb": "fusion_interactive",+   "status": "MANUAL",+   "why": "lifecycle, seat or presentation verbs: need a human-visible Fusion state; manual tier",+   "section": "gui-driving"+  },+  {+   "verb": "fusion_narrate",+   "status": "MANUAL",+   "why": "lifecycle, seat or presentation verbs: need a human-visible Fusion state; manual tier",+   "section": "gui-driving"+  },+  {+   "verb": "fusion_view",+   "status": "MANUAL",+   "why": "lifecycle, seat or presentation verbs: need a human-visible Fusion state; manual tier",+   "section": "gui-driving"+  },+  {+   "verb": "fusion_electronics_query",+   "status": "MANUAL",+   "why": "lifecycle, seat or presentation verbs: need a human-visible Fusion state; manual tier",+   "section": "cad-3d-bom"+  },+  {+   "verb": "fusion_schematic#guard",+   "status": "PASS",+   "why": "",+   "sec": 2.8,+   "section": "gui-driving"+  },+  {+   "verb": "fusion_schematic#missing",+   "status": "PASS",+   "why": "",+   "sec": 55.3,+   "section": "gui-driving"+  },+  {+   "verb": "fusion_schematic",+   "status": "MANUAL",+   "why": "open a cloud design's schematic / create a blank one: exercised by the weekly tour",+   "section": "gui-driving"+  },+  {+   "verb": "fusion_make_showcase_project#guard",+   "status": "PASS",+   "why": "",+   "sec": 3.4,+   "section": "cad-3d-bom"+  },+  {+   "verb": "fusion_make_showcase_project",+   "status": "MANUAL",+   "why": "places a library's parts on a fresh sch+brd; exercised on the Adom_ToF library",+   "section": "cad-3d-bom"+  },+  {+   "verb": "fusion_eagle_import_status#guard",+   "status": "PASS",+   "why": "",+   "sec": 2.4,+   "section": "cad-3d-bom"+  },+  {+   "verb": "fusion_eagle_import_status",+   "status": "MANUAL",+   "why": "status of a background EAGLE import",+   "section": "cad-3d-bom"+  },+  {+   "verb": "fusion_show_attributes#guard",+   "status": "PASS",+   "why": "",+   "sec": 3.3,+   "section": "cad-3d-bom"+  },+  {+   "verb": "fusion_show_attributes",+   "status": "MANUAL",+   "why": "opens the device editor for a deviceset and returns its metadata",+   "section": "cad-3d-bom"+  },+  {+   "verb": "focus_invariance",+   "status": "PASS",+   "why": "",+   "section": "gui-driving"+  }+ ],+ "durationSec": 2437.4+}\ No newline at end of file
tools/check-naming.sh

  
tools/check-portable.sh

  
tools/promote.sh

  
tools/promotions.log+1
@@ -12,3 +12,4 @@ 2026-09-29T11:42:01Z	promoted 1.11.9	attest: run the suite and promote it 2026-10-06T12:44:55Z	promoted 1.11.32	attest: yes, promote fusion bridge 2026-10-06T14:51:42Z	promoted 1.11.39	attest: do it (in reply to: promote Fusion bridge 1.11.39 to public?)+2026-10-18T13:30:56Z	promoted 1.11.42	attest: John, 2026-10-18, asked 'Should I promote 1.11.42 to public?': yes
tools/release.sh