Repository navigation
kvm-it 0.3.0: flash the adapter from the app
Firmware (0.1.0) and wire protocol (v1) are unchanged. The controller can now flash the adapter itself, on Linux and Windows.
Verification: see the README status table. On a physical board: kvmit flash on Linux (verified write, pairing kept by a
default flash and wiped by --erase-all, refusal while the adapter's USB port is plugged in, recovery from a write killed
halfway). In the Windows 11 VM with the board's COM bridge passed through: the CLI and the GUI wizard, and an MSI built, installed
and uninstalled. Not exercised: the Linux GUI wizard, bare-metal Windows, the signed release pipeline with the new packaging
before this tag. The flasher was adversarially reviewed over rounds 7-13 (docs/dev-process.md; round 13 by Claude Opus 5.5 because the usual reviewer was out of quota, a recorded deviation from STD-001, with a Codex round to follow); the adapter firmware now ships with the app.
Added
kvmit flash(in progress for 0.3.0): writes the adapter's firmware through its UART (COM) port with theespflashlibrary.
It validates the image first, refuses the board's native USB port (which would type into the flashing computer), keeps the
pairing and settings unless--erase-allis given, and asks for confirmation. Host-tested (image and port rules);
hardware-verified once on one board over its CH343 UART. Before writing it re-checks that the chosen port is still the same
device, that no Espressif USB device (which may be an adapter's own USB port: a keyboard and mouse, HID-only so not a serial port,
or the generic debug unit it shows in download mode) is plugged into the computer, that the chip is an ESP32-S3 with the image's flash size, and that the installed partition table keeps the settings
where they are; it validates the image (headers, partition table, file paths inside the firmware folder). Hardware
results: on Linux with a physical board the pairing survives a default flash and is wiped by--erase-all, and the native-USB
refusal works (also with--any-port); on Windows 11 (VM, the board's COM bridge passed through) the CLI and the GUI wizard
flash end to end. An interrupted flash (the Windows flasher killed halfway through the app) was recovered by flashing again, no BOOT button. Not exercised: the Linux GUI wizard, bare-metal Windows.- Flash adapter… in the GUI's Adapter popup (
flashwiz.rs): a window that finds the board's COM port, checks the firmware
folder, blocks while any Espressif native USB port is plugged into the computer, requires a second tick before erasing the
pairing, refuses while a script runs or the adapter is connected, flashes on a worker thread with a progress bar (no close button
and no app exit while writing), and says how to recover if it fails. Its rules are unit-tested; a flash through the window was run end to end in the
Windows 11 VM. Opening it cancels a pending connection attempt (which would otherwise block it with nothing to press). - The adapter firmware ships with the app:
firmware/release/(the exact images, with provenance and checksums) is installed
beside the program by the MSI, included in the zip and the AppImage, and found bykvmit flashand Flash adapter… with no
setup (KVMIT_FIRMWAREor--firmwareoverride it). CI checks that the bundled images are not older than the firmware sources;
verify-release.pychecks the zip carries them. Windows executables grew from ~21 MB to ~35 MB with the flasher (espflash). THIRD_PARTY_NOTICES.md(MPL-2.0 notice forserialport) ships in the zip, the MSI and the AppImage; the AppImage builder moved to Rust 1.99.
Changed
- Build toolchain is Rust 1.99 (was 1.90), needed for the in-app flasher planned for 0.3.0; clippy lints fixed (
as_chunks, an
always-trueminin a test, explicitf32for stroke widths). No behaviour change. The AppImage builder stays on 1.90 for now.
Changed (found cutting the release)
- The window title now carries the version ("kvm-it 0.3.0"), which also stamps it into
kvmit-gui.exe.scripts/verify-release.pychecks that stamp, and it had only
passed for 0.2.1 by coincidence (a dependency's source path in the executable happened to contain "0.2.1"): the GUI never embedded its own version before.
Known limitations
- Flashing: identical boards behind a USB bridge with no serial number cannot be told apart (the app says so and re-checks chip, flash size and settings layout); a USB device
the OS will not let the enumerator describe, one plugged in after the check, or an adapter's USB port running other firmware under another vendor id are not detected as
a reason to refuse. Firmware is not signed;KVMIT_FIRMWARE/--firmwarecan point at any valid ESP32-S3 image set. - BLE lifecycle around the flasher (review round 13, Low): pairing and then immediately connecting elsewhere can leave an idle OS-level link unowned, and a failed first
connection after a pairing may not close its link; both are dropped when the board is flashed (it resets). Planned for 0.3.1. - The Linux GUI wizard, Linux pairing with the new code and bare-metal Windows were not exercised.
Signing and assets
- Windows: code-signed.
SIGNATURES.txt(straight fromGet-AuthenticodeSignature) reportsValidforkvmit.exe,kvmit-gui.exeand the MSI, signer
CN=Joseph Spillers, signed in CI with Azure Artifact Signing (RFC 3161 timestamped).scripts/verify-release.py --require-signedpasses on the published assets
(hashes, zip contents, the bundled firmware byte-identical tofirmware/release, its checksums and source hash, PE headers, version stamps). - The signed MSI was installed in a Windows 11 VM: it places the firmware next to the app, both executables report a valid signature, and the installed
kvmit flashwrote the bundled firmware to a real board (verified write, pairing kept). - Linux:
kvm-it-0.3.0-x86_64.AppImage(+.sha256), built from the tag, not code-signed; check it against its checksum. Needs BlueZ, OpenGL and the usual
desktop libraries; glibc 2.35+. It carries the firmware too. Onlycli --versionandcli flash --listwere run from it; the GUI was not started from the AppImage. - Nothing here is verified on bare-metal Windows, on the Linux GUI wizard, or on Linux pairing with this release.
- The first publication attempt of this tag failed its own verifier (the GUI never embedded its version) before anything was attached; the tag was re-cut on the fixed
commit, which is why the tag is newer than the merge of the flasher work (details indocs/dev-process.md). - Review: the flasher went through thirteen adversarial review rounds; round 13 was done by Claude Opus 5.5 instead of the usual reviewer (out of quota), a recorded
deviation, and a Codex round over the same code is still to be run.