From fcae30631c9b4bd4e3036b15f1a60c08afc8e4bb Mon Sep 17 00:00:00 2001 From: Neil <4138956+nwparker@users.noreply.github.com> Date: Wed, 12 Aug 2026 16:32:36 -0700 Subject: [PATCH] docs(daemon): record the TOCTOU fix that was built, tested and reverted shutdownIfIdle is the right instrument and the daemon already implements it atomically: sole authenticated client, nothing in flight, zero sessions, listener closed before the acknowledgement. Asking it immediately before the kill closes the window that a re-read of listSessions can only move. It is not landing here. Gating every empty-verdict replacement on a new round trip means every failure of that round trip has to mean hold, which trades a rare race for a common failure mode and makes #8689 worse whenever the call is merely slow. It also flipped two endpoint-identity tests from rejecting to resolving, and an unexplained behaviour change is not something to merge at commit forty-two of a change whose whole subject is unintended consequences. Written down with the mechanism intact so the next person starts from a working design rather than rediscovering it. --- src/main/daemon/AGENTS.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/main/daemon/AGENTS.md b/src/main/daemon/AGENTS.md index 1a66c8ee573..050a355fdfd 100644 --- a/src/main/daemon/AGENTS.md +++ b/src/main/daemon/AGENTS.md @@ -71,7 +71,19 @@ hands → probe once more → `rename` in one syscall → verify we kept it. to them. Killing is chosen deliberately, because a daemon that can never be adopted and is never replaced leaves the app permanently degraded with no route back. Reconsider only with a way for the user to choose. - - **TOCTOU between the verdict and the kill.** An `empty` answer can go stale — another Orca + - **TOCTOU between the verdict and the kill.** The right fix is known and was implemented and + reverted once, deliberately: ask the daemon to retire itself via the existing `shutdownIfIdle` + RPC immediately before the kill, and treat only its own `{retiring: true}` as permission. + The daemon answers that atomically — sole authenticated client, nothing being created or + attached, zero sessions — and closes its listener before acknowledging, so nothing can slip + in behind the proof. A second `listSessions` would only move the race. + + It was reverted because it makes every empty-verdict replacement depend on a new round trip, + and any failure of that round trip must mean hold — which turns a rare race into a new, + common failure mode, and worsens #8689 whenever the call is merely slow. It also changed the + behaviour of two endpoint-identity tests in ways that were not quickly explainable. Land it + on a green base with its own review, not as an addendum. + An `empty` answer can go stale — another Orca instance may create a session before the ladder runs — and a dead endpoint can be republished. Nothing revalidates immediately before the kill, and `liveOwnerSurvived` is read only afterwards. Pre-existing, and narrowed by this change rather than widened: the