Skip to content

fix(daemon): require authoritative Claude job removal at stop - #150

Merged
ChesterRa merged 3 commits into
ChesterRa:mainfrom
chriscoveries:fix/claude-stop-gone-confirm-v4
Oct 23, 2026
Merged

ChesterRa merged 3 commits into
ChesterRa:mainfrom
chriscoveries:fix/claude-stop-gone-confirm-v4

Conversation

@chriscoveries

@chriscoveries chriscoveries commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

Agent View jobs can outlive their control harness. A missing or refusing control endpoint therefore leaves stop unconfirmed, regardless of how long it stays absent.

Stop now succeeds only after a successful authoritative job listing no longer contains the owned job. This adapter does not retain a process identity that could independently verify exit. If removal cannot be confirmed, callers receive an error such as Claude Agent View stop unconfirmed; ownership retained: job removal was not confirmed. Endpoint unavailability exhausts the existing timeout and preserves io::ErrorKind::TimedOut.

For Actor stop/restart, the caller receives an unsuccessful io_error response with that message and lifecycle_stage: "stop". An unconfirmed stop keeps the session registered and skips owned-resource cleanup. Replacement startup must complete that same stop before launching another job, so it propagates the error instead of starting a replacement.

The new regression runs the real native CLI offline, hides its bound socket for four seconds, and restores the same listener. It captures the same job still listed after the endpoint returns and requires the first stop to fail while ownership remains held. It then stops the job for real, verifies authoritative removal, and checks owned-resource cleanup. Existing genuine-stop coverage remains; stale-socket coverage now requires an unconfirmed stop and checks owner-directed cleanup. No fabricated job responses or output fixtures were added.

Validation:

  • Test-only commit on the original PR head: run 39801446267 fails the new native regression at a still-running task whose endpoint disappears and returns must not be reported stopped: (). The real capture records a 4,001 ms endpoint gap, the same job still listed, a successful stop result, and released ownership.
  • The identical regression on unchanged upstream main passes, with all six jobs green: run 39802102498. Main already lacks the elapsed-absence success path.
  • Fixed-head full fork CI: run 39807105212, all six jobs green, including rust-linux and the real native regression.

kill_and_confirm treated every NotFound and ConnectionRefused from the
Agent View control list call as transient. When the supervisor had
already exited, the stop therefore waited out the whole 10s
STOP_TIMEOUT and failed ("Claude Agent View task did not stop: No such
file or directory (os error 2); kill request also failed: ..."), and on
daemon shutdown that failure became exit status 1.

A missing control socket and a socket left behind with no listener both
mean nothing serves the endpoint. Once the endpoint has been absent in
either form for a 2s confirmation window, the task counts as stopped.
Switching between the two errors does not restart the window; a listing
that still shows the task, or a reset or aborted connection from a live
listener, does. The window keeps a brief harness restart, which Agent
View jobs survive, from being read as a stop, and a task that stays
listed still fails after STOP_TIMEOUT.

Tests: a missing endpoint, a stale socket with no listener, and an
endpoint alternating between the two all stop within the window; a task
that stays listed still times out.

Originally prepared on fork PR #17.

Copy link
Copy Markdown
Owner

I am holding this implementation because an absent control endpoint, including absence lasting two seconds, does not confirm that the managed task exited. Agent View work can outlive its control harness. Returning success here could release ownership and allow a replacement while the previous process still runs.

Please make success depend on authoritative job removal or verified exit of the owned process identity. If that cannot be established, retain an explicit unconfirmed stop result rather than treating an elapsed absence window as confirmation.

The key missing regression is a still-running task whose control endpoint disappears for longer than the proposed window and later returns. Include that alongside genuinely stopped tasks and stale-socket cleanup. The current missing/refused-socket tests establish endpoint absence, not task termination.

@chriscoveries chriscoveries changed the title fix(daemon): finish Claude stop when the control endpoint stays absent fix(daemon): require authoritative Claude job removal at stop Oct 22, 2026
@ChesterRa
ChesterRa merged commit bb43e84 into ChesterRa:main Oct 23, 2026
4 of 6 checks passed
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.

2 participants