Repository navigation
Conversation
ApprovabilityVerdict: Not approved Macroscope's review found this PR not approvable — This adds a new mobile Stop control that can interrupt real background tasks after a turn settles, including new request-state and retry behavior. The change is compact and reuses existing infrastructure, but the new native interaction and wiring are not directly covered by an identifiable mobile control test, so the runtime behavior merits human review. You can add or adjust custom eligibility rules. Learn more. |
Dismissing prior approval to re-evaluate d8abb52
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configuration
📒 Files selected for processing (3)
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 7 remain after this review. 📝 WalkthroughWalkthroughThe mobile thread screen now offers a Stop control for background work. The route sends an interrupt for the selected thread and tracks the request state until the call settles. ChangesMobile background-work stopping
Priority: ➖ Normal Estimated code review effort: 2 (Simple) | ~10 minutes Change: Feature · Severity of issue fixed: Medium Sequence Diagram(s)sequenceDiagram
actor User
participant FloatingWorkingControl
participant ThreadRouteContent
participant ThreadInterrupt
User->>FloatingWorkingControl: Press Stop
FloatingWorkingControl->>ThreadRouteContent: Invoke stop callback
ThreadRouteContent->>ThreadInterrupt: Interrupt selected thread without run ID
ThreadRouteContent->>ThreadRouteContent: Clear matching request when call settles
Suggested reviewers: Merge Risk: ⚪ Minimal · up to This adds a Stop control for background work in mobile threads. No concrete merge-blocking defect was established. One open question remains: whether a rejected interrupt call could leave the button showing "Stopping" until the user switches threads. The author could confirm this cheaply. Security Architecture ReviewSecurity architecture risk: 🔵 Low · up to The new action preserves existing operation permissions and selected-thread targeting. Stop is thread-wide, not limited to one displayed task, and request acceptance does not guarantee termination. Downstream isolation and termination behavior remain only partially verified. Retained concerns Security review detailsSecurity Blast Radius
Trust Boundaries and Controls
Resilience and Maintainability Implications
🚥 Pre-merge checks | ✅ 3 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (3 passed)
Full details: Linked Issues checkExplanation The PR implements the mobile Stop action and sends a thread-only interrupt for settled background work [
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
d8abb52 to
2e31bf9
Compare
Dismissing prior approval to re-evaluate 2e31bf9
f149308 to
4ddc3e3
Compare
4ddc3e3 to
98c205b
Compare
After a turn completes, background tasks can keep running while mobile has no way to stop them. Add a separate Stop action to the existing “Waiting on…” pill, preserving the composer draft.
Fixes #14655. Replaces #14661 with the requested interaction evidence. Rebased onto main at
61b9790816.V2 implementation
Use the existing
pendingBackgroundTasks/presentPendingBackgroundWorkmodel and its task labels. The thread-only shared interrupt command resolves the settled run with pending work and sends V2run.interrupt; no server, contract, or provider changes are needed.Stop is one more segment of the existing pill, built like the agents and queue segments beside it; the status label itself is unchanged from main. It is hidden when the client lacks the orchestration operate scope.
Pending behavior now matches V2 web: Stop is disabled as Stopping… while the interrupt request is pending. It becomes available after acceptance or failure if tasks remain visible; acceptance is not proof of termination. The pill disappears when the pending-task roster clears. This deliberately replaces the previous V1 implementation's “disabled until liveness clears” behavior.
Request state is scoped to the environment/thread and the individual request, so an older completion cannot clear a newer request. Only the separate Stop button interrupts work. Existing status priority, queue/agent/device controls, and foreground-turn Stop behavior are preserved. Long task labels truncate while Stop remains visible.
Approval and scope
Three mobile files. Web/desktop already provide this path. Shared iOS/Android code; native verification is Android/Claude only. Other providers retain their existing interrupt semantics. iOS and relay/tunnel were not device-tested.
Evidence
Current layout
Android 16 Pixel emulator against an isolated worktree-local server, main at
611132c171plus this change. A real Claude Sonnet 4.6 session startedsleep 3600withrun_in_background=trueand completed its turn. Tapping Stop ended thesleep, cleared the pill, and left the draft in place.12-second recording of the tap:
stop-interaction.mp4
The pairing query from #10298 fails on a local server (it binds a JS boolean), so this run used an uncommitted one-line local workaround for pairing only. It is not part of this PR.
Pending and failure behavior (earlier layout)
The material below was recorded before Stop became a pill segment. The Stop text sat in a separate label component then; the request handling it exercises is unchanged. The pending, retry, and failure states have not been re-recorded on the current layout.
Android 16 Pixel emulator, compatible current development client, V2 main plus this change. A fresh worktree-local
.t3and manufactured project/thread were created through server commands; no live user data was copied. A real Claude Sonnet 4.6 session startedsleep 3600withrun_in_background=true, completed its turn, and left a command inpendingBackgroundTasks. No separate runtime prerequisite patch was needed.22-second continuous recording, normal speed, with explanatory captions:
verification-v2.mp4
Original recording without captions.
A test-only WebSocket proxy rejects the first interrupt with
OrchestrationV2DispatchCommandError. On retry it forwards the real interrupt, holds the successful response and subscription updates separately, then releases each. This makes the transient states observable without modifying production code or fabricating task completion.enabled: falsein the native tree). The extra tap sends no new interrupt: count remains 2 total, including the rejected attempt.enabled: true) while the task roster is still held. This is the V2 web behavior.Keep this draft while stopping background work.stays unchanged.Checks
git diff --checkpassed.Implemented and verified with GPT-6-Astra through the Codex harness in T3 Code. Rebased, reworked to reuse the pill's segment UI, and re-verified with Opus 5.5 through the Claude Code harness in T3 Code.