Skip to content

[Bug]: watch_pull_request after t3_thread_organize settle is dropped when the turn ends #25620

Closed

Description

@SouthCarpet

Claude Opus 5.5 on behalf of SouthCarpet

Before submitting

  • I searched existing issues and did not find a duplicate.
  • I included enough detail to reproduce or investigate the problem.

Area

apps/server

Steps to reproduce

  1. Open a thread whose project has an open GitHub pull request, and link the pull request to the thread.
  2. In one turn, ask the agent to settle this thread and then watch the pull request. The agent calls t3_thread_organize with action: "settle"; the tool returns { "settlesWhenTurnEnds": true }.
  3. In the same turn the agent calls watch_pull_request for that pull request; the tool returns watching: true.
  4. Let the turn finish, then open the thread details.

I reproduced this with a focused test, not with a live agent run. On upstream main 220eb73524 the test calls the real MCP handlers as the thread's own agent: first t3_thread_organize with action: "settle", then watch_pull_request. Settle returned { settlesWhenTurnEnds: true }; watch returned watching: true and wasWatching: false. Before the run completed, the thread was not settled and the watch was present. After I wrote a run-completed event and awaited thread.settled, the thread was settled and the watch was gone (the pull request link stayed). Project lookup and the guide service are test fakes; the handlers, ThreadManagementService, the orchestrator and the in-memory store are real. Reversing the two calls (watch, then settle) also ends the watch, which matches the docs.

Expected behavior

The agent was told watching: true and to end its turn, so it expects to be woken on failed checks, comments or conflicts. One of these should be true:

  • A watch turned on after the settle request keeps the thread active, or cancels the pending settle.
  • Or watch_pull_request says that the thread settles at the end of the turn and that this will end the watch.

I do not know which one you prefer.

Actual behavior

At the end of the turn the deferred settle runs and clears the watch. No error or notice reaches the agent. Because the watch sweep selects only links that have a watch (apps/server/src/orchestration-v2/PullRequestWatchReactor.ts:556-563), I expect the agent is never woken; the test shows only that the watch is removed.

Code path on main 220eb73524:

  • apps/server/src/mcp/toolkits/thread/handlers.ts:296-303 and apps/server/src/orchestration-v2/ThreadManagementService.ts:962-972 fork settleAfterRun and return settlesWhenTurnEnds.
  • ThreadManagementService.ts:950-959 waits for the run and dispatches thread.settle. It does not check for a watch added after the request.
  • apps/server/src/orchestration-v2/Orchestrator.ts:3254 clears every watch in thread.settle.
  • apps/server/src/mcp/toolkits/pullRequests/handlers.ts:262-300 returns watching: true while the settle is still pending.

docs/user/source-control.md:295 says settling ends all watches of the thread. This report is only about the order: a watch turned on after the settle request.

Impact

Minor bug or occasional failure

Version or commit

Upstream main 220eb73524 (test reproduction); first seen in code on nightly 0.1.3-nightly.20261026.3726 (3f9448747b).

Environment

Windows 11, focused vitest run in a worktree of main (Node 25.8.1; the repository declares 26.12.1). No live agent run.

Workaround

Turn on the watch first, or settle in a separate turn after the watch has ended. Or unsettle the thread and ask the agent to watch again.

Related

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions