Skip to content

Preserve background tasks across daemon reconnects - #1165

Merged
ymichael merged 2 commits into
mainfrom
bb/reproduce-issue-1127-thr_mu373wc3ic
Aug 7, 2026
Merged

Preserve background tasks across daemon reconnects#1165
ymichael merged 2 commits into
mainfrom
bb/reproduce-issue-1127-thr_mu373wc3ic

Conversation

@ymichael

@ymichael ymichael commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • distinguish a reconnect from a genuinely new host-daemon instance when replacing a server session
  • close only the superseded WebSocket for same-instance reconnects, preserving resident provider runtimes and their background processes
  • retain the fatal session-close and task reconciliation behavior when a different daemon instance takes over
  • bump the host-daemon protocol version and add unit plus real-provider regression coverage

Root cause

Opening a replacement server session always sent session-close:replaced to the previous socket. On an ordinary reconnect, that socket belonged to the same live daemon instance. The daemon treated the message as terminal and shut down every environment runtime, which killed background commands before its supervisor restarted it.

The server already has both session instance IDs, so it can tell these cases apart. A same-instance replacement now closes only the stale transport. A different-instance replacement still shuts down the superseded daemon and settles its work.

Reproduction

I reproduced this with standalone dev servers and the bb CLI against both the v0.35.1 tag and this branch:

  • v0.35.1: replacing the live session with the same daemon instance immediately killed the background shell and sleep PIDs, recorded the task as stopped/interrupted, and logged session-close:replaced daemon shutdown
  • patched branch: the daemon reconnected with the same instance ID, the same background PIDs remained alive across a CLI follow-up, and the task completed and wrote its marker normally
  • control: an unchanged CLI follow-up without a reconnect preserved the background PIDs, confirming the reported failure is specifically the reconnect path

Tests

  • @bb/server lifecycle and hub regression tests: 32 passed
  • @bb/host-daemon-contract tests: 49 passed
  • sanitized install-machine regression suite: 10 passed
  • typechecks for @bb/server, @bb/host-daemon-contract, and @bb/integration-tests
  • real Claude end-to-end reconnect/background-process regression: passed
  • full server suite: 1,357 passed; the one environment-dependent install-script failure passed when rerun with the expected sanitized PATH

Closes #1127

@SawyerHood

Copy link
Copy Markdown
Collaborator

🚨 SLOP COP 🚨 · review

ELI5: A daemon reconnect is like a phone call that drops. This change keeps its long task alive after the new call starts.

I am SlopCop. I am reviewing this pull request for security, code quality, performance, tests, and architectural duplication. Three BB child threads will inspect these areas in parallel. I will post one final review after I verify their findings.

Comment thread tests/integration/real/provider-background-survival.test.ts Outdated
Comment thread tests/integration/real/provider-background-survival.test.ts Outdated

@SawyerHood SawyerHood left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚨 SLOP COP 🚨 · review

ELI5: A daemon reconnect is like a phone call that drops. This change keeps a long job alive after the new call starts.

I found no blocking product defect. The change keeps server policy in the server. It also adds a small socket-only hub method. I found no useful duplicate code or larger refactor.

I left two low-risk test comments:

  • Wait for the replacement WebSocket before the follow-up turn.
  • Give the real-provider test a larger timeout.

Security, code-quality, and performance threads reviewed the change. A separate GPT-5.6 gate confirmed the two test risks and found no product defect.

Targeted server tests passed with 11 tests. Contract tests passed with 49 tests. Server, contract, and integration type checks passed. The dev app loaded in a browser. All GitHub checks are green.

The real Claude test stopped before the reconnect scenario. The local Claude OAuth session had expired. This failure does not show a pull-request defect.

@ymichael
ymichael merged commit 120ff8b into main Aug 7, 2026
10 checks passed
@ymichael
ymichael deleted the bb/reproduce-issue-1127-thr_mu373wc3ic branch August 7, 2026 22:40
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.

bb kills background tasks that span an idle gap between turns — bb 0.35.1, provider claude-code.

2 participants