fix(cli): post-update fleet check fails closed when a running gateway yields zero rows (#93406, salvage #93410) - #93654
Merged
Conversation
…started (#93406) collect_fleet_versions() swallows every probe exception via logger.debug() and returns whatever accumulated — which can be an empty list. print_fleet_version_matrix([]) returns False (no rows to report), so the update exits 0 with "success" even though no gateway was actually verified. After the restart phase touches live gateways (restarted_services or killed_pids is truthy), an empty fleet snapshot means verification failed, not that everything is healthy. Treat it as incomplete so the receipt records "partial" and the exit code is 1. Fixes #93406
…ness signals (#93406) The #93410 guard keyed on (restarted_services or killed_pids), which never fires on Windows: _pause_windows_gateways_for_update / _resume_windows_gateways_after_update populate neither list, so a healthy resumed Windows gateway still yielded zero fleet rows and exit 0. Hoist the decision into _fleet_probe_expected_runtimes(), keyed on every pre-update liveness signal: - restarted_services / killed_pids (POSIX restart bookkeeping) - _pre_restart_gateway_pids non-empty or None (unreadable pre-state, same fail-closed contract as _restart_phase_failure_is_incomplete, #78574) - pre-update plan inventoried >=1 runtime - Windows pause/resume token carries profiles or unmapped entries Gate the 2.0s settle sleep on the same condition so a resumed Windows gateway gets its settle window before the probe. The guard keys only on zero-rows-despite-expected-runtimes; non-empty snapshots (including 'unknown'-state rows) are still judged solely by print_fleet_version_matrix. Regression tests cover: empty snapshot + plan runtimes -> incomplete; empty snapshot + genuinely idle -> success; Windows-resume token path -> fail-closed + settle sleep wiring. Builds on RelaxJonh's #93410. Fixes #93406
This was referenced Aug 24, 2026
This was referenced Aug 24, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
hermes updatecan no longer report success while its post-update fleet version check silently produced zero rows for a gateway that was demonstrably running. The success path swallowed probe failures and treated an empty snapshot as "nothing to check" — the fail-closed guard only existed on the restart-failure path, and on Windows the pause/resume phase populates none of the signals the naive guard would key on. Fixes #93406.Changes
hermes_cli/update_cmd.py: empty fleet snapshot is treated as incomplete when ANY pre-update liveness signal fired — plan runtimes, pre-restart gateway pids, the Windows resume token's profiles/unmapped entries, or restarted_services/killed_pids (salvaged guard from fix(cli): treat empty fleet probe as incomplete when gateways were restarted (#93406) #93410 widened cross-platform)Validation
Salvaged from #93410 (@RelaxJonh), authorship preserved; guard gap identified live by @Halldrix on the PR.
Infographic