Skip to content

fix(update): crashed updates no longer strand stopped gateways — a fresh process settles the restart debt (#92145, salvage #94392) - #95930

Merged
teknium1 merged 5 commits into
mainfrom
salv/wave2-94392
Aug 26, 2026
Merged

teknium1 merged 5 commits into
mainfrom
salv/wave2-94392

Conversation

@teknium1

Copy link
Copy Markdown
Collaborator

Summary

An update that crashes AFTER stopping gateways but BEFORE relaunching them no longer strands them dead — the next hermes update (a fresh process) discovers the unpaid restart debt and settles it (#92145; salvage of #94392 by @JoaoMarcos44, all four commits cherry-picked with authorship preserved, plus one adjustment commit from review). Fleet relevance (#91277): an interrupted update leaving a whole fleet's gateways down with no operator signal is the worst version of the stale-gateway class.

Changes

  • @JoaoMarcos44's four commits: persist "stopped these, owe restarts" to disk; a fresh process recovers the debt; per-profile recovery outcomes persisted into the receipt.
  • Adjustments (ours, per review):
    • Supervisor claims narrowed to what is OBSERVED: a rc==0 gateway restart is not proof of a running gateway. Only systemctl --user is-active-confirmed units report verified; everything else reports relaunch_attempted, never clears gateway_fleet_restart_incomplete, stays out of relaunched_profiles, and prints a "not supervisor-verified" operator warning. Parent fails closed on unaccounted profiles.
    • Serve-owned runtimes included: spawn-ledger serve/dashboard entries are partitioned explicitly — handled or recorded skipped-with-reason, never silently ignored.
    • Recovery suite grew 11 → 17 tests (verified-vs-attempted, missing systemctl, serve-skip recording, supervisors-map validation, real fresh-process E2E).

Validation

Result
Focused suites (8 files) 93/93 passed
A/B (4 product files reverted to merge-base, tests kept) 18 FAILED / 22 passed — recovery machinery provably absent
Sibling test_cmd_update.py 74 passed / 6 failed — all 6 re-verified as pre-existing on pure origin/main (same fixtures fail without this diff)
Live E2E real fresh-process recovery run via the suite's E2E (subprocess boundary crossed, receipt outcome persisted)

Live repro: A/B above — the fresh-process path and fresh_recovery receipt key don't exist on merge-base (KeyError).

Honest limits: launchd/s6 have no verification probe by design (they report relaunch_attempted; a launchctl verifier is a natural follow-up), and no real production systemd fleet was harmed in testing — the systemd observation path is proven via shim + units. Refs #92145 (the reviewer's RED→GREEN systemd harness standard for a full "Fixes" claim stands).

Credit: @JoaoMarcos44.

Infographic

Owed restarts

JoaoMarcos44 and others added 5 commits August 26, 2026 16:24
…restart recovery

Salvage adjustments to PR #94392 per review:

- Narrow the supervisor claim to the systemd-VERIFIED path only. The fresh
  recovery child now probes 'systemctl --user is-active' after each relaunch;
  only an observed-active systemd unit is reported 'verified'. A relaunch that
  merely exited 0 is labelled 'relaunch_attempted', never counts as supervisor
  coverage, and never clears gateway_fleet_restart_incomplete.
- Serve-owned runtimes (serve/dashboard entries from the spawn ledger, per the
  update_inventory serve collector) are no longer silently skipped: the
  recovery pass records them (and manual gateways) as skipped-with-reason in
  the recovery result and the persisted update receipt.
- Receipt fresh_recovery persists the conservative vocabulary
  (requested/verified/relaunch_attempted/failed/skipped); 'succeeded' is gone.
- Added an end-to-end test that drives the real recovery module in a genuinely
  fresh interpreter (sitecustomize shim intercepts the grandchild
  'gateway restart' and systemctl probes).
@github-actions

github-actions Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

૮ >ﻌ< ა ci review

ran on 7fa2d4f — fix(update): conservative outcomes + serve-ledger coverage f

⚠️ Warnings

OSV vulnerability scan · View job

6 known vulnerabilities found in pinned dependencies.

How to fix:

Review the findings in the Security tab. Update the affected dependencies if a patched version is available.


debug info

CI timings

CI timings · View report · View job

Wall time 3m18s vs 3m57s (-16.5%). 5 job(s) slower, 8 faster,

  • Python tests / Run tests: -42.0s
  • OS-specific tests / Windows-only tests: +13.0s
  • Python tests / e2e: -6.0s
  • OSV scan / Scan lockfiles / osv-scan: -6.0s
  • OS-specific tests / macOS-only tests: +6.0s

@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/cli CLI entry point, hermes_cli/, setup wizard labels Aug 26, 2026
@teknium1
teknium1 merged commit b2c0113 into main Aug 26, 2026
35 checks passed
@alt-glitch alt-glitch added comp/gateway Gateway runner, session dispatch, delivery area/install-update Installer, updater, packaging, wheels, doctor sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades labels Aug 26, 2026
@teknium1
teknium1 deleted the salv/wave2-94392 branch August 26, 2026 23:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/install-update Installer, updater, packaging, wheels, doctor comp/cli CLI entry point, hermes_cli/, setup wizard comp/gateway Gateway runner, session dispatch, delivery P2 Medium — degraded but workaround exists sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants