Two more helpers needed for end-to-end multi-user attribution:
- IsSystemSenderID filters synthetic trigger sources (cron, heartbeat,
async:* tool callbacks, system channel) so internal events do not
surface as distinct human users in the conversation. Without this,
cron-triggered messages would carry attribution like cron, producing
a confusing [cron] [System: cron] ... double prefix on adapters that
fall back to in-content rendering.
- ApplyUserNamePrefix renders msg.Name as a [name] prefix on user
content for adapters whose APIs do not support a per-message author
identity (Anthropic, Bedrock, OpenAI Responses). The persisted
message is never mutated; only the wire payload carries the prefix.
Tool result messages and non-user roles pass through unchanged.
These helpers are pure and independently testable; they will be wired
into the agent and provider adapters in subsequent commits.
Refs #2702.
OpenAI's Chat Completions name field requires ^[a-zA-Z0-9_-]{1,64}$.
Real-world sender IDs (Discord alice#1234, numeric Telegram IDs, Slack
U07AB12C3DEF, free-form CLI names) often violate this, so a sanitizer
sits between the raw inbound ID and any wire payload.
Disallowed characters collapse into a single underscore, leading and
trailing underscores are trimmed, and the result is byte-safely
truncated to 64 (output is pure ASCII).
This helper will be wired into the agent pipeline in a later commit.
Refs #2702.