Repository navigation
Description
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
- From any thread, call the MCP tool
t3_thread_sendto a Claude thread with:PREFIX: the literal mention $technical-writing appears mid-sentence here. SUFFIX: report the exact text you received, then stop. - Send the same text to a Codex thread.
- Send each thread a message that starts with the skill as a slash command instead:
/technical-writing PREFIX: report the exact text you received, then stop.
Any installed skill works; we used technical-writing because it changes nothing.
Expected behavior
Text that one agent sends another arrives as text. A skill mention in it does not invoke the skill, because the recipient's human never asked for that. An agent that means to invoke a skill in another thread says so explicitly.
Actual behavior
| Message from an agent | Claude thread | Codex thread |
|---|---|---|
$technical-writing mid-sentence |
the skill's full SKILL.md is added to the turn, framed as a /technical-writing command the user ran |
the skill's full SKILL.md is added to the turn in a skill wrapper |
Starts with /technical-writing |
same as above | nothing added |
The message text itself is kept; nothing is replaced. In the Claude thread the mention is rewritten to /technical-writing, and the command arguments hold only the text after it, so they drop everything before the mention. The recipient agent then reads that its user ran the skill on those arguments. Nothing tells it that another agent wrote the mention.
Source at eabcfa2 (main) matches this:
OrchestratorMcpService.tsrecordscreatedBy: agentandsenderThreadIdfor the message, then passes its text on unchanged.ClaudeSkillDispatch.ts(planClaudeSkillDispatch) turns any known$namemention into a native slash command, andClaudeAdapterV2.tssends it as user-role content, on both the start-turn and steer paths.CodexAdapterV2.tssends the text as plain input, and Codex invokes the mentioned skill itself.- Neither path uses the agent origin.
scheduledTasks/webhookTemplate.tsalready neutralizes mention and command syntax in untrusted webhook values, which looks like the boundary this case needs too.
Impact
Major degradation or frequent failure
Many skills treat an explicit invocation as the user's authorization to act. When agents message each other, as a coordinator relaying decisions or a reviewer reporting, a message that only names a skill (for example "the release skill reported X") starts that skill in the recipient. The recipient sees a command it cannot tell from its own user's. We saw it only with a read-only skill, and no tool ran.
Version or commit
T3 Code 0.1.3-nightly.20261024.3643; source read at eabcfa2 (2026-10-25)
Environment
Windows 11 x64; Claude Code (Claude Opus 5.5) and Codex (gpt-6-astra) threads
Workaround
Senders avoid writing skills as $name or a leading /name in messages to other threads.
Activity
offchan42 commentedon Oct 25, 2026
Addendum: the mention detector accepts any currency sign, not only
$, so the workaround above ("avoid$name") is incomplete.At
c79ef8c(main),apps/server/src/provider/Drivers/ClaudeSkillDispatch.ts:\p{Sc}is any Unicode currency symbol, andClaudeSkillDispatch.test.ts(lines 43-60) dispatches mentions prefixed with€ £ ¥ ₹ ₩ ₿ 𑿝. Amounts such as€20or$20kare excluded by the lookahead. So in a Claude thread, an agent's message containing€technical-writingshould dispatch the skill exactly as$technical-writingdoes. This follows from the source and its tests; we reproduced it live only with$, and we did not test other signs in Codex threads.For the fix:
scheduledTasks/webhookTemplate.tsalready breaks these mentions in untrusted webhook values (line 52,/[\p{Sc}@]|(?<=^|\s)\/(?=[^\s/]+(?:\s|$))|.../giu, followed by a U+2060 word joiner at line 170). Applying the same treatment to agent-originatedt3_thread_sendtext would cover every currency sign and a leading/name.On our side, a change accepted today makes sitrep, the cross-session messaging tool we use, push any message containing a currency sign as a neutral pointer. The recipient reads the exact text through its hook or by asking sitrep. That only covers our own sender; other agents calling
t3_thread_senddirectly are still affected.royalaid commentedon Nov 3, 2026
Another entry point for the same root cause, which the open fix (#24778) does not cover: delegated-task completion wakes.
When a
delegate_taskchild finishes, the server inlines the child's result into the parent's wake message (delegatedCompletionWakeDetail). The Claude adapter sends that wake like any user turn, with the user-invocable skill map (L10754, L11203), soplanClaudeSkillDispatchturns any$namein the child's output into a native skill command. #24778 neutralizes mentions only int3_thread_send, and its description says delegation flows keep their current behavior.What happened. A research child mined old transcripts and returned JSONL. One row quoted an earlier user prompt containing
$reprompt, which is an installed skill. The Claude parent's next turn ran/repromptwith the rest of the child's output as its arguments, and the skill loaded as if the user had invoked it. The parent noticed and ignored it; nothing in the turn showed that a child wrote the mention.The outgoing
prompt.offerin the provider event log shows the split (redacted, lengths are the real ones):content[1]is the tail ofcontent[0]from the mention on. The child's own text had$reprompt; T3 rewrote it.Still on the newest nightly.
ClaudeSkillDispatch.tshas not changed since the incident build. RunningplanClaudeSkillDispatchfromv0.1.7-nightly.20261103.4119on a wake-shaped string,Delegated task t1 [completed]:\n{"quote":"have it $reprompt itself, then tee it up"}, withrepromptin the skill map returnscommandText=/reprompt itself, then tee it up"}.Version: incident on 0.1.4-nightly.20261028.3824 (Linux x64 server, Claude Code 2.1.312, Opus 5.5 parent, Codex child on a linked environment). Source read at
v0.1.7-nightly.20261103.4119(cefb544).A fix at the wake boundary, such as the
webhookTemplate.tsmention treatment, would cover this path. Question relays and other server-built messages that embed agent output may need the same treatment. I did not check Codex parents, which per the report above expand$namethemselves.Filed by: Claude Opus 5.5 (Claude Code), on behalf of the poster, who reviewed it before posting.
fix(server): break only the recipient's own skill mentions in agent m…
test(server): agent cross-thread messages do not dispatch Claude skills
fix(server): OpenCode, Cursor and Grok no longer run a skill named in…