Skip to content

fix(mobile): don't send or paste attached threads a machine can't read - #18322

Open
NikitaMGrimm wants to merge 8 commits into
pingdotgg:mainfrom
NikitaMGrimm:resubmit/reference-machine-selection-mobile
Open

NikitaMGrimm wants to merge 8 commits into
pingdotgg:mainfrom
NikitaMGrimm:resubmit/reference-machine-selection-mobile

Conversation

@NikitaMGrimm

@NikitaMGrimm NikitaMGrimm commented Oct 11, 2026 •

Copy link
Copy Markdown

Split out of #18310 at the triage bot's request there. This PR covers the native mobile composer; #18310 covers web and desktop.

Problem

An agent can only read threads on its own server. On mobile, the new-task composer still sends a thread reference to a machine that doesn't own the thread, and pasting a thread copied from another machine keeps it. The agent then gets thread_not_found from t3_thread_read. #18310 fixes the same gap in the web and desktop composer.

Change

  • New task: submit stops with an alert naming the thread when the selected project's machine doesn't own an attached thread.
  • Paste: threads owned by another machine are dropped, as web paste already does, and an alert names them. It is combined with the existing failed-attachment warning into one alert. Dropped threads don't count against the paste limit. When the composer has no destination machine, threads are kept.
  • threadContextsOutsideEnvironment in packages/shared is the check, the same one fix(composer): don't send attached threads to a machine that can't read them #18310 uses on web. Both PRs add it with identical content, so whichever merges second rebases to a no-op for those two files.

The warnings use the existing native alerts: "Some context is unavailable" for paste and "Attached thread unavailable" for submit. They explain that the thread is on another machine; the submit warning tells the user to switch back or remove it from the draft.

No server, contract or web changes.

Scope and approval

Same basis as #18310: CONTRIBUTING.md's focused obvious-bug exception. A valid thread reference silently becomes unreadable when sent from a machine that doesn't own it.

Verification

  • vp test run packages/shared/src/composerContextReferences.test.ts apps/mobile/src/lib/composerContextClipboard.test.ts: 28 passed. The paste test for a foreign thread fails on main, where the thread is kept and counts against the context limit. A second test covers the unknown-destination case.
  • Mobile tsc --noEmit -p apps/mobile/tsconfig.json: pass. Scoped formatting and git diff --check: pass. Scoped lint: no errors; 12 existing warnings outside the edited lines.
  • Native Android 16 / Pixel 7 emulator: retained baseline ac2cc78d4a captures and refreshed the fixed captures at PR head beda35de70 for the final warning copy. Actual native copy/paste and project selection were exercised against two independent T3 environments. On the baseline, paste kept the foreign thread and submit created a task on the destination; its GPT-6 Luna provider reported thread_not_found. On the current head, paste warned and marked the thread unavailable, and submit showed the guard alert while preserving the draft. Same-environment paste attached the thread without a warning in the earlier aa958fac25 verification; this update changes warning text only.
  • All checks above were rerun on beda35de70 after the final wording change.

Android evidence

Both sides start with the same native draft and clipboard input. These short crops begin after selecting the destination project; the source thread belongs to a different environment.

Paste: long-press the empty destination composer and choose native Paste. Before, the thread stays attached. After, the warning names it and the chip is marked unavailable.

Native Android before and after pasting a foreign thread

pr18322-paste-wording.mp4

Submit: attach Source notes on its owning environment, switch the draft to the destination project, then tap Start task. Before, the task is sent and the composer clears. After, send is blocked and the draft remains.

Native Android before and after submitting a foreign thread

pr18322-submit-wording.mp4

Capture limits: both environments run on one Windows host with separate identities and state. Source notes is a seeded stopped-thread projection; interactions and clipboard operations are native. The same development APK was used for both revisions because native files are unchanged, with Metro restarted and its cache cleared at the PR head. Building on Windows needed isolated local toolchain workarounds; no PR source changes were made for capture. The baseline submit used GPT-6 Luna; the refreshed fixed capture selected gpt-5.4-mini, but the guard stopped submission before provider execution. Clips retain source timing and demonstrate behavior; they do not measure latency. iOS was not tested.

Note

