chadtmiller.com/knotless
git that lives in your Atmosphere account
A deploy keeps the runner unless its build changed
MergedThis replaces the source-path list with a build fingerprint. The image writes /etc/knotless-run.fingerprint (a hash of the knotless-run binary, the docker client and dpkg/status). deploy.sh up compares the running container's fingerprint with the one in knotless:current. KNOTLESS_COMMIT is now read with ENV at run time, in the last layer, so the binaries no longer change per commit.
I found nothing that must change. I checked these points:
knotless:currentis tagged before the STATUS block runs, so the candidate read is the new image.- No other
option_env!("KNOTLESS_COMMIT")orrun-unchangedreference remains.runner-host/deploy.shstill passes the build arg, which theARGstill accepts. - Every failure to read a fingerprint falls back to a restart, as before.
- The README and
docs/design/runner.mdare updated with the change.
One small thing: the fingerprint doesn't cover the knotless CLI or knotless-mcp binaries, so a runner step that depends on them could change without a restart. The runner doesn't appear to call them, so this is only a note.
8 passed, 2 skipped
What changes
A deploy restarts knotless-run only when the runner it would start is a different build from the one running, or its settings changed. The image keeps a fingerprint of what the runner is made of,
/etc/knotless-run.fingerprint: theknotless-runbinary, the docker client and the installed packages (git and the libraries).deploy.sh upcompares the running container's fingerprint with the new image's, in place ofdeploy/run-unchanged.sh's list of source paths, which is removed.So the fingerprint holds still across commits,
KNOTLESS_COMMITis read as the binaries run (ENV, the image's last layer) rather than built in withoption_env!, in knotless-run, knotless-serve, knotless-triage and knotless-agent.Why
On 2026-11-03, 15 of the 29 pulls that landed restarted the runner, and restarts cancelled 44 checks (
just queue-stats). Only about 6 of those pulls changed the runner. The rest restarted it for client-only files incrates/knotless/src(cli.rs,oauth.rs,status.rs), a release'sCargo.lock, or serve's Zoekt stage in theDockerfile, which the path list counted as the runner's. Comparing the built binary is exact: it restarts the runner only when its bytes change. A runner left running keeps logging the commit it was built from, which is what it runs.How it was checked
bash -n deploy/deploy.sh. The rest is left to CI, and to the first deploy after this lands. That deploy restarts the runner, as the old container keeps no fingerprint. The deploy log should then sayrun: its build, …, and settings are the same, not restartedfor a pull that does not touch the runner.Shortcomings
The deploy profile builds with 16 codegen units, and panic locations carry line numbers. So a change in
crates/knotlessthat knotless-run links may still change its bytes, and restart it, even when the runner behaves the same. That is never worse than the old path list. The cost of a restart that does happen is the next pull's work: the old runner hands over to the new one instead of cancelling.A release still restarts it, as
CARGO_PKG_VERSIONis built in.Changeset: none