Device lab
Fleet Runner
A shelf of old phones, turned into a device lab you can send work to.
My plant app identified species by sending photos to a cloud API. I wanted to know whether that could run on the phone instead — offline, at no per-call cost — and on which hardware it would still feel instant. Answering that properly needed more than a benchmark script, so I built the lab first.
One queued job installs a build on every attached device, runs a UI suite across them, benchmarks llama.cpp on real silicon, screenshots a site on two real phone screens and diffs it against a baseline, or drains a battery on purpose and plots the curve. A collector holds the queue, the leases, the artifact store and the results; agents on iOS, Android, desktop and in the browser claim work and report back.
- 77%
- top-1 on-device species ID
- 7 ms
- per image, on a phone CPU
- 28
- workloads across three executors
- 4
- agents, one protocol, no shared code


What it proves
Three things worth reporting
The answer was yes, and it was specific
An Apache-2.0 ResNet18 hit 77% top-1 and 90% top-5 on held-out images, and the int8 build ran in 7 ms per image on the CPU of a Dimensity 9400 — faster than fp32 with the GPU delegate, and loading in 23 ms instead of 428. The shipping configuration needs no GPU delegate at all, which deletes a whole class of failures.
Four implementations keep the protocol honest
Kotlin, Swift and two TypeScript agents implement the same five HTTP calls and share no code. They also share a synthetic benchmark that is identical on every platform token for token, which is what lets a 2019 Android phone, a current iPhone and a laptop land in the same table comparably. A conformance suite drives a running agent through eight clauses, every one of them something that has actually gone wrong.
The most useful thing it does is decline to produce a number
The iOS Simulator's emulated GPU returned an all-zero logits tensor for a model — silently, no error — and only a second device disagreeing caught it. A phone on battery was measured throttling decode roughly 100×, so a job can demand mains power and the runner refuses rather than reporting a number produced under duress. A wrong number recorded as a result is worse than a failure, because a failure gets investigated.
More open source
Actions Runners →