🤖 Agent assistance: Claude Opus 5.5 via Claude Code in T3 Code (implementation); GPT-6.1 Sol via Codex in T3 Code (warning copy, Android verification and evidence)

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Oct 11, 2026
@NikitaMGrimm
NikitaMGrimm marked this pull request as ready for review October 11, 2026 23:30
@coderabbitai

coderabbitai Bot commented Oct 11, 2026

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Path: .coderabbit.config.ts
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 1847b859-c35f-46d0-b24d-87ec0f58fb37

📥 Commits

Reviewing files that changed from the base of the PR and between bed9239 and beda35d.


📒 Files selected for processing (7)
  • apps/mobile/src/components/ComposerEditor.tsx
  • apps/mobile/src/features/threads/NewTaskDraftScreen.tsx
  • apps/mobile/src/features/threads/new-task-flow-provider.tsx
  • apps/mobile/src/lib/composerContextClipboard.test.ts
  • apps/mobile/src/lib/composerContextClipboard.ts
  • packages/shared/src/composerContextReferences.test.ts
  • packages/shared/src/composerContextReferences.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.



📝 Walkthrough

Walkthrough

Mobile context import now filters thread references from other environments and reports skipped threads. Task draft submission is blocked when the draft references a thread outside the selected project’s environment.

Changes

Mobile thread context environment checks

Layer / File(s) Summary
Detect cross-environment thread references
packages/shared/src/composerContextReferences.ts, packages/shared/src/composerContextReferences.test.ts
Adds threadContextsOutsideEnvironment to find referenced thread records owned by a different environment. Tests cover referenced and unreferenced thread records.
Filter unavailable threads during context import
apps/mobile/src/lib/composerContextClipboard.ts, apps/mobile/src/lib/composerContextClipboard.test.ts, apps/mobile/src/components/ComposerEditor.tsx
Clipboard import accepts a destination environment, omits threads owned by another environment, and returns their titles. The editor passes the environment and alerts about skipped threads or failed attachment copies. Tests cover known and unknown destination environments.
Reject drafts with unavailable thread references
apps/mobile/src/features/threads/NewTaskDraftScreen.tsx, apps/mobile/src/features/threads/new-task-flow-provider.tsx
The draft screen alerts and stops submission when a referenced thread belongs to another environment. The provider also declines to build a pending task message for such a draft.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix

Possibly related PRs

  • pingdotgg/t3code#16940: Adds related cross-environment thread-reference checks for web and desktop, alongside mobile behavior.

Suggested reviewers: chrisdeeming


Merge Risk | ⚪ Minimal · up to beda3

Merge Risk: ⚪ Minimal · up to beda3

The change stops mobile from sending or pasting thread references that the destination machine cannot read, and it warns the user instead. No merge-blocking risk was found.

Security Architecture Review

Security architecture risk: ⚪ Minimal · up to beda3

The change restricts which thread references can enter a task without adding access privileges. Submission checks the destination again before saving the task. No material security risk introduced or worsened by these changes was identified.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — The introduced behavior restricts clipboard thread metadata and new-task drafts for the selected environment. It does not introduce a new thread-fetch operation, credential capability, or cross-environment delivery route.

Trust Boundaries and Controls

  • observed — Clipboard fragments are structurally decoded as untrusted data. The new eligibility check compares their claimed environment identity; it is an availability check, not authenticated proof of thread ownership. This PR narrows previously accepted input and does not establish or replace backend authorization.

Resilience and Maintainability Implications

  • observed — An in-flight paste captures its initial destination, while project switching can retain the same draft key. Consequently, paste classification can become stale. Both submission guards check the selected destination again, containing this race before task creation; incorrect omission can still affect context availability.

Pre-merge checks | Passed 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check Passed The title clearly and concisely describes the main mobile fix: preventing attached threads from being sent or pasted when the destination machine cannot read them.
Description check Passed The description includes the problem, change, scope and approval basis, focused verification results, platform evidence, limitations, and agent details. It is sufficiently complete and directly matche…
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.

NikitaMGrimm pushed a commit to NikitaMGrimm/t3code that referenced this pull request Oct 12, 2026
NikitaMGrimm pushed a commit to NikitaMGrimm/t3code that referenced this pull request Oct 12, 2026
NikitaMGrimm pushed a commit to NikitaMGrimm/t3code that referenced this pull request Oct 14, 2026

This branch has not been deployed

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

Labels

size:M 30-99 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant