Altium - the Altium Bridge
Public Made by Adomby adom
Adom Bridge for Altium Designer: a resident DelphiScript agent gives the AI eval, the 1,100-command process launcher, all 8 EDA surfaces with screenshots, compile/ERC, DRC, OutJob outputs, native SchLib/PcbLib authoring with STEP 3D bodies, and dialog handling by PID.
main
4b57946
1mo ago
name: altium-bridge-test description: "DEVELOPER-only skill (user-invocable:false). The standard end-to-end verb battery for the Altium bridge: one runner that exercises EVERY altium_* verb in the live catalog against a real Altium on a real Windows box, on scratch copies of three test parts (leaded SOIC-8, QFN-24 with 9 heatsink vias, BGA-36). Coverage-enforced: a new verb with no entry turns the run red. Run it before every promotion to the public tier, after any change to the agent template or agent.rs/dialogs.rs, and once on every new Altium build or machine. Trigger words - test the altium bridge, altium verb test, verb battery, test all altium verbs, regression test altium, pre-release check altium, is altium-bridge safe to promote, run_verb_tests." user-invocable: false
The altium-bridge verb battery
dev-skills/altium-bridge-test/run_verb_tests.py drives every altium_* verb the LIVE bridge
declares (altium_describe.allVerbs) through adom-bridge --target <box>, the way a user's AI
does, and prints one line per verb plus a summary. It exists because of 2026-09-20: 0.2.20 looked
finished on the machine it was written on, and the first verb tried on a second machine parked
Altium on a script breakpoint. One machine and the verbs you happened to touch prove nothing.
python3 dev-skills/altium-bridge-test/run_verb_tests.py --target <machine> --thread "<your ai thread>"
[--only verb1,verb2] # re-run a few
[--keep-open] # do NOT close Altium at the end (default closes it: see Seats)
[--json report.json]
Exit code 0 only when there are no FAILs and no uncovered verbs.
What a result means
| Outcome | Meaning |
|---|---|
| PASS ok | the verb answered success:true (and its check, when the entry has one: pin counts, 9 via holes, 3 parts placed, netWorks:true) |
| PASS refused | the verb answered success:false WITH a named reason. For verbs whose real inputs the battery does not have (an OutJob, an IntLib, an Altium 365 token, a project) a fast, named refusal is the contract under test |
| SKIP | never run, reason printed. Exactly ONE verb: a365_logout, which really does sign the user out of Altium 365 on a configured machine and has no read-only mode |
| FAIL | a timeout or transport error (the bridge wedged), success:false with NO reason, the wrong outcome for the entry, or a dialog left on the user's screen after the verb (checked after every verb with altium_check_dialogs) |
The dialog check is the point of the whole thing: John's rule is that a dialog the user has to dismiss is a defect. A verb that "worked" and left a box up fails the battery.
Safety
- It only ever touches scratch copies in
<Documents>/Adom/altium-bridge-batteryon the target (Battery.SchLib,Battery.PcbLib,battery.SchDoc,battery.PcbDoc), rebuilt fromfixtures/on every run. It never opens or saves a user document. uninstallruns withdryRun:trueonly;ensure_licensedruns with defaults only (never signs out, never starts a trial).- Seats. An Altium 365 workspace has a fixed number of Author seats. An Altium left running on
a test box starves every other machine into view-only mode, where new documents silently refuse
to open (
view_only_no_author_seat). The battery therefore ENDS withagent_stop+close. Use--keep-openonly when you are about to keep working on that box, and never run the battery on two machines of the same workspace at once. selftest_script_errorflashes one Altium error box for under a second. Do not run the battery while someone is mid-edit in Altium on that machine.
The skip list is one verb, and stays that way
It used to hold nine. They were skipped when the only Altium lived on a machine someone was working on, and the reasons did not survive contact with a dedicated test box (John, 2026-09-21: "none of those verbs seem unsafe to me?" — he was right about eight of them). Each one either reads state or refuses by name BEFORE it touches anything, and proving that refusal is the whole point of a battery:
| Verb | What it actually does here |
|---|---|
demo |
stage:0 is a BACKGROUND beat with a screenshot. Only demo {live:true} takes the foreground, and that is not run |
foreground |
raises Altium on a box the runner already proved idle — run it last in phase 5 |
setup_trial |
with Altium CLOSED (phase 0) it reports the next action; the stage that could start a trial needs a signed-in, UNLICENSED Altium running |
connect_workspace |
with Altium closed it is a clean altium_not_running refusal, so the workspace picker never opens |
license |
an unknown action proves the dispatch and the named refusal; use_license / start_trial / sign_out are deliberately NOT exercised — the seat is shared and single |
install_extension |
Altium is running by phase 2, and the verb refuses in that state (it holds AdomBridge.dll open) |
a365_configure |
validates before it writes: no workspace = a named refusal, config untouched |
a365_oauth_begin |
validates before it opens anything: no workspace configured = a365_workspace_required |
Before you add a tenth skip, check whether the verb has a read-only mode, a safe stage, or a state in
which it refuses by name. install (stage preflight), uninstall (dryRun) and ensure_licensed
(defaults) all earn their coverage that way. A skip is an admission the contract is untested.
Adding a verb
Add the verb to src/bridge.json + verbs.rs as usual, then add ONE entry to matrix() in the
runner: the phase, real args against the scratch fixtures, and expect (ok / refuse / any /
skip with a SAFETY reason). Prefer ok with a check. Use refuse when the battery cannot
supply the input; never use skip to dodge a verb that is merely awkward to test.
Fixtures
fixtures/Adom_Test.SchLib + .PcbLib are built from the TST_*-fp.json / TST_*-sym.json create
files beside them (adom-footprint + adom-symbol, then adom-lbr import-kicad and
adom-lbr assemble-altium --no-dedupe). Three deliberately different packages: gull-wing leads, an
exposed pad with heatsink vias, an alphanumeric ball grid. Rebuild them when adom-lbr's Altium
writer changes, so the battery also covers that lane.
Before promoting to the public tier
- Battery green on at least TWO Altium builds (today: Altium Designer 26.x and Altium Designer
Develop behave differently on script errors; see
outcomeonselftest_script_error). - Battery green on a machine that is NOT the one the change was written on.
- Ideally once on a from-scratch Windows install (the install lane is the first thing a public user touches and the battery assumes Altium is already there).
- Then run it once more against the PROMOTED artifact, installed from the PUBLIC manifest the
way a new user would (
bridge_install {manifestUrl: ".../adom-bridge-altium-manifest.json"}). Testing the insiders zip proves the build; only this proves the thing strangers actually download. Done for 0.2.39 on 2026-09-21: 121 pass / 0 fail / 1 safety skip.
Promotion itself is never the AI's call. release.py --promote refuses without the human's own
words (--attest, 8+ chars, no placeholder). Quote them verbatim — they are the audit trail for why
the public tier moved.
Someone else may be shipping this bridge too. Colby works on it in parallel. adom-wiki repo clone the page before editing and push only the files you changed, or you will revert releases that
are newer than your tree. Check adom-wiki repo log adom/altium-bridge and the insiders
version.json first: a tier can be deliberately rolled BACK (he held 0.2.40/0.2.41 there on
2026-09-21 for want of a licensed box), and that is not a bug to "fix".
---
name: altium-bridge-test
description: "DEVELOPER-only skill (user-invocable:false). The standard end-to-end verb battery for the Altium bridge: one runner that exercises EVERY altium_* verb in the live catalog against a real Altium on a real Windows box, on scratch copies of three test parts (leaded SOIC-8, QFN-24 with 9 heatsink vias, BGA-36). Coverage-enforced: a new verb with no entry turns the run red. Run it before every promotion to the public tier, after any change to the agent template or agent.rs/dialogs.rs, and once on every new Altium build or machine. Trigger words - test the altium bridge, altium verb test, verb battery, test all altium verbs, regression test altium, pre-release check altium, is altium-bridge safe to promote, run_verb_tests."
user-invocable: false
---
# The altium-bridge verb battery
`dev-skills/altium-bridge-test/run_verb_tests.py` drives every `altium_*` verb the LIVE bridge
declares (`altium_describe.allVerbs`) through `adom-bridge --target <box>`, the way a user's AI
does, and prints one line per verb plus a summary. It exists because of 2026-09-20: 0.2.20 looked
finished on the machine it was written on, and the first verb tried on a second machine parked
Altium on a script breakpoint. One machine and the verbs you happened to touch prove nothing.
```
python3 dev-skills/altium-bridge-test/run_verb_tests.py --target <machine> --thread "<your ai thread>"
[--only verb1,verb2] # re-run a few
[--keep-open] # do NOT close Altium at the end (default closes it: see Seats)
[--json report.json]
```
Exit code 0 only when there are no FAILs and no uncovered verbs.
## What a result means
| Outcome | Meaning |
|---|---|
| PASS ok | the verb answered `success:true` (and its `check`, when the entry has one: pin counts, 9 via holes, 3 parts placed, `netWorks:true`) |
| PASS refused | the verb answered `success:false` WITH a named reason. For verbs whose real inputs the battery does not have (an OutJob, an IntLib, an Altium 365 token, a project) a fast, named refusal is the contract under test |
| SKIP | never run, reason printed. Exactly ONE verb: `a365_logout`, which really does sign the user out of Altium 365 on a configured machine and has no read-only mode |
| FAIL | a timeout or transport error (the bridge wedged), `success:false` with NO reason, the wrong outcome for the entry, or **a dialog left on the user's screen after the verb** (checked after every verb with `altium_check_dialogs`) |
The dialog check is the point of the whole thing: John's rule is that a dialog the user has to
dismiss is a defect. A verb that "worked" and left a box up fails the battery.
## Safety
- It only ever touches scratch copies in `<Documents>/Adom/altium-bridge-battery` on the target
(`Battery.SchLib`, `Battery.PcbLib`, `battery.SchDoc`, `battery.PcbDoc`), rebuilt from
`fixtures/` on every run. It never opens or saves a user document.
- `uninstall` runs with `dryRun:true` only; `ensure_licensed` runs with defaults only (never signs
out, never starts a trial).
- **Seats.** An Altium 365 workspace has a fixed number of Author seats. An Altium left running on
a test box starves every other machine into view-only mode, where new documents silently refuse
to open (`view_only_no_author_seat`). The battery therefore ENDS with `agent_stop` + `close`.
Use `--keep-open` only when you are about to keep working on that box, and never run the battery
on two machines of the same workspace at once.
- `selftest_script_error` flashes one Altium error box for under a second. Do not run the battery
while someone is mid-edit in Altium on that machine.
## The skip list is one verb, and stays that way
It used to hold nine. They were skipped when the only Altium lived on a machine someone was working
on, and the reasons did not survive contact with a dedicated test box (John, 2026-09-21: *"none of
those verbs seem unsafe to me?"* — he was right about eight of them). Each one either reads state or
refuses by name BEFORE it touches anything, and proving that refusal is the whole point of a battery:
| Verb | What it actually does here |
|---|---|
| `demo` | `stage:0` is a BACKGROUND beat with a screenshot. Only `demo {live:true}` takes the foreground, and that is not run |
| `foreground` | raises Altium on a box the runner already proved idle — run it last in phase 5 |
| `setup_trial` | with Altium CLOSED (phase 0) it reports the next action; the stage that could start a trial needs a signed-in, UNLICENSED Altium running |
| `connect_workspace` | with Altium closed it is a clean `altium_not_running` refusal, so the workspace picker never opens |
| `license` | an unknown action proves the dispatch and the named refusal; `use_license` / `start_trial` / `sign_out` are deliberately NOT exercised — the seat is shared and single |
| `install_extension` | Altium is running by phase 2, and the verb refuses in that state (it holds AdomBridge.dll open) |
| `a365_configure` | validates before it writes: no workspace = a named refusal, config untouched |
| `a365_oauth_begin` | validates before it opens anything: no workspace configured = `a365_workspace_required` |
Before you add a tenth skip, check whether the verb has a read-only mode, a safe stage, or a state in
which it refuses by name. `install` (stage `preflight`), `uninstall` (`dryRun`) and `ensure_licensed`
(defaults) all earn their coverage that way. A skip is an admission the contract is untested.
## Adding a verb
Add the verb to `src/bridge.json` + `verbs.rs` as usual, then add ONE entry to `matrix()` in the
runner: the phase, real args against the scratch fixtures, and `expect` (`ok` / `refuse` / `any` /
`skip` with a SAFETY reason). Prefer `ok` with a `check`. Use `refuse` when the battery cannot
supply the input; never use `skip` to dodge a verb that is merely awkward to test.
## Fixtures
`fixtures/Adom_Test.SchLib` + `.PcbLib` are built from the `TST_*-fp.json` / `TST_*-sym.json` create
files beside them (adom-footprint + adom-symbol, then `adom-lbr import-kicad` and
`adom-lbr assemble-altium --no-dedupe`). Three deliberately different packages: gull-wing leads, an
exposed pad with heatsink vias, an alphanumeric ball grid. Rebuild them when adom-lbr's Altium
writer changes, so the battery also covers that lane.
## Before promoting to the public tier
1. Battery green on at least TWO Altium builds (today: Altium Designer 26.x and Altium Designer
Develop behave differently on script errors; see `outcome` on `selftest_script_error`).
2. Battery green on a machine that is NOT the one the change was written on.
3. Ideally once on a from-scratch Windows install (the install lane is the first thing a public
user touches and the battery assumes Altium is already there).
4. **Then run it once more against the PROMOTED artifact**, installed from the PUBLIC manifest the
way a new user would (`bridge_install {manifestUrl: ".../adom-bridge-altium-manifest.json"}`).
Testing the insiders zip proves the build; only this proves the thing strangers actually download.
Done for 0.2.39 on 2026-09-21: 121 pass / 0 fail / 1 safety skip.
**Promotion itself is never the AI's call.** `release.py --promote` refuses without the human's own
words (`--attest`, 8+ chars, no placeholder). Quote them verbatim — they are the audit trail for why
the public tier moved.
**Someone else may be shipping this bridge too.** Colby works on it in parallel. `adom-wiki repo
clone` the page before editing and push only the files you changed, or you will revert releases that
are newer than your tree. Check `adom-wiki repo log adom/altium-bridge` and the insiders
`version.json` first: a tier can be deliberately rolled BACK (he held 0.2.40/0.2.41 there on
2026-09-21 for want of a licensed box), and that is not a bug to "fix".