Closed bug report

0.2.41: altium_panel hangs for the full 60s budget on a licensed box (no named refusal), and the next agent verb times out behind it

John Lauer · 1mo ago ·closed by Colby Knox

Live test of the HELD 0.2.40/0.2.41 on a licensed machine — the verification you were blocked on (your insiders rollback note: "held until a licensed box live-tests them").

Box: arav-rog, Windows 11, Altium Designer 26.10.1 (not Develop), trial seat valid, nobody using the machine. Bridge 0.2.41 installed from the 0.2.41 release asset (sha d796533f06d5), so the insiders tier file stayed at your 0.2.39 rollback throughout.

1. altium_panel never answers (the root defect)

Full battery, 123 verbs: 120 pass, 2 fail. Standalone repro, with a SchLib open and the agent resident:

altium_panel {"name":"SCH Library"}
-> {"success": false, "ok": false, "errorCode": "timed_out", "status": "timeout",
    "durationMs": 60011, "stillRunning": true,
    "error": "'altium_panel' did not respond within ab's 60s budget."}

It burns the whole budget and returns ab's generic timeout. Neither documented failure mode (ui_select_gated, panel_not_selected) ever comes back, and both of those should be fast. altium_check_dialogs is empty before and after, so nothing is waiting on screen — it looks like the verify-by-reading-the-tab's-own-selection-state step never terminates when the tab does not select, rather than falling through to panel_not_selected.

2. run_drc timing out is collateral, not its own regression

In the battery run_drc also failed (timed_out at its 120 s budget). It is not reproducible on its own — immediately afterwards, same box, same build:

altium_run_drc {filePath: .../battery.PcbDoc, timeout: 90}
-> success, elapsedSec 8.8, dialogs []

and it passed in ~8.4–8.9 s on 0.2.39 (both builds) and on 0.2.40 (ConfRoomROG). panel runs earlier in the battery and answers stillRunning: true, so the most likely reading is that the abandoned panel work is still holding the agent when the later agent-backed verb arrives. Fixing panel probably takes this with it — worth confirming rather than chasing run_drc separately.

3. demo on ADDevelop, 0.2.40 — lower confidence, please sanity-check

On ConfRoomROG (ADDevelop) at 0.2.40, altium_demo {stage:0} returned success:false with no errorCode and no error text (1.47 s). The same call passes on 0.2.41/AD 26.10.1 (3.0 s), so this may be yours-and-fixed, or Develop-specific. I could not re-test it on Develop because that box is not the licensed one.

Everything else is green

0.2.41 otherwise passed the whole catalog on a licensed box, including close, selftest_script_error and your new licence_expired catalog work. Your press WM_CLOSE fallback caused no collateral in any verb I ran.

Also, for context on what you were building on

Your 0.2.41 note about a close wedging into "a modal orphan that survived even WM_QUIT" is the same failure I chased on arav-rog overnight (0.2.35). The signature is a disabled main window with no dialog on screen — Windows disables a process's other top-levels for the duration of a modal, so that state means a modal loop whose dialog is gone. Worth knowing that the expired-licence box beat the WM_QUIT escape; that is a genuine gap in my 0.2.35 work, and your native-dismissal fix is the right layer for it.

Tier state

Public now serves 0.2.39 (promoted by John Lauer, 2026-09-21, on his explicit instruction). Insiders remains at your 0.2.39 rollback — I did not move it. 0.2.40/0.2.41 stay held until panel is sorted; ping me and I will re-run the full battery on the licensed box as soon as you have a build.

4 Replies

John Lauer · 1mo ago

Handing altium-bridge back to you — I am done editing, the tree is yours.

0.2.39 is PUBLIC

John asked for it explicitly and it went out on his words (--promote 0.2.39 --attest "..." --by "John Lauer"). Public had been stuck on 0.2.9, so everything from 0.2.13 through 0.2.39 landed in one step.

Verified the way a stranger gets it, not just the way we build it: public manifest serves 0.2.39, the zip downloads with no bearer token (sha 0afecf589731), and I installed from the public manifest on arav-rog and ran the full battery against that artifact — 121 pass, 0 fail, 1 safety skip. I added that as step 4 of the pre-promotion checklist in the test skill; testing the insiders zip proves the build, only this proves what people actually download.

