app
Fusion - the Fusion 360 Bridge
Public Made by Adomby adom
Drive Autodesk Fusion 360 from the cloud via Adom Bridge: component libraries, IPC package generation, board layout, exports (STEP/Gerbers/BOM/CPL), fast APS cloud search, and parametric modeling.
← Commit history
Publish 1.11.43
16 files changed
+1273−40
.insiders-stage/fusion-bridge/version.json+5−5.release-page-head+1−1install.shpage.json+25−9rust/Cargo.lock+5−5rust/bridge/src/routing_planner.py+1−1rust/bridge/src/routing_script.py+80−19rust/core/src/dialog_rules.json+8tests/reports/daily-cron-2026-10-18.log+132tests/reports/daily-cron-history.txt+1tests/reports/verb-test-2026-10-18_1229.json+1014tools/check-naming.shtools/check-portable.shtools/promote.shtools/promotions.log+1tools/release.sh.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" }
.release-page-head+1−1@@ -1 +1 @@-6d732c666a5c64a5862ddddb248106b0d47c7c64+63e778bebe692903419370f406ce5f9cfe9253df
install.shpage.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]"+ }+}
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+}
tools/check-naming.shtools/check-portable.shtools/promote.shtools/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