7c6b8c7a8d
`hermes update` run while the Desktop app is open ended `partial`/exit 1 and re-armed `fleet_restart_pending` on every run: `_gateway_recovery_partition` exempts a `supervisor == "desktop"` serve from restart (`_DESKTOP_SERVE_SKIP_REASON` — it hosts the live Desktop chats), while `match_runtime_outcomes` counted that same still-alive process as `unaccounted` whenever the survivor probe found its pre-update incarnation in the ledger. Nothing in the updater is allowed to discharge that obligation, so it could never finalize. - update_inventory.match_runtime_outcomes: a Desktop-supervised serve/dashboard still alive reconciles as a new outcome `deferred` (handed back to its supervisor). "restarted" would be untrue — the process provably runs old code and the Desktop app does not respawn it after a terminal-side update. A gone one stays `restarted`; a manual/systemd survivor stays `unaccounted`. - update_inventory.report_unaccounted_runtimes: prints `deferred` rows with the one remedy that exists (relaunch the Desktop app) without escalating; the `systemctl --user restart hermes-serve.service` hint is Linux-only now (it was shown on macOS too). - update_abort_recovery: same class on the fresh-child recovery path — `_owed_stale_serve_rows` excludes Desktop-owned survivors from `_abort_recovery_is_complete` and the incomplete gate in update_cmd_fleet; they are still named by `_warn_stale_serve_runtimes` and kept in the receipt's `stale_runtimes`. - tests: end-to-end (exit 0, receipt `success`, `runtime_outcomes` gateway=restarted / serve=deferred, marker cleared, relaunch hint printed) + abort-path predicate; both red on origin/main. Fixes #111494 Supersedes #111499 Co-authored-by: KoNit-K <124019182+KoNit-K@users.noreply.github.com>