multi-stakeholder-thread-management
Installation
SKILL.md
Multi-Stakeholder Thread Management
You are an expert in building sales bots that handle conversations involving multiple decision-makers. Your goal is to help developers create systems that track, coordinate, and advance conversations across buying committees.
Why Multi-Stakeholder Management Matters
The Complex Deal Reality
Modern B2B deals:
- Average 6-10 people in buying decision
- Multiple perspectives and priorities
- Different information needs
- Consensus often required
Single-threaded approach:
- Rely on one champion
- Miss other stakeholders
- Blind to objections elsewhere
- Deal stalls mysteriously
Multi-Threaded Approach
Managed stakeholder engagement:
- Map all decision participants
- Understand each person's priorities
- Address concerns individually
- Build consensus systematically
Result: Faster deals, fewer surprises
Stakeholder Mapping
Identifying Stakeholders
class StakeholderMap:
def __init__(self, deal_id):
self.deal_id = deal_id
self.stakeholders = []
def add_stakeholder(self, stakeholder):
self.stakeholders.append({
"id": generate_id(),
"name": stakeholder["name"],
"title": stakeholder["title"],
"role": classify_role(stakeholder), # champion, buyer, user, etc.
"influence": stakeholder.get("influence", "unknown"),
"sentiment": stakeholder.get("sentiment", "neutral"),
"priorities": stakeholder.get("priorities", []),
"objections": stakeholder.get("objections", []),
"engagement_level": 0,
"last_contact": None,
"preferred_channel": stakeholder.get("channel", "email")
})
def classify_role(stakeholder):
title = stakeholder["title"].lower()
if any(x in title for x in ["ceo", "cfo", "cto", "president", "owner"]):
return "economic_buyer"
elif any(x in title for x in ["vp", "director", "head of"]):
return "decision_maker"
elif any(x in title for x in ["manager", "lead"]):
return "influencer"
elif any(x in title for x in ["analyst", "specialist", "coordinator"]):
return "user"
else:
return "unknown"
Stakeholder Discovery
def discover_stakeholders_from_conversation(message, existing_map):
# Look for mentions of other people
mentions = extract_person_mentions(message)
for mention in mentions:
# "My boss Sarah"
# "Our CTO will need to review"
# "The finance team"
if mention not in existing_map:
stakeholder = {
"name": mention.get("name", "Unknown"),
"title": mention.get("title", "Unknown"),
"relationship": mention.get("relationship"), # boss, colleague, etc.
"mentioned_by": message.sender,
"discovered_from": message.content
}
existing_map.add_stakeholder(stakeholder)
return existing_map
Conversation Tracking
Per-Stakeholder Context
class StakeholderConversation:
def __init__(self, stakeholder_id, deal_id):
self.stakeholder_id = stakeholder_id
self.deal_id = deal_id
self.messages = []
self.topics_discussed = []
self.questions_asked = []
self.objections_raised = []
self.commitments_made = []
self.information_shared = []
def add_interaction(self, interaction):
self.messages.append(interaction)
# Extract context
if interaction.get("questions"):
self.questions_asked.extend(interaction["questions"])
if interaction.get("objections"):
self.objections_raised.extend(interaction["objections"])
if interaction.get("commitments"):
self.commitments_made.extend(interaction["commitments"])
def get_state(self):
return {
"last_contact": self.messages[-1]["timestamp"] if self.messages else None,
"engagement_count": len(self.messages),
"open_questions": [q for q in self.questions_asked if not q.get("answered")],
"unresolved_objections": [o for o in self.objections_raised if not o.get("resolved")],
"sentiment_trend": calculate_sentiment_trend(self.messages)
}
Cross-Stakeholder View
def get_deal_stakeholder_summary(deal_id):
stakeholder_map = get_stakeholder_map(deal_id)
summary = {
"total_stakeholders": len(stakeholder_map.stakeholders),
"by_role": {},
"engagement": {},
"risks": []
}
for stakeholder in stakeholder_map.stakeholders:
role = stakeholder["role"]
summary["by_role"][role] = summary["by_role"].get(role, 0) + 1
conv = get_stakeholder_conversation(stakeholder["id"], deal_id)
state = conv.get_state()
summary["engagement"][stakeholder["name"]] = {
"level": state["engagement_count"],
"sentiment": stakeholder["sentiment"],
"last_contact": state["last_contact"]
}
# Identify risks
if state["unresolved_objections"]:
summary["risks"].append({
"stakeholder": stakeholder["name"],
"type": "unresolved_objection",
"details": state["unresolved_objections"]
})
if stakeholder["sentiment"] == "negative":
summary["risks"].append({
"stakeholder": stakeholder["name"],
"type": "negative_sentiment"
})
return summary
Coordination Strategies
Information Consistency
def ensure_consistency(deal_id, message, recipient):
"""Ensure information is consistent across stakeholders"""
# Get what we've told other stakeholders
other_conversations = get_all_stakeholder_conversations(deal_id)
# Check for potential conflicts
for conv in other_conversations:
if conv.stakeholder_id != recipient.id:
conflicts = detect_information_conflicts(
new_message=message,
existing_conversation=conv
)
if conflicts:
# Flag for review or auto-reconcile
handle_conflict(conflicts, message, conv)
return message
Role-Appropriate Messaging
def customize_for_role(base_message, stakeholder):
role = stakeholder["role"]
customizations = {
"economic_buyer": {
"focus": ["roi", "risk", "strategic_fit"],
"detail_level": "executive_summary",
"cta": "Worth a brief discussion on strategic fit?"
},
"decision_maker": {
"focus": ["value", "implementation", "support"],
"detail_level": "moderate",
"cta": "Want to dive deeper into how this works?"
},
"influencer": {
"focus": ["features", "workflow", "team_impact"],
"detail_level": "detailed",
"cta": "Would a demo for your team be helpful?"
},
"user": {
"focus": ["usability", "training", "daily_workflow"],
"detail_level": "practical",
"cta": "Want to try it yourself?"
}
}
config = customizations.get(role, customizations["influencer"])
return adapt_message(base_message, config)
Stakeholder-Specific Objections
def track_and_address_objections(deal_id):
stakeholder_map = get_stakeholder_map(deal_id)
objection_matrix = {}
for stakeholder in stakeholder_map.stakeholders:
conv = get_stakeholder_conversation(stakeholder["id"], deal_id)
objection_matrix[stakeholder["name"]] = conv.objections_raised
# Identify common objections
common = find_common_objections(objection_matrix)
# Identify unique objections
unique = find_unique_objections(objection_matrix)
return {
"common_objections": common, # Address broadly
"unique_objections": unique, # Address individually
"recommended_actions": generate_objection_actions(common, unique)
}
Consensus Building
Alignment Tracking
def assess_buying_committee_alignment(deal_id):
stakeholder_map = get_stakeholder_map(deal_id)
alignment = {
"champions": [],
"supporters": [],
"neutral": [],
"skeptics": [],
"blockers": []
}
for stakeholder in stakeholder_map.stakeholders:
sentiment = stakeholder["sentiment"]
if sentiment == "very_positive":
alignment["champions"].append(stakeholder)
elif sentiment == "positive":
alignment["supporters"].append(stakeholder)
elif sentiment == "neutral":
alignment["neutral"].append(stakeholder)
elif sentiment == "negative":
alignment["skeptics"].append(stakeholder)
elif sentiment == "very_negative":
alignment["blockers"].append(stakeholder)
# Calculate alignment score
weights = {"champions": 2, "supporters": 1, "neutral": 0, "skeptics": -1, "blockers": -2}
score = sum(len(alignment[k]) * weights[k] for k in weights)
return {
"alignment": alignment,
"score": score,
"recommendation": get_alignment_recommendation(alignment)
}
def get_alignment_recommendation(alignment):
if alignment["blockers"]:
return f"Address blockers: {[s['name'] for s in alignment['blockers']]}"
elif alignment["skeptics"]:
return f"Convert skeptics: {[s['name'] for s in alignment['skeptics']]}"
elif not alignment["champions"]:
return "Develop a champion"
elif alignment["neutral"]:
return f"Engage neutral stakeholders: {[s['name'] for s in alignment['neutral']]}"
else:
return "Ready to advance"
Communication Orchestration
When to Contact Which Stakeholder
def plan_stakeholder_outreach(deal_id):
summary = get_deal_stakeholder_summary(deal_id)
plan = []
for stakeholder in summary["stakeholders"]:
state = summary["engagement"][stakeholder["name"]]
# Determine need for outreach
days_since_contact = (now() - state["last_contact"]).days if state["last_contact"] else 999
if days_since_contact > 14:
plan.append({
"stakeholder": stakeholder,
"reason": "re-engagement",
"priority": "medium"
})
if stakeholder["name"] in [r["stakeholder"] for r in summary["risks"]]:
plan.append({
"stakeholder": stakeholder,
"reason": "risk_mitigation",
"priority": "high"
})
# Sequence outreach appropriately
return sequence_outreach_plan(plan)
Coordinated Multi-Touch
def execute_coordinated_outreach(deal_id, campaign_type):
stakeholder_map = get_stakeholder_map(deal_id)
campaign_configs = {
"pre_demo": {
"economic_buyer": {"message": "exec_summary", "timing": "day_before"},
"decision_maker": {"message": "agenda_preview", "timing": "day_before"},
"user": {"message": "feature_teaser", "timing": "2_days_before"}
},
"post_demo": {
"economic_buyer": {"message": "roi_summary", "timing": "same_day"},
"decision_maker": {"message": "detailed_followup", "timing": "same_day"},
"user": {"message": "trial_invitation", "timing": "next_day"}
}
}
config = campaign_configs.get(campaign_type, {})
for stakeholder in stakeholder_map.stakeholders:
role_config = config.get(stakeholder["role"])
if role_config:
schedule_message(
stakeholder=stakeholder,
message_type=role_config["message"],
timing=role_config["timing"]
)
Metrics
Multi-Stakeholder Health
Track:
- Stakeholders identified vs engaged
- Sentiment by stakeholder
- Objection resolution rate
- Consensus score trend
- Deal velocity by stakeholder count
Weekly Installs
6
Repository
louisblythe/salesskillsGitHub Stars
11
First Seen
Mar 18, 2026
Security Audits