Repository navigation
Conversation
Make gateway updates use a two-phase notification lifecycle. Persist the initiating gateway PID with the durable update target, let the old process announce that restart is beginning without consuming completion state, and let only the freshly started gateway send the definitive online notification. Preserve pending, output, and exit-code markers when platform delivery raises or returns SendResult(success=False), so reconnect/startup watchers can retry instead of silently losing the result. Clean markers only after confirmed delivery. This closes the race where the updater writes its success marker before the supervisor stops the old gateway: the old watcher previously attempted a final send during shutdown and unconditionally deleted all markers even when delivery failed. Validation: 27 gateway update, streaming, and startup-race tests passed; Ruff and diff checks passed.
boudyai
force-pushed
the
fix/gateway-update-restart-notification
branch
from
August 6, 2026 08:21
f73068d to
401227e
Compare
This branch has not been deployed
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.
What does this PR do?
Makes
/updatecompletion notifications survive the gateway restart they report.The updater writes
.update_exit_codebefore asking systemd (or another platform supervisor) to restart the gateway. The old gateway watcher can therefore observe success while shutdown is already in progress. It currently attempts the final send and then unconditionally deletes.update_pending.json,.update_output.txt, and.update_exit_code, including when delivery fails. The new gateway starts with no durable target left and cannot notify the initiating chat.This PR turns success notification into a two-phase lifecycle:
Both raised exceptions and
SendResult(success=False)preserve and restore the marker for retry. Legacy markers without an initiating PID retain their existing behavior.Related Issue
N/A — no matching open or closed issue/PR was found after searching update, restart, completion-notification, and marker-related terms.
Type of Change
Changes Made
gateway/slash_commands.py: persist the initiating gateway PID in the durable update target.gateway/run.py: defer success to the restarted gateway, preserve markers on exceptions and soft send failures, and explicitly report that the gateway is back online.tests/gateway/test_update_command.py: cover PID handoff, successful post-restart delivery, cleanup, exception retry, andSendResult(success=False)retry.tests/gateway/test_update_streaming.py: reproduce the old-watcher race and verify soft-failure retries.How to Test
Start a messaging gateway under a restart-capable supervisor and invoke
/update.Confirm the initiating process can send
Update installed / Restarting gatewaywithout deleting the durable markers.Confirm the new gateway PID sends
Update finished / Gateway restarted and is back online, then removes the markers.Make
adapter.send()raise or returnSendResult(success=False)and confirm the pending marker remains retryable.Run:
Result: 27 passed.
Checklist
Code
fix(scope):,feat(scope):, etc.)pytest tests/ -qand all tests passThe full repository suite was not run locally. The three directly related test files pass via the canonical runner, and Ruff passes for every changed Python file.
Documentation & Housekeeping
docs/, docstrings) — N/A; no user-facing configuration or syntax changedcli-config.yaml.exampleif I added/changed config keys — N/A; no config keys changedCONTRIBUTING.mdorAGENTS.mdif I changed architecture or workflows — N/A; the existing marker/watcher architecture is retainedos.getpid()and durable marker handoff are platform-neutralScreenshots / Logs
Before:
Validation: