Everything else on this bench is a file copied onto a disk before the Amiga boots. That gets you a disk that ought to work. It does not tell you that it does, and the Amiga has a long history of disks that ought to work: a preference file in the wrong version, a monitor for the wrong card, a palette that reaches four pens and not eight. For twenty years the check has been a person looking at the screen. Intune and Jamf did not just push the files to the laptop; they reported back. That is the missing half.
AmiPilot is the report-back. It is two programs. One runs on the Amiga, a commodity called AmiPilotServer, which walks the operating system’s own list of screens, windows and gadgets and can act on them with real synthesised input: click this button, type into that string gadget, pick that menu item, drag this window. The other runs on the host, a Python client, which talks to the server over a serial link or TCP and asks it questions. Find me the window titled ScreenMode Preferences. Find the gadget labelled Width. What does it say? Press Use. Give me a picture of the screen. Selenium, for a machine that predates the web.
Not by pixels. By asking the operating system what it thinks is on the screen, then acting on that.
The distinction is the whole value. A screenshot can tell you a window is open; it cannot tell you the Width field reads 640, and it certainly cannot press the button. AmiPilot reads the number and presses the button, and the picture at the top of this page is one it took of itself doing so, early on. The project is published on GitHub under the name sidick, at version 1.1 as this is written, and it runs on anything from AmigaOS 2.04 on a plain 68000 upward. It also carries a file API, so the host can pull a preference file off the running machine or push one on, and an ARexx port, so Amiga programs can drive it from inside.
How it is wired in
On this disk the server is installed by a script like everything else, and started from S:User-Startup ten seconds after Workbench so it never delays the boot. It talks over the Amiga’s serial port, which WinUAE bridges to a TCP socket on the Windows host; the emulator’s network-card emulation was tried first and was not reliable for a program that listens rather than connects. There is a timing rule: if the host connects the instant WinUAE starts, the socket is up before the server has opened serial.device, and the first command vanishes. The scripts wait for the guest to answer. By hand, wait about twenty-five seconds.
With that in place, a check of the disk is a script and not a person. Quit WinUAE through its own control pipe so the hardfile is flushed, start it again, wait for the server, and then ask: is there a window with the Workbench title, or did Scalos come up as the backdrop with no titled root window at all? Pull SYS:Disk.info and SYS:Trashcan.info off the disk and decode them: do they carry NewIcon data? Capture the emulator’s client area and count the colours. Write a report with a single ok in it. If a change is judged by that report and not by a glance, a fix that only worked until the next boot cannot pass.
What it cannot reach
Four things, each of which shaped a script. MUI windows are, to the operating system, one gadget with everything painted inside, so AmiPilot can open MUI Preferences and cannot press anything in it; the Scalos palette file was written from the Scalos source instead of read back from a Save. WHDLoad pauses the operating system when a game starts, and the server with it, so a running game can only be photographed from outside. A Scalos backdrop has no window title to address, so drawers are opened through Scalos’s own opendrawer tool rather than by double-click. And the MiSTer has no serial bridge and no pipe, so nothing on the board can be driven at all; everything is proven in WinUAE and then minted.
One smaller limit turned a script inside out. The file API has an upload cap, and a game icon with its NewIcon merged in is over it. So instead of the host merging the icon and pushing it, the host asks AmiPilot to run the Amiga’s own copynewicon on the two files already on the disk, which produces the identical result from the other side.
Still to build
The captures that judge a drawer are taken from Windows, of the emulator’s window; AmiPilot’s own screen capture refuses a 640×480 screen as over its size cap, so it is not in that path. The picture that would prove a game launched does not exist yet at all. The preference-window script promised here has since been written, capture_prefs.sh, and it taught two things on its first run. Window titles must be exact; the pattern matching AmigaDOS has, #?, this version of AmiPilot does not, and a prefix is enough to pick the wrong window when Scalos and Scalos Palette are both open. And menu items are picked by position, not by name: pass a name and you get the first item of the first menu, which is Open, and a file requester you did not ask for.
What AmiPilot took over
This ledger is different from the others. Nothing on this page is a step of the guide; it is the checking the guide never had. Each row is a thing a person used to decide by looking.
- Automated
Install
Copy the server onto the disk and start it at boot.
install_amipilot.sh --serial-only writes AmiPilotServer and AmiInspect and the delayed start line. setup_winuae.sh --amipilot does it during the build and writes the serial bridge into the .uae file. setup_amipilot_host.sh installs the pinned host client once.
- Automated
The desktop
Boot and look: did Scalos come up as the backdrop, are the icons in colour?
verify_winuae_desktop.sh restarts the emulator cleanly, waits for the server, checks the window list for a backdrop, pulls the disk and trashcan icons and decodes them, captures and scores the screen, and writes report.json. --icon adds any icon you name; --no-scalos checks a plain Workbench; --no-restart checks the machine already running.
- Automated
A drawer
Open it and look at the icons.
show_drawer.sh opens the drawer through opendrawer, pulls every icon in it, runs icon_report.py on each, and captures the result. This is how Eight pens was measured.
- Automated
ScreenMode
Pick the graphics-card row, Use, Save.
In the first-boot acceptance run, run_workbench_acceptance.py opens ScreenMode, selects the row, reads Width and Height back and presses Use, capturing at each stage; run_interactive_winuae_acceptance.sh launches it in a Windows session that can actually see the emulator, because one started over ssh cannot.
- Automated
A template
Work out a preference file’s format from documentation.
Press Save in the real editor with AmiPilot, pull the file it wrote, and use those bytes as the template the host writes from. write_palette_prefs.py was made this way, and the saved file is kept as a test fixture so the byte-for-byte claim is checked on every run. The MiSTer screen mode took the same approach without AmiPilot: chosen by hand on the board, saved, and read back off the card.
- Automated
Icons on a live disk
Fix a RomIcon without taking the disk offline.
whdload_newicon_guest.py has the server run the guest’s copynewicon for each game, because the merged icon is over the upload cap.
- Automated
A preferences window
Double-click the editor, look at it, press Cancel.
capture_prefs.sh starts the editor the way Workbench would, waits for its exact title, reports the window’s position and size so the Windows capture can be cropped to it, and quits it through its own Project menu, looked up by name and picked by position. It took the pictures on the MUI, ClassAct, NewIcons and Scalos pages. NewIcons is the exception: no menu, so it opens and captures but does not close.
- By hand
A game
Start it and see whether it plays.
Still a person. The capture from outside the Amiga that would prove a launch is not built.
- By hand
The board
Boot the MiSTer and look at the television.
Still a person. There is no AmiPilot path to the Minimig core.
AmiPilot is sidick/amipilot, with its documentation at sidick.github.io/amipilot. The scripts that use it are in amiga-utils. The words are ours.