📝 Walkthrough
ChatView now supports guarded automatic retargeting for scratch-project drafts. Project selection can carry a validated provider/model selection into new or reusable empty drafts.
Changes: Draft auto-routing
Layer / File(s) Summary Retarget planning and request guards
apps/web/src/components/ChatView.logic.ts,apps/web/src/components/ChatView.logic.test.tsPlanning helpers define valid retarget actions. Applicability checks reject stale, promoted, sending, manual, or already-resolved drafts when required. Keyed request gates cancel superseded requests and validate the current generation. ChatView retarget integration
apps/web/src/components/ChatView.tsx,apps/web/src/components/chat/useDraftEnvironmentRouting.ts,apps/web/src/composerDraftStore.test.tsAutomatic balancing includes scratch-project drafts. Scratch projects open before retargeting. Retargeting applies only when the request and draft remain valid. Re-arming Auto cancels the active request, and manual switching uses shared validation. Tests verify mapping migration and model-option preservation. Picker model selection
Layer / File(s) Summary Selection handoff and validation
apps/web/src/components/chat/DraftHeroHeadline.tsx,apps/web/src/hooks/useHandleNewThread.tsProject selection passes an explicit provider/model selection when one exists. The thread handler validates the provider instance against destination environment settings and project overrides. Apply selection to new and reused drafts
apps/web/src/hooks/useHandleNewThread.ts,apps/web/src/hooks/useHandleNewThread.test.tsA valid picker selection is applied explicitly to new or reusable empty drafts, with options replaced. Otherwise, existing default/carry resolution remains. Tests cover available, missing, and disabled providers. Priority: ➖ Normal
Estimated code review effort: 4 (Complex) | ~45 minutes
Change: Bug fix
Sequence Diagram(s)
Scratch draft retargeting
mermaid1 sequenceDiagram 2 participant ChatView 3 participant createKeyedRequestGate 4 participant DraftState 5 ChatView->>createKeyedRequestGate: begin request for draft and target environment 6 ChatView->>ChatView: open scratch project when target has none 7 ChatView->>createKeyedRequestGate: check whether request is current 8 ChatView->>DraftState: retarget when request and draft remain applicable Picker model selection
mermaid1 sequenceDiagram 2 participant DraftHeroHeadline 3 participant useNewThreadHandler 4 participant DestinationEnvironmentProviders 5 participant Draft 6 DraftHeroHeadline->>useNewThreadHandler: pass picker model selection 7 useNewThreadHandler->>DestinationEnvironmentProviders: validate provider instance and project settings 8 DestinationEnvironmentProviders-->>useNewThreadHandler: return selectable provider entry 9 useNewThreadHandler->>Draft: apply valid selection explicitly Suggested reviewers:
juliusmarminge
Merge Risk: 🔵 Low · up to 7f2f0
If a project is picked before the destination machine's provider list has loaded, the user's chosen model may silently revert to the project default. This is a narrow, self-recoverable edge case, so the change is mergeable with a small follow-up.
Security architecture risk: 🟡 Moderate · up to 21edc
Most routing safeguards remain intact, but an overlapping automatic and manual machine switch can discard the manual choice. A later message could consequently run on a different connected machine than the user selected.
Retained concerns
- Medium · security · inferred: Automatic and manual scratch opens do not share routing-intent arbitration. Starting a manual switch records a separate pending request but leaves the draft eligible for the automatic completion. With a draft on A, an automatic open for B and a later manual open for C can overlap. If B resolves first, it retargets the draft; C then fails the original-environment/project check and is discarded. The pending manual scope is also abandoned after the move. A subsequent user-initiated send can therefore use B rather than the explicitly selected C. This newly reachable ordering weakens destination-selection integrity across connected environments, although destination permissions still apply and no actual disclosure was observed.
Security review details
Security Blast Radius
- inferred — The identified concern is bounded to a browser draft and its configured machine destinations. Scratch candidates come from known environments; automatic candidates additionally require a connected machine, positive routing weight, and a matching enabled, installed, authenticated, available provider. The wrong-destination scenario requires overlapping opens for distinct destinations, such as automatic B and manual C from A. The evidence does not establish arbitrary-host reachability or tenant-wide exposure.
Security Findings and Attack Paths
- inferred — Response ordering can determine the winning machine despite a later manual choice. Once the automatic move resolves routing and abandons the old manual-request scope, a subsequent send can transmit prompt content and start a turn using the resulting environment. This is a potential destination-confidentiality and execution-placement consequence; it still requires user submission and destination permission, and no runtime exploitation or data disclosure was demonstrated.
Trust Boundaries and Controls
- observed — The send path checks orchestration-operate permission for its environment and blocks while a manual change is pending or automatic routing remains unresolved. Picker handoff separately validates provider identity against the destination catalog and settings. These are client-side controls; their presence does not establish the server’s authorization guarantees.
Resilience and Maintainability Implications
- observed — The keyed-gate tests cover target cancellation, A-to-B-to-A repetition, failed-key deduplication, and unmount cancellation in isolation. They do not exercise the competing manual request channel, so those tests do not resolve the cross-path arbitration concern.
Hardening Proposals
- proposed — Use a shared routing-intent generation for automatic and manual transitions, invalidated when a new choice starts rather than when its project resolves. Require both completion paths to hold that generation before committing the destination and mapping.
Pre-merge checks: Passed 3 · Failed 1
Failed Failed checks: 1 warning
Check name Status Explanation Resolution Description check Warning The description explains the problem, implementation, acceptance criteria, and verification in sufficient detail, but it does not provide the required Scope and approval information. Add the triaged bug issue or maintainer approval discussion with the approval comment. If this is an obvious focused fix without prior approval, explain why it qualifies for that exemption. Passed Passed checks: 3 passed
Check name Status Explanation Title check Passed The title clearly and concisely describes the primary change: enabling Auto balance for no-project drafts. Linked Issues check Passed Check skipped because no linked issues were found for this pull request. Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
- Create a new PR
- Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Comment @coderabbitai help to get the list of available commands.