Skip to content

fix(mcp): t3_thread_read tells agents which thread sent a message - #18194

Open
Mnigos wants to merge 3 commits into
pingdotgg:mainfrom
Mnigos:thread-read-shows-sender-thread
Open

Mnigos wants to merge 3 commits into
pingdotgg:mainfrom
Mnigos:thread-read-shows-sender-thread

Conversation

@Mnigos

@Mnigos Mnigos commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor

Addresses the t3_thread_read part of #17517; the server-authored line in the delivered turn is left out (see below).

Problem

When one thread sends a message to another with t3_thread_send, the server records the sender on the message as senderThreadId, and the web and mobile timelines use it. t3_thread_read left the field out of its timeline items, so the agent that received the message could not tell which thread sent it. It only saw createdBy: "agent" and creationSource: "mcp". @pawelwitek34's reproduction shows this clearly. A parent with two delegated children could only work out the sender by reading each child's timeline and matching messageIds.

Change

  • OrchestratorMcpThreadTimelineItem (packages/contracts/src/orchestratorMcp.ts) gets an optional senderThreadId.
  • timelineItem in apps/server/src/mcp/OrchestratorMcpService.ts copies it from the stored message. The field appears only when the message has a sender, so items without one add no response bytes; the advertised output schema gains the optional field.

The issue also suggests adding a server-written line to the delivered turn so the agent would not need a second call. That is out of scope here. It changes the prompt text that every provider receives and needs its own design for how the line is worded and placed. The field on t3_thread_read gives agents a reliable sender id now.

Verification

Gate Result
New test in OrchestratorMcpService.activity.test.ts on base Fails (senderThreadId is undefined)
Same test with the fix Passes: the message from the other thread carries senderThreadId and the user message has no such field
vp test run src/mcp (apps/server) 26 files, 286 tests passed
vp run typecheck (apps/server, packages/contracts) 0 errors
fmt / lint on changed files Clean

Server/contract change with no UI, so no screenshots.

Not checked: a live delegate_task + t3_thread_send round trip against real providers.

Implemented with Claude Opus 5.5, verified with GPT-6 Astra, coordinated by Claude Fable 5.1 in Claude Code.

Messages sent from another thread already record senderThreadId, and the
web and mobile timelines use it, but t3_thread_read items left it out, so
the receiving agent could not tell which thread sent a message.

Timeline items now carry an optional senderThreadId, included only when
the message has one.
@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XS 0-9 changed lines (additions + deletions). labels Oct 11, 2026
macroscopeapp[bot]
macroscopeapp Bot previously approved these changes Oct 11, 2026
@macroscopeapp

macroscopeapp Bot commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at d73854e

Macroscope's review found this PR approvable — This is a focused, backward-compatible MCP response fix that exposes already-recorded sender thread metadata and omits it for ordinary messages. It adds targeted coverage without changing defaults, workflows, persistence, or deployment behavior.

You can add or adjust custom eligibility rules. Learn more.

@juliusmarminge juliusmarminge added the macroscope-review Opt PRs made by unvouched contributors in for Macroscope review. Vouched contributors auto-reviews label Oct 11, 2026 — with ChatGPT Codex Connector
@macroscopeapp
macroscopeapp Bot dismissed their stale review October 11, 2026 11:13

Dismissing prior approval to re-evaluate 4f43047

macroscopeapp[bot]
macroscopeapp Bot previously approved these changes Oct 11, 2026
@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: 3c098471-8fd3-48ed-9e63-8a8c4fe08275


📥 Commits

Reviewing files that changed from the base of the PR and between 4f43047 and d73854e.



📒 Files selected for processing (3)
  • apps/server/src/mcp/OrchestratorMcpService.activity.test.ts
  • apps/server/src/mcp/OrchestratorMcpService.ts
  • packages/contracts/src/orchestratorMcp.ts


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




📝 Walkthrough
📝 Walkthrough

Walkthrough

Thread timeline items now include senderThreadId when the source message defines one. The contract marks the field as optional. A test checks messages with and without the field.

Changes

Thread timeline sender IDs

Layer / File(s) Summary
Add sender thread IDs to timeline items
packages/contracts/src/orchestratorMcp.ts, apps/server/src/mcp/OrchestratorMcpService.ts, apps/server/src/mcp/OrchestratorMcpService.activity.test.ts
The timeline item contract adds an optional senderThreadId. The timeline mapping includes the field when the source message defines it. The test checks that messages without a sender thread omit the field.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Suggested reviewers: juliusmarminge



Merge Risk: ⚪ Minimal · up to d7385

Thread timeline items now identify the sending thread when a message has one, and omit the field otherwise. The change is small and additive, and no merge-blocking risk is evident. A live round trip against real providers was not checked.

Security Architecture Review

Security architecture risk: 🔵 Low · up to d7385

This is a small, additive response change. Existing access checks remain unchanged, and no permission expansion was identified. Sender attribution is derived from the calling thread on the messaging path reviewed, but its integrity across every message-creation path was not fully confirmed.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • observed — The added disclosure is the originating thread identifier on messages already returned by thread reads. Cross-project reading within the environment predates this PR and is explicitly exercised by an existing test; the change does not introduce that reachability.

Trust Boundaries and Controls

  • observed — Thread reads load the caller through the existing orchestration capability gate and reject missing or deleted target threads. The MCP send path obtains senderThreadId from the caller's loaded thread, omitting it when there is no calling thread.
  • observed — A separate, existing message.dispatch contract accepts senderThreadId. Its WebSocket handler applies user creation provenance, and WebSocket admission authenticates the session and installs scope-based authorization. Complete normalization of the sender field on this path remains unverified, so the MCP-path evidence does not establish universal attribution integrity.

Pre-merge checks | Passed 4
✅ Passed checks (4 passed)
Check name Status Explanation
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.
Title check Passed The title clearly and concisely describes the main change: t3_thread_read now tells agents which thread sent a message.
Description check Passed The description includes the problem, change, scope, out-of-scope clarification, verification results, and unchecked live-provider validation. It references issue #17517 and provides specific test and…

✨ 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.

The new readThread sender test now provides ServerSettings.layerTest(), which OrchestratorMcpService requires since main added the server settings dependency.
@macroscopeapp
macroscopeapp Bot dismissed their stale review October 11, 2026 11:17

Dismissing prior approval to re-evaluate d73854e

AdEx-Partners-DE added a commit to AdEx-Partners-DE/t3code that referenced this pull request Oct 11, 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

macroscope-review Opt PRs made by unvouched contributors in for Macroscope review. Vouched contributors auto-reviews size:XS 0-9 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.

2 participants