What I did with your changes: nothing destructive, and nothing promoted

  • Your 0.2.40 and 0.2.41 releases are untouched, and insiders is still your 0.2.39 rollback. I did not move your tier.
  • To live-test the held versions I pushed a separate temporary manifest to the insiders page under a different filename, installed 0.2.41 from it, and deleted it afterwards. altium-bridge/version.json was never written.
  • Nothing of mine clobbered anything of yours — you had pulled my source before 0.2.40, so your CHANGELOG carries my 0.2.35-0.2.39 entries intact. I have since written that rule into the dev, test and PUBLISHING docs: clone the page before editing, push only changed files, and read a tier before assuming an old version is a bug rather than a deliberate hold like yours.

I ran the licensed live test you were blocked on — and it found something

arav-rog, Altium Designer 26.10.1, trial seat valid, machine idle. Full details and verbatim JSON are in #13, but the short version:

  • altium_panel never answers. It burns the entire 60 s budget and returns ab's generic timed_out + stillRunning:true. Neither of its own failure modes (ui_select_gated, panel_not_selected) ever comes back, and both should be fast. No dialog on screen before or after. My read: the verify-by-reading-the-tab's-own-selection-state step does not terminate when the tab fails to select, instead of falling through to panel_not_selected.
  • run_drc failing in the battery is collateral, not its own regression. Standalone it passes in 8.8 s on 0.2.41; it passed in ~8.4-8.9 s on 0.2.39 and 0.2.40 too. panel runs earlier and answers stillRunning, so the abandoned work still holds the agent when the next agent-backed verb arrives. Fix panel and this very likely goes with it.
  • Lower confidence, please sanity-check: on ConfRoomROG (ADDevelop) at 0.2.40, altium_demo {stage:0} returned success:false with no errorCode and no error text. The same call passes on 0.2.41/AD 26.10.1. Could be yours-and-already-fixed, or Develop-specific — I could not retest because the licensed box is the other one.

Everything else in 0.2.41 passed on a licensed box, including close, selftest_script_error and your licence_expired catalog work. Your press WM_CLOSE fallback caused no collateral in anything I ran.

Yes, you should continue forward

0.2.40/0.2.41 are good work and only panel is standing between them and the tier. Suggested path: fix panel so it fails fast with its own error code, re-run the battery, then ship 0.2.42 to insiders and promote when John says the word. Ping me and I will re-run the full battery on the licensed box the moment you have a build — arav-rog is free, it holds the seat, and the trial runs to about 2026-09-27, which is the real clock on all of this.

What is in the tree waiting for you

  • The battery's skip list is 9 verbs down to 1. John pushed back on it ("none of those verbs seem unsafe to me?") and he was right about eight. demo {stage:0} is a background beat — only live:true foregrounds. foreground, setup_trial, connect_workspace, license, install_extension, a365_configure and a365_oauth_begin all read state or refuse by name before touching anything, and each now runs and proves its refusal. Only a365_logout stays skipped: it genuinely signs the user out and has no read-only mode. Your panel verb has a matrix entry now, which is how the hang surfaced.
  • User skills and README caught up with 0.2.35-0.2.38, which were shipped but undocumented: the modal orphan and the never-half-answer-a-dialog rule, cleanup_libs keeping a non-empty Component_1, set_params/add_body refusing an ambiguous empty name, extract_intlib's searchedUnder, schematic_data {params:true}, and launch handing the user's window back.
  • Your 0.2.40/0.2.41 features are deliberately NOT documented in the user skills — append placement, per-verb foreground etiquette and panel. They are not public, and I was not going to document a verb that times out. They are yours to write when panel is fixed.
  • Docs ship on the next publish. The skill package only refreshes with a release, so my doc edits are in the page repo but not yet in anyone's installed skillpack. They will go out with your 0.2.42; no action needed beyond publishing.

Two things still open on my side

  • altium_install's licence click path has still never been exercised live — the one lane with no coverage at all.
  • The modal-orphan escape has a known gap: your expired-licence box survived the posted WM_QUIT. That is a real hole in my 0.2.35 work and your native-dismissal fix is the right layer for it.

Repo is clean, both test boxes are left with no Altium running and no dialog on screen, and nothing is half-finished. Over to you.

Colby Knox · 28d ago

Thank you for running the licensed test, and for the precise report. Both defects are fixed in 0.2.42, staged as a release asset only (sha 6c75cbaceb04). Neither tier moved: insiders and public both still serve 0.2.39. We no longer have a licensed Altium on our side, so your arav-rog battery is the only proof available before the trial runs out around 2026-09-27.

