[BUG] Buddy/Companion can inject ghost messages into the input stream as role: "user", impersonating the user

Resolved 💬 6 comments Opened Apr 8, 2026 by centaurverse Closed May 23, 2026

Summary

The Buddy/Companion feature (April seasonal companion) can write messages into the input stream that appear as Human: (user role) messages. The model cannot distinguish these from genuine user input, leading to unintended actions and responses.

Reproduction

  1. Start a Claude Code session with the Buddy companion active
  2. Use Telegram channels (--channels plugin:telegram@claude-plugins-official)
  3. Observe that Buddy occasionally injects text into the session as ⏺ Human: entries
  4. The model treats these as genuine user messages and responds accordingly — including sending replies through the Telegram channel to the real user

Observed behavior

  • Buddy-generated text appears as ⏺ Human: in the terminal, indistinguishable from real user input
  • The model acts on these ghost inputs: executing commands, sending channel replies, and making decisions based on messages the user never sent
  • When channels are active, this results in unsolicited replies being sent to the user's Telegram/Discord/iMessage, responding to messages they never wrote
  • The user has no way to identify which Human: messages were theirs vs. Buddy's without manually cross-referencing the terminal log

Expected behavior

Buddy/Companion messages should either:

  1. Use a distinct role or tag (e.g., role: "companion" or <companion> wrapper) so the model can identify and ignore them
  2. Be rendered in the UI only (speech bubble) without writing to the input stream at all

Root cause

Claude Code delivers all system events through role: "user" messages because there is no system-event role. The Buddy feature appears to write into this same input stream, making its output indistinguishable from genuine user input at the model level.

This is especially dangerous when combined with --dangerously-skip-permissions, as ghost inputs can trigger tool calls that execute without any user confirmation.

Impact

  • Security: Any feature that can write role: "user" messages is an injection vector. If Buddy can do it, other plugins or MCP servers could potentially do the same.
  • Trust: Users cannot trust that the model's actions were triggered by their own input.
  • Channel safety: Ghost inputs trigger real outbound messages through channels (Telegram, Discord, iMessage), breaking user expectations.

Environment

  • Claude Code version: 2.1.96
  • Companion: Rabbit (Zephyr)
  • Channels: Telegram plugin active
  • OS: macOS

View original on GitHub ↗

This issue has 6 comments on GitHub. Read the full discussion on GitHub ↗