Formalize sub-agent Slack-DM-on-cross-context-block protocol in HEARTBEAT.md
completedAgent: slava-agent
Priority: 2
From 2026-06-17 self-reflection. Atomic HEARTBEAT.md edit. Workspace-internal (no PR).
ADD a new ### subsection to HEARTBEAT.md adjacent to the existing sub-agent dispatch / thread-bound rules (06-09 36482727 in-thread one-liner; 06-11 c19e8021 post-CI-only; 06-16 367f3d9f gpt-5.5 thinking-leak). Title: 'Sub-agent Slack-DM-on-cross-context-block protocol.'
CONTEXT: when a heartbeat-spawned sub-agent's final step is a Slack DM and the dispatch context is webchat-bound (not Slack-thread-bound), the `message` tool returns: `Cross-context messaging denied: action=send target provider 'slack' while bound to 'webchat'.` The sub-agent CANNOT deliver the DM itself. The 05-04 lesson (subagent completed != delivery confirmed) covers a sub-agent CLAIMING delivery; this is a structural inability to deliver.
RULE: any thread-bound sub-agent dispatch whose final step is a Slack DM MUST include this explicit clause in the dispatch task description:
CRITICAL: if your final Slack DM call returns a `Cross-context messaging denied` error, do NOT treat the work as complete. Instead:
- In your final reply to the parent, include: (a) the exact suggested DM text, (b) the thread id, (c) the channel id, (d) the literal error string returned by the message tool.
- The parent agent will deliver the DM from its own (Slack-thread-bound) context.
- Do NOT silently drop the DM. Do NOT mark the fleet-task completed without surfacing the delivery gap.
This is upstream of and complementary to the 05-04 "subagent completed != delivery confirmed" lesson: that lesson required parent verification post-hoc; this rule requires sub-agent self-surfacing pre-hoc.
CASE STUDY (2026-06-16T~11:00-11:30Z): sub-agent `027d9ec0-3ace-4842-baa6-549f8d5159c6` (sonnet-4.6) for PR #12298 review-fix tried to DM Slack thread `1781603232.142049`. Hit `Cross-context messaging denied: action=send target provider 'slack' while bound to 'webchat'.` Defensively returned suggested DM text + thread id + channel id + error string to the parent in its final reply. Parent delivered the DM at 11:30Z (msg `1781610011.916369`). PR #12298 merged at 11:39:59Z. The defense was behavioral, not structural — formalize via doctrine.
ATOMIC STEPS:
1. Read current HEARTBEAT.md.
2. Locate the sub-agent dispatch / thread-bound rules cluster (06-09, 06-11, 06-16).
3. Insert the new subsection adjacent.
4. Verify edit clean.
5. PATCH this task to completed via bin/fleet-task-patch.sh with file:line of the new subsection.
Event Timeline
created
status_change
queued → completed