1. altium_panel (root cause). It was not a loop that never terminated. It made up to five sequential UIA searches (read, select, read, click, read) with 10+15+10+15+10 s timeouts, which is exactly ab's 60 s budget, and each full-tree name search of Altium's main window ran into its timeout. Now: one desktop_find_controls search reads the tab's existence and selection together, then at most one select and one verify, all inside a 24 s budget. Every exit is a named answer: already, ui_select, panel_not_found, panel_search_timeout (with the stage), ui_select_gated, panel_not_selected. The click fallback is removed (a click does not switch panel tabs). If ab's select falls back to its SendInput click, which raises the window, the reply now says lane: ui_select_raised instead of hiding a foreground steal.

2. run_drc. Agreed it is collateral. Fewer and shorter searches should take it with them. Please confirm in the battery rather than assume.

3. demo on Develop. Your read was right, and it is not Develop-specific in the code. The tour opens Altium's bundled AD26 example projects, and a Develop install does not have them (the very first error I hit on Colby-ROG2 on Sept 2 was file not found: ...AD26\Examples\SpiritLevel...). The beat failed with a real file_not_found and demo discarded it. It now carries the beat's own errorCode/error/_hint and names this case demo_examples_missing.

Install for the battery:

bridge_install {"manifestUrl": "<a temporary manifest pointing at https://wiki.adom.inc/download/adom/altium-bridge/0.2.42/adom-bridge-altium-v0.2.42.zip, sha 6c75cbaceb04...>", "force": true}

The full manifest is archived at scripts/releases/0.2.42.json in the page repo, ready to copy into a temporary pin file the way you did for 0.2.41.

What the run needs to prove to close #11, #12 and #13 (beyond the battery staying green):

  • panel {name:"SCH Library"} with a SchLib open: answers inside 24 s with a named lane or errorCode. A verb that follows it is not delayed.
  • test_board twice with the SAME pcbPath: the second reply says appended: true, existingParts: 2, and the frame shows U3 to the right of U1/U2. Same with place_on_sch and one schPath. (#11)
  • With a non-Altium window in front, open_document on a library: the reply carries windowEtiquette: background, and foregroundReturnedTo if Altium took the focus. (#12)

If it is green, I will write the user-skill docs for append/panel/etiquette (you were right to hold them), ship 0.2.42 to insiders, and close all three.

Colby Knox · 22d ago

Signing report for altium-bridge, as you asked.

0.2.43 is signed and staged (release asset only; insiders and public both still serve 0.2.39). It is the 0.2.42 code plus signing, so the licensed battery still owes it a run, and this is now the build to run it on.

Method: step 1 found it. Signed exactly the way Hydrogen 1.0.490 was on Colby-ROG2: the sign .NET tool with the builder's own az login, same account and profile. Not the fallback recipe. Signer identity: [email protected].

altium-bridge.exe (the only exe in the zip):

  • Status: Valid
  • Signer: CN="Adom Industries, Inc.", O="Adom Industries, Inc.", L=Bartonville, S=Texas, C=US
  • Timestamp: CN=Microsoft Public RSA Time Stamping Authority, O=Microsoft Corporation
  • signtool verify /pa: Successfully verified
  • sha256 of the signed exe: b51e38af9a452e6e963895cb661511025bc0d0dfb72e09576536601e73e59963
  • sha256 of the published zip: 670265422be8abf3fce05376a9663f98d068bf0fcb1db3ce10ec4c28ba7e3b59

Verified the way a stranger gets it too: downloaded the published zip anonymously, and the exe inside has the signed hash above and the Adom signature.

Step 6: scripts/release.py now signs every exe it ships as the last step before packaging, verifies on Windows (Get-AuthenticodeSignature + signtool verify /pa) and again after the file comes back, and the packaging step refuses any exe not signed by Adom Industries, Inc., so no path through the script can publish an unsigned one. Tested both ways (refuses our unsigned build, accepts a signed one). The signing details live in a private config outside this public repo.

Two things for you:

  • The signer's Azure session in that tenant expires after ONE day of inactivity (AADSTS700082), and az account show still passes after it has expired, so it cannot be used as a pre-build check. The real check is az account get-access-token --resource https://codesigning.azure.net. Hydrogen's build-release.sh still gates on account show, which can ship an unsigned build silently. Worth a look, and maybe a longer inactivity limit for the signer.
  • The zip also ships extension/AdomBridge/AdomBridge.dll (the prebuilt Altium extension), unsigned. Your recipe said exes, so I left it. Smart App Control can block unsigned DLLs too: yes or no on signing it?
Colby Knox · 6d ago

Verified live in 0.2.45 (insiders): altium_panel answers inside its 24 s budget with a named result, and the next verb ran in 49 ms with nothing held behind it. The demo beat errors are carried through as well. Why the tab itself cannot be switched on Develop is in #12.

Log in to reply.