Agents in seven different places were sending me Discord direct messages. I wanted every one of them to use the channels I already had. My first prompt was one line: “I wanted to update my agents to always contact me in the dx channels instead of dm. Can you audit and help with this.” The session ran to 135 prompts.
Seven places that reached me
The audit covered the main ops repo, the business-ops agent, the async relay, the relay between me and a collaborator, the platform’s status droplet, the edge worker and the ticket bot. In the ops repo, the agent alerts to me were the keepalive, the “say” command and the listener escalation.
The channels I got wrong
Some of the channels created along the way were wrong, and they were deleted. The rule that stuck was to use the lane channels that already existed. Every venture posts as the bot into its existing lane channel in my own server, with an @mention. That gives four lanes: the platform, business ops, blog and agent system. Agents never DM me.
What review changed in the sender
The first version of the ops repo’s Discord sender had a silent default to the platform venture. A review pass fixed that, and --venture is now required on send, read and wait.
The same review pass changed the business-ops listener. In a shared channel it now hears my message only when the message is addressed to it.
Alerts that stay private
The edge worker’s alerts and the status alerts post through a webhook with an @mention into my private platform channel. For the status alerts, SMS stays as the fallback if the post fails, and failures are logged. Agent alerts to me, covering the keepalive, “say” and listener escalation, post the same way into my private alert channel.
One credential line was wrong
A code review flagged an entry in the secrets manifest. It described the webhook token as post-only, and the reviewer’s finding said that description was incorrect.
What to take from it
With seven senders, a default destination decides where alerts land when someone forgets to choose. A call to the sender with no --venture no longer lands in the platform channel by default. It fails.
AI Skills
Use this lesson with the AI assistant you already use
Agents in seven places sent the owner Discord direct messages, and moving them to existing lane channels exposed a sender whose first version silently defaulted to the platform venture. A review pass made the venture a required argument on send, read and wait.
Paste the prompt, share only the context needed to answer it, and treat the result as a draft for your review. Do not include confidential information or let an AI assistant make changes without your approval.
The prompt works in any AI assistant as it is. We are also building a /dxdev skill for visual reports and saved memory.
It is not released yet: see what you can use today.
dxdev LESSON · paste into your AI coding agent
LESSON: Make The Destination A Required Argument So An Alert Sender Cannot Default To The Wrong Channel
SOURCE: dxdev.com/blog/agents-never-dm-the-owner
WHAT HAPPENED: Agents in seven places reached the owner by Discord direct message: the ops repo, the business-ops agent, the async relay, the relay between the owner and a collaborator, the platform status droplet, the edge worker and the ticket bot. The fix was to post as the bot into each venture's existing lane channel with an @mention. The first version of the ops repo's Discord sender had a silent default to the platform venture. A review pass fixed that, and the venture is now a required argument on send, read and wait. The same review changed the business-ops listener so that in a shared channel it hears a message only when the message is addressed to it. Some channels created along the way were wrong and were deleted.
THE RULE: When many agents send alerts, make the destination a required argument rather than a default, so a missing value fails loudly instead of landing in the wrong channel.
CHECK MY CODE, then report PASS or FAIL with file:line for each:
1. List every function that sends, reads or waits on a chat channel and confirm the destination is a required argument with no default.
2. Run each sender once with the destination omitted and confirm it fails instead of posting anywhere.
3. Confirm that every listener in a shared channel acts only on messages addressed to it.
THEN PRINT: a table (check, PASS/FAIL, evidence, fix) + a verdict (applies / partially / OUT_OF_SCOPE / no) + the single most important next action.