VIP DM Escalated Handling
Context
The Unified Channel Intelligence Pipeline (ADR-0131) classifies all Slack messages with Haiku (~$0.001/msg) for signal/noise routing. However, DMs from VIP contacts (tagged vip: true in Vault contacts) carry significantly higher signal density and relationship stakes. A message from Kent about MEGA content alignment or Grzegorz about cohort scheduling needs richer understanding than a channel noise classifier provides.
Decision
VIP DMs receive escalated classification:
1. VIP Detection
- On ingest, check if the Slack user ID maps to a Vault contact with
vip: true - VIP contacts store
slack_user_idandslack_dm_channelin frontmatter - Bot DMs with Joel are always VIP (Joel is always VIP to himself)
2. Escalated Classification (Sonnet 4.6 via OpenRouter)
- VIP messages skip Haiku classification
- Classified by Sonnet 4.6 with enriched context window:
- Full Vault contact dossier (projects, recent activity, key context)
- Related project state (e.g., MEGA status, agreements, open threads)
- Recent DM history (last 20 messages for thread continuity)
- Active Granola meeting summaries if recent (<24h)
- Classification output:
urgency: immediate / today / this_week / fyitopics: array of topic tagsaction_required: boolean — does Joel need to respond/act?suggested_context: what Joel should know before respondingrelated_contacts: other VIPs involved in the threadproject_refs: linked projects/ADRs
3. Routing & Escalation
Multi-channel notification — VIP messages fan out, not single-channel:
| Urgency | Channels | Behavior |
|---|---|---|
immediate + action_required | Telegram + Discord + iMessage | All three fire simultaneously. iMessage via imsg-rpc ensures Joel sees it even if not at desk. Context brief in each. |
immediate (no action) | Telegram + Discord | Inform both active channels, skip iMessage |
today | Telegram | Priority placement in next digest + standalone push |
this_week / fyi | Discord | Threaded summary in monitoring channel, indexed |
Escalation path if no ack within threshold:
- T+0: Initial notification to classified channels
- T+15min: If
immediate+action_requiredand no Joel activity detected → re-ping Telegram with “⚠️ VIP waiting” reminder - T+1hr: If still no ack → iMessage escalation (even for
todaytier) with full context - T+2hr: If still no ack → voice call via Telnyx (ADR-0079) with TTS summary: “You have an urgent message from [VIP name] about [topic]. Check your messages.”
- T+4hr: Log as missed in contact’s activity, surface in daily briefing as unresolved
“Joel activity detected” = any message sent from any gateway channel within the window (not necessarily a reply to the VIP).
4. Cost Model
- Sonnet 4.6 via OpenRouter: ~$0.01-0.03 per VIP message (vs $0.001 Haiku)
- Expected VIP volume: <50 messages/day across all VIPs
- Monthly cost ceiling: ~$30-45 for VIP classification
- Worth it: one missed VIP message costs more than a year of classification
VIP Contact Registry
Initial VIPs (from Vault contacts with vip: true):
- VIP Contact A (
<slack-user-id>) — priority collaborator - VIP Contact B (
<slack-user-id>) — priority collaborator
Registry grows as contacts are tagged VIP. No hard limit.
Implementation
Inngest Function: slack-vip-dm-classify
- Trigger:
channel/slack.message.receivedwheredata.is_vip == true - Steps:
load-contact— Read Vault contact markdownload-project-context— Query Typesense for related project docsload-dm-history— Fetch last 20 messages from Slack APIclassify— Sonnet 4.6 via OpenRouter with assembled contextroute— Push/digest/index based on classificationupdate-contact— Append to contact’s recent activity
Pre-requisites
- ADR-0131 message ingest pipeline (provides the trigger event)
- Vault contacts with
vip: trueandslack_user_id - OpenRouter API access (already available via
openrouter_api_key)
Consequences
- VIP messages get 10-30x richer classification than standard channels
- Joel gets contextual briefs (“Kent is asking about X, which relates to the MEGA timeline you discussed yesterday”)
- Cost is bounded and proportional to relationship value
- Non-VIP messages continue on Haiku path unchanged
- Contact dossiers become living documents updated by the pipeline