Skip to content

Keep a busy daemon through an update, and bring back what a restart stops - #31

Merged
enowdev merged 2 commits into
mainfrom
fix/sessions-survive-update-2
Nov 4, 2026
Merged

enowdev merged 2 commits into
mainfrom
fix/sessions-survive-update-2

Conversation

@enowdev

@enowdev enowdev commented Nov 4, 2026

Copy link
Copy Markdown
Owner

First part of "sessions survive an update". Sessions' programs run on terminals the daemon holds, so replacing the daemon ended them, without asking.

Design

Keep the daemon rather than hand over its terminals. Every update replaced the app and its daemon together, but the app and daemon already work across versions, so the daemon can simply stay.

  • Waits: as the app connects, a daemon of another version is asked what a restart would stop (daemon.restartPlan): agents at work or asking, and what runs in terminals. If nothing, it's replaced as before. Otherwise it stays (hostconn.keepBusyDaemon), for every caller of Connect, so nothing replaces it by accident.
  • Asks: a card says what would stop: Restart it now (confirms first) or When agents are done.
  • Old daemons: one too old to answer (0.6.2 or before) is judged by its sessions, every terminal counting. So this protects the first update too.
  • If it does restart:
    • an agent mid-turn is told once to carry on; its prompt isn't resent
    • an agent in a terminal comes back on its conversation with only its mode, model and permission flags, never a prompt or key
    • a command isn't run again: the terminal and the app say what ended

Handing live terminals to a new daemon isn't in this PR: it needs a holder process, and Windows' ConPTY needs its own answer. Listed in the owner's note acf8233d3e5c.

What each system gets

The same on macOS, Linux and Windows, local and remote: nothing is killed by an update unasked, and programs survive for as long as the daemon stays. None yet survive a daemon that is really replaced.

Tests

  • Real daemons, separate ENOWX_HOME: TestUpdateKeepsABusyDaemon builds enowxd: idle gets replaced, one running a command stays with its PID, asking replaces it and lists what ended.
  • Restarts: mid-turn told once and prompt not resent, agent in a terminal, GOA's board and waiting lines kept, plan contents, flag filtering, masked commands.
  • On enowxlabs: core/agent, proto, client, hostconn test, full daemon, and in ui the card's wording and TestReconnectsByItself (fixed here: it hung on hosts with Xpra; the cause isn't in the app).

Not run: the real app and the card; a real update; a real agent; remote hosts (remoteDaemonBusy has no test, as it needs SSH); Windows and macOS beyond CI and cross-builds.

Behavior changes

  • After an update, a busy daemon stays at its old version, so new daemon features wait until it's replaced.
  • An update from 0.6.2 with any terminal open keeps the daemon, as that version can't say what runs there.
  • Crashes note nothing, so an agent cut off by one comes back without being told to carry on.

Queued tasks across a restart depend on #30.

Touches no go.mod, version/ or cloud/, so merging doesn't deploy the cloud.

🤖 Generated with Claude Code

enowdev and others added 2 commits November 4, 2026 20:40
On a host with Xpra the app asks for it as it connects, which waits for a
window's loop the test doesn't have, so the sessions never showed. CI has no
Xpra, so it only failed on machines that do.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tops

Restarting after an update replaced the daemon, whose terminals its sessions'
programs run on: agents mid-turn stopped, an agent in a shell tab came back as a
bare shell that ran what was sent to it, and commands ended unsaid.

The daemon is now replaced only when that stops nothing, or when the user says so;
a card says what would stop. A restart that does happen tells an agent mid-turn to
carry on, once, brings an agent in a terminal back on its conversation in its mode,
never with its prompt, and says what commands ended.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@enowdev
enowdev merged commit 6deb5a8 into main Nov 4, 2026
4 checks passed
@enowdev

enowdev commented Nov 5, 2026

Copy link
Copy Markdown
Owner Author

Its commits are in main through the 0.7.0 release merge (#40, e306b3b).

@enowdev
enowdev deleted the fix/sessions-survive-update-2 branch November 5, 2026 04:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant