Symptom

Deploy Local Runner.yml was a hybrid of two unrelated jobs glued together: a deb-build pipeline (server / desktop / krill-pi4j / krill-mcp) and a post-build “tester” handoff to krill-ghost-bot. It picked up on the generic ['self-hosted', 'Linux', 'ARM64'] label set, which any ARM64 self-hosted runner across the org could match — so QA-verify runs were landing on whichever ARM64 box happened to be free instead of the dedicated ghost runner where the QA agent’s tooling (skill symlink, bearer cache, MCP host config) actually lives. It also re-cloned the three repos via actions/checkout even though the runner already has long-lived working copies under /home/ben/Code/, and it didn’t stamp the deb Version: per run, so a second verify on the same PR was a dpkg no-op against an already-installed identical-version package.

Root cause

Two drift points compounded:

  1. Runner targeting too broad. Dev Agent Blue.yml (the analogous dev-side workflow) targets ['self-hosted', 'Linux', 'X64', 'blue'] — the trailing blue is what pins the job to the dev-agent workstation. The verify workflow had been written before that pattern was established and never picked up the equivalent ghost label.
  2. No per-run version stamping. The four control files at */package/DEBIAN/control carry the release version (e.g. 1.0.894). Release Version.yml bumps them in lockstep with version.txt on a release. Inside a PR-verify run the working tree never sees that bump, so the rebuilt deb has the same Version: as the previously-installed one and apt-get install short-circuits.

Fix

Prevention